diff --git a/House.9ff42634.ldtkl b/House.9ff42634.ldtkl new file mode 100644 index 0000000..d95469e --- /dev/null +++ b/House.9ff42634.ldtkl @@ -0,0 +1,536 @@ +{ + "__header__": { + "fileType": "LDtk Project JSON", + "app": "LDtk", + "doc": "https://ldtk.io/json", + "schema": "https://ldtk.io/files/JSON_SCHEMA.json", + "appAuthor": "Sebastien 'deepnight' Benard", + "appVersion": "1.5.3", + "url": "https://ldtk.io" + }, + "identifier": "House", + "iid": "bc0f7ad0-b0a0-11ee-9c50-2597384ac3cd", + "uid": 21, + "worldX": 336, + "worldY": -256, + "worldDepth": 0, + "pxWid": 256, + "pxHei": 256, + "__bgColor": "#696A79", + "bgColor": null, + "useAutoIdentifier": false, + "bgRelPath": null, + "bgPos": null, + "bgPivotX": 0.5, + "bgPivotY": 0.5, + "__smartColor": "#ADADB5", + "__bgPos": null, + "externalRelPath": null, + "fieldInstances": [], + "layerInstances": [ + { + "__identifier": "Colliders", + "__type": "IntGrid", + "__cWid": 32, + "__cHei": 32, + "__gridSize": 8, + "__opacity": 0.54, + "__pxTotalOffsetX": 0, + "__pxTotalOffsetY": 0, + "__tilesetDefUid": null, + "__tilesetRelPath": null, + "iid": "bc0f7ad1-b0a0-11ee-9c50-5bc074c093c1", + "levelId": 21, + "layerDefUid": 9, + "pxOffsetX": 0, + "pxOffsetY": 0, + "visible": true, + "optionalRules": [], + "intGridCsv": [ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1 + ], + "autoLayerTiles": [], + "seed": 3233315, + "overrideTilesetUid": null, + "gridTiles": [], + "entityInstances": [] + }, + { + "__identifier": "Foreground", + "__type": "Tiles", + "__cWid": 16, + "__cHei": 16, + "__gridSize": 16, + "__opacity": 1, + "__pxTotalOffsetX": 0, + "__pxTotalOffsetY": 0, + "__tilesetDefUid": 1, + "__tilesetRelPath": "Solaria Demo Pack Update 03/Solaria Demo Pack Update 03/16x16/Tilesets/Solaria Demo Update 01.png", + "iid": "bc0f7ad2-b0a0-11ee-9c50-9356ce8b2d49", + "levelId": 21, + "layerDefUid": 4, + "pxOffsetX": 0, + "pxOffsetY": 0, + "visible": true, + "optionalRules": [], + "intGridCsv": [], + "autoLayerTiles": [], + "seed": 6916443, + "overrideTilesetUid": null, + "gridTiles": [ + { "px": [0,0], "src": [160,112], "f": 0, "t": 206, "d": [0], "a": 1 }, + { "px": [16,0], "src": [176,112], "f": 0, "t": 207, "d": [1], "a": 1 }, + { "px": [32,0], "src": [176,112], "f": 0, "t": 207, "d": [2], "a": 1 }, + { "px": [48,0], "src": [176,112], "f": 0, "t": 207, "d": [3], "a": 1 }, + { "px": [64,0], "src": [176,112], "f": 0, "t": 207, "d": [4], "a": 1 }, + { "px": [80,0], "src": [176,112], "f": 0, "t": 207, "d": [5], "a": 1 }, + { "px": [96,0], "src": [176,112], "f": 0, "t": 207, "d": [6], "a": 1 }, + { "px": [112,0], "src": [176,112], "f": 0, "t": 207, "d": [7], "a": 1 }, + { "px": [128,0], "src": [176,112], "f": 0, "t": 207, "d": [8], "a": 1 }, + { "px": [144,0], "src": [176,112], "f": 0, "t": 207, "d": [9], "a": 1 }, + { "px": [160,0], "src": [176,112], "f": 0, "t": 207, "d": [10], "a": 1 }, + { "px": [176,0], "src": [176,112], "f": 0, "t": 207, "d": [11], "a": 1 }, + { "px": [192,0], "src": [176,112], "f": 0, "t": 207, "d": [12], "a": 1 }, + { "px": [208,0], "src": [176,112], "f": 0, "t": 207, "d": [13], "a": 1 }, + { "px": [224,0], "src": [176,112], "f": 0, "t": 207, "d": [14], "a": 1 }, + { "px": [240,0], "src": [192,112], "f": 0, "t": 208, "d": [15], "a": 1 }, + { "px": [0,16], "src": [160,128], "f": 0, "t": 234, "d": [16], "a": 1 }, + { "px": [240,16], "src": [192,128], "f": 0, "t": 236, "d": [31], "a": 1 }, + { "px": [0,32], "src": [160,128], "f": 0, "t": 234, "d": [32], "a": 1 }, + { "px": [240,32], "src": [192,128], "f": 0, "t": 236, "d": [47], "a": 1 }, + { "px": [0,48], "src": [160,128], "f": 0, "t": 234, "d": [48], "a": 1 }, + { "px": [240,48], "src": [192,128], "f": 0, "t": 236, "d": [63], "a": 1 }, + { "px": [0,64], "src": [160,128], "f": 0, "t": 234, "d": [64], "a": 1 }, + { "px": [240,64], "src": [192,128], "f": 0, "t": 236, "d": [79], "a": 1 }, + { "px": [0,80], "src": [160,128], "f": 0, "t": 234, "d": [80], "a": 1 }, + { "px": [240,80], "src": [192,128], "f": 0, "t": 236, "d": [95], "a": 1 }, + { "px": [0,96], "src": [160,128], "f": 0, "t": 234, "d": [96], "a": 1 }, + { "px": [240,96], "src": [192,128], "f": 0, "t": 236, "d": [111], "a": 1 }, + { "px": [0,112], "src": [160,128], "f": 0, "t": 234, "d": [112], "a": 1 }, + { "px": [240,112], "src": [192,128], "f": 0, "t": 236, "d": [127], "a": 1 }, + { "px": [0,128], "src": [160,128], "f": 0, "t": 234, "d": [128], "a": 1 }, + { "px": [240,128], "src": [192,128], "f": 0, "t": 236, "d": [143], "a": 1 }, + { "px": [0,144], "src": [160,128], "f": 0, "t": 234, "d": [144], "a": 1 }, + { "px": [240,144], "src": [192,128], "f": 0, "t": 236, "d": [159], "a": 1 }, + { "px": [0,160], "src": [160,128], "f": 0, "t": 234, "d": [160], "a": 1 }, + { "px": [240,160], "src": [192,128], "f": 0, "t": 236, "d": [175], "a": 1 }, + { "px": [0,176], "src": [160,128], "f": 0, "t": 234, "d": [176], "a": 1 }, + { "px": [240,176], "src": [192,128], "f": 0, "t": 236, "d": [191], "a": 1 }, + { "px": [0,192], "src": [160,128], "f": 0, "t": 234, "d": [192], "a": 1 }, + { "px": [240,192], "src": [192,128], "f": 0, "t": 236, "d": [207], "a": 1 }, + { "px": [0,208], "src": [160,128], "f": 0, "t": 234, "d": [208], "a": 1 }, + { "px": [240,208], "src": [192,128], "f": 0, "t": 236, "d": [223], "a": 1 }, + { "px": [0,224], "src": [160,128], "f": 0, "t": 234, "d": [224], "a": 1 }, + { "px": [240,224], "src": [192,128], "f": 0, "t": 236, "d": [239], "a": 1 }, + { "px": [0,240], "src": [160,144], "f": 0, "t": 262, "d": [240], "a": 1 }, + { "px": [16,240], "src": [176,144], "f": 0, "t": 263, "d": [241], "a": 1 }, + { "px": [32,240], "src": [176,144], "f": 0, "t": 263, "d": [242], "a": 1 }, + { "px": [48,240], "src": [176,144], "f": 0, "t": 263, "d": [243], "a": 1 }, + { "px": [64,240], "src": [176,144], "f": 0, "t": 263, "d": [244], "a": 1 }, + { "px": [80,240], "src": [176,144], "f": 0, "t": 263, "d": [245], "a": 1 }, + { "px": [96,240], "src": [176,144], "f": 0, "t": 263, "d": [246], "a": 1 }, + { "px": [128,240], "src": [176,144], "f": 0, "t": 263, "d": [248], "a": 1 }, + { "px": [144,240], "src": [176,144], "f": 0, "t": 263, "d": [249], "a": 1 }, + { "px": [160,240], "src": [176,144], "f": 0, "t": 263, "d": [250], "a": 1 }, + { "px": [176,240], "src": [176,144], "f": 0, "t": 263, "d": [251], "a": 1 }, + { "px": [192,240], "src": [176,144], "f": 0, "t": 263, "d": [252], "a": 1 }, + { "px": [208,240], "src": [176,144], "f": 0, "t": 263, "d": [253], "a": 1 }, + { "px": [224,240], "src": [176,144], "f": 0, "t": 263, "d": [254], "a": 1 }, + { "px": [240,240], "src": [192,144], "f": 0, "t": 264, "d": [255], "a": 1 } + ], + "entityInstances": [] + }, + { + "__identifier": "Objects", + "__type": "Entities", + "__cWid": 16, + "__cHei": 16, + "__gridSize": 16, + "__opacity": 1, + "__pxTotalOffsetX": 0, + "__pxTotalOffsetY": 0, + "__tilesetDefUid": null, + "__tilesetRelPath": null, + "iid": "bc0fa1e0-b0a0-11ee-9c50-21dd3227d946", + "levelId": 21, + "layerDefUid": 3, + "pxOffsetX": 0, + "pxOffsetY": 0, + "visible": true, + "optionalRules": [], + "intGridCsv": [], + "autoLayerTiles": [], + "seed": 2273073, + "overrideTilesetUid": null, + "gridTiles": [], + "entityInstances": [ + { + "__identifier": "Sword", + "__grid": [8,8], + "__pivot": [0,0], + "__tags": [], + "__tile": { "tilesetUid": 1, "x": 128, "y": 144, "w": 16, "h": 16 }, + "__smartColor": "#E4A672", + "iid": "1aa46e70-b0a0-11ee-9c50-712775d86446", + "width": 16, + "height": 16, + "defUid": 11, + "px": [128,128], + "fieldInstances": [{ "__identifier": "attack", "__type": "Int", "__value": 50, "__tile": null, "defUid": 12, "realEditorValues": [] }], + "__worldX": 464, + "__worldY": -128 + }, + { + "__identifier": "PlayerStart", + "__grid": [7,14], + "__pivot": [0,0], + "__tags": [], + "__tile": { "tilesetUid": 8, "x": 0, "y": 0, "w": 16, "h": 16 }, + "__smartColor": "#BE2F2F", + "iid": "1e7e7450-b0a0-11ee-9c50-7d2d54e12fb8", + "width": 16, + "height": 16, + "defUid": 5, + "px": [112,224], + "fieldInstances": [ + { "__identifier": "Health", "__type": "Float", "__value": 100, "__tile": null, "defUid": 13, "realEditorValues": [] }, + { "__identifier": "Attack", "__type": "Float", "__value": 25, "__tile": null, "defUid": 14, "realEditorValues": [] } + ], + "__worldX": 448, + "__worldY": -32 + }, + { + "__identifier": "Door", + "__grid": [7,15], + "__pivot": [0,0], + "__tags": [], + "__tile": null, + "__smartColor": "#733E39", + "iid": "c5bc40f0-b0a0-11ee-9c50-d9161829661d", + "width": 16, + "height": 16, + "defUid": 20, + "px": [112,240], + "fieldInstances": [{ "__identifier": "scene", "__type": "String", "__value": "overworld", "__tile": null, "defUid": 22, "realEditorValues": [{ + "id": "V_String", + "params": ["overworld"] + }] }], + "__worldX": 448, + "__worldY": -16 + } + ] + }, + { + "__identifier": "Background", + "__type": "Tiles", + "__cWid": 16, + "__cHei": 16, + "__gridSize": 16, + "__opacity": 1, + "__pxTotalOffsetX": 0, + "__pxTotalOffsetY": 0, + "__tilesetDefUid": 1, + "__tilesetRelPath": "Solaria Demo Pack Update 03/Solaria Demo Pack Update 03/16x16/Tilesets/Solaria Demo Update 01.png", + "iid": "bc0fa1e1-b0a0-11ee-9c50-71014690f9ed", + "levelId": 21, + "layerDefUid": 2, + "pxOffsetX": 0, + "pxOffsetY": 0, + "visible": true, + "optionalRules": [], + "intGridCsv": [], + "autoLayerTiles": [], + "seed": 7471874, + "overrideTilesetUid": null, + "gridTiles": [ + { "px": [0,0], "src": [176,96], "f": 0, "t": 179, "d": [0], "a": 1 }, + { "px": [16,0], "src": [176,96], "f": 0, "t": 179, "d": [1], "a": 1 }, + { "px": [32,0], "src": [176,96], "f": 0, "t": 179, "d": [2], "a": 1 }, + { "px": [48,0], "src": [176,96], "f": 0, "t": 179, "d": [3], "a": 1 }, + { "px": [64,0], "src": [176,96], "f": 0, "t": 179, "d": [4], "a": 1 }, + { "px": [80,0], "src": [176,96], "f": 0, "t": 179, "d": [5], "a": 1 }, + { "px": [96,0], "src": [176,96], "f": 0, "t": 179, "d": [6], "a": 1 }, + { "px": [112,0], "src": [176,96], "f": 0, "t": 179, "d": [7], "a": 1 }, + { "px": [128,0], "src": [176,96], "f": 0, "t": 179, "d": [8], "a": 1 }, + { "px": [144,0], "src": [176,96], "f": 0, "t": 179, "d": [9], "a": 1 }, + { "px": [160,0], "src": [176,96], "f": 0, "t": 179, "d": [10], "a": 1 }, + { "px": [176,0], "src": [176,96], "f": 0, "t": 179, "d": [11], "a": 1 }, + { "px": [192,0], "src": [176,96], "f": 0, "t": 179, "d": [12], "a": 1 }, + { "px": [208,0], "src": [176,96], "f": 0, "t": 179, "d": [13], "a": 1 }, + { "px": [224,0], "src": [176,96], "f": 0, "t": 179, "d": [14], "a": 1 }, + { "px": [240,0], "src": [176,96], "f": 0, "t": 179, "d": [15], "a": 1 }, + { "px": [0,16], "src": [176,96], "f": 0, "t": 179, "d": [16], "a": 1 }, + { "px": [16,16], "src": [176,96], "f": 0, "t": 179, "d": [17], "a": 1 }, + { "px": [32,16], "src": [176,96], "f": 0, "t": 179, "d": [18], "a": 1 }, + { "px": [48,16], "src": [176,96], "f": 0, "t": 179, "d": [19], "a": 1 }, + { "px": [64,16], "src": [176,96], "f": 0, "t": 179, "d": [20], "a": 1 }, + { "px": [80,16], "src": [176,96], "f": 0, "t": 179, "d": [21], "a": 1 }, + { "px": [96,16], "src": [176,96], "f": 0, "t": 179, "d": [22], "a": 1 }, + { "px": [112,16], "src": [176,96], "f": 0, "t": 179, "d": [23], "a": 1 }, + { "px": [128,16], "src": [176,96], "f": 0, "t": 179, "d": [24], "a": 1 }, + { "px": [144,16], "src": [176,96], "f": 0, "t": 179, "d": [25], "a": 1 }, + { "px": [160,16], "src": [176,96], "f": 0, "t": 179, "d": [26], "a": 1 }, + { "px": [176,16], "src": [176,96], "f": 0, "t": 179, "d": [27], "a": 1 }, + { "px": [192,16], "src": [176,96], "f": 0, "t": 179, "d": [28], "a": 1 }, + { "px": [208,16], "src": [176,96], "f": 0, "t": 179, "d": [29], "a": 1 }, + { "px": [224,16], "src": [176,96], "f": 0, "t": 179, "d": [30], "a": 1 }, + { "px": [240,16], "src": [176,96], "f": 0, "t": 179, "d": [31], "a": 1 }, + { "px": [0,32], "src": [176,96], "f": 0, "t": 179, "d": [32], "a": 1 }, + { "px": [16,32], "src": [176,96], "f": 0, "t": 179, "d": [33], "a": 1 }, + { "px": [32,32], "src": [176,96], "f": 0, "t": 179, "d": [34], "a": 1 }, + { "px": [48,32], "src": [176,96], "f": 0, "t": 179, "d": [35], "a": 1 }, + { "px": [64,32], "src": [176,96], "f": 0, "t": 179, "d": [36], "a": 1 }, + { "px": [80,32], "src": [176,96], "f": 0, "t": 179, "d": [37], "a": 1 }, + { "px": [96,32], "src": [176,96], "f": 0, "t": 179, "d": [38], "a": 1 }, + { "px": [112,32], "src": [176,96], "f": 0, "t": 179, "d": [39], "a": 1 }, + { "px": [128,32], "src": [176,96], "f": 0, "t": 179, "d": [40], "a": 1 }, + { "px": [144,32], "src": [176,96], "f": 0, "t": 179, "d": [41], "a": 1 }, + { "px": [160,32], "src": [176,96], "f": 0, "t": 179, "d": [42], "a": 1 }, + { "px": [176,32], "src": [176,96], "f": 0, "t": 179, "d": [43], "a": 1 }, + { "px": [192,32], "src": [176,96], "f": 0, "t": 179, "d": [44], "a": 1 }, + { "px": [208,32], "src": [176,96], "f": 0, "t": 179, "d": [45], "a": 1 }, + { "px": [224,32], "src": [176,96], "f": 0, "t": 179, "d": [46], "a": 1 }, + { "px": [240,32], "src": [176,96], "f": 0, "t": 179, "d": [47], "a": 1 }, + { "px": [0,48], "src": [176,96], "f": 0, "t": 179, "d": [48], "a": 1 }, + { "px": [16,48], "src": [176,96], "f": 0, "t": 179, "d": [49], "a": 1 }, + { "px": [32,48], "src": [176,96], "f": 0, "t": 179, "d": [50], "a": 1 }, + { "px": [48,48], "src": [176,96], "f": 0, "t": 179, "d": [51], "a": 1 }, + { "px": [64,48], "src": [176,96], "f": 0, "t": 179, "d": [52], "a": 1 }, + { "px": [80,48], "src": [176,96], "f": 0, "t": 179, "d": [53], "a": 1 }, + { "px": [96,48], "src": [176,96], "f": 0, "t": 179, "d": [54], "a": 1 }, + { "px": [112,48], "src": [176,96], "f": 0, "t": 179, "d": [55], "a": 1 }, + { "px": [128,48], "src": [176,96], "f": 0, "t": 179, "d": [56], "a": 1 }, + { "px": [144,48], "src": [176,96], "f": 0, "t": 179, "d": [57], "a": 1 }, + { "px": [160,48], "src": [176,96], "f": 0, "t": 179, "d": [58], "a": 1 }, + { "px": [176,48], "src": [176,96], "f": 0, "t": 179, "d": [59], "a": 1 }, + { "px": [192,48], "src": [176,96], "f": 0, "t": 179, "d": [60], "a": 1 }, + { "px": [208,48], "src": [176,96], "f": 0, "t": 179, "d": [61], "a": 1 }, + { "px": [224,48], "src": [176,96], "f": 0, "t": 179, "d": [62], "a": 1 }, + { "px": [240,48], "src": [176,96], "f": 0, "t": 179, "d": [63], "a": 1 }, + { "px": [0,64], "src": [176,96], "f": 0, "t": 179, "d": [64], "a": 1 }, + { "px": [16,64], "src": [176,96], "f": 0, "t": 179, "d": [65], "a": 1 }, + { "px": [32,64], "src": [176,96], "f": 0, "t": 179, "d": [66], "a": 1 }, + { "px": [48,64], "src": [176,96], "f": 0, "t": 179, "d": [67], "a": 1 }, + { "px": [64,64], "src": [176,96], "f": 0, "t": 179, "d": [68], "a": 1 }, + { "px": [80,64], "src": [176,96], "f": 0, "t": 179, "d": [69], "a": 1 }, + { "px": [96,64], "src": [176,96], "f": 0, "t": 179, "d": [70], "a": 1 }, + { "px": [112,64], "src": [176,96], "f": 0, "t": 179, "d": [71], "a": 1 }, + { "px": [128,64], "src": [176,96], "f": 0, "t": 179, "d": [72], "a": 1 }, + { "px": [144,64], "src": [176,96], "f": 0, "t": 179, "d": [73], "a": 1 }, + { "px": [160,64], "src": [176,96], "f": 0, "t": 179, "d": [74], "a": 1 }, + { "px": [176,64], "src": [176,96], "f": 0, "t": 179, "d": [75], "a": 1 }, + { "px": [192,64], "src": [176,96], "f": 0, "t": 179, "d": [76], "a": 1 }, + { "px": [208,64], "src": [176,96], "f": 0, "t": 179, "d": [77], "a": 1 }, + { "px": [224,64], "src": [176,96], "f": 0, "t": 179, "d": [78], "a": 1 }, + { "px": [240,64], "src": [176,96], "f": 0, "t": 179, "d": [79], "a": 1 }, + { "px": [0,80], "src": [176,96], "f": 0, "t": 179, "d": [80], "a": 1 }, + { "px": [16,80], "src": [176,96], "f": 0, "t": 179, "d": [81], "a": 1 }, + { "px": [32,80], "src": [176,96], "f": 0, "t": 179, "d": [82], "a": 1 }, + { "px": [48,80], "src": [176,96], "f": 0, "t": 179, "d": [83], "a": 1 }, + { "px": [64,80], "src": [176,96], "f": 0, "t": 179, "d": [84], "a": 1 }, + { "px": [80,80], "src": [176,96], "f": 0, "t": 179, "d": [85], "a": 1 }, + { "px": [96,80], "src": [176,96], "f": 0, "t": 179, "d": [86], "a": 1 }, + { "px": [112,80], "src": [176,96], "f": 0, "t": 179, "d": [87], "a": 1 }, + { "px": [128,80], "src": [176,96], "f": 0, "t": 179, "d": [88], "a": 1 }, + { "px": [144,80], "src": [176,96], "f": 0, "t": 179, "d": [89], "a": 1 }, + { "px": [160,80], "src": [176,96], "f": 0, "t": 179, "d": [90], "a": 1 }, + { "px": [176,80], "src": [176,96], "f": 0, "t": 179, "d": [91], "a": 1 }, + { "px": [192,80], "src": [176,96], "f": 0, "t": 179, "d": [92], "a": 1 }, + { "px": [208,80], "src": [176,96], "f": 0, "t": 179, "d": [93], "a": 1 }, + { "px": [224,80], "src": [176,96], "f": 0, "t": 179, "d": [94], "a": 1 }, + { "px": [240,80], "src": [176,96], "f": 0, "t": 179, "d": [95], "a": 1 }, + { "px": [0,96], "src": [176,96], "f": 0, "t": 179, "d": [96], "a": 1 }, + { "px": [16,96], "src": [176,96], "f": 0, "t": 179, "d": [97], "a": 1 }, + { "px": [32,96], "src": [176,96], "f": 0, "t": 179, "d": [98], "a": 1 }, + { "px": [48,96], "src": [176,96], "f": 0, "t": 179, "d": [99], "a": 1 }, + { "px": [64,96], "src": [176,96], "f": 0, "t": 179, "d": [100], "a": 1 }, + { "px": [80,96], "src": [176,96], "f": 0, "t": 179, "d": [101], "a": 1 }, + { "px": [96,96], "src": [176,96], "f": 0, "t": 179, "d": [102], "a": 1 }, + { "px": [112,96], "src": [176,96], "f": 0, "t": 179, "d": [103], "a": 1 }, + { "px": [128,96], "src": [176,96], "f": 0, "t": 179, "d": [104], "a": 1 }, + { "px": [144,96], "src": [176,96], "f": 0, "t": 179, "d": [105], "a": 1 }, + { "px": [160,96], "src": [176,96], "f": 0, "t": 179, "d": [106], "a": 1 }, + { "px": [176,96], "src": [176,96], "f": 0, "t": 179, "d": [107], "a": 1 }, + { "px": [192,96], "src": [176,96], "f": 0, "t": 179, "d": [108], "a": 1 }, + { "px": [208,96], "src": [176,96], "f": 0, "t": 179, "d": [109], "a": 1 }, + { "px": [224,96], "src": [176,96], "f": 0, "t": 179, "d": [110], "a": 1 }, + { "px": [240,96], "src": [176,96], "f": 0, "t": 179, "d": [111], "a": 1 }, + { "px": [0,112], "src": [176,96], "f": 0, "t": 179, "d": [112], "a": 1 }, + { "px": [16,112], "src": [176,96], "f": 0, "t": 179, "d": [113], "a": 1 }, + { "px": [32,112], "src": [176,96], "f": 0, "t": 179, "d": [114], "a": 1 }, + { "px": [48,112], "src": [176,96], "f": 0, "t": 179, "d": [115], "a": 1 }, + { "px": [64,112], "src": [176,96], "f": 0, "t": 179, "d": [116], "a": 1 }, + { "px": [80,112], "src": [176,96], "f": 0, "t": 179, "d": [117], "a": 1 }, + { "px": [96,112], "src": [176,96], "f": 0, "t": 179, "d": [118], "a": 1 }, + { "px": [112,112], "src": [176,96], "f": 0, "t": 179, "d": [119], "a": 1 }, + { "px": [128,112], "src": [176,96], "f": 0, "t": 179, "d": [120], "a": 1 }, + { "px": [144,112], "src": [176,96], "f": 0, "t": 179, "d": [121], "a": 1 }, + { "px": [160,112], "src": [176,96], "f": 0, "t": 179, "d": [122], "a": 1 }, + { "px": [176,112], "src": [176,96], "f": 0, "t": 179, "d": [123], "a": 1 }, + { "px": [192,112], "src": [176,96], "f": 0, "t": 179, "d": [124], "a": 1 }, + { "px": [208,112], "src": [176,96], "f": 0, "t": 179, "d": [125], "a": 1 }, + { "px": [224,112], "src": [176,96], "f": 0, "t": 179, "d": [126], "a": 1 }, + { "px": [240,112], "src": [176,96], "f": 0, "t": 179, "d": [127], "a": 1 }, + { "px": [0,128], "src": [176,96], "f": 0, "t": 179, "d": [128], "a": 1 }, + { "px": [16,128], "src": [176,96], "f": 0, "t": 179, "d": [129], "a": 1 }, + { "px": [32,128], "src": [176,96], "f": 0, "t": 179, "d": [130], "a": 1 }, + { "px": [48,128], "src": [176,96], "f": 0, "t": 179, "d": [131], "a": 1 }, + { "px": [64,128], "src": [176,96], "f": 0, "t": 179, "d": [132], "a": 1 }, + { "px": [80,128], "src": [176,96], "f": 0, "t": 179, "d": [133], "a": 1 }, + { "px": [96,128], "src": [176,96], "f": 0, "t": 179, "d": [134], "a": 1 }, + { "px": [112,128], "src": [176,96], "f": 0, "t": 179, "d": [135], "a": 1 }, + { "px": [128,128], "src": [176,96], "f": 0, "t": 179, "d": [136], "a": 1 }, + { "px": [144,128], "src": [176,96], "f": 0, "t": 179, "d": [137], "a": 1 }, + { "px": [160,128], "src": [176,96], "f": 0, "t": 179, "d": [138], "a": 1 }, + { "px": [176,128], "src": [176,96], "f": 0, "t": 179, "d": [139], "a": 1 }, + { "px": [192,128], "src": [176,96], "f": 0, "t": 179, "d": [140], "a": 1 }, + { "px": [208,128], "src": [176,96], "f": 0, "t": 179, "d": [141], "a": 1 }, + { "px": [224,128], "src": [176,96], "f": 0, "t": 179, "d": [142], "a": 1 }, + { "px": [240,128], "src": [176,96], "f": 0, "t": 179, "d": [143], "a": 1 }, + { "px": [0,144], "src": [176,96], "f": 0, "t": 179, "d": [144], "a": 1 }, + { "px": [16,144], "src": [176,96], "f": 0, "t": 179, "d": [145], "a": 1 }, + { "px": [32,144], "src": [176,96], "f": 0, "t": 179, "d": [146], "a": 1 }, + { "px": [48,144], "src": [176,96], "f": 0, "t": 179, "d": [147], "a": 1 }, + { "px": [64,144], "src": [176,96], "f": 0, "t": 179, "d": [148], "a": 1 }, + { "px": [80,144], "src": [176,96], "f": 0, "t": 179, "d": [149], "a": 1 }, + { "px": [96,144], "src": [176,96], "f": 0, "t": 179, "d": [150], "a": 1 }, + { "px": [112,144], "src": [176,96], "f": 0, "t": 179, "d": [151], "a": 1 }, + { "px": [128,144], "src": [176,96], "f": 0, "t": 179, "d": [152], "a": 1 }, + { "px": [144,144], "src": [176,96], "f": 0, "t": 179, "d": [153], "a": 1 }, + { "px": [160,144], "src": [176,96], "f": 0, "t": 179, "d": [154], "a": 1 }, + { "px": [176,144], "src": [176,96], "f": 0, "t": 179, "d": [155], "a": 1 }, + { "px": [192,144], "src": [176,96], "f": 0, "t": 179, "d": [156], "a": 1 }, + { "px": [208,144], "src": [176,96], "f": 0, "t": 179, "d": [157], "a": 1 }, + { "px": [224,144], "src": [176,96], "f": 0, "t": 179, "d": [158], "a": 1 }, + { "px": [240,144], "src": [176,96], "f": 0, "t": 179, "d": [159], "a": 1 }, + { "px": [0,160], "src": [176,96], "f": 0, "t": 179, "d": [160], "a": 1 }, + { "px": [16,160], "src": [176,96], "f": 0, "t": 179, "d": [161], "a": 1 }, + { "px": [32,160], "src": [176,96], "f": 0, "t": 179, "d": [162], "a": 1 }, + { "px": [48,160], "src": [176,96], "f": 0, "t": 179, "d": [163], "a": 1 }, + { "px": [64,160], "src": [176,96], "f": 0, "t": 179, "d": [164], "a": 1 }, + { "px": [80,160], "src": [176,96], "f": 0, "t": 179, "d": [165], "a": 1 }, + { "px": [96,160], "src": [176,96], "f": 0, "t": 179, "d": [166], "a": 1 }, + { "px": [112,160], "src": [176,96], "f": 0, "t": 179, "d": [167], "a": 1 }, + { "px": [128,160], "src": [176,96], "f": 0, "t": 179, "d": [168], "a": 1 }, + { "px": [144,160], "src": [176,96], "f": 0, "t": 179, "d": [169], "a": 1 }, + { "px": [160,160], "src": [176,96], "f": 0, "t": 179, "d": [170], "a": 1 }, + { "px": [176,160], "src": [176,96], "f": 0, "t": 179, "d": [171], "a": 1 }, + { "px": [192,160], "src": [176,96], "f": 0, "t": 179, "d": [172], "a": 1 }, + { "px": [208,160], "src": [176,96], "f": 0, "t": 179, "d": [173], "a": 1 }, + { "px": [224,160], "src": [176,96], "f": 0, "t": 179, "d": [174], "a": 1 }, + { "px": [240,160], "src": [176,96], "f": 0, "t": 179, "d": [175], "a": 1 }, + { "px": [0,176], "src": [176,96], "f": 0, "t": 179, "d": [176], "a": 1 }, + { "px": [16,176], "src": [176,96], "f": 0, "t": 179, "d": [177], "a": 1 }, + { "px": [32,176], "src": [176,96], "f": 0, "t": 179, "d": [178], "a": 1 }, + { "px": [48,176], "src": [176,96], "f": 0, "t": 179, "d": [179], "a": 1 }, + { "px": [64,176], "src": [176,96], "f": 0, "t": 179, "d": [180], "a": 1 }, + { "px": [80,176], "src": [176,96], "f": 0, "t": 179, "d": [181], "a": 1 }, + { "px": [96,176], "src": [176,96], "f": 0, "t": 179, "d": [182], "a": 1 }, + { "px": [112,176], "src": [176,96], "f": 0, "t": 179, "d": [183], "a": 1 }, + { "px": [128,176], "src": [176,96], "f": 0, "t": 179, "d": [184], "a": 1 }, + { "px": [144,176], "src": [176,96], "f": 0, "t": 179, "d": [185], "a": 1 }, + { "px": [160,176], "src": [176,96], "f": 0, "t": 179, "d": [186], "a": 1 }, + { "px": [176,176], "src": [176,96], "f": 0, "t": 179, "d": [187], "a": 1 }, + { "px": [192,176], "src": [176,96], "f": 0, "t": 179, "d": [188], "a": 1 }, + { "px": [208,176], "src": [176,96], "f": 0, "t": 179, "d": [189], "a": 1 }, + { "px": [224,176], "src": [176,96], "f": 0, "t": 179, "d": [190], "a": 1 }, + { "px": [240,176], "src": [176,96], "f": 0, "t": 179, "d": [191], "a": 1 }, + { "px": [0,192], "src": [176,96], "f": 0, "t": 179, "d": [192], "a": 1 }, + { "px": [16,192], "src": [176,96], "f": 0, "t": 179, "d": [193], "a": 1 }, + { "px": [32,192], "src": [176,96], "f": 0, "t": 179, "d": [194], "a": 1 }, + { "px": [48,192], "src": [176,96], "f": 0, "t": 179, "d": [195], "a": 1 }, + { "px": [64,192], "src": [176,96], "f": 0, "t": 179, "d": [196], "a": 1 }, + { "px": [80,192], "src": [176,96], "f": 0, "t": 179, "d": [197], "a": 1 }, + { "px": [96,192], "src": [176,96], "f": 0, "t": 179, "d": [198], "a": 1 }, + { "px": [112,192], "src": [176,96], "f": 0, "t": 179, "d": [199], "a": 1 }, + { "px": [128,192], "src": [176,96], "f": 0, "t": 179, "d": [200], "a": 1 }, + { "px": [144,192], "src": [176,96], "f": 0, "t": 179, "d": [201], "a": 1 }, + { "px": [160,192], "src": [176,96], "f": 0, "t": 179, "d": [202], "a": 1 }, + { "px": [176,192], "src": [176,96], "f": 0, "t": 179, "d": [203], "a": 1 }, + { "px": [192,192], "src": [176,96], "f": 0, "t": 179, "d": [204], "a": 1 }, + { "px": [208,192], "src": [176,96], "f": 0, "t": 179, "d": [205], "a": 1 }, + { "px": [224,192], "src": [176,96], "f": 0, "t": 179, "d": [206], "a": 1 }, + { "px": [240,192], "src": [176,96], "f": 0, "t": 179, "d": [207], "a": 1 }, + { "px": [0,208], "src": [176,96], "f": 0, "t": 179, "d": [208], "a": 1 }, + { "px": [16,208], "src": [176,96], "f": 0, "t": 179, "d": [209], "a": 1 }, + { "px": [32,208], "src": [176,96], "f": 0, "t": 179, "d": [210], "a": 1 }, + { "px": [48,208], "src": [176,96], "f": 0, "t": 179, "d": [211], "a": 1 }, + { "px": [64,208], "src": [176,96], "f": 0, "t": 179, "d": [212], "a": 1 }, + { "px": [80,208], "src": [176,96], "f": 0, "t": 179, "d": [213], "a": 1 }, + { "px": [96,208], "src": [176,96], "f": 0, "t": 179, "d": [214], "a": 1 }, + { "px": [112,208], "src": [176,96], "f": 0, "t": 179, "d": [215], "a": 1 }, + { "px": [128,208], "src": [176,96], "f": 0, "t": 179, "d": [216], "a": 1 }, + { "px": [144,208], "src": [176,96], "f": 0, "t": 179, "d": [217], "a": 1 }, + { "px": [160,208], "src": [176,96], "f": 0, "t": 179, "d": [218], "a": 1 }, + { "px": [176,208], "src": [176,96], "f": 0, "t": 179, "d": [219], "a": 1 }, + { "px": [192,208], "src": [176,96], "f": 0, "t": 179, "d": [220], "a": 1 }, + { "px": [208,208], "src": [176,96], "f": 0, "t": 179, "d": [221], "a": 1 }, + { "px": [224,208], "src": [176,96], "f": 0, "t": 179, "d": [222], "a": 1 }, + { "px": [240,208], "src": [176,96], "f": 0, "t": 179, "d": [223], "a": 1 }, + { "px": [0,224], "src": [176,96], "f": 0, "t": 179, "d": [224], "a": 1 }, + { "px": [16,224], "src": [176,96], "f": 0, "t": 179, "d": [225], "a": 1 }, + { "px": [32,224], "src": [176,96], "f": 0, "t": 179, "d": [226], "a": 1 }, + { "px": [48,224], "src": [176,96], "f": 0, "t": 179, "d": [227], "a": 1 }, + { "px": [64,224], "src": [176,96], "f": 0, "t": 179, "d": [228], "a": 1 }, + { "px": [80,224], "src": [176,96], "f": 0, "t": 179, "d": [229], "a": 1 }, + { "px": [96,224], "src": [176,96], "f": 0, "t": 179, "d": [230], "a": 1 }, + { "px": [112,224], "src": [176,96], "f": 0, "t": 179, "d": [231], "a": 1 }, + { "px": [128,224], "src": [176,96], "f": 0, "t": 179, "d": [232], "a": 1 }, + { "px": [144,224], "src": [176,96], "f": 0, "t": 179, "d": [233], "a": 1 }, + { "px": [160,224], "src": [176,96], "f": 0, "t": 179, "d": [234], "a": 1 }, + { "px": [176,224], "src": [176,96], "f": 0, "t": 179, "d": [235], "a": 1 }, + { "px": [192,224], "src": [176,96], "f": 0, "t": 179, "d": [236], "a": 1 }, + { "px": [208,224], "src": [176,96], "f": 0, "t": 179, "d": [237], "a": 1 }, + { "px": [224,224], "src": [176,96], "f": 0, "t": 179, "d": [238], "a": 1 }, + { "px": [240,224], "src": [176,96], "f": 0, "t": 179, "d": [239], "a": 1 }, + { "px": [0,240], "src": [176,96], "f": 0, "t": 179, "d": [240], "a": 1 }, + { "px": [16,240], "src": [176,96], "f": 0, "t": 179, "d": [241], "a": 1 }, + { "px": [32,240], "src": [176,96], "f": 0, "t": 179, "d": [242], "a": 1 }, + { "px": [48,240], "src": [176,96], "f": 0, "t": 179, "d": [243], "a": 1 }, + { "px": [64,240], "src": [176,96], "f": 0, "t": 179, "d": [244], "a": 1 }, + { "px": [80,240], "src": [176,96], "f": 0, "t": 179, "d": [245], "a": 1 }, + { "px": [96,240], "src": [176,96], "f": 0, "t": 179, "d": [246], "a": 1 }, + { "px": [112,240], "src": [176,96], "f": 0, "t": 179, "d": [247], "a": 1 }, + { "px": [128,240], "src": [176,96], "f": 0, "t": 179, "d": [248], "a": 1 }, + { "px": [144,240], "src": [176,96], "f": 0, "t": 179, "d": [249], "a": 1 }, + { "px": [160,240], "src": [176,96], "f": 0, "t": 179, "d": [250], "a": 1 }, + { "px": [176,240], "src": [176,96], "f": 0, "t": 179, "d": [251], "a": 1 }, + { "px": [192,240], "src": [176,96], "f": 0, "t": 179, "d": [252], "a": 1 }, + { "px": [208,240], "src": [176,96], "f": 0, "t": 179, "d": [253], "a": 1 }, + { "px": [224,240], "src": [176,96], "f": 0, "t": 179, "d": [254], "a": 1 }, + { "px": [240,240], "src": [176,96], "f": 0, "t": 179, "d": [255], "a": 1 } + ], + "entityInstances": [] + } + ], + "__neighbours": [{ "levelIid": "471aa8b0-b0a0-11ee-83ad-197e8057ca90", "dir": "s" }] +} \ No newline at end of file diff --git a/Level_0.076f9bf4.ldtkl b/Level_0.4121d29c.ldtkl similarity index 97% rename from Level_0.076f9bf4.ldtkl rename to Level_0.4121d29c.ldtkl index bfdbcc4..a357f73 100644 --- a/Level_0.076f9bf4.ldtkl +++ b/Level_0.4121d29c.ldtkl @@ -181,25 +181,6 @@ "__worldX": 192, "__worldY": 176 }, - { - "__identifier": "PlayerStart", - "__grid": [4,9], - "__pivot": [0,0], - "__tags": [], - "__tile": { "tilesetUid": 8, "x": 0, "y": 0, "w": 16, "h": 16 }, - "__smartColor": "#BE2F2F", - "iid": "638cc210-6280-11ee-bc44-cb342b86cd82", - "width": 16, - "height": 16, - "defUid": 5, - "px": [64,144], - "fieldInstances": [ - { "__identifier": "Health", "__type": "Float", "__value": 100, "__tile": null, "defUid": 13, "realEditorValues": [] }, - { "__identifier": "Attack", "__type": "Float", "__value": 25, "__tile": null, "defUid": 14, "realEditorValues": [] } - ], - "__worldX": 64, - "__worldY": 144 - }, { "__identifier": "Sword", "__grid": [11,8], @@ -233,7 +214,7 @@ "id": "V_Bool", "params": [ true ] }] }, - { "__identifier": "zoom", "__type": "Float", "__value": 2, "__tile": null, "defUid": 18, "realEditorValues": [] } + { "__identifier": "zoom", "__type": "Float", "__value": 2, "__tile": null, "defUid": 18, "realEditorValues": [{ "id": "V_Float", "params": [2] }] } ], "__worldX": 104, "__worldY": 136 diff --git a/Level_1.fb97a422.ldtkl b/Level_1.0859d067.ldtkl similarity index 95% rename from Level_1.fb97a422.ldtkl rename to Level_1.0859d067.ldtkl index 5cbc5cb..22b89d3 100644 --- a/Level_1.fb97a422.ldtkl +++ b/Level_1.0859d067.ldtkl @@ -54,8 +54,8 @@ 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0, + 1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1, 1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0, @@ -147,7 +147,6 @@ { "px": [128,64], "src": [176,64], "f": 0, "t": 123, "d": [72], "a": 1 }, { "px": [144,64], "src": [176,64], "f": 0, "t": 123, "d": [73], "a": 1 }, { "px": [160,64], "src": [176,64], "f": 0, "t": 123, "d": [74], "a": 1 }, - { "px": [176,64], "src": [176,64], "f": 0, "t": 123, "d": [75], "a": 1 }, { "px": [192,64], "src": [176,64], "f": 0, "t": 123, "d": [76], "a": 1 }, { "px": [208,64], "src": [176,64], "f": 0, "t": 123, "d": [77], "a": 1 }, { "px": [224,64], "src": [176,64], "f": 0, "t": 123, "d": [78], "a": 1 }, @@ -270,6 +269,44 @@ "fieldInstances": [], "__worldX": 464, "__worldY": 112 + }, + { + "__identifier": "Door", + "__grid": [11,4], + "__pivot": [0,0], + "__tags": [], + "__tile": null, + "__smartColor": "#733E39", + "iid": "a9b65de0-b0a0-11ee-9c50-c3bafa55d925", + "width": 16, + "height": 16, + "defUid": 20, + "px": [176,64], + "fieldInstances": [{ "__identifier": "scene", "__type": "String", "__value": "house", "__tile": null, "defUid": 22, "realEditorValues": [{ + "id": "V_String", + "params": ["house"] + }] }], + "__worldX": 432, + "__worldY": 64 + }, + { + "__identifier": "PlayerStart", + "__grid": [11,6], + "__pivot": [0,0], + "__tags": [], + "__tile": { "tilesetUid": 8, "x": 0, "y": 0, "w": 16, "h": 16 }, + "__smartColor": "#BE2F2F", + "iid": "889ccc60-b0a0-11ee-9c50-fb8c75d80a06", + "width": 16, + "height": 16, + "defUid": 5, + "px": [176,96], + "fieldInstances": [ + { "__identifier": "Health", "__type": "Float", "__value": 100, "__tile": null, "defUid": 13, "realEditorValues": [] }, + { "__identifier": "Attack", "__type": "Float", "__value": 25, "__tile": null, "defUid": 14, "realEditorValues": [] } + ], + "__worldX": 432, + "__worldY": 96 } ] }, @@ -357,6 +394,7 @@ { "px": [128,64], "src": [96,0], "f": 0, "t": 6, "d": [72], "a": 1 }, { "px": [144,64], "src": [80,0], "f": 0, "t": 5, "d": [73], "a": 1 }, { "px": [160,64], "src": [96,0], "f": 0, "t": 6, "d": [74], "a": 1 }, + { "px": [176,64], "src": [160,80], "f": 0, "t": 150, "d": [75], "a": 1 }, { "px": [0,80], "src": [80,96], "f": 0, "t": 173, "d": [80], "a": 1 }, { "px": [16,80], "src": [80,96], "f": 0, "t": 173, "d": [81], "a": 1 }, { "px": [32,80], "src": [0,112], "f": 0, "t": 196, "d": [82], "a": 1 }, @@ -537,5 +575,5 @@ "entityInstances": [] } ], - "__neighbours": [{ "levelIid": "db4d09b0-6280-11ee-bc44-1b84534fe012", "dir": "w" }] + "__neighbours": [ { "levelIid": "db4d09b0-6280-11ee-bc44-1b84534fe012", "dir": "w" }, { "levelIid": "bc0f7ad0-b0a0-11ee-9c50-2597384ac3cd", "dir": "n" } ] } \ No newline at end of file diff --git a/index.c2a0b4ac.js b/index.a78842eb.js similarity index 70% rename from index.c2a0b4ac.js rename to index.a78842eb.js index f15b8c1..87a3df1 100644 --- a/index.c2a0b4ac.js +++ b/index.a78842eb.js @@ -1,5 +1,5 @@ -let t;function e(t,e,i,s){Object.defineProperty(t,e,{get:i,set:s,enumerable:!0,configurable:!0})}function i(t){return t&&t.__esModule?t.default:t}var s=globalThis,r={},n={},o=s.parcelRequire4b3c;null==o&&((o=function(t){if(t in r)return r[t].exports;if(t in n){var e=n[t];delete n[t];var i={id:t,exports:{}};return r[t]=i,e.call(i.exports,i,i.exports),i.exports}var s=Error("Cannot find module '"+t+"'");throw s.code="MODULE_NOT_FOUND",s}).register=function(t,e){n[t]=e},s.parcelRequire4b3c=o),(0,o.register)("3MXpL",function(t,i){e(t.exports,"ActionCompleteEvent",()=>a),e(t.exports,"ActionContext",()=>l),e(t.exports,"ActionQueue",()=>h),e(t.exports,"ActionSequence",()=>d),e(t.exports,"ActionStartEvent",()=>c),e(t.exports,"ActionsComponent",()=>u),e(t.exports,"ActionsSystem",()=>p),e(t.exports,"ActivateEvent",()=>g),e(t.exports,"Actor",()=>_),e(t.exports,"AddedComponent",()=>f),e(t.exports,"AffineMatrix",()=>m),e(t.exports,"Animation",()=>v),e(t.exports,"AnimationDirection",()=>y),e(t.exports,"AnimationEvents",()=>x),e(t.exports,"AnimationStrategy",()=>w),e(t.exports,"ArcadeSolver",()=>b),e(t.exports,"AudioContextFactory",()=>C),e(t.exports,"Axes",()=>T),e(t.exports,"Axis",()=>S),e(t.exports,"BaseAlign",()=>A),e(t.exports,"Blink",()=>E),e(t.exports,"BodyComponent",()=>P),e(t.exports,"BoundingBox",()=>I),e(t.exports,"BroadphaseStrategy",()=>k),e(t.exports,"BrowserComponent",()=>D),e(t.exports,"BrowserEvents",()=>R),e(t.exports,"Buttons",()=>F),e(t.exports,"Camera",()=>B),e(t.exports,"CameraEvents",()=>M),e(t.exports,"Canvas",()=>L),e(t.exports,"Circle",()=>z),e(t.exports,"CircleCollider",()=>O),e(t.exports,"Clock",()=>U),e(t.exports,"ClosestLine",()=>N),e(t.exports,"ClosestLineJumpTable",()=>Z),e(t.exports,"Collider",()=>H),e(t.exports,"ColliderComponent",()=>V),e(t.exports,"CollisionContact",()=>W),e(t.exports,"CollisionEndEvent",()=>G),e(t.exports,"CollisionGroup",()=>j),e(t.exports,"CollisionGroupManager",()=>q),e(t.exports,"CollisionJumpTable",()=>X),e(t.exports,"CollisionPostSolveEvent",()=>$),e(t.exports,"CollisionPreSolveEvent",()=>K),e(t.exports,"CollisionStartEvent",()=>Y),e(t.exports,"CollisionSystem",()=>Q),e(t.exports,"CollisionType",()=>J),e(t.exports,"Color",()=>tt),e(t.exports,"ColorBlindFlags",()=>te),e(t.exports,"ColorBlindnessMode",()=>ti),e(t.exports,"ColorBlindnessPostProcessor",()=>ts),e(t.exports,"Component",()=>tr),e(t.exports,"CompositeCollider",()=>tn),e(t.exports,"Configurable",()=>to),e(t.exports,"ConsoleAppender",()=>ta),e(t.exports,"ContactConstraintPoint",()=>tl),e(t.exports,"ContactEndEvent",()=>th),e(t.exports,"ContactSolveBias",()=>td),e(t.exports,"ContactStartEvent",()=>tc),e(t.exports,"CoordPlane",()=>tu),e(t.exports,"CrossFade",()=>tp),e(t.exports,"DeactivateEvent",()=>tg),e(t.exports,"Debug",()=>t_),e(t.exports,"DebugConfig",()=>tf),e(t.exports,"DebugGraphicsComponent",()=>tm),e(t.exports,"DebugSystem",()=>tv),e(t.exports,"DebugText",()=>ty),e(t.exports,"DefaultAntialiasOptions",()=>tx),e(t.exports,"DefaultLoader",()=>tw),e(t.exports,"DefaultPhysicsConfig",()=>tb),e(t.exports,"DefaultPixelArtOptions",()=>tC),e(t.exports,"DegreeOfFreedom",()=>tT),e(t.exports,"Delay",()=>tS),e(t.exports,"DeprecatedStaticToConfig",()=>tA),e(t.exports,"Detector",()=>tE),e(t.exports,"Die",()=>tP),e(t.exports,"Direction",()=>tI),e(t.exports,"Director",()=>tk),e(t.exports,"DirectorEvents",()=>tD),e(t.exports,"DisplayMode",()=>tR),e(t.exports,"DynamicTree",()=>tF),e(t.exports,"DynamicTreeCollisionProcessor",()=>tB),e(t.exports,"EX_VERSION",()=>tM),e(t.exports,"EaseBy",()=>tL),e(t.exports,"EaseTo",()=>tz),e(t.exports,"EasingFunctions",()=>tO),e(t.exports,"EdgeCollider",()=>tU),e(t.exports,"ElasticToActorStrategy",()=>tN),e(t.exports,"EmitterType",()=>tZ),e(t.exports,"Engine",()=>tH),e(t.exports,"EngineEvents",()=>tV),e(t.exports,"EnterTriggerEvent",()=>tW),e(t.exports,"EnterViewPortEvent",()=>tG),e(t.exports,"Entity",()=>tj),e(t.exports,"EntityEvents",()=>tq),e(t.exports,"EntityManager",()=>tX),e(t.exports,"EventDispatcher",()=>t$),e(t.exports,"EventEmitter",()=>tK),e(t.exports,"EventTypes",()=>tY),e(t.exports,"Events",()=>tQ),e(t.exports,"ExResponse",()=>tJ),e(t.exports,"ExcaliburGraphicsContext2DCanvas",()=>t0),e(t.exports,"ExcaliburGraphicsContextWebGL",()=>t1),e(t.exports,"ExitTriggerEvent",()=>t2),e(t.exports,"ExitViewPortEvent",()=>t5),e(t.exports,"Fade",()=>t4),e(t.exports,"FadeInOut",()=>t3),e(t.exports,"Flags",()=>t9),e(t.exports,"Follow",()=>t6),e(t.exports,"Font",()=>t7),e(t.exports,"FontCache",()=>t8),e(t.exports,"FontSource",()=>et),e(t.exports,"FontStyle",()=>ee),e(t.exports,"FontUnit",()=>ei),e(t.exports,"FpsSampler",()=>es),e(t.exports,"FrameStats",()=>er),e(t.exports,"Future",()=>en),e(t.exports,"GameEvent",()=>eo),e(t.exports,"GameStartEvent",()=>ea),e(t.exports,"GameStopEvent",()=>el),e(t.exports,"Gamepad",()=>eh),e(t.exports,"GamepadAxisEvent",()=>ed),e(t.exports,"GamepadButtonEvent",()=>ec),e(t.exports,"GamepadConnectEvent",()=>eu),e(t.exports,"GamepadDisconnectEvent",()=>ep),e(t.exports,"Gamepads",()=>eg),e(t.exports,"Gif",()=>e_),e(t.exports,"GlobalCoordinates",()=>ef),e(t.exports,"Graphic",()=>em),e(t.exports,"GraphicsComponent",()=>ev),e(t.exports,"GraphicsGroup",()=>ey),e(t.exports,"GraphicsSystem",()=>ex),e(t.exports,"HiddenEvent",()=>ew),e(t.exports,"HorizontalFirst",()=>eb),e(t.exports,"ImageFiltering",()=>eC),e(t.exports,"ImageSource",()=>eT),e(t.exports,"InitializeEvent",()=>eS),e(t.exports,"Input",()=>eA),e(t.exports,"InputHost",()=>eE),e(t.exports,"InputMapper",()=>eP),e(t.exports,"Integrator",()=>eI),e(t.exports,"IsometricEntityComponent",()=>ek),e(t.exports,"IsometricEntitySystem",()=>eD),e(t.exports,"IsometricMap",()=>eR),e(t.exports,"IsometricTile",()=>eF),e(t.exports,"KeyEvent",()=>eB),e(t.exports,"Keyboard",()=>eM),e(t.exports,"Keys",()=>eL),e(t.exports,"KillEvent",()=>ez),e(t.exports,"Label",()=>eO),e(t.exports,"LimitCameraBoundsStrategy",()=>eU),e(t.exports,"Line",()=>eN),e(t.exports,"LineSegment",()=>eZ),e(t.exports,"Loader",()=>eH),e(t.exports,"LoaderEvents",()=>eV),e(t.exports,"LockCameraToActorAxisStrategy",()=>eW),e(t.exports,"LockCameraToActorStrategy",()=>eG),e(t.exports,"LogLevel",()=>ej),e(t.exports,"Logger",()=>eq),e(t.exports,"Material",()=>eX),e(t.exports,"Matrix",()=>e$),e(t.exports,"MatrixLocations",()=>eK),e(t.exports,"MediaEvent",()=>eY),e(t.exports,"Meet",()=>eQ),e(t.exports,"MotionComponent",()=>eJ),e(t.exports,"MotionSystem",()=>e0),e(t.exports,"MoveBy",()=>e1),e(t.exports,"MoveTo",()=>e2),e(t.exports,"NativePointerButton",()=>e5),e(t.exports,"NativeSoundEvent",()=>e4),e(t.exports,"NativeSoundProcessedEvent",()=>e3),e(t.exports,"None",()=>e9),e(t.exports,"Observable",()=>e6),e(t.exports,"OffscreenSystem",()=>e7),e(t.exports,"Pair",()=>e8),e(t.exports,"ParallaxComponent",()=>it),e(t.exports,"ParallelActions",()=>ie),e(t.exports,"ParseGif",()=>ii),e(t.exports,"Particle",()=>is),e(t.exports,"ParticleEmitter",()=>ir),e(t.exports,"ParticleTransform",()=>io),e(t.exports,"Physics",()=>ia),e(t.exports,"PhysicsStats",()=>il),e(t.exports,"PhysicsWorld",()=>ih),e(t.exports,"PointerAbstraction",()=>id),e(t.exports,"PointerButton",()=>ic),e(t.exports,"PointerComponent",()=>iu),e(t.exports,"PointerEvent",()=>ip),e(t.exports,"PointerEventReceiver",()=>ig),e(t.exports,"PointerScope",()=>i_),e(t.exports,"PointerSystem",()=>im),e(t.exports,"PointerType",()=>iv),e(t.exports,"Polygon",()=>iy),e(t.exports,"PolygonCollider",()=>ix),e(t.exports,"Pool",()=>iw),e(t.exports,"PostCollisionEvent",()=>ib),e(t.exports,"PostDebugDrawEvent",()=>iC),e(t.exports,"PostDrawEvent",()=>iT),e(t.exports,"PostFrameEvent",()=>iS),e(t.exports,"PostKillEvent",()=>iA),e(t.exports,"PostTransformDrawEvent",()=>iE),e(t.exports,"PostUpdateEvent",()=>iP),e(t.exports,"PreCollisionEvent",()=>iI),e(t.exports,"PreDebugDrawEvent",()=>ik),e(t.exports,"PreDrawEvent",()=>iD),e(t.exports,"PreFrameEvent",()=>iR),e(t.exports,"PreKillEvent",()=>iF),e(t.exports,"PreLoadEvent",()=>iB),e(t.exports,"PreTransformDrawEvent",()=>iM),e(t.exports,"PreUpdateEvent",()=>iL),e(t.exports,"Projection",()=>iz),e(t.exports,"QuadIndexBuffer",()=>iO),e(t.exports,"QuadTree",()=>iU),e(t.exports,"Query",()=>iN),e(t.exports,"QueryManager",()=>iZ),e(t.exports,"RadiusAroundActorStrategy",()=>iH),e(t.exports,"Random",()=>iV),e(t.exports,"Raster",()=>iW),e(t.exports,"Ray",()=>iG),e(t.exports,"RealisticSolver",()=>ij),e(t.exports,"Rectangle",()=>iq),e(t.exports,"RemovedComponent",()=>iX),e(t.exports,"Repeat",()=>i$),e(t.exports,"RepeatForever",()=>iK),e(t.exports,"Resolution",()=>iY),e(t.exports,"Resource",()=>iQ),e(t.exports,"ResourceEvents",()=>iJ),e(t.exports,"RotateBy",()=>i0),e(t.exports,"RotateTo",()=>i1),e(t.exports,"RotationType",()=>i2),e(t.exports,"ScaleBy",()=>i5),e(t.exports,"ScaleTo",()=>i4),e(t.exports,"Scene",()=>i3),e(t.exports,"SceneEvents",()=>i9),e(t.exports,"Screen",()=>i6),e(t.exports,"ScreenAppender",()=>i7),e(t.exports,"ScreenElement",()=>i8),e(t.exports,"ScreenEvents",()=>st),e(t.exports,"ScreenShader",()=>se),e(t.exports,"ScrollPreventionMode",()=>si),e(t.exports,"Semaphore",()=>ss),e(t.exports,"Shader",()=>sr),e(t.exports,"Shape",()=>sn),e(t.exports,"Side",()=>so),e(t.exports,"SolverStrategy",()=>sa),e(t.exports,"Sound",()=>sl),e(t.exports,"SoundEvents",()=>sh),e(t.exports,"Sprite",()=>sd),e(t.exports,"SpriteFont",()=>sc),e(t.exports,"SpriteSheet",()=>su),e(t.exports,"StandardClock",()=>sp),e(t.exports,"StateMachine",()=>sg),e(t.exports,"StrategyContainer",()=>s_),e(t.exports,"Stream",()=>sf),e(t.exports,"System",()=>sm),e(t.exports,"SystemManager",()=>sv),e(t.exports,"SystemPriority",()=>sy),e(t.exports,"SystemType",()=>sx),e(t.exports,"TagQuery",()=>sw),e(t.exports,"TestClock",()=>sb),e(t.exports,"Text",()=>sC),e(t.exports,"TextAlign",()=>sT),e(t.exports,"TextureLoader",()=>sS),e(t.exports,"Tile",()=>sA),e(t.exports,"TileMap",()=>sE),e(t.exports,"TileMapEvents",()=>sP),e(t.exports,"Timer",()=>sI),e(t.exports,"Toaster",()=>sk),e(t.exports,"Transform",()=>sD),e(t.exports,"TransformComponent",()=>sR),e(t.exports,"Transition",()=>sF),e(t.exports,"TreeNode",()=>sB),e(t.exports,"Trigger",()=>sM),e(t.exports,"TriggerEvents",()=>sL),e(t.exports,"TwoPI",()=>sz),e(t.exports,"Util",()=>sO),e(t.exports,"Vector",()=>sU),e(t.exports,"VectorView",()=>sN),e(t.exports,"VertexBuffer",()=>sZ),e(t.exports,"VertexLayout",()=>sH),e(t.exports,"VerticalFirst",()=>sV),e(t.exports,"VisibleEvent",()=>sW),e(t.exports,"WebAudio",()=>sG),e(t.exports,"WebAudioInstance",()=>sj),e(t.exports,"WheelDeltaMode",()=>sq),e(t.exports,"WheelEvent",()=>sX),e(t.exports,"World",()=>s$),e(t.exports,"canonicalizeAngle",()=>sK),e(t.exports,"clamp",()=>sY),e(t.exports,"coroutine",()=>sQ),e(t.exports,"createId",()=>sJ),e(t.exports,"frac",()=>s0),e(t.exports,"hasGraphicsTick",()=>s1),e(t.exports,"hasOnInitialize",()=>s2),e(t.exports,"hasOnPostUpdate",()=>s5),e(t.exports,"hasOnPreUpdate",()=>s4),e(t.exports,"hasPostDraw",()=>s3),e(t.exports,"hasPreDraw",()=>s9),e(t.exports,"has_initialize",()=>s6),e(t.exports,"has_postupdate",()=>s7),e(t.exports,"has_preupdate",()=>s8),e(t.exports,"isAddedComponent",()=>rt),e(t.exports,"isComponentCtor",()=>re),e(t.exports,"isLoaderConstructor",()=>ri),e(t.exports,"isRemovedComponent",()=>rs),e(t.exports,"isSceneConstructor",()=>rr),e(t.exports,"isScreenElement",()=>rn),e(t.exports,"isSystemConstructor",()=>ro),e(t.exports,"maxMessages",()=>ra),e(t.exports,"obsolete",()=>rl),e(t.exports,"pixelSnapEpsilon",()=>rh),e(t.exports,"randomInRange",()=>rd),e(t.exports,"randomIntInRange",()=>rc),e(t.exports,"range",()=>ru),e(t.exports,"resetObsoleteCounter",()=>rp),e(t.exports,"sign",()=>rg),e(t.exports,"toDegrees",()=>r_),e(t.exports,"toRadians",()=>rf),e(t.exports,"vec",()=>rm),e(t.exports,"webgl",()=>rv);/*! - * excalibur - 0.29.0 - 2024-2-20 +let t;function e(t,e,i,s){Object.defineProperty(t,e,{get:i,set:s,enumerable:!0,configurable:!0})}function i(t){return t&&t.__esModule?t.default:t}var s=globalThis,r={},n={},o=s.parcelRequire4b3c;null==o&&((o=function(t){if(t in r)return r[t].exports;if(t in n){var e=n[t];delete n[t];var i={id:t,exports:{}};return r[t]=i,e.call(i.exports,i,i.exports),i.exports}var s=Error("Cannot find module '"+t+"'");throw s.code="MODULE_NOT_FOUND",s}).register=function(t,e){n[t]=e},s.parcelRequire4b3c=o),(0,o.register)("3MXpL",function(t,i){e(t.exports,"ActionCompleteEvent",()=>a),e(t.exports,"ActionContext",()=>l),e(t.exports,"ActionQueue",()=>h),e(t.exports,"ActionSequence",()=>d),e(t.exports,"ActionStartEvent",()=>c),e(t.exports,"ActionsComponent",()=>u),e(t.exports,"ActionsSystem",()=>p),e(t.exports,"ActivateEvent",()=>g),e(t.exports,"Actor",()=>_),e(t.exports,"AddedComponent",()=>f),e(t.exports,"AffineMatrix",()=>m),e(t.exports,"Animation",()=>v),e(t.exports,"AnimationDirection",()=>y),e(t.exports,"AnimationEvents",()=>x),e(t.exports,"AnimationStrategy",()=>w),e(t.exports,"ArcadeSolver",()=>b),e(t.exports,"AudioContextFactory",()=>C),e(t.exports,"Axes",()=>T),e(t.exports,"Axis",()=>S),e(t.exports,"BaseAlign",()=>A),e(t.exports,"Blink",()=>E),e(t.exports,"BodyComponent",()=>P),e(t.exports,"BoundingBox",()=>I),e(t.exports,"BroadphaseStrategy",()=>k),e(t.exports,"BrowserComponent",()=>D),e(t.exports,"BrowserEvents",()=>R),e(t.exports,"Buttons",()=>F),e(t.exports,"Camera",()=>B),e(t.exports,"CameraEvents",()=>L),e(t.exports,"Canvas",()=>M),e(t.exports,"Circle",()=>z),e(t.exports,"CircleCollider",()=>O),e(t.exports,"Clock",()=>U),e(t.exports,"ClosestLine",()=>N),e(t.exports,"ClosestLineJumpTable",()=>Z),e(t.exports,"Collider",()=>H),e(t.exports,"ColliderComponent",()=>V),e(t.exports,"CollisionContact",()=>W),e(t.exports,"CollisionEndEvent",()=>G),e(t.exports,"CollisionGroup",()=>j),e(t.exports,"CollisionGroupManager",()=>q),e(t.exports,"CollisionJumpTable",()=>X),e(t.exports,"CollisionPostSolveEvent",()=>$),e(t.exports,"CollisionPreSolveEvent",()=>K),e(t.exports,"CollisionStartEvent",()=>Y),e(t.exports,"CollisionSystem",()=>Q),e(t.exports,"CollisionType",()=>J),e(t.exports,"Color",()=>tt),e(t.exports,"ColorBlindFlags",()=>te),e(t.exports,"ColorBlindnessMode",()=>ti),e(t.exports,"ColorBlindnessPostProcessor",()=>ts),e(t.exports,"Component",()=>tr),e(t.exports,"CompositeCollider",()=>tn),e(t.exports,"Configurable",()=>to),e(t.exports,"ConsoleAppender",()=>ta),e(t.exports,"ContactConstraintPoint",()=>tl),e(t.exports,"ContactEndEvent",()=>th),e(t.exports,"ContactSolveBias",()=>td),e(t.exports,"ContactStartEvent",()=>tc),e(t.exports,"CoordPlane",()=>tu),e(t.exports,"CrossFade",()=>tp),e(t.exports,"DeactivateEvent",()=>tg),e(t.exports,"Debug",()=>t_),e(t.exports,"DebugConfig",()=>tf),e(t.exports,"DebugGraphicsComponent",()=>tm),e(t.exports,"DebugSystem",()=>tv),e(t.exports,"DebugText",()=>ty),e(t.exports,"DefaultAntialiasOptions",()=>tx),e(t.exports,"DefaultLoader",()=>tw),e(t.exports,"DefaultPhysicsConfig",()=>tb),e(t.exports,"DefaultPixelArtOptions",()=>tC),e(t.exports,"DegreeOfFreedom",()=>tT),e(t.exports,"Delay",()=>tS),e(t.exports,"DeprecatedStaticToConfig",()=>tA),e(t.exports,"Detector",()=>tE),e(t.exports,"Die",()=>tP),e(t.exports,"Direction",()=>tI),e(t.exports,"Director",()=>tk),e(t.exports,"DirectorEvents",()=>tD),e(t.exports,"DisplayMode",()=>tR),e(t.exports,"DynamicTree",()=>tF),e(t.exports,"DynamicTreeCollisionProcessor",()=>tB),e(t.exports,"EX_VERSION",()=>tL),e(t.exports,"EaseBy",()=>tM),e(t.exports,"EaseTo",()=>tz),e(t.exports,"EasingFunctions",()=>tO),e(t.exports,"EdgeCollider",()=>tU),e(t.exports,"ElasticToActorStrategy",()=>tN),e(t.exports,"EmitterType",()=>tZ),e(t.exports,"Engine",()=>tH),e(t.exports,"EngineEvents",()=>tV),e(t.exports,"EnterTriggerEvent",()=>tW),e(t.exports,"EnterViewPortEvent",()=>tG),e(t.exports,"Entity",()=>tj),e(t.exports,"EntityEvents",()=>tq),e(t.exports,"EntityManager",()=>tX),e(t.exports,"EventDispatcher",()=>t$),e(t.exports,"EventEmitter",()=>tK),e(t.exports,"EventTypes",()=>tY),e(t.exports,"Events",()=>tQ),e(t.exports,"ExResponse",()=>tJ),e(t.exports,"ExcaliburGraphicsContext2DCanvas",()=>t0),e(t.exports,"ExcaliburGraphicsContextWebGL",()=>t1),e(t.exports,"ExitTriggerEvent",()=>t2),e(t.exports,"ExitViewPortEvent",()=>t5),e(t.exports,"Fade",()=>t4),e(t.exports,"FadeInOut",()=>t3),e(t.exports,"Flags",()=>t9),e(t.exports,"Follow",()=>t6),e(t.exports,"Font",()=>t7),e(t.exports,"FontCache",()=>t8),e(t.exports,"FontSource",()=>et),e(t.exports,"FontStyle",()=>ee),e(t.exports,"FontUnit",()=>ei),e(t.exports,"FpsSampler",()=>es),e(t.exports,"FrameStats",()=>er),e(t.exports,"Future",()=>en),e(t.exports,"GameEvent",()=>eo),e(t.exports,"GameStartEvent",()=>ea),e(t.exports,"GameStopEvent",()=>el),e(t.exports,"Gamepad",()=>eh),e(t.exports,"GamepadAxisEvent",()=>ed),e(t.exports,"GamepadButtonEvent",()=>ec),e(t.exports,"GamepadConnectEvent",()=>eu),e(t.exports,"GamepadDisconnectEvent",()=>ep),e(t.exports,"Gamepads",()=>eg),e(t.exports,"Gif",()=>e_),e(t.exports,"GlobalCoordinates",()=>ef),e(t.exports,"Graphic",()=>em),e(t.exports,"GraphicsComponent",()=>ev),e(t.exports,"GraphicsGroup",()=>ey),e(t.exports,"GraphicsSystem",()=>ex),e(t.exports,"HiddenEvent",()=>ew),e(t.exports,"HorizontalFirst",()=>eb),e(t.exports,"ImageFiltering",()=>eC),e(t.exports,"ImageSource",()=>eT),e(t.exports,"InitializeEvent",()=>eS),e(t.exports,"Input",()=>eA),e(t.exports,"InputHost",()=>eE),e(t.exports,"InputMapper",()=>eP),e(t.exports,"Integrator",()=>eI),e(t.exports,"IsometricEntityComponent",()=>ek),e(t.exports,"IsometricEntitySystem",()=>eD),e(t.exports,"IsometricMap",()=>eR),e(t.exports,"IsometricTile",()=>eF),e(t.exports,"KeyEvent",()=>eB),e(t.exports,"Keyboard",()=>eL),e(t.exports,"Keys",()=>eM),e(t.exports,"KillEvent",()=>ez),e(t.exports,"Label",()=>eO),e(t.exports,"LimitCameraBoundsStrategy",()=>eU),e(t.exports,"Line",()=>eN),e(t.exports,"LineSegment",()=>eZ),e(t.exports,"Loader",()=>eH),e(t.exports,"LoaderEvents",()=>eV),e(t.exports,"LockCameraToActorAxisStrategy",()=>eW),e(t.exports,"LockCameraToActorStrategy",()=>eG),e(t.exports,"LogLevel",()=>ej),e(t.exports,"Logger",()=>eq),e(t.exports,"Material",()=>eX),e(t.exports,"Matrix",()=>e$),e(t.exports,"MatrixLocations",()=>eK),e(t.exports,"MediaEvent",()=>eY),e(t.exports,"Meet",()=>eQ),e(t.exports,"MotionComponent",()=>eJ),e(t.exports,"MotionSystem",()=>e0),e(t.exports,"MoveBy",()=>e1),e(t.exports,"MoveTo",()=>e2),e(t.exports,"NativePointerButton",()=>e5),e(t.exports,"NativeSoundEvent",()=>e4),e(t.exports,"NativeSoundProcessedEvent",()=>e3),e(t.exports,"None",()=>e9),e(t.exports,"Observable",()=>e6),e(t.exports,"OffscreenSystem",()=>e7),e(t.exports,"Pair",()=>e8),e(t.exports,"ParallaxComponent",()=>it),e(t.exports,"ParallelActions",()=>ie),e(t.exports,"ParseGif",()=>ii),e(t.exports,"Particle",()=>is),e(t.exports,"ParticleEmitter",()=>ir),e(t.exports,"ParticleTransform",()=>io),e(t.exports,"Physics",()=>ia),e(t.exports,"PhysicsStats",()=>il),e(t.exports,"PhysicsWorld",()=>ih),e(t.exports,"PointerAbstraction",()=>id),e(t.exports,"PointerButton",()=>ic),e(t.exports,"PointerComponent",()=>iu),e(t.exports,"PointerEvent",()=>ip),e(t.exports,"PointerEventReceiver",()=>ig),e(t.exports,"PointerScope",()=>i_),e(t.exports,"PointerSystem",()=>im),e(t.exports,"PointerType",()=>iv),e(t.exports,"Polygon",()=>iy),e(t.exports,"PolygonCollider",()=>ix),e(t.exports,"Pool",()=>iw),e(t.exports,"PostCollisionEvent",()=>ib),e(t.exports,"PostDebugDrawEvent",()=>iC),e(t.exports,"PostDrawEvent",()=>iT),e(t.exports,"PostFrameEvent",()=>iS),e(t.exports,"PostKillEvent",()=>iA),e(t.exports,"PostTransformDrawEvent",()=>iE),e(t.exports,"PostUpdateEvent",()=>iP),e(t.exports,"PreCollisionEvent",()=>iI),e(t.exports,"PreDebugDrawEvent",()=>ik),e(t.exports,"PreDrawEvent",()=>iD),e(t.exports,"PreFrameEvent",()=>iR),e(t.exports,"PreKillEvent",()=>iF),e(t.exports,"PreLoadEvent",()=>iB),e(t.exports,"PreTransformDrawEvent",()=>iL),e(t.exports,"PreUpdateEvent",()=>iM),e(t.exports,"Projection",()=>iz),e(t.exports,"QuadIndexBuffer",()=>iO),e(t.exports,"QuadTree",()=>iU),e(t.exports,"Query",()=>iN),e(t.exports,"QueryManager",()=>iZ),e(t.exports,"RadiusAroundActorStrategy",()=>iH),e(t.exports,"Random",()=>iV),e(t.exports,"Raster",()=>iW),e(t.exports,"Ray",()=>iG),e(t.exports,"RealisticSolver",()=>ij),e(t.exports,"Rectangle",()=>iq),e(t.exports,"RemovedComponent",()=>iX),e(t.exports,"Repeat",()=>i$),e(t.exports,"RepeatForever",()=>iK),e(t.exports,"Resolution",()=>iY),e(t.exports,"Resource",()=>iQ),e(t.exports,"ResourceEvents",()=>iJ),e(t.exports,"RotateBy",()=>i0),e(t.exports,"RotateTo",()=>i1),e(t.exports,"RotationType",()=>i2),e(t.exports,"ScaleBy",()=>i5),e(t.exports,"ScaleTo",()=>i4),e(t.exports,"Scene",()=>i3),e(t.exports,"SceneEvents",()=>i9),e(t.exports,"Screen",()=>i6),e(t.exports,"ScreenAppender",()=>i7),e(t.exports,"ScreenElement",()=>i8),e(t.exports,"ScreenEvents",()=>st),e(t.exports,"ScreenShader",()=>se),e(t.exports,"ScrollPreventionMode",()=>si),e(t.exports,"Semaphore",()=>ss),e(t.exports,"Shader",()=>sr),e(t.exports,"Shape",()=>sn),e(t.exports,"Side",()=>so),e(t.exports,"SolverStrategy",()=>sa),e(t.exports,"Sound",()=>sl),e(t.exports,"SoundEvents",()=>sh),e(t.exports,"Sprite",()=>sd),e(t.exports,"SpriteFont",()=>sc),e(t.exports,"SpriteSheet",()=>su),e(t.exports,"StandardClock",()=>sp),e(t.exports,"StateMachine",()=>sg),e(t.exports,"StrategyContainer",()=>s_),e(t.exports,"Stream",()=>sf),e(t.exports,"System",()=>sm),e(t.exports,"SystemManager",()=>sv),e(t.exports,"SystemPriority",()=>sy),e(t.exports,"SystemType",()=>sx),e(t.exports,"TagQuery",()=>sw),e(t.exports,"TestClock",()=>sb),e(t.exports,"Text",()=>sC),e(t.exports,"TextAlign",()=>sT),e(t.exports,"TextureLoader",()=>sS),e(t.exports,"Tile",()=>sA),e(t.exports,"TileMap",()=>sE),e(t.exports,"TileMapEvents",()=>sP),e(t.exports,"Timer",()=>sI),e(t.exports,"Toaster",()=>sk),e(t.exports,"Transform",()=>sD),e(t.exports,"TransformComponent",()=>sR),e(t.exports,"Transition",()=>sF),e(t.exports,"TreeNode",()=>sB),e(t.exports,"Trigger",()=>sL),e(t.exports,"TriggerEvents",()=>sM),e(t.exports,"TwoPI",()=>sz),e(t.exports,"Util",()=>sO),e(t.exports,"Vector",()=>sU),e(t.exports,"VectorView",()=>sN),e(t.exports,"VertexBuffer",()=>sZ),e(t.exports,"VertexLayout",()=>sH),e(t.exports,"VerticalFirst",()=>sV),e(t.exports,"VisibleEvent",()=>sW),e(t.exports,"WebAudio",()=>sG),e(t.exports,"WebAudioInstance",()=>sj),e(t.exports,"WheelDeltaMode",()=>sq),e(t.exports,"WheelEvent",()=>sX),e(t.exports,"World",()=>s$),e(t.exports,"canonicalizeAngle",()=>sK),e(t.exports,"clamp",()=>sY),e(t.exports,"coroutine",()=>sQ),e(t.exports,"createId",()=>sJ),e(t.exports,"frac",()=>s0),e(t.exports,"hasGraphicsTick",()=>s1),e(t.exports,"hasOnInitialize",()=>s2),e(t.exports,"hasOnPostUpdate",()=>s5),e(t.exports,"hasOnPreUpdate",()=>s4),e(t.exports,"hasPostDraw",()=>s3),e(t.exports,"hasPreDraw",()=>s9),e(t.exports,"has_initialize",()=>s6),e(t.exports,"has_postupdate",()=>s7),e(t.exports,"has_preupdate",()=>s8),e(t.exports,"isAddedComponent",()=>rt),e(t.exports,"isComponentCtor",()=>re),e(t.exports,"isLoaderConstructor",()=>ri),e(t.exports,"isRemovedComponent",()=>rs),e(t.exports,"isSceneConstructor",()=>rr),e(t.exports,"isScreenElement",()=>rn),e(t.exports,"isSystemConstructor",()=>ro),e(t.exports,"maxMessages",()=>ra),e(t.exports,"obsolete",()=>rl),e(t.exports,"pixelSnapEpsilon",()=>rh),e(t.exports,"randomInRange",()=>rd),e(t.exports,"randomIntInRange",()=>rc),e(t.exports,"range",()=>ru),e(t.exports,"resetObsoleteCounter",()=>rp),e(t.exports,"sign",()=>rg),e(t.exports,"toDegrees",()=>r_),e(t.exports,"toRadians",()=>rf),e(t.exports,"vec",()=>rm),e(t.exports,"webgl",()=>rv);/*! + * excalibur - 0.29.1 - 2024-2-23 * https://github.com/excaliburjs/Excalibur * Copyright (c) 2024 Excalibur.js * Licensed BSD-2-Clause @@ -154,7 +154,7 @@ button#excalibur-play:active { .ex-toast-message button { align-self: flex-start; -}`,"",{version:3,sources:["webpack://./Util/Toaster.css"],names:[],mappings:";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB",sourcesContent:["\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}"],sourceRoot:""}]);let a=o},2609:t=>{t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var i="",s=void 0!==e[5];return e[4]&&(i+="@supports (".concat(e[4],") {")),e[2]&&(i+="@media ".concat(e[2]," {")),s&&(i+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),i+=t(e),s&&(i+="}"),e[2]&&(i+="}"),e[4]&&(i+="}"),i}).join("")},e.i=function(t,i,s,r,n){"string"==typeof t&&(t=[[null,t,void 0]]);var o={};if(s)for(var a=0;a0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=n),i&&(d[2]&&(d[1]="@media ".concat(d[2]," {").concat(d[1],"}")),d[2]=i),r&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=r):d[4]="".concat(r)),e.push(d))}},e}},272:t=>{t.exports=function(t){var e=t[1],i=t[3];if(!i)return e;if("function"==typeof btoa){var s=btoa(unescape(encodeURIComponent(JSON.stringify(i))));return[e].concat(["/*# ".concat("sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(s)," */")]).join("\n")}return[e].join("\n")}},1324:(t,e,i)=>{i(7206);var s=i(8193);t.exports=s("Array","sort")},3571:(t,e,i)=>{i(9867);var s=i(8588);t.exports=s.Object.keys},1052:(t,e,i)=>{var s=i(688),r=i(3397),n=TypeError;t.exports=function(t){if(s(t))return t;throw new n(r(t)+" is not a function")}},9175:(t,e,i)=>{var s=i(5309),r=String,n=TypeError;t.exports=function(t){if(s(t))return t;throw new n(r(t)+" is not an object")}},1138:(t,e,i)=>{var s=i(6854),r=i(7352),n=i(8344),o=function(t){return function(e,i,o){var a,l=s(e),h=n(l),d=r(o,h);if(t&&i!=i){for(;h>d;)if((a=l[d++])!=a)return!0}else for(;h>d;d++)if((t||d in l)&&l[d]===i)return t||d||0;return!t&&-1}};t.exports={includes:o(!0),indexOf:o(!1)}},567:(t,e,i)=>{var s=i(4694);t.exports=function(t,e){var i=[][t];return!!i&&s(function(){i.call(null,e||function(){return 1},1)})}},7686:(t,e,i)=>{var s=i(9668);t.exports=s([].slice)},3097:(t,e,i)=>{var s=i(7686),r=Math.floor,n=function(t,e){var i=t.length;if(i<8)for(var o,a,l=1;l0;)t[a]=t[--a];a!==l++&&(t[a]=o)}else for(var h=r(i/2),d=n(s(t,0,h),e),c=n(s(t,h),e),u=d.length,p=c.length,g=0,_=0;g=e(d[g],c[_])?d[g++]:c[_++]:g{var s=i(9668),r=s({}.toString),n=s("".slice);t.exports=function(t){return n(r(t),8,-1)}},1566:(t,e,i)=>{var s=i(2522),r=i(688),n=i(2177),o=i(2032)("toStringTag"),a=Object,l="Arguments"===n(function(){return arguments}()),h=function(t,e){try{return t[e]}catch(t){}};t.exports=s?n:function(t){var e,i,s;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(i=h(e=a(t),o))?i:l?n(e):"Object"===(s=n(e))&&r(e.callee)?"Arguments":s}},3891:(t,e,i)=>{var s=i(4678),r=i(990),n=i(7537),o=i(2131);t.exports=function(t,e,i){for(var a=r(e),l=o.f,h=n.f,d=0;d{var s=i(9924),r=i(2131),n=i(7781);t.exports=s?function(t,e,i){return r.f(t,e,n(1,i))}:function(t,e,i){return t[e]=i,t}},7781:t=>{t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},2470:(t,e,i)=>{var s=i(688),r=i(2131),n=i(1135),o=i(1604);t.exports=function(t,e,i,a){a||(a={});var l=a.enumerable,h=void 0!==a.name?a.name:e;if(s(i)&&n(i,h,a),a.global)l?t[e]=i:o(e,i);else{try{a.unsafe?t[e]&&(l=!0):delete t[e]}catch(t){}l?t[e]=i:r.f(t,e,{value:i,enumerable:!1,configurable:!a.nonConfigurable,writable:!a.nonWritable})}return t}},1604:(t,e,i)=>{var s=i(2150),r=Object.defineProperty;t.exports=function(t,e){try{r(s,t,{value:e,configurable:!0,writable:!0})}catch(i){s[t]=e}return e}},955:(t,e,i)=>{var s=i(3397),r=TypeError;t.exports=function(t,e){if(!delete t[e])throw new r("Cannot delete property "+s(e)+" of "+s(t))}},9924:(t,e,i)=>{var s=i(4694);t.exports=!s(function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]})},1442:(t,e,i)=>{var s=i(2150),r=i(5309),n=s.document,o=r(n)&&r(n.createElement);t.exports=function(t){return o?n.createElement(t):{}}},9016:(t,e,i)=>{var s=i(1370).match(/firefox\/(\d+)/i);t.exports=!!s&&+s[1]},821:(t,e,i)=>{var s=i(1370);t.exports=/MSIE|Trident/.test(s)},1370:t=>{t.exports="undefined"!=typeof navigator&&String(navigator.userAgent)||""},7067:(t,e,i)=>{var s,r,n=i(2150),o=i(1370),a=n.process,l=n.Deno,h=a&&a.versions||l&&l.version,d=h&&h.v8;d&&(r=(s=d.split("."))[0]>0&&s[0]<4?1:+(s[0]+s[1])),!r&&o&&(!(s=o.match(/Edge\/(\d+)/))||s[1]>=74)&&(s=o.match(/Chrome\/(\d+)/))&&(r=+s[1]),t.exports=r},4389:(t,e,i)=>{var s=i(1370).match(/AppleWebKit\/(\d+)\./);t.exports=!!s&&+s[1]},8193:(t,e,i)=>{var s=i(2150),r=i(9668);t.exports=function(t,e){return r(s[t].prototype[e])}},2367:t=>{t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},5532:(t,e,i)=>{var s=i(2150),r=i(7537).f,n=i(2385),o=i(2470),a=i(1604),l=i(3891),h=i(1633);t.exports=function(t,e){var i,d,c,u,p,g=t.target,_=t.global,f=t.stat;if(i=_?s:f?s[g]||a(g,{}):s[g]&&s[g].prototype)for(d in e){if(u=e[d],c=t.dontCallGetSet?(p=r(i,d))&&p.value:i[d],!h(_?d:g+(f?".":"#")+d,t.forced)&&void 0!==c){if(typeof u==typeof c)continue;l(u,c)}(t.sham||c&&c.sham)&&n(u,"sham",!0),o(i,d,u,t)}}},4694:t=>{t.exports=function(t){try{return!!t()}catch(t){return!0}}},6398:(t,e,i)=>{var s=i(4694);t.exports=!s(function(){var t=(function(){}).bind();return"function"!=typeof t||t.hasOwnProperty("prototype")})},8724:(t,e,i)=>{var s=i(6398),r=Function.prototype.call;t.exports=s?r.bind(r):function(){return r.apply(r,arguments)}},453:(t,e,i)=>{var s=i(9924),r=i(4678),n=Function.prototype,o=s&&Object.getOwnPropertyDescriptor,a=r(n,"name"),l=a&&(!s||s&&o(n,"name").configurable);t.exports={EXISTS:a,PROPER:a&&"something"===(function(){}).name,CONFIGURABLE:l}},9668:(t,e,i)=>{var s=i(6398),r=Function.prototype,n=r.call,o=s&&r.bind.bind(n,n);t.exports=s?o:function(t){return function(){return n.apply(t,arguments)}}},2160:(t,e,i)=>{var s=i(2150),r=i(688);t.exports=function(t,e){var i;return arguments.length<2?r(i=s[t])?i:void 0:s[t]&&s[t][e]}},5383:(t,e,i)=>{var s=i(1052),r=i(5268);t.exports=function(t,e){var i=t[e];return r(i)?void 0:s(i)}},2150:function(t,e,i){var s=function(t){return t&&t.Math===Math&&t};t.exports=s("object"==typeof globalThis&&globalThis)||s("object"==typeof window&&window)||s("object"==typeof self&&self)||s("object"==typeof i.g&&i.g)||s("object"==typeof this&&this)||function(){return this}()||Function("return this")()},4678:(t,e,i)=>{var s=i(9668),r=i(298),n=s({}.hasOwnProperty);t.exports=Object.hasOwn||function(t,e){return n(r(t),e)}},7390:t=>{t.exports={}},7913:(t,e,i)=>{var s=i(9924),r=i(4694),n=i(1442);t.exports=!s&&!r(function(){return 7!==Object.defineProperty(n("div"),"a",{get:function(){return 7}}).a})},4347:(t,e,i)=>{var s=i(9668),r=i(4694),n=i(2177),o=Object,a=s("".split);t.exports=r(function(){return!o("z").propertyIsEnumerable(0)})?function(t){return"String"===n(t)?a(t,""):o(t)}:o},1881:(t,e,i)=>{var s=i(9668),r=i(688),n=i(6762),o=s(Function.toString);r(n.inspectSource)||(n.inspectSource=function(t){return o(t)}),t.exports=n.inspectSource},7804:(t,e,i)=>{var s,r,n,o=i(4724),a=i(2150),l=i(5309),h=i(2385),d=i(4678),c=i(6762),u=i(1962),p=i(7390),g="Object already initialized",_=a.TypeError,f=a.WeakMap;if(o||c.state){var m=c.state||(c.state=new f);m.get=m.get,m.has=m.has,m.set=m.set,s=function(t,e){if(m.has(t))throw new _(g);return e.facade=t,m.set(t,e),e},r=function(t){return m.get(t)||{}},n=function(t){return m.has(t)}}else{var v=u("state");p[v]=!0,s=function(t,e){if(d(t,v))throw new _(g);return e.facade=t,h(t,v,e),e},r=function(t){return d(t,v)?t[v]:{}},n=function(t){return d(t,v)}}t.exports={set:s,get:r,has:n,enforce:function(t){return n(t)?r(t):s(t,{})},getterFor:function(t){return function(e){var i;if(!l(e)||(i=r(e)).type!==t)throw new _("Incompatible receiver, "+t+" required");return i}}}},688:t=>{var e="object"==typeof document&&document.all;t.exports=void 0===e&&void 0!==e?function(t){return"function"==typeof t||t===e}:function(t){return"function"==typeof t}},1633:(t,e,i)=>{var s=i(4694),r=i(688),n=/#|\.prototype\./,o=function(t,e){var i=l[a(t)];return i===d||i!==h&&(r(e)?s(e):!!e)},a=o.normalize=function(t){return String(t).replace(n,".").toLowerCase()},l=o.data={},h=o.NATIVE="N",d=o.POLYFILL="P";t.exports=o},5268:t=>{t.exports=function(t){return null==t}},5309:(t,e,i)=>{var s=i(688);t.exports=function(t){return"object"==typeof t?null!==t:s(t)}},6555:t=>{t.exports=!1},7935:(t,e,i)=>{var s=i(2160),r=i(688),n=i(6148),o=i(4866),a=Object;t.exports=o?function(t){return"symbol"==typeof t}:function(t){var e=s("Symbol");return r(e)&&n(e.prototype,a(t))}},8344:(t,e,i)=>{var s=i(7331);t.exports=function(t){return s(t.length)}},1135:(t,e,i)=>{var s=i(9668),r=i(4694),n=i(688),o=i(4678),a=i(9924),l=i(453).CONFIGURABLE,h=i(1881),d=i(7804),c=d.enforce,u=d.get,p=String,g=Object.defineProperty,_=s("".slice),f=s("".replace),m=s([].join),v=a&&!r(function(){return 8!==g(function(){},"length",{value:8}).length}),y=String(String).split("String"),x=t.exports=function(t,e,i){"Symbol("===_(p(e),0,7)&&(e="["+f(p(e),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),i&&i.getter&&(e="get "+e),i&&i.setter&&(e="set "+e),(!o(t,"name")||l&&t.name!==e)&&(a?g(t,"name",{value:e,configurable:!0}):t.name=e),v&&i&&o(i,"arity")&&t.length!==i.arity&&g(t,"length",{value:i.arity});try{i&&o(i,"constructor")&&i.constructor?a&&g(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var s=c(t);return o(s,"source")||(s.source=m(y,"string"==typeof e?e:"")),t};Function.prototype.toString=x(function(){return n(this)&&u(this).source||h(this)},"toString")},1787:t=>{var e=Math.ceil,i=Math.floor;t.exports=Math.trunc||function(t){var s=+t;return(s>0?i:e)(s)}},2131:(t,e,i)=>{var s=i(9924),r=i(7913),n=i(2666),o=i(9175),a=i(2358),l=TypeError,h=Object.defineProperty,d=Object.getOwnPropertyDescriptor,c="enumerable",u="configurable",p="writable";e.f=s?n?function(t,e,i){if(o(t),e=a(e),o(i),"function"==typeof t&&"prototype"===e&&"value"in i&&p in i&&!i[p]){var s=d(t,e);s&&s[p]&&(t[e]=i.value,i={configurable:u in i?i[u]:s[u],enumerable:c in i?i[c]:s[c],writable:!1})}return h(t,e,i)}:h:function(t,e,i){if(o(t),e=a(e),o(i),r)try{return h(t,e,i)}catch(t){}if("get"in i||"set"in i)throw new l("Accessors not supported");return"value"in i&&(t[e]=i.value),t}},7537:(t,e,i)=>{var s=i(9924),r=i(8724),n=i(8208),o=i(7781),a=i(6854),l=i(2358),h=i(4678),d=i(7913),c=Object.getOwnPropertyDescriptor;e.f=s?c:function(t,e){if(t=a(t),e=l(e),d)try{return c(t,e)}catch(t){}if(h(t,e))return o(!r(n.f,t,e),t[e])}},6217:(t,e,i)=>{var s=i(1528),r=i(2367).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return s(t,r)}},5168:(t,e)=>{e.f=Object.getOwnPropertySymbols},6148:(t,e,i)=>{var s=i(9668);t.exports=s({}.isPrototypeOf)},1528:(t,e,i)=>{var s=i(9668),r=i(4678),n=i(6854),o=i(1138).indexOf,a=i(7390),l=s([].push);t.exports=function(t,e){var i,s=n(t),h=0,d=[];for(i in s)!r(a,i)&&r(s,i)&&l(d,i);for(;e.length>h;)r(s,i=e[h++])&&(~o(d,i)||l(d,i));return d}},1728:(t,e,i)=>{var s=i(1528),r=i(2367);t.exports=Object.keys||function(t){return s(t,r)}},8208:(t,e)=>{var i={}.propertyIsEnumerable,s=Object.getOwnPropertyDescriptor,r=s&&!i.call({1:2},1);e.f=r?function(t){var e=s(this,t);return!!e&&e.enumerable}:i},110:(t,e,i)=>{var s=i(8724),r=i(688),n=i(5309),o=TypeError;t.exports=function(t,e){var i,a;if("string"===e&&r(i=t.toString)&&!n(a=s(i,t))||r(i=t.valueOf)&&!n(a=s(i,t))||"string"!==e&&r(i=t.toString)&&!n(a=s(i,t)))return a;throw new o("Can't convert object to primitive value")}},990:(t,e,i)=>{var s=i(2160),r=i(9668),n=i(6217),o=i(5168),a=i(9175),l=r([].concat);t.exports=s("Reflect","ownKeys")||function(t){var e=n.f(a(t)),i=o.f;return i?l(e,i(t)):e}},8588:(t,e,i)=>{var s=i(2150);t.exports=s},1166:(t,e,i)=>{var s=i(5268),r=TypeError;t.exports=function(t){if(s(t))throw new r("Can't call method on "+t);return t}},1962:(t,e,i)=>{var s=i(2645),r=i(5736),n=s("keys");t.exports=function(t){return n[t]||(n[t]=r(t))}},6762:(t,e,i)=>{var s=i(2150),r=i(1604),n="__core-js_shared__",o=s[n]||r(n,{});t.exports=o},2645:(t,e,i)=>{var s=i(6555),r=i(6762);(t.exports=function(t,e){return r[t]||(r[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.35.1",mode:s?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE",source:"https://github.com/zloirock/core-js"})},4112:(t,e,i)=>{var s=i(7067),r=i(4694),n=i(2150).String;t.exports=!!Object.getOwnPropertySymbols&&!r(function(){var t=Symbol("symbol detection");return!n(t)||!(Object(t) instanceof Symbol)||!Symbol.sham&&s&&s<41})},7352:(t,e,i)=>{var s=i(1680),r=Math.max,n=Math.min;t.exports=function(t,e){var i=s(t);return i<0?r(i+e,0):n(i,e)}},6854:(t,e,i)=>{var s=i(4347),r=i(1166);t.exports=function(t){return s(r(t))}},1680:(t,e,i)=>{var s=i(1787);t.exports=function(t){var e=+t;return e!=e||0===e?0:s(e)}},7331:(t,e,i)=>{var s=i(1680),r=Math.min;t.exports=function(t){var e=s(t);return e>0?r(e,9007199254740991):0}},298:(t,e,i)=>{var s=i(1166),r=Object;t.exports=function(t){return r(s(t))}},1272:(t,e,i)=>{var s=i(8724),r=i(5309),n=i(7935),o=i(5383),a=i(110),l=i(2032),h=TypeError,d=l("toPrimitive");t.exports=function(t,e){if(!r(t)||n(t))return t;var i,l=o(t,d);if(l){if(void 0===e&&(e="default"),!r(i=s(l,t,e))||n(i))return i;throw new h("Can't convert object to primitive value")}return void 0===e&&(e="number"),a(t,e)}},2358:(t,e,i)=>{var s=i(1272),r=i(7935);t.exports=function(t){var e=s(t,"string");return r(e)?e:e+""}},2522:(t,e,i)=>{var s=i(2032)("toStringTag"),r={};r[s]="z",t.exports="[object z]"===String(r)},599:(t,e,i)=>{var s=i(1566),r=String;t.exports=function(t){if("Symbol"===s(t))throw TypeError("Cannot convert a Symbol value to a string");return r(t)}},3397:t=>{var e=String;t.exports=function(t){try{return e(t)}catch(t){return"Object"}}},5736:(t,e,i)=>{var s=i(9668),r=0,n=Math.random(),o=s(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+o(++r+n,36)}},4866:(t,e,i)=>{var s=i(4112);t.exports=s&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},2666:(t,e,i)=>{var s=i(9924),r=i(4694);t.exports=s&&r(function(){return 42!==Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype})},4724:(t,e,i)=>{var s=i(2150),r=i(688),n=s.WeakMap;t.exports=r(n)&&/native code/.test(String(n))},2032:(t,e,i)=>{var s=i(2150),r=i(2645),n=i(4678),o=i(5736),a=i(4112),l=i(4866),h=s.Symbol,d=r("wks"),c=l?h.for||h:h&&h.withoutSetter||o;t.exports=function(t){return n(d,t)||(d[t]=a&&n(h,t)?h[t]:c("Symbol."+t)),d[t]}},7206:(t,e,i)=>{var s=i(5532),r=i(9668),n=i(1052),o=i(298),a=i(8344),l=i(955),h=i(599),d=i(4694),c=i(3097),u=i(567),p=i(9016),g=i(821),_=i(7067),f=i(4389),m=[],v=r(m.sort),y=r(m.push),x=d(function(){m.sort(void 0)}),w=d(function(){m.sort(null)}),b=u("sort"),C=!d(function(){if(_)return _<70;if(!p||!(p>3)){if(g)return!0;if(f)return f<603;var t,e,i,s,r="";for(t=65;t<76;t++){switch(e=String.fromCharCode(t),t){case 66:case 69:case 70:case 72:i=3;break;case 68:case 71:i=4;break;default:i=2}for(s=0;s<47;s++)m.push({k:e+s,v:i})}for(m.sort(function(t,e){return e.v-t.v}),s=0;sh(i)?1:-1}),e=a(r),i=0;i{var s=i(5532),r=i(298),n=i(1728);s({target:"Object",stat:!0,forced:i(4694)(function(){n(1)})},{keys:function(t){return n(r(t))}})}},r={};function n(t){var e=r[t];if(void 0!==e)return e.exports;var i=r[t]={id:t,exports:{}};return s[t].call(i.exports,i,i.exports,n),i.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var i in e)n.o(e,i)&&!n.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};(()=>{n.d(o,{y1j:()=>iy,fWn:()=>sN,Ia8:()=>sb,rqv:()=>nl,zH6:()=>iv,hLI:()=>sZ,yyv:()=>rE,tX5:()=>ic,vtX:()=>sj,r7K:()=>sd,cE4:()=>t2,fwF:()=>rv,sce:()=>to,AQ6:()=>rm,_c7:()=>ta,KUs:()=>rp,Ajp:()=>eL,dkO:()=>tc,RDh:()=>tr,_H9:()=>te,mxs:()=>sB,OmD:()=>sh,kBf:()=>tq,C4F:()=>X,NQt:()=>r0,JjN:()=>r1,EK_:()=>td,V1s:()=>s7,xHm:()=>s6,Xz7:()=>eU,Cdc:()=>sy,FKn:()=>st,SUY:()=>r3,ab2:()=>i7,GfZ:()=>i8,YMS:()=>iJ,oyv:()=>sl,aUb:()=>se,SdD:()=>ih,JUv:()=>ij,jEj:()=>iG,TFq:()=>ss,HDU:()=>ia,R_y:()=>io,t50:()=>il,s$$:()=>rf,v2G:()=>G,Ilk:()=>tH,s9i:()=>rK,dxL:()=>tm,LLX:()=>r$,wA2:()=>iZ,R_p:()=>i9,IQ$:()=>rx,I5F:()=>tG,X8$:()=>rg,FR6:()=>ir,pTZ:()=>K,U8o:()=>is,kbG:()=>j,FEv:()=>nI,iS_:()=>iu,cGG:()=>sn,ETM:()=>rY,RPN:()=>sY,skb:()=>rS,SLU:()=>eo,Q3w:()=>r2,xK2:()=>iE,vrO:()=>i4,EA2:()=>r5,RdJ:()=>Y,cNu:()=>sL,wtG:()=>i3,gU7:()=>iL,LSk:()=>sz,Nmp:()=>ts,twX:()=>ne,UND:()=>nt,d1Y:()=>V,xrL:()=>iK,sRW:()=>iQ,cmV:()=>nU,qWz:()=>sF,N0Q:()=>sR,q8b:()=>sw,ynB:()=>sr,jT9:()=>s4,wAz:()=>tl,D4V:()=>ns,NLr:()=>ni,N6H:()=>i_,W1A:()=>ig,JHW:()=>s_,ZZ$:()=>sg,v2K:()=>rr,pBf:()=>nr,vpe:()=>tP,GMl:()=>W,zW2:()=>tx,B0K:()=>eN,Nv7:()=>eR,C_p:()=>ek,MUA:()=>im,xqU:()=>ip,pTp:()=>sM,trb:()=>nP,vUK:()=>tS,j9l:()=>sO,Zxw:()=>sW,v51:()=>sV,gYv:()=>nS,Hdx:()=>ti,Z$d:()=>J,iqV:()=>r4,o$7:()=>rQ,olM:()=>tE,Zm$:()=>eV,$QH:()=>eq,i78:()=>eX,nJg:()=>rF,h6u:()=>e7,hts:()=>e6,j88:()=>e3,VME:()=>e9,fy2:()=>rR,nt:()=>ny,Ukr:()=>rO,zsu:()=>et,oA6:()=>sm,TVh:()=>ry,xxj:()=>rT,XdK:()=>it,fBD:()=>i2,Jmb:()=>H,cXo:()=>es,Dm5:()=>id,IIB:()=>tb,IX$:()=>rV,ebW:()=>rB,zI0:()=>$,LYD:()=>rP,cEG:()=>rI,SEl:()=>na,t9V:()=>no,ez5:()=>rL,N1d:()=>rz,R8U:()=>tu,SKZ:()=>eW,__J:()=>nn,RI$:()=>s9,x12:()=>nk,ccz:()=>i6,aNw:()=>iB,XrL:()=>iS,xwn:()=>s5,dNK:()=>s2,ini:()=>U,YdH:()=>tW,F5T:()=>eA,y3G:()=>t1,l57:()=>Z,xn0:()=>ix,t2V:()=>sU,uxB:()=>iW,cpd:()=>ru,fiy:()=>sS,$XZ:()=>sA,UG6:()=>tg,uqK:()=>iw,STE:()=>ib,Hq9:()=>i5,y$z:()=>iH,mAD:()=>rk,sOq:()=>iq,hUw:()=>sK,_0G:()=>nh,Sqs:()=>nT,hpZ:()=>rb,Vol:()=>rC,vYX:()=>th,wIZ:()=>i0,cBi:()=>rJ,c30:()=>rD,PGK:()=>rZ,MPV:()=>t_,RFv:()=>sx,Ux6:()=>rU,rxy:()=>rH,I$c:()=>O,kfC:()=>rA,VjY:()=>tf,mgq:()=>nD,YVA:()=>so,Kgp:()=>eC,HH$:()=>ii,M_d:()=>e0,rgh:()=>eK,Ra6:()=>e4,KhR:()=>ej,gvQ:()=>eQ,BS5:()=>e2,xhz:()=>ie,xOq:()=>eJ,a9j:()=>e$,bHk:()=>e5,CgK:()=>eG,A0M:()=>rW,cEd:()=>eY,cuY:()=>e1,kvE:()=>iX,SBu:()=>ey,PsT:()=>nd,AE_:()=>rn,ctO:()=>ra,OLH:()=>s3,kky:()=>tI,nSF:()=>eO,zHn:()=>iY,zwx:()=>r_,AeJ:()=>sv,hLz:()=>su,wA:()=>sC,jhr:()=>sT,GVs:()=>eF,_zO:()=>t9,LXZ:()=>t3,w6$:()=>sP,mhV:()=>sE,MOD:()=>Q,kwd:()=>sk,Lmr:()=>sI,xsS:()=>rq,K5l:()=>rG,lLr:()=>eM,Z$r:()=>tj,IXb:()=>sX,Xsu:()=>eB,SGH:()=>rX,SMj:()=>tv,L34:()=>nO,exe:()=>eu,bnF:()=>sa,MFA:()=>N,kPj:()=>q,$uU:()=>iT,Sap:()=>iC,jyi:()=>ee,E03:()=>er,V6q:()=>en,rg2:()=>r9,DVW:()=>eZ,nVo:()=>s1,F6N:()=>nb,xP7:()=>rs,Odq:()=>rh,uY9:()=>ri,Zif:()=>tn,c_d:()=>ro,MJk:()=>r6,xvT:()=>sG,PHM:()=>tt,dpR:()=>ei,n9L:()=>s0,KwO:()=>sJ,SxM:()=>sQ,B7y:()=>s$,x7r:()=>r8,wx7:()=>iU,Uvn:()=>iV,uTP:()=>nE,OFT:()=>i$,xzN:()=>re,CcZ:()=>s8,M5Z:()=>tk,ZrN:()=>tC,OWs:()=>tN,dF9:()=>iz,oZy:()=>ep,rD2:()=>eg,KmN:()=>i1,VHo:()=>e8,ohE:()=>ez,R$E:()=>eH,xQN:()=>tp,AdJ:()=>rN,q3I:()=>rd,Pab:()=>tB,uZ5:()=>tF,TAE:()=>nA,McK:()=>tA,F9c:()=>tD,k0b:()=>sf,hnT:()=>nu,RSJ:()=>nf,Mku:()=>ng,h90:()=>nv,rms:()=>nm,ErP:()=>nc,aVg:()=>n_,lPc:()=>np,Z8E:()=>sc,k15:()=>iN,YsU:()=>iA,lNv:()=>sp,Xyg:()=>rj,cu9:()=>sq,p88:()=>rl,MZQ:()=>nR,FUM:()=>nL,BxR:()=>eP,vdf:()=>tO,iaL:()=>tU,w6H:()=>tz,Q4c:()=>nB,Xxe:()=>tR,Uxb:()=>tM,Yr5:()=>tL,Bhw:()=>tZ,yOA:()=>ty});var t,e,i,s,r,a,l,h,d,c,u,p,g,_,f,m,v,y,x,w,b,C,T,S,A,E,P,I,k,D,R,F,B,M,L,z,O,U,N,Z,H,V,W,G,j,q,X,$,K,Y,Q,J,tt,te,ti,ts,tr,tn,to,ta,tl,th,td,tc,tu,tp,tg,t_,tf,tm,tv,ty={};n.r(ty),n.d(ty,{getAttributeComponentSize:()=>ed,getAttributePointerType:()=>ec,getGlTypeSizeBytes:()=>eh});var tx={};n.r(tx),n.d(tx,{ActionCompleteEvent:()=>iy,ActionStartEvent:()=>iv,ActivateEvent:()=>ic,CollisionEndEvent:()=>ih,CollisionPostSolveEvent:()=>ia,CollisionPreSolveEvent:()=>io,CollisionStartEvent:()=>il,ContactEndEvent:()=>ir,ContactStartEvent:()=>is,DeactivateEvent:()=>iu,EnterTriggerEvent:()=>i_,EnterViewPortEvent:()=>ig,EventTypes:()=>W,ExitTriggerEvent:()=>im,ExitViewPortEvent:()=>ip,GameEvent:()=>eV,GameStartEvent:()=>eq,GameStopEvent:()=>eX,GamepadAxisEvent:()=>e7,GamepadButtonEvent:()=>e6,GamepadConnectEvent:()=>e3,GamepadDisconnectEvent:()=>e9,HiddenEvent:()=>it,InitializeEvent:()=>id,KillEvent:()=>eW,PostCollisionEvent:()=>ii,PostDebugDrawEvent:()=>e0,PostDrawEvent:()=>eK,PostFrameEvent:()=>e4,PostKillEvent:()=>ej,PostTransformDrawEvent:()=>eQ,PostUpdateEvent:()=>e2,PreCollisionEvent:()=>ie,PreDebugDrawEvent:()=>eJ,PreDrawEvent:()=>e$,PreFrameEvent:()=>e5,PreKillEvent:()=>eG,PreTransformDrawEvent:()=>eY,PreUpdateEvent:()=>e1,VisibleEvent:()=>e8});var tw={};n.r(tw),n.d(tw,{circle:()=>iR,line:()=>iP,point:()=>iI,roundRect:()=>iD,vector:()=>ik});var tb={};n.r(tb),n.d(tb,{Axes:()=>tc,Buttons:()=>td,Gamepad:()=>rF,Gamepads:()=>rR,KeyEvent:()=>rL,Keyboard:()=>rz,Keys:()=>tu,NativePointerButton:()=>tg,PointerButton:()=>t_,PointerComponent:()=>sx,PointerEvent:()=>rU,PointerEventReceiver:()=>rH,PointerScope:()=>O,PointerSystem:()=>rA,PointerType:()=>tf,WheelDeltaMode:()=>tp,WheelEvent:()=>rN});var tC={};function tT(){if("undefined"==typeof window&&(window={audioContext:function(){}}),"undefined"==typeof window||window.requestAnimationFrame||(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setInterval(t,1e3/60)}),"undefined"==typeof window||window.cancelAnimationFrame||(window.cancelAnimationFrame=window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(){}),"undefined"!=typeof window&&!window.AudioContext){if(window.webkitAudioContext){let t=window.webkitAudioContext.prototype.decodeAudioData;window.webkitAudioContext.prototype.decodeAudioData=function(e){return new Promise((i,s)=>{t.call(this,e,i,s)})}}window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext}"undefined"==typeof window||window.devicePixelRatio||(window.devicePixelRatio=window.devicePixelRatio||1)}n.r(tC),n.d(tC,{ConsoleAppender:()=>tG,DrawUtil:()=>tw,EasingFunctions:()=>sw,LogLevel:()=>U,Logger:()=>tW,Observable:()=>iH,ScreenAppender:()=>tj,addItemToArray:()=>t$,contains:()=>tY,delay:()=>tJ,fail:()=>tQ,getPosition:()=>tX,omit:()=>t0,removeItemFromArray:()=>tK}),n(1324),n(3571);class tS{static useCanvasGraphicsContext(){tS.enable("use-canvas-context")}static freeze(){tS._FROZEN=!0}static _reset(){tS._FROZEN=!1,tS._FLAGS={}}static enable(t){if(this._FROZEN)throw Error("Feature flags can only be enabled before Engine constructor time");tS._FLAGS[t]=!0}static disable(t){if(this._FROZEN)throw Error("Feature flags can only be disabled before Engine constructor time");tS._FLAGS[t]=!1}static isEnabled(t){return!!tS._FLAGS[t]}static show(){return Object.keys(tS._FLAGS)}}function tA(t,e){return{type:t,value:e}}tS._FROZEN=!1,tS._FLAGS={};class tE{constructor(){this._isCompleted=!1,this.promise=new Promise((t,e)=>{this._resolver=t,this._rejecter=e})}get isCompleted(){return this._isCompleted}resolve(t){this._isCompleted||(this._isCompleted=!0,this._resolver(t))}reject(t){this._isCompleted||(this._isCompleted=!0,this._rejecter(t))}}class tP{constructor(){this._paused=!1,this._listeners={},this._listenersOnce={},this._pipes=[]}clear(){this._listeners={},this._listenersOnce={},this._pipes.length=0}on(t,e){var i;return this._listeners[t]=null!==(i=this._listeners[t])&&void 0!==i?i:[],this._listeners[t].push(e),{close:()=>this.off(t,e)}}once(t,e){var i;return this._listenersOnce[t]=null!==(i=this._listenersOnce[t])&&void 0!==i?i:[],this._listenersOnce[t].push(e),{close:()=>this.off(t,e)}}off(t,e){var i,s;if(e){let r=null===(i=this._listeners[t])||void 0===i?void 0:i.filter(t=>t!==e);this._listeners[t]=r;let n=null===(s=this._listenersOnce[t])||void 0===s?void 0:s.filter(t=>t!==e);this._listenersOnce[t]=n}else delete this._listeners[t]}emit(t,e){var i;if(this._paused)return;null===(i=this._listeners[t])||void 0===i||i.forEach(t=>t(e));let s=this._listenersOnce[t];this._listenersOnce[t]=[],s&&s.forEach(t=>t(e)),this._pipes.forEach(i=>{i.emit(t,e)})}pipe(t){if(this===t)throw Error("Cannot pipe to self");return this._pipes.push(t),{close:()=>{let e=this._pipes.indexOf(t);e>-1&&this._pipes.splice(e,1)}}}unpipe(t){let e=this._pipes.indexOf(t);e>-1&&this._pipes.splice(e,1)}pause(){this._paused=!0}unpause(){this._paused=!1}}(t=O||(O={})).Canvas="Canvas",t.Document="Document";class tI{constructor(t){this.seed=t,this._lowerMask=2147483647,this._upperMask=2147483648,this._w=32,this._n=624,this._m=397,this._a=2567483615,this._u=11,this._s=7,this._b=2636928640,this._t=15,this._c=4022730752,this._l=18,this._f=1812433253,this._mt=Array(this._n),this._mt[0]=(t||Date.now())>>>0;for(let t=1;t>>this._w-2;this._mt[t]=(this._f*((4294901760&e)>>>16)<<16)+this._f*(65535&e)+t>>>0}this._index=this._n}_twist(){let t=[0,this._a],e=0,i=0;for(;i>>1^4294967295&t[1&e];for(;i>>1^4294967295&t[1&e];e=this._mt[this._n-1]&this._upperMask|this._mt[0]&this._lowerMask,this._mt[this._n-1]=this._mt[this._m-1]^e>>>1^4294967295&t[1&e],this._index=0}nextInt(){this._index>=this._n&&this._twist();let t=this._mt[this._index++];return t^=t>>>this._u,t^=t<>>this._l)>>>0}next(){return this.nextInt()*(1/4294967296)}floating(t,e){return(e-t)*this.next()+t}integer(t,e){return Math.floor((e-t+1)*this.next()+t)}bool(t=.5){return this.next()<=t}pickOne(t){return t[this.integer(0,t.length-1)]}pickSet(t,e,i=!1){return i?this._pickSetWithDuplicates(t,e):this._pickSetWithoutDuplicates(t,e)}_pickSetWithoutDuplicates(t,e){if(e>t.length||e<0)throw Error("Invalid number of elements to pick, must pick a value 0 < n <= length");if(e===t.length)return t;let i=Array(e),s=0,r=t.slice(0);for(;s=0?t-Math.floor(t):t-Math.ceil(t)}function tR(t){return 0===t?0:t<0?-1:1}function tF(t,e,i){return Math.min(Math.max(e,t),i)}function tB(t){let e=t;if(t>tk)for(;e>tk;)e-=tk;if(t<0)for(;e<0;)e+=tk;return e}function tM(t){return 180/Math.PI*t}function tL(t){return t/180*Math.PI}let tz=(t,e)=>Array.from(Array(e-t+1),(e,i)=>i+t);function tO(t,e,i=new tI){return i?i.floating(t,e):t+Math.random()*(e-t)}function tU(t,e,i=new tI){return i?i.integer(t,e):Math.round(tO(t,e))}class tN{static get Zero(){return new tN(0,0)}static get One(){return new tN(1,1)}static get Half(){return new tN(.5,.5)}static get Up(){return new tN(0,-1)}static get Down(){return new tN(0,1)}static get Left(){return new tN(-1,0)}static get Right(){return new tN(1,0)}static fromAngle(t){return new tN(Math.cos(t),Math.sin(t))}static isValid(t){return!(null==t||isNaN(t.x)||isNaN(t.y))&&t.x!==1/0&&t.y!==1/0&&t.x!==-1/0&&t.y!==-1/0}static distance(t,e){return Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2))}static min(t,e){return new tN(Math.min(t.x,e.x),Math.min(t.y,e.y))}static max(t,e){return new tN(Math.max(t.x,e.x),Math.max(t.y,e.y))}constructor(t,e){this._x=0,this._y=0,this._x=t,this._y=e}get x(){return this._x}set x(t){this._x=t}get y(){return this._y}set y(t){this._y=t}setTo(t,e){this.x=t,this.y=e}equals(t,e=.001){return Math.abs(this.x-t.x)<=e&&Math.abs(this.y-t.y)<=e}distance(t){if(!t)return Math.sqrt(this.x*this.x+this.y*this.y);let e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)}squareDistance(t){t||(t=tN.Zero);let e=this.x-t.x,i=this.y-t.y;return e*e+i*i}clampMagnitude(t){let e=tF(this.size,0,t);return this.size=e,this}get size(){return this.distance()}set size(t){let e=this.normalize().scale(t);this.setTo(e.x,e.y)}normalize(){let t=this.distance();return t>0?new tN(this.x/t,this.y/t):new tN(0,1)}average(t){return this.add(t).scale(.5)}scale(t,e){let i=e||new tN(0,0);return t instanceof tN?(i.x=this.x*t.x,i.y=this.y*t.y):(i.x=this.x*t,i.y=this.y*t),i}add(t,e){return e?(e.x=this.x+t.x,e.y=this.y+t.y,e):new tN(this.x+t.x,this.y+t.y)}sub(t){return new tN(this.x-t.x,this.y-t.y)}addEqual(t){return this.setTo(this.x+t.x,this.y+t.y),this}subEqual(t){return this.setTo(this.x-t.x,this.y-t.y),this}scaleEqual(t){return this.setTo(this.x*t,this.y*t),this}dot(t){return this.x*t.x+this.y*t.y}cross(t){return t instanceof tN?this.x*t.y-this.y*t.x:"number"==typeof t?new tN(t*this.y,-t*this.x):void 0}static cross(t,e){return new tN(-t*e.y,t*e.x)}perpendicular(){return new tN(this.y,-this.x)}normal(){return this.perpendicular().normalize()}negate(){return this.scale(-1)}toAngle(){return Math.atan2(this.y,this.x)}rotate(t,e){e||(e=new tN(0,0));let i=Math.sin(t),s=Math.cos(t);return new tN(s*(this.x-e.x)-i*(this.y-e.y)+e.x,i*(this.x-e.x)+s*(this.y-e.y)+e.y)}clone(t){let e=null!=t?t:new tN(0,0);return e.x=this.x,e.y=this.y,e}toString(t){return t?`(${this.x.toFixed(t)}, ${this.y.toFixed(t)})`:`(${this.x}, ${this.y})`}}function tZ(t,e){return new tN(t,e)}class tH{constructor(t,e,i,s){this.r=t,this.g=e,this.b=i,this.a=null!=s?s:1}static fromRGB(t,e,i,s){return new tH(t,e,i,s)}static fromRGBString(t){let e=null;if(e=t.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)/i)){let t=parseInt(e[1],10),i=parseInt(e[2],10),s=parseInt(e[3],10),r=1;return e[4]&&(r=parseFloat(e[4])),new tH(t,i,s,r)}throw Error("Invalid rgb/a string: "+t)}static fromHex(t){let e=null;if(e=t.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i)){let t=parseInt(e[1],16),i=parseInt(e[2],16),s=parseInt(e[3],16),r=1;return e[4]&&(r=parseInt(e[4],16)/255),new tH(t,i,s,r)}throw Error("Invalid hex string: "+t)}static fromHSL(t,e,i,s=1){return new tV(t,e,i,s).toRGBA()}lighten(t=.1){let e=tV.fromRGBA(this.r,this.g,this.b,this.a);return e.l+=(1-e.l)*t,e.toRGBA()}darken(t=.1){let e=tV.fromRGBA(this.r,this.g,this.b,this.a);return e.l-=e.l*t,e.toRGBA()}saturate(t=.1){let e=tV.fromRGBA(this.r,this.g,this.b,this.a);return e.s+=e.s*t,e.toRGBA()}desaturate(t=.1){let e=tV.fromRGBA(this.r,this.g,this.b,this.a);return e.s-=e.s*t,e.toRGBA()}multiply(t){let e=t.r/255*this.r/255*255;return new tH(e,t.g/255*this.g/255*255,t.b/255*this.b/255*255,t.a*this.a)}screen(t){let e=t.invert(),i=t.invert();return e.multiply(i).invert()}invert(){return new tH(255-this.r,255-this.g,255-this.b,1-this.a)}average(t){let e=(t.r+this.r)/2;return new tH(e,(t.g+this.g)/2,(t.b+this.b)/2,(t.a+this.a)/2)}equal(t){return this.toString()===t.toString()}toString(t="rgb"){switch(t){case"rgb":return this.toRGBA();case"hsl":return this.toHSLA();case"hex":return this.toHex();default:throw Error("Invalid Color format")}}_componentToHex(t){let e=t.toString(16);return 1===e.length?"0"+e:e}toHex(){return"#"+this._componentToHex(this.r)+this._componentToHex(this.g)+this._componentToHex(this.b)}toRGBA(){let t=String(this.r.toFixed(0))+", "+String(this.g.toFixed(0))+", "+String(this.b.toFixed(0));return void 0!==this.a||null!==this.a?"rgba("+t+", "+String(this.a)+")":"rgb("+t+")"}toHSLA(){return tV.fromRGBA(this.r,this.g,this.b,this.a).toString()}fillStyle(){return this.toString()}clone(){return new tH(this.r,this.g,this.b,this.a)}static get Black(){return tH.fromHex("#000000")}static get White(){return tH.fromHex("#FFFFFF")}static get Gray(){return tH.fromHex("#808080")}static get LightGray(){return tH.fromHex("#D3D3D3")}static get DarkGray(){return tH.fromHex("#A9A9A9")}static get Yellow(){return tH.fromHex("#FFFF00")}static get Orange(){return tH.fromHex("#FFA500")}static get Red(){return tH.fromHex("#FF0000")}static get Vermilion(){return tH.fromHex("#FF5B31")}static get Rose(){return tH.fromHex("#FF007F")}static get Magenta(){return tH.fromHex("#FF00FF")}static get Violet(){return tH.fromHex("#7F00FF")}static get Blue(){return tH.fromHex("#0000FF")}static get Azure(){return tH.fromHex("#007FFF")}static get Cyan(){return tH.fromHex("#00FFFF")}static get Viridian(){return tH.fromHex("#59978F")}static get Green(){return tH.fromHex("#00FF00")}static get Chartreuse(){return tH.fromHex("#7FFF00")}static get Transparent(){return tH.fromHex("#FFFFFF00")}static get ExcaliburBlue(){return tH.fromHex("#176BAA")}}class tV{constructor(t,e,i,s){this.h=t,this.s=e,this.l=i,this.a=s}static hue2rgb(t,e,i){return(i<0&&(i+=1),i>1&&(i-=1),i<1/6)?t+(e-t)*6*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}static fromRGBA(t,e,i,s){let r,n;t/=255,e/=255,i/=255;let o=Math.max(t,e,i),a=Math.min(t,e,i),l=(o+a)/2;if(o===a)r=n=0;else{let s=o-a;switch(n=l>.5?s/(2-o-a):s/(o+a),o){case t:r=(e-i)/s+(e=this.defaultLevel&&this._appenders[s].log(t,e)}_logOnce(t,e){let i=t+e.join("+");this._logOnceSet.has(i)||(this._logOnceSet.add(i),this._log(t,e))}debug(...t){this._log(U.Debug,t)}debugOnce(...t){this._logOnce(U.Debug,t)}info(...t){this._log(U.Info,t)}infoOnce(...t){this._logOnce(U.Info,t)}warn(...t){this._log(U.Warn,t)}warnOnce(...t){this._logOnce(U.Warn,t)}error(...t){this._log(U.Error,t)}errorOnce(...t){this._logOnce(U.Error,t)}fatal(...t){this._log(U.Fatal,t)}fatalOnce(...t){this._logOnce(U.Fatal,t)}}tW._INSTANCE=null;class tG{log(t,e){if(!console&&!console.log&&console.warn&&console.error)return;let i=[];i.unshift.apply(i,e),i.unshift("["+U[t]+"] : "),t{this._positionScreenAppenderCanvas()})}_positionScreenAppenderCanvas(){var t,e,i,s;let r=this._options;this.canvas.width=null!==(t=r.width)&&void 0!==t?t:r.engine.screen.resolution.width,this.canvas.height=null!==(e=r.height)&&void 0!==e?e:r.engine.screen.resolution.height,this.canvas.style.position="absolute";let n=r.engine.screen.screenToPageCoordinates(tZ(0,0));this.canvas.style.left=n.x+"px",this.canvas.style.top=n.y+"px",this._pos=null!==(i=r.xPos)&&void 0!==i?i:this._pos,this._color=null!==(s=r.color)&&void 0!==s?s:this._color}log(t,e){let i=e.join(",");this._ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this._messages.unshift("["+U[t]+"] : "+i);let s=10;this._messages=this._messages.slice(0,1e3);for(let t=0;tr&&(r=e[i].dot(t),n=i);return i[n]};class tq{constructor(t=0,e=0,i=0,s=0){this._points=[],"object"==typeof t?(this.left=t.left,this.top=t.top,this.right=t.right,this.bottom=t.bottom):"number"==typeof t&&(this.left=t,this.top=e,this.right=i,this.bottom=s)}clone(){return new tq(this.left,this.top,this.right,this.bottom)}static getSideFromIntersection(t){return t?t?Math.abs(t.x)>Math.abs(t.y)?t.x<0?N.Right:N.Left:t.y<0?N.Bottom:N.Top:N.None:N.None}static fromPoints(t){let e=1/0,i=1/0,s=-1/0,r=-1/0;for(let n=0;ns&&(s=t[n].x),t[n].yr&&(r=t[n].y);return new tq(e,i,s,r)}static fromDimension(t,e,i=tN.Half,s=tN.Zero){return new tq(-t*i.x+s.x,-e*i.y+s.y,t-t*i.x+s.x,e-e*i.y+s.y)}get width(){return this.right-this.left}get height(){return this.bottom-this.top}hasZeroDimensions(){return 0===this.width||0===this.height}get center(){return new tN((this.left+this.right)/2,(this.top+this.bottom)/2)}get topLeft(){return new tN(this.left,this.top)}get bottomRight(){return new tN(this.right,this.bottom)}get topRight(){return new tN(this.right,this.top)}get bottomLeft(){return new tN(this.left,this.bottom)}translate(t){return new tq(this.left+t.x,this.top+t.y,this.right+t.x,this.bottom+t.y)}rotate(t,e=tN.Zero){let i=this.getPoints().map(i=>i.rotate(t,e));return tq.fromPoints(i)}scale(t,e=tN.Zero){let i=this.translate(e);return new tq(i.left*t.x,i.top*t.y,i.right*t.x,i.bottom*t.y)}transform(t){let e=t.data[0]*this.left,i=t.data[1]*this.left,s=t.data[0]*this.right,r=t.data[1]*this.right,n=t.data[2]*this.top,o=t.data[3]*this.top,a=t.data[2]*this.bottom,l=t.data[3]*this.bottom,h=t.getPosition(),d=Math.min(e,s)+Math.min(n,a)+h.x;return new tq({left:d,top:Math.min(i,r)+Math.min(o,l)+h.y,right:Math.max(e,s)+Math.max(n,a)+h.x,bottom:Math.max(i,r)+Math.max(o,l)+h.y})}getPerimeter(){return 2*(this.width+this.height)}getPoints(){return(this._left!==this.left||this._right!==this.right||this._top!==this.top||this._bottom!==this.bottom)&&(this._points.length=0,this._points.push(new tN(this.left,this.top)),this._points.push(new tN(this.right,this.top)),this._points.push(new tN(this.right,this.bottom)),this._points.push(new tN(this.left,this.bottom)),this._left=this.left,this._right=this.right,this._top=this.top,this._bottom=this.bottom),this._points}rayCast(t,e=1/0){let i=-1/0,s=1/0,r=0===t.dir.x?Number.MAX_VALUE:1/t.dir.x,n=0===t.dir.y?Number.MAX_VALUE:1/t.dir.y,o=(this.left-t.pos.x)*r,a=(this.right-t.pos.x)*r;i=Math.min(o,a),s=Math.max(o,a);let l=(this.top-t.pos.y)*n,h=(this.bottom-t.pos.y)*n;return i=Math.max(i,Math.min(l,h)),(s=Math.min(s,Math.max(l,h)))>=Math.max(0,i)&&i=Math.max(0,i)&&i=t.y&&this.right>=t.x:t instanceof tq&&this.left<=t.left&&this.top<=t.top&&t.bottom<=this.bottom&&t.right<=this.right}combine(t){return new tq(Math.min(this.left,t.left),Math.min(this.top,t.top),Math.max(this.right,t.right),Math.max(this.bottom,t.bottom))}get dimensions(){return new tN(this.width,this.height)}overlaps(t,e){let i=e||0;if(t.hasZeroDimensions())return this.contains(t);if(this.hasZeroDimensions())return t.contains(this);let s=this.combine(t);return s.width+i=t.left&&this.right<=t.right?t.left-this.right:t.right-this.left;let i=0;return Math.abs(e)=t.top?t.bottom-this.top:t.top-this.bottom)?new tN(e,0):new tN(0,i)}if(!(e.dimensions.equals(t.dimensions)||e.dimensions.equals(this.dimensions)))return null;{let e=0;e=this.width-t.width>=0?this.right-t.right<=t.left-this.left?t.left-this.right:t.right-this.left:t.right-this.right<=this.left-t.left?this.left-t.right:this.right-t.left;let i=0;return Math.abs(e)=0?this.bottom-t.bottom<=t.top-this.top?t.top-this.bottom:t.bottom-this.top:t.bottom-this.bottom<=this.top-t.top?this.top-t.bottom:this.bottom-t.top)?new tN(e,0):new tN(0,i)}}intersectWithSide(t){let e=this.intersect(t);return tq.getSideFromIntersection(e)}draw(t,e=tH.Yellow){t.debug.drawRect(this.left,this.top,this.width,this.height,{color:e})}}function tX(t){let e=t.getBoundingClientRect();return tZ(e.x+window.scrollX,e.y+window.scrollY)}function t$(t,e){return -1===e.indexOf(t)&&(e.push(t),!0)}function tK(t,e){let i=-1;return(i=e.indexOf(t))>-1&&(e.splice(i,1),!0)}function tY(t,e){for(let i=0;i{s.resolve()},t),s.promise}function t0(t,e){let i={};for(let s in t)e.includes(s)||(i[s]=t[s]);return i}(r=Z||(Z={}))[r.X=12]="X",r[r.Y=13]="Y";class t1{constructor(){this.data=new Float32Array(16),this._scaleX=1,this._scaleSignX=1,this._scaleY=1,this._scaleSignY=1}static ortho(t,e,i,s,r,n){let o=new t1;return o.data[0]=2/(e-t),o.data[1]=0,o.data[2]=0,o.data[3]=0,o.data[4]=0,o.data[5]=2/(s-i),o.data[6]=0,o.data[7]=0,o.data[8]=0,o.data[9]=0,o.data[10]=-2/(n-r),o.data[11]=0,o.data[12]=-(e+t)/(e-t),o.data[13]=-(s+i)/(s-i),o.data[14]=-(n+r)/(n-r),o.data[15]=1,o}clone(t){let e=t||new t1;return e.data[0]=this.data[0],e.data[1]=this.data[1],e.data[2]=this.data[2],e.data[3]=this.data[3],e.data[4]=this.data[4],e.data[5]=this.data[5],e.data[6]=this.data[6],e.data[7]=this.data[7],e.data[8]=this.data[8],e.data[9]=this.data[9],e.data[10]=this.data[10],e.data[11]=this.data[11],e.data[12]=this.data[12],e.data[13]=this.data[13],e.data[14]=this.data[14],e.data[15]=this.data[15],e}toDOMMatrix(){return new DOMMatrix([...this.data])}static fromFloat32Array(t){let e=new t1;return e.data=t,e}static identity(){let t=new t1;return t.data[0]=1,t.data[1]=0,t.data[2]=0,t.data[3]=0,t.data[4]=0,t.data[5]=1,t.data[6]=0,t.data[7]=0,t.data[8]=0,t.data[9]=0,t.data[10]=1,t.data[11]=0,t.data[12]=0,t.data[13]=0,t.data[14]=0,t.data[15]=1,t}reset(){return this.data[0]=1,this.data[1]=0,this.data[2]=0,this.data[3]=0,this.data[4]=0,this.data[5]=1,this.data[6]=0,this.data[7]=0,this.data[8]=0,this.data[9]=0,this.data[10]=1,this.data[11]=0,this.data[12]=0,this.data[13]=0,this.data[14]=0,this.data[15]=1,this}static translation(t,e){let i=t1.identity();return i.data[12]=t,i.data[13]=e,i}static scale(t,e){let i=t1.identity();return i.data[0]=t,i.data[5]=e,i.data[10]=1,i.data[15]=1,i}static rotation(t){let e=t1.identity();return e.data[0]=Math.cos(t),e.data[4]=-Math.sin(t),e.data[1]=Math.sin(t),e.data[5]=Math.cos(t),e}multiply(t,e){if(t instanceof tN){let i=e||new tN(0,0),s=t.x*this.data[0]+t.y*this.data[4]+this.data[12],r=t.x*this.data[1]+t.y*this.data[5]+this.data[13];return i.x=s,i.y=r,i}{let i=e||new t1,s=this.data[0],r=this.data[1],n=this.data[2],o=this.data[3],a=this.data[4],l=this.data[5],h=this.data[6],d=this.data[7],c=this.data[8],u=this.data[9],p=this.data[10],g=this.data[11],_=this.data[12],f=this.data[13],m=this.data[14],v=this.data[15],y=t.data[0],x=t.data[1],w=t.data[2],b=t.data[3],C=t.data[4],T=t.data[5],S=t.data[6],A=t.data[7],E=t.data[8],P=t.data[9],I=t.data[10],k=t.data[11],D=t.data[12],R=t.data[13],F=t.data[14],B=t.data[15];i.data[0]=s*y+a*x+c*w+_*b,i.data[1]=r*y+l*x+u*w+f*b,i.data[2]=n*y+h*x+p*w+m*b,i.data[3]=o*y+d*x+g*w+v*b,i.data[4]=s*C+a*T+c*S+_*A,i.data[5]=r*C+l*T+u*S+f*A,i.data[6]=n*C+h*T+p*S+m*A,i.data[7]=o*C+d*T+g*S+v*A,i.data[8]=s*E+a*P+c*I+_*k,i.data[9]=r*E+l*P+u*I+f*k,i.data[10]=n*E+h*P+p*I+m*k,i.data[11]=o*E+d*P+g*I+v*k,i.data[12]=s*D+a*R+c*F+_*B,i.data[13]=r*D+l*R+u*F+f*B,i.data[14]=n*D+h*R+p*F+m*B,i.data[15]=o*D+d*R+g*F+v*B;let M=this.getScale();return i._scaleSignX=tR(M.x)*tR(i._scaleSignX),i._scaleSignY=tR(M.y)*tR(i._scaleSignY),i}}translate(t,e){let i=this.data[0],s=this.data[1],r=this.data[2],n=this.data[3],o=this.data[4],a=this.data[5],l=this.data[6],h=this.data[7],d=this.data[8],c=this.data[9],u=this.data[10],p=this.data[11],g=this.data[12],_=this.data[13],f=this.data[14],m=this.data[15];return this.data[12]=i*t+o*e+0*d+1*g,this.data[13]=s*t+a*e+0*c+1*_,this.data[14]=r*t+l*e+0*u+1*f,this.data[15]=n*t+h*e+0*p+1*m,this}setPosition(t,e){this.data[12]=t,this.data[13]=e}getPosition(){return tZ(this.data[12],this.data[13])}rotate(t){let e=this.data[0],i=this.data[1],s=this.data[2],r=this.data[3],n=this.data[4],o=this.data[5],a=this.data[6],l=this.data[7],h=Math.sin(t),d=Math.cos(t);return this.data[0]=d*e+h*n,this.data[1]=d*i+h*o,this.data[2]=d*s+h*a,this.data[3]=d*r+h*l,this.data[4]=d*n-h*e,this.data[5]=d*o-h*i,this.data[6]=d*a-h*s,this.data[7]=d*l-h*r,this}scale(t,e){let i=this.data[0],s=this.data[1],r=this.data[2],n=this.data[3],o=this.data[4],a=this.data[5],l=this.data[6],h=this.data[7];return this.data[0]=i*t,this.data[1]=s*t,this.data[2]=r*t,this.data[3]=n*t,this.data[4]=o*e,this.data[5]=a*e,this.data[6]=l*e,this.data[7]=h*e,this}setRotation(t){let e=this.getScale(),i=Math.sin(t),s=Math.cos(t);this.data[0]=s*e.x,this.data[1]=i*e.y,this.data[4]=-i*e.x,this.data[5]=s*e.y}getRotation(){return tB(Math.atan2(this.data[1]/this.getScaleY(),this.data[0]/this.getScaleX()))}getScaleX(){let t=tZ(this.data[0],this.data[4]).size;return this._scaleSignX*t}getScaleY(){let t=tZ(this.data[1],this.data[5]).size;return this._scaleSignY*t}getScale(){return tZ(this.getScaleX(),this.getScaleY())}setScaleX(t){if(this._scaleX===t)return;this._scaleSignX=tR(t);let e=tZ(this.data[0]*this._scaleSignX,this.data[4]*this._scaleSignX).normalize();this.data[0]=e.x*t,this.data[4]=e.y*t,this._scaleX=t}setScaleY(t){if(this._scaleY===t)return;this._scaleSignY=tR(t);let e=tZ(this.data[1]*this._scaleSignY,this.data[5]*this._scaleSignY).normalize();this.data[1]=e.x*t,this.data[5]=e.y*t,this._scaleY=t}setScale(t){this.setScaleX(t.x),this.setScaleY(t.y)}getBasisDeterminant(){return this.data[0]*this.data[5]-this.data[1]*this.data[4]}getAffineInverse(t){let e=1/this.getBasisDeterminant(),i=this.data[0],s=this.data[4],r=this.data[1],n=this.data[5],o=t||t1.identity();o.data[0]=n*e,o.data[1]=-r*e,o.data[4]=-s*e,o.data[5]=i*e;let a=this.data[12],l=this.data[13];return o.data[12]=-(a*o.data[0]+l*o.data[4]),o.data[13]=-(a*o.data[1]+l*o.data[5]),o}isIdentity(){return 1===this.data[0]&&0===this.data[1]&&0===this.data[2]&&0===this.data[3]&&0===this.data[4]&&1===this.data[5]&&0===this.data[6]&&0===this.data[7]&&0===this.data[8]&&0===this.data[9]&&1===this.data[10]&&0===this.data[11]&&0===this.data[12]&&0===this.data[13]&&0===this.data[14]&&1===this.data[15]}toString(){return` +}`,"",{version:3,sources:["webpack://./Util/Toaster.css"],names:[],mappings:";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB",sourcesContent:["\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}"],sourceRoot:""}]);let a=o},2609:t=>{t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var i="",s=void 0!==e[5];return e[4]&&(i+="@supports (".concat(e[4],") {")),e[2]&&(i+="@media ".concat(e[2]," {")),s&&(i+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),i+=t(e),s&&(i+="}"),e[2]&&(i+="}"),e[4]&&(i+="}"),i}).join("")},e.i=function(t,i,s,r,n){"string"==typeof t&&(t=[[null,t,void 0]]);var o={};if(s)for(var a=0;a0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=n),i&&(d[2]&&(d[1]="@media ".concat(d[2]," {").concat(d[1],"}")),d[2]=i),r&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=r):d[4]="".concat(r)),e.push(d))}},e}},272:t=>{t.exports=function(t){var e=t[1],i=t[3];if(!i)return e;if("function"==typeof btoa){var s=btoa(unescape(encodeURIComponent(JSON.stringify(i))));return[e].concat(["/*# ".concat("sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(s)," */")]).join("\n")}return[e].join("\n")}},1324:(t,e,i)=>{i(7206);var s=i(8193);t.exports=s("Array","sort")},3571:(t,e,i)=>{i(9867);var s=i(8588);t.exports=s.Object.keys},1052:(t,e,i)=>{var s=i(688),r=i(3397),n=TypeError;t.exports=function(t){if(s(t))return t;throw new n(r(t)+" is not a function")}},9175:(t,e,i)=>{var s=i(5309),r=String,n=TypeError;t.exports=function(t){if(s(t))return t;throw new n(r(t)+" is not an object")}},1138:(t,e,i)=>{var s=i(6854),r=i(7352),n=i(8344),o=function(t){return function(e,i,o){var a,l=s(e),h=n(l),d=r(o,h);if(t&&i!=i){for(;h>d;)if((a=l[d++])!=a)return!0}else for(;h>d;d++)if((t||d in l)&&l[d]===i)return t||d||0;return!t&&-1}};t.exports={includes:o(!0),indexOf:o(!1)}},567:(t,e,i)=>{var s=i(4694);t.exports=function(t,e){var i=[][t];return!!i&&s(function(){i.call(null,e||function(){return 1},1)})}},7686:(t,e,i)=>{var s=i(9668);t.exports=s([].slice)},3097:(t,e,i)=>{var s=i(7686),r=Math.floor,n=function(t,e){var i=t.length;if(i<8)for(var o,a,l=1;l0;)t[a]=t[--a];a!==l++&&(t[a]=o)}else for(var h=r(i/2),d=n(s(t,0,h),e),c=n(s(t,h),e),u=d.length,p=c.length,g=0,_=0;g=e(d[g],c[_])?d[g++]:c[_++]:g{var s=i(9668),r=s({}.toString),n=s("".slice);t.exports=function(t){return n(r(t),8,-1)}},1566:(t,e,i)=>{var s=i(2522),r=i(688),n=i(2177),o=i(2032)("toStringTag"),a=Object,l="Arguments"===n(function(){return arguments}()),h=function(t,e){try{return t[e]}catch(t){}};t.exports=s?n:function(t){var e,i,s;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(i=h(e=a(t),o))?i:l?n(e):"Object"===(s=n(e))&&r(e.callee)?"Arguments":s}},3891:(t,e,i)=>{var s=i(4678),r=i(990),n=i(7537),o=i(2131);t.exports=function(t,e,i){for(var a=r(e),l=o.f,h=n.f,d=0;d{var s=i(9924),r=i(2131),n=i(7781);t.exports=s?function(t,e,i){return r.f(t,e,n(1,i))}:function(t,e,i){return t[e]=i,t}},7781:t=>{t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},2470:(t,e,i)=>{var s=i(688),r=i(2131),n=i(1135),o=i(1604);t.exports=function(t,e,i,a){a||(a={});var l=a.enumerable,h=void 0!==a.name?a.name:e;if(s(i)&&n(i,h,a),a.global)l?t[e]=i:o(e,i);else{try{a.unsafe?t[e]&&(l=!0):delete t[e]}catch(t){}l?t[e]=i:r.f(t,e,{value:i,enumerable:!1,configurable:!a.nonConfigurable,writable:!a.nonWritable})}return t}},1604:(t,e,i)=>{var s=i(2150),r=Object.defineProperty;t.exports=function(t,e){try{r(s,t,{value:e,configurable:!0,writable:!0})}catch(i){s[t]=e}return e}},955:(t,e,i)=>{var s=i(3397),r=TypeError;t.exports=function(t,e){if(!delete t[e])throw new r("Cannot delete property "+s(e)+" of "+s(t))}},9924:(t,e,i)=>{var s=i(4694);t.exports=!s(function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]})},1442:(t,e,i)=>{var s=i(2150),r=i(5309),n=s.document,o=r(n)&&r(n.createElement);t.exports=function(t){return o?n.createElement(t):{}}},9016:(t,e,i)=>{var s=i(1370).match(/firefox\/(\d+)/i);t.exports=!!s&&+s[1]},821:(t,e,i)=>{var s=i(1370);t.exports=/MSIE|Trident/.test(s)},1370:t=>{t.exports="undefined"!=typeof navigator&&String(navigator.userAgent)||""},7067:(t,e,i)=>{var s,r,n=i(2150),o=i(1370),a=n.process,l=n.Deno,h=a&&a.versions||l&&l.version,d=h&&h.v8;d&&(r=(s=d.split("."))[0]>0&&s[0]<4?1:+(s[0]+s[1])),!r&&o&&(!(s=o.match(/Edge\/(\d+)/))||s[1]>=74)&&(s=o.match(/Chrome\/(\d+)/))&&(r=+s[1]),t.exports=r},4389:(t,e,i)=>{var s=i(1370).match(/AppleWebKit\/(\d+)\./);t.exports=!!s&&+s[1]},8193:(t,e,i)=>{var s=i(2150),r=i(9668);t.exports=function(t,e){return r(s[t].prototype[e])}},2367:t=>{t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},5532:(t,e,i)=>{var s=i(2150),r=i(7537).f,n=i(2385),o=i(2470),a=i(1604),l=i(3891),h=i(1633);t.exports=function(t,e){var i,d,c,u,p,g=t.target,_=t.global,f=t.stat;if(i=_?s:f?s[g]||a(g,{}):s[g]&&s[g].prototype)for(d in e){if(u=e[d],c=t.dontCallGetSet?(p=r(i,d))&&p.value:i[d],!h(_?d:g+(f?".":"#")+d,t.forced)&&void 0!==c){if(typeof u==typeof c)continue;l(u,c)}(t.sham||c&&c.sham)&&n(u,"sham",!0),o(i,d,u,t)}}},4694:t=>{t.exports=function(t){try{return!!t()}catch(t){return!0}}},6398:(t,e,i)=>{var s=i(4694);t.exports=!s(function(){var t=(function(){}).bind();return"function"!=typeof t||t.hasOwnProperty("prototype")})},8724:(t,e,i)=>{var s=i(6398),r=Function.prototype.call;t.exports=s?r.bind(r):function(){return r.apply(r,arguments)}},453:(t,e,i)=>{var s=i(9924),r=i(4678),n=Function.prototype,o=s&&Object.getOwnPropertyDescriptor,a=r(n,"name"),l=a&&(!s||s&&o(n,"name").configurable);t.exports={EXISTS:a,PROPER:a&&"something"===(function(){}).name,CONFIGURABLE:l}},9668:(t,e,i)=>{var s=i(6398),r=Function.prototype,n=r.call,o=s&&r.bind.bind(n,n);t.exports=s?o:function(t){return function(){return n.apply(t,arguments)}}},2160:(t,e,i)=>{var s=i(2150),r=i(688);t.exports=function(t,e){var i;return arguments.length<2?r(i=s[t])?i:void 0:s[t]&&s[t][e]}},5383:(t,e,i)=>{var s=i(1052),r=i(5268);t.exports=function(t,e){var i=t[e];return r(i)?void 0:s(i)}},2150:function(t,e,i){var s=function(t){return t&&t.Math===Math&&t};t.exports=s("object"==typeof globalThis&&globalThis)||s("object"==typeof window&&window)||s("object"==typeof self&&self)||s("object"==typeof i.g&&i.g)||s("object"==typeof this&&this)||function(){return this}()||Function("return this")()},4678:(t,e,i)=>{var s=i(9668),r=i(298),n=s({}.hasOwnProperty);t.exports=Object.hasOwn||function(t,e){return n(r(t),e)}},7390:t=>{t.exports={}},7913:(t,e,i)=>{var s=i(9924),r=i(4694),n=i(1442);t.exports=!s&&!r(function(){return 7!==Object.defineProperty(n("div"),"a",{get:function(){return 7}}).a})},4347:(t,e,i)=>{var s=i(9668),r=i(4694),n=i(2177),o=Object,a=s("".split);t.exports=r(function(){return!o("z").propertyIsEnumerable(0)})?function(t){return"String"===n(t)?a(t,""):o(t)}:o},1881:(t,e,i)=>{var s=i(9668),r=i(688),n=i(6762),o=s(Function.toString);r(n.inspectSource)||(n.inspectSource=function(t){return o(t)}),t.exports=n.inspectSource},7804:(t,e,i)=>{var s,r,n,o=i(4724),a=i(2150),l=i(5309),h=i(2385),d=i(4678),c=i(6762),u=i(1962),p=i(7390),g="Object already initialized",_=a.TypeError,f=a.WeakMap;if(o||c.state){var m=c.state||(c.state=new f);m.get=m.get,m.has=m.has,m.set=m.set,s=function(t,e){if(m.has(t))throw new _(g);return e.facade=t,m.set(t,e),e},r=function(t){return m.get(t)||{}},n=function(t){return m.has(t)}}else{var v=u("state");p[v]=!0,s=function(t,e){if(d(t,v))throw new _(g);return e.facade=t,h(t,v,e),e},r=function(t){return d(t,v)?t[v]:{}},n=function(t){return d(t,v)}}t.exports={set:s,get:r,has:n,enforce:function(t){return n(t)?r(t):s(t,{})},getterFor:function(t){return function(e){var i;if(!l(e)||(i=r(e)).type!==t)throw new _("Incompatible receiver, "+t+" required");return i}}}},688:t=>{var e="object"==typeof document&&document.all;t.exports=void 0===e&&void 0!==e?function(t){return"function"==typeof t||t===e}:function(t){return"function"==typeof t}},1633:(t,e,i)=>{var s=i(4694),r=i(688),n=/#|\.prototype\./,o=function(t,e){var i=l[a(t)];return i===d||i!==h&&(r(e)?s(e):!!e)},a=o.normalize=function(t){return String(t).replace(n,".").toLowerCase()},l=o.data={},h=o.NATIVE="N",d=o.POLYFILL="P";t.exports=o},5268:t=>{t.exports=function(t){return null==t}},5309:(t,e,i)=>{var s=i(688);t.exports=function(t){return"object"==typeof t?null!==t:s(t)}},6555:t=>{t.exports=!1},7935:(t,e,i)=>{var s=i(2160),r=i(688),n=i(6148),o=i(4866),a=Object;t.exports=o?function(t){return"symbol"==typeof t}:function(t){var e=s("Symbol");return r(e)&&n(e.prototype,a(t))}},8344:(t,e,i)=>{var s=i(7331);t.exports=function(t){return s(t.length)}},1135:(t,e,i)=>{var s=i(9668),r=i(4694),n=i(688),o=i(4678),a=i(9924),l=i(453).CONFIGURABLE,h=i(1881),d=i(7804),c=d.enforce,u=d.get,p=String,g=Object.defineProperty,_=s("".slice),f=s("".replace),m=s([].join),v=a&&!r(function(){return 8!==g(function(){},"length",{value:8}).length}),y=String(String).split("String"),x=t.exports=function(t,e,i){"Symbol("===_(p(e),0,7)&&(e="["+f(p(e),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),i&&i.getter&&(e="get "+e),i&&i.setter&&(e="set "+e),(!o(t,"name")||l&&t.name!==e)&&(a?g(t,"name",{value:e,configurable:!0}):t.name=e),v&&i&&o(i,"arity")&&t.length!==i.arity&&g(t,"length",{value:i.arity});try{i&&o(i,"constructor")&&i.constructor?a&&g(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var s=c(t);return o(s,"source")||(s.source=m(y,"string"==typeof e?e:"")),t};Function.prototype.toString=x(function(){return n(this)&&u(this).source||h(this)},"toString")},1787:t=>{var e=Math.ceil,i=Math.floor;t.exports=Math.trunc||function(t){var s=+t;return(s>0?i:e)(s)}},2131:(t,e,i)=>{var s=i(9924),r=i(7913),n=i(2666),o=i(9175),a=i(2358),l=TypeError,h=Object.defineProperty,d=Object.getOwnPropertyDescriptor,c="enumerable",u="configurable",p="writable";e.f=s?n?function(t,e,i){if(o(t),e=a(e),o(i),"function"==typeof t&&"prototype"===e&&"value"in i&&p in i&&!i[p]){var s=d(t,e);s&&s[p]&&(t[e]=i.value,i={configurable:u in i?i[u]:s[u],enumerable:c in i?i[c]:s[c],writable:!1})}return h(t,e,i)}:h:function(t,e,i){if(o(t),e=a(e),o(i),r)try{return h(t,e,i)}catch(t){}if("get"in i||"set"in i)throw new l("Accessors not supported");return"value"in i&&(t[e]=i.value),t}},7537:(t,e,i)=>{var s=i(9924),r=i(8724),n=i(8208),o=i(7781),a=i(6854),l=i(2358),h=i(4678),d=i(7913),c=Object.getOwnPropertyDescriptor;e.f=s?c:function(t,e){if(t=a(t),e=l(e),d)try{return c(t,e)}catch(t){}if(h(t,e))return o(!r(n.f,t,e),t[e])}},6217:(t,e,i)=>{var s=i(1528),r=i(2367).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return s(t,r)}},5168:(t,e)=>{e.f=Object.getOwnPropertySymbols},6148:(t,e,i)=>{var s=i(9668);t.exports=s({}.isPrototypeOf)},1528:(t,e,i)=>{var s=i(9668),r=i(4678),n=i(6854),o=i(1138).indexOf,a=i(7390),l=s([].push);t.exports=function(t,e){var i,s=n(t),h=0,d=[];for(i in s)!r(a,i)&&r(s,i)&&l(d,i);for(;e.length>h;)r(s,i=e[h++])&&(~o(d,i)||l(d,i));return d}},1728:(t,e,i)=>{var s=i(1528),r=i(2367);t.exports=Object.keys||function(t){return s(t,r)}},8208:(t,e)=>{var i={}.propertyIsEnumerable,s=Object.getOwnPropertyDescriptor,r=s&&!i.call({1:2},1);e.f=r?function(t){var e=s(this,t);return!!e&&e.enumerable}:i},110:(t,e,i)=>{var s=i(8724),r=i(688),n=i(5309),o=TypeError;t.exports=function(t,e){var i,a;if("string"===e&&r(i=t.toString)&&!n(a=s(i,t))||r(i=t.valueOf)&&!n(a=s(i,t))||"string"!==e&&r(i=t.toString)&&!n(a=s(i,t)))return a;throw new o("Can't convert object to primitive value")}},990:(t,e,i)=>{var s=i(2160),r=i(9668),n=i(6217),o=i(5168),a=i(9175),l=r([].concat);t.exports=s("Reflect","ownKeys")||function(t){var e=n.f(a(t)),i=o.f;return i?l(e,i(t)):e}},8588:(t,e,i)=>{var s=i(2150);t.exports=s},1166:(t,e,i)=>{var s=i(5268),r=TypeError;t.exports=function(t){if(s(t))throw new r("Can't call method on "+t);return t}},1962:(t,e,i)=>{var s=i(2645),r=i(5736),n=s("keys");t.exports=function(t){return n[t]||(n[t]=r(t))}},6762:(t,e,i)=>{var s=i(2150),r=i(1604),n="__core-js_shared__",o=s[n]||r(n,{});t.exports=o},2645:(t,e,i)=>{var s=i(6555),r=i(6762);(t.exports=function(t,e){return r[t]||(r[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.35.1",mode:s?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE",source:"https://github.com/zloirock/core-js"})},4112:(t,e,i)=>{var s=i(7067),r=i(4694),n=i(2150).String;t.exports=!!Object.getOwnPropertySymbols&&!r(function(){var t=Symbol("symbol detection");return!n(t)||!(Object(t) instanceof Symbol)||!Symbol.sham&&s&&s<41})},7352:(t,e,i)=>{var s=i(1680),r=Math.max,n=Math.min;t.exports=function(t,e){var i=s(t);return i<0?r(i+e,0):n(i,e)}},6854:(t,e,i)=>{var s=i(4347),r=i(1166);t.exports=function(t){return s(r(t))}},1680:(t,e,i)=>{var s=i(1787);t.exports=function(t){var e=+t;return e!=e||0===e?0:s(e)}},7331:(t,e,i)=>{var s=i(1680),r=Math.min;t.exports=function(t){var e=s(t);return e>0?r(e,9007199254740991):0}},298:(t,e,i)=>{var s=i(1166),r=Object;t.exports=function(t){return r(s(t))}},1272:(t,e,i)=>{var s=i(8724),r=i(5309),n=i(7935),o=i(5383),a=i(110),l=i(2032),h=TypeError,d=l("toPrimitive");t.exports=function(t,e){if(!r(t)||n(t))return t;var i,l=o(t,d);if(l){if(void 0===e&&(e="default"),!r(i=s(l,t,e))||n(i))return i;throw new h("Can't convert object to primitive value")}return void 0===e&&(e="number"),a(t,e)}},2358:(t,e,i)=>{var s=i(1272),r=i(7935);t.exports=function(t){var e=s(t,"string");return r(e)?e:e+""}},2522:(t,e,i)=>{var s=i(2032)("toStringTag"),r={};r[s]="z",t.exports="[object z]"===String(r)},599:(t,e,i)=>{var s=i(1566),r=String;t.exports=function(t){if("Symbol"===s(t))throw TypeError("Cannot convert a Symbol value to a string");return r(t)}},3397:t=>{var e=String;t.exports=function(t){try{return e(t)}catch(t){return"Object"}}},5736:(t,e,i)=>{var s=i(9668),r=0,n=Math.random(),o=s(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+o(++r+n,36)}},4866:(t,e,i)=>{var s=i(4112);t.exports=s&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},2666:(t,e,i)=>{var s=i(9924),r=i(4694);t.exports=s&&r(function(){return 42!==Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype})},4724:(t,e,i)=>{var s=i(2150),r=i(688),n=s.WeakMap;t.exports=r(n)&&/native code/.test(String(n))},2032:(t,e,i)=>{var s=i(2150),r=i(2645),n=i(4678),o=i(5736),a=i(4112),l=i(4866),h=s.Symbol,d=r("wks"),c=l?h.for||h:h&&h.withoutSetter||o;t.exports=function(t){return n(d,t)||(d[t]=a&&n(h,t)?h[t]:c("Symbol."+t)),d[t]}},7206:(t,e,i)=>{var s=i(5532),r=i(9668),n=i(1052),o=i(298),a=i(8344),l=i(955),h=i(599),d=i(4694),c=i(3097),u=i(567),p=i(9016),g=i(821),_=i(7067),f=i(4389),m=[],v=r(m.sort),y=r(m.push),x=d(function(){m.sort(void 0)}),w=d(function(){m.sort(null)}),b=u("sort"),C=!d(function(){if(_)return _<70;if(!p||!(p>3)){if(g)return!0;if(f)return f<603;var t,e,i,s,r="";for(t=65;t<76;t++){switch(e=String.fromCharCode(t),t){case 66:case 69:case 70:case 72:i=3;break;case 68:case 71:i=4;break;default:i=2}for(s=0;s<47;s++)m.push({k:e+s,v:i})}for(m.sort(function(t,e){return e.v-t.v}),s=0;sh(i)?1:-1}),e=a(r),i=0;i{var s=i(5532),r=i(298),n=i(1728);s({target:"Object",stat:!0,forced:i(4694)(function(){n(1)})},{keys:function(t){return n(r(t))}})}},r={};function n(t){var e=r[t];if(void 0!==e)return e.exports;var i=r[t]={id:t,exports:{}};return s[t].call(i.exports,i,i.exports,n),i.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var i in e)n.o(e,i)&&!n.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};(()=>{n.d(o,{y1j:()=>iy,fWn:()=>sN,Ia8:()=>sb,rqv:()=>nl,zH6:()=>iv,hLI:()=>sZ,yyv:()=>rE,tX5:()=>ic,vtX:()=>sj,r7K:()=>sd,cE4:()=>t2,fwF:()=>rv,sce:()=>to,AQ6:()=>rm,_c7:()=>ta,KUs:()=>rp,Ajp:()=>eM,dkO:()=>tc,RDh:()=>tr,_H9:()=>te,mxs:()=>sB,OmD:()=>sh,kBf:()=>tq,C4F:()=>X,NQt:()=>r0,JjN:()=>r1,EK_:()=>td,V1s:()=>s7,xHm:()=>s6,Xz7:()=>eU,Cdc:()=>sy,FKn:()=>st,SUY:()=>r3,ab2:()=>i7,GfZ:()=>i8,YMS:()=>iJ,oyv:()=>sl,aUb:()=>se,SdD:()=>ih,JUv:()=>ij,jEj:()=>iG,TFq:()=>ss,HDU:()=>ia,R_y:()=>io,t50:()=>il,s$$:()=>rf,v2G:()=>G,Ilk:()=>tH,s9i:()=>rK,dxL:()=>tm,LLX:()=>r$,wA2:()=>iZ,R_p:()=>i9,IQ$:()=>rx,I5F:()=>tG,X8$:()=>rg,FR6:()=>ir,pTZ:()=>K,U8o:()=>is,kbG:()=>j,FEv:()=>nI,iS_:()=>iu,cGG:()=>sn,ETM:()=>rY,RPN:()=>sY,skb:()=>rS,SLU:()=>eo,Q3w:()=>r2,xK2:()=>iE,vrO:()=>i4,EA2:()=>r5,RdJ:()=>Y,cNu:()=>sM,wtG:()=>i3,gU7:()=>iM,LSk:()=>sz,Nmp:()=>ts,twX:()=>ne,UND:()=>nt,d1Y:()=>V,xrL:()=>iK,sRW:()=>iQ,cmV:()=>nU,qWz:()=>sF,N0Q:()=>sR,q8b:()=>sw,ynB:()=>sr,jT9:()=>s4,wAz:()=>tl,D4V:()=>ns,NLr:()=>ni,N6H:()=>i_,W1A:()=>ig,JHW:()=>s_,ZZ$:()=>sg,v2K:()=>rr,pBf:()=>nr,vpe:()=>tP,GMl:()=>W,zW2:()=>tx,B0K:()=>eN,Nv7:()=>eR,C_p:()=>ek,MUA:()=>im,xqU:()=>ip,pTp:()=>sL,trb:()=>nP,vUK:()=>tS,j9l:()=>sO,Zxw:()=>sW,v51:()=>sV,gYv:()=>nS,Hdx:()=>ti,Z$d:()=>J,iqV:()=>r4,o$7:()=>rQ,olM:()=>tE,Zm$:()=>eV,$QH:()=>eq,i78:()=>eX,nJg:()=>rF,h6u:()=>e7,hts:()=>e6,j88:()=>e3,VME:()=>e9,fy2:()=>rR,nt:()=>ny,Ukr:()=>rO,zsu:()=>et,oA6:()=>sm,TVh:()=>ry,xxj:()=>rT,XdK:()=>it,fBD:()=>i2,Jmb:()=>H,cXo:()=>es,Dm5:()=>id,IIB:()=>tb,IX$:()=>rV,ebW:()=>rB,zI0:()=>$,LYD:()=>rP,cEG:()=>rI,SEl:()=>na,t9V:()=>no,ez5:()=>rM,N1d:()=>rz,R8U:()=>tu,SKZ:()=>eW,__J:()=>nn,RI$:()=>s9,x12:()=>nk,ccz:()=>i6,aNw:()=>iB,XrL:()=>iS,xwn:()=>s5,dNK:()=>s2,ini:()=>U,YdH:()=>tW,F5T:()=>eA,y3G:()=>t1,l57:()=>Z,xn0:()=>ix,t2V:()=>sU,uxB:()=>iW,cpd:()=>ru,fiy:()=>sS,$XZ:()=>sA,UG6:()=>tg,uqK:()=>iw,STE:()=>ib,Hq9:()=>i5,y$z:()=>iH,mAD:()=>rk,sOq:()=>iq,hUw:()=>sK,_0G:()=>nh,Sqs:()=>nT,hpZ:()=>rb,Vol:()=>rC,vYX:()=>th,wIZ:()=>i0,cBi:()=>rJ,c30:()=>rD,PGK:()=>rZ,MPV:()=>t_,RFv:()=>sx,Ux6:()=>rU,rxy:()=>rH,I$c:()=>O,kfC:()=>rA,VjY:()=>tf,mgq:()=>nD,YVA:()=>so,Kgp:()=>eC,HH$:()=>ii,M_d:()=>e0,rgh:()=>eK,Ra6:()=>e4,KhR:()=>ej,gvQ:()=>eQ,BS5:()=>e2,xhz:()=>ie,xOq:()=>eJ,a9j:()=>e$,bHk:()=>e5,CgK:()=>eG,A0M:()=>rW,cEd:()=>eY,cuY:()=>e1,kvE:()=>iX,SBu:()=>ey,PsT:()=>nd,AE_:()=>rn,ctO:()=>ra,OLH:()=>s3,kky:()=>tI,nSF:()=>eO,zHn:()=>iY,zwx:()=>r_,AeJ:()=>sv,hLz:()=>su,wA:()=>sC,jhr:()=>sT,GVs:()=>eF,_zO:()=>t9,LXZ:()=>t3,w6$:()=>sP,mhV:()=>sE,MOD:()=>Q,kwd:()=>sk,Lmr:()=>sI,xsS:()=>rq,K5l:()=>rG,lLr:()=>eL,Z$r:()=>tj,IXb:()=>sX,Xsu:()=>eB,SGH:()=>rX,SMj:()=>tv,L34:()=>nO,exe:()=>eu,bnF:()=>sa,MFA:()=>N,kPj:()=>q,$uU:()=>iT,Sap:()=>iC,jyi:()=>ee,E03:()=>er,V6q:()=>en,rg2:()=>r9,DVW:()=>eZ,nVo:()=>s1,F6N:()=>nb,xP7:()=>rs,Odq:()=>rh,uY9:()=>ri,Zif:()=>tn,c_d:()=>ro,MJk:()=>r6,xvT:()=>sG,PHM:()=>tt,dpR:()=>ei,n9L:()=>s0,KwO:()=>sJ,SxM:()=>sQ,B7y:()=>s$,x7r:()=>r8,wx7:()=>iU,Uvn:()=>iV,uTP:()=>nE,OFT:()=>i$,xzN:()=>re,CcZ:()=>s8,M5Z:()=>tk,ZrN:()=>tC,OWs:()=>tN,dF9:()=>iz,oZy:()=>ep,rD2:()=>eg,KmN:()=>i1,VHo:()=>e8,ohE:()=>ez,R$E:()=>eH,xQN:()=>tp,AdJ:()=>rN,q3I:()=>rd,Pab:()=>tB,uZ5:()=>tF,TAE:()=>nA,McK:()=>tA,F9c:()=>tD,k0b:()=>sf,hnT:()=>nu,RSJ:()=>nf,Mku:()=>ng,h90:()=>nv,rms:()=>nm,ErP:()=>nc,aVg:()=>n_,lPc:()=>np,Z8E:()=>sc,k15:()=>iN,YsU:()=>iA,lNv:()=>sp,Xyg:()=>rj,cu9:()=>sq,p88:()=>rl,MZQ:()=>nR,FUM:()=>nM,BxR:()=>eP,vdf:()=>tO,iaL:()=>tU,w6H:()=>tz,Q4c:()=>nB,Xxe:()=>tR,Uxb:()=>tL,Yr5:()=>tM,Bhw:()=>tZ,yOA:()=>ty});var t,e,i,s,r,a,l,h,d,c,u,p,g,_,f,m,v,y,x,w,b,C,T,S,A,E,P,I,k,D,R,F,B,L,M,z,O,U,N,Z,H,V,W,G,j,q,X,$,K,Y,Q,J,tt,te,ti,ts,tr,tn,to,ta,tl,th,td,tc,tu,tp,tg,t_,tf,tm,tv,ty={};n.r(ty),n.d(ty,{getAttributeComponentSize:()=>ed,getAttributePointerType:()=>ec,getGlTypeSizeBytes:()=>eh});var tx={};n.r(tx),n.d(tx,{ActionCompleteEvent:()=>iy,ActionStartEvent:()=>iv,ActivateEvent:()=>ic,CollisionEndEvent:()=>ih,CollisionPostSolveEvent:()=>ia,CollisionPreSolveEvent:()=>io,CollisionStartEvent:()=>il,ContactEndEvent:()=>ir,ContactStartEvent:()=>is,DeactivateEvent:()=>iu,EnterTriggerEvent:()=>i_,EnterViewPortEvent:()=>ig,EventTypes:()=>W,ExitTriggerEvent:()=>im,ExitViewPortEvent:()=>ip,GameEvent:()=>eV,GameStartEvent:()=>eq,GameStopEvent:()=>eX,GamepadAxisEvent:()=>e7,GamepadButtonEvent:()=>e6,GamepadConnectEvent:()=>e3,GamepadDisconnectEvent:()=>e9,HiddenEvent:()=>it,InitializeEvent:()=>id,KillEvent:()=>eW,PostCollisionEvent:()=>ii,PostDebugDrawEvent:()=>e0,PostDrawEvent:()=>eK,PostFrameEvent:()=>e4,PostKillEvent:()=>ej,PostTransformDrawEvent:()=>eQ,PostUpdateEvent:()=>e2,PreCollisionEvent:()=>ie,PreDebugDrawEvent:()=>eJ,PreDrawEvent:()=>e$,PreFrameEvent:()=>e5,PreKillEvent:()=>eG,PreTransformDrawEvent:()=>eY,PreUpdateEvent:()=>e1,VisibleEvent:()=>e8});var tw={};n.r(tw),n.d(tw,{circle:()=>iR,line:()=>iP,point:()=>iI,roundRect:()=>iD,vector:()=>ik});var tb={};n.r(tb),n.d(tb,{Axes:()=>tc,Buttons:()=>td,Gamepad:()=>rF,Gamepads:()=>rR,KeyEvent:()=>rM,Keyboard:()=>rz,Keys:()=>tu,NativePointerButton:()=>tg,PointerButton:()=>t_,PointerComponent:()=>sx,PointerEvent:()=>rU,PointerEventReceiver:()=>rH,PointerScope:()=>O,PointerSystem:()=>rA,PointerType:()=>tf,WheelDeltaMode:()=>tp,WheelEvent:()=>rN});var tC={};function tT(){if("undefined"==typeof window&&(window={audioContext:function(){}}),"undefined"==typeof window||window.requestAnimationFrame||(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setInterval(t,1e3/60)}),"undefined"==typeof window||window.cancelAnimationFrame||(window.cancelAnimationFrame=window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(){}),"undefined"!=typeof window&&!window.AudioContext){if(window.webkitAudioContext){let t=window.webkitAudioContext.prototype.decodeAudioData;window.webkitAudioContext.prototype.decodeAudioData=function(e){return new Promise((i,s)=>{t.call(this,e,i,s)})}}window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext}"undefined"==typeof window||window.devicePixelRatio||(window.devicePixelRatio=window.devicePixelRatio||1)}n.r(tC),n.d(tC,{ConsoleAppender:()=>tG,DrawUtil:()=>tw,EasingFunctions:()=>sw,LogLevel:()=>U,Logger:()=>tW,Observable:()=>iH,ScreenAppender:()=>tj,addItemToArray:()=>t$,contains:()=>tY,delay:()=>tJ,fail:()=>tQ,getPosition:()=>tX,omit:()=>t0,removeItemFromArray:()=>tK}),n(1324),n(3571);class tS{static useCanvasGraphicsContext(){tS.enable("use-canvas-context")}static freeze(){tS._FROZEN=!0}static _reset(){tS._FROZEN=!1,tS._FLAGS={}}static enable(t){if(this._FROZEN)throw Error("Feature flags can only be enabled before Engine constructor time");tS._FLAGS[t]=!0}static disable(t){if(this._FROZEN)throw Error("Feature flags can only be disabled before Engine constructor time");tS._FLAGS[t]=!1}static isEnabled(t){return!!tS._FLAGS[t]}static show(){return Object.keys(tS._FLAGS)}}function tA(t,e){return{type:t,value:e}}tS._FROZEN=!1,tS._FLAGS={};class tE{constructor(){this._isCompleted=!1,this.promise=new Promise((t,e)=>{this._resolver=t,this._rejecter=e})}get isCompleted(){return this._isCompleted}resolve(t){this._isCompleted||(this._isCompleted=!0,this._resolver(t))}reject(t){this._isCompleted||(this._isCompleted=!0,this._rejecter(t))}}class tP{constructor(){this._paused=!1,this._listeners={},this._listenersOnce={},this._pipes=[]}clear(){this._listeners={},this._listenersOnce={},this._pipes.length=0}on(t,e){var i;return this._listeners[t]=null!==(i=this._listeners[t])&&void 0!==i?i:[],this._listeners[t].push(e),{close:()=>this.off(t,e)}}once(t,e){var i;return this._listenersOnce[t]=null!==(i=this._listenersOnce[t])&&void 0!==i?i:[],this._listenersOnce[t].push(e),{close:()=>this.off(t,e)}}off(t,e){var i,s;if(e){let r=null===(i=this._listeners[t])||void 0===i?void 0:i.filter(t=>t!==e);this._listeners[t]=r;let n=null===(s=this._listenersOnce[t])||void 0===s?void 0:s.filter(t=>t!==e);this._listenersOnce[t]=n}else delete this._listeners[t]}emit(t,e){var i;if(this._paused)return;null===(i=this._listeners[t])||void 0===i||i.forEach(t=>t(e));let s=this._listenersOnce[t];this._listenersOnce[t]=[],s&&s.forEach(t=>t(e)),this._pipes.forEach(i=>{i.emit(t,e)})}pipe(t){if(this===t)throw Error("Cannot pipe to self");return this._pipes.push(t),{close:()=>{let e=this._pipes.indexOf(t);e>-1&&this._pipes.splice(e,1)}}}unpipe(t){let e=this._pipes.indexOf(t);e>-1&&this._pipes.splice(e,1)}pause(){this._paused=!0}unpause(){this._paused=!1}}(t=O||(O={})).Canvas="Canvas",t.Document="Document";class tI{constructor(t){this.seed=t,this._lowerMask=2147483647,this._upperMask=2147483648,this._w=32,this._n=624,this._m=397,this._a=2567483615,this._u=11,this._s=7,this._b=2636928640,this._t=15,this._c=4022730752,this._l=18,this._f=1812433253,this._mt=Array(this._n),this._mt[0]=(t||Date.now())>>>0;for(let t=1;t>>this._w-2;this._mt[t]=(this._f*((4294901760&e)>>>16)<<16)+this._f*(65535&e)+t>>>0}this._index=this._n}_twist(){let t=[0,this._a],e=0,i=0;for(;i>>1^4294967295&t[1&e];for(;i>>1^4294967295&t[1&e];e=this._mt[this._n-1]&this._upperMask|this._mt[0]&this._lowerMask,this._mt[this._n-1]=this._mt[this._m-1]^e>>>1^4294967295&t[1&e],this._index=0}nextInt(){this._index>=this._n&&this._twist();let t=this._mt[this._index++];return t^=t>>>this._u,t^=t<>>this._l)>>>0}next(){return this.nextInt()*(1/4294967296)}floating(t,e){return(e-t)*this.next()+t}integer(t,e){return Math.floor((e-t+1)*this.next()+t)}bool(t=.5){return this.next()<=t}pickOne(t){return t[this.integer(0,t.length-1)]}pickSet(t,e,i=!1){return i?this._pickSetWithDuplicates(t,e):this._pickSetWithoutDuplicates(t,e)}_pickSetWithoutDuplicates(t,e){if(e>t.length||e<0)throw Error("Invalid number of elements to pick, must pick a value 0 < n <= length");if(e===t.length)return t;let i=Array(e),s=0,r=t.slice(0);for(;s=0?t-Math.floor(t):t-Math.ceil(t)}function tR(t){return 0===t?0:t<0?-1:1}function tF(t,e,i){return Math.min(Math.max(e,t),i)}function tB(t){let e=t;if(t>tk)for(;e>tk;)e-=tk;if(t<0)for(;e<0;)e+=tk;return e}function tL(t){return 180/Math.PI*t}function tM(t){return t/180*Math.PI}let tz=(t,e)=>Array.from(Array(e-t+1),(e,i)=>i+t);function tO(t,e,i=new tI){return i?i.floating(t,e):t+Math.random()*(e-t)}function tU(t,e,i=new tI){return i?i.integer(t,e):Math.round(tO(t,e))}class tN{static get Zero(){return new tN(0,0)}static get One(){return new tN(1,1)}static get Half(){return new tN(.5,.5)}static get Up(){return new tN(0,-1)}static get Down(){return new tN(0,1)}static get Left(){return new tN(-1,0)}static get Right(){return new tN(1,0)}static fromAngle(t){return new tN(Math.cos(t),Math.sin(t))}static isValid(t){return!(null==t||isNaN(t.x)||isNaN(t.y))&&t.x!==1/0&&t.y!==1/0&&t.x!==-1/0&&t.y!==-1/0}static distance(t,e){return Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2))}static min(t,e){return new tN(Math.min(t.x,e.x),Math.min(t.y,e.y))}static max(t,e){return new tN(Math.max(t.x,e.x),Math.max(t.y,e.y))}constructor(t,e){this._x=0,this._y=0,this._x=t,this._y=e}get x(){return this._x}set x(t){this._x=t}get y(){return this._y}set y(t){this._y=t}setTo(t,e){this.x=t,this.y=e}equals(t,e=.001){return Math.abs(this.x-t.x)<=e&&Math.abs(this.y-t.y)<=e}distance(t){if(!t)return Math.sqrt(this.x*this.x+this.y*this.y);let e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)}squareDistance(t){t||(t=tN.Zero);let e=this.x-t.x,i=this.y-t.y;return e*e+i*i}clampMagnitude(t){let e=tF(this.size,0,t);return this.size=e,this}get size(){return this.distance()}set size(t){let e=this.normalize().scale(t);this.setTo(e.x,e.y)}normalize(){let t=this.distance();return t>0?new tN(this.x/t,this.y/t):new tN(0,1)}average(t){return this.add(t).scale(.5)}scale(t,e){let i=e||new tN(0,0);return t instanceof tN?(i.x=this.x*t.x,i.y=this.y*t.y):(i.x=this.x*t,i.y=this.y*t),i}add(t,e){return e?(e.x=this.x+t.x,e.y=this.y+t.y,e):new tN(this.x+t.x,this.y+t.y)}sub(t){return new tN(this.x-t.x,this.y-t.y)}addEqual(t){return this.setTo(this.x+t.x,this.y+t.y),this}subEqual(t){return this.setTo(this.x-t.x,this.y-t.y),this}scaleEqual(t){return this.setTo(this.x*t,this.y*t),this}dot(t){return this.x*t.x+this.y*t.y}cross(t){return t instanceof tN?this.x*t.y-this.y*t.x:"number"==typeof t?new tN(t*this.y,-t*this.x):void 0}static cross(t,e){return new tN(-t*e.y,t*e.x)}perpendicular(){return new tN(this.y,-this.x)}normal(){return this.perpendicular().normalize()}negate(){return this.scale(-1)}toAngle(){return Math.atan2(this.y,this.x)}rotate(t,e){e||(e=new tN(0,0));let i=Math.sin(t),s=Math.cos(t);return new tN(s*(this.x-e.x)-i*(this.y-e.y)+e.x,i*(this.x-e.x)+s*(this.y-e.y)+e.y)}clone(t){let e=null!=t?t:new tN(0,0);return e.x=this.x,e.y=this.y,e}toString(t){return t?`(${this.x.toFixed(t)}, ${this.y.toFixed(t)})`:`(${this.x}, ${this.y})`}}function tZ(t,e){return new tN(t,e)}class tH{constructor(t,e,i,s){this.r=t,this.g=e,this.b=i,this.a=null!=s?s:1}static fromRGB(t,e,i,s){return new tH(t,e,i,s)}static fromRGBString(t){let e=null;if(e=t.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)/i)){let t=parseInt(e[1],10),i=parseInt(e[2],10),s=parseInt(e[3],10),r=1;return e[4]&&(r=parseFloat(e[4])),new tH(t,i,s,r)}throw Error("Invalid rgb/a string: "+t)}static fromHex(t){let e=null;if(e=t.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i)){let t=parseInt(e[1],16),i=parseInt(e[2],16),s=parseInt(e[3],16),r=1;return e[4]&&(r=parseInt(e[4],16)/255),new tH(t,i,s,r)}throw Error("Invalid hex string: "+t)}static fromHSL(t,e,i,s=1){return new tV(t,e,i,s).toRGBA()}lighten(t=.1){let e=tV.fromRGBA(this.r,this.g,this.b,this.a);return e.l+=(1-e.l)*t,e.toRGBA()}darken(t=.1){let e=tV.fromRGBA(this.r,this.g,this.b,this.a);return e.l-=e.l*t,e.toRGBA()}saturate(t=.1){let e=tV.fromRGBA(this.r,this.g,this.b,this.a);return e.s+=e.s*t,e.toRGBA()}desaturate(t=.1){let e=tV.fromRGBA(this.r,this.g,this.b,this.a);return e.s-=e.s*t,e.toRGBA()}multiply(t){let e=t.r/255*this.r/255*255;return new tH(e,t.g/255*this.g/255*255,t.b/255*this.b/255*255,t.a*this.a)}screen(t){let e=t.invert(),i=t.invert();return e.multiply(i).invert()}invert(){return new tH(255-this.r,255-this.g,255-this.b,1-this.a)}average(t){let e=(t.r+this.r)/2;return new tH(e,(t.g+this.g)/2,(t.b+this.b)/2,(t.a+this.a)/2)}equal(t){return this.toString()===t.toString()}toString(t="rgb"){switch(t){case"rgb":return this.toRGBA();case"hsl":return this.toHSLA();case"hex":return this.toHex();default:throw Error("Invalid Color format")}}_componentToHex(t){let e=t.toString(16);return 1===e.length?"0"+e:e}toHex(){return"#"+this._componentToHex(this.r)+this._componentToHex(this.g)+this._componentToHex(this.b)}toRGBA(){let t=String(this.r.toFixed(0))+", "+String(this.g.toFixed(0))+", "+String(this.b.toFixed(0));return void 0!==this.a||null!==this.a?"rgba("+t+", "+String(this.a)+")":"rgb("+t+")"}toHSLA(){return tV.fromRGBA(this.r,this.g,this.b,this.a).toString()}fillStyle(){return this.toString()}clone(){return new tH(this.r,this.g,this.b,this.a)}static get Black(){return tH.fromHex("#000000")}static get White(){return tH.fromHex("#FFFFFF")}static get Gray(){return tH.fromHex("#808080")}static get LightGray(){return tH.fromHex("#D3D3D3")}static get DarkGray(){return tH.fromHex("#A9A9A9")}static get Yellow(){return tH.fromHex("#FFFF00")}static get Orange(){return tH.fromHex("#FFA500")}static get Red(){return tH.fromHex("#FF0000")}static get Vermilion(){return tH.fromHex("#FF5B31")}static get Rose(){return tH.fromHex("#FF007F")}static get Magenta(){return tH.fromHex("#FF00FF")}static get Violet(){return tH.fromHex("#7F00FF")}static get Blue(){return tH.fromHex("#0000FF")}static get Azure(){return tH.fromHex("#007FFF")}static get Cyan(){return tH.fromHex("#00FFFF")}static get Viridian(){return tH.fromHex("#59978F")}static get Green(){return tH.fromHex("#00FF00")}static get Chartreuse(){return tH.fromHex("#7FFF00")}static get Transparent(){return tH.fromHex("#FFFFFF00")}static get ExcaliburBlue(){return tH.fromHex("#176BAA")}}class tV{constructor(t,e,i,s){this.h=t,this.s=e,this.l=i,this.a=s}static hue2rgb(t,e,i){return(i<0&&(i+=1),i>1&&(i-=1),i<1/6)?t+(e-t)*6*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}static fromRGBA(t,e,i,s){let r,n;t/=255,e/=255,i/=255;let o=Math.max(t,e,i),a=Math.min(t,e,i),l=(o+a)/2;if(o===a)r=n=0;else{let s=o-a;switch(n=l>.5?s/(2-o-a):s/(o+a),o){case t:r=(e-i)/s+(e=this.defaultLevel&&this._appenders[s].log(t,e)}_logOnce(t,e){let i=t+e.join("+");this._logOnceSet.has(i)||(this._logOnceSet.add(i),this._log(t,e))}debug(...t){this._log(U.Debug,t)}debugOnce(...t){this._logOnce(U.Debug,t)}info(...t){this._log(U.Info,t)}infoOnce(...t){this._logOnce(U.Info,t)}warn(...t){this._log(U.Warn,t)}warnOnce(...t){this._logOnce(U.Warn,t)}error(...t){this._log(U.Error,t)}errorOnce(...t){this._logOnce(U.Error,t)}fatal(...t){this._log(U.Fatal,t)}fatalOnce(...t){this._logOnce(U.Fatal,t)}}tW._INSTANCE=null;class tG{log(t,e){if(!console&&!console.log&&console.warn&&console.error)return;let i=[];i.unshift.apply(i,e),i.unshift("["+U[t]+"] : "),t{this._positionScreenAppenderCanvas()})}_positionScreenAppenderCanvas(){var t,e,i,s;let r=this._options;this.canvas.width=null!==(t=r.width)&&void 0!==t?t:r.engine.screen.resolution.width,this.canvas.height=null!==(e=r.height)&&void 0!==e?e:r.engine.screen.resolution.height,this.canvas.style.position="absolute";let n=r.engine.screen.screenToPageCoordinates(tZ(0,0));this.canvas.style.left=n.x+"px",this.canvas.style.top=n.y+"px",this._pos=null!==(i=r.xPos)&&void 0!==i?i:this._pos,this._color=null!==(s=r.color)&&void 0!==s?s:this._color}log(t,e){let i=e.join(",");this._ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this._messages.unshift("["+U[t]+"] : "+i);let s=10;this._messages=this._messages.slice(0,1e3);for(let t=0;tr&&(r=e[i].dot(t),n=i);return i[n]};class tq{constructor(t=0,e=0,i=0,s=0){this._points=[],"object"==typeof t?(this.left=t.left,this.top=t.top,this.right=t.right,this.bottom=t.bottom):"number"==typeof t&&(this.left=t,this.top=e,this.right=i,this.bottom=s)}clone(){return new tq(this.left,this.top,this.right,this.bottom)}static getSideFromIntersection(t){return t?t?Math.abs(t.x)>Math.abs(t.y)?t.x<0?N.Right:N.Left:t.y<0?N.Bottom:N.Top:N.None:N.None}static fromPoints(t){let e=1/0,i=1/0,s=-1/0,r=-1/0;for(let n=0;ns&&(s=t[n].x),t[n].yr&&(r=t[n].y);return new tq(e,i,s,r)}static fromDimension(t,e,i=tN.Half,s=tN.Zero){return new tq(-t*i.x+s.x,-e*i.y+s.y,t-t*i.x+s.x,e-e*i.y+s.y)}get width(){return this.right-this.left}get height(){return this.bottom-this.top}hasZeroDimensions(){return 0===this.width||0===this.height}get center(){return new tN((this.left+this.right)/2,(this.top+this.bottom)/2)}get topLeft(){return new tN(this.left,this.top)}get bottomRight(){return new tN(this.right,this.bottom)}get topRight(){return new tN(this.right,this.top)}get bottomLeft(){return new tN(this.left,this.bottom)}translate(t){return new tq(this.left+t.x,this.top+t.y,this.right+t.x,this.bottom+t.y)}rotate(t,e=tN.Zero){let i=this.getPoints().map(i=>i.rotate(t,e));return tq.fromPoints(i)}scale(t,e=tN.Zero){let i=this.translate(e);return new tq(i.left*t.x,i.top*t.y,i.right*t.x,i.bottom*t.y)}transform(t){let e=t.data[0]*this.left,i=t.data[1]*this.left,s=t.data[0]*this.right,r=t.data[1]*this.right,n=t.data[2]*this.top,o=t.data[3]*this.top,a=t.data[2]*this.bottom,l=t.data[3]*this.bottom,h=t.getPosition(),d=Math.min(e,s)+Math.min(n,a)+h.x;return new tq({left:d,top:Math.min(i,r)+Math.min(o,l)+h.y,right:Math.max(e,s)+Math.max(n,a)+h.x,bottom:Math.max(i,r)+Math.max(o,l)+h.y})}getPerimeter(){return 2*(this.width+this.height)}getPoints(){return(this._left!==this.left||this._right!==this.right||this._top!==this.top||this._bottom!==this.bottom)&&(this._points.length=0,this._points.push(new tN(this.left,this.top)),this._points.push(new tN(this.right,this.top)),this._points.push(new tN(this.right,this.bottom)),this._points.push(new tN(this.left,this.bottom)),this._left=this.left,this._right=this.right,this._top=this.top,this._bottom=this.bottom),this._points}rayCast(t,e=1/0){let i=-1/0,s=1/0,r=0===t.dir.x?Number.MAX_VALUE:1/t.dir.x,n=0===t.dir.y?Number.MAX_VALUE:1/t.dir.y,o=(this.left-t.pos.x)*r,a=(this.right-t.pos.x)*r;i=Math.min(o,a),s=Math.max(o,a);let l=(this.top-t.pos.y)*n,h=(this.bottom-t.pos.y)*n;return i=Math.max(i,Math.min(l,h)),(s=Math.min(s,Math.max(l,h)))>=Math.max(0,i)&&i=Math.max(0,i)&&i=t.y&&this.right>=t.x:t instanceof tq&&this.left<=t.left&&this.top<=t.top&&t.bottom<=this.bottom&&t.right<=this.right}combine(t){return new tq(Math.min(this.left,t.left),Math.min(this.top,t.top),Math.max(this.right,t.right),Math.max(this.bottom,t.bottom))}get dimensions(){return new tN(this.width,this.height)}overlaps(t,e){let i=e||0;if(t.hasZeroDimensions())return this.contains(t);if(this.hasZeroDimensions())return t.contains(this);let s=this.combine(t);return s.width+i=t.left&&this.right<=t.right?t.left-this.right:t.right-this.left;let i=0;return Math.abs(e)=t.top?t.bottom-this.top:t.top-this.bottom)?new tN(e,0):new tN(0,i)}if(!(e.dimensions.equals(t.dimensions)||e.dimensions.equals(this.dimensions)))return null;{let e=0;e=this.width-t.width>=0?this.right-t.right<=t.left-this.left?t.left-this.right:t.right-this.left:t.right-this.right<=this.left-t.left?this.left-t.right:this.right-t.left;let i=0;return Math.abs(e)=0?this.bottom-t.bottom<=t.top-this.top?t.top-this.bottom:t.bottom-this.top:t.bottom-this.bottom<=this.top-t.top?this.top-t.bottom:this.bottom-t.top)?new tN(e,0):new tN(0,i)}}intersectWithSide(t){let e=this.intersect(t);return tq.getSideFromIntersection(e)}draw(t,e=tH.Yellow){t.debug.drawRect(this.left,this.top,this.width,this.height,{color:e})}}function tX(t){let e=t.getBoundingClientRect();return tZ(e.x+window.scrollX,e.y+window.scrollY)}function t$(t,e){return -1===e.indexOf(t)&&(e.push(t),!0)}function tK(t,e){let i=-1;return(i=e.indexOf(t))>-1&&(e.splice(i,1),!0)}function tY(t,e){for(let i=0;i{s.resolve()},t),s.promise}function t0(t,e){let i={};for(let s in t)e.includes(s)||(i[s]=t[s]);return i}(r=Z||(Z={}))[r.X=12]="X",r[r.Y=13]="Y";class t1{constructor(){this.data=new Float32Array(16),this._scaleX=1,this._scaleSignX=1,this._scaleY=1,this._scaleSignY=1}static ortho(t,e,i,s,r,n){let o=new t1;return o.data[0]=2/(e-t),o.data[1]=0,o.data[2]=0,o.data[3]=0,o.data[4]=0,o.data[5]=2/(s-i),o.data[6]=0,o.data[7]=0,o.data[8]=0,o.data[9]=0,o.data[10]=-2/(n-r),o.data[11]=0,o.data[12]=-(e+t)/(e-t),o.data[13]=-(s+i)/(s-i),o.data[14]=-(n+r)/(n-r),o.data[15]=1,o}clone(t){let e=t||new t1;return e.data[0]=this.data[0],e.data[1]=this.data[1],e.data[2]=this.data[2],e.data[3]=this.data[3],e.data[4]=this.data[4],e.data[5]=this.data[5],e.data[6]=this.data[6],e.data[7]=this.data[7],e.data[8]=this.data[8],e.data[9]=this.data[9],e.data[10]=this.data[10],e.data[11]=this.data[11],e.data[12]=this.data[12],e.data[13]=this.data[13],e.data[14]=this.data[14],e.data[15]=this.data[15],e}toDOMMatrix(){return new DOMMatrix([...this.data])}static fromFloat32Array(t){let e=new t1;return e.data=t,e}static identity(){let t=new t1;return t.data[0]=1,t.data[1]=0,t.data[2]=0,t.data[3]=0,t.data[4]=0,t.data[5]=1,t.data[6]=0,t.data[7]=0,t.data[8]=0,t.data[9]=0,t.data[10]=1,t.data[11]=0,t.data[12]=0,t.data[13]=0,t.data[14]=0,t.data[15]=1,t}reset(){return this.data[0]=1,this.data[1]=0,this.data[2]=0,this.data[3]=0,this.data[4]=0,this.data[5]=1,this.data[6]=0,this.data[7]=0,this.data[8]=0,this.data[9]=0,this.data[10]=1,this.data[11]=0,this.data[12]=0,this.data[13]=0,this.data[14]=0,this.data[15]=1,this}static translation(t,e){let i=t1.identity();return i.data[12]=t,i.data[13]=e,i}static scale(t,e){let i=t1.identity();return i.data[0]=t,i.data[5]=e,i.data[10]=1,i.data[15]=1,i}static rotation(t){let e=t1.identity();return e.data[0]=Math.cos(t),e.data[4]=-Math.sin(t),e.data[1]=Math.sin(t),e.data[5]=Math.cos(t),e}multiply(t,e){if(t instanceof tN){let i=e||new tN(0,0),s=t.x*this.data[0]+t.y*this.data[4]+this.data[12],r=t.x*this.data[1]+t.y*this.data[5]+this.data[13];return i.x=s,i.y=r,i}{let i=e||new t1,s=this.data[0],r=this.data[1],n=this.data[2],o=this.data[3],a=this.data[4],l=this.data[5],h=this.data[6],d=this.data[7],c=this.data[8],u=this.data[9],p=this.data[10],g=this.data[11],_=this.data[12],f=this.data[13],m=this.data[14],v=this.data[15],y=t.data[0],x=t.data[1],w=t.data[2],b=t.data[3],C=t.data[4],T=t.data[5],S=t.data[6],A=t.data[7],E=t.data[8],P=t.data[9],I=t.data[10],k=t.data[11],D=t.data[12],R=t.data[13],F=t.data[14],B=t.data[15];i.data[0]=s*y+a*x+c*w+_*b,i.data[1]=r*y+l*x+u*w+f*b,i.data[2]=n*y+h*x+p*w+m*b,i.data[3]=o*y+d*x+g*w+v*b,i.data[4]=s*C+a*T+c*S+_*A,i.data[5]=r*C+l*T+u*S+f*A,i.data[6]=n*C+h*T+p*S+m*A,i.data[7]=o*C+d*T+g*S+v*A,i.data[8]=s*E+a*P+c*I+_*k,i.data[9]=r*E+l*P+u*I+f*k,i.data[10]=n*E+h*P+p*I+m*k,i.data[11]=o*E+d*P+g*I+v*k,i.data[12]=s*D+a*R+c*F+_*B,i.data[13]=r*D+l*R+u*F+f*B,i.data[14]=n*D+h*R+p*F+m*B,i.data[15]=o*D+d*R+g*F+v*B;let L=this.getScale();return i._scaleSignX=tR(L.x)*tR(i._scaleSignX),i._scaleSignY=tR(L.y)*tR(i._scaleSignY),i}}translate(t,e){let i=this.data[0],s=this.data[1],r=this.data[2],n=this.data[3],o=this.data[4],a=this.data[5],l=this.data[6],h=this.data[7],d=this.data[8],c=this.data[9],u=this.data[10],p=this.data[11],g=this.data[12],_=this.data[13],f=this.data[14],m=this.data[15];return this.data[12]=i*t+o*e+0*d+1*g,this.data[13]=s*t+a*e+0*c+1*_,this.data[14]=r*t+l*e+0*u+1*f,this.data[15]=n*t+h*e+0*p+1*m,this}setPosition(t,e){this.data[12]=t,this.data[13]=e}getPosition(){return tZ(this.data[12],this.data[13])}rotate(t){let e=this.data[0],i=this.data[1],s=this.data[2],r=this.data[3],n=this.data[4],o=this.data[5],a=this.data[6],l=this.data[7],h=Math.sin(t),d=Math.cos(t);return this.data[0]=d*e+h*n,this.data[1]=d*i+h*o,this.data[2]=d*s+h*a,this.data[3]=d*r+h*l,this.data[4]=d*n-h*e,this.data[5]=d*o-h*i,this.data[6]=d*a-h*s,this.data[7]=d*l-h*r,this}scale(t,e){let i=this.data[0],s=this.data[1],r=this.data[2],n=this.data[3],o=this.data[4],a=this.data[5],l=this.data[6],h=this.data[7];return this.data[0]=i*t,this.data[1]=s*t,this.data[2]=r*t,this.data[3]=n*t,this.data[4]=o*e,this.data[5]=a*e,this.data[6]=l*e,this.data[7]=h*e,this}setRotation(t){let e=this.getScale(),i=Math.sin(t),s=Math.cos(t);this.data[0]=s*e.x,this.data[1]=i*e.y,this.data[4]=-i*e.x,this.data[5]=s*e.y}getRotation(){return tB(Math.atan2(this.data[1]/this.getScaleY(),this.data[0]/this.getScaleX()))}getScaleX(){let t=tZ(this.data[0],this.data[4]).size;return this._scaleSignX*t}getScaleY(){let t=tZ(this.data[1],this.data[5]).size;return this._scaleSignY*t}getScale(){return tZ(this.getScaleX(),this.getScaleY())}setScaleX(t){if(this._scaleX===t)return;this._scaleSignX=tR(t);let e=tZ(this.data[0]*this._scaleSignX,this.data[4]*this._scaleSignX).normalize();this.data[0]=e.x*t,this.data[4]=e.y*t,this._scaleX=t}setScaleY(t){if(this._scaleY===t)return;this._scaleSignY=tR(t);let e=tZ(this.data[1]*this._scaleSignY,this.data[5]*this._scaleSignY).normalize();this.data[1]=e.x*t,this.data[5]=e.y*t,this._scaleY=t}setScale(t){this.setScaleX(t.x),this.setScaleY(t.y)}getBasisDeterminant(){return this.data[0]*this.data[5]-this.data[1]*this.data[4]}getAffineInverse(t){let e=1/this.getBasisDeterminant(),i=this.data[0],s=this.data[4],r=this.data[1],n=this.data[5],o=t||t1.identity();o.data[0]=n*e,o.data[1]=-r*e,o.data[4]=-s*e,o.data[5]=i*e;let a=this.data[12],l=this.data[13];return o.data[12]=-(a*o.data[0]+l*o.data[4]),o.data[13]=-(a*o.data[1]+l*o.data[5]),o}isIdentity(){return 1===this.data[0]&&0===this.data[1]&&0===this.data[2]&&0===this.data[3]&&0===this.data[4]&&1===this.data[5]&&0===this.data[6]&&0===this.data[7]&&0===this.data[8]&&0===this.data[9]&&1===this.data[10]&&0===this.data[11]&&0===this.data[12]&&0===this.data[13]&&0===this.data[14]&&1===this.data[15]}toString(){return` [${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}] [${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}] [${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}] @@ -182,7 +182,7 @@ ${i}${this._processSourceForError(e,i)}`)}return r}_processSourceForError(t,e){i `,s+=` vec2 uv = u_pixelart ? uv_iq(v_texcoord, v_res) : v_texcoord; color = texture(u_textures[${t}], uv); } -`;return i.replace("%%texture_picker%%",s)}_addImageAsTexture(t){let e=t.getAttribute("filtering"),i=null;(e===H.Blended||e===H.Pixel)&&(i=e);let s="true"===t.getAttribute("forceUpload"),r=this._context.textureLoader.load(t,i,s);t.removeAttribute("forceUpload"),-1===this._textures.indexOf(r)&&this._textures.push(r)}_bindTextures(t){for(let e=0;e=this._maxImages||this._textures.length>=this._maxTextures}draw(t,e,i,s,r,n,o,a,l){var h,d,c,u;this._isFull()&&this.flush(),this._imageCount++,this._addImageAsTexture(t);let p=(null==t?void 0:t.width)||s||0,g=(null==t?void 0:t.height)||r||0,_=[0,0,null!==(h=null!=s?s:null==t?void 0:t.width)&&void 0!==h?h:0,null!==(d=null!=r?r:null==t?void 0:t.height)&&void 0!==d?d:0],f=[null!=e?e:1,null!=i?i:1];void 0!==n&&void 0!==o&&void 0!==a&&void 0!==l&&(_=[null!=e?e:1,null!=i?i:1,null!==(c=null!=s?s:null==t?void 0:t.width)&&void 0!==c?c:0,null!==(u=null!=r?r:null==t?void 0:t.height)&&void 0!==u?u:0],f=[n,o],p=a,g=l),e=_[0],i=_[1];let m=_[2],v=_[3],y=this._context.getTransform(),x=this._context.opacity,w=this._context.snapToPixel,b=tZ(f[0],f[1]),C=tZ(f[0]+p,f[1]),T=tZ(f[0],f[1]+g),S=tZ(f[0]+p,f[1]+g);b=y.multiply(b),C=y.multiply(C),T=y.multiply(T),S=y.multiply(S),w&&(b.x=~~(b.x+tR(b.x)*eP),b.y=~~(b.y+tR(b.y)*eP),C.x=~~(C.x+tR(C.x)*eP),C.y=~~(C.y+tR(C.y)*eP),T.x=~~(T.x+tR(T.x)*eP),T.y=~~(T.y+tR(T.y)*eP),S.x=~~(S.x+tR(S.x)*eP),S.y=~~(S.y+tR(S.y)*eP));let A=this._context.tint,E=this._getTextureIdForImage(t),P=t.width||p,I=t.height||g,k=(e+this.uvPadding)/P,D=(i+this.uvPadding)/I,R=(e+m-this.uvPadding)/P,F=(i+v-this.uvPadding)/I,B=t.width,M=t.height,L=this._layout.vertexBuffer.bufferData;L[this._vertexIndex++]=b.x,L[this._vertexIndex++]=b.y,L[this._vertexIndex++]=x,L[this._vertexIndex++]=B,L[this._vertexIndex++]=M,L[this._vertexIndex++]=k,L[this._vertexIndex++]=D,L[this._vertexIndex++]=E,L[this._vertexIndex++]=A.r/255,L[this._vertexIndex++]=A.g/255,L[this._vertexIndex++]=A.b/255,L[this._vertexIndex++]=A.a,L[this._vertexIndex++]=T.x,L[this._vertexIndex++]=T.y,L[this._vertexIndex++]=x,L[this._vertexIndex++]=B,L[this._vertexIndex++]=M,L[this._vertexIndex++]=k,L[this._vertexIndex++]=F,L[this._vertexIndex++]=E,L[this._vertexIndex++]=A.r/255,L[this._vertexIndex++]=A.g/255,L[this._vertexIndex++]=A.b/255,L[this._vertexIndex++]=A.a,L[this._vertexIndex++]=C.x,L[this._vertexIndex++]=C.y,L[this._vertexIndex++]=x,L[this._vertexIndex++]=B,L[this._vertexIndex++]=M,L[this._vertexIndex++]=R,L[this._vertexIndex++]=D,L[this._vertexIndex++]=E,L[this._vertexIndex++]=A.r/255,L[this._vertexIndex++]=A.g/255,L[this._vertexIndex++]=A.b/255,L[this._vertexIndex++]=A.a,L[this._vertexIndex++]=S.x,L[this._vertexIndex++]=S.y,L[this._vertexIndex++]=x,L[this._vertexIndex++]=B,L[this._vertexIndex++]=M,L[this._vertexIndex++]=R,L[this._vertexIndex++]=F,L[this._vertexIndex++]=E,L[this._vertexIndex++]=A.r/255,L[this._vertexIndex++]=A.g/255,L[this._vertexIndex++]=A.b/255,L[this._vertexIndex++]=A.a}hasPendingDraws(){return 0!==this._imageCount}flush(){if(0===this._imageCount)return;let t=this._gl;this._shader.use(),this._layout.use(!0,48*this._imageCount),this._shader.setUniformMatrix("u_matrix",this._context.ortho),this._shader.setUniformBoolean("u_pixelart",this.pixelArtSampler),this._bindTextures(t),this._quads.bind(),t.drawElements(t.TRIANGLES,6*this._imageCount,this._quads.bufferGlType,0),e_.DrawnImagesCount+=this._imageCount,e_.DrawCallCount++,this._imageCount=0,this._vertexIndex=0,this._textures.length=0}}class ew{constructor(){this.type="ex.rectangle",this.priority=0,this._maxRectangles=10922,this._rectangleCount=0,this._vertexIndex=0}initialize(t,e){this._gl=t,this._context=e,this._shader=new eu({gl:t,fragmentSource:"#version 300 es\r\n\r\nprecision mediump float;\r\n\r\n// UV coord\r\nin vec2 v_uv;\r\n\r\nin vec2 v_size; // in pixels\r\n\r\n// Color coord to blend with image\r\nin lowp vec4 v_color;\r\n\r\n// Stroke color if used\r\nin lowp vec4 v_strokeColor;\r\n\r\n// Stroke thickness if used\r\nin lowp float v_strokeThickness; // in pixels\r\n\r\n// Opacity\r\nin float v_opacity;\r\n\r\nout vec4 fragColor;\r\n\r\nvoid main() {\r\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\r\n vec2 uv = v_uv;\r\n vec2 fragCoord = uv * v_size;\r\n float maxX = v_size.x - v_strokeThickness;\r\n float minX = v_strokeThickness;\r\n float maxY = v_size.y - v_strokeThickness;\r\n float minY = v_strokeThickness;\r\n\r\n if (fragCoord.x < maxX && fragCoord.x > minX &&\r\n fragCoord.y < maxY && fragCoord.y > minY) {\r\n fragColor = v_color;\r\n } else {\r\n fragColor = v_strokeColor;\r\n }\r\n fragColor.a *= v_opacity;\r\n fragColor.rgb *= fragColor.a;\r\n\r\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\r\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\r\n\r\n // float fHalfBorderDist = 0.0;\r\n // float fHalfBorderThickness = 0.0;\r\n\r\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \r\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\r\n // {\r\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\r\n // fHalfBorderThickness = v_strokeThickness / 2.0;\r\n // }\r\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \r\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\r\n // {\r\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\r\n // fHalfBorderThickness = v_strokeThickness / 2.0;\r\n // }\r\n // else\r\n // {\r\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\r\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\r\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\r\n \r\n // float ellipse_ab = v_radius-v_strokeThickness;\r\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\r\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \r\n \r\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\r\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\r\n // }\r\n\r\n // vec4 v4FromColor = v_strokeColor;\r\n // v4FromColor.rgb *= v4FromColor.a;\r\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\r\n // if (fHalfBorderDist < 0.0) {\r\n // v4ToColor = v_color;\r\n // v4ToColor.rgb *= v4ToColor.a;\r\n // }\r\n\r\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\r\n\r\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\r\n // gl_FragColor = finalColor;\r\n}",vertexSource:"#version 300 es\r\nin vec2 a_position;\r\n\r\n// UV coordinate\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nin vec2 a_size;\r\nout vec2 v_size;\r\n\r\n// Opacity \r\nin float a_opacity;\r\nout float v_opacity;\r\n\r\nin vec4 a_color;\r\nout vec4 v_color;\r\n\r\nin vec4 a_strokeColor;\r\nout vec4 v_strokeColor;\r\n\r\nin float a_strokeThickness;\r\nout float v_strokeThickness;\r\n\r\nuniform mat4 u_matrix;\r\n\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho transform matrix\r\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through UV coords\r\n v_uv = a_uv;\r\n // Pass through size\r\n v_size = a_size;\r\n // Pass through the Opacity to the fragment shader\r\n v_opacity = a_opacity;\r\n // Pass through the color to the fragment shader\r\n v_color = a_color;\r\n // Pass through the stroke color to the fragment shader\r\n v_strokeColor = a_strokeColor;\r\n // Pass through the stroke thickenss to the fragment shader\r\n v_strokeThickness = a_strokeThickness;\r\n}"}),this._shader.compile(),this._shader.use(),this._shader.setUniformMatrix("u_matrix",e.ortho),this._buffer=new ep({gl:t,size:64*this._maxRectangles,type:"dynamic"}),this._layout=new eg({gl:t,shader:this._shader,vertexBuffer:this._buffer,attributes:[["a_position",2],["a_uv",2],["a_size",2],["a_opacity",1],["a_color",4],["a_strokeColor",4],["a_strokeThickness",1]]}),this._quads=new ey(t,this._maxRectangles,!0)}dispose(){this._buffer.dispose(),this._quads.dispose(),this._shader.dispose(),this._context=null,this._gl=null}_isFull(){return this._rectangleCount>=this._maxRectangles}draw(...t){t[0]instanceof tN&&t[1]instanceof tN?this.drawLine.apply(this,t):this.drawRectangle.apply(this,t)}drawLine(t,e,i,s=1){this._isFull()&&this.flush(),this._rectangleCount++;let r=this._context.getTransform(),n=this._context.opacity,o=this._context.snapToPixel,a=e.sub(t),l=a.size,h=a.normalize().perpendicular(),d=s/2,c=r.multiply(h.scale(d).add(t)),u=r.multiply(h.scale(-d).add(t)),p=r.multiply(h.scale(d).add(e)),g=r.multiply(h.scale(-d).add(e));o&&(c.x=~~(c.x+eP),c.y=~~(c.y+eP),p.x=~~(p.x+eP),p.y=~~(p.y+eP),u.x=~~(u.x+eP),u.y=~~(u.y+eP),g.x=~~(g.x+eP),g.y=~~(g.y+eP));let _=tH.Transparent,f=this._layout.vertexBuffer.bufferData;f[this._vertexIndex++]=c.x,f[this._vertexIndex++]=c.y,f[this._vertexIndex++]=0,f[this._vertexIndex++]=0,f[this._vertexIndex++]=l,f[this._vertexIndex++]=s,f[this._vertexIndex++]=n,f[this._vertexIndex++]=i.r/255,f[this._vertexIndex++]=i.g/255,f[this._vertexIndex++]=i.b/255,f[this._vertexIndex++]=i.a,f[this._vertexIndex++]=_.r/255,f[this._vertexIndex++]=_.g/255,f[this._vertexIndex++]=_.b/255,f[this._vertexIndex++]=_.a,f[this._vertexIndex++]=0,f[this._vertexIndex++]=u.x,f[this._vertexIndex++]=u.y,f[this._vertexIndex++]=0,f[this._vertexIndex++]=1,f[this._vertexIndex++]=l,f[this._vertexIndex++]=s,f[this._vertexIndex++]=n,f[this._vertexIndex++]=i.r/255,f[this._vertexIndex++]=i.g/255,f[this._vertexIndex++]=i.b/255,f[this._vertexIndex++]=i.a,f[this._vertexIndex++]=_.r/255,f[this._vertexIndex++]=_.g/255,f[this._vertexIndex++]=_.b/255,f[this._vertexIndex++]=_.a,f[this._vertexIndex++]=0,f[this._vertexIndex++]=p.x,f[this._vertexIndex++]=p.y,f[this._vertexIndex++]=1,f[this._vertexIndex++]=0,f[this._vertexIndex++]=l,f[this._vertexIndex++]=s,f[this._vertexIndex++]=n,f[this._vertexIndex++]=i.r/255,f[this._vertexIndex++]=i.g/255,f[this._vertexIndex++]=i.b/255,f[this._vertexIndex++]=i.a,f[this._vertexIndex++]=_.r/255,f[this._vertexIndex++]=_.g/255,f[this._vertexIndex++]=_.b/255,f[this._vertexIndex++]=_.a,f[this._vertexIndex++]=0,f[this._vertexIndex++]=g.x,f[this._vertexIndex++]=g.y,f[this._vertexIndex++]=1,f[this._vertexIndex++]=1,f[this._vertexIndex++]=l,f[this._vertexIndex++]=s,f[this._vertexIndex++]=n,f[this._vertexIndex++]=i.r/255,f[this._vertexIndex++]=i.g/255,f[this._vertexIndex++]=i.b/255,f[this._vertexIndex++]=i.a,f[this._vertexIndex++]=_.r/255,f[this._vertexIndex++]=_.g/255,f[this._vertexIndex++]=_.b/255,f[this._vertexIndex++]=_.a,f[this._vertexIndex++]=0}drawRectangle(t,e,i,s,r=tH.Transparent,n=0){this._isFull()&&this.flush(),this._rectangleCount++;let o=this._context.getTransform(),a=this._context.opacity,l=this._context.snapToPixel,h=o.multiply(t.add(tZ(0,0))),d=o.multiply(t.add(tZ(e,0))),c=o.multiply(t.add(tZ(e,i))),u=o.multiply(t.add(tZ(0,i)));l&&(h.x=~~(h.x+eP),h.y=~~(h.y+eP),d.x=~~(d.x+eP),d.y=~~(d.y+eP),u.x=~~(u.x+eP),u.y=~~(u.y+eP),c.x=~~(c.x+eP),c.y=~~(c.y+eP));let p=this._layout.vertexBuffer.bufferData;p[this._vertexIndex++]=h.x,p[this._vertexIndex++]=h.y,p[this._vertexIndex++]=0,p[this._vertexIndex++]=0,p[this._vertexIndex++]=e,p[this._vertexIndex++]=i,p[this._vertexIndex++]=a,p[this._vertexIndex++]=s.r/255,p[this._vertexIndex++]=s.g/255,p[this._vertexIndex++]=s.b/255,p[this._vertexIndex++]=s.a,p[this._vertexIndex++]=r.r/255,p[this._vertexIndex++]=r.g/255,p[this._vertexIndex++]=r.b/255,p[this._vertexIndex++]=r.a,p[this._vertexIndex++]=n,p[this._vertexIndex++]=u.x,p[this._vertexIndex++]=u.y,p[this._vertexIndex++]=0,p[this._vertexIndex++]=1,p[this._vertexIndex++]=e,p[this._vertexIndex++]=i,p[this._vertexIndex++]=a,p[this._vertexIndex++]=s.r/255,p[this._vertexIndex++]=s.g/255,p[this._vertexIndex++]=s.b/255,p[this._vertexIndex++]=s.a,p[this._vertexIndex++]=r.r/255,p[this._vertexIndex++]=r.g/255,p[this._vertexIndex++]=r.b/255,p[this._vertexIndex++]=r.a,p[this._vertexIndex++]=n,p[this._vertexIndex++]=d.x,p[this._vertexIndex++]=d.y,p[this._vertexIndex++]=1,p[this._vertexIndex++]=0,p[this._vertexIndex++]=e,p[this._vertexIndex++]=i,p[this._vertexIndex++]=a,p[this._vertexIndex++]=s.r/255,p[this._vertexIndex++]=s.g/255,p[this._vertexIndex++]=s.b/255,p[this._vertexIndex++]=s.a,p[this._vertexIndex++]=r.r/255,p[this._vertexIndex++]=r.g/255,p[this._vertexIndex++]=r.b/255,p[this._vertexIndex++]=r.a,p[this._vertexIndex++]=n,p[this._vertexIndex++]=c.x,p[this._vertexIndex++]=c.y,p[this._vertexIndex++]=1,p[this._vertexIndex++]=1,p[this._vertexIndex++]=e,p[this._vertexIndex++]=i,p[this._vertexIndex++]=a,p[this._vertexIndex++]=s.r/255,p[this._vertexIndex++]=s.g/255,p[this._vertexIndex++]=s.b/255,p[this._vertexIndex++]=s.a,p[this._vertexIndex++]=r.r/255,p[this._vertexIndex++]=r.g/255,p[this._vertexIndex++]=r.b/255,p[this._vertexIndex++]=r.a,p[this._vertexIndex++]=n}hasPendingDraws(){return 0!==this._rectangleCount}flush(){if(0===this._rectangleCount)return;let t=this._gl;this._shader.use(),this._layout.use(!0),this._shader.setUniformMatrix("u_matrix",this._context.ortho),this._quads.bind(),t.drawElements(t.TRIANGLES,6*this._rectangleCount,this._quads.bufferGlType,0),e_.DrawnImagesCount+=this._rectangleCount,e_.DrawCallCount++,this._rectangleCount=0,this._vertexIndex=0}}class eb{constructor(){this.type="ex.circle",this.priority=0,this._maxCircles=10922,this._circleCount=0,this._vertexIndex=0}initialize(t,e){this._gl=t,this._context=e,this._shader=new eu({gl:t,fragmentSource:"#version 300 es\r\nprecision highp float;\r\n\r\n// UV coord\r\nin vec2 v_uv;\r\n\r\n// Color coord to blend with image\r\nin lowp vec4 v_color;\r\n\r\n// Stroke color if used\r\nin lowp vec4 v_strokeColor;\r\n\r\n// Stroke thickness if used\r\nin lowp float v_strokeThickness;\r\n\r\n// Opacity\r\nin float v_opacity;\r\n\r\nout vec4 fragColor;\r\n\r\nvoid main() {\r\n // make (0, 0) the center the uv \r\n vec2 uv = v_uv * 2.0 - 1.0;\r\n\r\n vec4 color = v_color;\r\n vec4 strokeColor = v_strokeColor;\r\n\r\n // circle border is at radius 1.0 \r\n // dist is > 0 when inside the circle \r\n float d = length(uv);\r\n float dist = 1.0 - length(uv);\r\n\r\n // Fade based on fwidth\r\n float fade = fwidth(dot(uv, uv));\r\n\r\n // if dist is greater than 0 step to 1;\r\n // when we cross this 0 threshold add a smooth fade\r\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\r\n\r\n // if dist is greater than the stroke thickness step to 1\r\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\r\n\r\n strokeColor.a *= fill * stroke;\r\n strokeColor.rgb *= strokeColor.a;\r\n\r\n color.a *= fill * (1.0 - stroke);\r\n color.rgb *= color.a;\r\n\r\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\r\n finalColor.rgb = finalColor.rgb * v_opacity;\r\n finalColor.a = finalColor.a * v_opacity;\r\n fragColor = finalColor;\r\n}",vertexSource:"#version 300 es\r\nin vec2 a_position;\r\n\r\n// UV coordinate\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\n// Opacity \r\nin float a_opacity;\r\nout float v_opacity;\r\n\r\nin vec4 a_color;\r\nout vec4 v_color;\r\n\r\nin vec4 a_strokeColor;\r\nout vec4 v_strokeColor;\r\n\r\nin float a_strokeThickness;\r\nout float v_strokeThickness;\r\n\r\nuniform mat4 u_matrix;\r\n\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho transform matrix\r\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through UV coords\r\n v_uv = a_uv;\r\n // Pass through the Opacity to the fragment shader\r\n v_opacity = a_opacity;\r\n // Pass through the color to the fragment shader\r\n v_color = a_color;\r\n // Pass through the stroke color to the fragment shader\r\n v_strokeColor = a_strokeColor;\r\n // Pass through the stroke thickenss to the fragment shader\r\n v_strokeThickness = a_strokeThickness;\r\n}"}),this._shader.compile(),this._shader.use(),this._shader.setUniformMatrix("u_matrix",e.ortho),this._buffer=new ep({gl:t,size:56*this._maxCircles,type:"dynamic"}),this._layout=new eg({gl:t,shader:this._shader,vertexBuffer:this._buffer,attributes:[["a_position",2],["a_uv",2],["a_opacity",1],["a_color",4],["a_strokeColor",4],["a_strokeThickness",1]]}),this._quads=new ey(t,this._maxCircles,!0)}dispose(){this._buffer.dispose(),this._quads.dispose(),this._shader.dispose(),this._context=null,this._gl=null}_isFull(){return this._circleCount>=this._maxCircles}draw(t,e,i,s=tH.Transparent,r=0){this._isFull()&&this.flush(),this._circleCount++;let n=this._context.getTransform(),o=this._context.opacity,a=this._context.snapToPixel,l=n.multiply(t.add(tZ(-e,-e))),h=n.multiply(t.add(tZ(e,-e))),d=n.multiply(t.add(tZ(e,e))),c=n.multiply(t.add(tZ(-e,e)));a&&(l.x=~~(l.x+eP),l.y=~~(l.y+eP),h.x=~~(h.x+eP),h.y=~~(h.y+eP),c.x=~~(c.x+eP),c.y=~~(c.y+eP),d.x=~~(d.x+eP),d.y=~~(d.y+eP));let u=this._layout.vertexBuffer.bufferData;u[this._vertexIndex++]=l.x,u[this._vertexIndex++]=l.y,u[this._vertexIndex++]=0,u[this._vertexIndex++]=0,u[this._vertexIndex++]=o,u[this._vertexIndex++]=i.r/255,u[this._vertexIndex++]=i.g/255,u[this._vertexIndex++]=i.b/255,u[this._vertexIndex++]=i.a,u[this._vertexIndex++]=s.r/255,u[this._vertexIndex++]=s.g/255,u[this._vertexIndex++]=s.b/255,u[this._vertexIndex++]=s.a,u[this._vertexIndex++]=r/e,u[this._vertexIndex++]=c.x,u[this._vertexIndex++]=c.y,u[this._vertexIndex++]=0,u[this._vertexIndex++]=1,u[this._vertexIndex++]=o,u[this._vertexIndex++]=i.r/255,u[this._vertexIndex++]=i.g/255,u[this._vertexIndex++]=i.b/255,u[this._vertexIndex++]=i.a,u[this._vertexIndex++]=s.r/255,u[this._vertexIndex++]=s.g/255,u[this._vertexIndex++]=s.b/255,u[this._vertexIndex++]=s.a,u[this._vertexIndex++]=r/e,u[this._vertexIndex++]=h.x,u[this._vertexIndex++]=h.y,u[this._vertexIndex++]=1,u[this._vertexIndex++]=0,u[this._vertexIndex++]=o,u[this._vertexIndex++]=i.r/255,u[this._vertexIndex++]=i.g/255,u[this._vertexIndex++]=i.b/255,u[this._vertexIndex++]=i.a,u[this._vertexIndex++]=s.r/255,u[this._vertexIndex++]=s.g/255,u[this._vertexIndex++]=s.b/255,u[this._vertexIndex++]=s.a,u[this._vertexIndex++]=r/e,u[this._vertexIndex++]=d.x,u[this._vertexIndex++]=d.y,u[this._vertexIndex++]=1,u[this._vertexIndex++]=1,u[this._vertexIndex++]=o,u[this._vertexIndex++]=i.r/255,u[this._vertexIndex++]=i.g/255,u[this._vertexIndex++]=i.b/255,u[this._vertexIndex++]=i.a,u[this._vertexIndex++]=s.r/255,u[this._vertexIndex++]=s.g/255,u[this._vertexIndex++]=s.b/255,u[this._vertexIndex++]=s.a,u[this._vertexIndex++]=r/e}hasPendingDraws(){return 0!==this._circleCount}flush(){if(0===this._circleCount)return;let t=this._gl;this._shader.use(),this._layout.use(!0),this._shader.setUniformMatrix("u_matrix",this._context.ortho),this._quads.bind(),t.drawElements(t.TRIANGLES,6*this._circleCount,this._quads.bufferGlType,0),e_.DrawnImagesCount+=this._circleCount,e_.DrawCallCount++,this._circleCount=0,this._vertexIndex=0}}class eC{constructor(t,e,i=100){this.builder=t,this.recycler=e,this.maxObjects=i,this.totalAllocations=0,this.index=0,this.objects=[],this.disableWarnings=!1,this._logger=tW.getInstance()}dispose(){this.objects.length=0}preallocate(){for(let t=0;t=this._maxImages||this._textures.length>=this._maxTextures}draw(t,e,i,s,r,n,o,a,l){var h,d,c,u;this._isFull()&&this.flush(),this._imageCount++,this._addImageAsTexture(t);let p=(null==t?void 0:t.width)||s||0,g=(null==t?void 0:t.height)||r||0,_=[0,0,null!==(h=null!=s?s:null==t?void 0:t.width)&&void 0!==h?h:0,null!==(d=null!=r?r:null==t?void 0:t.height)&&void 0!==d?d:0],f=[null!=e?e:1,null!=i?i:1];void 0!==n&&void 0!==o&&void 0!==a&&void 0!==l&&(_=[null!=e?e:1,null!=i?i:1,null!==(c=null!=s?s:null==t?void 0:t.width)&&void 0!==c?c:0,null!==(u=null!=r?r:null==t?void 0:t.height)&&void 0!==u?u:0],f=[n,o],p=a,g=l),e=_[0],i=_[1];let m=_[2],v=_[3],y=this._context.getTransform(),x=this._context.opacity,w=this._context.snapToPixel,b=tZ(f[0],f[1]),C=tZ(f[0]+p,f[1]),T=tZ(f[0],f[1]+g),S=tZ(f[0]+p,f[1]+g);b=y.multiply(b),C=y.multiply(C),T=y.multiply(T),S=y.multiply(S),w&&(b.x=~~(b.x+tR(b.x)*eP),b.y=~~(b.y+tR(b.y)*eP),C.x=~~(C.x+tR(C.x)*eP),C.y=~~(C.y+tR(C.y)*eP),T.x=~~(T.x+tR(T.x)*eP),T.y=~~(T.y+tR(T.y)*eP),S.x=~~(S.x+tR(S.x)*eP),S.y=~~(S.y+tR(S.y)*eP));let A=this._context.tint,E=this._getTextureIdForImage(t),P=t.width||p,I=t.height||g,k=(e+this.uvPadding)/P,D=(i+this.uvPadding)/I,R=(e+m-this.uvPadding)/P,F=(i+v-this.uvPadding)/I,B=t.width,L=t.height,M=this._layout.vertexBuffer.bufferData;M[this._vertexIndex++]=b.x,M[this._vertexIndex++]=b.y,M[this._vertexIndex++]=x,M[this._vertexIndex++]=B,M[this._vertexIndex++]=L,M[this._vertexIndex++]=k,M[this._vertexIndex++]=D,M[this._vertexIndex++]=E,M[this._vertexIndex++]=A.r/255,M[this._vertexIndex++]=A.g/255,M[this._vertexIndex++]=A.b/255,M[this._vertexIndex++]=A.a,M[this._vertexIndex++]=T.x,M[this._vertexIndex++]=T.y,M[this._vertexIndex++]=x,M[this._vertexIndex++]=B,M[this._vertexIndex++]=L,M[this._vertexIndex++]=k,M[this._vertexIndex++]=F,M[this._vertexIndex++]=E,M[this._vertexIndex++]=A.r/255,M[this._vertexIndex++]=A.g/255,M[this._vertexIndex++]=A.b/255,M[this._vertexIndex++]=A.a,M[this._vertexIndex++]=C.x,M[this._vertexIndex++]=C.y,M[this._vertexIndex++]=x,M[this._vertexIndex++]=B,M[this._vertexIndex++]=L,M[this._vertexIndex++]=R,M[this._vertexIndex++]=D,M[this._vertexIndex++]=E,M[this._vertexIndex++]=A.r/255,M[this._vertexIndex++]=A.g/255,M[this._vertexIndex++]=A.b/255,M[this._vertexIndex++]=A.a,M[this._vertexIndex++]=S.x,M[this._vertexIndex++]=S.y,M[this._vertexIndex++]=x,M[this._vertexIndex++]=B,M[this._vertexIndex++]=L,M[this._vertexIndex++]=R,M[this._vertexIndex++]=F,M[this._vertexIndex++]=E,M[this._vertexIndex++]=A.r/255,M[this._vertexIndex++]=A.g/255,M[this._vertexIndex++]=A.b/255,M[this._vertexIndex++]=A.a}hasPendingDraws(){return 0!==this._imageCount}flush(){if(0===this._imageCount)return;let t=this._gl;this._shader.use(),this._layout.use(!0,48*this._imageCount),this._shader.setUniformMatrix("u_matrix",this._context.ortho),this._shader.setUniformBoolean("u_pixelart",this.pixelArtSampler),this._bindTextures(t),this._quads.bind(),t.drawElements(t.TRIANGLES,6*this._imageCount,this._quads.bufferGlType,0),e_.DrawnImagesCount+=this._imageCount,e_.DrawCallCount++,this._imageCount=0,this._vertexIndex=0,this._textures.length=0}}class ew{constructor(){this.type="ex.rectangle",this.priority=0,this._maxRectangles=10922,this._rectangleCount=0,this._vertexIndex=0}initialize(t,e){this._gl=t,this._context=e,this._shader=new eu({gl:t,fragmentSource:"#version 300 es\r\n\r\nprecision mediump float;\r\n\r\n// UV coord\r\nin vec2 v_uv;\r\n\r\nin vec2 v_size; // in pixels\r\n\r\n// Color coord to blend with image\r\nin lowp vec4 v_color;\r\n\r\n// Stroke color if used\r\nin lowp vec4 v_strokeColor;\r\n\r\n// Stroke thickness if used\r\nin lowp float v_strokeThickness; // in pixels\r\n\r\n// Opacity\r\nin float v_opacity;\r\n\r\nout vec4 fragColor;\r\n\r\nvoid main() {\r\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\r\n vec2 uv = v_uv;\r\n vec2 fragCoord = uv * v_size;\r\n float maxX = v_size.x - v_strokeThickness;\r\n float minX = v_strokeThickness;\r\n float maxY = v_size.y - v_strokeThickness;\r\n float minY = v_strokeThickness;\r\n\r\n if (fragCoord.x < maxX && fragCoord.x > minX &&\r\n fragCoord.y < maxY && fragCoord.y > minY) {\r\n fragColor = v_color;\r\n } else {\r\n fragColor = v_strokeColor;\r\n }\r\n fragColor.a *= v_opacity;\r\n fragColor.rgb *= fragColor.a;\r\n\r\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\r\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\r\n\r\n // float fHalfBorderDist = 0.0;\r\n // float fHalfBorderThickness = 0.0;\r\n\r\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \r\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\r\n // {\r\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\r\n // fHalfBorderThickness = v_strokeThickness / 2.0;\r\n // }\r\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \r\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\r\n // {\r\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\r\n // fHalfBorderThickness = v_strokeThickness / 2.0;\r\n // }\r\n // else\r\n // {\r\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\r\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\r\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\r\n \r\n // float ellipse_ab = v_radius-v_strokeThickness;\r\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\r\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \r\n \r\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\r\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\r\n // }\r\n\r\n // vec4 v4FromColor = v_strokeColor;\r\n // v4FromColor.rgb *= v4FromColor.a;\r\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\r\n // if (fHalfBorderDist < 0.0) {\r\n // v4ToColor = v_color;\r\n // v4ToColor.rgb *= v4ToColor.a;\r\n // }\r\n\r\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\r\n\r\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\r\n // gl_FragColor = finalColor;\r\n}",vertexSource:"#version 300 es\r\nin vec2 a_position;\r\n\r\n// UV coordinate\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nin vec2 a_size;\r\nout vec2 v_size;\r\n\r\n// Opacity \r\nin float a_opacity;\r\nout float v_opacity;\r\n\r\nin vec4 a_color;\r\nout vec4 v_color;\r\n\r\nin vec4 a_strokeColor;\r\nout vec4 v_strokeColor;\r\n\r\nin float a_strokeThickness;\r\nout float v_strokeThickness;\r\n\r\nuniform mat4 u_matrix;\r\n\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho transform matrix\r\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through UV coords\r\n v_uv = a_uv;\r\n // Pass through size\r\n v_size = a_size;\r\n // Pass through the Opacity to the fragment shader\r\n v_opacity = a_opacity;\r\n // Pass through the color to the fragment shader\r\n v_color = a_color;\r\n // Pass through the stroke color to the fragment shader\r\n v_strokeColor = a_strokeColor;\r\n // Pass through the stroke thickenss to the fragment shader\r\n v_strokeThickness = a_strokeThickness;\r\n}"}),this._shader.compile(),this._shader.use(),this._shader.setUniformMatrix("u_matrix",e.ortho),this._buffer=new ep({gl:t,size:64*this._maxRectangles,type:"dynamic"}),this._layout=new eg({gl:t,shader:this._shader,vertexBuffer:this._buffer,attributes:[["a_position",2],["a_uv",2],["a_size",2],["a_opacity",1],["a_color",4],["a_strokeColor",4],["a_strokeThickness",1]]}),this._quads=new ey(t,this._maxRectangles,!0)}dispose(){this._buffer.dispose(),this._quads.dispose(),this._shader.dispose(),this._context=null,this._gl=null}_isFull(){return this._rectangleCount>=this._maxRectangles}draw(...t){t[0]instanceof tN&&t[1]instanceof tN?this.drawLine.apply(this,t):this.drawRectangle.apply(this,t)}drawLine(t,e,i,s=1){this._isFull()&&this.flush(),this._rectangleCount++;let r=this._context.getTransform(),n=this._context.opacity,o=this._context.snapToPixel,a=e.sub(t),l=a.size,h=a.normalize().perpendicular(),d=s/2,c=r.multiply(h.scale(d).add(t)),u=r.multiply(h.scale(-d).add(t)),p=r.multiply(h.scale(d).add(e)),g=r.multiply(h.scale(-d).add(e));o&&(c.x=~~(c.x+eP),c.y=~~(c.y+eP),p.x=~~(p.x+eP),p.y=~~(p.y+eP),u.x=~~(u.x+eP),u.y=~~(u.y+eP),g.x=~~(g.x+eP),g.y=~~(g.y+eP));let _=tH.Transparent,f=this._layout.vertexBuffer.bufferData;f[this._vertexIndex++]=c.x,f[this._vertexIndex++]=c.y,f[this._vertexIndex++]=0,f[this._vertexIndex++]=0,f[this._vertexIndex++]=l,f[this._vertexIndex++]=s,f[this._vertexIndex++]=n,f[this._vertexIndex++]=i.r/255,f[this._vertexIndex++]=i.g/255,f[this._vertexIndex++]=i.b/255,f[this._vertexIndex++]=i.a,f[this._vertexIndex++]=_.r/255,f[this._vertexIndex++]=_.g/255,f[this._vertexIndex++]=_.b/255,f[this._vertexIndex++]=_.a,f[this._vertexIndex++]=0,f[this._vertexIndex++]=u.x,f[this._vertexIndex++]=u.y,f[this._vertexIndex++]=0,f[this._vertexIndex++]=1,f[this._vertexIndex++]=l,f[this._vertexIndex++]=s,f[this._vertexIndex++]=n,f[this._vertexIndex++]=i.r/255,f[this._vertexIndex++]=i.g/255,f[this._vertexIndex++]=i.b/255,f[this._vertexIndex++]=i.a,f[this._vertexIndex++]=_.r/255,f[this._vertexIndex++]=_.g/255,f[this._vertexIndex++]=_.b/255,f[this._vertexIndex++]=_.a,f[this._vertexIndex++]=0,f[this._vertexIndex++]=p.x,f[this._vertexIndex++]=p.y,f[this._vertexIndex++]=1,f[this._vertexIndex++]=0,f[this._vertexIndex++]=l,f[this._vertexIndex++]=s,f[this._vertexIndex++]=n,f[this._vertexIndex++]=i.r/255,f[this._vertexIndex++]=i.g/255,f[this._vertexIndex++]=i.b/255,f[this._vertexIndex++]=i.a,f[this._vertexIndex++]=_.r/255,f[this._vertexIndex++]=_.g/255,f[this._vertexIndex++]=_.b/255,f[this._vertexIndex++]=_.a,f[this._vertexIndex++]=0,f[this._vertexIndex++]=g.x,f[this._vertexIndex++]=g.y,f[this._vertexIndex++]=1,f[this._vertexIndex++]=1,f[this._vertexIndex++]=l,f[this._vertexIndex++]=s,f[this._vertexIndex++]=n,f[this._vertexIndex++]=i.r/255,f[this._vertexIndex++]=i.g/255,f[this._vertexIndex++]=i.b/255,f[this._vertexIndex++]=i.a,f[this._vertexIndex++]=_.r/255,f[this._vertexIndex++]=_.g/255,f[this._vertexIndex++]=_.b/255,f[this._vertexIndex++]=_.a,f[this._vertexIndex++]=0}drawRectangle(t,e,i,s,r=tH.Transparent,n=0){this._isFull()&&this.flush(),this._rectangleCount++;let o=this._context.getTransform(),a=this._context.opacity,l=this._context.snapToPixel,h=o.multiply(t.add(tZ(0,0))),d=o.multiply(t.add(tZ(e,0))),c=o.multiply(t.add(tZ(e,i))),u=o.multiply(t.add(tZ(0,i)));l&&(h.x=~~(h.x+eP),h.y=~~(h.y+eP),d.x=~~(d.x+eP),d.y=~~(d.y+eP),u.x=~~(u.x+eP),u.y=~~(u.y+eP),c.x=~~(c.x+eP),c.y=~~(c.y+eP));let p=this._layout.vertexBuffer.bufferData;p[this._vertexIndex++]=h.x,p[this._vertexIndex++]=h.y,p[this._vertexIndex++]=0,p[this._vertexIndex++]=0,p[this._vertexIndex++]=e,p[this._vertexIndex++]=i,p[this._vertexIndex++]=a,p[this._vertexIndex++]=s.r/255,p[this._vertexIndex++]=s.g/255,p[this._vertexIndex++]=s.b/255,p[this._vertexIndex++]=s.a,p[this._vertexIndex++]=r.r/255,p[this._vertexIndex++]=r.g/255,p[this._vertexIndex++]=r.b/255,p[this._vertexIndex++]=r.a,p[this._vertexIndex++]=n,p[this._vertexIndex++]=u.x,p[this._vertexIndex++]=u.y,p[this._vertexIndex++]=0,p[this._vertexIndex++]=1,p[this._vertexIndex++]=e,p[this._vertexIndex++]=i,p[this._vertexIndex++]=a,p[this._vertexIndex++]=s.r/255,p[this._vertexIndex++]=s.g/255,p[this._vertexIndex++]=s.b/255,p[this._vertexIndex++]=s.a,p[this._vertexIndex++]=r.r/255,p[this._vertexIndex++]=r.g/255,p[this._vertexIndex++]=r.b/255,p[this._vertexIndex++]=r.a,p[this._vertexIndex++]=n,p[this._vertexIndex++]=d.x,p[this._vertexIndex++]=d.y,p[this._vertexIndex++]=1,p[this._vertexIndex++]=0,p[this._vertexIndex++]=e,p[this._vertexIndex++]=i,p[this._vertexIndex++]=a,p[this._vertexIndex++]=s.r/255,p[this._vertexIndex++]=s.g/255,p[this._vertexIndex++]=s.b/255,p[this._vertexIndex++]=s.a,p[this._vertexIndex++]=r.r/255,p[this._vertexIndex++]=r.g/255,p[this._vertexIndex++]=r.b/255,p[this._vertexIndex++]=r.a,p[this._vertexIndex++]=n,p[this._vertexIndex++]=c.x,p[this._vertexIndex++]=c.y,p[this._vertexIndex++]=1,p[this._vertexIndex++]=1,p[this._vertexIndex++]=e,p[this._vertexIndex++]=i,p[this._vertexIndex++]=a,p[this._vertexIndex++]=s.r/255,p[this._vertexIndex++]=s.g/255,p[this._vertexIndex++]=s.b/255,p[this._vertexIndex++]=s.a,p[this._vertexIndex++]=r.r/255,p[this._vertexIndex++]=r.g/255,p[this._vertexIndex++]=r.b/255,p[this._vertexIndex++]=r.a,p[this._vertexIndex++]=n}hasPendingDraws(){return 0!==this._rectangleCount}flush(){if(0===this._rectangleCount)return;let t=this._gl;this._shader.use(),this._layout.use(!0),this._shader.setUniformMatrix("u_matrix",this._context.ortho),this._quads.bind(),t.drawElements(t.TRIANGLES,6*this._rectangleCount,this._quads.bufferGlType,0),e_.DrawnImagesCount+=this._rectangleCount,e_.DrawCallCount++,this._rectangleCount=0,this._vertexIndex=0}}class eb{constructor(){this.type="ex.circle",this.priority=0,this._maxCircles=10922,this._circleCount=0,this._vertexIndex=0}initialize(t,e){this._gl=t,this._context=e,this._shader=new eu({gl:t,fragmentSource:"#version 300 es\r\nprecision highp float;\r\n\r\n// UV coord\r\nin vec2 v_uv;\r\n\r\n// Color coord to blend with image\r\nin lowp vec4 v_color;\r\n\r\n// Stroke color if used\r\nin lowp vec4 v_strokeColor;\r\n\r\n// Stroke thickness if used\r\nin lowp float v_strokeThickness;\r\n\r\n// Opacity\r\nin float v_opacity;\r\n\r\nout vec4 fragColor;\r\n\r\nvoid main() {\r\n // make (0, 0) the center the uv \r\n vec2 uv = v_uv * 2.0 - 1.0;\r\n\r\n vec4 color = v_color;\r\n vec4 strokeColor = v_strokeColor;\r\n\r\n // circle border is at radius 1.0 \r\n // dist is > 0 when inside the circle \r\n float d = length(uv);\r\n float dist = 1.0 - length(uv);\r\n\r\n // Fade based on fwidth\r\n float fade = fwidth(dot(uv, uv));\r\n\r\n // if dist is greater than 0 step to 1;\r\n // when we cross this 0 threshold add a smooth fade\r\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\r\n\r\n // if dist is greater than the stroke thickness step to 1\r\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\r\n\r\n strokeColor.a *= fill * stroke;\r\n strokeColor.rgb *= strokeColor.a;\r\n\r\n color.a *= fill * (1.0 - stroke);\r\n color.rgb *= color.a;\r\n\r\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\r\n finalColor.rgb = finalColor.rgb * v_opacity;\r\n finalColor.a = finalColor.a * v_opacity;\r\n fragColor = finalColor;\r\n}",vertexSource:"#version 300 es\r\nin vec2 a_position;\r\n\r\n// UV coordinate\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\n// Opacity \r\nin float a_opacity;\r\nout float v_opacity;\r\n\r\nin vec4 a_color;\r\nout vec4 v_color;\r\n\r\nin vec4 a_strokeColor;\r\nout vec4 v_strokeColor;\r\n\r\nin float a_strokeThickness;\r\nout float v_strokeThickness;\r\n\r\nuniform mat4 u_matrix;\r\n\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho transform matrix\r\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through UV coords\r\n v_uv = a_uv;\r\n // Pass through the Opacity to the fragment shader\r\n v_opacity = a_opacity;\r\n // Pass through the color to the fragment shader\r\n v_color = a_color;\r\n // Pass through the stroke color to the fragment shader\r\n v_strokeColor = a_strokeColor;\r\n // Pass through the stroke thickenss to the fragment shader\r\n v_strokeThickness = a_strokeThickness;\r\n}"}),this._shader.compile(),this._shader.use(),this._shader.setUniformMatrix("u_matrix",e.ortho),this._buffer=new ep({gl:t,size:56*this._maxCircles,type:"dynamic"}),this._layout=new eg({gl:t,shader:this._shader,vertexBuffer:this._buffer,attributes:[["a_position",2],["a_uv",2],["a_opacity",1],["a_color",4],["a_strokeColor",4],["a_strokeThickness",1]]}),this._quads=new ey(t,this._maxCircles,!0)}dispose(){this._buffer.dispose(),this._quads.dispose(),this._shader.dispose(),this._context=null,this._gl=null}_isFull(){return this._circleCount>=this._maxCircles}draw(t,e,i,s=tH.Transparent,r=0){this._isFull()&&this.flush(),this._circleCount++;let n=this._context.getTransform(),o=this._context.opacity,a=this._context.snapToPixel,l=n.multiply(t.add(tZ(-e,-e))),h=n.multiply(t.add(tZ(e,-e))),d=n.multiply(t.add(tZ(e,e))),c=n.multiply(t.add(tZ(-e,e)));a&&(l.x=~~(l.x+eP),l.y=~~(l.y+eP),h.x=~~(h.x+eP),h.y=~~(h.y+eP),c.x=~~(c.x+eP),c.y=~~(c.y+eP),d.x=~~(d.x+eP),d.y=~~(d.y+eP));let u=this._layout.vertexBuffer.bufferData;u[this._vertexIndex++]=l.x,u[this._vertexIndex++]=l.y,u[this._vertexIndex++]=0,u[this._vertexIndex++]=0,u[this._vertexIndex++]=o,u[this._vertexIndex++]=i.r/255,u[this._vertexIndex++]=i.g/255,u[this._vertexIndex++]=i.b/255,u[this._vertexIndex++]=i.a,u[this._vertexIndex++]=s.r/255,u[this._vertexIndex++]=s.g/255,u[this._vertexIndex++]=s.b/255,u[this._vertexIndex++]=s.a,u[this._vertexIndex++]=r/e,u[this._vertexIndex++]=c.x,u[this._vertexIndex++]=c.y,u[this._vertexIndex++]=0,u[this._vertexIndex++]=1,u[this._vertexIndex++]=o,u[this._vertexIndex++]=i.r/255,u[this._vertexIndex++]=i.g/255,u[this._vertexIndex++]=i.b/255,u[this._vertexIndex++]=i.a,u[this._vertexIndex++]=s.r/255,u[this._vertexIndex++]=s.g/255,u[this._vertexIndex++]=s.b/255,u[this._vertexIndex++]=s.a,u[this._vertexIndex++]=r/e,u[this._vertexIndex++]=h.x,u[this._vertexIndex++]=h.y,u[this._vertexIndex++]=1,u[this._vertexIndex++]=0,u[this._vertexIndex++]=o,u[this._vertexIndex++]=i.r/255,u[this._vertexIndex++]=i.g/255,u[this._vertexIndex++]=i.b/255,u[this._vertexIndex++]=i.a,u[this._vertexIndex++]=s.r/255,u[this._vertexIndex++]=s.g/255,u[this._vertexIndex++]=s.b/255,u[this._vertexIndex++]=s.a,u[this._vertexIndex++]=r/e,u[this._vertexIndex++]=d.x,u[this._vertexIndex++]=d.y,u[this._vertexIndex++]=1,u[this._vertexIndex++]=1,u[this._vertexIndex++]=o,u[this._vertexIndex++]=i.r/255,u[this._vertexIndex++]=i.g/255,u[this._vertexIndex++]=i.b/255,u[this._vertexIndex++]=i.a,u[this._vertexIndex++]=s.r/255,u[this._vertexIndex++]=s.g/255,u[this._vertexIndex++]=s.b/255,u[this._vertexIndex++]=s.a,u[this._vertexIndex++]=r/e}hasPendingDraws(){return 0!==this._circleCount}flush(){if(0===this._circleCount)return;let t=this._gl;this._shader.use(),this._layout.use(!0),this._shader.setUniformMatrix("u_matrix",this._context.ortho),this._quads.bind(),t.drawElements(t.TRIANGLES,6*this._circleCount,this._quads.bufferGlType,0),e_.DrawnImagesCount+=this._circleCount,e_.DrawCallCount++,this._circleCount=0,this._vertexIndex=0}}class eC{constructor(t,e,i=100){this.builder=t,this.recycler=e,this.maxObjects=i,this.totalAllocations=0,this.index=0,this.objects=[],this.disableWarnings=!1,this._logger=tW.getInstance()}dispose(){this.objects.length=0}preallocate(){for(let t=0;t4096||t.height>4096)&&(e=!1),e}constructor(t){this._logger=tW.getInstance(),this._renderers=new Map,this._isDrawLifecycle=!1,this.useDrawSorting=!0,this._drawCallPool=new eC(()=>new eT,t=>(t.priority=0,t.z=0,t.renderer=void 0,t.args=void 0,t),4e3),this._drawCalls=[],this._postProcessTargets=[],this._postprocessors=[],this._transform=new t5,this._state=new t4,this.snapToPixel=!1,this.smoothing=!1,this.pixelArtSampler=!1,this.uvPadding=.01,this.backgroundColor=tH.ExcaliburBlue,this.multiSampleAntialiasing=!0,this.transparency=!0,this._disposed=!1,this.debug=new eI(this),this._totalPostProcessorTime=0;let{canvasElement:e,context:i,enableTransparency:s,antialiasing:r,uvPadding:n,multiSampleAntialiasing:o,pixelArtSampler:a,powerPreference:l,snapToPixel:h,backgroundColor:d,useDrawSorting:c}=t;if(this.__gl=null!=i?i:e.getContext("webgl2",{antialias:null!=r?r:this.smoothing,premultipliedAlpha:!1,alpha:null!=s?s:this.transparency,depth:!1,powerPreference:null!=l?l:"high-performance"}),!this.__gl)throw Error("Failed to retrieve webgl context from browser");this.textureLoader=new ei(this.__gl),this.snapToPixel=null!=h?h:this.snapToPixel,this.smoothing=null!=r?r:this.smoothing,this.transparency=null!=s?s:this.transparency,this.pixelArtSampler=null!=a?a:this.pixelArtSampler,this.uvPadding=null!=n?n:this.uvPadding,this.multiSampleAntialiasing="boolean"==typeof o?o:this.multiSampleAntialiasing,this.samples="object"==typeof o?o.samples:void 0,this.backgroundColor=null!=d?d:this.backgroundColor,this.useDrawSorting=null!=c?c:this.useDrawSorting,this._drawCallPool.disableWarnings=!0,this._drawCallPool.preallocate(),this._init()}dispose(){if(!this._disposed){for(let t of(this._disposed=!0,this.textureLoader.dispose(),this._renderers.values()))t.dispose();this._renderers.clear(),this._drawCallPool.dispose(),this._drawCalls.length=0,this.__gl=null}}_init(){let t=this.__gl;this._ortho=t1.ortho(0,t.canvas.width,t.canvas.height,0,400,-400),t.viewport(0,0,t.canvas.width,t.canvas.height),t.clearColor(this.backgroundColor.r/255,this.backgroundColor.g/255,this.backgroundColor.b/255,this.backgroundColor.a),t.clear(t.COLOR_BUFFER_BIT),t.enable(t.BLEND),t.blendEquation(t.FUNC_ADD),t.blendFunc(t.ONE,t.ONE_MINUS_SRC_ALPHA),t.blendEquationSeparate(t.FUNC_ADD,t.FUNC_ADD),t.blendFuncSeparate(t.ONE,t.ONE_MINUS_SRC_ALPHA,t.ONE,t.ONE_MINUS_SRC_ALPHA),this.register(new ex({uvPadding:this.uvPadding,pixelArtSampler:this.pixelArtSampler})),this.register(new eE),this.register(new ew),this.register(new eb),this.register(new em),this.register(new ef),this.materialScreenTexture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.materialScreenTexture),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.width,this.height,0,t.RGBA,t.UNSIGNED_BYTE,null),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.REPEAT),t.bindTexture(t.TEXTURE_2D,null),this._screenRenderer=new ev(t),this._renderTarget=new el({gl:t,transparency:this.transparency,width:t.canvas.width,height:t.canvas.height}),this._postProcessTargets=[new el({gl:t,transparency:this.transparency,width:t.canvas.width,height:t.canvas.height}),new el({gl:t,transparency:this.transparency,width:t.canvas.width,height:t.canvas.height})],this._msaaTarget=new el({gl:t,transparency:this.transparency,width:t.canvas.width,height:t.canvas.height,antialias:this.multiSampleAntialiasing,samples:this.samples})}register(t){this._renderers.set(t.type,t),t.initialize(this.__gl,this)}get(t){return this._renderers.get(t)}_isCurrentRenderer(t){return!this._currentRenderer||this._currentRenderer===t}beginDrawLifecycle(){this._isDrawLifecycle=!0}endDrawLifecycle(){this._isDrawLifecycle=!1}draw(t,...e){this._isDrawLifecycle||this._logger.warnOnce(`Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors. -If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);let i=this._renderers.get(t);if(i){if(this.useDrawSorting){let s=this._drawCallPool.get();s.z=this._state.current.z,s.priority=i.priority,s.renderer=t,this.getTransform().clone(s.transform),s.state.z=this._state.current.z,s.state.opacity=this._state.current.opacity,s.state.tint=this._state.current.tint,s.state.material=this._state.current.material,s.args=e,this._drawCalls.push(s)}else this._currentRenderer||(this._currentRenderer=i),this._isCurrentRenderer(i)||this._currentRenderer.flush(),i.draw(...e),this._currentRenderer=i}else throw Error(`No renderer with name ${t} has been registered`)}resetTransform(){this._transform.current=t2.identity()}updateViewport(t){let e=this.__gl;this._ortho=this._ortho=t1.ortho(0,t.width,t.height,0,400,-400),this._renderTarget.setResolution(e.canvas.width,e.canvas.height),this._msaaTarget.setResolution(e.canvas.width,e.canvas.height),this._postProcessTargets[0].setResolution(e.canvas.width,e.canvas.height),this._postProcessTargets[1].setResolution(e.canvas.width,e.canvas.height)}drawImage(t,e,i,s,r,n,o,a,l){if(0!==s&&0!==r&&0!==a&&0!==l&&0!==t.width&&0!==t.height){if(!t){tW.getInstance().warn("Cannot draw a null or undefined image"),console.trace&&console.trace();return}this._state.current.material?this.draw("ex.material",t,e,i,s,r,n,o,a,l):this.draw("ex.image",t,e,i,s,r,n,o,a,l)}}drawLine(t,e,i,s=1){this.draw("ex.rectangle",t,e,i,s)}drawRectangle(t,e,i,s,r,n){this.draw("ex.rectangle",t,e,i,s,r,n)}drawCircle(t,e,i,s,r){this.draw("ex.circle",t,e,i,s,r)}save(){this._transform.save(),this._state.save()}restore(){this._transform.restore(),this._state.restore()}translate(t,e){this._transform.translate(this.snapToPixel?~~(t+eP):t,this.snapToPixel?~~(e+eP):e)}rotate(t){this._transform.rotate(t)}scale(t,e){this._transform.scale(t,e)}transform(t){this._transform.current=t}getTransform(){return this._transform.current}multiply(t){this._transform.current.multiply(t,this._transform.current)}addPostProcessor(t){this._postprocessors.push(t),t.initialize(this.__gl)}removePostProcessor(t){let e=this._postprocessors.indexOf(t);-1!==e&&this._postprocessors.splice(e,1)}clearPostProcessors(){this._postprocessors.length=0}updatePostProcessors(t){for(let e of this._postprocessors){let i=e.getShader();i.use();let s=i.getUniforms();this._totalPostProcessorTime+=t,s.find(t=>"u_time_ms"===t.name)&&i.setUniformFloat("u_time_ms",this._totalPostProcessorTime),s.find(t=>"u_elapsed_ms"===t.name)&&i.setUniformFloat("u_elapsed_ms",t),s.find(t=>"u_resolution"===t.name)&&i.setUniformFloatVector("u_resolution",tZ(this.width,this.height)),e.onUpdate&&e.onUpdate(t)}}set material(t){this._state.current.material=t}get material(){return this._state.current.material}createMaterial(t){return new eA({...t,graphicsContext:this})}createShader(t){let e=this.__gl,{vertexSource:i,fragmentSource:s}=t,r=new eu({gl:e,vertexSource:i,fragmentSource:s});return r.compile(),r}clear(){let t=this.__gl;(this.multiSampleAntialiasing?this._msaaTarget:this._renderTarget).use(),t.clearColor(this.backgroundColor.r/255,this.backgroundColor.g/255,this.backgroundColor.b/255,this.backgroundColor.a),t.clear(t.COLOR_BUFFER_BIT)}flush(){let t=this.multiSampleAntialiasing?this._msaaTarget:this._renderTarget;if(t.use(),this.useDrawSorting){let e=new Map;for(let[t]of this._renderers){let i=this._drawCalls.findIndex(e=>e.renderer===t);e.set(t,i)}this._drawCalls.sort((t,i)=>{let s=t.z-i.z,r=e.get(t.renderer)-e.get(i.renderer),n=t.priority-i.priority;return 0===s?0===n?r:n:s});let i=this._transform.current,s=this._state.current;if(this._drawCalls.length){let e=this._drawCalls[0].renderer,i=this._renderers.get(e);for(let s=0;s0&&t.toRenderSource().use();for(let e=0;evoid 0!==t).map(t=>"number"==typeof t&&this.snapToPixel?~~t:t);this.__ctx.drawImage.apply(this.__ctx,h),e_.DrawCallCount++,e_.DrawnImagesCount=1}drawLine(t,e,i,s=1){this.__ctx.save(),this.__ctx.beginPath(),this.__ctx.strokeStyle=i.toString(),this.__ctx.moveTo(this.snapToPixel?~~(t.x+1e-4):t.x,this.snapToPixel?~~(t.y+1e-4):t.y),this.__ctx.lineTo(this.snapToPixel?~~(e.x+1e-4):e.x,this.snapToPixel?~~(e.y+1e-4):e.y),this.__ctx.lineWidth=s,this.__ctx.stroke(),this.__ctx.closePath(),this.__ctx.restore()}drawRectangle(t,e,i,s){this.__ctx.save(),this.__ctx.fillStyle=s.toString(),this.__ctx.fillRect(this.snapToPixel?~~(t.x+1e-4):t.x,this.snapToPixel?~~(t.y+1e-4):t.y,this.snapToPixel?~~(e+1e-4):e,this.snapToPixel?~~(i+1e-4):i),this.__ctx.restore()}drawCircle(t,e,i,s,r){this.__ctx.save(),this.__ctx.beginPath(),s&&(this.__ctx.strokeStyle=s.toString()),r&&(this.__ctx.lineWidth=r),this.__ctx.fillStyle=i.toString(),this.__ctx.arc(this.snapToPixel?~~(t.x+1e-4):t.x,this.snapToPixel?~~(t.y+1e-4):t.y,e,0,2*Math.PI),this.__ctx.fill(),s&&this.__ctx.stroke(),this.__ctx.closePath(),this.__ctx.restore()}save(){this.__ctx.save(),this._state.save()}restore(){this.__ctx.restore(),this._state.restore()}translate(t,e){this.__ctx.translate(this.snapToPixel?~~(t+1e-4):t,this.snapToPixel?~~(e+1e-4):e)}rotate(t){this.__ctx.rotate(t)}scale(t,e){this.__ctx.scale(t,e)}getTransform(){throw Error("Not implemented")}multiply(t){this.__ctx.setTransform(this.__ctx.getTransform().multiply(t.toDOMMatrix()))}addPostProcessor(t){}removePostProcessor(t){}clearPostProcessors(){}updatePostProcessors(t){}beginDrawLifecycle(){}endDrawLifecycle(){}set material(t){this._state.current.material=t}get material(){return this._state.current.material}createMaterial(t){return null}clear(){this.__ctx.clearRect(0,0,this.width,this.height),this.__ctx.fillStyle=this.backgroundColor.toString(),this.__ctx.fillRect(0,0,this.width,this.height),e_.clear()}flush(){}dispose(){this.__ctx=null}}(l=V||(V={})).Fixed="Fixed",l.FitContainerAndFill="FitContainerAndFill",l.FitScreenAndFill="FitScreenAndFill",l.FitContainerAndZoom="FitContainerAndZoom",l.FitScreenAndZoom="FitScreenAndZoom",l.FitScreen="FitScreen",l.FillScreen="FillScreen",l.FitContainer="FitContainer",l.FillContainer="FillContainer";class eF{static get SVGA(){return{width:800,height:600}}static get Standard(){return{width:1920,height:1080}}static get Atari2600(){return{width:160,height:192}}static get GameBoy(){return{width:160,height:144}}static get GameBoyAdvance(){return{width:240,height:160}}static get NintendoDS(){return{width:256,height:192}}static get NES(){return{width:256,height:224}}static get SNES(){return{width:256,height:244}}}let eB={ScreenResize:"resize",PixelRatioChange:"pixelratio",FullScreenChange:"fullscreen"};class eM{constructor(t){var e,i,s,r;this.events=new tP,this._antialiasing=!0,this._canvasImageRendering="auto",this._resolutionStack=[],this._viewportStack=[],this._pixelRatioOverride=null,this._isFullScreen=!1,this._isDisposed=!1,this._logger=tW.getInstance(),this._fullscreenChangeHandler=()=>{this._isDisposed||(this._isFullScreen=!this._isFullScreen,this._logger.debug("Fullscreen Change",this._isFullScreen),this.events.emit("fullscreen",{fullscreen:this.isFullScreen}))},this._pixelRatioChangeHandler=()=>{this._isDisposed||(this._logger.debug("Pixel Ratio Change",window.devicePixelRatio),this._listenForPixelRatio(),this._devicePixelRatio=this._calculateDevicePixelRatio(),this.applyResolutionAndViewport(),this.events.emit("pixelratio",{pixelRatio:this.pixelRatio}))},this._resizeHandler=()=>{if(this._isDisposed)return;let t=this.parent;this._logger.debug("View port resized"),this._setResolutionAndViewportByDisplayMode(t),this.applyResolutionAndViewport(),this.events.emit("resize",{resolution:this.resolution,viewport:this.viewport})},this._devicePixelRatio=this._calculateDevicePixelRatio(),this._contentArea=new tq,this.viewport=t.viewport,this.resolution=null!==(e=t.resolution)&&void 0!==e?e:{...this.viewport},this._contentResolution=this.resolution,this._displayMode=null!==(i=t.displayMode)&&void 0!==i?i:V.Fixed,this._canvas=t.canvas,this.graphicsContext=t.context,this._antialiasing=null!==(s=t.antialiasing)&&void 0!==s?s:this._antialiasing,this._canvasImageRendering=null!==(r=t.canvasImageRendering)&&void 0!==r?r:this._canvasImageRendering,this._browser=t.browser,this._pixelRatioOverride=t.pixelRatio,this._applyDisplayMode(),this._listenForPixelRatio(),this._canvas.addEventListener("fullscreenchange",this._fullscreenChangeHandler),this.applyResolutionAndViewport()}_listenForPixelRatio(){this._mediaQueryList&&!this._mediaQueryList.addEventListener&&this._mediaQueryList.removeListener(this._pixelRatioChangeHandler),this._mediaQueryList=this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),this._mediaQueryList.addEventListener?this._mediaQueryList.addEventListener("change",this._pixelRatioChangeHandler,{once:!0}):this._mediaQueryList.addListener(this._pixelRatioChangeHandler)}dispose(){this._isDisposed||(this._isDisposed=!0,this.events.clear(),this._browser.window.off("resize",this._resizeHandler),this._browser.window.clear(),this._resizeObserver&&this._resizeObserver.disconnect(),this.parent.removeEventListener("resize",this._resizeHandler),this._mediaQueryList.removeEventListener?this._mediaQueryList.removeEventListener("change",this._pixelRatioChangeHandler):this._mediaQueryList.removeListener(this._pixelRatioChangeHandler),this._canvas.removeEventListener("fullscreenchange",this._fullscreenChangeHandler),this._canvas=null)}_calculateDevicePixelRatio(){return window.devicePixelRatio<1?1:window.devicePixelRatio||1}get pixelRatio(){return this._pixelRatioOverride?this._pixelRatioOverride:this._devicePixelRatio}get pixelRatioOverride(){return this._pixelRatioOverride}set pixelRatioOverride(t){this._pixelRatioOverride=t}get isHiDpi(){return 1!==this.pixelRatio}get displayMode(){return this._displayMode}get canvas(){return this._canvas}get parent(){switch(this.displayMode){case V.FillContainer:case V.FitContainer:case V.FitContainerAndFill:case V.FitContainerAndZoom:return this.canvas.parentElement||document.body;default:return window}}get resolution(){return this._resolution}set resolution(t){this._resolution=t}get viewport(){return this._viewport?this._viewport:this._resolution}set viewport(t){this._viewport=t}get aspectRatio(){return this._resolution.width/this._resolution.height}get scaledWidth(){return this._resolution.width*this.pixelRatio}get scaledHeight(){return this._resolution.height*this.pixelRatio}setCurrentCamera(t){this._camera=t}pushResolutionAndViewport(){this._resolutionStack.push(this.resolution),this._viewportStack.push(this.viewport),this.resolution={...this.resolution},this.viewport={...this.viewport}}peekViewport(){return this._viewportStack[this._viewportStack.length-1]}peekResolution(){return this._resolutionStack[this._resolutionStack.length-1]}popResolutionAndViewport(){this._resolutionStack.length&&this._viewportStack.length&&(this.resolution=this._resolutionStack.pop(),this.viewport=this._viewportStack.pop())}applyResolutionAndViewport(){this._canvas.width=this.scaledWidth,this._canvas.height=this.scaledHeight,this.graphicsContext instanceof ek&&!this.graphicsContext.checkIfResolutionSupported({width:this.scaledWidth,height:this.scaledHeight})&&this._logger.warnOnce(`The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio}) are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly. Try reducing the resolution or disabling Hi DPI scaling to avoid this (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).`),"auto"===this._canvasImageRendering?this._canvas.style.imageRendering="auto":(this._canvas.style.imageRendering="pixelated",""===this._canvas.style.imageRendering&&(this._canvas.style.imageRendering="crisp-edges")),this._canvas.style.width=this.viewport.width+"px",this._canvas.style.height=this.viewport.height+"px",this.graphicsContext.updateViewport(this.resolution),this.graphicsContext.resetTransform(),this.graphicsContext.smoothing=this._antialiasing,this.graphicsContext instanceof eR&&this.graphicsContext.scale(this.pixelRatio,this.pixelRatio)}get antialiasing(){return this._antialiasing}set antialiasing(t){this._antialiasing=t,this.graphicsContext.smoothing=this._antialiasing}get isFullScreen(){return this._isFullScreen}goFullScreen(t){if(t){let e=document.getElementById(t);if(e)return e.getAttribute("ex-fullscreen-listener")||(e.setAttribute("ex-fullscreen-listener","true"),e.addEventListener("fullscreenchange",this._fullscreenChangeHandler)),e.requestFullscreen()}return this._canvas.requestFullscreen()}exitFullScreen(){return document.exitFullscreen()}pageToScreenCoordinates(t){let e=t.x,i=t.y;if(this._isFullScreen||(e-=tX(this._canvas).x,i-=tX(this._canvas).y),this._isFullScreen){if(window.innerWidth/this.aspectRatiot?this.canvas.style.left=-(o-t)/2+"px":this.canvas.style.left="",a>e?this.canvas.style.top=-(a-e)/2+"px":this.canvas.style.top="",this.viewport={width:o,height:a};let l=tq.fromDimension(this.viewport.width,this.viewport.height,tN.Zero);if(this.viewport.width>t){let e=(this.viewport.width-t)/this.viewport.width*this.resolution.width;l.top=0,l.left=e/2,l.right=this.resolution.width-e/2,l.bottom=this.resolution.height}if(this.viewport.height>e){let t=(this.viewport.height-e)/this.viewport.height*this.resolution.height;l.top=t/2,l.left=0,l.bottom=this.resolution.height-t/2,l.right=this.resolution.width}this._contentArea=l}_computeFitContainer(){let t=this.aspectRatio,e=0,i=0,s=this.canvas.parentElement;s.clientWidth/t{this._resizeHandler()}),this._resizeObserver.observe(this.parent)),this.parent.addEventListener("resize",this._resizeHandler)}_setResolutionAndViewportByDisplayMode(t){this.displayMode===V.FillContainer&&(this.resolution={width:t.clientWidth,height:t.clientHeight},this.viewport=this.resolution),this.displayMode===V.FillScreen&&(document.body.style.margin="0px",document.body.style.overflow="hidden",this.resolution={width:t.innerWidth,height:t.innerHeight},this.viewport=this.resolution),this._contentArea=tq.fromDimension(this.resolution.width,this.resolution.height,tN.Zero),this.displayMode===V.FitScreen&&this._computeFit(),this.displayMode===V.FitContainer&&this._computeFitContainer(),this.displayMode===V.FitScreenAndFill&&this._computeFitScreenAndFill(),this.displayMode===V.FitContainerAndFill&&this._computeFitContainerAndFill(),this.displayMode===V.FitScreenAndZoom&&this._computeFitScreenAndZoom(),this.displayMode===V.FitContainerAndZoom&&this._computeFitContainerAndZoom()}}class eL{static create(){return!this._INSTANCE&&(window.AudioContext||window.webkitAudioContext)&&(this._INSTANCE=new AudioContext),this._INSTANCE}}eL._INSTANCE=null;class ez{static unlock(){return new Promise((t,e)=>{if(ez._UNLOCKED||!eL.create())return t(!0);let i=setTimeout(()=>{tW.getInstance().warn("Excalibur was unable to unlock the audio context, audio probably will not play in this browser."),t(!1)},200),s=eL.create();s.resume().then(()=>{let e=s.createBuffer(1,1,22050),r=s.createBufferSource(),n=!1;r.buffer=e,r.connect(s.destination),r.onended=()=>n=!0,r.start(0),setTimeout(()=>{r.playbackState?(r.playbackState===r.PLAYING_STATE||r.playbackState===r.FINISHED_STATE)&&(ez._UNLOCKED=!0):(s.currentTime>0||n)&&(ez._UNLOCKED=!0)},0),clearTimeout(i),t(!0)},()=>{e()})})}static isUnlocked(){return this._UNLOCKED}}ez._UNLOCKED=!1;class eO extends et{constructor(t){var e,i,s,r,n,o,a,l,h,d;super(t0(t,["width","height"])),this.filtering=null,this.lineCap="butt",this.quality=1,this._dirty=!0,this._smoothing=!1,this._color=t6(tH.Black,()=>this.flagDirty()),this._lineWidth=1,this._lineDash=[],this._padding=0,t&&(this.quality=null!==(e=t.quality)&&void 0!==e?e:this.quality,this.color=null!==(i=t.color)&&void 0!==i?i:tH.Black,this.strokeColor=null==t?void 0:t.strokeColor,this.smoothing=null!==(s=t.smoothing)&&void 0!==s?s:this.smoothing,this.lineWidth=null!==(r=t.lineWidth)&&void 0!==r?r:this.lineWidth,this.lineDash=null!==(n=t.lineDash)&&void 0!==n?n:this.lineDash,this.lineCap=null!==(o=t.lineCap)&&void 0!==o?o:this.lineCap,this.padding=null!==(a=t.padding)&&void 0!==a?a:this.padding,this.filtering=null!==(l=t.filtering)&&void 0!==l?l:this.filtering),this._bitmap=document.createElement("canvas");let c=null!==(h=null==t?void 0:t.width)&&void 0!==h?h:this._bitmap.width,u=null!==(d=null==t?void 0:t.height)&&void 0!==d?d:this._bitmap.height;this.width=c,this.height=u;let p=this._bitmap.getContext("2d");if(p)this._ctx=p;else throw Error("Browser does not support 2d canvas drawing, cannot create Raster graphic")}cloneRasterOptions(){return{color:this.color?this.color.clone():null,strokeColor:this.strokeColor?this.strokeColor.clone():null,smoothing:this.smoothing,lineWidth:this.lineWidth,lineDash:this.lineDash,lineCap:this.lineCap,quality:this.quality,padding:this.padding}}get dirty(){return this._dirty}flagDirty(){this._dirty=!0}get width(){return Math.abs(this._getTotalWidth()*this.scale.x)}set width(t){t/=Math.abs(this.scale.x),this._bitmap.width=t,this._originalWidth=t,this.flagDirty()}get height(){return Math.abs(this._getTotalHeight()*this.scale.y)}set height(t){t/=Math.abs(this.scale.y),this._bitmap.height=t,this._originalHeight=t,this.flagDirty()}_getTotalWidth(){var t;return((null!==(t=this._originalWidth)&&void 0!==t?t:this._bitmap.width)+2*this.padding)*1}_getTotalHeight(){var t;return((null!==(t=this._originalHeight)&&void 0!==t?t:this._bitmap.height)+2*this.padding)*1}get localBounds(){return tq.fromDimension(this._getTotalWidth()*this.scale.x,this._getTotalHeight()*this.scale.y,tN.Zero)}get smoothing(){return this._smoothing}set smoothing(t){this._smoothing=t,this.flagDirty()}get color(){return this._color}set color(t){this.flagDirty(),this._color=t6(t,()=>this.flagDirty())}get strokeColor(){return this._strokeColor}set strokeColor(t){this.flagDirty(),this._strokeColor=t6(t,()=>this.flagDirty())}get lineWidth(){return this._lineWidth}set lineWidth(t){this._lineWidth=t,this.flagDirty()}get lineDash(){return this._lineDash}set lineDash(t){this._lineDash=t,this.flagDirty()}get padding(){return this._padding}set padding(t){this._padding=t,this.flagDirty()}rasterize(){this._dirty=!1,this._ctx.clearRect(0,0,this._getTotalWidth(),this._getTotalHeight()),this._ctx.save(),this._applyRasterProperties(this._ctx),this.execute(this._ctx),this._ctx.restore()}_applyRasterProperties(t){var e,i,s;this._bitmap.width=this._getTotalWidth()*this.quality,this._bitmap.height=this._getTotalHeight()*this.quality,this._bitmap.setAttribute("filtering",this.filtering),this._bitmap.setAttribute("forceUpload","true"),t.scale(this.quality,this.quality),t.translate(this.padding,this.padding),t.imageSmoothingEnabled=this.smoothing,t.lineWidth=this.lineWidth,t.setLineDash(null!==(e=this.lineDash)&&void 0!==e?e:t.getLineDash()),t.lineCap=this.lineCap,t.strokeStyle=null===(i=this.strokeColor)||void 0===i?void 0:i.toString(),t.fillStyle=null===(s=this.color)||void 0===s?void 0:s.toString()}_drawImage(t,e,i){this._dirty&&this.rasterize(),t.scale(1/this.quality,1/this.quality),t.drawImage(this._bitmap,e,i)}}class eU extends eO{get ctx(){return this._ctx}constructor(t){super(t),this._options=t}clone(){return new eU({...this._options,...this.cloneGraphicOptions(),...this.cloneRasterOptions()})}execute(t){var e,i;(null===(e=this._options)||void 0===e?void 0:e.draw)&&(null===(i=this._options)||void 0===i||i.draw(t)),this._options.cache||this.flagDirty()}}class eN{}eN.type={any:"",blob:"blob",json:"json",text:"text",document:"document",arraybuffer:"arraybuffer"};class eZ{constructor(){this.states=new Map}get currentState(){return this._currentState}set currentState(t){this._currentState=t}static create(t,e){let i=new eZ;for(let s in i.data=e,t.states)i.states.set(s,{name:s,...t.states[s]});for(let t of i.states.values())for(let e of t.transitions)if("*"!==e&&!i.states.has(e))throw Error(`Invalid state machine, state [${t.name}] has a transition to another state that doesn't exist [${e}]`);return i.currentState=i.startState=i.states.get(t.start),i}in(t){return this.currentState.name===t}go(t,e){var i,s;if(this.currentState.transitions.includes(t)||this.currentState.transitions.includes("*")){let r=this.states.get(t);return(!this.currentState.onExit||!1!==(null===(i=this.currentState)||void 0===i?void 0:i.onExit({to:r.name,data:this.data})))&&(null==r||!r.onEnter||!1!==(null==r?void 0:r.onEnter({from:this.currentState.name,eventData:e,data:this.data})))&&(this.currentState=r,(null===(s=this.currentState)||void 0===s?void 0:s.onState)&&this.currentState.onState(),!0)}return!1}update(t){this.currentState.onUpdate&&this.currentState.onUpdate(this.data,t)}save(t){localStorage.setItem(t,JSON.stringify({currentState:this.currentState.name,data:this.data}))}restore(t){let e=JSON.parse(localStorage.getItem(t));this.currentState=this.states.get(e.currentState),this.data=e.data}}class eH{_createNewBufferSource(){this._instance=this._audioContext.createBufferSource(),this._instance.buffer=this._src,this._instance.loop=this.loop,this._instance.playbackRate.value=this._playbackRate,this._instance.connect(this._volumeNode),this._volumeNode.connect(this._audioContext.destination)}_handleEnd(){this.loop||(this._instance.onended=()=>{this._playingFuture.resolve(!0)})}set loop(t){this._loop=t,this._instance&&(this._instance.loop=t,this.loop||(this._instance.onended=()=>{this._playingFuture.resolve(!0)}))}get loop(){return this._loop}set volume(t){t=tF(t,0,1),this._volume=t,this._stateMachine.in("PLAYING")&&this._volumeNode.gain.setTargetAtTime?this._volumeNode.gain.setTargetAtTime(t,this._audioContext.currentTime,.1):this._volumeNode.gain.value=t}get volume(){return this._volume}get duration(){var t;return null!==(t=this._duration)&&void 0!==t?t:this.getTotalPlaybackDuration()}set duration(t){this._duration=t}constructor(t){this._src=t,this._audioContext=eL.create(),this._volumeNode=this._audioContext.createGain(),this._playingFuture=new tE,this._stateMachine=eZ.create({start:"STOPPED",states:{PLAYING:{onEnter:({data:t})=>{this._createNewBufferSource(),this._handleEnd(),this.loop?this._instance.start(0,t.pausedAt*this._playbackRate):this._instance.start(0,t.pausedAt*this._playbackRate,this.duration),t.startedAt=this._audioContext.currentTime-t.pausedAt,t.pausedAt=0},onState:()=>this._playStarted(),onExit:({to:t})=>{"STOPPED"===t&&this._playingFuture.resolve(!0),this._instance.onended=null,this._instance.disconnect(),this._instance.stop(0),this._instance=null},transitions:["STOPPED","PAUSED","SEEK"]},SEEK:{onEnter:({eventData:t,data:e})=>{e.pausedAt=(null!=t?t:0)/this._playbackRate,e.startedAt=0},transitions:["*"]},STOPPED:{onEnter:({data:t})=>{t.pausedAt=0,t.startedAt=0,this._playingFuture.resolve(!0)},transitions:["PLAYING","PAUSED","SEEK"]},PAUSED:{onEnter:({data:t})=>{t.pausedAt=this._audioContext.currentTime-t.startedAt},transitions:["PLAYING","STOPPED","SEEK"]}}},{startedAt:0,pausedAt:0}),this._volume=1,this._loop=!1,this._playStarted=()=>{},this._playbackRate=1,this._createNewBufferSource()}isPlaying(){return this._stateMachine.in("PLAYING")}isPaused(){return this._stateMachine.in("PAUSED")||this._stateMachine.in("SEEK")}isStopped(){return this._stateMachine.in("STOPPED")}play(t=()=>{}){return this._playStarted=t,this._stateMachine.go("PLAYING"),this._playingFuture.promise}pause(){this._stateMachine.go("PAUSED")}stop(){this._stateMachine.go("STOPPED")}seek(t){this._stateMachine.go("PAUSED"),this._stateMachine.go("SEEK",t)}getTotalPlaybackDuration(){return this._src.duration}getPlaybackPosition(){let{pausedAt:t,startedAt:e}=this._stateMachine.data;return t?t*this._playbackRate:e?(this._audioContext.currentTime-e)*this._playbackRate:0}set playbackRate(t){this._instance.playbackRate.value=this._playbackRate=t}get playbackRate(){return this._instance.playbackRate.value}}(h=W||(W={})).Kill="kill",h.PreKill="prekill",h.PostKill="postkill",h.PreDraw="predraw",h.PostDraw="postdraw",h.PreDebugDraw="predebugdraw",h.PostDebugDraw="postdebugdraw",h.PreUpdate="preupdate",h.PostUpdate="postupdate",h.PreFrame="preframe",h.PostFrame="postframe",h.PreCollision="precollision",h.CollisionStart="collisionstart",h.CollisionEnd="collisionend",h.PostCollision="postcollision",h.Initialize="initialize",h.Activate="activate",h.Deactivate="deactivate",h.ExitViewport="exitviewport",h.EnterViewport="enterviewport",h.ExitTrigger="exit",h.EnterTrigger="enter",h.Connect="connect",h.Disconnect="disconnect",h.Button="button",h.Axis="axis",h.Visible="visible",h.Hidden="hidden",h.Start="start",h.Stop="stop",h.PointerUp="pointerup",h.PointerDown="pointerdown",h.PointerMove="pointermove",h.PointerEnter="pointerenter",h.PointerLeave="pointerleave",h.PointerCancel="pointercancel",h.PointerWheel="pointerwheel",h.Up="up",h.Down="down",h.Move="move",h.Enter="enter",h.Leave="leave",h.Cancel="cancel",h.Wheel="wheel",h.Press="press",h.Release="release",h.Hold="hold",h.PointerDragStart="pointerdragstart",h.PointerDragEnd="pointerdragend",h.PointerDragEnter="pointerdragenter",h.PointerDragLeave="pointerdragleave",h.PointerDragMove="pointerdragmove",h.ActionStart="actionstart",h.ActionComplete="actioncomplete";class eV{constructor(){this._bubbles=!0}get bubbles(){return this._bubbles}set bubbles(t){this._bubbles=t}stopPropagation(){this.bubbles=!1}}class eW extends eV{constructor(t){super(),this.target=t}}class eG extends eV{constructor(t){super(),this.target=t}}class ej extends eV{constructor(t){super(),this.target=t}}class eq extends eV{constructor(t){super(),this.target=t}}class eX extends eV{constructor(t){super(),this.target=t}}class e$ extends eV{constructor(t,e,i){super(),this.ctx=t,this.delta=e,this.target=i}}class eK extends eV{constructor(t,e,i){super(),this.ctx=t,this.delta=e,this.target=i}}class eY extends eV{constructor(t,e,i){super(),this.ctx=t,this.delta=e,this.target=i}}class eQ extends eV{constructor(t,e,i){super(),this.ctx=t,this.delta=e,this.target=i}}class eJ extends eV{constructor(t,e){super(),this.ctx=t,this.target=e}}class e0 extends eV{constructor(t,e){super(),this.ctx=t,this.target=e}}class e1 extends eV{constructor(t,e,i){super(),this.engine=t,this.delta=e,this.target=i}}class e2 extends eV{constructor(t,e,i){super(),this.engine=t,this.delta=e,this.target=i}}class e5 extends eV{constructor(t,e){super(),this.engine=t,this.prevStats=e,this.target=t}}class e4 extends eV{constructor(t,e){super(),this.engine=t,this.stats=e,this.target=t}}class e3 extends eV{constructor(t,e){super(),this.index=t,this.gamepad=e,this.target=e}}class e9 extends eV{constructor(t,e){super(),this.index=t,this.gamepad=e,this.target=e}}class e6 extends eV{constructor(t,e,i){super(),this.button=t,this.value=e,this.target=i}}class e7 extends eV{constructor(t,e,i){super(),this.axis=t,this.value=e,this.target=i}}class e8 extends eV{constructor(t){super(),this.target=t}}class it extends eV{constructor(t){super(),this.target=t}}class ie extends eV{constructor(t,e,i,s,r){super(),this.other=e,this.side=i,this.intersection=s,this.contact=r,this.target=t}}class ii extends eV{constructor(t,e,i,s,r){super(),this.other=e,this.side=i,this.intersection=s,this.contact=r,this.target=t}get actor(){return this.target}set actor(t){this.target=t}}class is{constructor(t,e,i,s){this.target=t,this.other=e,this.side=i,this.contact=s}}class ir{constructor(t,e,i,s){this.target=t,this.other=e,this.side=i,this.lastContact=s}}class io{constructor(t,e,i,s,r){this.target=t,this.other=e,this.side=i,this.intersection=s,this.contact=r}}class ia{constructor(t,e,i,s,r){this.target=t,this.other=e,this.side=i,this.intersection=s,this.contact=r}}class il extends eV{constructor(t,e,i,s){super(),this.other=e,this.side=i,this.contact=s,this.target=t}get actor(){return this.target}set actor(t){this.target=t}}class ih extends eV{constructor(t,e,i,s){super(),this.other=e,this.side=i,this.lastContact=s,this.target=t}get actor(){return this.target}set actor(t){this.target=t}}class id extends eV{constructor(t,e){super(),this.engine=t,this.target=e}}class ic extends eV{constructor(t,e){super(),this.context=t,this.target=e}}class iu extends eV{constructor(t,e){super(),this.context=t,this.target=e}}class ip extends eV{constructor(t){super(),this.target=t}}class ig extends eV{constructor(t){super(),this.target=t}}class i_ extends eV{constructor(t,e){super(),this.target=t,this.actor=e}}class im extends eV{constructor(t,e){super(),this.target=t,this.actor=e}}class iv extends eV{constructor(t,e){super(),this.action=t,this.target=e}}class iy extends eV{constructor(t,e){super(),this.action=t,this.target=e}}class ix extends eV{set bubbles(t){}get bubbles(){return!1}get _path(){return null}set _path(t){}constructor(t,e="MediaEvent"){super(),this.target=t,this._name=e}stopPropagation(){}action(){}propagate(){}layPath(t){}}class iw extends ix{constructor(t,e){super(t,"NativeSoundEvent"),this.track=e}}class ib extends ix{constructor(t,e){super(t,"NativeSoundProcessedEvent"),this._processedData=e,this.data=this._processedData}}let iC={VolumeChange:"volumechange",Processed:"processed",Pause:"pause",Stop:"stop",PlaybackEnd:"playbackend",Resume:"resume",PlaybackStart:"playbackstart"};class iT{set loop(t){for(let e of(this._loop=t,this._tracks))e.loop=this._loop;this.logger.debug("Set loop for all instances of sound",this.path,"to",this._loop)}get loop(){return this._loop}set volume(t){for(let e of(this._volume=t,this._tracks))e.volume=this._volume;this.events.emit("volumechange",new iw(this)),this.logger.debug("Set loop for all instances of sound",this.path,"to",this._volume)}get volume(){return this._volume}get duration(){return this._duration}set duration(t){this._duration=t}get instances(){return this._tracks}get path(){return this._resource.path}set path(t){this._resource.path=t}get bustCache(){return this._resource.bustCache}set bustCache(t){this._resource.bustCache=t}constructor(...t){for(let e of(this.events=new tP,this.logger=tW.getInstance(),this._loop=!1,this._volume=1,this._isStopped=!1,this._tracks=[],this._wasPlayingOnHidden=!1,this._playbackRate=1,this._audioContext=eL.create(),this._resource=new t9("",eN.type.arraybuffer),t))if(function(t){try{let e=new Audio,i=t.match(/.*\.([A-Za-z0-9]+)(?:(?:\?|\#).*)*$/)[1];if(e.canPlayType("audio/"+i))return!0;return!1}catch(t){return tW.getInstance().warn("Cannot determine audio support, assuming no support for the Audio Tag",t),!1}}(e)){this.path=e;break}this.path||(this.logger.warn("This browser does not support any of the audio files specified:",t.join(", ")),this.logger.warn("Attempting to use",t[0]),this.path=t[0])}isLoaded(){return!!this.data}async load(){var t,e;if(this.data)return this.data;let i=await this._resource.load(),s=await this.decodeAudio(i.slice(0));return this._duration=null!==(e=null!==(t=this._duration)&&void 0!==t?t:null==s?void 0:s.duration)&&void 0!==e?e:void 0,this.events.emit("processed",new ib(this,s)),this.data=s}async decodeAudio(t){try{return await this._audioContext.decodeAudioData(t.slice(0))}catch(t){return this.logger.error("Unable to decode this browser may not fully support this format, or the file may be corrupt, if this is an mp3 try removing id3 tags and album art from the file."),await Promise.reject()}}wireEngine(t){t&&(this._engine=t,this._engine.on("hidden",()=>{t.pauseAudioWhenHidden&&this.isPlaying()&&(this._wasPlayingOnHidden=!0,this.pause())}),this._engine.on("visible",()=>{t.pauseAudioWhenHidden&&this._wasPlayingOnHidden&&(this.play(),this._wasPlayingOnHidden=!1)}),this._engine.on("start",()=>{this._isStopped=!1}),this._engine.on("stop",()=>{this.stop(),this._isStopped=!0}))}instanceCount(){return this._tracks.length}isPlaying(){return this._tracks.some(t=>t.isPlaying())}isPaused(){return this._tracks.some(t=>t.isPaused())}isStopped(){return this._tracks.some(t=>t.isStopped())}play(t){return this.isLoaded()?this._isStopped?(this.logger.warn("Cannot start playing. Engine is in a stopped state."),Promise.resolve(!1)):(this.volume=t||this.volume,this.isPaused())?this._resumePlayback():this._startPlayback():(this.logger.warn("Cannot start playing. Resource",this.path,"is not loaded yet"),Promise.resolve(!0))}pause(){if(this.isPlaying()){for(let t of this._tracks)t.pause();this.events.emit("pause",new iw(this)),this.logger.debug("Paused all instances of sound",this.path)}}stop(){for(let t of this._tracks)t.stop();this.events.emit("stop",new iw(this)),this._tracks.length=0,this.logger.debug("Stopped all instances of sound",this.path)}get playbackRate(){return this._playbackRate}set playbackRate(t){this._playbackRate=t,this._tracks.forEach(t=>{t.playbackRate=this._playbackRate})}seek(t,e=0){0===this._tracks.length&&this._getTrackInstance(this.data),this._tracks[e].seek(t)}getTotalPlaybackDuration(){return this.isLoaded()?this.data.duration:(this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`),0)}getPlaybackPosition(t=0){return this._tracks.length?this._tracks[t].getPlaybackPosition():0}getTrackId(t){return this._tracks.indexOf(t)}async _resumePlayback(){if(this.isPaused){let t=[];for(let e of this._tracks)t.push(e.play().then(()=>(this._tracks.splice(this.getTrackId(e),1),!0)));this.events.emit("resume",new iw(this)),this.logger.debug("Resuming paused instances for sound",this.path,this._tracks),await Promise.all(t)}return!0}async _startPlayback(){let t=this._getTrackInstance(this.data),e=await t.play(()=>{this.events.emit("playbackstart",new iw(this,t)),this.logger.debug("Playing new instance for sound",this.path)});this.events.emit("playbackend",new iw(this,t));let i=this.getTrackId(t);return -1!==i&&this._tracks.splice(i,1),e}_getTrackInstance(t){let e=new eH(t);return e.loop=this.loop,e.volume=this.volume,e.duration=this.duration,e.playbackRate=this._playbackRate,this._tracks.push(e),e}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}}let iS={BeforeLoad:"beforeload",AfterLoad:"afterload",UserAction:"useraction",LoadResourceStart:"loadresourcestart",LoadResourceEnd:"loadresourceend"};function iA(t){var e,i;return!!(null==t?void 0:t.prototype)&&!!(null===(i=null===(e=null==t?void 0:t.prototype)||void 0===e?void 0:e.constructor)||void 0===i?void 0:i.name)}class iE{get resources(){return this._resources}constructor(t){var e;this.events=new tP,this.canvas=new eU({filtering:H.Blended,smoothing:!0,cache:!1,draw:this.onDraw.bind(this)}),this._resources=[],this._numLoaded=0,this._totalTimeMs=0,this._loadingFuture=new tE,t&&(null===(e=t.loadables)||void 0===e?void 0:e.length)&&this.addResources(t.loadables)}onInitialize(t){this.engine=t,this.canvas.width=this.engine.screen.canvasWidth,this.canvas.height=this.engine.screen.canvasHeight}async onUserAction(){return await Promise.resolve()}async onBeforeLoad(){}async onAfterLoad(){await tJ(500,this.engine.clock)}addResource(t){this._resources.push(t)}addResources(t){let e=0,i=t.length;for(;e0?tF(this._numLoaded,0,t)/t:1}isLoaded(){return this._numLoaded===this._resources.length}onUpdate(t,e){this._totalTimeMs+=e}onDraw(t){let e=this._totalTimeMs/1e3;t.fillStyle=tH.Black.toRGBA(),t.fillRect(0,0,this.engine.screen.drawWidth,this.engine.screen.drawHeight),t.save(),t.translate(this.engine.screen.center.x,this.engine.screen.center.y);let i=10*e;t.strokeStyle="white",t.lineWidth=10,t.lineCap="round",t.arc(0,0,40,i,i+3*Math.PI/2),t.stroke(),t.fillStyle="white",t.font="16px sans-serif";let s=(100*this.progress).toFixed(0)+"%",r=t.measureText(s),n=Math.abs(r.actualBoundingBoxLeft)+Math.abs(r.actualBoundingBoxRight),o=Math.abs(r.actualBoundingBoxAscent)+Math.abs(r.actualBoundingBoxDescent);t.fillText(s,-n/2,o/2),t.restore()}areResourcesLoaded(){return this._loadingFuture.promise}async load(){for(let t of(await this.onBeforeLoad(),this.events.emit("beforeload"),this.canvas.flagDirty(),await Promise.all(this._resources.map(async t=>{this.events.emit("loadresourcestart",t),await t.load().finally(()=>{this._numLoaded++,this.canvas.flagDirty(),this.events.emit("loadresourceend",t)})})),this._resources))t instanceof iT&&t.wireEngine(this.engine);return this._loadingFuture.resolve(),this.canvas.flagDirty(),await this.onUserAction(),this.events.emit("useraction"),await ez.unlock(),await this.onAfterLoad(),this.events.emit("afterload"),this.data=this._resources}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}}function iP(t,e=tH.Red,i,s,r,n,o=1,a="butt"){t.save(),t.beginPath(),t.lineWidth=o,t.lineCap=a,t.strokeStyle=e.toString(),t.moveTo(i,s),t.lineTo(r,n),t.closePath(),t.stroke(),t.restore()}function iI(t,e=tH.Red,i){t.beginPath(),t.strokeStyle=e.toString(),t.arc(i.x,i.y,5,0,2*Math.PI),t.closePath(),t.stroke()}function ik(t,e,i,s,r=1){let n=e?e.toString():"blue",o=s.scale(r);t.beginPath(),t.strokeStyle=n,t.moveTo(i.x,i.y),t.lineTo(i.x+o.x,i.y+o.y),t.closePath(),t.stroke()}function iD(t,e,i,s,r,n=5,o=tH.White,a=null){let l;if("number"==typeof n)l={tl:n,tr:n,br:n,bl:n};else{let t={tl:0,tr:0,br:0,bl:0};for(let e in t)t.hasOwnProperty(e)&&(l[e]=n[e]||t[e])}t.beginPath(),t.moveTo(e+l.tl,i),t.lineTo(e+s-l.tr,i),t.quadraticCurveTo(e+s,i,e+s,i+l.tr),t.lineTo(e+s,i+r-l.br),t.quadraticCurveTo(e+s,i+r,e+s-l.br,i+r),t.lineTo(e+l.bl,i+r),t.quadraticCurveTo(e,i+r,e,i+r-l.bl),t.lineTo(e,i+l.tl),t.quadraticCurveTo(e,i,e+l.tl,i),t.closePath(),a&&(t.fillStyle=a.toString(),t.fill()),o&&(t.strokeStyle=o.toString(),t.stroke())}function iR(t,e,i,s,r=tH.White,n=null){t.beginPath(),t.arc(e,i,s,0,2*Math.PI),t.closePath(),n&&(t.fillStyle=n.toString(),t.fill()),r&&(t.strokeStyle=r.toString(),t.stroke())}var iF=n(7835);class iB extends iE{get _image(){return this._imageElement||(this._imageElement=new Image,this._imageElement.src=this.logo),this._imageElement}get playButtonRootElement(){return this._playButtonRootElement}get playButtonElement(){return this._playButtonElement}get _playButton(){let t=document.getElementById("excalibur-play-root");return t&&(this._playButtonRootElement=t),this._playButtonRootElement||(this._playButtonRootElement=document.createElement("div"),this._playButtonRootElement.id="excalibur-play-root",this._playButtonRootElement.style.position="absolute",document.body.appendChild(this._playButtonRootElement)),this._styleBlock||(this._styleBlock=document.createElement("style"),this._styleBlock.textContent=this._playButtonStyles,document.head.appendChild(this._styleBlock)),this._playButtonElement||(this._playButtonElement=this.startButtonFactory(),this._playButtonRootElement.appendChild(this._playButtonElement)),this._playButtonElement}constructor(t){let e=Array.isArray(t)?{loadables:t}:t;super(e),this._logger=tW.getInstance(),this._originalOptions={loadables:[]},this.events=new tP,this._playButtonShown=!1,this.logo="data:image/png;base64,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",this.logoWidth=468,this.logoHeight=118,this.loadingBarColor=tH.White,this.backgroundColor="#176BAA",this.suppressPlayButton=!1,this._playButtonStyles=iF.Z.toString(),this.playButtonText="Play game",this.startButtonFactory=()=>{let t=document.getElementById("excalibur-play");return t||(t=document.createElement("button")),t.id="excalibur-play",t.textContent=this.playButtonText,t.style.display="none",t},this._configuredPixelRatio=null,this._originalOptions={...iB._DEFAULT_LOADER_OPTIONS,...e}}onInitialize(t){this.engine=t,this.screen=t.screen,this.canvas.width=this.engine.canvas.width,this.canvas.height=this.engine.canvas.height}async showPlayButton(){var t,e;if(this.suppressPlayButton)this.hidePlayButton(),await tJ(500,null===(t=this.engine)||void 0===t?void 0:t.clock);else{let t=()=>{try{this._positionPlayButton()}catch(t){}};(null===(e=this.engine)||void 0===e?void 0:e.browser)&&this.engine.browser.window.on("resize",t),this._playButtonShown=!0,this._playButton.style.display="block",document.body.addEventListener("keyup",t=>{"Enter"===t.key&&this._playButton.click()}),this._positionPlayButton();let i=new Promise(e=>{let i=i=>{var s;if(i.stopPropagation(),this.hidePlayButton(),(null===(s=this.engine)||void 0===s?void 0:s.browser)&&this.engine.browser.window.off("resize",t),this._originalOptions.fullscreenAfterLoad)try{this._logger.info("requesting fullscreen"),this._originalOptions.fullscreenContainer instanceof HTMLElement?this._originalOptions.fullscreenContainer.requestFullscreen():this.engine.screen.goFullScreen(this._originalOptions.fullscreenContainer)}catch(t){this._logger.error("could not go fullscreen",t)}e()};this._playButton.addEventListener("click",i),this._playButton.addEventListener("touchend",i),this._playButton.addEventListener("pointerup",i)});return await i}}hidePlayButton(){this._playButtonShown=!1,this._playButton.style.display="none"}dispose(){this._playButtonRootElement.parentElement&&(this._playButtonRootElement.removeChild(this._playButtonElement),document.body.removeChild(this._playButtonRootElement),document.head.removeChild(this._styleBlock),this._playButtonRootElement=null,this._playButtonElement=null,this._styleBlock=null)}async onUserAction(){var t;await tJ(200,null===(t=this.engine)||void 0===t?void 0:t.clock),this.canvas.flagDirty(),await this.showPlayButton()}async onBeforeLoad(){var t;this._configuredPixelRatio=this.screen.pixelRatioOverride,this.screen.pushResolutionAndViewport(),this.screen.resolution=this.screen.viewport,this.screen.pixelRatioOverride=1,this.screen.applyResolutionAndViewport(),this.canvas.width=this.engine.canvas.width,this.canvas.height=this.engine.canvas.height,await (null===(t=this._image)||void 0===t?void 0:t.decode())}async onAfterLoad(){this.screen.pixelRatioOverride=this._configuredPixelRatio,this.screen.popResolutionAndViewport(),this.screen.applyResolutionAndViewport(),this.dispose()}_positionPlayButton(){if(this.engine){let t=this.engine.screen.viewport.height,e=this.engine.screen.viewport.width;if(this._playButtonRootElement){let i=this.engine.canvas.offsetLeft,s=this.engine.canvas.offsetTop,r=this._playButton.clientWidth,n=this._playButton.clientHeight;this.playButtonPosition?(this._playButtonRootElement.style.left=`${this.playButtonPosition.x}px`,this._playButtonRootElement.style.top=`${this.playButtonPosition.y}px`):(this._playButtonRootElement.style.left=`${i+e/2-r/2}px`,this._playButtonRootElement.style.top=`${s+t/2-n/2+100}px`)}}}onDraw(t){let e=this.engine.canvasHeight/this.engine.pixelRatio,i=this.engine.canvasWidth/this.engine.pixelRatio;this._positionPlayButton(),t.fillStyle=this.backgroundColor,t.fillRect(0,0,i,e);let s=e/2,r=Math.min(this.logoWidth,.75*i),n=i/2-r/2;this.logoPosition&&(n=this.logoPosition.x,s=this.logoPosition.y);let o=Math.floor(this.logoHeight/this.logoWidth*r),a=this.engine.getAntialiasing();if(this.engine.setAntialiasing(!0),this.logoPosition?t.drawImage(this._image,0,0,this.logoWidth,this.logoHeight,n,s,r,o):t.drawImage(this._image,0,0,this.logoWidth,this.logoHeight,n,s-o-20,r,o),!this.suppressPlayButton&&this._playButtonShown){this.engine.setAntialiasing(a);return}let l=n,h=s;this.loadingBarPosition&&(l=this.loadingBarPosition.x,h=this.loadingBarPosition.y),t.lineWidth=2,iD(t,l,h,r,20,10,this.loadingBarColor);let d=r*this.progress-10;iD(t,l+5,h+5,d>10?d:10,10,5,null,this.loadingBarColor),this.engine.setAntialiasing(a)}}iB._DEFAULT_LOADER_OPTIONS={loadables:[],fullscreenAfterLoad:!1,fullscreenContainer:void 0};let iM={webgl:"WebGL",webaudio:"WebAudio",gamepadapi:"Gamepad API"};class iL{constructor(){this._features=null,this.failedTests=[],this._criticalTests={canvasSupport:function(){let t=document.createElement("canvas");return!!(t.getContext&&t.getContext("2d"))},arrayBufferSupport:function(){let t=new XMLHttpRequest;t.open("GET","/");try{t.responseType="arraybuffer"}catch(t){return!1}return"arraybuffer"===t.responseType},dataUrlSupport:function(){return 0===document.createElement("canvas").toDataURL("image/png").indexOf("data:image/png")},objectUrlSupport:function(){return"URL"in window&&"revokeObjectURL"in URL&&"createObjectURL"in URL},rgbaSupport:function(){let t=document.createElement("a").style;return t.cssText="background-color:rgba(150,255,150,.5)",(""+t.backgroundColor).indexOf("rgba")>-1}},this._warningTest={webAudioSupport:function(){return!!(window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext)},webglSupport:function(){let t=document.createElement("canvas");return!!(t.getContext&&t.getContext("webgl"))}},this._features=this._loadBrowserFeatures()}getBrowserFeatures(){return null===this._features&&(this._features=this._loadBrowserFeatures()),this._features}logBrowserFeatures(){let t="%cSUPPORTED BROWSER FEATURES\n==========================%c\n",e=["font-weight: bold; color: navy","font-weight: normal; color: inherit"],i=this.getBrowserFeatures();for(let s of Object.keys(iM))i[s]?(t+="(%c✓%c)",e.push("font-weight: bold; color: green")):(t+="(%c✗%c)",e.push("font-weight: bold; color: red")),e.push("font-weight: normal; color: inherit"),t+=" "+iM[s]+"\n";e.unshift(t),console.log.apply(console,e)}_loadBrowserFeatures(){return{canvas:this._criticalTests.canvasSupport(),arraybuffer:this._criticalTests.arrayBufferSupport(),dataurl:this._criticalTests.dataUrlSupport(),objecturl:this._criticalTests.objectUrlSupport(),rgba:this._criticalTests.rgbaSupport(),webaudio:this._warningTest.webAudioSupport(),webgl:this._warningTest.webglSupport(),gamepadapi:!!navigator.getGamepads}}test(){let t=!1;for(let e in this._criticalTests)this._criticalTests[e].call(this)||(this.failedTests.push(e),tW.getInstance().error("Critical browser feature missing, Excalibur requires:",e),t=!0);if(t)return!1;for(let t in this._warningTest)this._warningTest[t]()||tW.getInstance().warn("Warning browser feature missing, Excalibur will have reduced performance:",t);return!0}}(d=G||(G={})).PreventCollision="PreventCollision",d.Passive="Passive",d.Active="Active",d.Fixed="Fixed",(c=j||(j={})).World="world",c.Screen="screen";class iz extends tN{constructor(t){super(0,0),this._getX=t.getX,this._getY=t.getY,this._setX=t.setX,this._setY=t.setY}get x(){return this._x=this._getX()}set x(t){this._setX(t),this._x=t}get y(){return this._y=this._getY()}set y(t){this._setY(t),this._y=t}}class iO extends tN{constructor(t,e){super(t.x,t.y),this.original=t,this.change=e}get x(){return this._x=this.original.x}set x(t){this.change(t,this._y),this._x=this.original.x=t}get y(){return this._y=this.original.y}set y(t){this.change(this._x,t),this._y=this.original.y=t}}class iU{constructor(){this._parent=null,this._children=[],this._pos=tZ(0,0),this._rotation=0,this._scale=tZ(1,1),this._isDirty=!1,this._isInverseDirty=!1,this._matrix=t2.identity(),this._inverse=t2.identity()}get parent(){return this._parent}set parent(t){if(this._parent){let t=this._parent._children.indexOf(this);t>-1&&this._parent._children.splice(t,1)}this._parent=t,this._parent&&this._parent._children.push(this),this.flagDirty()}get children(){return this._children}set pos(t){t.equals(this._pos)||(this._pos.x=t.x,this._pos.y=t.y,this.flagDirty())}get pos(){return new iO(this._pos,(t,e)=>{(t!==this._pos.x||e!==this._pos.y)&&this.flagDirty()})}set globalPos(t){let e=t.clone();this.parent&&(e=this.parent.inverse.multiply(t)),e.equals(this._pos)||(this._pos=e,this.flagDirty())}get globalPos(){return new iz({getX:()=>this.matrix.data[4],getY:()=>this.matrix.data[5],setX:t=>{if(this.parent){let{x:e}=this.parent.inverse.multiply(tZ(t,this.pos.y));this.pos.x=e}else this.pos.x=t;t!==this.matrix.data[4]&&this.flagDirty()},setY:t=>{if(this.parent){let{y:e}=this.parent.inverse.multiply(tZ(this.pos.x,t));this.pos.y=e}else this.pos.y=t;t!==this.matrix.data[5]&&this.flagDirty()}})}set rotation(t){let e=tB(t);e!==this._rotation&&this.flagDirty(),this._rotation=e}get rotation(){return this._rotation}set globalRotation(t){let e=0;this.parent&&(e=this.parent.globalRotation);let i=tB(t+e);i!==this._rotation&&this.flagDirty(),this._rotation=i}get globalRotation(){return this.parent?this.matrix.getRotation():this.rotation}set scale(t){t.equals(this._scale)||(this._scale.x=t.x,this._scale.y=t.y,this.flagDirty())}get scale(){return new iO(this._scale,(t,e)=>{(t!==this._scale.x||e!==this._scale.y)&&this.flagDirty()})}set globalScale(t){let e=tZ(1,1);this.parent&&(e=this.parent.globalScale),this.scale=t.scale(tZ(1/e.x,1/e.y))}get globalScale(){return new iz({getX:()=>this.parent?this.matrix.getScaleX():this.scale.x,getY:()=>this.parent?this.matrix.getScaleY():this.scale.y,setX:t=>{if(this.parent){let e=this.parent.globalScale.x;this.scale.x=t/e}else this.scale.x=t},setY:t=>{if(this.parent){let e=this.parent.globalScale.y;this.scale.y=t/e}else this.scale.y=t}})}get matrix(){return this._isDirty&&(null===this.parent?this._matrix=this._calculateMatrix():this._matrix=this.parent.matrix.multiply(this._calculateMatrix()),this._isDirty=!1),this._matrix}get inverse(){return this._isInverseDirty&&(this._inverse=this.matrix.inverse(),this._isInverseDirty=!1),this._inverse}_calculateMatrix(){return t2.identity().translate(this.pos.x,this.pos.y).rotate(this.rotation).scale(this.scale.x,this.scale.y)}flagDirty(){this._isDirty=!0,this._isInverseDirty=!0;for(let t=0;t{let e=t.get(iV);e&&(e._transform.parent=this._transform,e._parentComponent=this)},this.zIndexChanged$=new iH,this._z=0,this._coordPlane=j.World}get(){return this._transform}onAdd(t){for(let e of t.children)this._addChildTransform(e);t.childrenAdded$.subscribe(t=>this._addChildTransform(t)),t.childrenRemoved$.subscribe(t=>{let e=t.get(iV);e&&(e._transform.parent=null,e._parentComponent=null)})}onRemove(t){this._transform.parent=null,this._parentComponent=null}get z(){return this._z}set z(t){let e=this._z;this._z=t,e!==t&&this.zIndexChanged$.notifyAll(t)}get coordPlane(){return this._parentComponent?this._parentComponent.coordPlane:this._coordPlane}set coordPlane(t){var e;this._parentComponent?this._logger.warn(`Cannot set coordinate plane on child entity ${null===(e=this.owner)||void 0===e?void 0:e.name}, children inherit their coordinate plane from their parents.`):this._coordPlane=t}get pos(){return this._transform.pos}set pos(t){this._transform.pos=t}get globalPos(){return this._transform.globalPos}set globalPos(t){this._transform.globalPos=t}get rotation(){return this._transform.rotation}set rotation(t){this._transform.rotation=t}get globalRotation(){return this._transform.globalRotation}set globalRotation(t){this._transform.globalRotation=t}get scale(){return this._transform.scale}set scale(t){this._transform.scale=t}get globalScale(){return this._transform.globalScale}set globalScale(t){this._transform.globalScale=t}applyInverse(t){return this._transform.applyInverse(t)}apply(t){return this._transform.apply(t)}clone(){let t=new iV;return t._transform=this._transform.clone(),t._z=this._z,t}}class iW extends iZ{constructor(){super(...arguments),this.vel=tN.Zero,this.acc=tN.Zero,this.scaleFactor=tN.Zero,this.angularVelocity=0,this.torque=0,this.inertia=1}}class iG{static create(t,e){if(this._CURRENT_GROUP>this._MAX_GROUPS)throw Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);if(this._GROUPS.get(t)){let i=this._GROUPS.get(t);if(i.mask===e)return i;throw Error(`Collision group ${t} already exists with a different mask!`)}let i=new ij(t,this._CURRENT_BIT,void 0!==e?e:~this._CURRENT_BIT);return this._CURRENT_BIT=this._CURRENT_BIT<<1|0,this._CURRENT_GROUP++,this._GROUPS.set(t,i),i}static get groups(){return Array.from(this._GROUPS.values())}static groupByName(t){return this._GROUPS.get(t)}static reset(){this._GROUPS=new Map,this._CURRENT_BIT=this._STARTING_BIT,this._CURRENT_GROUP=1}}iG._STARTING_BIT=1,iG._MAX_GROUPS=32,iG._CURRENT_GROUP=1,iG._CURRENT_BIT=iG._STARTING_BIT,iG._GROUPS=new Map;class ij{constructor(t,e,i){this._name=t,this._category=e,this._mask=i}get name(){return this._name}get category(){return this._category}get mask(){return this._mask}canCollide(t){let e=this.category&t.mask,i=this.mask&t.category;return 0!==e&&0!==i}invert(){let t=iG.create("~("+this.name+")",0|~this.mask);return t._category=~this.category,t}static combine(t){let e=t.map(t=>t.name).join("+"),i=t.reduce((t,e)=>e.category|t,0);return iG.create(e,~i)}static collidesWith(t){let e=`collidesWith(${t.map(t=>t.name).join("+")})`,i=t.reduce((t,e)=>e.category|t,0);return iG.create(e,i)}toString(){return` +`;class eA{constructor(t){this._logger=tW.getInstance(),this._color=tH.Transparent,this._initialized=!1,this._images=new Map,this._textures=new Map;let{color:e,name:i,vertexSource:s,fragmentSource:r,graphicsContext:n,images:o}=t;if(this._name=null!=i?i:"anonymous material",this._vertexSource=null!=s?s:eS,this._fragmentSource=r,this._color=null!=e?e:this._color,!n)throw Error(`Material ${i} must be provided an excalibur webgl graphics context`);if(n instanceof ek?(this._graphicsContext=n,this._initialize(n)):this._logger.warn(`Material ${i} was created in 2D Canvas mode, currently only WebGL is supported`),o)for(let t in o)this.addImageSource(t,o[t])}_initialize(t){if(this._initialized)return;let e=t.__gl;this._maxTextureSlots=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS)-2,this._shader=t.createShader({vertexSource:this._vertexSource,fragmentSource:this._fragmentSource}),this._shader.compile(),this._initialized=!0}get name(){var t;return null!==(t=this._name)&&void 0!==t?t:"anonymous material"}get isUsingScreenTexture(){return this._fragmentSource.includes("u_screen_texture")}update(t){this._shader&&(this._shader.use(),t(this._shader))}getShader(){return this._shader}addImageSource(t,e){this._images.size4096||t.height>4096)&&(e=!1),e}constructor(t){this._logger=tW.getInstance(),this._renderers=new Map,this._isDrawLifecycle=!1,this.useDrawSorting=!0,this._drawCallPool=new eC(()=>new eT,t=>(t.priority=0,t.z=0,t.renderer=void 0,t.args=void 0,t),4e3),this._drawCalls=[],this._postProcessTargets=[],this._postprocessors=[],this._transform=new t5,this._state=new t4,this.snapToPixel=!1,this.smoothing=!1,this.pixelArtSampler=!1,this.uvPadding=.01,this.backgroundColor=tH.ExcaliburBlue,this.multiSampleAntialiasing=!0,this.transparency=!0,this._disposed=!1,this.debug=new eI(this),this._totalPostProcessorTime=0;let{canvasElement:e,context:i,enableTransparency:s,antialiasing:r,uvPadding:n,multiSampleAntialiasing:o,pixelArtSampler:a,powerPreference:l,snapToPixel:h,backgroundColor:d,useDrawSorting:c}=t;if(this.__gl=null!=i?i:e.getContext("webgl2",{antialias:null!=r?r:this.smoothing,premultipliedAlpha:!1,alpha:null!=s?s:this.transparency,depth:!1,powerPreference:null!=l?l:"high-performance"}),!this.__gl)throw Error("Failed to retrieve webgl context from browser");this.textureLoader=new ei(this.__gl),this.snapToPixel=null!=h?h:this.snapToPixel,this.smoothing=null!=r?r:this.smoothing,this.transparency=null!=s?s:this.transparency,this.pixelArtSampler=null!=a?a:this.pixelArtSampler,this.uvPadding=null!=n?n:this.uvPadding,this.multiSampleAntialiasing="boolean"==typeof o?o:this.multiSampleAntialiasing,this.samples="object"==typeof o?o.samples:void 0,this.backgroundColor=null!=d?d:this.backgroundColor,this.useDrawSorting=null!=c?c:this.useDrawSorting,this._drawCallPool.disableWarnings=!0,this._drawCallPool.preallocate(),this._init()}dispose(){if(!this._disposed){for(let t of(this._disposed=!0,this.textureLoader.dispose(),this._renderers.values()))t.dispose();this._renderers.clear(),this._drawCallPool.dispose(),this._drawCalls.length=0,this.__gl=null}}_init(){let t=this.__gl;this._ortho=t1.ortho(0,t.canvas.width,t.canvas.height,0,400,-400),t.viewport(0,0,t.canvas.width,t.canvas.height),t.clearColor(this.backgroundColor.r/255,this.backgroundColor.g/255,this.backgroundColor.b/255,this.backgroundColor.a),t.clear(t.COLOR_BUFFER_BIT),t.enable(t.BLEND),t.blendEquation(t.FUNC_ADD),t.blendFunc(t.ONE,t.ONE_MINUS_SRC_ALPHA),t.blendEquationSeparate(t.FUNC_ADD,t.FUNC_ADD),t.blendFuncSeparate(t.ONE,t.ONE_MINUS_SRC_ALPHA,t.ONE,t.ONE_MINUS_SRC_ALPHA),this.register(new ex({uvPadding:this.uvPadding,pixelArtSampler:this.pixelArtSampler})),this.register(new eE),this.register(new ew),this.register(new eb),this.register(new em),this.register(new ef),this.materialScreenTexture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.materialScreenTexture),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.width,this.height,0,t.RGBA,t.UNSIGNED_BYTE,null),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.REPEAT),t.bindTexture(t.TEXTURE_2D,null),this._screenRenderer=new ev(t),this._renderTarget=new el({gl:t,transparency:this.transparency,width:t.canvas.width,height:t.canvas.height}),this._postProcessTargets=[new el({gl:t,transparency:this.transparency,width:t.canvas.width,height:t.canvas.height}),new el({gl:t,transparency:this.transparency,width:t.canvas.width,height:t.canvas.height})],this._msaaTarget=new el({gl:t,transparency:this.transparency,width:t.canvas.width,height:t.canvas.height,antialias:this.multiSampleAntialiasing,samples:this.samples})}register(t){this._renderers.set(t.type,t),t.initialize(this.__gl,this)}get(t){return this._renderers.get(t)}_isCurrentRenderer(t){return!this._currentRenderer||this._currentRenderer===t}beginDrawLifecycle(){this._isDrawLifecycle=!0}endDrawLifecycle(){this._isDrawLifecycle=!1}draw(t,...e){this._isDrawLifecycle||this._logger.warnOnce(`Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors. +If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);let i=this._renderers.get(t);if(i){if(this.useDrawSorting){let s=this._drawCallPool.get();s.z=this._state.current.z,s.priority=i.priority,s.renderer=t,this.getTransform().clone(s.transform),s.state.z=this._state.current.z,s.state.opacity=this._state.current.opacity,s.state.tint=this._state.current.tint,s.state.material=this._state.current.material,s.args=e,this._drawCalls.push(s)}else this._currentRenderer||(this._currentRenderer=i),this._isCurrentRenderer(i)||this._currentRenderer.flush(),i.draw(...e),this._currentRenderer=i}else throw Error(`No renderer with name ${t} has been registered`)}resetTransform(){this._transform.current=t2.identity()}updateViewport(t){let e=this.__gl;this._ortho=this._ortho=t1.ortho(0,t.width,t.height,0,400,-400),this._renderTarget.setResolution(e.canvas.width,e.canvas.height),this._msaaTarget.setResolution(e.canvas.width,e.canvas.height),this._postProcessTargets[0].setResolution(e.canvas.width,e.canvas.height),this._postProcessTargets[1].setResolution(e.canvas.width,e.canvas.height)}drawImage(t,e,i,s,r,n,o,a,l){if(0!==s&&0!==r&&0!==a&&0!==l&&0!==t.width&&0!==t.height){if(!t){tW.getInstance().warn("Cannot draw a null or undefined image"),console.trace&&console.trace();return}this._state.current.material?this.draw("ex.material",t,e,i,s,r,n,o,a,l):this.draw("ex.image",t,e,i,s,r,n,o,a,l)}}drawLine(t,e,i,s=1){this.draw("ex.rectangle",t,e,i,s)}drawRectangle(t,e,i,s,r,n){this.draw("ex.rectangle",t,e,i,s,r,n)}drawCircle(t,e,i,s,r){this.draw("ex.circle",t,e,i,s,r)}save(){this._transform.save(),this._state.save()}restore(){this._transform.restore(),this._state.restore()}translate(t,e){this._transform.translate(this.snapToPixel?~~(t+eP):t,this.snapToPixel?~~(e+eP):e)}rotate(t){this._transform.rotate(t)}scale(t,e){this._transform.scale(t,e)}transform(t){this._transform.current=t}getTransform(){return this._transform.current}multiply(t){this._transform.current.multiply(t,this._transform.current)}addPostProcessor(t){this._postprocessors.push(t),t.initialize(this.__gl)}removePostProcessor(t){let e=this._postprocessors.indexOf(t);-1!==e&&this._postprocessors.splice(e,1)}clearPostProcessors(){this._postprocessors.length=0}updatePostProcessors(t){for(let e of this._postprocessors){let i=e.getShader();i.use();let s=i.getUniforms();this._totalPostProcessorTime+=t,s.find(t=>"u_time_ms"===t.name)&&i.setUniformFloat("u_time_ms",this._totalPostProcessorTime),s.find(t=>"u_elapsed_ms"===t.name)&&i.setUniformFloat("u_elapsed_ms",t),s.find(t=>"u_resolution"===t.name)&&i.setUniformFloatVector("u_resolution",tZ(this.width,this.height)),e.onUpdate&&e.onUpdate(t)}}set material(t){this._state.current.material=t}get material(){return this._state.current.material}createMaterial(t){return new eA({...t,graphicsContext:this})}createShader(t){let e=this.__gl,{vertexSource:i,fragmentSource:s}=t,r=new eu({gl:e,vertexSource:i,fragmentSource:s});return r.compile(),r}clear(){let t=this.__gl;(this.multiSampleAntialiasing?this._msaaTarget:this._renderTarget).use(),t.clearColor(this.backgroundColor.r/255,this.backgroundColor.g/255,this.backgroundColor.b/255,this.backgroundColor.a),t.clear(t.COLOR_BUFFER_BIT)}flush(){let t=this.multiSampleAntialiasing?this._msaaTarget:this._renderTarget;if(t.use(),this.useDrawSorting){let e=new Map;for(let[t]of this._renderers){let i=this._drawCalls.findIndex(e=>e.renderer===t);e.set(t,i)}this._drawCalls.sort((t,i)=>{let s=t.z-i.z,r=e.get(t.renderer)-e.get(i.renderer),n=t.priority-i.priority;return 0===s?0===n?r:n:s});let i=this._transform.current,s=this._state.current;if(this._drawCalls.length){let e=this._drawCalls[0].renderer,i=this._renderers.get(e);for(let s=0;s0&&t.toRenderSource().use();for(let e=0;evoid 0!==t).map(t=>"number"==typeof t&&this.snapToPixel?~~t:t);this.__ctx.drawImage.apply(this.__ctx,h),e_.DrawCallCount++,e_.DrawnImagesCount=1}drawLine(t,e,i,s=1){this.__ctx.save(),this.__ctx.beginPath(),this.__ctx.strokeStyle=i.toString(),this.__ctx.moveTo(this.snapToPixel?~~(t.x+1e-4):t.x,this.snapToPixel?~~(t.y+1e-4):t.y),this.__ctx.lineTo(this.snapToPixel?~~(e.x+1e-4):e.x,this.snapToPixel?~~(e.y+1e-4):e.y),this.__ctx.lineWidth=s,this.__ctx.stroke(),this.__ctx.closePath(),this.__ctx.restore()}drawRectangle(t,e,i,s){this.__ctx.save(),this.__ctx.fillStyle=s.toString(),this.__ctx.fillRect(this.snapToPixel?~~(t.x+1e-4):t.x,this.snapToPixel?~~(t.y+1e-4):t.y,this.snapToPixel?~~(e+1e-4):e,this.snapToPixel?~~(i+1e-4):i),this.__ctx.restore()}drawCircle(t,e,i,s,r){this.__ctx.save(),this.__ctx.beginPath(),s&&(this.__ctx.strokeStyle=s.toString()),r&&(this.__ctx.lineWidth=r),this.__ctx.fillStyle=i.toString(),this.__ctx.arc(this.snapToPixel?~~(t.x+1e-4):t.x,this.snapToPixel?~~(t.y+1e-4):t.y,e,0,2*Math.PI),this.__ctx.fill(),s&&this.__ctx.stroke(),this.__ctx.closePath(),this.__ctx.restore()}save(){this.__ctx.save(),this._state.save()}restore(){this.__ctx.restore(),this._state.restore()}translate(t,e){this.__ctx.translate(this.snapToPixel?~~(t+1e-4):t,this.snapToPixel?~~(e+1e-4):e)}rotate(t){this.__ctx.rotate(t)}scale(t,e){this.__ctx.scale(t,e)}getTransform(){throw Error("Not implemented")}multiply(t){this.__ctx.setTransform(this.__ctx.getTransform().multiply(t.toDOMMatrix()))}addPostProcessor(t){}removePostProcessor(t){}clearPostProcessors(){}updatePostProcessors(t){}beginDrawLifecycle(){}endDrawLifecycle(){}set material(t){this._state.current.material=t}get material(){return this._state.current.material}createMaterial(t){return null}clear(){this.__ctx.clearRect(0,0,this.width,this.height),this.__ctx.fillStyle=this.backgroundColor.toString(),this.__ctx.fillRect(0,0,this.width,this.height),e_.clear()}flush(){}dispose(){this.__ctx=null}}(l=V||(V={})).Fixed="Fixed",l.FitContainerAndFill="FitContainerAndFill",l.FitScreenAndFill="FitScreenAndFill",l.FitContainerAndZoom="FitContainerAndZoom",l.FitScreenAndZoom="FitScreenAndZoom",l.FitScreen="FitScreen",l.FillScreen="FillScreen",l.FitContainer="FitContainer",l.FillContainer="FillContainer";class eF{static get SVGA(){return{width:800,height:600}}static get Standard(){return{width:1920,height:1080}}static get Atari2600(){return{width:160,height:192}}static get GameBoy(){return{width:160,height:144}}static get GameBoyAdvance(){return{width:240,height:160}}static get NintendoDS(){return{width:256,height:192}}static get NES(){return{width:256,height:224}}static get SNES(){return{width:256,height:244}}}let eB={ScreenResize:"resize",PixelRatioChange:"pixelratio",FullScreenChange:"fullscreen"};class eL{constructor(t){var e,i,s,r;this.events=new tP,this._antialiasing=!0,this._canvasImageRendering="auto",this._resolutionStack=[],this._viewportStack=[],this._pixelRatioOverride=null,this._isFullScreen=!1,this._isDisposed=!1,this._logger=tW.getInstance(),this._fullscreenChangeHandler=()=>{this._isDisposed||(this._isFullScreen=!this._isFullScreen,this._logger.debug("Fullscreen Change",this._isFullScreen),this.events.emit("fullscreen",{fullscreen:this.isFullScreen}))},this._pixelRatioChangeHandler=()=>{this._isDisposed||(this._logger.debug("Pixel Ratio Change",window.devicePixelRatio),this._listenForPixelRatio(),this._devicePixelRatio=this._calculateDevicePixelRatio(),this.applyResolutionAndViewport(),this.events.emit("pixelratio",{pixelRatio:this.pixelRatio}))},this._resizeHandler=()=>{if(this._isDisposed)return;let t=this.parent;this._logger.debug("View port resized"),this._setResolutionAndViewportByDisplayMode(t),this.applyResolutionAndViewport(),this.events.emit("resize",{resolution:this.resolution,viewport:this.viewport})},this._devicePixelRatio=this._calculateDevicePixelRatio(),this._contentArea=new tq,this._unsafeArea=new tq,this.viewport=t.viewport,this.resolution=null!==(e=t.resolution)&&void 0!==e?e:{...this.viewport},this._contentResolution=this.resolution,this._displayMode=null!==(i=t.displayMode)&&void 0!==i?i:V.Fixed,this._canvas=t.canvas,this.graphicsContext=t.context,this._antialiasing=null!==(s=t.antialiasing)&&void 0!==s?s:this._antialiasing,this._canvasImageRendering=null!==(r=t.canvasImageRendering)&&void 0!==r?r:this._canvasImageRendering,this._browser=t.browser,this._pixelRatioOverride=t.pixelRatio,this._applyDisplayMode(),this._listenForPixelRatio(),this._canvas.addEventListener("fullscreenchange",this._fullscreenChangeHandler),this.applyResolutionAndViewport()}_listenForPixelRatio(){this._mediaQueryList&&!this._mediaQueryList.addEventListener&&this._mediaQueryList.removeListener(this._pixelRatioChangeHandler),this._mediaQueryList=this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),this._mediaQueryList.addEventListener?this._mediaQueryList.addEventListener("change",this._pixelRatioChangeHandler,{once:!0}):this._mediaQueryList.addListener(this._pixelRatioChangeHandler)}dispose(){this._isDisposed||(this._isDisposed=!0,this.events.clear(),this._browser.window.off("resize",this._resizeHandler),this._browser.window.clear(),this._resizeObserver&&this._resizeObserver.disconnect(),this.parent.removeEventListener("resize",this._resizeHandler),this._mediaQueryList.removeEventListener?this._mediaQueryList.removeEventListener("change",this._pixelRatioChangeHandler):this._mediaQueryList.removeListener(this._pixelRatioChangeHandler),this._canvas.removeEventListener("fullscreenchange",this._fullscreenChangeHandler),this._canvas=null)}_calculateDevicePixelRatio(){return window.devicePixelRatio<1?1:window.devicePixelRatio||1}get pixelRatio(){return this._pixelRatioOverride?this._pixelRatioOverride:this._devicePixelRatio}get pixelRatioOverride(){return this._pixelRatioOverride}set pixelRatioOverride(t){this._pixelRatioOverride=t}get isHiDpi(){return 1!==this.pixelRatio}get displayMode(){return this._displayMode}get canvas(){return this._canvas}get parent(){switch(this.displayMode){case V.FillContainer:case V.FitContainer:case V.FitContainerAndFill:case V.FitContainerAndZoom:return this.canvas.parentElement||document.body;default:return window}}get resolution(){return this._resolution}set resolution(t){this._resolution=t}get viewport(){return this._viewport?this._viewport:this._resolution}set viewport(t){this._viewport=t}get aspectRatio(){return this._resolution.width/this._resolution.height}get scaledWidth(){return this._resolution.width*this.pixelRatio}get scaledHeight(){return this._resolution.height*this.pixelRatio}setCurrentCamera(t){this._camera=t}pushResolutionAndViewport(){this._resolutionStack.push(this.resolution),this._viewportStack.push(this.viewport),this.resolution={...this.resolution},this.viewport={...this.viewport}}peekViewport(){return this._viewportStack[this._viewportStack.length-1]}peekResolution(){return this._resolutionStack[this._resolutionStack.length-1]}popResolutionAndViewport(){this._resolutionStack.length&&this._viewportStack.length&&(this.resolution=this._resolutionStack.pop(),this.viewport=this._viewportStack.pop())}applyResolutionAndViewport(){this._canvas.width=this.scaledWidth,this._canvas.height=this.scaledHeight,this.graphicsContext instanceof ek&&!this.graphicsContext.checkIfResolutionSupported({width:this.scaledWidth,height:this.scaledHeight})&&this._logger.warnOnce(`The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio}) are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly. Try reducing the resolution or disabling Hi DPI scaling to avoid this (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).`),"auto"===this._canvasImageRendering?this._canvas.style.imageRendering="auto":(this._canvas.style.imageRendering="pixelated",""===this._canvas.style.imageRendering&&(this._canvas.style.imageRendering="crisp-edges")),this._canvas.style.width=this.viewport.width+"px",this._canvas.style.height=this.viewport.height+"px",this.graphicsContext.updateViewport(this.resolution),this.graphicsContext.resetTransform(),this.graphicsContext.smoothing=this._antialiasing,this.graphicsContext instanceof eR&&this.graphicsContext.scale(this.pixelRatio,this.pixelRatio)}get antialiasing(){return this._antialiasing}set antialiasing(t){this._antialiasing=t,this.graphicsContext.smoothing=this._antialiasing}get isFullScreen(){return this._isFullScreen}goFullScreen(t){if(t){let e=document.getElementById(t);if(e)return e.getAttribute("ex-fullscreen-listener")||(e.setAttribute("ex-fullscreen-listener","true"),e.addEventListener("fullscreenchange",this._fullscreenChangeHandler)),e.requestFullscreen()}return this._canvas.requestFullscreen()}exitFullScreen(){return document.exitFullscreen()}pageToScreenCoordinates(t){let e=t.x,i=t.y;if(this._isFullScreen||(e-=tX(this._canvas).x,i-=tX(this._canvas).y),this._isFullScreen){if(window.innerWidth/this.aspectRatiot?this.canvas.style.left=-(o-t)/2+"px":this.canvas.style.left="",a>e?this.canvas.style.top=-(a-e)/2+"px":this.canvas.style.top="",this.viewport={width:o,height:a};let l=tq.fromDimension(this.viewport.width,this.viewport.height,tN.Zero);if(this.viewport.width>t){let e=(this.viewport.width-t)/this.viewport.width*this.resolution.width;l.top=0,l.left=e/2,l.right=this.resolution.width-e/2,l.bottom=this.resolution.height}if(this.viewport.height>e){let t=(this.viewport.height-e)/this.viewport.height*this.resolution.height;l.top=t/2,l.left=0,l.bottom=this.resolution.height-t/2,l.right=this.resolution.width}this._contentArea=l}_computeFitContainer(){let t=this.aspectRatio,e=0,i=0,s=this.canvas.parentElement;s.clientWidth/t{this._resizeHandler()}),this._resizeObserver.observe(this.parent)),this.parent.addEventListener("resize",this._resizeHandler)}_setResolutionAndViewportByDisplayMode(t){this.displayMode===V.FillContainer&&(this.resolution={width:t.clientWidth,height:t.clientHeight},this.viewport=this.resolution),this.displayMode===V.FillScreen&&(document.body.style.margin="0px",document.body.style.overflow="hidden",this.resolution={width:t.innerWidth,height:t.innerHeight},this.viewport=this.resolution),this._contentArea=tq.fromDimension(this.resolution.width,this.resolution.height,tN.Zero),this.displayMode===V.FitScreen&&this._computeFit(),this.displayMode===V.FitContainer&&this._computeFitContainer(),this.displayMode===V.FitScreenAndFill&&this._computeFitScreenAndFill(),this.displayMode===V.FitContainerAndFill&&this._computeFitContainerAndFill(),this.displayMode===V.FitScreenAndZoom&&this._computeFitScreenAndZoom(),this.displayMode===V.FitContainerAndZoom&&this._computeFitContainerAndZoom()}}class eM{static create(){return!this._INSTANCE&&(window.AudioContext||window.webkitAudioContext)&&(this._INSTANCE=new AudioContext),this._INSTANCE}}eM._INSTANCE=null;class ez{static unlock(){return new Promise((t,e)=>{if(ez._UNLOCKED||!eM.create())return t(!0);let i=setTimeout(()=>{tW.getInstance().warn("Excalibur was unable to unlock the audio context, audio probably will not play in this browser."),t(!1)},200),s=eM.create();s.resume().then(()=>{let e=s.createBuffer(1,1,22050),r=s.createBufferSource(),n=!1;r.buffer=e,r.connect(s.destination),r.onended=()=>n=!0,r.start(0),setTimeout(()=>{r.playbackState?(r.playbackState===r.PLAYING_STATE||r.playbackState===r.FINISHED_STATE)&&(ez._UNLOCKED=!0):(s.currentTime>0||n)&&(ez._UNLOCKED=!0)},0),clearTimeout(i),t(!0)},()=>{e()})})}static isUnlocked(){return this._UNLOCKED}}ez._UNLOCKED=!1;class eO extends et{constructor(t){var e,i,s,r,n,o,a,l,h,d;super(t0(t,["width","height"])),this.filtering=null,this.lineCap="butt",this.quality=1,this._dirty=!0,this._smoothing=!1,this._color=t6(tH.Black,()=>this.flagDirty()),this._lineWidth=1,this._lineDash=[],this._padding=0,t&&(this.quality=null!==(e=t.quality)&&void 0!==e?e:this.quality,this.color=null!==(i=t.color)&&void 0!==i?i:tH.Black,this.strokeColor=null==t?void 0:t.strokeColor,this.smoothing=null!==(s=t.smoothing)&&void 0!==s?s:this.smoothing,this.lineWidth=null!==(r=t.lineWidth)&&void 0!==r?r:this.lineWidth,this.lineDash=null!==(n=t.lineDash)&&void 0!==n?n:this.lineDash,this.lineCap=null!==(o=t.lineCap)&&void 0!==o?o:this.lineCap,this.padding=null!==(a=t.padding)&&void 0!==a?a:this.padding,this.filtering=null!==(l=t.filtering)&&void 0!==l?l:this.filtering),this._bitmap=document.createElement("canvas");let c=null!==(h=null==t?void 0:t.width)&&void 0!==h?h:this._bitmap.width,u=null!==(d=null==t?void 0:t.height)&&void 0!==d?d:this._bitmap.height;this.width=c,this.height=u;let p=this._bitmap.getContext("2d");if(p)this._ctx=p;else throw Error("Browser does not support 2d canvas drawing, cannot create Raster graphic")}cloneRasterOptions(){return{color:this.color?this.color.clone():null,strokeColor:this.strokeColor?this.strokeColor.clone():null,smoothing:this.smoothing,lineWidth:this.lineWidth,lineDash:this.lineDash,lineCap:this.lineCap,quality:this.quality,padding:this.padding}}get dirty(){return this._dirty}flagDirty(){this._dirty=!0}get width(){return Math.abs(this._getTotalWidth()*this.scale.x)}set width(t){t/=Math.abs(this.scale.x),this._bitmap.width=t,this._originalWidth=t,this.flagDirty()}get height(){return Math.abs(this._getTotalHeight()*this.scale.y)}set height(t){t/=Math.abs(this.scale.y),this._bitmap.height=t,this._originalHeight=t,this.flagDirty()}_getTotalWidth(){var t;return((null!==(t=this._originalWidth)&&void 0!==t?t:this._bitmap.width)+2*this.padding)*1}_getTotalHeight(){var t;return((null!==(t=this._originalHeight)&&void 0!==t?t:this._bitmap.height)+2*this.padding)*1}get localBounds(){return tq.fromDimension(this._getTotalWidth()*this.scale.x,this._getTotalHeight()*this.scale.y,tN.Zero)}get smoothing(){return this._smoothing}set smoothing(t){this._smoothing=t,this.flagDirty()}get color(){return this._color}set color(t){this.flagDirty(),this._color=t6(t,()=>this.flagDirty())}get strokeColor(){return this._strokeColor}set strokeColor(t){this.flagDirty(),this._strokeColor=t6(t,()=>this.flagDirty())}get lineWidth(){return this._lineWidth}set lineWidth(t){this._lineWidth=t,this.flagDirty()}get lineDash(){return this._lineDash}set lineDash(t){this._lineDash=t,this.flagDirty()}get padding(){return this._padding}set padding(t){this._padding=t,this.flagDirty()}rasterize(){this._dirty=!1,this._ctx.clearRect(0,0,this._getTotalWidth(),this._getTotalHeight()),this._ctx.save(),this._applyRasterProperties(this._ctx),this.execute(this._ctx),this._ctx.restore()}_applyRasterProperties(t){var e,i,s;this._bitmap.width=this._getTotalWidth()*this.quality,this._bitmap.height=this._getTotalHeight()*this.quality,this._bitmap.setAttribute("filtering",this.filtering),this._bitmap.setAttribute("forceUpload","true"),t.scale(this.quality,this.quality),t.translate(this.padding,this.padding),t.imageSmoothingEnabled=this.smoothing,t.lineWidth=this.lineWidth,t.setLineDash(null!==(e=this.lineDash)&&void 0!==e?e:t.getLineDash()),t.lineCap=this.lineCap,t.strokeStyle=null===(i=this.strokeColor)||void 0===i?void 0:i.toString(),t.fillStyle=null===(s=this.color)||void 0===s?void 0:s.toString()}_drawImage(t,e,i){this._dirty&&this.rasterize(),t.scale(1/this.quality,1/this.quality),t.drawImage(this._bitmap,e,i)}}class eU extends eO{get ctx(){return this._ctx}constructor(t){super(t),this._options=t}clone(){return new eU({...this._options,...this.cloneGraphicOptions(),...this.cloneRasterOptions()})}execute(t){var e,i;(null===(e=this._options)||void 0===e?void 0:e.draw)&&(null===(i=this._options)||void 0===i||i.draw(t)),this._options.cache||this.flagDirty()}}class eN{}eN.type={any:"",blob:"blob",json:"json",text:"text",document:"document",arraybuffer:"arraybuffer"};class eZ{constructor(){this.states=new Map}get currentState(){return this._currentState}set currentState(t){this._currentState=t}static create(t,e){let i=new eZ;for(let s in i.data=e,t.states)i.states.set(s,{name:s,...t.states[s]});for(let t of i.states.values())for(let e of t.transitions)if("*"!==e&&!i.states.has(e))throw Error(`Invalid state machine, state [${t.name}] has a transition to another state that doesn't exist [${e}]`);return i.currentState=i.startState=i.states.get(t.start),i}in(t){return this.currentState.name===t}go(t,e){var i,s;if(this.currentState.transitions.includes(t)||this.currentState.transitions.includes("*")){let r=this.states.get(t);return(!this.currentState.onExit||!1!==(null===(i=this.currentState)||void 0===i?void 0:i.onExit({to:r.name,data:this.data})))&&(null==r||!r.onEnter||!1!==(null==r?void 0:r.onEnter({from:this.currentState.name,eventData:e,data:this.data})))&&(this.currentState=r,(null===(s=this.currentState)||void 0===s?void 0:s.onState)&&this.currentState.onState(),!0)}return!1}update(t){this.currentState.onUpdate&&this.currentState.onUpdate(this.data,t)}save(t){localStorage.setItem(t,JSON.stringify({currentState:this.currentState.name,data:this.data}))}restore(t){let e=JSON.parse(localStorage.getItem(t));this.currentState=this.states.get(e.currentState),this.data=e.data}}class eH{_createNewBufferSource(){this._instance=this._audioContext.createBufferSource(),this._instance.buffer=this._src,this._instance.loop=this.loop,this._instance.playbackRate.value=this._playbackRate,this._instance.connect(this._volumeNode),this._volumeNode.connect(this._audioContext.destination)}_handleEnd(){this.loop||(this._instance.onended=()=>{this._playingFuture.resolve(!0)})}set loop(t){this._loop=t,this._instance&&(this._instance.loop=t,this.loop||(this._instance.onended=()=>{this._playingFuture.resolve(!0)}))}get loop(){return this._loop}set volume(t){t=tF(t,0,1),this._volume=t,this._stateMachine.in("PLAYING")&&this._volumeNode.gain.setTargetAtTime?this._volumeNode.gain.setTargetAtTime(t,this._audioContext.currentTime,.1):this._volumeNode.gain.value=t}get volume(){return this._volume}get duration(){var t;return null!==(t=this._duration)&&void 0!==t?t:this.getTotalPlaybackDuration()}set duration(t){this._duration=t}constructor(t){this._src=t,this._audioContext=eM.create(),this._volumeNode=this._audioContext.createGain(),this._playingFuture=new tE,this._stateMachine=eZ.create({start:"STOPPED",states:{PLAYING:{onEnter:({data:t})=>{this._createNewBufferSource(),this._handleEnd(),this.loop?this._instance.start(0,t.pausedAt*this._playbackRate):this._instance.start(0,t.pausedAt*this._playbackRate,this.duration),t.startedAt=this._audioContext.currentTime-t.pausedAt,t.pausedAt=0},onState:()=>this._playStarted(),onExit:({to:t})=>{"STOPPED"===t&&this._playingFuture.resolve(!0),this._instance.onended=null,this._instance.disconnect(),this._instance.stop(0),this._instance=null},transitions:["STOPPED","PAUSED","SEEK"]},SEEK:{onEnter:({eventData:t,data:e})=>{e.pausedAt=(null!=t?t:0)/this._playbackRate,e.startedAt=0},transitions:["*"]},STOPPED:{onEnter:({data:t})=>{t.pausedAt=0,t.startedAt=0,this._playingFuture.resolve(!0)},transitions:["PLAYING","PAUSED","SEEK"]},PAUSED:{onEnter:({data:t})=>{t.pausedAt=this._audioContext.currentTime-t.startedAt},transitions:["PLAYING","STOPPED","SEEK"]}}},{startedAt:0,pausedAt:0}),this._volume=1,this._loop=!1,this._playStarted=()=>{},this._playbackRate=1,this._createNewBufferSource()}isPlaying(){return this._stateMachine.in("PLAYING")}isPaused(){return this._stateMachine.in("PAUSED")||this._stateMachine.in("SEEK")}isStopped(){return this._stateMachine.in("STOPPED")}play(t=()=>{}){return this._playStarted=t,this._stateMachine.go("PLAYING"),this._playingFuture.promise}pause(){this._stateMachine.go("PAUSED")}stop(){this._stateMachine.go("STOPPED")}seek(t){this._stateMachine.go("PAUSED"),this._stateMachine.go("SEEK",t)}getTotalPlaybackDuration(){return this._src.duration}getPlaybackPosition(){let{pausedAt:t,startedAt:e}=this._stateMachine.data;return t?t*this._playbackRate:e?(this._audioContext.currentTime-e)*this._playbackRate:0}set playbackRate(t){this._instance.playbackRate.value=this._playbackRate=t}get playbackRate(){return this._instance.playbackRate.value}}(h=W||(W={})).Kill="kill",h.PreKill="prekill",h.PostKill="postkill",h.PreDraw="predraw",h.PostDraw="postdraw",h.PreDebugDraw="predebugdraw",h.PostDebugDraw="postdebugdraw",h.PreUpdate="preupdate",h.PostUpdate="postupdate",h.PreFrame="preframe",h.PostFrame="postframe",h.PreCollision="precollision",h.CollisionStart="collisionstart",h.CollisionEnd="collisionend",h.PostCollision="postcollision",h.Initialize="initialize",h.Activate="activate",h.Deactivate="deactivate",h.ExitViewport="exitviewport",h.EnterViewport="enterviewport",h.ExitTrigger="exit",h.EnterTrigger="enter",h.Connect="connect",h.Disconnect="disconnect",h.Button="button",h.Axis="axis",h.Visible="visible",h.Hidden="hidden",h.Start="start",h.Stop="stop",h.PointerUp="pointerup",h.PointerDown="pointerdown",h.PointerMove="pointermove",h.PointerEnter="pointerenter",h.PointerLeave="pointerleave",h.PointerCancel="pointercancel",h.PointerWheel="pointerwheel",h.Up="up",h.Down="down",h.Move="move",h.Enter="enter",h.Leave="leave",h.Cancel="cancel",h.Wheel="wheel",h.Press="press",h.Release="release",h.Hold="hold",h.PointerDragStart="pointerdragstart",h.PointerDragEnd="pointerdragend",h.PointerDragEnter="pointerdragenter",h.PointerDragLeave="pointerdragleave",h.PointerDragMove="pointerdragmove",h.ActionStart="actionstart",h.ActionComplete="actioncomplete";class eV{constructor(){this._bubbles=!0}get bubbles(){return this._bubbles}set bubbles(t){this._bubbles=t}stopPropagation(){this.bubbles=!1}}class eW extends eV{constructor(t){super(),this.target=t}}class eG extends eV{constructor(t){super(),this.target=t}}class ej extends eV{constructor(t){super(),this.target=t}}class eq extends eV{constructor(t){super(),this.target=t}}class eX extends eV{constructor(t){super(),this.target=t}}class e$ extends eV{constructor(t,e,i){super(),this.ctx=t,this.delta=e,this.target=i}}class eK extends eV{constructor(t,e,i){super(),this.ctx=t,this.delta=e,this.target=i}}class eY extends eV{constructor(t,e,i){super(),this.ctx=t,this.delta=e,this.target=i}}class eQ extends eV{constructor(t,e,i){super(),this.ctx=t,this.delta=e,this.target=i}}class eJ extends eV{constructor(t,e){super(),this.ctx=t,this.target=e}}class e0 extends eV{constructor(t,e){super(),this.ctx=t,this.target=e}}class e1 extends eV{constructor(t,e,i){super(),this.engine=t,this.delta=e,this.target=i}}class e2 extends eV{constructor(t,e,i){super(),this.engine=t,this.delta=e,this.target=i}}class e5 extends eV{constructor(t,e){super(),this.engine=t,this.prevStats=e,this.target=t}}class e4 extends eV{constructor(t,e){super(),this.engine=t,this.stats=e,this.target=t}}class e3 extends eV{constructor(t,e){super(),this.index=t,this.gamepad=e,this.target=e}}class e9 extends eV{constructor(t,e){super(),this.index=t,this.gamepad=e,this.target=e}}class e6 extends eV{constructor(t,e,i){super(),this.button=t,this.value=e,this.target=i}}class e7 extends eV{constructor(t,e,i){super(),this.axis=t,this.value=e,this.target=i}}class e8 extends eV{constructor(t){super(),this.target=t}}class it extends eV{constructor(t){super(),this.target=t}}class ie extends eV{constructor(t,e,i,s,r){super(),this.other=e,this.side=i,this.intersection=s,this.contact=r,this.target=t}}class ii extends eV{constructor(t,e,i,s,r){super(),this.other=e,this.side=i,this.intersection=s,this.contact=r,this.target=t}get actor(){return this.target}set actor(t){this.target=t}}class is{constructor(t,e,i,s){this.target=t,this.other=e,this.side=i,this.contact=s}}class ir{constructor(t,e,i,s){this.target=t,this.other=e,this.side=i,this.lastContact=s}}class io{constructor(t,e,i,s,r){this.target=t,this.other=e,this.side=i,this.intersection=s,this.contact=r}}class ia{constructor(t,e,i,s,r){this.target=t,this.other=e,this.side=i,this.intersection=s,this.contact=r}}class il extends eV{constructor(t,e,i,s){super(),this.other=e,this.side=i,this.contact=s,this.target=t}get actor(){return this.target}set actor(t){this.target=t}}class ih extends eV{constructor(t,e,i,s){super(),this.other=e,this.side=i,this.lastContact=s,this.target=t}get actor(){return this.target}set actor(t){this.target=t}}class id extends eV{constructor(t,e){super(),this.engine=t,this.target=e}}class ic extends eV{constructor(t,e){super(),this.context=t,this.target=e}}class iu extends eV{constructor(t,e){super(),this.context=t,this.target=e}}class ip extends eV{constructor(t){super(),this.target=t}}class ig extends eV{constructor(t){super(),this.target=t}}class i_ extends eV{constructor(t,e){super(),this.target=t,this.actor=e}}class im extends eV{constructor(t,e){super(),this.target=t,this.actor=e}}class iv extends eV{constructor(t,e){super(),this.action=t,this.target=e}}class iy extends eV{constructor(t,e){super(),this.action=t,this.target=e}}class ix extends eV{set bubbles(t){}get bubbles(){return!1}get _path(){return null}set _path(t){}constructor(t,e="MediaEvent"){super(),this.target=t,this._name=e}stopPropagation(){}action(){}propagate(){}layPath(t){}}class iw extends ix{constructor(t,e){super(t,"NativeSoundEvent"),this.track=e}}class ib extends ix{constructor(t,e){super(t,"NativeSoundProcessedEvent"),this._processedData=e,this.data=this._processedData}}let iC={VolumeChange:"volumechange",Processed:"processed",Pause:"pause",Stop:"stop",PlaybackEnd:"playbackend",Resume:"resume",PlaybackStart:"playbackstart"};class iT{set loop(t){for(let e of(this._loop=t,this._tracks))e.loop=this._loop;this.logger.debug("Set loop for all instances of sound",this.path,"to",this._loop)}get loop(){return this._loop}set volume(t){for(let e of(this._volume=t,this._tracks))e.volume=this._volume;this.events.emit("volumechange",new iw(this)),this.logger.debug("Set loop for all instances of sound",this.path,"to",this._volume)}get volume(){return this._volume}get duration(){return this._duration}set duration(t){this._duration=t}get instances(){return this._tracks}get path(){return this._resource.path}set path(t){this._resource.path=t}get bustCache(){return this._resource.bustCache}set bustCache(t){this._resource.bustCache=t}constructor(...t){for(let e of(this.events=new tP,this.logger=tW.getInstance(),this._loop=!1,this._volume=1,this._isStopped=!1,this._tracks=[],this._wasPlayingOnHidden=!1,this._playbackRate=1,this._audioContext=eM.create(),this._resource=new t9("",eN.type.arraybuffer),t))if(function(t){try{let e=new Audio,i=t.match(/.*\.([A-Za-z0-9]+)(?:(?:\?|\#).*)*$/)[1];if(e.canPlayType("audio/"+i))return!0;return!1}catch(t){return tW.getInstance().warn("Cannot determine audio support, assuming no support for the Audio Tag",t),!1}}(e)){this.path=e;break}this.path||(this.logger.warn("This browser does not support any of the audio files specified:",t.join(", ")),this.logger.warn("Attempting to use",t[0]),this.path=t[0])}isLoaded(){return!!this.data}async load(){var t,e;if(this.data)return this.data;let i=await this._resource.load(),s=await this.decodeAudio(i.slice(0));return this._duration=null!==(e=null!==(t=this._duration)&&void 0!==t?t:null==s?void 0:s.duration)&&void 0!==e?e:void 0,this.events.emit("processed",new ib(this,s)),this.data=s}async decodeAudio(t){try{return await this._audioContext.decodeAudioData(t.slice(0))}catch(t){return this.logger.error("Unable to decode this browser may not fully support this format, or the file may be corrupt, if this is an mp3 try removing id3 tags and album art from the file."),await Promise.reject()}}wireEngine(t){t&&(this._engine=t,this._engine.on("hidden",()=>{t.pauseAudioWhenHidden&&this.isPlaying()&&(this._wasPlayingOnHidden=!0,this.pause())}),this._engine.on("visible",()=>{t.pauseAudioWhenHidden&&this._wasPlayingOnHidden&&(this.play(),this._wasPlayingOnHidden=!1)}),this._engine.on("start",()=>{this._isStopped=!1}),this._engine.on("stop",()=>{this.stop(),this._isStopped=!0}))}instanceCount(){return this._tracks.length}isPlaying(){return this._tracks.some(t=>t.isPlaying())}isPaused(){return this._tracks.some(t=>t.isPaused())}isStopped(){return this._tracks.some(t=>t.isStopped())}play(t){return this.isLoaded()?this._isStopped?(this.logger.warn("Cannot start playing. Engine is in a stopped state."),Promise.resolve(!1)):(this.volume=t||this.volume,this.isPaused())?this._resumePlayback():this._startPlayback():(this.logger.warn("Cannot start playing. Resource",this.path,"is not loaded yet"),Promise.resolve(!0))}pause(){if(this.isPlaying()){for(let t of this._tracks)t.pause();this.events.emit("pause",new iw(this)),this.logger.debug("Paused all instances of sound",this.path)}}stop(){for(let t of this._tracks)t.stop();this.events.emit("stop",new iw(this)),this._tracks.length=0,this.logger.debug("Stopped all instances of sound",this.path)}get playbackRate(){return this._playbackRate}set playbackRate(t){this._playbackRate=t,this._tracks.forEach(t=>{t.playbackRate=this._playbackRate})}seek(t,e=0){0===this._tracks.length&&this._getTrackInstance(this.data),this._tracks[e].seek(t)}getTotalPlaybackDuration(){return this.isLoaded()?this.data.duration:(this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`),0)}getPlaybackPosition(t=0){return this._tracks.length?this._tracks[t].getPlaybackPosition():0}getTrackId(t){return this._tracks.indexOf(t)}async _resumePlayback(){if(this.isPaused){let t=[];for(let e of this._tracks)t.push(e.play().then(()=>(this._tracks.splice(this.getTrackId(e),1),!0)));this.events.emit("resume",new iw(this)),this.logger.debug("Resuming paused instances for sound",this.path,this._tracks),await Promise.all(t)}return!0}async _startPlayback(){let t=this._getTrackInstance(this.data),e=await t.play(()=>{this.events.emit("playbackstart",new iw(this,t)),this.logger.debug("Playing new instance for sound",this.path)});this.events.emit("playbackend",new iw(this,t));let i=this.getTrackId(t);return -1!==i&&this._tracks.splice(i,1),e}_getTrackInstance(t){let e=new eH(t);return e.loop=this.loop,e.volume=this.volume,e.duration=this.duration,e.playbackRate=this._playbackRate,this._tracks.push(e),e}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}}let iS={BeforeLoad:"beforeload",AfterLoad:"afterload",UserAction:"useraction",LoadResourceStart:"loadresourcestart",LoadResourceEnd:"loadresourceend"};function iA(t){var e,i;return!!(null==t?void 0:t.prototype)&&!!(null===(i=null===(e=null==t?void 0:t.prototype)||void 0===e?void 0:e.constructor)||void 0===i?void 0:i.name)}class iE{get resources(){return this._resources}constructor(t){var e;this.events=new tP,this.canvas=new eU({filtering:H.Blended,smoothing:!0,cache:!1,draw:this.onDraw.bind(this)}),this._resources=[],this._numLoaded=0,this._totalTimeMs=0,this._loadingFuture=new tE,t&&(null===(e=t.loadables)||void 0===e?void 0:e.length)&&this.addResources(t.loadables)}onInitialize(t){this.engine=t,this.canvas.width=this.engine.screen.resolution.width,this.canvas.height=this.engine.screen.resolution.height}async onUserAction(){return await Promise.resolve()}async onBeforeLoad(){}async onAfterLoad(){await tJ(500,this.engine.clock)}addResource(t){this._resources.push(t)}addResources(t){let e=0,i=t.length;for(;e0?tF(this._numLoaded,0,t)/t:1}isLoaded(){return this._numLoaded===this._resources.length}onUpdate(t,e){this._totalTimeMs+=e}onDraw(t){let e=this._totalTimeMs/1e3;t.fillStyle=tH.Black.toRGBA(),t.fillRect(0,0,this.engine.screen.resolution.width,this.engine.screen.resolution.height),t.save(),t.translate(this.engine.screen.resolution.width/2,this.engine.screen.resolution.height/2);let i=10*e;t.strokeStyle="white",t.lineWidth=10,t.lineCap="round",t.arc(0,0,40,i,i+3*Math.PI/2),t.stroke(),t.fillStyle="white",t.font="16px sans-serif";let s=(100*this.progress).toFixed(0)+"%",r=t.measureText(s),n=Math.abs(r.actualBoundingBoxLeft)+Math.abs(r.actualBoundingBoxRight),o=Math.abs(r.actualBoundingBoxAscent)+Math.abs(r.actualBoundingBoxDescent);t.fillText(s,-n/2,o/2),t.restore()}areResourcesLoaded(){return this._loadingFuture.promise}async load(){for(let t of(await this.onBeforeLoad(),this.events.emit("beforeload"),this.canvas.flagDirty(),await Promise.all(this._resources.map(async t=>{this.events.emit("loadresourcestart",t),await t.load().finally(()=>{this._numLoaded++,this.canvas.flagDirty(),this.events.emit("loadresourceend",t)})})),this._resources))t instanceof iT&&t.wireEngine(this.engine);return this._loadingFuture.resolve(),this.canvas.flagDirty(),await this.onUserAction(),this.events.emit("useraction"),await ez.unlock(),await this.onAfterLoad(),this.events.emit("afterload"),this.data=this._resources}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}}function iP(t,e=tH.Red,i,s,r,n,o=1,a="butt"){t.save(),t.beginPath(),t.lineWidth=o,t.lineCap=a,t.strokeStyle=e.toString(),t.moveTo(i,s),t.lineTo(r,n),t.closePath(),t.stroke(),t.restore()}function iI(t,e=tH.Red,i){t.beginPath(),t.strokeStyle=e.toString(),t.arc(i.x,i.y,5,0,2*Math.PI),t.closePath(),t.stroke()}function ik(t,e,i,s,r=1){let n=e?e.toString():"blue",o=s.scale(r);t.beginPath(),t.strokeStyle=n,t.moveTo(i.x,i.y),t.lineTo(i.x+o.x,i.y+o.y),t.closePath(),t.stroke()}function iD(t,e,i,s,r,n=5,o=tH.White,a=null){let l;if("number"==typeof n)l={tl:n,tr:n,br:n,bl:n};else{let t={tl:0,tr:0,br:0,bl:0};for(let e in t)t.hasOwnProperty(e)&&(l[e]=n[e]||t[e])}t.beginPath(),t.moveTo(e+l.tl,i),t.lineTo(e+s-l.tr,i),t.quadraticCurveTo(e+s,i,e+s,i+l.tr),t.lineTo(e+s,i+r-l.br),t.quadraticCurveTo(e+s,i+r,e+s-l.br,i+r),t.lineTo(e+l.bl,i+r),t.quadraticCurveTo(e,i+r,e,i+r-l.bl),t.lineTo(e,i+l.tl),t.quadraticCurveTo(e,i,e+l.tl,i),t.closePath(),a&&(t.fillStyle=a.toString(),t.fill()),o&&(t.strokeStyle=o.toString(),t.stroke())}function iR(t,e,i,s,r=tH.White,n=null){t.beginPath(),t.arc(e,i,s,0,2*Math.PI),t.closePath(),n&&(t.fillStyle=n.toString(),t.fill()),r&&(t.strokeStyle=r.toString(),t.stroke())}var iF=n(7835);class iB extends iE{get _image(){return this._imageElement||(this._imageElement=new Image,this._imageElement.src=this.logo),this._imageElement}get playButtonRootElement(){return this._playButtonRootElement}get playButtonElement(){return this._playButtonElement}get _playButton(){let t=document.getElementById("excalibur-play-root");return t&&(this._playButtonRootElement=t),this._playButtonRootElement||(this._playButtonRootElement=document.createElement("div"),this._playButtonRootElement.id="excalibur-play-root",this._playButtonRootElement.style.position="absolute",document.body.appendChild(this._playButtonRootElement)),this._styleBlock||(this._styleBlock=document.createElement("style"),this._styleBlock.textContent=this._playButtonStyles,document.head.appendChild(this._styleBlock)),this._playButtonElement||(this._playButtonElement=this.startButtonFactory(),this._playButtonRootElement.appendChild(this._playButtonElement)),this._playButtonElement}constructor(t){let e=Array.isArray(t)?{loadables:t}:t;super(e),this._logger=tW.getInstance(),this._originalOptions={loadables:[]},this.events=new tP,this._playButtonShown=!1,this.logo="data:image/png;base64,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",this.logoWidth=468,this.logoHeight=118,this.loadingBarColor=tH.White,this.backgroundColor="#176BAA",this.suppressPlayButton=!1,this._playButtonStyles=iF.Z.toString(),this.playButtonText="Play game",this.startButtonFactory=()=>{let t=document.getElementById("excalibur-play");return t||(t=document.createElement("button")),t.id="excalibur-play",t.textContent=this.playButtonText,t.style.display="none",t},this._configuredPixelRatio=null,this._originalOptions={...iB._DEFAULT_LOADER_OPTIONS,...e}}onInitialize(t){this.engine=t,this.screen=t.screen,this.canvas.width=this.engine.canvas.width,this.canvas.height=this.engine.canvas.height}async showPlayButton(){var t,e;if(this.suppressPlayButton)this.hidePlayButton(),await tJ(500,null===(t=this.engine)||void 0===t?void 0:t.clock);else{let t=()=>{try{this._positionPlayButton()}catch(t){}};(null===(e=this.engine)||void 0===e?void 0:e.browser)&&this.engine.browser.window.on("resize",t),this._playButtonShown=!0,this._playButton.style.display="block",document.body.addEventListener("keyup",t=>{"Enter"===t.key&&this._playButton.click()}),this._positionPlayButton();let i=new Promise(e=>{let i=i=>{var s;if(i.stopPropagation(),this.hidePlayButton(),(null===(s=this.engine)||void 0===s?void 0:s.browser)&&this.engine.browser.window.off("resize",t),this._originalOptions.fullscreenAfterLoad)try{this._logger.info("requesting fullscreen"),this._originalOptions.fullscreenContainer instanceof HTMLElement?this._originalOptions.fullscreenContainer.requestFullscreen():this.engine.screen.goFullScreen(this._originalOptions.fullscreenContainer)}catch(t){this._logger.error("could not go fullscreen",t)}e()};this._playButton.addEventListener("click",i),this._playButton.addEventListener("touchend",i),this._playButton.addEventListener("pointerup",i)});return await i}}hidePlayButton(){this._playButtonShown=!1,this._playButton.style.display="none"}dispose(){this._playButtonRootElement.parentElement&&(this._playButtonRootElement.removeChild(this._playButtonElement),document.body.removeChild(this._playButtonRootElement),document.head.removeChild(this._styleBlock),this._playButtonRootElement=null,this._playButtonElement=null,this._styleBlock=null)}async onUserAction(){var t;await tJ(200,null===(t=this.engine)||void 0===t?void 0:t.clock),this.canvas.flagDirty(),await this.showPlayButton()}async onBeforeLoad(){var t;this._configuredPixelRatio=this.screen.pixelRatioOverride,this.screen.pushResolutionAndViewport(),this.screen.resolution=this.screen.viewport,this.screen.pixelRatioOverride=1,this.screen.applyResolutionAndViewport(),this.canvas.width=this.engine.canvas.width,this.canvas.height=this.engine.canvas.height,await (null===(t=this._image)||void 0===t?void 0:t.decode())}async onAfterLoad(){this.screen.pixelRatioOverride=this._configuredPixelRatio,this.screen.popResolutionAndViewport(),this.screen.applyResolutionAndViewport(),this.dispose()}_positionPlayButton(){if(this.engine){let t=this.engine.screen.viewport.height,e=this.engine.screen.viewport.width;if(this._playButtonRootElement){let i=this.engine.canvas.offsetLeft,s=this.engine.canvas.offsetTop,r=this._playButton.clientWidth,n=this._playButton.clientHeight;this.playButtonPosition?(this._playButtonRootElement.style.left=`${this.playButtonPosition.x}px`,this._playButtonRootElement.style.top=`${this.playButtonPosition.y}px`):(this._playButtonRootElement.style.left=`${i+e/2-r/2}px`,this._playButtonRootElement.style.top=`${s+t/2-n/2+100}px`)}}}onDraw(t){let e=this.engine.canvasHeight/this.engine.pixelRatio,i=this.engine.canvasWidth/this.engine.pixelRatio;this._positionPlayButton(),t.fillStyle=this.backgroundColor,t.fillRect(0,0,i,e);let s=e/2,r=Math.min(this.logoWidth,.75*i),n=i/2-r/2;this.logoPosition&&(n=this.logoPosition.x,s=this.logoPosition.y);let o=Math.floor(this.logoHeight/this.logoWidth*r),a=this.engine.getAntialiasing();if(this.engine.setAntialiasing(!0),this.logoPosition?t.drawImage(this._image,0,0,this.logoWidth,this.logoHeight,n,s,r,o):t.drawImage(this._image,0,0,this.logoWidth,this.logoHeight,n,s-o-20,r,o),!this.suppressPlayButton&&this._playButtonShown){this.engine.setAntialiasing(a);return}let l=n,h=s;this.loadingBarPosition&&(l=this.loadingBarPosition.x,h=this.loadingBarPosition.y),t.lineWidth=2,iD(t,l,h,r,20,10,this.loadingBarColor);let d=r*this.progress-10;iD(t,l+5,h+5,d>10?d:10,10,5,null,this.loadingBarColor),this.engine.setAntialiasing(a)}}iB._DEFAULT_LOADER_OPTIONS={loadables:[],fullscreenAfterLoad:!1,fullscreenContainer:void 0};let iL={webgl:"WebGL",webaudio:"WebAudio",gamepadapi:"Gamepad API"};class iM{constructor(){this._features=null,this.failedTests=[],this._criticalTests={canvasSupport:function(){let t=document.createElement("canvas");return!!(t.getContext&&t.getContext("2d"))},arrayBufferSupport:function(){let t=new XMLHttpRequest;t.open("GET","/");try{t.responseType="arraybuffer"}catch(t){return!1}return"arraybuffer"===t.responseType},dataUrlSupport:function(){return 0===document.createElement("canvas").toDataURL("image/png").indexOf("data:image/png")},objectUrlSupport:function(){return"URL"in window&&"revokeObjectURL"in URL&&"createObjectURL"in URL},rgbaSupport:function(){let t=document.createElement("a").style;return t.cssText="background-color:rgba(150,255,150,.5)",(""+t.backgroundColor).indexOf("rgba")>-1}},this._warningTest={webAudioSupport:function(){return!!(window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext)},webglSupport:function(){let t=document.createElement("canvas");return!!(t.getContext&&t.getContext("webgl"))}},this._features=this._loadBrowserFeatures()}getBrowserFeatures(){return null===this._features&&(this._features=this._loadBrowserFeatures()),this._features}logBrowserFeatures(){let t="%cSUPPORTED BROWSER FEATURES\n==========================%c\n",e=["font-weight: bold; color: navy","font-weight: normal; color: inherit"],i=this.getBrowserFeatures();for(let s of Object.keys(iL))i[s]?(t+="(%c✓%c)",e.push("font-weight: bold; color: green")):(t+="(%c✗%c)",e.push("font-weight: bold; color: red")),e.push("font-weight: normal; color: inherit"),t+=" "+iL[s]+"\n";e.unshift(t),console.log.apply(console,e)}_loadBrowserFeatures(){return{canvas:this._criticalTests.canvasSupport(),arraybuffer:this._criticalTests.arrayBufferSupport(),dataurl:this._criticalTests.dataUrlSupport(),objecturl:this._criticalTests.objectUrlSupport(),rgba:this._criticalTests.rgbaSupport(),webaudio:this._warningTest.webAudioSupport(),webgl:this._warningTest.webglSupport(),gamepadapi:!!navigator.getGamepads}}test(){let t=!1;for(let e in this._criticalTests)this._criticalTests[e].call(this)||(this.failedTests.push(e),tW.getInstance().error("Critical browser feature missing, Excalibur requires:",e),t=!0);if(t)return!1;for(let t in this._warningTest)this._warningTest[t]()||tW.getInstance().warn("Warning browser feature missing, Excalibur will have reduced performance:",t);return!0}}(d=G||(G={})).PreventCollision="PreventCollision",d.Passive="Passive",d.Active="Active",d.Fixed="Fixed",(c=j||(j={})).World="world",c.Screen="screen";class iz extends tN{constructor(t){super(0,0),this._getX=t.getX,this._getY=t.getY,this._setX=t.setX,this._setY=t.setY}get x(){return this._x=this._getX()}set x(t){this._setX(t),this._x=t}get y(){return this._y=this._getY()}set y(t){this._setY(t),this._y=t}}class iO extends tN{constructor(t,e){super(t.x,t.y),this.original=t,this.change=e}get x(){return this._x=this.original.x}set x(t){this.change(t,this._y),this._x=this.original.x=t}get y(){return this._y=this.original.y}set y(t){this.change(this._x,t),this._y=this.original.y=t}}class iU{constructor(){this._parent=null,this._children=[],this._pos=tZ(0,0),this._rotation=0,this._scale=tZ(1,1),this._isDirty=!1,this._isInverseDirty=!1,this._matrix=t2.identity(),this._inverse=t2.identity()}get parent(){return this._parent}set parent(t){if(this._parent){let t=this._parent._children.indexOf(this);t>-1&&this._parent._children.splice(t,1)}this._parent=t,this._parent&&this._parent._children.push(this),this.flagDirty()}get children(){return this._children}set pos(t){t.equals(this._pos)||(this._pos.x=t.x,this._pos.y=t.y,this.flagDirty())}get pos(){return new iO(this._pos,(t,e)=>{(t!==this._pos.x||e!==this._pos.y)&&this.flagDirty()})}set globalPos(t){let e=t.clone();this.parent&&(e=this.parent.inverse.multiply(t)),e.equals(this._pos)||(this._pos=e,this.flagDirty())}get globalPos(){return new iz({getX:()=>this.matrix.data[4],getY:()=>this.matrix.data[5],setX:t=>{if(this.parent){let{x:e}=this.parent.inverse.multiply(tZ(t,this.pos.y));this.pos.x=e}else this.pos.x=t;t!==this.matrix.data[4]&&this.flagDirty()},setY:t=>{if(this.parent){let{y:e}=this.parent.inverse.multiply(tZ(this.pos.x,t));this.pos.y=e}else this.pos.y=t;t!==this.matrix.data[5]&&this.flagDirty()}})}set rotation(t){let e=tB(t);e!==this._rotation&&this.flagDirty(),this._rotation=e}get rotation(){return this._rotation}set globalRotation(t){let e=0;this.parent&&(e=this.parent.globalRotation);let i=tB(t+e);i!==this._rotation&&this.flagDirty(),this._rotation=i}get globalRotation(){return this.parent?this.matrix.getRotation():this.rotation}set scale(t){t.equals(this._scale)||(this._scale.x=t.x,this._scale.y=t.y,this.flagDirty())}get scale(){return new iO(this._scale,(t,e)=>{(t!==this._scale.x||e!==this._scale.y)&&this.flagDirty()})}set globalScale(t){let e=tZ(1,1);this.parent&&(e=this.parent.globalScale),this.scale=t.scale(tZ(1/e.x,1/e.y))}get globalScale(){return new iz({getX:()=>this.parent?this.matrix.getScaleX():this.scale.x,getY:()=>this.parent?this.matrix.getScaleY():this.scale.y,setX:t=>{if(this.parent){let e=this.parent.globalScale.x;this.scale.x=t/e}else this.scale.x=t},setY:t=>{if(this.parent){let e=this.parent.globalScale.y;this.scale.y=t/e}else this.scale.y=t}})}get matrix(){return this._isDirty&&(null===this.parent?this._matrix=this._calculateMatrix():this._matrix=this.parent.matrix.multiply(this._calculateMatrix()),this._isDirty=!1),this._matrix}get inverse(){return this._isInverseDirty&&(this._inverse=this.matrix.inverse(),this._isInverseDirty=!1),this._inverse}_calculateMatrix(){return t2.identity().translate(this.pos.x,this.pos.y).rotate(this.rotation).scale(this.scale.x,this.scale.y)}flagDirty(){this._isDirty=!0,this._isInverseDirty=!0;for(let t=0;t{let e=t.get(iV);e&&(e._transform.parent=this._transform,e._parentComponent=this)},this.zIndexChanged$=new iH,this._z=0,this._coordPlane=j.World}get(){return this._transform}onAdd(t){for(let e of t.children)this._addChildTransform(e);t.childrenAdded$.subscribe(t=>this._addChildTransform(t)),t.childrenRemoved$.subscribe(t=>{let e=t.get(iV);e&&(e._transform.parent=null,e._parentComponent=null)})}onRemove(t){this._transform.parent=null,this._parentComponent=null}get z(){return this._z}set z(t){let e=this._z;this._z=t,e!==t&&this.zIndexChanged$.notifyAll(t)}get coordPlane(){return this._parentComponent?this._parentComponent.coordPlane:this._coordPlane}set coordPlane(t){var e;this._parentComponent?this._logger.warn(`Cannot set coordinate plane on child entity ${null===(e=this.owner)||void 0===e?void 0:e.name}, children inherit their coordinate plane from their parents.`):this._coordPlane=t}get pos(){return this._transform.pos}set pos(t){this._transform.pos=t}get globalPos(){return this._transform.globalPos}set globalPos(t){this._transform.globalPos=t}get rotation(){return this._transform.rotation}set rotation(t){this._transform.rotation=t}get globalRotation(){return this._transform.globalRotation}set globalRotation(t){this._transform.globalRotation=t}get scale(){return this._transform.scale}set scale(t){this._transform.scale=t}get globalScale(){return this._transform.globalScale}set globalScale(t){this._transform.globalScale=t}applyInverse(t){return this._transform.applyInverse(t)}apply(t){return this._transform.apply(t)}clone(){let t=new iV;return t._transform=this._transform.clone(),t._z=this._z,t}}class iW extends iZ{constructor(){super(...arguments),this.vel=tN.Zero,this.acc=tN.Zero,this.scaleFactor=tN.Zero,this.angularVelocity=0,this.torque=0,this.inertia=1}}class iG{static create(t,e){if(this._CURRENT_GROUP>this._MAX_GROUPS)throw Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);if(this._GROUPS.get(t)){let i=this._GROUPS.get(t);if(i.mask===e)return i;throw Error(`Collision group ${t} already exists with a different mask!`)}let i=new ij(t,this._CURRENT_BIT,void 0!==e?e:~this._CURRENT_BIT);return this._CURRENT_BIT=this._CURRENT_BIT<<1|0,this._CURRENT_GROUP++,this._GROUPS.set(t,i),i}static get groups(){return Array.from(this._GROUPS.values())}static groupByName(t){return this._GROUPS.get(t)}static reset(){this._GROUPS=new Map,this._CURRENT_BIT=this._STARTING_BIT,this._CURRENT_GROUP=1}}iG._STARTING_BIT=1,iG._MAX_GROUPS=32,iG._CURRENT_GROUP=1,iG._CURRENT_BIT=iG._STARTING_BIT,iG._GROUPS=new Map;class ij{constructor(t,e,i){this._name=t,this._category=e,this._mask=i}get name(){return this._name}get category(){return this._category}get mask(){return this._mask}canCollide(t){let e=this.category&t.mask,i=this.mask&t.category;return 0!==e&&0!==i}invert(){let t=iG.create("~("+this.name+")",0|~this.mask);return t._category=~this.category,t}static combine(t){let e=t.map(t=>t.name).join("+"),i=t.reduce((t,e)=>e.category|t,0);return iG.create(e,~i)}static collidesWith(t){let e=`collidesWith(${t.map(t=>t.name).join("+")})`,i=t.reduce((t,e)=>e.category|t,0);return iG.create(e,i)}toString(){return` category: ${this.category.toString(2).padStart(32,"0")} mask: ${(this.mask>>>0).toString(2).padStart(32,"0")} - `}}ij.All=new ij("Collide with all groups",-1,-1);class iq{constructor(t,e){this.colliderA=t,this.colliderB=e,this.id=null,this.id=iq.calculatePairHash(t.id,e.id)}static canCollide(t,e){var i,s;let r=null===(i=null==t?void 0:t.owner)||void 0===i?void 0:i.get(sh),n=null===(s=null==e?void 0:e.owner)||void 0===s?void 0:s.get(sh);return!(t.id===e.id||t.owner&&e.owner&&t.owner.id===e.owner.id||t.localBounds.hasZeroDimensions()||e.localBounds.hasZeroDimensions())&&!!r&&!!n&&!!r.group.canCollide(n.group)&&(r.collisionType!==G.Fixed||n.collisionType!==G.Fixed)&&n.collisionType!==G.PreventCollision&&r.collisionType!==G.PreventCollision&&!!r.active&&!!n.active}get canCollide(){let t=this.colliderA,e=this.colliderB;return iq.canCollide(t,e)}collide(){return this.colliderA.collide(this.colliderB)}hasCollider(t){return t===this.colliderA||t===this.colliderB}static calculatePairHash(t,e){return t.valuet.min&&t.max>this.min}getOverlap(t){return this.overlaps(t)?this.max>t.max?t.max-this.min:this.max-t.min:0}}class i${constructor(t){this.parent=t,this.parent=t||null,this.data=null,this.bounds=new tq,this.left=null,this.right=null,this.height=0}isLeaf(){return!this.left&&!this.right}}class iK{constructor(t,e=new tq(-Number.MAX_VALUE,-Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE)){this._config=t,this.worldBounds=e,this.root=null,this.nodes={}}_insert(t){if(null===this.root){this.root=t,this.root.parent=null;return}let e=t.bounds,i=this.root;for(;!i.isLeaf();){let t;let s=i.left,r=i.right,n=i.bounds.getPerimeter(),o=i.bounds.combine(e).getPerimeter(),a=2*o,l=2*(o-n),h=0,d=e.combine(s.bounds);s.isLeaf()?h=d.getPerimeter()+l:(t=s.bounds.getPerimeter(),h=d.getPerimeter()-t+l);let c=0,u=e.combine(r.bounds);if(r.isLeaf()?c=u.getPerimeter()+l:(t=r.bounds.getPerimeter(),c=u.getPerimeter()-t+l),a1)return i.left=t,i.parent=t.parent,t.parent=i,i.parent?i.parent.left===t?i.parent.left=i:i.parent.right=i:this.root=i,n.height>o.height?(i.right=n,t.right=o,o.parent=t,t.bounds=e.bounds.combine(o.bounds),i.bounds=t.bounds.combine(n.bounds),t.height=1+Math.max(e.height,o.height),i.height=1+Math.max(t.height,n.height)):(i.right=o,t.right=n,n.parent=t,t.bounds=e.bounds.combine(n.bounds),i.bounds=t.bounds.combine(o.bounds),t.height=1+Math.max(e.height,n.height),i.height=1+Math.max(t.height,o.height)),i;if(a<-1){if(e.left=t,e.parent=t.parent,t.parent=e,e.parent){if(e.parent.left===t)e.parent.left=e;else{if(e.parent.right!==t)throw"Error rotating Dynamic Tree";e.parent.right=e}}else this.root=e;return s.height>r.height?(e.right=s,t.left=r,r.parent=t,t.bounds=i.bounds.combine(r.bounds),e.bounds=t.bounds.combine(s.bounds),t.height=1+Math.max(i.height,r.height),e.height=1+Math.max(t.height,s.height)):(e.right=r,t.left=s,s.parent=t,t.bounds=i.bounds.combine(s.bounds),e.bounds=t.bounds.combine(r.bounds),t.height=1+Math.max(i.height,s.height),e.height=1+Math.max(t.height,r.height)),e}return t}getHeight(){return null===this.root?0:this.root.height}query(t,e){let i=t.bounds,s=r=>{if(r&&r.bounds.overlaps(i)){if(!r.isLeaf()||r.data===t)return s(r.left)||s(r.right);if(e.call(t,r.data))return!0}return!1};s(this.root)}rayCastQuery(t,e=1/0,i){let s=r=>{if(r&&r.bounds.rayCast(t,e)){if(!r.isLeaf())return s(r.left)||s(r.right);if(i.call(t,r.data))return!0}return!1};s(this.root)}getNodes(){let t=e=>e?[e].concat(t(e.left),t(e.right)):[];return t(this.root)}debug(t){let e=i=>{i&&(i.isLeaf()?i.bounds.draw(t,tH.Green):i.bounds.draw(t,tH.White),i.left&&e(i.left),i.right&&e(i.right))};e(this.root)}}class iY{constructor(t,e){this.pos=t,this.dir=e.normalize()}intersect(t){let e=t.begin.sub(this.pos);if(0===this.dir.cross(t.getSlope())&&0!==e.cross(this.dir))return -1;let i=this.dir.cross(t.getSlope());if(0===i)return -1;let s=e.cross(t.getSlope())/i;if(s>=0){let r=e.cross(this.dir)/i/t.getLength();if(r>=0&&r<=1)return s}return -1}intersectPoint(t){let e=this.intersect(t);return e<0?null:this.getPoint(e)}getPoint(t){return this.pos.add(this.dir.scale(t))}}class iQ{constructor(t){this._config=t,this._pairs=new Set,this._collisionPairCache=[],this._colliders=[],this._dynamicCollisionTree=new iK(t.dynamicTree)}getColliders(){return this._colliders}rayCast(t,e){var i,s,r;let n=[],o=null!==(i=null==e?void 0:e.maxDistance)&&void 0!==i?i:1/0,a=null==e?void 0:e.collisionGroup,l=a?a.category:null!==(s=null==e?void 0:e.collisionMask)&&void 0!==s?s:ij.All.category,h=null!==(r=null==e?void 0:e.searchAllColliders)&&void 0!==r&&r;return this._dynamicCollisionTree.rayCastQuery(t,o,i=>{let s=i.owner.get(sh);if((null==e?void 0:e.ignoreCollisionGroupAll)&&s.group===ij.All)return!1;let r=(l&s.group.category)!=0;if((null==s?void 0:s.group)&&!r)return!1;let a=i.rayCast(t,o);if(a){if(null==e?void 0:e.filter){if(e.filter(a)&&(n.push(a),!h))return!0}else if(n.push(a),!h)return!0}return!1}),n}track(t){if(!t){tW.getInstance().warn("Cannot track null collider");return}if(t instanceof i9)for(let e of t.getColliders())e.owner=t.owner,this._colliders.push(e),this._dynamicCollisionTree.trackCollider(e);else this._colliders.push(t),this._dynamicCollisionTree.trackCollider(t)}untrack(t){if(!t){tW.getInstance().warn("Cannot untrack a null collider");return}if(t instanceof i9)for(let e of t.getColliders()){let t=this._colliders.indexOf(e);-1!==t&&this._colliders.splice(t,1),this._dynamicCollisionTree.untrackCollider(e)}else{let e=this._colliders.indexOf(t);-1!==e&&this._colliders.splice(e,1),this._dynamicCollisionTree.untrackCollider(t)}}_pairExists(t,e){let i=iq.calculatePairHash(t.id,e.id);return this._pairs.has(i)}broadphase(t,e,i){let s;let r=e/1e3,n=t.filter(t=>{var e,i;let s=null===(e=t.owner)||void 0===e?void 0:e.get(sh);return(null===(i=t.owner)||void 0===i?void 0:i.active)&&s.collisionType!==G.PreventCollision});this._collisionPairCache=[],this._pairs.clear();for(let t=0,e=n.length;t{if(!this._pairExists(s,t)&&iq.canCollide(s,t)){let e=new iq(s,t);this._pairs.add(e.id),this._collisionPairCache.push(e)}return!1});if(i&&(i.physics.pairs=this._collisionPairCache.length),this._config.continuous.checkForFastBodies)for(let t of n){let e=t.owner.get(sh);if(e.collisionType!==G.Active)continue;let s=e.vel.size*r+.5*e.acc.size*r*r,n=Math.min(t.bounds.height,t.bounds.width);if(this._config.continuous.disableMinimumSpeedForFastBody||s>n/2){let r;i&&i.physics.fastBodies++;let n=e.globalPos.sub(e.oldPos),o=t.center,a=t.getFurthestPoint(e.vel),l=a.sub(n),h=new iY(l,e.vel);h.pos=h.pos.add(h.dir.scale(-2*this._config.continuous.surfaceEpsilon));let d=new tN(1/0,1/0);if(this._dynamicCollisionTree.rayCastQuery(h,s+2*this._config.continuous.surfaceEpsilon,e=>{if(!this._pairExists(t,e)&&iq.canCollide(t,e)){let t=e.rayCast(h,s+10*this._config.continuous.surfaceEpsilon);if(t){let i=t.point.sub(l);i.size0)for(let t of r)e.physics.contacts.set(t.id,t)}return e&&(e.physics.collisions+=i.length),i}update(t){let e=0,i=t.length;for(let s=0;se.offset.addEqual(t.offset)):e=[t],e))i.events.pipe(this.events),i.composite=this,this._colliders.push(i),this._collisionProcessor.track(i),this._dynamicAABBTree.trackCollider(i)}removeCollider(t){t.events.pipe(this.events),t.composite=null,tK(t,this._colliders),this._collisionProcessor.untrack(t),this._dynamicAABBTree.untrackCollider(t)}getColliders(){return this._colliders}get worldPos(){var t,e;return(null!==(e=null===(t=this._transform)||void 0===t?void 0:t.pos)&&void 0!==e?e:tN.Zero).add(this.offset)}get center(){var t,e;return(null!==(e=null===(t=this._transform)||void 0===t?void 0:t.pos)&&void 0!==e?e:tN.Zero).add(this.offset)}get bounds(){var t,e;let i=this.getColliders();return i.reduce((t,e)=>t.combine(e.bounds),null!==(e=null===(t=i[0])||void 0===t?void 0:t.bounds)&&void 0!==e?e:new tq().translate(this.worldPos)).translate(this.offset)}get localBounds(){var t,e;let i=this.getColliders();return i.reduce((t,e)=>t.combine(e.localBounds),null!==(e=null===(t=i[0])||void 0===t?void 0:t.localBounds)&&void 0!==e?e:new tq)}get axes(){let t=this.getColliders(),e=[];for(let i of t)e=e.concat(i.axes);return e}getFurthestPoint(t){let e=this.getColliders(),i=[];for(let s of e)i.push(s.getFurthestPoint(t));let s=i[0],r=-Number.MAX_VALUE;for(let e of i){let i=e.dot(t);i>r&&(s=e,r=i)}return s}getInertia(t){let e=this.getColliders(),i=0;for(let s of e)i+=s.getInertia(t);return i}collide(t){let e=[t];t instanceof i9&&(e=t.getColliders());let i=[];for(let t of e)this._dynamicAABBTree.query(t,e=>(i.push(new iq(t,e)),!1));let s=[];for(let t of i)s=s.concat(t.collide());return s}getClosestLineBetween(t){let e=this.getColliders(),i=[];if(t instanceof i9){let s=t.getColliders();for(let t of e)for(let e of s){let s=t.getClosestLineBetween(e);s&&i.push(s)}}else for(let s of e){let e=t.getClosestLineBetween(s);e&&i.push(e)}if(i.length){let t=i[0].getLength(),e=i[0];for(let s of i){let i=s.getLength();it.clone()));return t.offset=this.offset.clone(),t}}class i6{constructor(t,e){this.begin=t,this.end=e}get slope(){return(this.end.y-this.begin.y)/(this.end.x-this.begin.x)}get intercept(){return this.begin.y-this.slope*this.begin.x}normal(){return this._normal?this._normal:this._normal=this.end.sub(this.begin).normal()}dir(){return this._dir?this._dir:this._dir=this.end.sub(this.begin)}getPoints(){return[this.begin,this.end]}getSlope(){if(this._slope)return this._slope;let t=this.begin,e=this.end,i=t.distance(e);return this._slope=e.sub(t).scale(1/i)}getEdge(){let t=this.begin;return this.end.sub(t)}getLength(){if(this._length)return this._length;let t=this.begin,e=this.end,i=t.distance(e);return this._length=i}get midpoint(){return this.begin.add(this.end).scale(.5)}flip(){return new i6(this.end,this.begin)}below(t){return(this.end.x-this.begin.x)*(t.y-this.begin.y)-(this.end.y-this.begin.y)*(t.x-this.begin.x)>=0}clip(t,e){let i=t,s=(i=i.normalize()).dot(this.begin)-e,r=i.dot(this.end)-e,n=[];return(s<=0&&n.push(this.begin),r<=0&&n.push(this.end),s*r<0&&n.push(this.begin.add(this.end.sub(this.begin).scale(s/(s-r)))),2!==n.length)?null:new i6(n[0],n[1])}distanceToPoint(t,e=!1){let i=t.x,s=t.y,r=this.getLength(),n=((this.end.y-this.begin.y)*i-(this.end.x-this.begin.x)*s+this.end.x*this.begin.y-this.end.y*this.begin.x)/r;return e?n:Math.abs(n)}findVectorToPoint(t){let e=this.begin.sub(t),i=this.getSlope();return e.sub(i.scale(e.dot(i)))}findPoint(t=null,e=null){let i=this.slope,s=this.intercept;if(null!==t)return new tN(t,i*t+s);if(null!==e)return new tN((e-s)/i,e);throw Error("You must provide an X or a Y value")}hasPoint(){let t;let e=0;if("number"==typeof arguments[0]&&"number"==typeof arguments[1])t=new tN(arguments[0],arguments[1]),e=arguments[2]||0;else if(arguments[0]instanceof tN)t=arguments[0],e=arguments[1]||0;else throw"Could not determine the arguments for Vector.hasPoint";let i=t.x-this.begin.x,s=t.y-this.begin.y,r=this.end.x-this.begin.x,n=this.end.y-this.begin.y;return!(Math.abs(i*n-s*r)>e)&&(Math.abs(r)>=Math.abs(n)?r>0?this.begin.x<=t.x&&t.x<=this.end.x:this.end.x<=t.x&&t.x<=this.begin.x:n>0?this.begin.y<=t.y&&t.y<=this.end.y:this.end.y<=t.y&&t.y<=this.begin.y)}}function i7(t,e,i,s){let r=t.sub(i),n=e.dot(e),o=e.dot(s),a=s.dot(s),l=e.dot(r),h=s.dot(r),d=n*a-o*o,c=d,u=d;if(0===d||d<=.01)return new i6(t,i.add(s.scale(l/o)));let p=o*h-a*l,g=n*h-o*l;return p<0?(p=0,g=h,u=a):p>c&&(p=c,g=h+o,u=a),g<0?(g=0,0>-l?p=0:-l>n?p=c:(p=-l,c=n)):g>u&&(g=u,-l+o<0?p=0:-l+o>n?p=c:(p=-l+o,c=n)),p=.001>Math.abs(p)?0:p/c,g=.001>Math.abs(g)?0:g/u,new i6(t.add(e.scale(p)),i.add(s.scale(g)))}let i8={PolygonPolygonClosestLine(t,e){let i=e.worldPos,s=i.sub(t.worldPos),r=s.negate(),n=new iY(t.worldPos,s),o=new iY(i,r),a=t.rayCast(n).point.add(n.dir.scale(.1)),l=e.rayCast(o).point.add(o.dir.scale(.1)),h=t.getClosestFace(a),d=e.getClosestFace(l),c=h.face.begin;return i7(c,h.face.getEdge(),d.face.begin,d.face.getEdge())},PolygonEdgeClosestLine(t,e){let i=e.worldPos.sub(t.worldPos),s=new iY(t.worldPos,i),r=t.rayCast(s).point.add(s.dir.scale(.1)),n=t.getClosestFace(r),o=n.face.begin,a=n.face.getEdge(),l=e.asLine();return i7(o,a,l.begin,l.getEdge())},PolygonCircleClosestLine(t,e){let i=e.worldPos,s=i.sub(t.worldPos),r=new iY(t.worldPos,s.normalize()),n=t.rayCast(r).point.add(r.dir.scale(.1)),o=t.getClosestFace(n),a=o.face.begin,l=o.face.getEdge(),h=(l.x*(i.x-a.x)+l.y*(i.y-a.y))/(l.x*l.x+l.y*l.y);h>1?h=1:h<0&&(h=0);let d=Math.sqrt(Math.pow(a.x+l.x*h-i.x,2)+Math.pow(a.y+l.y*h-i.y,2))-e.radius,c=(a.x+l.x*h-i.x)*e.radius/(e.radius+d),u=(a.y+l.y*h-i.y)*e.radius/(e.radius+d);return new i6(l.scale(h).add(a),new tN(i.x+c,i.y+u))},CircleCircleClosestLine(t,e){let i=e.worldPos.sub(t.worldPos),s=t.worldPos.sub(e.worldPos),r=new iY(t.worldPos,i),n=new iY(e.worldPos,s),o=t.rayCast(r),a=e.rayCast(n);return new i6(o.point,a.point)},CircleEdgeClosestLine(t,e){let i=t.worldPos,s=e.asLine(),r=s.begin,n=s.getEdge(),o=(n.x*(i.x-r.x)+n.y*(i.y-r.y))/(n.x*n.x+n.y*n.y);o>1?o=1:o<0&&(o=0);let a=Math.sqrt(Math.pow(r.x+n.x*o-i.x,2)+Math.pow(r.y+n.y*o-i.y,2))-t.radius,l=(r.x+n.x*o-i.x)*t.radius/(t.radius+a),h=(r.y+n.y*o-i.y)*t.radius/(t.radius+a);return new i6(n.scale(o).add(r),new tN(i.x+l,i.y+h))},EdgeEdgeClosestLine(t,e){let i=t.asLine(),s=i.begin,r=i.getEdge(),n=e.asLine();return i7(s,r,n.begin,n.getEdge())}};class st extends iJ{get worldPos(){return this._globalMatrix.getPosition()}get radius(){var t;let e=this._transform,i=null!==(t=null==e?void 0:e.globalScale)&&void 0!==t?t:tN.One;return this._naturalRadius*Math.min(i.x,i.y)}set radius(t){var e;let i=this._transform,s=null!==(e=null==i?void 0:i.globalScale)&&void 0!==e?e:tN.One;this._naturalRadius=t/Math.min(s.x,s.y)}constructor(t){super(),this.offset=tN.Zero,this._globalMatrix=t2.identity(),this.offset=t.offset||tN.Zero,this.radius=t.radius||0,this._globalMatrix.translate(this.offset.x,this.offset.y)}clone(){return new st({offset:this.offset.clone(),radius:this.radius})}get center(){return this._globalMatrix.getPosition()}contains(t){var e,i;return(null!==(i=null===(e=this._transform)||void 0===e?void 0:e.pos)&&void 0!==i?i:this.offset).distance(t)<=this.radius}rayCast(t,e=1/0){var i,s;let r=this.center,n=t.dir,o=t.pos,a=Math.sqrt(Math.pow(n.dot(o.sub(r)),2)-Math.pow(o.sub(r).distance(),2)+Math.pow(this.radius,2));if(a<0)return null;{let l=0;if(0===a){if((l=-n.dot(o.sub(r)))>0&&l=0&&h.push(i),l>=0&&h.push(l);let d=Math.min(...h);if(d<=e){let e=t.getPoint(d);return{point:e,normal:e.sub(r).normalize(),collider:this,body:null===(s=this.owner)||void 0===s?void 0:s.get(sh),distance:d}}return null}}}getClosestLineBetween(t){if(t instanceof st)return i8.CircleCircleClosestLine(this,t);if(t instanceof so)return i8.PolygonCircleClosestLine(t,this).flip();if(t instanceof sr)return i8.CircleEdgeClosestLine(this,t).flip();throw Error(`Polygon could not collide with unknown CollisionShape ${typeof t}`)}collide(t){if(t instanceof st)return ss.CollideCircleCircle(this,t);if(t instanceof so)return ss.CollideCirclePolygon(this,t);if(t instanceof sr)return ss.CollideCircleEdge(this,t);throw Error(`Circle could not collide with unknown CollisionShape ${typeof t}`)}getFurthestPoint(t){return this.center.add(t.normalize().scale(this.radius))}getFurthestLocalPoint(t){return t.normalize().scale(this.radius)}get bounds(){var t,e,i;let s=this._transform,r=null!==(t=null==s?void 0:s.globalScale)&&void 0!==t?t:tN.One,n=null!==(e=null==s?void 0:s.globalRotation)&&void 0!==e?e:0,o=null!==(i=null==s?void 0:s.globalPos)&&void 0!==i?i:tN.Zero;return new tq(this.offset.x-this._naturalRadius,this.offset.y-this._naturalRadius,this.offset.x+this._naturalRadius,this.offset.y+this._naturalRadius).rotate(n).scale(r).translate(o)}get localBounds(){return new tq(this.offset.x-this._naturalRadius,this.offset.y-this._naturalRadius,this.offset.x+this._naturalRadius,this.offset.y+this._naturalRadius)}get axes(){return[]}getInertia(t){return t*this.radius*this.radius/2}update(t){var e;this._transform=t,(null!==(e=t.matrix)&&void 0!==e?e:this._globalMatrix).clone(this._globalMatrix),this._globalMatrix.translate(this.offset.x,this.offset.y)}project(t){let e=[],i=this.center.dot(t);return e.push(i),e.push(i+this.radius),e.push(i-this.radius),new iX(Math.min.apply(Math,e),Math.max.apply(Math,e))}debug(t,e,i){var s,r,n,o;let{lineWidth:a}={lineWidth:1,...i},l=this._transform,h=null!==(s=null==l?void 0:l.globalScale)&&void 0!==s?s:tN.One,d=null!==(r=null==l?void 0:l.globalRotation)&&void 0!==r?r:0,c=null!==(n=null==l?void 0:l.globalPos)&&void 0!==n?n:tN.Zero;t.save(),t.translate(c.x,c.y),t.rotate(d),t.scale(h.x,h.y),t.drawCircle(null!==(o=this.offset)&&void 0!==o?o:tN.Zero,this._naturalRadius,tH.Transparent,e,a),t.restore()}}class se{constructor(t,e,i,s,r,n,o,a){var l,h,d,c,u,p;if(this._canceled=!1,this.colliderA=t,this.colliderB=e,this.mtv=i,this.normal=s,this.tangent=r,this.points=n,this.localPoints=o,this.info=a,this.id=iq.calculatePairHash(t.id,e.id),t.composite||e.composite){let i=(null===(l=t.composite)||void 0===l?void 0:l.compositeStrategy)==="separate"?t.id:null!==(d=null===(h=t.composite)||void 0===h?void 0:h.id)&&void 0!==d?d:t.id,s=(null===(c=e.composite)||void 0===c?void 0:c.compositeStrategy)==="separate"?e.id:null!==(p=null===(u=e.composite)||void 0===u?void 0:u.id)&&void 0!==p?p:e.id;this.id+="|"+iq.calculatePairHash(i,s)}}matchAwake(){let t=this.colliderA.owner.get(sh),e=this.colliderB.owner.get(sh);t&&e&&t.sleeping!==e.sleeping&&(t.sleeping&&t.collisionType!==G.Fixed&&e.sleepMotion>=t.wakeThreshold&&t.setSleeping(!1),e.sleeping&&e.collisionType!==G.Fixed&&t.sleepMotion>=e.wakeThreshold&&e.setSleeping(!1))}isCanceled(){return this._canceled}cancel(){this._canceled=!0}}class si{static findPolygonPolygonSeparation(t,e){let i=-Number.MAX_VALUE,s=null,r=null,n=-1,o=null,a=t.getSides(),l=t.getLocalSides();for(let t=0;ti&&(i=c,s=l,r=h,n=t,o=d)}return{collider:t,separation:r?i:99,axis:r,side:s,localSide:l[n],sideId:n,point:o,localPoint:r?e.getFurthestLocalPoint(r.negate()):null}}static findCirclePolygonSeparation(t,e){let i=e.axes,s=e.center.sub(t.worldPos),r=e.getFurthestPoint(s.negate());i.push(r.sub(t.worldPos).normalize());let n=Number.MAX_VALUE,o=null,a=-1;for(let s=0;sr)return[];let o=r-n,a=s.sub(i).normalize(),l=a.perpendicular(),h=a.scale(o),d=t.getFurthestPoint(a),c=t.getFurthestLocalPoint(a);return[new se(t,e,h,a,l,[d],[c],{collider:t,separation:o,axis:a,point:d})]},CollideCirclePolygon(t,e){var i,s;let r=si.findCirclePolygonSeparation(t,e);if(!r)return[];r=0>r.dot(e.center.sub(t.center))?r.negate():r;let n=t.getFurthestPoint(r),o=(null!==(s=null===(i=t.owner)||void 0===i?void 0:i.get(iV))&&void 0!==s?s:new iV).applyInverse(n),a=r.normalize(),l={collider:t,separation:-r.size,axis:a,point:n,localPoint:o,side:e.findSide(a.negate()),localSide:e.findLocalSide(a.negate())};return[new se(t,e,r,a,a.perpendicular(),[n],[o],l)]},CollideCircleEdge(t,e){let i=t.center,s=e.asLine(),r=s.end.sub(s.begin),n=r.dot(s.end.sub(i)),o=r.dot(i.sub(s.begin)),a=e.asLine(),l=e.asLocalLine();if(o<=0){let r=s.begin.sub(i),n=r.dot(r);if(n>t.radius*t.radius)return[];let o=r.normalize(),h=t.radius-Math.sqrt(n),d={collider:t,separation:h,axis:o,point:a.begin,side:a,localSide:l};return[new se(t,e,o.scale(h),o,o.perpendicular(),[a.begin],[l.begin],d)]}if(n<=0){let r=s.end.sub(i),n=r.dot(r);if(n>t.radius*t.radius)return[];let o=r.normalize(),h=t.radius-Math.sqrt(n),d={collider:t,separation:h,axis:o,point:a.end,side:a,localSide:l};return[new se(t,e,o.scale(h),o,o.perpendicular(),[a.end],[l.end],d)]}let h=r.dot(r),d=s.begin.scale(n).add(s.end.scale(o)).scale(1/h),c=i.sub(d),u=c.dot(c);if(u>t.radius*t.radius)return[];let p=r.perpendicular();0>p.dot(i.sub(s.begin))&&(p.x=-p.x,p.y=-p.y),p=p.normalize();let g=t.radius-Math.sqrt(u),_=p.scale(g),f={collider:t,separation:g,axis:p,point:d,side:a,localSide:l};return[new se(t,e,_,p.negate(),p.negate().perpendicular(),[d],[d.sub(e.worldPos)],f)]},CollideEdgeEdge:()=>[],CollidePolygonEdge(t,e){var i;let s=t.center,r=e.center.sub(s).normalize(),n=new so({points:[e.begin,e.end,e.end.add(r.scale(100)),e.begin.add(r.scale(100))],offset:e.offset});n.owner=e.owner,(null===(i=e.owner)||void 0===i?void 0:i.get(iV))&&n.update(e.owner.get(iV).get());let o=this.CollidePolygonPolygon(t,n);return o.length&&(o[0].colliderB=e,o[0].id=iq.calculatePairHash(t.id,e.id)),o},CollidePolygonPolygon(t,e){var i,s,r,n;let o=si.findPolygonPolygonSeparation(t,e);if(o.separation>0)return[];let a=si.findPolygonPolygonSeparation(e,t);if(a.separation>0)return[];let l=o.separation>a.separation?o:a,h=(l.collider===t?e:t).findSide(l.axis.negate()),d=l.side,c=d.dir().normalize(),u=h.clip(c.negate(),-c.dot(d.begin)),p=null;if(u&&(p=u.clip(c,c.dot(d.end))),p){let o=p.getPoints().filter(t=>d.below(t)),a=l.axis,h=a.perpendicular();0>e.center.sub(t.center).dot(a)&&(h=(a=a.negate()).perpendicular());let c=[];if(l.collider===t){let t=null!==(s=null===(i=e.owner)||void 0===i?void 0:i.get(iV))&&void 0!==s?s:new iV;c=o.map(e=>t.applyInverse(e))}else{let e=null!==(n=null===(r=t.owner)||void 0===r?void 0:r.get(iV))&&void 0!==n?n:new iV;c=o.map(t=>e.applyInverse(t))}return[new se(t,e,a.scale(-l.separation),a,h,o,c,l)]}return[]},FindContactSeparation(t,e){var i,s,r,n;let o=t.colliderA,a=null!==(s=null===(i=t.colliderA.owner)||void 0===i?void 0:i.get(iV))&&void 0!==s?s:new iV,l=t.colliderB,h=null!==(n=null===(r=t.colliderB.owner)||void 0===r?void 0:r.get(iV))&&void 0!==n?n:new iV;if(o instanceof st&&l instanceof st)return-(o.radius+l.radius-a.pos.distance(h.pos));if(o instanceof so&&l instanceof so&&t.info.localSide){let i,s;return t.info.collider===o?(i=new i6(a.apply(t.info.localSide.begin),a.apply(t.info.localSide.end)),s=h.apply(e)):(i=new i6(h.apply(t.info.localSide.begin),h.apply(t.info.localSide.end)),s=a.apply(e)),i.distanceToPoint(s,!0)}if(o instanceof so&&l instanceof st||l instanceof so&&o instanceof st){let i=a.apply(e);if(t.info.side)return t.info.side.distanceToPoint(i,!0)}if(o instanceof sr&&l instanceof so||l instanceof sr&&o instanceof so){let i;if(i=t.info.collider===o?h.apply(e):a.apply(e),t.info.side)return t.info.side.distanceToPoint(i,!0)}if(o instanceof st&&l instanceof sr||l instanceof st&&o instanceof sr){let i;let s=h.apply(e);o instanceof st&&(i=o.getFurthestPoint(t.normal));let r=s.distance(i);if(t.info.side)return r>0?-r:0}return 0}};class sr extends iJ{constructor(t){var e;super(),this._globalMatrix=t2.identity(),this.begin=t.begin||tN.Zero,this.end=t.end||tN.Zero,this.offset=null!==(e=t.offset)&&void 0!==e?e:tN.Zero}clone(){return new sr({begin:this.begin.clone(),end:this.end.clone()})}get worldPos(){var t;let e=this._transform;return null!==(t=null==e?void 0:e.globalPos.add(this.offset))&&void 0!==t?t:this.offset}get center(){let t=this._getTransformedBegin(),e=this._getTransformedEnd();return t.average(e)}_getTransformedBegin(){return this._globalMatrix.multiply(this.begin)}_getTransformedEnd(){return this._globalMatrix.multiply(this.end)}getSlope(){let t=this._getTransformedBegin(),e=this._getTransformedEnd(),i=t.distance(e);return e.sub(t).scale(1/i)}getLength(){let t=this._getTransformedBegin(),e=this._getTransformedEnd();return t.distance(e)}contains(){return!1}rayCast(t,e=1/0){var i;let s=this._getTransformedBegin().sub(t.pos);if(0===t.dir.cross(this.getSlope())&&0!==s.cross(t.dir))return null;let r=t.dir.cross(this.getSlope());if(0===r)return null;let n=s.cross(this.getSlope())/r;if(n>=0&&n<=e){let e=s.cross(t.dir)/r/this.getLength();if(e>=0&&e<=1)return{distance:n,normal:this.asLine().normal(),collider:this,body:null===(i=this.owner)||void 0===i?void 0:i.get(sh),point:t.getPoint(n)}}return null}getClosestLineBetween(t){if(t instanceof st)return i8.CircleEdgeClosestLine(t,this);if(t instanceof so)return i8.PolygonEdgeClosestLine(t,this).flip();if(t instanceof sr)return i8.EdgeEdgeClosestLine(this,t);throw Error(`Polygon could not collide with unknown CollisionShape ${typeof t}`)}collide(t){if(t instanceof st)return ss.CollideCircleEdge(t,this);if(t instanceof so)return ss.CollidePolygonEdge(t,this);if(t instanceof sr)return ss.CollideEdgeEdge();throw Error(`Edge could not collide with unknown CollisionShape ${typeof t}`)}getFurthestPoint(t){let e=this._getTransformedBegin(),i=this._getTransformedEnd();return t.dot(e)>0?e:i}_boundsFromBeginEnd(t,e,i=10){return new tq(Math.min(t.x,e.x)-i,Math.min(t.y,e.y)-i,Math.max(t.x,e.x)+i,Math.max(t.y,e.y)+i)}get bounds(){let t=this._getTransformedBegin(),e=this._getTransformedEnd();return this._boundsFromBeginEnd(t,e)}get localBounds(){return this._boundsFromBeginEnd(this.begin,this.end)}asLine(){return new i6(this._getTransformedBegin(),this._getTransformedEnd())}asLocalLine(){return new i6(this.begin,this.end)}get axes(){let t=this._getTransformedEnd().sub(this._getTransformedBegin()).normal(),e=[];return e.push(t),e.push(t.negate()),e.push(t.normal()),e.push(t.normal().negate()),e}getInertia(t){let e=this.end.sub(this.begin).distance()/2;return t*e*e}update(t){var e;this._transform=t,(null!==(e=t.matrix)&&void 0!==e?e:this._globalMatrix).clone(this._globalMatrix),this._globalMatrix.translate(this.offset.x,this.offset.y)}project(t){let e=[],i=[this._getTransformedBegin(),this._getTransformedEnd()],s=i.length;for(let r=0;r{i.debug.drawPoint(t,e)})}static drawLine(t,e,i){sn.draw(s=>{s.debug.drawLine(t,e,i)})}static drawLines(t,e){t.length>1&&sn.draw(i=>{for(let s=0;s{i.debug.drawText(t,e)})}static drawPolygon(t,e){t.length>1&&sn.draw(i=>{let s=t[0],r=[...t,s];for(let t=0;t{i.drawCircle(t,e,s,r,n)})}static drawBounds(t,e){sn.draw(i=>{i.debug.drawRect(t.left,t.top,t.width,t.height,e)})}static drawRay(t,e){let{distance:i,color:s}={color:tH.Blue,distance:10,...e};sn.draw(e=>{let r=t.pos,n=t.pos.add(t.dir.scale(i));e.debug.drawLine(r,n,{color:s})})}static flush(t){for(let e of(t.save(),t.z=sn.z,sn._drawCalls))e(t);t.restore(),sn.clear()}static clear(){sn._drawCalls.length=0}}sn._drawCalls=[],sn.z=1/0;class so extends iJ{flagDirty(){this._localBoundsDirty=!0,this._localSidesDirty=!0,this._transformedPointsDirty=!0,this._sidesDirty=!0}set points(t){this._points=t,this.flagDirty()}get points(){return this._points}constructor(t){var e,i;super(),this._logger=tW.getInstance(),this._transformedPoints=[],this._sides=[],this._localSides=[],this._globalMatrix=t2.identity(),this._transformedPointsDirty=!0,this._sidesDirty=!0,this._localSidesDirty=!0,this._localBoundsDirty=!0,this.offset=null!==(e=t.offset)&&void 0!==e?e:tN.Zero,this._globalMatrix.translate(this.offset.x,this.offset.y),this.points=null!==(i=t.points)&&void 0!==i?i:[],this._isCounterClockwiseWinding(this.points)||this.points.reverse(),this.isConvex()||t.suppressConvexWarning||this._logger.warn("Excalibur only supports convex polygon colliders and will not behave properly.Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles"),this._calculateTransformation()}_isCounterClockwiseWinding(t){let e=0;for(let i=0;iMath.PI&&(l-=2*Math.PI),0===o){if(0===l)return!1;r=l>0?1:-1}else if(r*l<=0)return!1;n+=l}return 1===Math.abs(Math.round(n/(2*Math.PI)))}tessellate(){let t=[];for(let e=1;esa.Polygon(t)))}triangulate(){if(this.points.length<3)throw Error("Invalid polygon");let t=[],e=[...this.points].reverse(),i=e.length;function s(t){return 0===t?i-1:t-1}function r(t){return t===i-1?0:t+1}function n(t){let i=s(t),n=r(t),o=e[i],a=e[t],l=e[n],h=o.sub(a),d=l.sub(a);return!(0>h.cross(d))}let o=e.map((t,e)=>n(e));for(;i>3;){!function(n){let a=s(n),l=r(n),h=e[a],d=e[n],c=e[l];t.push([h,d,c]),e.splice(n,1),o.splice(n,1),i--}(function(){for(let t=0;t0)&&!(c>0)&&!(u>0)}(e[s],a,l,h)){d=!1;break}if(d)return t}for(let t=0;tsa.Polygon(t,tN.Zero,!0)))}clone(){return new so({offset:this.offset.clone(),points:this.points.map(t=>t.clone())})}get worldPos(){return this._transform?this._transform.pos.add(this.offset):this.offset}get center(){return this.bounds.center}_calculateTransformation(){let t=this.points,e=t.length;this._transformedPoints.length=0;for(let i=0;is&&(i=n,s=o)}return i}findLocalSide(t){let e=this.getLocalSides(),i=e[0],s=-Number.MAX_VALUE;for(let r=0;rs&&(i=n,s=o)}return i}get axes(){let t=[],e=this.getSides();for(let i=0;i=0?t+1:t},0)%2!=0}getClosestLineBetween(t){if(t instanceof st)return i8.PolygonCircleClosestLine(this,t);if(t instanceof so)return i8.PolygonPolygonClosestLine(this,t);if(t instanceof sr)return i8.PolygonEdgeClosestLine(this,t);throw Error(`Polygon could not collide with unknown CollisionShape ${typeof t}`)}collide(t){if(t instanceof st)return ss.CollideCirclePolygon(t,this);if(t instanceof so)return ss.CollidePolygonPolygon(this,t);if(t instanceof sr)return ss.CollidePolygonEdge(this,t);throw Error(`Polygon could not collide with unknown CollisionShape ${typeof t}`)}getFurthestPoint(t){let e=this.getTransformedPoints(),i=null,s=-Number.MAX_VALUE;for(let r=0;rs&&(s=n,i=e[r])}return i}getFurthestLocalPoint(t){let e=this.points,i=e[0],s=-Number.MAX_VALUE;for(let r=0;rs&&(s=n,i=e[r])}return i}getClosestFace(t){let e=this.getSides(),i=Number.POSITIVE_INFINITY,s=-1,r=-1;for(let n=0;n=0&&n=0?{collider:this,distance:o,body:null===(i=this.owner)||void 0===i?void 0:i.get(sh),point:t.getPoint(o),normal:s.normal()}:null}project(t){let e=this.getTransformedPoints(),i=e.length,s=Number.MAX_VALUE,r=-Number.MAX_VALUE;for(let n=0;n=t)?[sa.Circle(t/2,tZ(0,-e/2+t/2).add(i)),sa.Box(t,e-t,tN.Half,i),sa.Circle(t/2,tZ(0,e/2-t/2).add(i))]:[sa.Circle(e/2,tZ(-t/2+e/2,0).add(i)),sa.Box(t-e,e,tN.Half,i),sa.Circle(e/2,tZ(t/2-e/2,0).add(i))])}}class sl extends iZ{constructor(t){super(),this.events=new tP,this.$colliderAdded=new iH,this.$colliderRemoved=new iH,this._collidersToRemove=[],this.set(t)}get(){return this._collider}set(t){return this.clear(),t&&(this._collider=t,this._collider.owner=this.owner,t.events.pipe(this.events),this.$colliderAdded.notifyAll(t),this.update()),t}clear(){this._collider&&(this._collidersToRemove.push(this._collider),this._collider=null)}processColliderRemoval(){for(let t of this._collidersToRemove)t.events.unpipe(this.events),this.$colliderRemoved.notifyAll(t),t.owner=null}clone(){return new sl(this._collider.clone())}get bounds(){var t,e;return null!==(e=null===(t=this._collider)||void 0===t?void 0:t.bounds)&&void 0!==e?e:new tq}get localBounds(){var t,e;return null!==(e=null===(t=this._collider)||void 0===t?void 0:t.localBounds)&&void 0!==e?e:new tq}update(){var t;let e=null===(t=this.owner)||void 0===t?void 0:t.get(iV);this._collider&&(this._collider.owner=this.owner,e&&this._collider.update(e.get()))}collide(t){let e=this._collider,i=t._collider;if(!e||!i)return[];let s=!1;if(i instanceof i9&&(e=i,i=this._collider,s=!0),this._collider){let r=e.collide(i);if(r)return s&&r.forEach(e=>{e.mtv=e.mtv.negate(),e.normal=e.normal.negate(),e.tangent=e.normal.perpendicular(),e.colliderA=this._collider,e.colliderB=t._collider}),r}return[]}onAdd(t){this._collider&&this.update(),this.events.on("precollision",e=>{t.events.emit("precollision",new ie(e.target.owner,e.other.owner,e.side,e.intersection,e.contact)),t instanceof sj&&t.onPreCollisionResolve(e.target,e.other,e.side,e.contact)}),this.events.on("postcollision",e=>{t.events.emit("postcollision",new ii(e.target.owner,e.other.owner,e.side,e.intersection,e.contact)),t instanceof sj&&t.onPostCollisionResolve(e.target,e.other,e.side,e.contact)}),this.events.on("collisionstart",e=>{t.events.emit("collisionstart",new il(e.target.owner,e.other.owner,e.side,e.contact)),t instanceof sj&&t.onCollisionStart(e.target,e.other,e.side,e.contact)}),this.events.on("collisionend",e=>{t.events.emit("collisionend",new ih(e.target.owner,e.other.owner,e.side,e.lastContact)),t instanceof sj&&t.onCollisionEnd(e.target,e.other,e.side,e.lastContact)})}onRemove(){this.events.clear(),this.$colliderRemoved.notifyAll(this._collider)}useBoxCollider(t,e,i=tN.Half,s=tN.Zero){let r=sa.Box(t,e,i,s);return this.set(r)}usePolygonCollider(t,e=tN.Zero){let i=sa.Polygon(t,e);return this.set(i)}useCircleCollider(t,e=tN.Zero){let i=sa.Circle(t,e);return this.set(i)}useEdgeCollider(t,e){let i=sa.Edge(t,e);return this.set(i)}useCompositeCollider(t){return this.set(new i9(t))}}(f=Y||(Y={})).Rotation="rotation",f.X="x",f.Y="y";class sh extends iZ{constructor(t){var e,i,s;super(),this.dependencies=[iV,iW],this.id=tA("body",sh._ID++),this.events=new tP,this.oldTransform=new iU,this.__oldTransformCaptured=!1,this.enableFixedUpdateInterpolate=!0,this.collisionType=G.PreventCollision,this.group=ij.All,this._sleeping=!1,this.bounciness=.2,this.friction=.99,this.useGravity=!0,this.limitDegreeOfFreedom=[],this.oldVel=new tN(0,0),this.oldAcc=tN.Zero,t?(this.collisionType=null!==(e=t.type)&&void 0!==e?e:this.collisionType,this.group=null!==(i=t.group)&&void 0!==i?i:this.group,this.useGravity=null!==(s=t.useGravity)&&void 0!==s?s:this.useGravity,this._bodyConfig={...i4.bodies,...t.config}):this._bodyConfig={...i4.bodies},this.updatePhysicsConfig(this._bodyConfig),this._mass=sh._DEFAULT_CONFIG.defaultMass}get matrix(){return this.transform.get().matrix}updatePhysicsConfig(t){this._bodyConfig={...i4.bodies,...t},this.canSleep=this._bodyConfig.canSleepByDefault,this.sleepMotion=5*this._bodyConfig.sleepEpsilon,this.wakeThreshold=this._bodyConfig.wakeThreshold}static updateDefaultPhysicsConfig(t){sh._DEFAULT_CONFIG=t}get mass(){return this._mass}set mass(t){this._mass=t,this._cachedInertia=void 0,this._cachedInverseInertia=void 0}get inverseMass(){return this.collisionType===G.Fixed?0:1/this.mass}get sleeping(){return this._sleeping}setSleeping(t){this._sleeping=t,t?(this.vel=tN.Zero,this.acc=tN.Zero,this.angularVelocity=0,this.sleepMotion=0):this.sleepMotion=5*this._bodyConfig.sleepEpsilon}updateMotion(){this._sleeping&&this.setSleeping(!0);let t=this.vel.size*this.vel.size+Math.abs(this.angularVelocity*this.angularVelocity),e=this._bodyConfig.sleepBias;this.sleepMotion=e*this.sleepMotion+(1-e)*t,this.sleepMotion=tF(this.sleepMotion,0,10*this._bodyConfig.sleepEpsilon),this.canSleep&&this.sleepMotion{this._cachedInertia=null}),t.$colliderRemoved.subscribe(()=>{this._cachedInertia=null});let e=t.get();if(e)return this._cachedInertia=e.getInertia(this.mass)}return 0}get inverseInertia(){return this._cachedInverseInertia?this._cachedInverseInertia:this._cachedInverseInertia=this.collisionType===G.Fixed?0:1/this.inertia}get active(){var t;return!!(null===(t=this.owner)||void 0===t?void 0:t.active)}get center(){return this.globalPos}get transform(){var t;return null===(t=this.owner)||void 0===t?void 0:t.get(iV)}get motion(){var t;return null===(t=this.owner)||void 0===t?void 0:t.get(iW)}get pos(){return this.transform.pos}set pos(t){this.transform.pos=t}get globalPos(){return this.transform.globalPos}set globalPos(t){this.transform.globalPos=t}get oldPos(){return this.oldTransform.pos}get vel(){return this.motion.vel}set vel(t){this.motion.vel=t}get acc(){return this.motion.acc}set acc(t){this.motion.acc=t}get torque(){return this.motion.torque}set torque(t){this.motion.torque=t}get oldRotation(){return this.oldTransform.rotation}get rotation(){return this.transform.globalRotation}set rotation(t){this.transform.globalRotation=t}get scale(){return this.transform.globalScale}set scale(t){this.transform.globalScale=t}get oldScale(){return this.oldTransform.scale}get scaleFactor(){return this.motion.scaleFactor}set scaleFactor(t){this.motion.scaleFactor=t}get angularVelocity(){return this.motion.angularVelocity}set angularVelocity(t){this.motion.angularVelocity=t}applyImpulse(t,e){if(this.collisionType!==G.Active)return;let i=e.scale(this.inverseMass);if(this.limitDegreeOfFreedom.includes(Y.X)&&(i.x=0),this.limitDegreeOfFreedom.includes(Y.Y)&&(i.y=0),this.vel.addEqual(i),!this.limitDegreeOfFreedom.includes(Y.Rotation)){let i=t.sub(this.globalPos);this.angularVelocity+=this.inverseInertia*i.cross(e)}}applyLinearImpulse(t){if(this.collisionType!==G.Active)return;let e=t.scale(this.inverseMass);this.limitDegreeOfFreedom.includes(Y.X)&&(e.x=0),this.limitDegreeOfFreedom.includes(Y.Y)&&(e.y=0),this.vel=this.vel.add(e)}applyAngularImpulse(t,e){if(this.collisionType===G.Active&&!this.limitDegreeOfFreedom.includes(Y.Rotation)){let i=t.sub(this.globalPos);this.angularVelocity+=this.inverseInertia*i.cross(e)}}captureOldTransform(){this.__oldTransformCaptured=!0;let t=this.transform.get();t.clone(this.oldTransform),this.oldTransform.parent=t.parent,this.oldVel.setTo(this.vel.x,this.vel.y),this.oldAcc.setTo(this.acc.x,this.acc.y)}clone(){return super.clone()}}sh._ID=0,sh._DEFAULT_CONFIG={...i4.bodies};class sd{constructor(t){this.data=t,this.type="Component Added"}}function sc(t){return!!t&&"Component Added"===t.type}class su{constructor(t){this.data=t,this.type="Component Removed"}}function sp(t){return!!t&&"Component Removed"===t.type}let sg={Initialize:"initialize",PreUpdate:"preupdate",PostUpdate:"postupdate",Kill:"kill"};class s_{constructor(t,e){let i,s;if(this.id=s_._ID++,this.name=`Entity#${this.id}`,this.events=new tP,this._tags=new Set,this.componentAdded$=new iH,this.componentRemoved$=new iH,this.tagAdded$=new iH,this.tagRemoved$=new iH,this.components=new Map,this._componentsToRemove=[],this._instanceOfComponentCacheDirty=!0,this._instanceOfComponentCache=new Map,this.scene=null,this.active=!0,this._parent=null,this.childrenAdded$=new iH,this.childrenRemoved$=new iH,this._children=[],this._isInitialized=!1,Array.isArray(t))i=t,s=e;else if(t&&"object"==typeof t){let{components:e,name:r}=t;i=e,s=r}if(s&&(this.name=s),i)for(let t of i)this.addComponent(t)}kill(){this.active&&(this.active=!1,this.unparent()),this.emit("kill",new eW(this))}isKilled(){return!this.active}get tags(){return this._tags}hasTag(t){return this._tags.has(t)}addTag(t){this._tags.add(t),this.tagAdded$.notifyAll(t)}removeTag(t){this._tags.delete(t),this.tagRemoved$.notifyAll(t)}get types(){return Array.from(this.components.keys())}getComponents(){return Array.from(this.components.values())}hasAll(t){for(let e=0;e=0;t--)this.removeChild(this.children[t]);return this}getAncestors(){let t=[this],e=this.parent;for(;e;)t.push(e),e=e.parent;return t.reverse()}getDescendants(){let t=[this],e=[this];for(;e.length>0;){let i=e.pop();i&&(e=e.concat(i.children),t=t.concat(i.children))}return t}clone(){let t=new s_;for(let e of this.types){let i=this.get(e);i&&t.addComponent(i.clone())}for(let e of this.children)t.addChild(e.clone());return t}addTemplate(t,e=!1){for(let i of t.getComponents())this.addComponent(i.clone(),e);for(let e of t.children)this.addChild(e.clone().addTemplate(e));return this}addComponent(t,e=!1){if(this._instanceOfComponentCacheDirty=!0,this.has(t.constructor)){if(!e)return this;this.removeComponent(t.constructor,!0)}if(t.dependencies&&t.dependencies.length)for(let e of t.dependencies)this.addComponent(new e);return t.owner=this,this.components.set(t.constructor,t),t.onAdd&&t.onAdd(this),this.componentAdded$.notifyAll(t),this}removeComponent(t,e=!1){let i;if(i=iN(t)?t:t.constructor,e){let t=this.components.get(i);t&&(this.componentRemoved$.notifyAll(t),t.owner=void 0,t.onRemove&&t.onRemove(this)),this.components.delete(i),this._instanceOfComponentCacheDirty=!0}else this._componentsToRemove.push(i);return this}clearComponents(){for(let t of this.types)this.removeComponent(t)}processComponentRemoval(){for(let t of this._componentsToRemove)this.removeComponent(t,!0);this._componentsToRemove.length=0}has(t){return this.components.has(t)}get isInitialized(){return this._isInitialized}_initialize(t){this.isInitialized||(this.onInitialize(t),this.events.emit("initialize",new id(t,this)),this._isInitialized=!0)}_preupdate(t,e){this.events.emit("preupdate",new e1(t,e,this)),this.onPreUpdate(t,e)}_postupdate(t,e){this.events.emit("postupdate",new e2(t,e,this)),this.onPostUpdate(t,e)}onInitialize(t){}onPreUpdate(t,e){}onPostUpdate(t,e){}update(t,e){for(let i of(this._initialize(t),this._preupdate(t,e),this.children))i.update(t,e);this._postupdate(t,e)}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){e?this.events.off(t,e):this.events.off(t)}}function sf(t){return!!t.tick}s_._ID=0;class sm extends iZ{get offset(){return new iO(this._offset,()=>{this.recalculateBounds()})}set offset(t){this._offset=t,this.recalculateBounds()}get anchor(){return new iO(this._anchor,()=>{this.recalculateBounds()})}set anchor(t){this._anchor=t,this.recalculateBounds()}constructor(t){super(),this._logger=tW.getInstance(),this._current="default",this._graphics={},this._options={},this.material=null,this.visible=!0,this.opacity=1,this._offset=tN.Zero,this._anchor=tN.Half,this.flipHorizontal=!1,this.flipVertical=!1,this.copyGraphics=!1,this._localBounds=null;let{current:e,anchor:i,opacity:s,visible:r,graphics:n,offset:o,copyGraphics:a,onPreDraw:l,onPostDraw:h,onPreTransformDraw:d,onPostTransformDraw:c}=t={visible:this.visible,graphics:{},...t};for(let[t,e]of Object.entries(n))e instanceof et?this._graphics[t]=e:(this._graphics[t]=e.graphic,this._options[t]=e.options);this.offset=null!=o?o:this.offset,this.opacity=null!=s?s:this.opacity,this.anchor=null!=i?i:this.anchor,this.copyGraphics=null!=a?a:this.copyGraphics,this.onPreDraw=null!=l?l:this.onPreDraw,this.onPostDraw=null!=h?h:this.onPostDraw,this.onPreDraw=null!=d?d:this.onPreTransformDraw,this.onPostTransformDraw=null!=c?c:this.onPostTransformDraw,this.visible=!!r,this._current=null!=e?e:this._current,e&&this._graphics[e]&&this.use(e)}getGraphic(t){return this._graphics[t]}getOptions(t){return this._options[t]}getNames(){return Object.keys(this._graphics)}get current(){return this._graphics[this._current]}get currentOptions(){return this._options[this._current]}get graphics(){return this._graphics}get options(){return this._options}add(t,e,i){let s,r="default",n=null;return"string"==typeof t&&e instanceof et&&(r=t,n=e,s=i),t instanceof et&&!(e instanceof et)&&(n=t,s=e),this._graphics[r]=this.copyGraphics?n.clone():n,this._options[r]=this.copyGraphics?{...s}:s,"default"===r&&this.use("default"),n}remove(t){delete this._graphics[t],delete this._options[t],this._current===t&&(this._current="default",this.recalculateBounds())}show(t,e){return this.use(t,e)}use(t,e){var i;if(t instanceof et){let i=t;this.copyGraphics&&(i=t.clone()),this._current="default",this._graphics[this._current]=i,this._options[this._current]=e}else this._current=t,this._options[this._current]=e,this._current in this._graphics||this._logger.warn(`Graphic ${this._current} is not registered with the graphics component owned by ${null===(i=this.owner)||void 0===i?void 0:i.name}. Nothing will be drawn.`);return this.recalculateBounds(),this.current}hide(){this._current="ex.none"}set localBounds(t){this._localBounds=t}recalculateBounds(){let t=new tq,e=this._graphics[this._current],i=this._options[this._current];if(!e){this._localBounds=t;return}let s=this.anchor,r=this.offset;(null==i?void 0:i.anchor)&&(s=i.anchor),(null==i?void 0:i.offset)&&(r=i.offset);let n=e.localBounds,o=-n.width*s.x+r.x,a=-n.height*s.y+r.y;t=null==e?void 0:e.localBounds.translate(tZ(o,a)).combine(t),this._localBounds=t}get localBounds(){return(!this._localBounds||this._localBounds.hasZeroDimensions())&&this.recalculateBounds(),this._localBounds}update(t,e=0){let i=this.current;i&&sf(i)&&i.tick(t,e)}clone(){let t=new sm;return t._graphics={...this._graphics},t._options={...this._options},t.offset=this.offset.clone(),t.opacity=this.opacity,t.anchor=this.anchor.clone(),t.copyGraphics=this.copyGraphics,t.onPreDraw=this.onPreDraw,t.onPostDraw=this.onPostDraw,t.visible=this.visible,t}}class sv extends eO{constructor(t){super(t),this.width=t.width,this.height=t.height,this.rasterize()}clone(){return new sv({width:this.width,height:this.height,...this.cloneGraphicOptions(),...this.cloneRasterOptions()})}execute(t){this.color&&t.fillRect(0,0,this.width,this.height),this.strokeColor&&t.strokeRect(0,0,this.width,this.height)}}class sy extends eO{get radius(){return this._radius}set radius(t){this._radius=t,this.width=2*this._radius,this.height=2*this._radius,this.flagDirty()}constructor(t){var e,i,s;super(t),this._radius=0;let r=null!==(e=t.lineWidth)&&void 0!==e?e:t.strokeColor?1:0;this.padding=null!==(i=t.padding)&&void 0!==i?i:2+r/2,this.radius=t.radius,this.filtering=null!==(s=t.filtering)&&void 0!==s?s:H.Blended,this.rasterize()}clone(){return new sy({radius:this.radius,...this.cloneGraphicOptions(),...this.cloneRasterOptions()})}execute(t){this.radius>0&&(t.beginPath(),t.arc(this.radius,this.radius,this.radius,0,2*Math.PI),this.color&&t.fill(),this.strokeColor&&t.stroke())}}class sx extends iZ{constructor(){super(...arguments),this.useColliderShape=!0,this.useGraphicsBounds=!0}}class sw{static CreateReversibleEasingFunction(t){return(e,i,s,r)=>snew tN(t(e,i.x,s.x,r),t(e,i.y,s.y,r))}}sw.Linear=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e)*t/s+e),sw.EaseInQuad=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e)*(t/=s)*t+e),sw.EaseOutQuad=sw.CreateReversibleEasingFunction((t,e,i,s)=>-(i-=e)*(t/=s)*(t-2)+e),sw.EaseInOutQuad=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e,(t/=s/2)<1)?i/2*t*t+e:-i/2*(--t*(t-2)-1)+e),sw.EaseInCubic=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e)*(t/=s)*t*t+e),sw.EaseOutCubic=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e,t/=s,i*(--t*t*t+1)+e)),sw.EaseInOutCubic=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e,(t/=s/2)<1)?i/2*t*t*t+e:i/2*((t-=2)*t*t+2)+e);class sb{constructor(t){this._actions=[],this._currentAction=null,this._completedActions=[],this._entity=t}add(t){this._actions.push(t)}remove(t){let e=this._actions.indexOf(t);this._actions.splice(e,1)}clearActions(){this._actions.length=0,this._completedActions.length=0,this._currentAction&&this._currentAction.stop()}getActions(){return this._actions.concat(this._completedActions)}hasNext(){return this._actions.length>0}isComplete(){return 0===this._actions.length}reset(){this._actions=this.getActions();let t=this._actions.length;for(let e=0;e0&&(this._currentAction!==this._actions[0]&&(this._currentAction=this._actions[0],this._entity.emit("actionstart",new iv(this._currentAction,this._entity))),this._currentAction.update(t),this._currentAction.isComplete(this._entity))){this._entity.emit("actioncomplete",new iy(this._currentAction,this._entity));let t=this._actions.shift();t&&this._completedActions.push(t)}}}class sC{constructor(t,e,i){this._stopped=!1,this._repeatBuilder=e,this._repeatContext=new sN(t),this._actionQueue=this._repeatContext.getQueue(),this._repeat=i,this._originalRepeat=i,this._repeatBuilder(this._repeatContext),this._repeat--}update(t){this._actionQueue.isComplete()&&(this._actionQueue.clearActions(),this._repeatBuilder(this._repeatContext),this._repeat--),this._actionQueue.update(t)}isComplete(){return this._stopped||this._repeat<=0&&this._actionQueue.isComplete()}stop(){this._stopped=!0}reset(){this._repeat=this._originalRepeat}}class sT{constructor(t,e){this._stopped=!1,this._repeatBuilder=e,this._repeatContext=new sN(t),this._actionQueue=this._repeatContext.getQueue(),this._repeatBuilder(this._repeatContext)}update(t){this._stopped||(this._actionQueue.isComplete()&&(this._actionQueue.clearActions(),this._repeatBuilder(this._repeatContext)),this._actionQueue.update(t))}isComplete(){return this._stopped}stop(){this._stopped=!0,this._actionQueue.clearActions()}reset(){}}class sS{constructor(t,e,i,s){if(this._started=!1,this._stopped=!1,this._entity=t,this._tx=t.get(iV),this._motion=t.get(iW),this._speed=s,this._offset=new tN(e,i),s<=0)throw tW.getInstance().error("Attempted to moveBy with speed less than or equal to zero : "+s),Error("Speed must be greater than 0 pixels per second")}update(t){this._started||(this._started=!0,this._start=new tN(this._tx.pos.x,this._tx.pos.y),this._end=this._start.add(this._offset),this._distance=this._offset.size,this._dir=this._end.sub(this._start).normalize()),this.isComplete(this._entity)?(this._tx.pos=tZ(this._end.x,this._end.y),this._motion.vel=tZ(0,0)):this._motion.vel=this._dir.scale(this._speed)}isComplete(t){let e=t.get(iV);return this._stopped||e.pos.distance(this._start)>=this._distance}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sA{constructor(t,e,i,s){this.entity=t,this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._end=new tN(e,i),this._speed=s}update(t){this._started||(this._started=!0,this._start=new tN(this._tx.pos.x,this._tx.pos.y),this._distance=this._start.distance(this._end),this._dir=this._end.sub(this._start).normalize());let e=this._dir.scale(this._speed);this._motion.vel=tZ(e.x,e.y),this.isComplete(this.entity)&&(this._tx.pos=tZ(this._end.x,this._end.y),this._motion.vel=tZ(0,0))}isComplete(t){let e=t.get(iV);return this._stopped||new tN(e.pos.x,e.pos.y).distance(this._start)>=this._distance}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}(m=Q||(Q={}))[m.ShortestPath=0]="ShortestPath",m[m.LongestPath=1]="LongestPath",m[m.Clockwise=2]="Clockwise",m[m.CounterClockwise=3]="CounterClockwise";class sE{constructor(t,e,i,s){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._end=e,this._speed=i,this._rotationType=s||Q.ShortestPath}update(t){if(!this._started){this._started=!0,this._start=this._tx.rotation,this._currentNonCannonAngle=this._tx.rotation;let t=Math.abs(this._end-this._start),e=tk-t;switch(t>e?(this._shortDistance=e,this._longDistance=t):(this._shortDistance=t,this._longDistance=e),this._shortestPathIsPositive=(this._start-this._end+tk)%tk>=Math.PI,this._rotationType){case Q.ShortestPath:this._distance=this._shortDistance,this._shortestPathIsPositive?this._direction=1:this._direction=-1;break;case Q.LongestPath:this._distance=this._longDistance,this._shortestPathIsPositive?this._direction=-1:this._direction=1;break;case Q.Clockwise:this._direction=1,this._shortestPathIsPositive?this._distance=this._shortDistance:this._distance=this._longDistance;break;case Q.CounterClockwise:this._direction=-1,this._shortestPathIsPositive?this._distance=this._longDistance:this._distance=this._shortDistance}}this._motion.angularVelocity=this._direction*this._speed,this._currentNonCannonAngle+=this._direction*this._speed*(t/1e3),this.isComplete()&&(this._tx.rotation=this._end,this._motion.angularVelocity=0,this._stopped=!0)}isComplete(){let t=Math.abs(this._currentNonCannonAngle-this._start);return this._stopped||t>=Math.abs(this._distance)}stop(){this._motion.angularVelocity=0,this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sP{constructor(t,e,i,s){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._speed=i,this._offset=e,this._rotationType=s||Q.ShortestPath}update(t){if(!this._started){this._started=!0,this._start=this._tx.rotation,this._currentNonCannonAngle=this._tx.rotation,this._end=this._start+this._offset;let t=Math.abs(this._end-this._start),e=tk-t;switch(t>e?(this._shortDistance=e,this._longDistance=t):(this._shortDistance=t,this._longDistance=e),this._shortestPathIsPositive=(this._start-this._end+tk)%tk>=Math.PI,this._rotationType){case Q.ShortestPath:this._distance=this._shortDistance,this._shortestPathIsPositive?this._direction=1:this._direction=-1;break;case Q.LongestPath:this._distance=this._longDistance,this._shortestPathIsPositive?this._direction=-1:this._direction=1;break;case Q.Clockwise:this._direction=1,this._shortDistance>=0?this._distance=this._shortDistance:this._distance=this._longDistance;break;case Q.CounterClockwise:this._direction=-1,this._shortDistance<=0?this._distance=this._shortDistance:this._distance=this._longDistance}}this._motion.angularVelocity=this._direction*this._speed,this._currentNonCannonAngle+=this._direction*this._speed*(t/1e3),this.isComplete()&&(this._tx.rotation=this._end,this._motion.angularVelocity=0,this._stopped=!0)}isComplete(){let t=Math.abs(this._currentNonCannonAngle-this._start);return this._stopped||t>=Math.abs(this._distance)}stop(){this._motion.angularVelocity=0,this._stopped=!0}reset(){this._started=!1,this._stopped=!1,this._start=void 0,this._currentNonCannonAngle=void 0,this._distance=void 0}}class sI{constructor(t,e,i,s,r){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._endX=e,this._endY=i,this._speedX=s,this._speedY=r}update(t){if(this._started||(this._started=!0,this._startX=this._tx.scale.x,this._startY=this._tx.scale.y,this._distanceX=Math.abs(this._endX-this._startX),this._distanceY=Math.abs(this._endY-this._startY)),Math.abs(this._tx.scale.x-this._startX)>=this._distanceX)this._motion.scaleFactor.x=0;else{let t=this._endY=this._distanceY)this._motion.scaleFactor.y=0;else{let t=this._endY=this._distanceX-.01&&Math.abs(this._tx.scale.y-this._startY)>=this._distanceY-.01}stop(){this._motion.scaleFactor.x=0,this._motion.scaleFactor.y=0,this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sk{constructor(t,e,i,s){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._offset=new tN(e,i),this._speedX=this._speedY=s}update(t){this._started||(this._started=!0,this._startScale=this._tx.scale.clone(),this._endScale=this._startScale.add(this._offset),this._distanceX=Math.abs(this._endScale.x-this._startScale.x),this._distanceY=Math.abs(this._endScale.y-this._startScale.y),this._directionX=this._endScale.x=this._distanceX-.01&&Math.abs(this._tx.scale.y-this._startScale.y)>=this._distanceY-.01}stop(){this._motion.scaleFactor.x=0,this._motion.scaleFactor.y=0,this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sD{constructor(t){this._method=null,this._hasBeenCalled=!1,this._method=t}update(t){this._method(),this._hasBeenCalled=!0}isComplete(){return this._hasBeenCalled}reset(){this._hasBeenCalled=!1}stop(){this._hasBeenCalled=!0}}class sR{constructor(t,e,i,s,r){this.easingFcn=r,this._currentLerpTime=0,this._lerpDuration=1e3,this._lerpStart=new tN(0,0),this._lerpEnd=new tN(0,0),this._initialized=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._lerpDuration=s,this._lerpEnd=new tN(e,i)}_initialize(){this._lerpStart=new tN(this._tx.pos.x,this._tx.pos.y),this._currentLerpTime=0}update(t){this._initialized||(this._initialize(),this._initialized=!0),this._currentLerpTime+=t;let e=this._tx.pos.x,i=this._tx.pos.y;this._currentLerpTime=this._lerpDuration}reset(){this._initialized=!1,this._stopped=!1,this._currentLerpTime=0}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}}class sF{constructor(t,e,i,s,r){this.easingFcn=r,this._currentLerpTime=0,this._lerpDuration=1e3,this._lerpStart=new tN(0,0),this._lerpEnd=new tN(0,0),this._initialized=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._lerpDuration=s,this._offset=new tN(e,i)}_initialize(){this._lerpStart=new tN(this._tx.pos.x,this._tx.pos.y),this._currentLerpTime=0,this._lerpEnd=this._lerpStart.add(this._offset)}update(t){this._initialized||(this._initialize(),this._initialized=!0),this._currentLerpTime+=t;let e=this._tx.pos.x,i=this._tx.pos.y;this._currentLerpTime=this._lerpDuration}reset(){this._initialized=!1,this._stopped=!1,this._currentLerpTime=0}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}}class sB{constructor(t,e,i,s=1){this._timeVisible=0,this._timeNotVisible=0,this._elapsedTime=0,this._totalTime=0,this._stopped=!1,this._started=!1,this._graphics=t.get(sm),this._timeVisible=e,this._timeNotVisible=i,this._duration=(e+i)*s}update(t){this._started||(this._started=!0,this._elapsedTime=0,this._totalTime=0),this._graphics&&(this._elapsedTime+=t,this._totalTime+=t,this._graphics.visible&&this._elapsedTime>=this._timeVisible&&(this._graphics.visible=!1,this._elapsedTime=0),!this._graphics.visible&&this._elapsedTime>=this._timeNotVisible&&(this._graphics.visible=!0,this._elapsedTime=0),this.isComplete()&&(this._graphics.visible=!0))}isComplete(){return this._stopped||this._totalTime>=this._duration}stop(){this._graphics&&(this._graphics.visible=!0),this._stopped=!0}reset(){this._started=!1,this._stopped=!1,this._elapsedTime=0,this._totalTime=0}}class sM{constructor(t,e,i){this._multiplier=1,this._started=!1,this._stopped=!1,this._graphics=t.get(sm),this._endOpacity=e,this._speed=this._ogspeed=i}update(t){this._graphics&&(this._started||(this._started=!0,this._speed=this._ogspeed,this._endOpacity0&&(this._graphics.opacity+=this._multiplier*(Math.abs(this._graphics.opacity-this._endOpacity)*t)/this._speed),this._speed-=t,this.isComplete()&&(this._graphics.opacity=this._endOpacity),tW.getInstance().debug("[Action fade] Actor opacity:",this._graphics.opacity))}isComplete(){return this._stopped||.05>Math.abs(this._graphics.opacity-this._endOpacity)}stop(){this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sL{constructor(t){this._elapsedTime=0,this._started=!1,this._stopped=!1,this._delay=t}update(t){this._started||(this._started=!0),this._elapsedTime+=t}isComplete(){return this._stopped||this._elapsedTime>=this._delay}stop(){this._stopped=!0}reset(){this._elapsedTime=0,this._started=!1,this._stopped=!1}}class sz{constructor(t){this._stopped=!1,this._entity=t}update(t){this._entity.get(sZ).clearActions(),this._entity.kill(),this._stopped=!0}isComplete(){return this._stopped}stop(){}reset(){}}class sO{constructor(t,e,i){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._followTx=e.get(iV),this._followMotion=e.get(iW),this._current=new tN(this._tx.pos.x,this._tx.pos.y),this._end=new tN(this._followTx.pos.x,this._followTx.pos.y),this._maximumDistance=void 0!==i?i:this._current.distance(this._end),this._speed=0}update(t){this._started||(this._started=!0,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.sub(this._current).normalize());let e=Math.sqrt(Math.pow(this._followMotion.vel.x,2)+Math.pow(this._followMotion.vel.y,2));if(0!==e&&(this._speed=e),this._current=tZ(this._tx.pos.x,this._tx.pos.y),this._end=tZ(this._followTx.pos.x,this._followTx.pos.y),this._distanceBetween=this._current.distance(this._end),this._dir=this._end.sub(this._current).normalize(),this._distanceBetween>=this._maximumDistance){let t=this._dir.scale(this._speed);this._motion.vel=tZ(t.x,t.y)}else this._motion.vel=tZ(0,0);this.isComplete()&&(this._tx.pos=tZ(this._end.x,this._end.y),this._motion.vel=tZ(0,0))}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}isComplete(){return this._stopped}reset(){this._started=!1,this._stopped=!1}}class sU{constructor(t,e,i){this._started=!1,this._stopped=!1,this._speedWasSpecified=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._meetTx=e.get(iV),this._meetMotion=e.get(iW),this._current=new tN(this._tx.pos.x,this._tx.pos.y),this._end=new tN(this._meetTx.pos.x,this._meetTx.pos.y),this._speed=i||0,void 0!==i&&(this._speedWasSpecified=!0)}update(t){this._started||(this._started=!0,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.sub(this._current).normalize());let e=Math.sqrt(Math.pow(this._meetMotion.vel.x,2)+Math.pow(this._meetMotion.vel.y,2));0===e||this._speedWasSpecified||(this._speed=e),this._current=tZ(this._tx.pos.x,this._tx.pos.y),this._end=tZ(this._meetTx.pos.x,this._meetTx.pos.y),this._distanceBetween=this._current.distance(this._end),this._dir=this._end.sub(this._current).normalize();let i=this._dir.scale(this._speed);this._motion.vel=tZ(i.x,i.y),this.isComplete()&&(this._tx.pos=tZ(this._end.x,this._end.y),this._motion.vel=tZ(0,0))}isComplete(){return this._stopped||this._distanceBetween<=1}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}reset(){this._started=!1,this._stopped=!1,this._distanceBetween=void 0}}class sN{constructor(t){this._entity=t,this._queue=new sb(t)}getQueue(){return this._queue}update(t){this._queue.update(t)}clearActions(){this._queue.clearActions()}runAction(t){return t.reset(),this._queue.add(t),this}easeTo(...t){var e,i;let s=0,r=0,n=0,o=sw.Linear;return t[0]instanceof tN?(s=t[0].x,r=t[0].y,n=t[1],o=null!==(e=t[2])&&void 0!==e?e:o):(s=t[0],r=t[1],n=t[2],o=null!==(i=t[3])&&void 0!==i?i:o),this._queue.add(new sR(this._entity,s,r,n,o)),this}easeBy(...t){var e,i;let s=0,r=0,n=0,o=sw.Linear;return t[0]instanceof tN?(s=t[0].x,r=t[0].y,n=t[1],o=null!==(e=t[2])&&void 0!==e?e:o):(s=t[0],r=t[1],n=t[2],o=null!==(i=t[3])&&void 0!==i?i:o),this._queue.add(new sF(this._entity,s,r,n,o)),this}moveTo(t,e,i){let s=0,r=0,n=0;return t instanceof tN?(s=t.x,r=t.y,n=e):(s=t,r=e,n=i),this._queue.add(new sA(this._entity,s,r,n)),this}moveBy(t,e,i){let s=0,r=0,n=0;return t instanceof tN?(s=t.x,r=t.y,n=e):(s=t,r=e,n=i),this._queue.add(new sS(this._entity,s,r,n)),this}rotateTo(t,e,i){return this._queue.add(new sE(this._entity,t,e,i)),this}rotateBy(t,e,i){return this._queue.add(new sP(this._entity,t,e,i)),this}scaleTo(t,e,i,s){let r=1,n=1,o=0,a=0;return t instanceof tN&&e instanceof tN&&(r=t.x,n=t.y,o=e.x,a=e.y),"number"==typeof t&&"number"==typeof e&&(r=t,n=e,o=i,a=s),this._queue.add(new sI(this._entity,r,n,o,a)),this}scaleBy(t,e,i){let s=1,r=1;return t instanceof tN&&(s=t.x,r=t.y,i=e),"number"==typeof t&&"number"==typeof e&&(s=t,r=e),this._queue.add(new sk(this._entity,s,r,i)),this}blink(t,e,i=1){return this._queue.add(new sB(this._entity,t,e,i)),this}fade(t,e){return this._queue.add(new sM(this._entity,t,e)),this}delay(t){return this._queue.add(new sL(t)),this}die(){return this._queue.add(new sz(this._entity)),this}callMethod(t){return this._queue.add(new sD(t)),this}repeat(t,e){return e?this._queue.add(new sC(this._entity,t,e)):this.repeatForever(t),this}repeatForever(t){return this._queue.add(new sT(this._entity,t)),this}follow(t,e){return void 0===e?this._queue.add(new sO(this._entity,t)):this._queue.add(new sO(this._entity,t,e)),this}meet(t,e){return void 0===e?this._queue.add(new sU(this._entity,t)):this._queue.add(new sU(this._entity,t,e)),this}toPromise(){return new Promise(t=>{this._queue.add(new sD(()=>{t()}))})}}class sZ extends iZ{constructor(){super(...arguments),this.dependencies=[iV,iW],this._ctx=null}onAdd(t){this._ctx=new sN(t)}onRemove(){this._ctx=null}_getCtx(){if(!this._ctx)throw Error("Actions component not attached to an entity, no context available");return this._ctx}getQueue(){if(!this._ctx)throw Error("Actions component not attached to an entity, no queue available");return this._ctx.getQueue()}runAction(t){if(!this._ctx)throw Error("Actions component not attached to an entity, cannot run action");return this._ctx.runAction(t)}update(t){var e;return null===(e=this._ctx)||void 0===e?void 0:e.update(t)}clearActions(){var t;null===(t=this._ctx)||void 0===t||t.clearActions()}easeTo(...t){return this._getCtx().easeTo.apply(this._ctx,t)}easeBy(...t){return this._getCtx().easeBy.apply(this._ctx,t)}moveTo(t,e,i){return this._getCtx().moveTo.apply(this._ctx,[t,e,i])}moveBy(t,e,i){return this._getCtx().moveBy.apply(this._ctx,[t,e,i])}rotateTo(t,e,i){return this._getCtx().rotateTo(t,e,i)}rotateBy(t,e,i){return this._getCtx().rotateBy(t,e,i)}scaleTo(t,e,i,s){return this._getCtx().scaleTo.apply(this._ctx,[t,e,i,s])}scaleBy(t,e,i){return this._getCtx().scaleBy.apply(this._ctx,[t,e,i])}blink(t,e,i){return this._getCtx().blink(t,e,i)}fade(t,e){return this._getCtx().fade(t,e)}delay(t){return this._getCtx().delay(t)}die(){return this._getCtx().die()}callMethod(t){return this._getCtx().callMethod(t)}repeat(t,e){return this._getCtx().repeat(t,e)}repeatForever(t){return this._getCtx().repeatForever(t)}follow(t,e){return this._getCtx().follow(t,e)}meet(t,e){return this._getCtx().meet(t,e)}toPromise(){return this._getCtx().toPromise()}}(v=J||(J={})).Em="em",v.Rem="rem",v.Px="px",v.Pt="pt",v.Percent="%",(y=tt||(tt={})).Left="left",y.Right="right",y.Center="center",y.Start="start",y.End="end",(x=te||(te={})).Top="top",x.Hanging="hanging",x.Middle="middle",x.Alphabetic="alphabetic",x.Ideographic="ideographic",x.Bottom="bottom",(w=ti||(ti={})).Normal="normal",w.Italic="italic",w.Oblique="oblique",(b=ts||(ts={})).LeftToRight="ltr",b.RightToLeft="rtl";class sH{constructor(t,e,i,s){this.font=t,this.text=e,this.color=i,this.maxWidth=s,this._textFragments=[],this.disposed=!1,this._dirty=!0,this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.dimensions=this.measureText(e),this._setDimension(this.dimensions,this.ctx),this._lastHashCode=this.getHashCode()}measureText(t,e){if(this.disposed)throw Error("Accessing disposed text instance! "+this.text);let i=null,s=(i=null!=e?this._getLinesFromText(t,e):t.split("\n")).reduce((t,e)=>t.length>e.length?t:e);this._applyFont(this.ctx);let r=this.ctx.measureText(s),n=Math.abs(r.actualBoundingBoxAscent)+Math.abs(r.actualBoundingBoxDescent),o=n*i.length;n=o;let a=o-Math.abs(r.actualBoundingBoxAscent);return new tq({left:0-Math.abs(r.actualBoundingBoxLeft)-this.font.padding,top:0-Math.abs(r.actualBoundingBoxAscent)-this.font.padding,bottom:0+a+this.font.padding,right:0+Math.abs(r.actualBoundingBoxRight)+this.font.padding})}_setDimension(t,e){let i=1;this.font.lineHeight&&(i=this.font.lineHeight/this.font.size),e.canvas.width=(t.width+2*this.font.padding)*2*this.font.quality,e.canvas.height=(t.height+2*this.font.padding)*2*this.font.quality*i}static getHashCode(t,e,i){var s;return e+"__hashcode__"+t.fontString+t.showDebug+t.textAlign+t.baseAlign+t.direction+t.lineHeight+JSON.stringify(t.shadow)+(t.padding.toString()+t.smoothing.toString()+t.lineWidth.toString()+t.lineDash.toString()+(null===(s=t.strokeColor)||void 0===s?void 0:s.toString())+(i?i.toString():t.color.toString()))}getHashCode(t=!0){return sH.getHashCode(this.font,this.text,t?this.color:void 0)}_applyRasterProperties(t){var e,i;t.translate(this.font.padding,this.font.padding),t.imageSmoothingEnabled=this.font.smoothing,t.lineWidth=this.font.lineWidth,t.setLineDash(null!==(e=this.font.lineDash)&&void 0!==e?e:t.getLineDash()),t.strokeStyle=null===(i=this.font.strokeColor)||void 0===i?void 0:i.toString(),t.fillStyle=this.color.toString()}_applyFont(t){t.resetTransform(),t.translate(this.font.padding+t.canvas.width/2,this.font.padding+t.canvas.height/2),t.scale(this.font.quality,this.font.quality),t.textAlign=this.font.textAlign,t.textBaseline=this.font.baseAlign,t.font=this.font.fontString,t.direction=this.font.direction,this.font.shadow&&(t.shadowColor=this.font.shadow.color.toString(),t.shadowBlur=this.font.shadow.blur,t.shadowOffsetX=this.font.shadow.offset.x,t.shadowOffsetY=this.font.shadow.offset.y)}_drawText(t,e,i){this._applyRasterProperties(t),this._applyFont(t);for(let s=0;se){for(;this.measureText(s).width>e;)r=s[s.length-1]+r,s=s.slice(0,-1);i[t]=s,i[t+1]=r}}return this._cachedText=t,this._cachedLines=i,this._cachedRenderWidth=e,i}}class sV{static measureText(t,e,i){let s=sH.getHashCode(e,t);if(sV._MEASURE_CACHE.has(s))return sV._MEASURE_CACHE.get(s);sV._LOGGER.debug("Font text measurement cache miss");let r=e.measureTextWithoutCache(t,i);return sV._MEASURE_CACHE.set(s,r),r}static getTextInstance(t,e,i){let s=sH.getHashCode(e,t,i),r=sV._TEXT_CACHE.get(s);return r||(r=new sH(e,t,i),sV._TEXT_CACHE.set(s,r),sV._LOGGER.debug("Font text instance cache miss")),sV._TEXT_USAGE.set(r,performance.now()),r}static checkAndClearCache(){let t=[],e=new Set;for(let[i,s]of sV._TEXT_USAGE.entries())if(s+sV.FONT_TIMEOUT{sV._TEXT_USAGE.delete(t)}),this._TEXT_CACHE.clear(),this._TEXT_USAGE.entries()))this._TEXT_CACHE.set(e.getHashCode(),e);let i=new Map;for(let t of e)sV._MEASURE_CACHE.has(t)&&i.set(t,sV._MEASURE_CACHE.get(t));this._MEASURE_CACHE.clear(),this._MEASURE_CACHE=i}static get cacheSize(){return sV._TEXT_USAGE.size}static clearCache(){for(let[t]of sV._TEXT_USAGE.entries())t.dispose();sV._TEXT_USAGE.clear(),sV._TEXT_CACHE.clear(),sV._MEASURE_CACHE.clear()}}sV.FONT_TIMEOUT=500,sV._LOGGER=tW.getInstance(),sV._TEXT_USAGE=new Map,sV._TEXT_CACHE=new Map,sV._MEASURE_CACHE=new Map;class sW extends et{constructor(t={}){var e,i,s,r,n,o,a,l,h,d,c,u,p,g,_,f,m,v,y,x;super(t),this.filtering=H.Blended,this.quality=2,this.padding=2,this.smoothing=!1,this.lineWidth=1,this.lineDash=[],this.color=tH.Black,this.family="sans-serif",this.style=ti.Normal,this.bold=!1,this.unit=J.Px,this.textAlign=tt.Left,this.baseAlign=te.Top,this.direction=ts.LeftToRight,this.lineHeight=void 0,this.size=10,this.shadow=null,this._textBounds=new tq,this._textMeasurement=new sH(this,"",tH.Black),this.smoothing=null!==(e=null==t?void 0:t.smoothing)&&void 0!==e?e:this.smoothing,this.padding=null!==(i=null==t?void 0:t.padding)&&void 0!==i?i:this.padding,this.color=null!==(s=null==t?void 0:t.color)&&void 0!==s?s:this.color,this.strokeColor=null!==(r=null==t?void 0:t.strokeColor)&&void 0!==r?r:this.strokeColor,this.lineDash=null!==(n=null==t?void 0:t.lineDash)&&void 0!==n?n:this.lineDash,this.lineWidth=null!==(o=null==t?void 0:t.lineWidth)&&void 0!==o?o:this.lineWidth,this.filtering=null!==(a=null==t?void 0:t.filtering)&&void 0!==a?a:this.filtering,this.family=null!==(l=null==t?void 0:t.family)&&void 0!==l?l:this.family,this.style=null!==(h=null==t?void 0:t.style)&&void 0!==h?h:this.style,this.bold=null!==(d=null==t?void 0:t.bold)&&void 0!==d?d:this.bold,this.size=null!==(c=null==t?void 0:t.size)&&void 0!==c?c:this.size,this.unit=null!==(u=null==t?void 0:t.unit)&&void 0!==u?u:this.unit,this.textAlign=null!==(p=null==t?void 0:t.textAlign)&&void 0!==p?p:this.textAlign,this.baseAlign=null!==(g=null==t?void 0:t.baseAlign)&&void 0!==g?g:this.baseAlign,this.direction=null!==(_=null==t?void 0:t.direction)&&void 0!==_?_:this.direction,this.lineHeight=null!==(f=null==t?void 0:t.lineHeight)&&void 0!==f?f:this.lineHeight,this.quality=null!==(m=null==t?void 0:t.quality)&&void 0!==m?m:this.quality,(null==t?void 0:t.shadow)&&(this.shadow={},this.shadow.blur=null!==(v=t.shadow.blur)&&void 0!==v?v:this.shadow.blur,this.shadow.offset=null!==(y=t.shadow.offset)&&void 0!==y?y:this.shadow.offset,this.shadow.color=null!==(x=t.shadow.color)&&void 0!==x?x:this.shadow.color)}clone(){return new sW({...this.cloneGraphicOptions(),size:this.size,unit:this.unit,family:this.family,style:this.style,bold:this.bold,textAlign:this.textAlign,baseAlign:this.baseAlign,direction:this.direction,shadow:this.shadow?{blur:this.shadow.blur,offset:this.shadow.offset,color:this.shadow.color}:null})}get fontString(){return`${this.style} ${this.bold?"bold":""} ${this.size}${this.unit} ${this.family}`}get localBounds(){return this._textBounds}_drawImage(t,e,i){}_rotate(t){var e;let i=null!==(e=this.origin)&&void 0!==e?e:this._textBounds.center;t.translate(i.x,i.y),t.rotate(this.rotation),t.translate(-i.x,-i.y)}_flip(t){this.flipHorizontal&&(t.translate(this._textBounds.width/this.scale.x,0),t.scale(-1,1)),this.flipVertical&&(t.translate(0,-this._textBounds.height/2/this.scale.y),t.scale(1,-1))}measureTextWithoutCache(t,e){return this._textMeasurement.measureText(t,e)}measureText(t,e){return sV.measureText(t,this,e)}_postDraw(t){t.restore()}render(t,e,i,s,r,n){let o=sV.getTextInstance(e,this,i);this._textBounds=o.dimensions,this._preDraw(t,s,r),o.render(t,s,r,n),this._postDraw(t)}}class sG extends et{constructor(t){var e,i;super(t),this._text="",this._textWidth=0,this._textHeight=0,this.font=null!==(e=t.font)&&void 0!==e?e:new sW,this.color=null!==(i=t.color)&&void 0!==i?i:this.color,this.text=t.text,this.maxWidth=t.maxWidth}clone(){var t,e;return new sG({text:this.text.slice(),color:null!==(e=null===(t=this.color)||void 0===t?void 0:t.clone())&&void 0!==e?e:tH.Black,font:this.font.clone(),maxWidth:this.maxWidth})}get text(){return this._text}set text(t){this._text=t,this._calculateDimension()}get font(){return this._font}set font(t){this._font=t}get width(){return 0===this._textWidth&&this._calculateDimension(),this._textWidth*this.scale.x}get height(){return 0===this._textHeight&&this._calculateDimension(),this._textHeight*this.scale.y}_calculateDimension(){let{width:t,height:e}=this.font.measureText(this._text,this.maxWidth);this._textWidth=t,this._textHeight=e}get localBounds(){return this.font.measureText(this._text,this.maxWidth).scale(this.scale)}_rotate(t){}_flip(t){}_preDraw(t,e,i){(this.isStale()||this.font.isStale())&&(this.font.flipHorizontal=this.flipHorizontal,this.font.flipVertical=this.flipVertical,this.font.rotation=this.rotation,this.font.origin=this.origin,this.font.opacity=this.opacity),this.font.tint=this.tint,super._preDraw(t,e,i)}_drawImage(t,e,i){var s;let r=tH.Black;this.font instanceof sW&&(r=null!==(s=this.color)&&void 0!==s?s:this.font.color);let{width:n,height:o}=this.font.measureText(this._text,this.maxWidth);this._textWidth=n,this._textHeight=o,this.font.render(t,this._text,r,e,i,this.maxWidth),this.font.showDebug&&(t.debug.drawRect(e-n,i-o,2*n,2*o),null!=this.maxWidth&&t.debug.drawRect(e,i,this.maxWidth,this.height,{color:tH.Yellow}))}}class sj extends s_{get pos(){return this.transform.pos}set pos(t){this.transform.pos=t.clone()}get oldPos(){return this.body.oldPos}set oldPos(t){this.body.oldPos.setTo(t.x,t.y)}get vel(){return this.motion.vel}set vel(t){this.motion.vel=t.clone()}get oldVel(){return this.body.oldVel}set oldVel(t){this.body.oldVel.setTo(t.x,t.y)}get acc(){return this.motion.acc}set acc(t){this.motion.acc=t.clone()}set oldAcc(t){this.body.oldAcc.setTo(t.x,t.y)}get oldAcc(){return this.body.oldAcc}get rotation(){return this.transform.rotation}set rotation(t){this.transform.rotation=t}get angularVelocity(){return this.motion.angularVelocity}set angularVelocity(t){this.motion.angularVelocity=t}get scale(){return this.get(iV).scale}set scale(t){this.get(iV).scale=t}get anchor(){return this._anchor}set anchor(t){this._anchor=t6(t,t=>this._handleAnchorChange(t)),this._handleAnchorChange(t)}_handleAnchorChange(t){this.graphics&&(this.graphics.anchor=t)}get offset(){return this._offset}set offset(t){this._offset=t6(t,t=>this._handleOffsetChange(t)),this._handleOffsetChange(t)}_handleOffsetChange(t){this.graphics&&(this.graphics.offset=t)}get isOffScreen(){return this.hasTag("ex.offscreen")}get draggable(){return this._draggable}set draggable(t){t&&(t&&!this._draggable?(this.events.on("pointerdragstart",this._pointerDragStartHandler),this.events.on("pointerdragend",this._pointerDragEndHandler),this.events.on("pointerdragmove",this._pointerDragMoveHandler),this.events.on("pointerdragleave",this._pointerDragLeaveHandler)):!t&&this._draggable&&(this.events.off("pointerdragstart",this._pointerDragStartHandler),this.events.off("pointerdragend",this._pointerDragEndHandler),this.events.off("pointerdragmove",this._pointerDragMoveHandler),this.events.off("pointerdragleave",this._pointerDragLeaveHandler)),this._draggable=t)}get color(){return this._color}set color(t){this._color=t.clone();let e=this.graphics.current;(e instanceof eO||e instanceof sG)&&(e.color=this._color)}constructor(t){super(),this.events=new tP,this._anchor=t6(tN.Half,t=>this._handleAnchorChange(t)),this._offset=t6(tN.Zero,t=>this._handleOffsetChange(t)),this.logger=tW.getInstance(),this._draggable=!1,this._dragging=!1,this._pointerDragStartHandler=()=>{this._dragging=!0},this._pointerDragEndHandler=()=>{this._dragging=!1},this._pointerDragMoveHandler=t=>{this._dragging&&(this.pos=t.worldPos)},this._pointerDragLeaveHandler=t=>{this._dragging&&(this.pos=t.worldPos)};let{name:e,x:i,y:s,pos:r,coordPlane:n,scale:o,width:a,height:l,radius:h,collider:d,vel:c,acc:u,rotation:p,angularVelocity:g,z:_,color:f,visible:m,opacity:v,anchor:y,offset:x,collisionType:w,collisionGroup:b}={...t};this.name=null!=e?e:this.name,this.anchor=null!=y?y:sj.defaults.anchor.clone(),this.offset=null!=x?x:tN.Zero,this.transform=new iV,this.addComponent(this.transform),this.pos=null!=r?r:tZ(null!=i?i:0,null!=s?s:0),this.rotation=null!=p?p:0,this.scale=null!=o?o:tZ(1,1),this.z=null!=_?_:0,this.transform.coordPlane=null!=n?n:j.World,this.pointer=new sx,this.addComponent(this.pointer),this.graphics=new sm({anchor:this.anchor,offset:this.offset,opacity:v}),this.addComponent(this.graphics),this.motion=new iW,this.addComponent(this.motion),this.vel=null!=c?c:tN.Zero,this.acc=null!=u?u:tN.Zero,this.angularVelocity=null!=g?g:0,this.actions=new sZ,this.addComponent(this.actions),this.body=new sh,this.addComponent(this.body),this.body.collisionType=null!=w?w:G.Passive,b&&(this.body.group=b),d?this.collider=new sl(d):h?this.collider=new sl(sa.Circle(h)):a>0&&l>0?this.collider=new sl(sa.Box(a,l,this.anchor)):this.collider=new sl,this.addComponent(this.collider),this.graphics.visible=null==m||m,f&&(this.color=f,a&&l?this.graphics.add(new sv({color:f,width:a,height:l})):h&&this.graphics.add(new sy({color:f,radius:h})))}clone(){let t=new sj({color:this.color.clone(),anchor:this.anchor.clone(),offset:this.offset.clone()});t.clearComponents(),t.processComponentRemoval(),t.addComponent(t.transform=this.transform.clone(),!0),t.addComponent(t.pointer=this.pointer.clone(),!0),t.addComponent(t.graphics=this.graphics.clone(),!0),t.addComponent(t.motion=this.motion.clone(),!0),t.addComponent(t.actions=this.actions.clone(),!0),t.addComponent(t.body=this.body.clone(),!0),t.addComponent(t.collider=this.collider.clone(),!0);let e=[this.transform,this.pointer,this.graphics,this.motion,this.actions,this.body,this.collider];for(let i of this.getComponents())e.includes(i)||t.addComponent(i.clone(),!0);return t}onInitialize(t){}_initialize(t){for(let e of(super._initialize(t),this.children))e._initialize(t)}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}_prekill(t){this.events.emit("prekill",new eG(this)),this.onPreKill(t)}onPreKill(t){}_postkill(t){this.events.emit("postkill",new ej(this)),this.onPostKill(t)}onPostKill(t){}kill(){this.scene?(this._prekill(this.scene),this.events.emit("kill",new eW(this)),super.kill(),this._postkill(this.scene)):this.logger.warn(`Cannot kill actor named "${this.name}", it was never added to the Scene`)}unkill(){this.active=!0}isKilled(){return!this.active}get z(){return this.get(iV).z}set z(t){this.get(iV).z=t}get center(){let t=this.getGlobalPos();return new tN(t.x+this.width/2-this.anchor.x*this.width,t.y+this.height/2-this.anchor.y*this.height)}get localCenter(){return new tN(this.pos.x+this.width/2-this.anchor.x*this.width,this.pos.y+this.height/2-this.anchor.y*this.height)}get width(){return this.collider.localBounds.width*this.getGlobalScale().x}get height(){return this.collider.localBounds.height*this.getGlobalScale().y}getGlobalRotation(){return this.get(iV).globalRotation}getGlobalPos(){return this.get(iV).globalPos}getGlobalScale(){return this.get(iV).globalScale}contains(t,e,i=!1){let s=tZ(t,e),r=this.get(sl);r.update();let n=r.get();if(!n)return!1;let o=n.contains(s);return i?o||this.children.some(i=>i.contains(t,e,!0)):o}within(t,e){let i=this.get(sl),s=t.get(sl),r=i.get(),n=s.get();return!!r&&!!n&&r.getClosestLineBetween(n).getLength()<=e}update(t,e){this._initialize(t),this._preupdate(t,e),this._postupdate(t,e)}onPreUpdate(t,e){}onPostUpdate(t,e){}onPreCollisionResolve(t,e,i,s){}onPostCollisionResolve(t,e,i,s){}onCollisionStart(t,e,i,s){}onCollisionEnd(t,e,i,s){}_preupdate(t,e){this.events.emit("preupdate",new e1(t,e,this)),this.onPreUpdate(t,e)}_postupdate(t,e){this.events.emit("postupdate",new e2(t,e,this)),this.onPostUpdate(t,e)}}function sq(t){return t instanceof sX}sj.defaults={anchor:tN.Half};class sX extends sj{constructor(t){var e,i;super({...t}),this.get(iV).coordPlane=j.Screen,this.anchor=null!==(e=null==t?void 0:t.anchor)&&void 0!==e?e:tZ(0,0),this.body.collisionType=null!==(i=null==t?void 0:t.collisionType)&&void 0!==i?i:G.PreventCollision,this.pointer.useGraphicsBounds=!0,this.pointer.useColliderShape=!1,!(null==t?void 0:t.collider)&&(null==t?void 0:t.width)>0&&(null==t?void 0:t.height)>0&&this.collider.useBoxCollider(this.width,this.height,this.anchor)}_initialize(t){this._engine=t,super._initialize(t)}contains(t,e,i=!0){if(i)return super.contains(t,e);let s=this._engine.worldToScreenCoordinates(new tN(t,e));return super.contains(s.x,s.y)}}class s${get complete(){return this._complete}constructor(t,e,i,s,r,n){if(this._logger=tW.getInstance(),this.id=0,this._elapsedTime=0,this._totalTimeAlive=0,this._running=!1,this._numberOfTicks=0,this.interval=10,this.repeats=!1,this.maxNumberOfRepeats=-1,this.randomRange=[0,0],this._baseInterval=10,this._generateRandomInterval=()=>this._baseInterval+this.random.integer(this.randomRange[0],this.randomRange[1]),this._complete=!1,this.scene=null,"function"!=typeof t){let o=t;t=o.fcn,e=o.interval,i=o.repeats,s=o.numberOfRepeats,r=o.randomRange,n=o.random}if(s&&s>=0&&(this.maxNumberOfRepeats=s,!i))throw Error("repeats must be set to true if numberOfRepeats is set");if(this.id=s$._MAX_ID++,this._callbacks=[],this._baseInterval=this.interval=e,r){if(r[0]>r[1])throw Error("min value must be lower than max value for range");this.random=null!=n?n:new tI,this.randomRange=r,this.interval=this._generateRandomInterval(),this.on(()=>{this.interval=this._generateRandomInterval()})}this.repeats=i||this.repeats,t&&this.on(t)}on(t){this._callbacks.push(t)}off(t){let e=this._callbacks.indexOf(t);this._callbacks.splice(e,1)}update(t){this._running&&(this._totalTimeAlive+=t,this._elapsedTime+=t,this.maxNumberOfRepeats>-1&&this._numberOfTicks>=this.maxNumberOfRepeats&&(this._complete=!0,this._running=!1,this._elapsedTime=0),!this.complete&&this._elapsedTime>=this.interval&&(this._callbacks.forEach(t=>{t.call(this)}),this._numberOfTicks++,this.repeats||(this._complete=!0,this._running=!1),this._elapsedTime=0))}reset(t,e){if(t&&t>=0&&(this._baseInterval=this.interval=t),this.maxNumberOfRepeats&&this.maxNumberOfRepeats>=0&&(this.maxNumberOfRepeats=e,!this.repeats))throw Error("repeats must be set to true if numberOfRepeats is set");this._complete=!1,this._elapsedTime=0,this._numberOfTicks=0}get timesRepeated(){return this._numberOfTicks}getTimeRunning(){return this._totalTimeAlive}get timeToNextAction(){return this.complete?0:this.interval-this._elapsedTime}get timeElapsedTowardNextAction(){return this._elapsedTime}get isRunning(){return this._running}pause(){return this._running=!1,this}resume(){return this._running=!0,this}start(){return this.scene||this._logger.warn("Cannot start a timer not part of a scene, timer wont start until added"),this._running=!0,this.complete&&(this._complete=!1,this._elapsedTime=0,this._numberOfTicks=0),this}stop(){return this._running=!1,this._elapsedTime=0,this._numberOfTicks=0,this}cancel(){this.pause(),this.scene&&this.scene.cancelTimer(this)}}s$._MAX_ID=0;class sK extends iZ{constructor(t){super(),this.parallaxFactor=tZ(1,1),this.parallaxFactor=null!=t?t:this.parallaxFactor}}class sY extends iZ{constructor(t,e=!0){super(),this.draw=t,this.useTransform=e}}let sQ={PreUpdate:"preupdate",PostUpdate:"postupdate",PreDraw:"predraw",PostDraw:"postdraw"};class sJ extends s_{flagCollidersDirty(){this._collidersDirty=!0}flagTilesDirty(){for(let t=0;tthis.draw(t,e)})),this.addComponent(new sY((t,e)=>this.debug(t,e),!1)),this.addComponent(new sl),this._graphics=this.get(sm),this.transform=this.get(iV),this._motion=this.get(iW),this.collider=this.get(sl),this._composite=this.collider.useCompositeCollider([]),this.transform.pos=null!==(i=t.pos)&&void 0!==i?i:tN.Zero,this._oldPos=this.transform.pos.clone(),this._oldScale=this.transform.scale.clone(),this.renderFromTopOfGraphic=null!==(s=t.renderFromTopOfGraphic)&&void 0!==s?s:this.renderFromTopOfGraphic,this.tileWidth=t.tileWidth,this.tileHeight=t.tileHeight,this.rows=t.rows,this.columns=t.columns,this.tiles=Array(this.rows*this.columns),this._rows=Array(this.rows),this._cols=Array(this.columns);let r=[];for(let t=0;t!!t&&!!e&&t.top===e.top&&t.bottom===e.bottom&&t.right===e.left,s=(t,e,s=this.meshingLookBehind)=>{if(!t)return!1;for(let r=e.length-1;r>=0&&!(s--<0);r--){let s=e[r];if(i(s,t))return e[r]=s.combine(t),!0}return!1};for(let i=0;i0){for(let t of n.getColliders()){let e=this._getOrSetColliderOriginalOffset(t);t.offset=tZ(n.x*this.tileWidth*this.scale.x,n.y*this.tileHeight*this.scale.y).add(e),t.owner=this,this._composite.addCollider(t)}t&&!s(t,e)&&e.push(t),t=null}else t=t?t.combine(n.defaultGeometry):n.defaultGeometry}else t&&!s(t,e)&&e.push(t),t=null}t&&!s(t,e)&&e.push(t),t=null}for(let t of e){let e=sa.Box(t.width,t.height,tN.Zero,tZ(t.left-this.pos.x,t.top-this.pos.y));e.owner=this,this._composite.addCollider(e)}this.collider.update(),this.collider.$colliderAdded.notifyAll(this._composite)}getTileByIndex(t){return this.tiles[t]}getTile(t,e){return t<0||e<0||t>=this.columns||e>=this.rows?null:this.tiles[t+e*this.columns]}getTileByPoint(t){let{x:e,y:i}=this._getTileCoordinates(t),s=this.getTile(e,i);return e>=0&&i>=0&&e-1&&(this._graphics.splice(e,1),this._offsets.splice(e,1))}clearGraphics(){this._graphics.length=0,this._offsets.length=0}getColliders(){return this._colliders}addCollider(t){this._colliders.push(t),this.map.flagCollidersDirty()}removeCollider(t){let e=this._colliders.indexOf(t);e>-1&&this._colliders.splice(e,1),this.map.flagCollidersDirty()}clearColliders(){this._colliders.length=0,this.map.flagCollidersDirty()}constructor(t){var e,i;super(),this._posDirty=!1,this._solid=!1,this._graphics=[],this._offsets=[],this._colliders=[],this.data=new Map,this.x=t.x,this.y=t.y,this.map=t.map,this._width=t.map.tileWidth*this.map.scale.x,this._height=t.map.tileHeight*this.map.scale.y,this.solid=null!==(e=t.solid)&&void 0!==e?e:this.solid,this._graphics=null!==(i=t.graphics)&&void 0!==i?i:[],this._recalculate()}flagDirty(){return this._posDirty=!0}_recalculate(){let t=this.map.pos.add(tZ(this.x*this.map.tileWidth,this.y*this.map.tileHeight));this._geometry=new tq(t.x,t.y,t.x+this.map.tileWidth,t.y+this.map.tileHeight),this._width=this.map.tileWidth*this.map.scale.x,this._height=this.map.tileHeight*this.map.scale.y,this._pos=this.map.pos.add(tZ(this.x*this._width,this.y*this._height)),this._bounds=new tq(this._pos.x,this._pos.y,this._pos.x+this._width,this._pos.y+this._height),this.map.rotation&&(this._bounds=this._bounds.rotate(this.map.rotation,this.map.pos)),this._posDirty=!1}get bounds(){return this._posDirty&&this._recalculate(),this._bounds}get defaultGeometry(){return this._geometry}get center(){return this._posDirty&&this._recalculate(),new tN(this._pos.x+this._width/2,this._pos.y+this._height/2)}}class s1{constructor(t){this.camera=t}lockToActor(t){this.camera.addStrategy(new s2(t))}lockToActorAxis(t,e){this.camera.addStrategy(new s5(t,e))}elasticToActor(t,e,i){this.camera.addStrategy(new s4(t,e,i))}radiusAroundActor(t,e){this.camera.addStrategy(new s3(t,e))}limitCameraBounds(t){this.camera.addStrategy(new s9(t))}}(C=tr||(tr={}))[C.X=0]="X",C[C.Y=1]="Y";class s2{constructor(t){this.target=t,this.action=(t,e,i,s)=>t.center}}class s5{constructor(t,e){this.target=t,this.axis=e,this.action=(t,e,i,s)=>{let r=t.center,n=e.getFocus();return this.axis===tr.X?new tN(r.x,n.y):new tN(n.x,r.y)}}}class s4{constructor(t,e,i){this.target=t,this.cameraElasticity=e,this.cameraFriction=i,this.action=(t,e,i,s)=>{let r=t.center,n=e.getFocus(),o=e.vel.clone(),a=r.sub(n).scale(this.cameraElasticity),l=(o=o.add(a)).scale(-1).scale(this.cameraFriction);return o=o.add(l),n=n.add(o)}}}class s3{constructor(t,e){this.target=t,this.radius=e,this.action=(t,e,i,s)=>{let r=t.center,n=e.getFocus(),o=r.sub(n),a=o.size;if(a>=this.radius){let t=a-this.radius;return n.add(o.normalize().scale(t))}return n}}}class s9{constructor(t){this.target=t,this.boundSizeChecked=!1,this.action=(t,e,i,s)=>{let r=e.getFocus();this.boundSizeChecked||((t.bottom-t.topt.right-i.halfDrawWidth&&(n=t.right-i.halfDrawWidth),r.yt.bottom-i.halfDrawHeight&&(o=t.bottom-i.halfDrawHeight),tZ(n,o)}}}let s6={Initialize:"initialize",PreUpdate:"preupdate",PostUpdate:"postupdate"};class s7{constructor(){this.events=new tP,this.transform=t2.identity(),this.inverse=t2.identity(),this._cameraStrategies=[],this.strategy=new s1(this),this._z=1,this.dz=0,this.az=0,this.rotation=0,this._angularVelocity=0,this._posChanged=!1,this._pos=t8(tN.Zero,()=>this._posChanged=!0),this.drawPos=this.pos.clone(),this._oldPos=this.pos.clone(),this.vel=tN.Zero,this.acc=tN.Zero,this._cameraMoving=!1,this._currentLerpTime=0,this._lerpDuration=1e3,this._lerpStart=null,this._lerpEnd=null,this._isShaking=!1,this._shakeMagnitudeX=0,this._shakeMagnitudeY=0,this._shakeDuration=0,this._elapsedShakeTime=0,this._xShake=0,this._yShake=0,this._isZooming=!1,this._zoomStart=1,this._zoomEnd=1,this._currentZoomTime=0,this._zoomDuration=0,this._zoomEasing=sw.EaseInOutCubic,this._easing=sw.EaseInOutCubic,this._halfWidth=0,this._halfHeight=0,this._viewport=null,this._isInitialized=!1,this._snapPos=tZ(0,0)}get zoom(){return this._z}set zoom(t){this._z=t,this._engine&&(this._halfWidth=this._engine.halfDrawWidth,this._halfHeight=this._engine.halfDrawHeight)}get angularVelocity(){return this._angularVelocity}set angularVelocity(t){this._angularVelocity=t}get pos(){return this._pos}set pos(t){this._pos=t8(t,()=>this._posChanged=!0),this._posChanged=!0}get x(){return this.pos.x}set x(t){this._follow||this._cameraMoving||(this.pos=tZ(t,this.pos.y))}get y(){return this.pos.y}set y(t){this._follow||this._cameraMoving||(this.pos=tZ(this.pos.x,t))}get dx(){return this.vel.x}set dx(t){this.vel=tZ(t,this.vel.y)}get dy(){return this.vel.y}set dy(t){this.vel=tZ(this.vel.x,t)}get ax(){return this.acc.x}set ax(t){this.acc=tZ(t,this.acc.y)}get ay(){return this.acc.y}set ay(t){this.acc=tZ(this.acc.x,t)}getFocus(){return this.pos}move(t,e,i=sw.EaseInOutCubic){if("function"!=typeof i)throw"Please specify an EasingFunction";return this._follow?Promise.reject(t):(this._lerpPromise&&this._lerpResolve&&this._lerpResolve(t),this._lerpPromise=new Promise(t=>{this._lerpResolve=t}),this._lerpStart=this.getFocus().clone(),this._lerpDuration=e,this._lerpEnd=t,this._currentLerpTime=0,this._cameraMoving=!0,this._easing=i,this._lerpPromise)}shake(t,e,i){this._isShaking=!0,this._shakeMagnitudeX=t,this._shakeMagnitudeY=e,this._shakeDuration=i}zoomOverTime(t,e=0,i=sw.EaseInOutCubic){return(this._zoomPromise=new Promise(t=>{this._zoomResolve=t}),e)?(this._isZooming=!0,this._zoomEasing=i,this._currentZoomTime=0,this._zoomDuration=e,this._zoomStart=this.zoom,this._zoomEnd=t,this._zoomPromise):(this._isZooming=!1,this.zoom=t,Promise.resolve(!0))}get viewport(){return this._viewport?this._viewport:new tq(0,0,0,0)}addStrategy(t){this._cameraStrategies.push(t)}removeStrategy(t){tK(t,this._cameraStrategies)}clearAllStrategies(){this._cameraStrategies.length=0}_preupdate(t,e){this.events.emit("preupdate",new e1(t,e,this)),this.onPreUpdate(t,e)}onPreUpdate(t,e){}_postupdate(t,e){this.events.emit("postupdate",new e2(t,e,this)),this.onPostUpdate(t,e)}onPostUpdate(t,e){}get isInitialized(){return this._isInitialized}_initialize(t){if(!this.isInitialized){this._engine=t,this._screen=t.screen;let e=this._screen.contentArea,i=tZ(e.width/2,e.height/2);if(!this._engine.loadingComplete){let t=this._screen.peekResolution();t&&(i=tZ(t.width/2,t.height/2))}this._halfWidth=i.x,this._halfHeight=i.y,this._posChanged||(this.pos=i),this.pos.clone(this.drawPos),this.updateTransform(this.pos),this.runStrategies(t,t.clock.elapsed()),this.updateViewport(),this.updateTransform(this.pos),this.pos.clone(this._oldPos),this.onInitialize(t),this.events.emit("initialize",new id(t,this)),this._isInitialized=!0}}onInitialize(t){}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}runStrategies(t,e){for(let i of this._cameraStrategies)this.pos=i.action.call(i,i.target,this,t,e)}updateViewport(){this._viewport=new tq(this.x-this._halfWidth,this.y-this._halfHeight,this.x+this._halfWidth,this.y+this._halfHeight)}update(t,e){if(this._initialize(t),this._preupdate(t,e),this.pos.clone(this._oldPos),this.pos=this.pos.add(this.vel.scale(e/1e3)),this.zoom+=this.dz*e/1e3,this.vel=this.vel.add(this.acc.scale(e/1e3)),this.dz+=this.az*e/1e3,this.rotation+=this.angularVelocity*e/1e3,this._isZooming){if(this._currentZoomTime=this._shakeDuration}}let s8={ExitTrigger:"exit",EnterTrigger:"enter"},rt={pos:tN.Zero,width:10,height:10,visible:!1,action:()=>{},filter:()=>!0,repeat:-1};class re extends sj{constructor(t){super({x:t.pos.x,y:t.pos.y,width:t.width,height:t.height}),this.events=new tP,this.action=()=>{},this.filter=()=>!0,this.repeat=-1,t={...rt,...t},this.filter=t.filter||this.filter,this.repeat=t.repeat||this.repeat,this.action=t.action||this.action,t.target&&(this.target=t.target),this.graphics.visible=t.visible,this.body.collisionType=G.Passive,this.events.on("collisionstart",t=>{this.filter(t.other)&&(this.events.emit("enter",new i_(this,t.other)),this._dispatchAction(),0===this.repeat&&this.kill())}),this.events.on("collisionend",t=>{this.filter(t.other)&&this.events.emit("exit",new im(this,t.other))})}set target(t){this._target=t,this.filter=e=>e===t}get target(){return this._target}_initialize(t){super._initialize(t)}_dispatchAction(){0!==this.repeat&&(this.action.call(this),this.repeat--)}}let ri={Highest:-1/0,Higher:-5,Average:0,Lower:5,Lowest:1/0};(T=tn||(tn={})).Update="update",T.Draw="draw";class rs{constructor(){this.priority=ri.Average}}class rr{constructor(t){this._world=t,this.entities=[],this._entityIndex={},this._entitiesToRemove=[]}updateEntities(t,e){for(let i of this.entities)i.update(t.engine,e),i.active||this.removeEntity(i)}findEntitiesForRemoval(){for(let t of this.entities)t.active||this.removeEntity(t)}addEntity(t){t.active=!0,t.scene=this._world.scene,t&&!this._entityIndex[t.id]&&(this._entityIndex[t.id]=t,this.entities.push(t),this._world.queryManager.addEntity(t),t.children.forEach(e=>{e.scene=t.scene,this.addEntity(e)}),t.childrenAdded$.register({notify:t=>{this.addEntity(t)}}),t.childrenRemoved$.register({notify:t=>{this.removeEntity(t,!1)}}))}removeEntity(t,e=!0){var i,s;let r=0;r=t instanceof s_?t.id:t;let n=this._entityIndex[r];if(n&&n.active&&(n.active=!1),n&&e){this._entitiesToRemove.push(n);return}delete this._entityIndex[r],n&&(n.scene=null,tK(n,this.entities),this._world.queryManager.removeEntity(n),n.children.forEach(t=>{t.scene=null,this.removeEntity(t,e)}),n.childrenAdded$.clear(),n.childrenRemoved$.clear(),(null===(s=null===(i=this._world)||void 0===i?void 0:i.scene)||void 0===s?void 0:s.engine)&&this._world.scene.engine.stats.currFrame.actors.killed++)}processEntityRemovals(){for(let t of this._entitiesToRemove)t.active||this.removeEntity(t,!1);this._entitiesToRemove.length=0}processComponentRemovals(){for(let t of this.entities)t.processComponentRemoval()}getById(t){return this._entityIndex[t]}getByName(t){return this.entities.filter(e=>e.name===t)}clear(){for(let t=this.entities.length-1;t>=0;t--)this.removeEntity(this.entities[t])}}class rn{constructor(t){if(this.requiredComponents=t,this.components=new Set,this.entities=[],this.entityAdded$=new iH,this.entityRemoved$=new iH,0===t.length)throw Error("Cannot create query without components");for(let e of t)this.components.add(e);this.id=rn.createId(t)}static createId(t){return t.slice().map(t=>t.name).sort().join("-")}checkAndAdd(t){return!!(!this.entities.includes(t)&&t.hasAll(Array.from(this.components)))&&(this.entities.push(t),this.entityAdded$.notifyAll(t),!0)}removeEntity(t){let e=this.entities.indexOf(t);e>-1&&(this.entities.splice(e,1),this.entityRemoved$.notifyAll(t))}getEntities(t){return t&&this.entities.sort(t),this.entities}}class ro{constructor(t){if(this.requiredTags=t,this.tags=new Set,this.entities=[],this.entityAdded$=new iH,this.entityRemoved$=new iH,0===t.length)throw Error("Cannot create tag query without tags");for(let e of t)this.tags.add(e);this.id=ro.createId(t)}static createId(t){return t.slice().sort().join("-")}checkAndAdd(t){return!!(!this.entities.includes(t)&&t.hasAllTags(Array.from(this.tags)))&&(this.entities.push(t),this.entityAdded$.notifyAll(t),!0)}removeEntity(t){let e=this.entities.indexOf(t);e>-1&&(this.entities.splice(e,1),this.entityRemoved$.notifyAll(t))}getEntities(t){return t&&this.entities.sort(t),this.entities}}class ra{constructor(t){this._world=t,this._queries=new Map,this._addComponentHandlers=new Map,this._removeComponentHandlers=new Map,this._componentToQueriesIndex=new Map,this._tagQueries=new Map,this._addTagHandlers=new Map,this._removeTagHandlers=new Map,this._tagToQueriesIndex=new Map,this._createAddComponentHandler=t=>e=>{this.addComponent(t,e)},this._createRemoveComponentHandler=t=>e=>{this.removeComponent(t,e)},this._createAddTagHandler=t=>e=>{this.addTag(t,e)},this._createRemoveTagHandler=t=>e=>{this.removeTag(t,e)}}createQuery(t){let e=rn.createId(t);if(this._queries.has(e))return this._queries.get(e);let i=new rn(t);for(let e of(this._queries.set(i.id,i),t)){let t=this._componentToQueriesIndex.get(e);t?t.push(i):this._componentToQueriesIndex.set(e,[i])}for(let t of this._world.entities)this.addEntity(t);return i}createTagQuery(t){let e=ro.createId(t);if(this._tagQueries.has(e))return this._tagQueries.get(e);let i=new ro(t);for(let e of(this._tagQueries.set(i.id,i),t)){let t=this._tagToQueriesIndex.get(e);t?t.push(i):this._tagToQueriesIndex.set(e,[i])}for(let t of this._world.entities)this.addEntity(t);return i}addEntity(t){let e=this._addComponentHandlers.get(t),i=this._removeComponentHandlers.get(t),s=null!=e?e:this._createAddComponentHandler(t),r=null!=i?i:this._createRemoveComponentHandler(t);this._addComponentHandlers.set(t,s),this._removeComponentHandlers.set(t,r);let n=this._addTagHandlers.get(t),o=this._removeTagHandlers.get(t),a=null!=n?n:this._createAddTagHandler(t),l=null!=o?o:this._createRemoveTagHandler(t);for(let e of(this._addTagHandlers.set(t,a),this._removeTagHandlers.set(t,l),this._queries.values()))e.checkAndAdd(t);for(let e of this._tagQueries.values())e.checkAndAdd(t);t.componentAdded$.subscribe(s),t.componentRemoved$.subscribe(r),t.tagAdded$.subscribe(a),t.tagRemoved$.subscribe(l)}removeEntity(t){let e=this._addComponentHandlers.get(t),i=this._removeComponentHandlers.get(t);for(let e of this._queries.values())e.removeEntity(t);e&&t.componentAdded$.unsubscribe(e),i&&t.componentRemoved$.unsubscribe(i);let s=this._addTagHandlers.get(t),r=this._removeTagHandlers.get(t);for(let e of this._tagQueries.values())e.removeEntity(t);s&&t.tagAdded$.unsubscribe(s),r&&t.tagRemoved$.unsubscribe(r)}addComponent(t,e){var i;for(let s of null!==(i=this._componentToQueriesIndex.get(e.constructor))&&void 0!==i?i:[])s.checkAndAdd(t)}removeComponent(t,e){var i;for(let s of null!==(i=this._componentToQueriesIndex.get(e.constructor))&&void 0!==i?i:[])s.removeEntity(t)}addTag(t,e){var i;for(let s of null!==(i=this._tagToQueriesIndex.get(e))&&void 0!==i?i:[])s.checkAndAdd(t)}removeTag(t,e){var i;for(let s of null!==(i=this._tagToQueriesIndex.get(e))&&void 0!==i?i:[])s.removeEntity(t)}}function rl(t){var e,i;return!!(null==t?void 0:t.prototype)&&!!(null===(i=null===(e=null==t?void 0:t.prototype)||void 0===e?void 0:e.constructor)||void 0===i?void 0:i.name)}class rh{constructor(t){this._world=t,this.systems=[],this.initialized=!1}get(t){return this.systems.find(e=>e instanceof t)}addSystem(t){let e;e=t instanceof rs?t:new t(this._world),this.systems.push(e),this.systems.sort((t,e)=>t.priority-e.priority),this.initialized&&e.initialize&&e.initialize(this._world,this._world.scene)}removeSystem(t){tK(t,this.systems)}initialize(){if(!this.initialized)for(let t of(this.initialized=!0,this.systems))t.initialize&&t.initialize(this._world,this._world.scene)}updateSystems(t,e,i){let s=this.systems.filter(e=>e.systemType===t);for(let t of s)t.preupdate&&t.preupdate(e,i);for(let t of s)t.update(i);for(let t of s)t.postupdate&&t.postupdate(e,i)}clear(){for(let t=this.systems.length-1;t>=0;t--)this.removeSystem(this.systems[t])}}class rd{constructor(t){this.scene=t,this.queryManager=new ra(this),this.entityManager=new rr(this),this.systemManager=new rh(this)}query(t){return this.queryManager.createQuery(t)}queryTags(t){return this.queryManager.createTagQuery(t)}update(t,e){t===tn.Update&&this.entityManager.updateEntities(this.scene,e),this.systemManager.updateSystems(t,this.scene,e),this.entityManager.findEntitiesForRemoval(),this.entityManager.processComponentRemovals(),this.entityManager.processEntityRemovals()}add(t){t instanceof s_&&this.entityManager.addEntity(t),(t instanceof rs||rl(t))&&this.systemManager.addSystem(t)}get(t){return this.systemManager.get(t)}remove(t,e=!0){t instanceof s_&&this.entityManager.removeEntity(t,e),t instanceof rs&&this.systemManager.removeSystem(t)}get entities(){return this.entityManager.entities}clearEntities(){this.entityManager.clear()}clearSystems(){this.systemManager.clear()}}class rc{static integrate(t,e,i,s){let r=s/1e3;e.vel.addEqual(i.scale(r,rc._ACC)),t.pos.add(e.vel.scale(r,rc._VEL),rc._POS).addEqual(i.scale(.5*r*r,rc._VEL_ACC)),e.angularVelocity+=e.torque*(1/e.inertia)*r;let n=t.rotation+e.angularVelocity*r;t.scale.add(e.scaleFactor.scale(r,this._SCALE_FACTOR),rc._SCALE),t.get().setTransform(rc._POS,n,rc._SCALE)}}rc._POS=new tN(0,0),rc._SCALE=new tN(1,1),rc._ACC=new tN(0,0),rc._VEL=new tN(0,0),rc._VEL_ACC=new tN(0,0),rc._SCALE_FACTOR=new tN(0,0);class ru extends rs{constructor(t,e){super(),this.world=t,this.physics=e,this.systemType=tn.Update,this.priority=ri.Higher,this._physicsConfigDirty=!1,e.$configUpdate.subscribe(()=>this._physicsConfigDirty=!0),this.query=this.world.query([iV,iW])}update(t){let e,i;let s=this.query.entities;for(let r=0;r!t.isCanceled()),this.config.contactSolveBias){case K.HorizontalFirst:e=i2;break;case K.VerticalFirst:e=i1;break;default:e=i5}for(let i of(t.sort((t,i)=>{let s=this.directionMap.get(t.id),r=this.directionMap.get(i.id),n=this.distanceMap.get(t.id),o=this.distanceMap.get(i.id);return e[s]-e[r]||n-o}),t))this.solvePosition(i),this.solveVelocity(i);return this.postSolve(t),t}preSolve(t){for(let e of t){if(1e-4>Math.abs(e.mtv.x)&&1e-4>Math.abs(e.mtv.y)){e.cancel();continue}let t=N.fromDirection(e.mtv),i=e.mtv.negate(),s=e.colliderA.worldPos.squareDistance(e.colliderB.worldPos);this.distanceMap.set(e.id,s),this.directionMap.set(e.id,t===N.Left||t===N.Right?"horizontal":"vertical"),e.colliderA.events.emit("precollision",new ie(e.colliderA,e.colliderB,t,i,e)),e.colliderB.events.emit("precollision",new ie(e.colliderB,e.colliderA,N.getOpposite(t),i.negate(),e))}}postSolve(t){var e,i;for(let s of t){if(s.isCanceled())continue;let t=s.colliderA,r=s.colliderB,n=null===(e=t.owner)||void 0===e?void 0:e.get(sh),o=null===(i=r.owner)||void 0===i?void 0:i.get(sh);if(n&&o&&(n.collisionType===G.Passive||o.collisionType===G.Passive))continue;let a=N.fromDirection(s.mtv),l=s.mtv.negate();s.colliderA.events.emit("postcollision",new ii(s.colliderA,s.colliderB,a,l,s)),s.colliderB.events.emit("postcollision",new ii(s.colliderB,s.colliderA,N.getOpposite(a),l.negate(),s))}}solvePosition(t){var e,i;if(!t.colliderA.bounds.overlaps(t.colliderB.bounds,1e-4)||1e-4>Math.abs(t.mtv.x)&&1e-4>Math.abs(t.mtv.y)){t.cancel();return}let s=t.mtv,r=t.colliderA,n=t.colliderB,o=null===(e=r.owner)||void 0===e?void 0:e.get(sh),a=null===(i=n.owner)||void 0===i?void 0:i.get(sh);if(o&&a){if(o.collisionType===G.Passive||a.collisionType===G.Passive)return;o.collisionType===G.Active&&a.collisionType===G.Active&&(s=s.scale(.5)),o.collisionType===G.Active&&(o.globalPos.x-=s.x,o.globalPos.y-=s.y,r.update(o.transform.get())),a.collisionType===G.Active&&(a.globalPos.x+=s.x,a.globalPos.y+=s.y,n.update(a.transform.get()))}}solveVelocity(t){var e,i;if(t.isCanceled())return;let s=t.colliderA,r=t.colliderB,n=null===(e=s.owner)||void 0===e?void 0:e.get(sh),o=null===(i=r.owner)||void 0===i?void 0:i.get(sh);if(n&&o){if(n.collisionType===G.Passive||o.collisionType===G.Passive)return;let e=t.normal,i=e.negate();if(n.collisionType===G.Active&&0>n.vel.normalize().dot(i)){let t=e.scale(e.dot(n.vel.negate()));n.vel=n.vel.add(t)}if(o.collisionType===G.Active&&0>o.vel.normalize().dot(e)){let t=i.scale(i.dot(o.vel.negate()));o.vel=o.vel.add(t)}}}}class rg{constructor(t,e,i){this.point=t,this.local=e,this.contact=i,this.normalImpulse=0,this.tangentImpulse=0,this.normalMass=0,this.tangentMass=0,this.aToContact=new tN(0,0),this.bToContact=new tN(0,0),this.originalVelocityAndRestitution=0,this.update()}update(){var t,e;let i=null===(t=this.contact.colliderA.owner)||void 0===t?void 0:t.get(sh),s=null===(e=this.contact.colliderB.owner)||void 0===e?void 0:e.get(sh);if(i&&s){let t=this.contact.normal,e=this.contact.tangent;this.aToContact=this.point.sub(i.globalPos),this.bToContact=this.point.sub(s.globalPos);let r=this.aToContact.cross(t),n=this.bToContact.cross(t);this.normalMass=i.inverseMass+s.inverseMass+i.inverseInertia*r*r+s.inverseInertia*n*n;let o=this.aToContact.cross(e),a=this.bToContact.cross(e);this.tangentMass=i.inverseMass+s.inverseMass+i.inverseInertia*o*o+s.inverseInertia*a*a}return this}getRelativeVelocity(){var t,e;let i=null===(t=this.contact.colliderA.owner)||void 0===t?void 0:t.get(sh),s=null===(e=this.contact.colliderB.owner)||void 0===e?void 0:e.get(sh);if(i&&s){let t=i.vel.add(tN.cross(i.angularVelocity,this.aToContact));return s.vel.add(tN.cross(s.angularVelocity,this.bToContact)).sub(t)}return tN.Zero}}class r_{constructor(t){this.config=t,this.lastFrameContacts=new Map,this.idToContactConstraint=new Map}getContactConstraints(t){var e;return null!==(e=this.idToContactConstraint.get(t))&&void 0!==e?e:[]}solve(t){return this.preSolve(t),t=t.filter(t=>!t.isCanceled()),this.solveVelocity(t),this.solvePosition(t),this.postSolve(t),t}preSolve(t){var e,i,s;for(let e of t){if(1e-4>Math.abs(e.mtv.x)&&1e-4>Math.abs(e.mtv.y)){e.cancel();continue}let t=N.fromDirection(e.mtv);e.colliderA.events.emit("precollision",new ie(e.colliderA,e.colliderB,t,e.mtv,e)),e.colliderA.events.emit("beforecollisionresolve",new io(e.colliderA,e.colliderB,t,e.mtv,e)),e.colliderB.events.emit("precollision",new ie(e.colliderB,e.colliderA,N.getOpposite(t),e.mtv.negate(),e)),e.colliderB.events.emit("beforecollisionresolve",new io(e.colliderB,e.colliderA,N.getOpposite(t),e.mtv.negate(),e)),e.matchAwake()}let r=Array.from(this.idToContactConstraint.keys());for(let n of t){let t=r.indexOf(n.id);t>-1&&r.splice(t,1);let o=null!==(e=this.idToContactConstraint.get(n.id))&&void 0!==e?e:[],a=0,l=n.colliderA.owner.get(sh),h=n.colliderB.owner.get(sh);if(l&&h)for(let t of n.points){let e=n.normal,r=n.tangent,d=t.sub(l.globalPos),c=t.sub(h.globalPos),u=d.cross(e),p=c.cross(e),g=l.inverseMass+h.inverseMass+l.inverseInertia*u*u+h.inverseInertia*p*p,_=d.cross(r),f=c.cross(r),m=l.inverseMass+h.inverseMass+l.inverseInertia*_*_+h.inverseInertia*f*f;o[a]&&(null===(s=null===(i=o[a])||void 0===i?void 0:i.point)||void 0===s?void 0:s.squareDistance(t))<4?(o[a].point=t,o[a].local=n.localPoints[a]):o[a]=new rg(t,n.localPoints[a],n),o[a].aToContact=d,o[a].bToContact=c,o[a].normalMass=1/g,o[a].tangentMass=1/m;let v=l.bounciness>h.bounciness?l.bounciness:h.bounciness,y=n.normal.dot(o[a].getRelativeVelocity());o[a].originalVelocityAndRestitution=0,y<-.1&&(o[a].originalVelocityAndRestitution=-v*y),a++}this.idToContactConstraint.set(n.id,o)}for(let t of r)this.idToContactConstraint.delete(t);if(this.config.warmStart)this.warmStart(t);else for(let e of t)for(let t of this.getContactConstraints(e.id))t.normalImpulse=0,t.tangentImpulse=0}postSolve(t){for(let e of t){let t=e.colliderA.owner.get(sh),i=e.colliderB.owner.get(sh);if(t&&i){if(t.collisionType===G.Passive||i.collisionType===G.Passive)continue;t.updateMotion(),i.updateMotion()}let s=N.fromDirection(e.mtv);e.colliderA.events.emit("postcollision",new ii(e.colliderA,e.colliderB,s,e.mtv,e)),e.colliderA.events.emit("aftercollisionresolve",new ia(e.colliderA,e.colliderB,s,e.mtv,e)),e.colliderB.events.emit("postcollision",new ii(e.colliderB,e.colliderA,N.getOpposite(s),e.mtv.negate(),e)),e.colliderB.events.emit("aftercollisionresolve",new ia(e.colliderB,e.colliderA,N.getOpposite(s),e.mtv.negate(),e))}for(let e of(this.lastFrameContacts.clear(),t))this.lastFrameContacts.set(e.id,e)}warmStart(t){var e,i,s;for(let r of t){let t=null===(e=r.colliderA.owner)||void 0===e?void 0:e.get(sh),n=null===(i=r.colliderB.owner)||void 0===i?void 0:i.get(sh);if(t&&n)for(let e of null!==(s=this.idToContactConstraint.get(r.id))&&void 0!==s?s:[])if(this.config.warmStart){let i=r.normal.scale(e.normalImpulse),s=r.tangent.scale(e.tangentImpulse),o=i.add(s);t.applyImpulse(e.point,o.negate()),n.applyImpulse(e.point,o)}else e.normalImpulse=0,e.tangentImpulse=0}}solvePosition(t){var e,i,s;for(let r=0;rthis._configDirty=!0),this._trackCollider=t=>this._processor.track(t),this._untrackCollider=t=>this._processor.untrack(t),this.query=t.query([iV,iW,sl]),this.query.entityAdded$.subscribe(t=>{let e=t.get(sl);e.$colliderAdded.subscribe(this._trackCollider),e.$colliderRemoved.subscribe(this._untrackCollider);let i=e.get();i&&this._processor.track(i)}),this.query.entityRemoved$.subscribe(t=>{let e=t.get(sl),i=e.get();e&&i&&this._processor.untrack(i)})}initialize(t,e){this._engine=e.engine}update(t){var e,i,s,r;if(!this._physics.config.enabled)return;let n=[];for(let t of this.query.entities){let i=t.get(sl),s=null==i?void 0:i.get();if(i&&(null===(e=i.owner)||void 0===e?void 0:e.active)&&s){if(i.update(),s instanceof i9){let t=s.getColliders();s.compositeStrategy||(s.compositeStrategy=this._physics.config.colliders.compositeStrategy),n=n.concat(t)}else n.push(s)}}this._processor.update(n);let o=this._processor.broadphase(n,t);this._currentFrameContacts.clear();let a=this._processor.narrowphase(o,null===(r=null===(s=null===(i=this._engine)||void 0===i?void 0:i.debug)||void 0===s?void 0:s.stats)||void 0===r?void 0:r.currFrame);for(let t of a=this.getSolver().solve(a)){if(t.isCanceled())continue;let e=t.id.indexOf("|");if(e>0){let i=t.id.substring(e+1);this._currentFrameContacts.set(i,t)}else this._currentFrameContacts.set(t.id,t)}for(let t of(this.runContactStartEnd(),this._lastFrameContacts.clear(),this._lastFrameContacts=new Map(this._currentFrameContacts),this.query.entities)){let e=t.get(sl);e&&e.processColliderRemoval()}}getSolver(){return this._configDirty&&(this._configDirty=!1,this._arcadeSolver=new rp(this._physics.config.arcade),this._realisticSolver=new r_(this._physics.config.realistic)),this._physics.config.solver===q.Realistic?this._realisticSolver:this._arcadeSolver}debug(t){this._processor.debug(t)}runContactStartEnd(){for(let[t,e]of this._currentFrameContacts)if(!this._lastFrameContacts.has(t)){let t=e.colliderA,i=e.colliderB,s=N.fromDirection(e.mtv),r=N.getOpposite(s);t.events.emit("collisionstart",new il(t,i,s,e)),t.events.emit("contactstart",new is(t,i,s,e)),i.events.emit("collisionstart",new il(i,t,r,e)),i.events.emit("contactstart",new is(i,t,r,e))}for(let[t,e]of this._lastFrameContacts)if(!this._currentFrameContacts.has(t)){let t=e.colliderA,i=e.colliderB,s=N.fromDirection(e.mtv),r=N.getOpposite(s);t.events.emit("collisionend",new ih(t,i,s,e)),t.events.emit("contactend",new ir(t,i,s,e)),i.events.emit("collisionend",new ih(i,t,r,e)),i.events.emit("contactend",new ir(i,t,r,e))}}}(S=to||(to={})).Forward="forward",S.Backward="backward",(A=ta||(ta={})).End="end",A.Loop="loop",A.PingPong="pingpong",A.Freeze="freeze";let rm={Frame:"frame",Loop:"loop",End:"end"};class rv extends et{constructor(t){var e,i,s;super(t),this.events=new tP,this.frames=[],this.strategy=ta.Loop,this.frameDuration=100,this._idempotencyToken=-1,this._firstTick=!0,this._currentFrame=0,this._timeLeftInFrame=0,this._pingPongDirection=1,this._done=!1,this._playing=!0,this._speed=1,this._reversed=!1,this.frames=t.frames,this.speed=null!==(e=t.speed)&&void 0!==e?e:this.speed,this.strategy=null!==(i=t.strategy)&&void 0!==i?i:this.strategy,this.frameDuration=t.totalDuration?t.totalDuration/this.frames.length:null!==(s=t.frameDuration)&&void 0!==s?s:this.frameDuration,t.reverse&&this.reverse(),this.goToFrame(0)}clone(){return new rv({frames:this.frames.map(t=>({...t})),frameDuration:this.frameDuration,speed:this.speed,reverse:this._reversed,strategy:this.strategy,...this.cloneGraphicOptions()})}get width(){let t=this.currentFrame;return t?Math.abs(t.graphic.width*this.scale.x):0}get height(){let t=this.currentFrame;return t?Math.abs(t.graphic.height*this.scale.y):0}static fromSpriteSheet(t,e,i,s=ta.Loop){let r=t.sprites.length-1,n=e.filter(t=>t<0||t>r);return n.length&&rv._LOGGER.warn(`Indices into SpriteSheet were provided that don't exist: ${n.join(",")} no frame will be shown`),new rv({frames:t.sprites.filter((t,i)=>e.indexOf(i)>-1).map(t=>({graphic:t,duration:i})),strategy:s})}static fromSpriteSheetCoordinates(t){let{spriteSheet:e,frameCoordinates:i,durationPerFrameMs:s,speed:r,strategy:n,reverse:o}=t,a=null!=s?s:100,l=[];for(let t of i){let{x:i,y:s,duration:r,options:n}=t,o=e.getSprite(i,s,n);o?l.push({graphic:o,duration:null!=r?r:a}):rv._LOGGER.warn(`Skipping frame! SpriteSheet does not have coordinate (${i}, ${s}), please check your SpriteSheet to confirm that sprite exists`)}return new rv({frames:l,strategy:n,speed:r,reverse:o})}get speed(){return this._speed}set speed(t){this._speed=tF(Math.abs(t),0,1/0)}get currentFrame(){return this._currentFrame>=0&&this._currentFrame=this.frames.length&&(this._done=!0,this._currentFrame=this.frames.length,this.events.emit("end",this));break;case ta.Freeze:(e=tF(t+1,0,this.frames.length-1))>=this.frames.length-1&&(this._done=!0,this.events.emit("end",this));break;case ta.PingPong:t+this._pingPongDirection>=this.frames.length&&(this._pingPongDirection=-1,this.events.emit("loop",this)),t+this._pingPongDirection<0&&(this._pingPongDirection=1,this.events.emit("loop",this)),e=t+this._pingPongDirection%this.frames.length}return e}tick(t,e=0){this._idempotencyToken!==e&&(this._idempotencyToken=e,this._playing&&(this._firstTick&&(this._firstTick=!1,this.events.emit("frame",{...this.currentFrame,frameIndex:this.currentFrameIndex})),this._timeLeftInFrame-=t*this._speed,this._timeLeftInFrame<=0&&this.goToFrame(this._nextFrame())))}_drawImage(t,e,i){this.currentFrame&&this.currentFrame.graphic.draw(t,e,i)}}rv._LOGGER=tW.getInstance();class ry extends et{constructor(t){super(t),this._logger=tW.getInstance(),this.members=[],this.members=t.members,this._updateDimensions()}clone(){return new ry({members:[...this.members],...this.cloneGraphicOptions()})}_updateDimensions(){let t=this.localBounds;return this.width=t.width,this.height=t.height,t}get localBounds(){let t=new tq;for(let e of this.members)if(e instanceof et)t=e.localBounds.combine(t);else{let{graphic:i,offset:s,useBounds:r}=e,n=void 0===r||r;i?n&&(t=i.localBounds.translate(s).combine(t)):this._logger.warnOnce(`Graphics group member has an null or undefined graphic, member definition: ${JSON.stringify(e)}.`)}return t}_isAnimationOrGroup(t){return t instanceof rv||t instanceof ry}tick(t,e){for(let i of this.members){let s;s=i instanceof et?i:i.graphic,this._isAnimationOrGroup(s)&&s.tick(t,e)}}reset(){for(let t of this.members){let e;e=t instanceof et?t:t.graphic,this._isAnimationOrGroup(e)&&e.reset()}}_preDraw(t,e,i){this._updateDimensions(),super._preDraw(t,e,i)}_drawImage(t,e,i){let s=tN.Zero;for(let r of this.members){let n;r instanceof et?n=r:(n=r.graphic,r.offset.clone(s)),n&&(t.save(),t.translate(e,i),n.draw(t,s.x,s.y),this.showDebug&&t.debug.drawRect(0,0,this.width,this.height),t.restore())}}}function rx(t){return class extends t{assign(t){for(let e in t)"function"!=typeof this[e]&&(this[e]=t[e])}constructor(...t){super(...t),1!==t.filter(function(t){return void 0!==t}).length||!t[0]||"object"!=typeof t[0]||t[0]instanceof Array||this.assign(t[0])}}}(E=tl||(tl={}))[E.Circle=0]="Circle",E[E.Rectangle=1]="Rectangle";class rw extends s_{constructor(t,e,i,s,r,n,o,a,l,h,d){super(),this.position=new tN(0,0),this.velocity=new tN(0,0),this.acceleration=new tN(0,0),this.particleRotationalVelocity=0,this.currentRotation=0,this.focus=null,this.focusAccel=0,this.opacity=1,this.beginColor=tH.White,this.endColor=tH.White,this.life=300,this.fadeFlag=!1,this._rRate=1,this._gRate=1,this._bRate=1,this._aRate=0,this._currentColor=tH.White,this.emitter=null,this.particleSize=5,this.particleSprite=null,this.sizeRate=0,this.elapsedMultiplier=0,this.visible=!0,this.isOffscreen=!1;let c=t;if(!c||t instanceof rC||(c=t.emitter,e=t.life,i=t.opacity,r=t.endColor,s=t.beginColor,n=t.position,o=t.velocity,a=t.acceleration,l=t.startSize,h=t.endSize,d=t.particleSprite),this.emitter=c,this.life=e||this.life,this.opacity=i||this.opacity,this.endColor=r||this.endColor.clone(),this.beginColor=s||this.beginColor.clone(),this._currentColor=this.beginColor.clone(),this.particleSprite=d,this.emitter.particleTransform===th.Global){let t=this.emitter.transform.globalPos;this.position=(n||this.position).add(t),this.velocity=(o||this.velocity).rotate(this.emitter.transform.globalRotation)}else this.velocity=o||this.velocity,this.position=n||this.position;this.acceleration=a||this.acceleration,this._rRate=(this.endColor.r-this.beginColor.r)/this.life,this._gRate=(this.endColor.g-this.beginColor.g)/this.life,this._bRate=(this.endColor.b-this.beginColor.b)/this.life,this._aRate=this.opacity/this.life,this.startSize=l||0,this.endSize=h||0,this.endSize>0&&this.startSize>0&&(this.sizeRate=(this.endSize-this.startSize)/this.life,this.particleSize=this.startSize),this.addComponent(this.transform=new iV),this.addComponent(this.graphics=new sm),this.transform.pos=this.position,this.transform.rotation=this.currentRotation,this.transform.scale=tZ(1,1),this.particleSprite?(this.graphics.opacity=this.opacity,this.graphics.use(this.particleSprite)):(this.graphics.localBounds=tq.fromDimension(this.particleSize,this.particleSize,tN.Half),this.graphics.onPostDraw=t=>{t.save(),this.graphics.opacity=this.opacity;let e=this._currentColor.clone();e.a=1,t.debug.drawPoint(tZ(0,0),{color:e,size:this.particleSize}),t.restore()})}kill(){this.emitter.removeParticle(this)}update(t,e){if(this.life=this.life-e,this.elapsedMultiplier=this.elapsedMultiplier+e,this.life<0&&this.kill(),this.fadeFlag&&(this.opacity=tF(this._aRate*this.life,1e-4,1)),this.startSize>0&&this.endSize>0&&(this.particleSize=tF(this.sizeRate*e+this.particleSize,Math.min(this.startSize,this.endSize),Math.max(this.startSize,this.endSize))),this._currentColor.r=tF(this._currentColor.r+this._rRate*e,0,255),this._currentColor.g=tF(this._currentColor.g+this._gRate*e,0,255),this._currentColor.b=tF(this._currentColor.b+this._bRate*e,0,255),this._currentColor.a=tF(this.opacity,1e-4,1),this.focus){let t=this.focus.sub(this.position).normalize().scale(this.focusAccel).scale(e/1e3);this.velocity=this.velocity.add(t)}else this.velocity=this.velocity.add(this.acceleration.scale(e/1e3));this.position=this.position.add(this.velocity.scale(e/1e3)),this.particleRotationalVelocity&&(this.currentRotation=(this.currentRotation+this.particleRotationalVelocity*e/1e3)%(2*Math.PI)),this.transform.pos=this.position,this.transform.rotation=this.currentRotation,this.transform.scale=tZ(1,1),this.graphics.opacity=this.opacity}}class rb extends rx(rw){constructor(t,e,i,s,r,n,o,a,l,h,d){super(t,e,i,s,r,n,o,a,l,h,d)}}(P=th||(th={})).Global="global",P.Local="local";class rC extends sj{get opacity(){return this.graphics.opacity}set opacity(t){this.graphics.opacity=t}get particleSprite(){return this._sprite}set particleSprite(t){t&&(this._sprite=t)}constructor(t){var e,i;super({width:null!==(e=t.width)&&void 0!==e?e:0,height:null!==(i=t.height)&&void 0!==i?i:0}),this._particlesToEmit=0,this.numParticles=0,this.isEmitting=!0,this.particles=[],this.deadParticles=[],this.minVel=0,this.maxVel=0,this.acceleration=new tN(0,0),this.minAngle=0,this.maxAngle=0,this.emitRate=1,this.particleLife=2e3,this.fadeFlag=!1,this.focus=null,this.focusAccel=null,this.startSize=null,this.endSize=null,this.minSize=5,this.maxSize=5,this.beginColor=tH.White,this.endColor=tH.White,this._sprite=null,this.emitterType=tl.Rectangle,this.radius=0,this.particleRotationalVelocity=0,this.randomRotation=!1,this.particleTransform=th.Global;let{x:s,y:r,pos:n,isEmitting:o,minVel:a,maxVel:l,acceleration:h,minAngle:d,maxAngle:c,emitRate:u,particleLife:p,opacity:g,fadeFlag:_,focus:f,focusAccel:m,startSize:v,endSize:y,minSize:x,maxSize:w,beginColor:b,endColor:C,particleSprite:T,emitterType:S,radius:A,particleRotationalVelocity:E,particleTransform:P,randomRotation:I,random:k}={...t};this.pos=null!=n?n:tZ(null!=s?s:0,null!=r?r:0),this.isEmitting=null!=o?o:this.isEmitting,this.minVel=null!=a?a:this.minVel,this.maxVel=null!=l?l:this.maxVel,this.acceleration=null!=h?h:this.acceleration,this.minAngle=null!=d?d:this.minAngle,this.maxAngle=null!=c?c:this.maxAngle,this.emitRate=null!=u?u:this.emitRate,this.particleLife=null!=p?p:this.particleLife,this.opacity=null!=g?g:this.opacity,this.fadeFlag=null!=_?_:this.fadeFlag,this.focus=null!=f?f:this.focus,this.focusAccel=null!=m?m:this.focusAccel,this.startSize=null!=v?v:this.startSize,this.endSize=null!=y?y:this.endSize,this.minSize=null!=x?x:this.minSize,this.maxSize=null!=w?w:this.maxSize,this.beginColor=null!=b?b:this.beginColor,this.endColor=null!=C?C:this.endColor,this.particleSprite=null!=T?T:this.particleSprite,this.emitterType=null!=S?S:this.emitterType,this.radius=null!=A?A:this.radius,this.particleRotationalVelocity=null!=E?E:this.particleRotationalVelocity,this.randomRotation=null!=I?I:this.randomRotation,this.particleTransform=null!=P?P:this.particleTransform,this.body.collisionType=G.PreventCollision,this.random=null!=k?k:new tI}removeParticle(t){this.deadParticles.push(t)}emitParticles(t){var e;for(let i=0;i1&&(this.emitParticles(Math.floor(this._particlesToEmit)),this._particlesToEmit=this._particlesToEmit-Math.floor(this._particlesToEmit)));for(let t=0;t{this._zHasChanged=!0},this._targetInterpolationTransform=new iU,this.query=this.world.query([iV,sm]),this.query.entityAdded$.subscribe(t=>{let e=t.get(iV);this._sortedTransforms.push(e),e.zIndexChanged$.subscribe(this._zIndexUpdate),this._zHasChanged=!0}),this.query.entityRemoved$.subscribe(t=>{let e=t.get(iV);e.zIndexChanged$.unsubscribe(this._zIndexUpdate);let i=this._sortedTransforms.indexOf(e);i>-1&&this._sortedTransforms.splice(i,1)})}initialize(t,e){this._camera=e.camera,this._engine=e.engine}preupdate(){this._graphicsContext=this._engine.graphicsContext,this._zHasChanged&&(this._sortedTransforms.sort((t,e)=>t.z-e.z),this._zHasChanged=!1)}update(t){let e;for(let i of(this._token++,sV.checkAndClearCache(),this._graphicsContext.save(),this._camera&&this._camera.draw(this._graphicsContext),this._sortedTransforms)){let s=i.owner;if(s.hasTag("ex.offscreen")||!(e=s.get(sm)).visible)continue;e.onPreTransformDraw&&e.onPreTransformDraw(this._graphicsContext,t),s.events.emit("pretransformdraw",new eY(this._graphicsContext,t,s)),i.coordPlane===j.Screen&&this._graphicsContext.restore(),this._graphicsContext.save(),i.coordPlane===j.Screen&&this._graphicsContext.translate(this._engine.screen.contentArea.left,this._engine.screen.contentArea.top),e.update(t,this._token);let r=s.get(sK);if(r){let t=tN.One.sub(r.parallaxFactor),e=this._camera.drawPos.scale(t);this._graphicsContext.translate(e.x,e.y)}this._applyTransform(s),e.material&&(this._graphicsContext.material=e.material),e.onPreDraw&&e.onPreDraw(this._graphicsContext,t),s.events.emit("predraw",new e$(this._graphicsContext,t,s));let n=s instanceof rb?s.opacity:1;this._graphicsContext.opacity*=e.opacity*n,this._drawGraphicsComponent(e,i),e.onPostDraw&&e.onPostDraw(this._graphicsContext,t),s.events.emit("postdraw",new eK(this._graphicsContext,t,s)),this._graphicsContext.restore(),i.coordPlane===j.Screen&&(this._graphicsContext.save(),this._camera&&this._camera.draw(this._graphicsContext)),e.onPostTransformDraw&&e.onPostTransformDraw(this._graphicsContext,t),s.events.emit("posttransformdraw",new eQ(this._graphicsContext,t,s))}this._graphicsContext.restore()}_drawGraphicsComponent(t,e){var i,s;if(t.visible){let r=t.flipHorizontal,n=t.flipVertical,o=t.current,a=null!==(i=t.currentOptions)&&void 0!==i?i:{};if(o){let i=t.anchor,l=t.offset,h=1,d=1;(null==a?void 0:a.anchor)&&(i=a.anchor),(null==a?void 0:a.offset)&&(l=a.offset);let c=e.globalScale;h*=o.scale.x*c.x,d*=o.scale.y*c.y;let u=-o.width*i.x+l.x*h,p=-o.height*i.y+l.y*d,g=o.flipHorizontal,_=o.flipVertical;if((r||n)&&(o.flipHorizontal=r?!g:g,o.flipVertical=n?!_:_),null==o||o.draw(this._graphicsContext,u,p),(r||n)&&(o.flipHorizontal=g,o.flipVertical=_),(null===(s=this._engine)||void 0===s?void 0:s.isDebug)&&this._engine.debug.graphics.showBounds){let t=tZ(u,p);if(o instanceof ry)for(let e of o.members){let i;let s=tN.Zero;e instanceof et?i=e:(i=e.graphic,s=e.offset),null==i||i.localBounds.translate(t.add(s)).draw(this._graphicsContext,this._engine.debug.graphics.boundsColor)}else null==o||o.localBounds.translate(t).draw(this._graphicsContext,this._engine.debug.graphics.boundsColor)}}}}_applyTransform(t){for(let e of t.getAncestors()){let t=null==e?void 0:e.get(iV),i=null==e?void 0:e.get(sh),s=t.get();if(i&&this._engine.fixedUpdateFps&&i.__oldTransformCaptured&&i.enableFixedUpdateInterpolate){let e=this._engine.currentFrameLagMs/(1e3/this._engine.fixedUpdateFps);s=function(t,e,i,s){if(t.parent!==e.parent){let i=t.clone(),s=t.globalPos.clone(),r=t.globalScale.clone(),n=t.globalRotation;i.parent=e.parent,i.globalPos=s,i.globalScale=r,i.globalRotation=n,t=i}let r=e.pos,n=e.scale,o=e.rotation;r=e.pos.scale(i).add(t.pos.scale(1-i)),n=e.scale.scale(i).add(t.scale.scale(1-i));let a=(1-i)*Math.cos(t.rotation)+i*Math.cos(e.rotation);o=Math.atan2((1-i)*Math.sin(t.rotation)+i*Math.sin(e.rotation),a);let l=null!=s?s:new iU;return l.setTransform(r,o,n),l}(i.oldTransform,t.get(),e,this._targetInterpolationTransform)}t&&(this._graphicsContext.z=t.z,this._graphicsContext.translate(s.pos.x,s.pos.y),this._graphicsContext.scale(s.scale.x,s.scale.y),this._graphicsContext.rotate(s.rotation))}}}class rS extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Draw,this.priority=ri.Lowest,this.query=this.world.query([iV])}initialize(t,e){this._graphicsContext=e.engine.graphicsContext,this._camera=e.camera,this._engine=e.engine,this._collisionSystem=t.systemManager.get(rf)}update(){var t;let e,i,s,r,n,o,a,l;if(!this._engine.isDebug)return;let h=this._engine.debug.filter,d=this._engine.debug.entity,c=this._engine.debug.transform,u=this._engine.debug.motion,p=this._engine.debug.collider,g=this._engine.debug.physics,_=this._engine.debug.graphics,f=this._engine.debug.body,m=this._engine.debug.camera;for(let g of this.query.entities){if(g.hasTag("offscreen")||g instanceof rb||h.useFilter&&(!(0===h.ids.length||h.ids.includes(g.id))||!(""===h.nameQuery||g.name.includes(h.nameQuery))))continue;let m=tN.Zero,v=tZ(0,16);if(e=g.id,i=g.name,s=g.get(iV),this._pushCameraTransform(s),this._graphicsContext.save(),s.coordPlane===j.Screen&&this._graphicsContext.translate(this._engine.screen.contentArea.left,this._engine.screen.contentArea.top),this._graphicsContext.z=c.debugZIndex,this._applyTransform(g),s&&((c.showAll||c.showPosition)&&this._graphicsContext.debug.drawPoint(tN.Zero,{size:4,color:c.positionColor}),(c.showAll||c.showPositionLabel)&&(this._graphicsContext.debug.drawText(`pos${s.pos.toString(2)}`,m),m=m.add(v)),(c.showAll||c.showZIndex)&&(this._graphicsContext.debug.drawText(`z(${s.z.toFixed(1)})`,m),m=m.add(v)),(d.showAll||d.showId)&&(this._graphicsContext.debug.drawText(`id(${e}) ${g.parent?"child of id("+(null===(t=g.parent)||void 0===t?void 0:t.id)+")":""}`,m),m=m.add(v)),(d.showAll||d.showName)&&(this._graphicsContext.debug.drawText(`name(${i})`,m),m=m.add(v)),(c.showAll||c.showRotation)&&(this._graphicsContext.drawLine(tN.Zero,tN.fromAngle(s.rotation).scale(50).add(tN.Zero),c.rotationColor,2),this._graphicsContext.debug.drawText(`rot deg(${tM(s.rotation).toFixed(2)})`,m),m=m.add(v)),(c.showAll||c.showScale)&&this._graphicsContext.drawLine(tN.Zero,s.scale.add(tN.Zero),c.scaleColor,2)),(o=g.get(sm))&&(_.showAll||_.showBounds)&&o.localBounds.draw(this._graphicsContext,_.boundsColor),(a=g.get(sY))&&(a.useTransform||this._graphicsContext.restore(),a.draw(this._graphicsContext,this._engine.debug),a.useTransform||(this._graphicsContext.save(),this._applyTransform(g))),(l=g.get(sh))&&((f.showAll||f.showCollisionGroup)&&(this._graphicsContext.debug.drawText(`collision group(${l.group.name})`,m),m=m.add(v)),(f.showAll||f.showCollisionType)&&(this._graphicsContext.debug.drawText(`collision type(${l.collisionType})`,m),m=m.add(v)),(f.showAll||f.showMass)&&(this._graphicsContext.debug.drawText(`mass(${l.mass})`,m),m=m.add(v)),(f.showAll||f.showMotion)&&(this._graphicsContext.debug.drawText(`motion(${l.sleepMotion})`,m),m=m.add(v)),(f.showAll||f.showSleeping)&&(this._graphicsContext.debug.drawText(`sleeping(${l.canSleep?l.sleeping:"cant sleep"})`,m),m=m.add(v))),this._graphicsContext.restore(),this._graphicsContext.save(),s.coordPlane===j.Screen&&this._graphicsContext.translate(this._engine.screen.contentArea.left,this._engine.screen.contentArea.top),this._graphicsContext.z=c.debugZIndex,(r=g.get(iW))&&((u.showAll||u.showVelocity)&&(this._graphicsContext.debug.drawText(`vel${r.vel.toString(2)}`,m.add(s.globalPos)),this._graphicsContext.drawLine(s.globalPos,s.globalPos.add(r.vel),u.velocityColor,2),m=m.add(v)),(u.showAll||u.showAcceleration)&&this._graphicsContext.drawLine(s.globalPos,s.globalPos.add(r.acc),u.accelerationColor,2)),n=g.get(sl)){let t=n.get();if((p.showAll||p.showGeometry)&&t&&t.debug(this._graphicsContext,p.geometryColor,{lineWidth:p.geometryLineWidth,pointSize:p.geometryPointSize}),p.showAll||p.showBounds){if(t instanceof i9){for(let e of t.getColliders()){let t=e.bounds,i=tZ(t.left,t.top);this._graphicsContext.debug.drawRect(i.x,i.y,t.width,t.height,{color:p.boundsColor}),(p.showAll||p.showOwner)&&this._graphicsContext.debug.drawText(`owner id(${e.owner.id})`,i)}n.bounds.draw(this._graphicsContext,p.boundsColor)}else if(t){let t=n.bounds,e=tZ(t.left,t.top);this._graphicsContext.debug.drawRect(e.x,e.y,t.width,t.height,{color:p.boundsColor}),(p.showAll||p.showOwner)&&this._graphicsContext.debug.drawText(`owner id(${n.owner.id})`,e)}}}this._graphicsContext.restore(),this._popCameraTransform(s)}if(this._graphicsContext.save(),this._camera.draw(this._graphicsContext),(g.showAll||g.showBroadphaseSpacePartitionDebug)&&this._collisionSystem.debug(this._graphicsContext),g.showAll||g.showCollisionContacts||g.showCollisionNormals)for(let[t,e]of this._engine.debug.stats.currFrame.physics.contacts){if(g.showAll||g.showCollisionContacts)for(let t of e.points)this._graphicsContext.debug.drawPoint(t,{size:g.contactSize,color:g.collisionContactColor});if(g.showAll||g.showCollisionNormals)for(let t of e.points)this._graphicsContext.debug.drawLine(t,e.normal.scale(30).add(t),{color:g.collisionNormalColor})}this._graphicsContext.restore(),m&&(this._graphicsContext.save(),this._camera.draw(this._graphicsContext),(m.showAll||m.showFocus)&&this._graphicsContext.drawCircle(this._camera.pos,4,m.focusColor),(m.showAll||m.showZoom)&&this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`,this._camera.pos),this._graphicsContext.restore()),this._graphicsContext.flush()}postupdate(t,e){this._engine.isDebug&&(this._graphicsContext.save(),this._camera&&this._camera.draw(this._graphicsContext),sn.flush(this._graphicsContext),this._graphicsContext.restore())}_applyTransform(t){for(let e of t.getAncestors()){let t=null==e?void 0:e.get(iV);t&&(this._graphicsContext.translate(t.pos.x,t.pos.y),this._graphicsContext.scale(t.scale.x,t.scale.y),this._graphicsContext.rotate(t.rotation))}}_pushCameraTransform(t){t.coordPlane===j.World&&(this._graphicsContext.save(),this._camera&&this._camera.draw(this._graphicsContext))}_popCameraTransform(t){t.coordPlane===j.World&&this._graphicsContext.restore()}}class rA extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Update,this.priority=ri.Higher,this.overrideUseColliderShape=!1,this.overrideUseGraphicsBounds=!1,this.lastFrameEntityToPointers=new Map,this.currentFrameEntityToPointers=new Map,this._sortedTransforms=[],this._sortedEntities=[],this._zHasChanged=!1,this._zIndexUpdate=()=>{this._zHasChanged=!0},this.query=this.world.query([iV,sx]),this.query.entityAdded$.subscribe(t=>{let e=t.get(iV);this._sortedTransforms.push(e),this._sortedEntities.push(e.owner),e.zIndexChanged$.subscribe(this._zIndexUpdate),this._zHasChanged=!0}),this.query.entityRemoved$.subscribe(t=>{let e=t.get(iV);e.zIndexChanged$.unsubscribe(this._zIndexUpdate);let i=this._sortedTransforms.indexOf(e);i>-1&&(this._sortedTransforms.splice(i,1),this._sortedEntities.splice(i,1))})}initialize(t,e){this._engine=e.engine,this._scene=e}preupdate(){this._receivers=[this._engine.input.pointers,this._scene.input.pointers],this._engineReceiver=this._engine.input.pointers,this._zHasChanged&&(this._sortedTransforms.sort((t,e)=>e.z-t.z),this._sortedEntities=this._sortedTransforms.map(t=>t.owner),this._zHasChanged=!1)}entityCurrentlyUnderPointer(t,e){return this.currentFrameEntityToPointers.has(t.id)&&this.currentFrameEntityToPointers.get(t.id).includes(e)}entityWasUnderPointer(t,e){return this.lastFrameEntityToPointers.has(t.id)&&this.lastFrameEntityToPointers.get(t.id).includes(e)}entered(t,e){return this.entityCurrentlyUnderPointer(t,e)&&!this.lastFrameEntityToPointers.has(t.id)}left(t,e){return!this.currentFrameEntityToPointers.has(t.id)&&this.entityWasUnderPointer(t,e)}addPointerToEntity(t,e){if(!this.currentFrameEntityToPointers.has(t.id)){this.currentFrameEntityToPointers.set(t.id,[e]);return}let i=this.currentFrameEntityToPointers.get(t.id);this.currentFrameEntityToPointers.set(t.id,i.concat(e))}update(){this._processPointerToEntity(this._sortedEntities),this._dispatchEvents(this._sortedEntities),this._receivers.forEach(t=>t.update()),this.lastFrameEntityToPointers.clear(),this.lastFrameEntityToPointers=new Map(this.currentFrameEntityToPointers),this.currentFrameEntityToPointers.clear(),this._receivers.forEach(t=>t.clear())}_processPointerToEntity(t){var e;let i,s,r,n;let o=this._engineReceiver;for(let a of t){if(i=a.get(iV),n=null!==(e=a.get(sx))&&void 0!==e?e:new sx,(s=a.get(sl))&&(n.useColliderShape||this.overrideUseColliderShape)){s.update();let t=s.get();if(t)for(let[e,s]of o.currentFramePointerCoords.entries())t.contains(i.coordPlane===j.World?s.worldPos:s.screenPos)&&this.addPointerToEntity(a,e)}if((r=a.get(sm))&&(n.useGraphicsBounds||this.overrideUseGraphicsBounds)){let t=r.localBounds.transform(i.get().matrix);for(let[e,s]of o.currentFramePointerCoords.entries())t.contains(i.coordPlane===j.World?s.worldPos:s.screenPos)&&this.addPointerToEntity(a,e)}}}_processDownAndEmit(t){let e=this._engineReceiver,i=new Map;for(let s of e.currentFrameDown)s.active&&t.active&&this.entityCurrentlyUnderPointer(t,s.pointerId)&&(t.events.emit("pointerdown",s),e.isDragStart(s.pointerId)&&t.events.emit("pointerdragstart",s)),i.set(s.pointerId,s);return i}_processUpAndEmit(t){let e=this._engineReceiver,i=new Map;for(let s of e.currentFrameUp)s.active&&t.active&&this.entityCurrentlyUnderPointer(t,s.pointerId)&&(t.events.emit("pointerup",s),e.isDragEnd(s.pointerId)&&t.events.emit("pointerdragend",s)),i.set(s.pointerId,s);return i}_processMoveAndEmit(t){let e=this._engineReceiver,i=new Map;for(let s of e.currentFrameMove)s.active&&t.active&&this.entityCurrentlyUnderPointer(t,s.pointerId)&&(t.events.emit("pointermove",s),e.isDragging(s.pointerId)&&t.events.emit("pointerdragmove",s)),i.set(s.pointerId,s);return i}_processEnterLeaveAndEmit(t,e){let i=this._engineReceiver;for(let s of e){if(s.active&&t.active&&this.entered(t,s.pointerId)){t.events.emit("pointerenter",s),i.isDragging(s.pointerId)&&t.events.emit("pointerdragenter",s);break}if(s.active&&t.active&&(this.left(t,s.pointerId)||this.entityCurrentlyUnderPointer(t,s.pointerId)&&"up"===s.type)){t.events.emit("pointerleave",s),i.isDragging(s.pointerId)&&t.events.emit("pointerdragleave",s);break}}}_processCancelAndEmit(t){for(let e of this._engineReceiver.currentFrameCancel)e.active&&t.active&&this.entityCurrentlyUnderPointer(t,e.pointerId)&&t.events.emit("pointercancel",e)}_processWheelAndEmit(t){for(let e of this._engineReceiver.currentFrameWheel)e.active&&t.active&&this.entityCurrentlyUnderPointer(t,0)&&t.events.emit("pointerwheel",e)}_dispatchEvents(t){let e,i;let s=new Set(this.lastFrameEntityToPointers.keys()),r=new Set(this.currentFrameEntityToPointers.keys());for(let n of t.filter(t=>s.has(t.id)||r.has(t.id))){i=this._processDownAndEmit(n),e=this._processUpAndEmit(n);let t=[...this._processMoveAndEmit(n).values(),...i.values(),...e.values()];this._processEnterLeaveAndEmit(n,t),this._processCancelAndEmit(n),this._processWheelAndEmit(n)}}}class rE extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Update,this.priority=ri.Higher,this._actions=[],this.query=this.world.query([sZ]),this.query.entityAdded$.subscribe(t=>this._actions.push(t.get(sZ))),this.query.entityRemoved$.subscribe(t=>{let e=t.get(sZ),i=this._actions.indexOf(e);i>-1&&this._actions.splice(i,1)})}update(t){for(let e of this._actions)e.update(t)}}class rP extends iZ{constructor(t){super(),this.elevation=0,this.columns=t.columns,this.rows=t.rows,this.tileWidth=t.tileWidth,this.tileHeight=t.tileHeight}}class rI extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Update,this.priority=ri.Lower,this.query=this.world.query([iV,rP])}update(){let t,e;for(let i of this.query.entities){t=i.get(iV);let s=Math.max((e=i.get(rP)).columns*e.tileWidth,e.rows*e.tileHeight)*e.elevation+t.pos.y;t.z=s}}}class rk extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Draw,this.priority=ri.Higher,this.query=this.world.query([iV,sm])}initialize(t,e){this._camera=e.camera,this._screen=e.engine.screen}update(){let t,e,i;for(let s of(this._worldBounds=this._screen.getWorldBounds(),this.query.entities)){let r;if(e=s.get(sm),t=s.get(iV),i=s.get(sK)){let t=tN.One.sub(i.parallaxFactor);r=this._camera.pos.scale(t)}let n=this._isOffscreen(t,e,r);n&&!s.hasTag("ex.offscreen")&&(s.events.emit("exitviewport",new ip(s)),s.addTag("ex.offscreen")),!n&&s.hasTag("ex.offscreen")&&(s.events.emit("enterviewport",new ig(s)),s.removeTag("ex.offscreen"))}}_isOffscreen(t,e,i){if(t.coordPlane!==j.World)return!1;{let s=e.localBounds;i&&(s=s.translate(i));let r=s.transform(t.get().matrix);return!this._worldBounds.overlaps(r)}}}class rD{get config(){var t;return(t=this._config)&&void 0===t.__isProxy?new Proxy(t,t7([],t=>{this.$configUpdate.notifyAll(t)},t)):t}set config(t){this._config=t,this.$configUpdate.notifyAll(t)}get collisionProcessor(){if(this._configDirty){this._configDirty=!1;let t=this._collisionProcessor.getColliders();for(let e of(this._collisionProcessor=new iQ(this._config),t))this._collisionProcessor.track(e)}return this._collisionProcessor}constructor(t){this.$configUpdate=new iH,this._configDirty=!1,this.config=t,this.$configUpdate.subscribe(t=>{this._configDirty=!0,sh.updateDefaultPhysicsConfig(t.bodies)}),this._collisionProcessor=new iQ(this.config)}rayCast(t,e){return this.collisionProcessor.rayCast(t,e)}}class rR{constructor(){this.events=new tP,this.enabled=!1,this.supported=!!navigator.getGamepads,this._gamePadTimeStamps=[0,0,0,0],this._oldPads=[],this._pads=[],this._initSuccess=!1,this._navigator=navigator,this._minimumConfiguration=null,this._enabled=!0}init(){this.supported&&!this._initSuccess&&(this._oldPads=this._clonePads(this._navigator.getGamepads()),this._oldPads.length&&this._oldPads[0]&&(this._initSuccess=!0))}toggleEnabled(t){this._enabled=t}setMinimumGamepadConfiguration(t){this._enableAndUpdate(),this._minimumConfiguration=t}_enableAndUpdate(){this.enabled||(this.enabled=!0,this.update())}_isGamepadValid(t){if(!this._minimumConfiguration)return!0;if(!t)return!1;let e=t.axes.filter(t=>!0).length,i=t.buttons.filter(t=>!0).length;return e>=this._minimumConfiguration.axis&&i>=this._minimumConfiguration.buttons&&t.connected}emit(t,e){this.events.emit(t,e)}on(t,e){return this._enableAndUpdate(),this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this._enableAndUpdate(),this.events.off(t,e)}update(){if(!this.enabled||!this.supported||!this._enabled)return;this.init();let t=this._navigator.getGamepads();for(let e=0;e=this._pads.length)for(let e=this._pads.length-1;et.connected).length}_clonePads(t){let e=[];for(let i=0,s=t.length;i=e}isButtonHeld(t,e=1){return this._buttons[t]>=e}wasButtonPressed(t,e=1){return this._buttonsDown[t]>=e}wasButtonReleased(t){return!!this._buttonsUp[t]}getButton(t){return this._buttons[t]}getAxes(t){let e=this._axes[t];return Math.abs(e){};window.top.addEventListener("blur",t),window.top.removeEventListener("blur",t)}catch(t){return!0}return!1}(D=tu||(tu={})).Num0="Numpad0",D.Num1="Numpad1",D.Num2="Numpad2",D.Num3="Numpad3",D.Num4="Numpad4",D.Num5="Numpad5",D.Num6="Numpad6",D.Num7="Numpad7",D.Num8="Numpad8",D.Num9="Numpad9",D.NumAdd="NumpadAdd",D.NumSubtract="NumpadSubtract",D.NumMultiply="NumpadMultiply",D.NumDivide="NumpadDivide",D.NumDecimal="NumpadDecimal",D.Numpad0="Numpad0",D.Numpad1="Numpad1",D.Numpad2="Numpad2",D.Numpad3="Numpad3",D.Numpad4="Numpad4",D.Numpad5="Numpad5",D.Numpad6="Numpad6",D.Numpad7="Numpad7",D.Numpad8="Numpad8",D.Numpad9="Numpad9",D.NumpadAdd="NumpadAdd",D.NumpadSubtract="NumpadSubtract",D.NumpadMultiply="NumpadMultiply",D.NumpadDivide="NumpadDivide",D.NumpadDecimal="NumpadDecimal",D.NumLock="NumLock",D.ShiftLeft="ShiftLeft",D.ShiftRight="ShiftRight",D.AltLeft="AltLeft",D.AltRight="AltRight",D.ControlLeft="ControlLeft",D.ControlRight="ControlRight",D.MetaLeft="MetaLeft",D.MetaRight="MetaRight",D.Key0="Digit0",D.Key1="Digit1",D.Key2="Digit2",D.Key3="Digit3",D.Key4="Digit4",D.Key5="Digit5",D.Key6="Digit6",D.Key7="Digit7",D.Key8="Digit8",D.Key9="Digit9",D.Digit0="Digit0",D.Digit1="Digit1",D.Digit2="Digit2",D.Digit3="Digit3",D.Digit4="Digit4",D.Digit5="Digit5",D.Digit6="Digit6",D.Digit7="Digit7",D.Digit8="Digit8",D.Digit9="Digit9",D.F1="F1",D.F2="F2",D.F3="F3",D.F4="F4",D.F5="F5",D.F6="F6",D.F7="F7",D.F8="F8",D.F9="F9",D.F10="F10",D.F11="F11",D.F12="F12",D.A="KeyA",D.B="KeyB",D.C="KeyC",D.D="KeyD",D.E="KeyE",D.F="KeyF",D.G="KeyG",D.H="KeyH",D.I="KeyI",D.J="KeyJ",D.K="KeyK",D.L="KeyL",D.M="KeyM",D.N="KeyN",D.O="KeyO",D.P="KeyP",D.Q="KeyQ",D.R="KeyR",D.S="KeyS",D.T="KeyT",D.U="KeyU",D.V="KeyV",D.W="KeyW",D.X="KeyX",D.Y="KeyY",D.Z="KeyZ",D.KeyA="KeyA",D.KeyB="KeyB",D.KeyC="KeyC",D.KeyD="KeyD",D.KeyE="KeyE",D.KeyF="KeyF",D.KeyG="KeyG",D.KeyH="KeyH",D.KeyI="KeyI",D.KeyJ="KeyJ",D.KeyK="KeyK",D.KeyL="KeyL",D.KeyM="KeyM",D.KeyN="KeyN",D.KeyO="KeyO",D.KeyP="KeyP",D.KeyQ="KeyQ",D.KeyR="KeyR",D.KeyS="KeyS",D.KeyT="KeyT",D.KeyU="KeyU",D.KeyV="KeyV",D.KeyW="KeyW",D.KeyX="KeyX",D.KeyY="KeyY",D.KeyZ="KeyZ",D.Semicolon="Semicolon",D.Quote="Quote",D.Comma="Comma",D.Minus="Minus",D.Period="Period",D.Slash="Slash",D.Equal="Equal",D.BracketLeft="BracketLeft",D.Backslash="Backslash",D.BracketRight="BracketRight",D.Backquote="Backquote",D.Up="ArrowUp",D.Down="ArrowDown",D.Left="ArrowLeft",D.Right="ArrowRight",D.ArrowUp="ArrowUp",D.ArrowDown="ArrowDown",D.ArrowLeft="ArrowLeft",D.ArrowRight="ArrowRight",D.Space="Space",D.Backspace="Backspace",D.Delete="Delete",D.Esc="Escape",D.Escape="Escape",D.Enter="Enter",D.NumpadEnter="NumpadEnter",D.ContextMenu="ContextMenu";class rL extends eV{constructor(t,e,i){super(),this.key=t,this.value=e,this.originalEvent=i}}class rz{constructor(){this.events=new tP,this._enabled=!0,this._keys=[],this._keysUp=[],this._keysDown=[],this._releaseAllKeys=t=>{for(let e of this._keys){let i=new rL(e,t.key,t);this.events.emit("up",i),this.events.emit("release",i)}this._keysUp=Array.from(new Set(this._keys.concat(this._keysUp))),this._keys.length=0},this._handleKeyDown=t=>{if(!this._enabled)return;!t.metaKey&&(this._keys.includes(tu.MetaLeft)||this._keys.includes(tu.MetaRight))&&this._releaseAllKeys(t);let e=t.code;if(-1===this._keys.indexOf(e)){this._keys.push(e),this._keysDown.push(e);let i=new rL(e,t.key,t);this.events.emit("down",i),this.events.emit("press",i)}},this._handleKeyUp=t=>{if(!this._enabled)return;let e=t.code,i=this._keys.indexOf(e);this._keys.splice(i,1),this._keysUp.push(e);let s=new rL(e,t.key,t);this.events.emit("up",s),this.events.emit("release",s),"Meta"===t.key&&this._releaseAllKeys(t)}}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}init(t){let{global:e}=t,{grabWindowFocus:i}=t;e||(rM()?(e=window,i&&window.focus(),tW.getInstance().warn("Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus")):e=window.top),e.addEventListener("blur",()=>{this._keys.length=0}),e.addEventListener("keyup",this._handleKeyUp),e.addEventListener("keydown",this._handleKeyDown)}toggleEnabled(t){this._enabled=t}update(){this._keysDown.length=0,this._keysUp.length=0;for(let t=0;t-1}isHeld(t){return this._keys.indexOf(t)>-1}wasReleased(t){return this._keysUp.indexOf(t)>-1}triggerEvent(t,e,i){"down"===t&&this._handleKeyDown(new KeyboardEvent("keydown",{code:e,key:null!=i?i:null})),"up"===t&&this._handleKeyUp(new KeyboardEvent("keyup",{code:e,key:null!=i?i:null}))}}class rO{static fromPagePosition(t,e,i){let s,r;3==arguments.length?(s=new tN(t,e),r=i):((s=t).x,s.y,r=e);let n=r.screen.pageToScreenCoordinates(s);return new rO(r.screen.screenToWorldCoordinates(n),s,n)}constructor(t,e,i){this.worldPos=t,this.pagePos=e,this.screenPos=i}}class rU{cancel(){this.active=!1}get pagePos(){return this.coordinates.pagePos}get screenPos(){return this.coordinates.screenPos}get worldPos(){return this.coordinates.worldPos}constructor(t,e,i,s,r,n){this.type=t,this.pointerId=e,this.button=i,this.pointerType=s,this.coordinates=r,this.nativeEvent=n,this.active=!0}}class rN{cancel(){this.active=!1}constructor(t,e,i,s,r,n,o,a,l,h,d,c){this.x=t,this.y=e,this.pageX=i,this.pageY=s,this.screenX=r,this.screenY=n,this.index=o,this.deltaX=a,this.deltaY=l,this.deltaZ=h,this.deltaMode=d,this.ev=c,this.active=!0}}class rZ{constructor(){this.events=new tP,this.lastPagePos=tN.Zero,this.lastScreenPos=tN.Zero,this.lastWorldPos=tN.Zero,this._onPointerMove=t=>{this.lastPagePos=new tN(t.pagePos.x,t.pagePos.y),this.lastScreenPos=new tN(t.screenPos.x,t.screenPos.y),this.lastWorldPos=new tN(t.worldPos.x,t.worldPos.y)},this._onPointerDown=t=>{this.lastPagePos=new tN(t.pagePos.x,t.pagePos.y),this.lastScreenPos=new tN(t.screenPos.x,t.screenPos.y),this.lastWorldPos=new tN(t.worldPos.x,t.worldPos.y)},this.on("move",this._onPointerMove),this.on("down",this._onPointerDown)}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}}(R=tp||(tp={})).Pixel="Pixel",R.Line="Line",R.Page="Page",(F=tg||(tg={}))[F.NoButton=-1]="NoButton",F[F.Left=0]="Left",F[F.Middle=1]="Middle",F[F.Right=2]="Right",F[F.Unknown=3]="Unknown",(B=t_||(t_={})).Left="Left",B.Middle="Middle",B.Right="Right",B.Unknown="Unknown",B.NoButton="NoButton",(M=tf||(tf={})).Touch="Touch",M.Mouse="Mouse",M.Pen="Pen",M.Unknown="Unknown";class rH{constructor(t,e){this.target=t,this.engine=e,this.events=new tP,this.primary=new rZ,this._activeNativePointerIdsToNormalized=new Map,this.lastFramePointerCoords=new Map,this.currentFramePointerCoords=new Map,this.currentFramePointerDown=new Map,this.lastFramePointerDown=new Map,this.currentFrameDown=[],this.currentFrameUp=[],this.currentFrameMove=[],this.currentFrameCancel=[],this.currentFrameWheel=[],this._enabled=!0,this._pointers=[this.primary],this._boundHandle=this._handle.bind(this),this._boundWheel=this._handleWheel.bind(this)}toggleEnabled(t){this._enabled=t}recreate(t,e){let i=new rH(t,e);return i.primary=this.primary,i._pointers=this._pointers,i}at(t){if(t>=this._pointers.length)for(let e=this._pointers.length-1;e{window.focus()};window.PointerEvent?this.target.addEventListener("pointerdown",t):(this.target.addEventListener("touchstart",t),this.target.addEventListener("mousedown",t))}}detach(){window.PointerEvent?(this.target.removeEventListener("pointerdown",this._boundHandle),this.target.removeEventListener("pointerup",this._boundHandle),this.target.removeEventListener("pointermove",this._boundHandle),this.target.removeEventListener("pointercancel",this._boundHandle)):(this.target.removeEventListener("touchstart",this._boundHandle),this.target.removeEventListener("touchend",this._boundHandle),this.target.removeEventListener("touchmove",this._boundHandle),this.target.removeEventListener("touchcancel",this._boundHandle),this.target.removeEventListener("mousedown",this._boundHandle),this.target.removeEventListener("mouseup",this._boundHandle),this.target.removeEventListener("mousemove",this._boundHandle)),"onwheel"in document.createElement("div")?this.target.removeEventListener("wheel",this._boundWheel):void 0!==document.onmousewheel?this.target.addEventListener("mousewheel",this._boundWheel):this.target.addEventListener("MozMousePixelScroll",this._boundWheel)}_normalizePointerId(t){this._activeNativePointerIdsToNormalized.set(t,-1);let e=Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((t,e)=>t-e).findIndex(e=>e===t);return this._activeNativePointerIdsToNormalized.set(t,e),e}_handle(t){let e,i;if(!this._enabled)return;t.preventDefault();let s=new Map;if(globalThis.TouchEvent&&t instanceof globalThis.TouchEvent){e=t_.Unknown,i=tf.Touch;for(let e=0;et instanceof sj)}get entities(){return this.world.entityManager.entities}get triggers(){return this.world.entityManager.entities.filter(t=>t instanceof re)}get tileMaps(){return this.world.entityManager.entities.filter(t=>t instanceof sJ)}get timers(){return this._timers}constructor(){this._logger=tW.getInstance(),this.events=new tP,this.camera=new s7,this.world=new rd(this),this.physics=new rD(i4),this._isInitialized=!1,this._timers=[],this._cancelQueue=[],this.world.add(rE),this.world.add(new ru(this.world,this.physics)),this.world.add(new rf(this.world,this.physics)),this.world.add(rA),this.world.add(rI),this.world.add(rk),this.world.add(rT),this.world.add(rS)}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}onPreLoad(t){}onTransition(t){}onInitialize(t){}onActivate(t){}onDeactivate(t){}onPreUpdate(t,e){}onPostUpdate(t,e){}onPreDraw(t,e){}onPostDraw(t,e){}_initializeChildren(){for(let t of this.entities)t._initialize(this.engine)}get isInitialized(){return this._isInitialized}async _initialize(t){var e;if(!this.isInitialized){try{this.engine=t,this.physics.config=this.engine.physics,this.input=new rV({pointerTarget:t.pointerScope===O.Canvas?t.canvas:document,grabWindowFocus:t.grabWindowFocus,engine:t}),this.camera._initialize(t),this.world.systemManager.initialize(),await this.onInitialize(t),this._initializeChildren(),this._logger.debug("Scene.onInitialize",this,t),this.events.emit("initialize",new id(t,this))}catch(i){throw this._logger.error(`Error during scene initialization for scene ${null===(e=t.director)||void 0===e?void 0:e.getSceneName(this)}!`),i}this._isInitialized=!0}}async _activate(t){var e,i;try{this._logger.debug("Scene.onActivate",this),this.input.toggleEnabled(!0),await this.onActivate(t)}catch(t){throw this._logger.error(`Error during scene activation for scene ${null===(i=null===(e=this.engine)||void 0===e?void 0:e.director)||void 0===i?void 0:i.getSceneName(this)}!`),t}}async _deactivate(t){this._logger.debug("Scene.onDeactivate",this),this.input.toggleEnabled(!1),await this.onDeactivate(t)}_preupdate(t,e){this.emit("preupdate",new e1(t,e,this)),this.onPreUpdate(t,e)}_postupdate(t,e){this.emit("postupdate",new e2(t,e,this)),this.onPostUpdate(t,e)}_predraw(t,e){this.emit("predraw",new e$(t,e,this)),this.onPreDraw(t,e)}_postdraw(t,e){this.emit("postdraw",new eK(t,e,this)),this.onPostDraw(t,e)}update(t,e){var i;let s,r;if(!this.isInitialized){this._logger.warnOnce(`Scene update called before initialize for scene ${null===(i=t.director)||void 0===i?void 0:i.getSceneName(this)}!`);return}for(this._preupdate(t,e),s=0,r=this._cancelQueue.length;s-1}add(t){if(this.emit("entityadded",{target:t}),this.world.add(t),t.scene=this,t instanceof s$){tY(this._timers,t)||this.addTimer(t);return}}transfer(t){let e;t instanceof s_&&t.scene&&t.scene!==this&&(e=t.scene,t.scene.world.remove(t,!1)),t instanceof s$&&t.scene&&(e=t.scene,t.scene.removeTimer(t)),null==e||e.emit("entityremoved",{target:t}),this.add(t)}remove(t){t instanceof s_&&(this.emit("entityremoved",{target:t}),t.active&&t.kill(),this.world.remove(t)),t instanceof s$&&this.removeTimer(t)}clear(t=!0){for(let e=this.entities.length-1;e>=0;e--)this.world.remove(this.entities[e],t);for(let t=this.timers.length-1;t>=0;t--)this.removeTimer(this.timers[t])}addTimer(t){return this._timers.push(t),t.scene=this,t}removeTimer(t){let e=this._timers.indexOf(t);return -1!==e&&this._timers.splice(e,1),t}cancelTimer(t){return this._cancelQueue.push(t),t}isTimerActive(t){return this._timers.indexOf(t)>-1&&!t.complete}isCurrentScene(){return!!this.engine&&this.engine.currentScene===this}_collectActorStats(t){for(let e of this.actors.filter(t=>t instanceof sX))t.stats.currFrame.actors.ui++;for(let e of this.actors)for(let i of(t.stats.currFrame.actors.alive++,e.children))sq(i)?t.stats.currFrame.actors.ui++:t.stats.currFrame.actors.alive++}}(L=tm||(tm={})).Protanope="Protanope",L.Deuteranope="Deuteranope",L.Tritanope="Tritanope";class rX{constructor(t,e){this._shader=new eu({gl:t,vertexSource:`#version 300 es + `}}ij.All=new ij("Collide with all groups",-1,-1);class iq{constructor(t,e){this.colliderA=t,this.colliderB=e,this.id=null,this.id=iq.calculatePairHash(t.id,e.id)}static canCollide(t,e){var i,s;let r=null===(i=null==t?void 0:t.owner)||void 0===i?void 0:i.get(sh),n=null===(s=null==e?void 0:e.owner)||void 0===s?void 0:s.get(sh);return!(t.id===e.id||t.owner&&e.owner&&t.owner.id===e.owner.id||t.localBounds.hasZeroDimensions()||e.localBounds.hasZeroDimensions())&&!!r&&!!n&&!!r.group.canCollide(n.group)&&(r.collisionType!==G.Fixed||n.collisionType!==G.Fixed)&&n.collisionType!==G.PreventCollision&&r.collisionType!==G.PreventCollision&&!!r.active&&!!n.active}get canCollide(){let t=this.colliderA,e=this.colliderB;return iq.canCollide(t,e)}collide(){return this.colliderA.collide(this.colliderB)}hasCollider(t){return t===this.colliderA||t===this.colliderB}static calculatePairHash(t,e){return t.valuet.min&&t.max>this.min}getOverlap(t){return this.overlaps(t)?this.max>t.max?t.max-this.min:this.max-t.min:0}}class i${constructor(t){this.parent=t,this.parent=t||null,this.data=null,this.bounds=new tq,this.left=null,this.right=null,this.height=0}isLeaf(){return!this.left&&!this.right}}class iK{constructor(t,e=new tq(-Number.MAX_VALUE,-Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE)){this._config=t,this.worldBounds=e,this.root=null,this.nodes={}}_insert(t){if(null===this.root){this.root=t,this.root.parent=null;return}let e=t.bounds,i=this.root;for(;!i.isLeaf();){let t;let s=i.left,r=i.right,n=i.bounds.getPerimeter(),o=i.bounds.combine(e).getPerimeter(),a=2*o,l=2*(o-n),h=0,d=e.combine(s.bounds);s.isLeaf()?h=d.getPerimeter()+l:(t=s.bounds.getPerimeter(),h=d.getPerimeter()-t+l);let c=0,u=e.combine(r.bounds);if(r.isLeaf()?c=u.getPerimeter()+l:(t=r.bounds.getPerimeter(),c=u.getPerimeter()-t+l),a1)return i.left=t,i.parent=t.parent,t.parent=i,i.parent?i.parent.left===t?i.parent.left=i:i.parent.right=i:this.root=i,n.height>o.height?(i.right=n,t.right=o,o.parent=t,t.bounds=e.bounds.combine(o.bounds),i.bounds=t.bounds.combine(n.bounds),t.height=1+Math.max(e.height,o.height),i.height=1+Math.max(t.height,n.height)):(i.right=o,t.right=n,n.parent=t,t.bounds=e.bounds.combine(n.bounds),i.bounds=t.bounds.combine(o.bounds),t.height=1+Math.max(e.height,n.height),i.height=1+Math.max(t.height,o.height)),i;if(a<-1){if(e.left=t,e.parent=t.parent,t.parent=e,e.parent){if(e.parent.left===t)e.parent.left=e;else{if(e.parent.right!==t)throw"Error rotating Dynamic Tree";e.parent.right=e}}else this.root=e;return s.height>r.height?(e.right=s,t.left=r,r.parent=t,t.bounds=i.bounds.combine(r.bounds),e.bounds=t.bounds.combine(s.bounds),t.height=1+Math.max(i.height,r.height),e.height=1+Math.max(t.height,s.height)):(e.right=r,t.left=s,s.parent=t,t.bounds=i.bounds.combine(s.bounds),e.bounds=t.bounds.combine(r.bounds),t.height=1+Math.max(i.height,s.height),e.height=1+Math.max(t.height,r.height)),e}return t}getHeight(){return null===this.root?0:this.root.height}query(t,e){let i=t.bounds,s=r=>{if(r&&r.bounds.overlaps(i)){if(!r.isLeaf()||r.data===t)return s(r.left)||s(r.right);if(e.call(t,r.data))return!0}return!1};s(this.root)}rayCastQuery(t,e=1/0,i){let s=r=>{if(r&&r.bounds.rayCast(t,e)){if(!r.isLeaf())return s(r.left)||s(r.right);if(i.call(t,r.data))return!0}return!1};s(this.root)}getNodes(){let t=e=>e?[e].concat(t(e.left),t(e.right)):[];return t(this.root)}debug(t){let e=i=>{i&&(i.isLeaf()?i.bounds.draw(t,tH.Green):i.bounds.draw(t,tH.White),i.left&&e(i.left),i.right&&e(i.right))};e(this.root)}}class iY{constructor(t,e){this.pos=t,this.dir=e.normalize()}intersect(t){let e=t.begin.sub(this.pos);if(0===this.dir.cross(t.getSlope())&&0!==e.cross(this.dir))return -1;let i=this.dir.cross(t.getSlope());if(0===i)return -1;let s=e.cross(t.getSlope())/i;if(s>=0){let r=e.cross(this.dir)/i/t.getLength();if(r>=0&&r<=1)return s}return -1}intersectPoint(t){let e=this.intersect(t);return e<0?null:this.getPoint(e)}getPoint(t){return this.pos.add(this.dir.scale(t))}}class iQ{constructor(t){this._config=t,this._pairs=new Set,this._collisionPairCache=[],this._colliders=[],this._dynamicCollisionTree=new iK(t.dynamicTree)}getColliders(){return this._colliders}rayCast(t,e){var i,s,r;let n=[],o=null!==(i=null==e?void 0:e.maxDistance)&&void 0!==i?i:1/0,a=null==e?void 0:e.collisionGroup,l=a?a.category:null!==(s=null==e?void 0:e.collisionMask)&&void 0!==s?s:ij.All.category,h=null!==(r=null==e?void 0:e.searchAllColliders)&&void 0!==r&&r;return this._dynamicCollisionTree.rayCastQuery(t,o,i=>{let s=i.owner.get(sh);if((null==e?void 0:e.ignoreCollisionGroupAll)&&s.group===ij.All)return!1;let r=(l&s.group.category)!=0;if((null==s?void 0:s.group)&&!r)return!1;let a=i.rayCast(t,o);if(a){if(null==e?void 0:e.filter){if(e.filter(a)&&(n.push(a),!h))return!0}else if(n.push(a),!h)return!0}return!1}),n}track(t){if(!t){tW.getInstance().warn("Cannot track null collider");return}if(t instanceof i9)for(let e of t.getColliders())e.owner=t.owner,this._colliders.push(e),this._dynamicCollisionTree.trackCollider(e);else this._colliders.push(t),this._dynamicCollisionTree.trackCollider(t)}untrack(t){if(!t){tW.getInstance().warn("Cannot untrack a null collider");return}if(t instanceof i9)for(let e of t.getColliders()){let t=this._colliders.indexOf(e);-1!==t&&this._colliders.splice(t,1),this._dynamicCollisionTree.untrackCollider(e)}else{let e=this._colliders.indexOf(t);-1!==e&&this._colliders.splice(e,1),this._dynamicCollisionTree.untrackCollider(t)}}_pairExists(t,e){let i=iq.calculatePairHash(t.id,e.id);return this._pairs.has(i)}broadphase(t,e,i){let s;let r=e/1e3,n=t.filter(t=>{var e,i;let s=null===(e=t.owner)||void 0===e?void 0:e.get(sh);return(null===(i=t.owner)||void 0===i?void 0:i.active)&&s.collisionType!==G.PreventCollision});this._collisionPairCache=[],this._pairs.clear();for(let t=0,e=n.length;t{if(!this._pairExists(s,t)&&iq.canCollide(s,t)){let e=new iq(s,t);this._pairs.add(e.id),this._collisionPairCache.push(e)}return!1});if(i&&(i.physics.pairs=this._collisionPairCache.length),this._config.continuous.checkForFastBodies)for(let t of n){let e=t.owner.get(sh);if(e.collisionType!==G.Active)continue;let s=e.vel.size*r+.5*e.acc.size*r*r,n=Math.min(t.bounds.height,t.bounds.width);if(this._config.continuous.disableMinimumSpeedForFastBody||s>n/2){let r;i&&i.physics.fastBodies++;let n=e.globalPos.sub(e.oldPos),o=t.center,a=t.getFurthestPoint(e.vel),l=a.sub(n),h=new iY(l,e.vel);h.pos=h.pos.add(h.dir.scale(-2*this._config.continuous.surfaceEpsilon));let d=new tN(1/0,1/0);if(this._dynamicCollisionTree.rayCastQuery(h,s+2*this._config.continuous.surfaceEpsilon,e=>{if(!this._pairExists(t,e)&&iq.canCollide(t,e)){let t=e.rayCast(h,s+10*this._config.continuous.surfaceEpsilon);if(t){let i=t.point.sub(l);i.size0)for(let t of r)e.physics.contacts.set(t.id,t)}return e&&(e.physics.collisions+=i.length),i}update(t){let e=0,i=t.length;for(let s=0;se.offset.addEqual(t.offset)):e=[t],e))i.events.pipe(this.events),i.composite=this,this._colliders.push(i),this._collisionProcessor.track(i),this._dynamicAABBTree.trackCollider(i)}removeCollider(t){t.events.pipe(this.events),t.composite=null,tK(t,this._colliders),this._collisionProcessor.untrack(t),this._dynamicAABBTree.untrackCollider(t)}getColliders(){return this._colliders}get worldPos(){var t,e;return(null!==(e=null===(t=this._transform)||void 0===t?void 0:t.pos)&&void 0!==e?e:tN.Zero).add(this.offset)}get center(){var t,e;return(null!==(e=null===(t=this._transform)||void 0===t?void 0:t.pos)&&void 0!==e?e:tN.Zero).add(this.offset)}get bounds(){var t,e;let i=this.getColliders();return i.reduce((t,e)=>t.combine(e.bounds),null!==(e=null===(t=i[0])||void 0===t?void 0:t.bounds)&&void 0!==e?e:new tq().translate(this.worldPos)).translate(this.offset)}get localBounds(){var t,e;let i=this.getColliders();return i.reduce((t,e)=>t.combine(e.localBounds),null!==(e=null===(t=i[0])||void 0===t?void 0:t.localBounds)&&void 0!==e?e:new tq)}get axes(){let t=this.getColliders(),e=[];for(let i of t)e=e.concat(i.axes);return e}getFurthestPoint(t){let e=this.getColliders(),i=[];for(let s of e)i.push(s.getFurthestPoint(t));let s=i[0],r=-Number.MAX_VALUE;for(let e of i){let i=e.dot(t);i>r&&(s=e,r=i)}return s}getInertia(t){let e=this.getColliders(),i=0;for(let s of e)i+=s.getInertia(t);return i}collide(t){let e=[t];t instanceof i9&&(e=t.getColliders());let i=[];for(let t of e)this._dynamicAABBTree.query(t,e=>(i.push(new iq(t,e)),!1));let s=[];for(let t of i)s=s.concat(t.collide());return s}getClosestLineBetween(t){let e=this.getColliders(),i=[];if(t instanceof i9){let s=t.getColliders();for(let t of e)for(let e of s){let s=t.getClosestLineBetween(e);s&&i.push(s)}}else for(let s of e){let e=t.getClosestLineBetween(s);e&&i.push(e)}if(i.length){let t=i[0].getLength(),e=i[0];for(let s of i){let i=s.getLength();it.clone()));return t.offset=this.offset.clone(),t}}class i6{constructor(t,e){this.begin=t,this.end=e}get slope(){return(this.end.y-this.begin.y)/(this.end.x-this.begin.x)}get intercept(){return this.begin.y-this.slope*this.begin.x}normal(){return this._normal?this._normal:this._normal=this.end.sub(this.begin).normal()}dir(){return this._dir?this._dir:this._dir=this.end.sub(this.begin)}getPoints(){return[this.begin,this.end]}getSlope(){if(this._slope)return this._slope;let t=this.begin,e=this.end,i=t.distance(e);return this._slope=e.sub(t).scale(1/i)}getEdge(){let t=this.begin;return this.end.sub(t)}getLength(){if(this._length)return this._length;let t=this.begin,e=this.end,i=t.distance(e);return this._length=i}get midpoint(){return this.begin.add(this.end).scale(.5)}flip(){return new i6(this.end,this.begin)}below(t){return(this.end.x-this.begin.x)*(t.y-this.begin.y)-(this.end.y-this.begin.y)*(t.x-this.begin.x)>=0}clip(t,e){let i=t,s=(i=i.normalize()).dot(this.begin)-e,r=i.dot(this.end)-e,n=[];return(s<=0&&n.push(this.begin),r<=0&&n.push(this.end),s*r<0&&n.push(this.begin.add(this.end.sub(this.begin).scale(s/(s-r)))),2!==n.length)?null:new i6(n[0],n[1])}distanceToPoint(t,e=!1){let i=t.x,s=t.y,r=this.getLength(),n=((this.end.y-this.begin.y)*i-(this.end.x-this.begin.x)*s+this.end.x*this.begin.y-this.end.y*this.begin.x)/r;return e?n:Math.abs(n)}findVectorToPoint(t){let e=this.begin.sub(t),i=this.getSlope();return e.sub(i.scale(e.dot(i)))}findPoint(t=null,e=null){let i=this.slope,s=this.intercept;if(null!==t)return new tN(t,i*t+s);if(null!==e)return new tN((e-s)/i,e);throw Error("You must provide an X or a Y value")}hasPoint(){let t;let e=0;if("number"==typeof arguments[0]&&"number"==typeof arguments[1])t=new tN(arguments[0],arguments[1]),e=arguments[2]||0;else if(arguments[0]instanceof tN)t=arguments[0],e=arguments[1]||0;else throw"Could not determine the arguments for Vector.hasPoint";let i=t.x-this.begin.x,s=t.y-this.begin.y,r=this.end.x-this.begin.x,n=this.end.y-this.begin.y;return!(Math.abs(i*n-s*r)>e)&&(Math.abs(r)>=Math.abs(n)?r>0?this.begin.x<=t.x&&t.x<=this.end.x:this.end.x<=t.x&&t.x<=this.begin.x:n>0?this.begin.y<=t.y&&t.y<=this.end.y:this.end.y<=t.y&&t.y<=this.begin.y)}}function i7(t,e,i,s){let r=t.sub(i),n=e.dot(e),o=e.dot(s),a=s.dot(s),l=e.dot(r),h=s.dot(r),d=n*a-o*o,c=d,u=d;if(0===d||d<=.01)return new i6(t,i.add(s.scale(l/o)));let p=o*h-a*l,g=n*h-o*l;return p<0?(p=0,g=h,u=a):p>c&&(p=c,g=h+o,u=a),g<0?(g=0,0>-l?p=0:-l>n?p=c:(p=-l,c=n)):g>u&&(g=u,-l+o<0?p=0:-l+o>n?p=c:(p=-l+o,c=n)),p=.001>Math.abs(p)?0:p/c,g=.001>Math.abs(g)?0:g/u,new i6(t.add(e.scale(p)),i.add(s.scale(g)))}let i8={PolygonPolygonClosestLine(t,e){let i=e.worldPos,s=i.sub(t.worldPos),r=s.negate(),n=new iY(t.worldPos,s),o=new iY(i,r),a=t.rayCast(n).point.add(n.dir.scale(.1)),l=e.rayCast(o).point.add(o.dir.scale(.1)),h=t.getClosestFace(a),d=e.getClosestFace(l),c=h.face.begin;return i7(c,h.face.getEdge(),d.face.begin,d.face.getEdge())},PolygonEdgeClosestLine(t,e){let i=e.worldPos.sub(t.worldPos),s=new iY(t.worldPos,i),r=t.rayCast(s).point.add(s.dir.scale(.1)),n=t.getClosestFace(r),o=n.face.begin,a=n.face.getEdge(),l=e.asLine();return i7(o,a,l.begin,l.getEdge())},PolygonCircleClosestLine(t,e){let i=e.worldPos,s=i.sub(t.worldPos),r=new iY(t.worldPos,s.normalize()),n=t.rayCast(r).point.add(r.dir.scale(.1)),o=t.getClosestFace(n),a=o.face.begin,l=o.face.getEdge(),h=(l.x*(i.x-a.x)+l.y*(i.y-a.y))/(l.x*l.x+l.y*l.y);h>1?h=1:h<0&&(h=0);let d=Math.sqrt(Math.pow(a.x+l.x*h-i.x,2)+Math.pow(a.y+l.y*h-i.y,2))-e.radius,c=(a.x+l.x*h-i.x)*e.radius/(e.radius+d),u=(a.y+l.y*h-i.y)*e.radius/(e.radius+d);return new i6(l.scale(h).add(a),new tN(i.x+c,i.y+u))},CircleCircleClosestLine(t,e){let i=e.worldPos.sub(t.worldPos),s=t.worldPos.sub(e.worldPos),r=new iY(t.worldPos,i),n=new iY(e.worldPos,s),o=t.rayCast(r),a=e.rayCast(n);return new i6(o.point,a.point)},CircleEdgeClosestLine(t,e){let i=t.worldPos,s=e.asLine(),r=s.begin,n=s.getEdge(),o=(n.x*(i.x-r.x)+n.y*(i.y-r.y))/(n.x*n.x+n.y*n.y);o>1?o=1:o<0&&(o=0);let a=Math.sqrt(Math.pow(r.x+n.x*o-i.x,2)+Math.pow(r.y+n.y*o-i.y,2))-t.radius,l=(r.x+n.x*o-i.x)*t.radius/(t.radius+a),h=(r.y+n.y*o-i.y)*t.radius/(t.radius+a);return new i6(n.scale(o).add(r),new tN(i.x+l,i.y+h))},EdgeEdgeClosestLine(t,e){let i=t.asLine(),s=i.begin,r=i.getEdge(),n=e.asLine();return i7(s,r,n.begin,n.getEdge())}};class st extends iJ{get worldPos(){return this._globalMatrix.getPosition()}get radius(){var t;let e=this._transform,i=null!==(t=null==e?void 0:e.globalScale)&&void 0!==t?t:tN.One;return this._naturalRadius*Math.min(i.x,i.y)}set radius(t){var e;let i=this._transform,s=null!==(e=null==i?void 0:i.globalScale)&&void 0!==e?e:tN.One;this._naturalRadius=t/Math.min(s.x,s.y)}constructor(t){super(),this.offset=tN.Zero,this._globalMatrix=t2.identity(),this.offset=t.offset||tN.Zero,this.radius=t.radius||0,this._globalMatrix.translate(this.offset.x,this.offset.y)}clone(){return new st({offset:this.offset.clone(),radius:this.radius})}get center(){return this._globalMatrix.getPosition()}contains(t){var e,i;return(null!==(i=null===(e=this._transform)||void 0===e?void 0:e.pos)&&void 0!==i?i:this.offset).distance(t)<=this.radius}rayCast(t,e=1/0){var i,s;let r=this.center,n=t.dir,o=t.pos,a=Math.sqrt(Math.pow(n.dot(o.sub(r)),2)-Math.pow(o.sub(r).distance(),2)+Math.pow(this.radius,2));if(a<0)return null;{let l=0;if(0===a){if((l=-n.dot(o.sub(r)))>0&&l=0&&h.push(i),l>=0&&h.push(l);let d=Math.min(...h);if(d<=e){let e=t.getPoint(d);return{point:e,normal:e.sub(r).normalize(),collider:this,body:null===(s=this.owner)||void 0===s?void 0:s.get(sh),distance:d}}return null}}}getClosestLineBetween(t){if(t instanceof st)return i8.CircleCircleClosestLine(this,t);if(t instanceof so)return i8.PolygonCircleClosestLine(t,this).flip();if(t instanceof sr)return i8.CircleEdgeClosestLine(this,t).flip();throw Error(`Polygon could not collide with unknown CollisionShape ${typeof t}`)}collide(t){if(t instanceof st)return ss.CollideCircleCircle(this,t);if(t instanceof so)return ss.CollideCirclePolygon(this,t);if(t instanceof sr)return ss.CollideCircleEdge(this,t);throw Error(`Circle could not collide with unknown CollisionShape ${typeof t}`)}getFurthestPoint(t){return this.center.add(t.normalize().scale(this.radius))}getFurthestLocalPoint(t){return t.normalize().scale(this.radius)}get bounds(){var t,e,i;let s=this._transform,r=null!==(t=null==s?void 0:s.globalScale)&&void 0!==t?t:tN.One,n=null!==(e=null==s?void 0:s.globalRotation)&&void 0!==e?e:0,o=null!==(i=null==s?void 0:s.globalPos)&&void 0!==i?i:tN.Zero;return new tq(this.offset.x-this._naturalRadius,this.offset.y-this._naturalRadius,this.offset.x+this._naturalRadius,this.offset.y+this._naturalRadius).rotate(n).scale(r).translate(o)}get localBounds(){return new tq(this.offset.x-this._naturalRadius,this.offset.y-this._naturalRadius,this.offset.x+this._naturalRadius,this.offset.y+this._naturalRadius)}get axes(){return[]}getInertia(t){return t*this.radius*this.radius/2}update(t){var e;this._transform=t,(null!==(e=t.matrix)&&void 0!==e?e:this._globalMatrix).clone(this._globalMatrix),this._globalMatrix.translate(this.offset.x,this.offset.y)}project(t){let e=[],i=this.center.dot(t);return e.push(i),e.push(i+this.radius),e.push(i-this.radius),new iX(Math.min.apply(Math,e),Math.max.apply(Math,e))}debug(t,e,i){var s,r,n,o;let{lineWidth:a}={lineWidth:1,...i},l=this._transform,h=null!==(s=null==l?void 0:l.globalScale)&&void 0!==s?s:tN.One,d=null!==(r=null==l?void 0:l.globalRotation)&&void 0!==r?r:0,c=null!==(n=null==l?void 0:l.globalPos)&&void 0!==n?n:tN.Zero;t.save(),t.translate(c.x,c.y),t.rotate(d),t.scale(h.x,h.y),t.drawCircle(null!==(o=this.offset)&&void 0!==o?o:tN.Zero,this._naturalRadius,tH.Transparent,e,a),t.restore()}}class se{constructor(t,e,i,s,r,n,o,a){var l,h,d,c,u,p;if(this._canceled=!1,this.colliderA=t,this.colliderB=e,this.mtv=i,this.normal=s,this.tangent=r,this.points=n,this.localPoints=o,this.info=a,this.id=iq.calculatePairHash(t.id,e.id),t.composite||e.composite){let i=(null===(l=t.composite)||void 0===l?void 0:l.compositeStrategy)==="separate"?t.id:null!==(d=null===(h=t.composite)||void 0===h?void 0:h.id)&&void 0!==d?d:t.id,s=(null===(c=e.composite)||void 0===c?void 0:c.compositeStrategy)==="separate"?e.id:null!==(p=null===(u=e.composite)||void 0===u?void 0:u.id)&&void 0!==p?p:e.id;this.id+="|"+iq.calculatePairHash(i,s)}}matchAwake(){let t=this.colliderA.owner.get(sh),e=this.colliderB.owner.get(sh);t&&e&&t.sleeping!==e.sleeping&&(t.sleeping&&t.collisionType!==G.Fixed&&e.sleepMotion>=t.wakeThreshold&&t.setSleeping(!1),e.sleeping&&e.collisionType!==G.Fixed&&t.sleepMotion>=e.wakeThreshold&&e.setSleeping(!1))}isCanceled(){return this._canceled}cancel(){this._canceled=!0}}class si{static findPolygonPolygonSeparation(t,e){let i=-Number.MAX_VALUE,s=null,r=null,n=-1,o=null,a=t.getSides(),l=t.getLocalSides();for(let t=0;ti&&(i=c,s=l,r=h,n=t,o=d)}return{collider:t,separation:r?i:99,axis:r,side:s,localSide:l[n],sideId:n,point:o,localPoint:r?e.getFurthestLocalPoint(r.negate()):null}}static findCirclePolygonSeparation(t,e){let i=e.axes,s=e.center.sub(t.worldPos),r=e.getFurthestPoint(s.negate());i.push(r.sub(t.worldPos).normalize());let n=Number.MAX_VALUE,o=null,a=-1;for(let s=0;sr)return[];let o=r-n,a=s.sub(i).normalize(),l=a.perpendicular(),h=a.scale(o),d=t.getFurthestPoint(a),c=t.getFurthestLocalPoint(a);return[new se(t,e,h,a,l,[d],[c],{collider:t,separation:o,axis:a,point:d})]},CollideCirclePolygon(t,e){var i,s;let r=si.findCirclePolygonSeparation(t,e);if(!r)return[];r=0>r.dot(e.center.sub(t.center))?r.negate():r;let n=t.getFurthestPoint(r),o=(null!==(s=null===(i=t.owner)||void 0===i?void 0:i.get(iV))&&void 0!==s?s:new iV).applyInverse(n),a=r.normalize(),l={collider:t,separation:-r.size,axis:a,point:n,localPoint:o,side:e.findSide(a.negate()),localSide:e.findLocalSide(a.negate())};return[new se(t,e,r,a,a.perpendicular(),[n],[o],l)]},CollideCircleEdge(t,e){let i=t.center,s=e.asLine(),r=s.end.sub(s.begin),n=r.dot(s.end.sub(i)),o=r.dot(i.sub(s.begin)),a=e.asLine(),l=e.asLocalLine();if(o<=0){let r=s.begin.sub(i),n=r.dot(r);if(n>t.radius*t.radius)return[];let o=r.normalize(),h=t.radius-Math.sqrt(n),d={collider:t,separation:h,axis:o,point:a.begin,side:a,localSide:l};return[new se(t,e,o.scale(h),o,o.perpendicular(),[a.begin],[l.begin],d)]}if(n<=0){let r=s.end.sub(i),n=r.dot(r);if(n>t.radius*t.radius)return[];let o=r.normalize(),h=t.radius-Math.sqrt(n),d={collider:t,separation:h,axis:o,point:a.end,side:a,localSide:l};return[new se(t,e,o.scale(h),o,o.perpendicular(),[a.end],[l.end],d)]}let h=r.dot(r),d=s.begin.scale(n).add(s.end.scale(o)).scale(1/h),c=i.sub(d),u=c.dot(c);if(u>t.radius*t.radius)return[];let p=r.perpendicular();0>p.dot(i.sub(s.begin))&&(p.x=-p.x,p.y=-p.y),p=p.normalize();let g=t.radius-Math.sqrt(u),_=p.scale(g),f={collider:t,separation:g,axis:p,point:d,side:a,localSide:l};return[new se(t,e,_,p.negate(),p.negate().perpendicular(),[d],[d.sub(e.worldPos)],f)]},CollideEdgeEdge:()=>[],CollidePolygonEdge(t,e){var i;let s=t.center,r=e.center.sub(s).normalize(),n=new so({points:[e.begin,e.end,e.end.add(r.scale(100)),e.begin.add(r.scale(100))],offset:e.offset});n.owner=e.owner,(null===(i=e.owner)||void 0===i?void 0:i.get(iV))&&n.update(e.owner.get(iV).get());let o=this.CollidePolygonPolygon(t,n);return o.length&&(o[0].colliderB=e,o[0].id=iq.calculatePairHash(t.id,e.id)),o},CollidePolygonPolygon(t,e){var i,s,r,n;let o=si.findPolygonPolygonSeparation(t,e);if(o.separation>0)return[];let a=si.findPolygonPolygonSeparation(e,t);if(a.separation>0)return[];let l=o.separation>a.separation?o:a,h=(l.collider===t?e:t).findSide(l.axis.negate()),d=l.side,c=d.dir().normalize(),u=h.clip(c.negate(),-c.dot(d.begin)),p=null;if(u&&(p=u.clip(c,c.dot(d.end))),p){let o=p.getPoints().filter(t=>d.below(t)),a=l.axis,h=a.perpendicular();0>e.center.sub(t.center).dot(a)&&(h=(a=a.negate()).perpendicular());let c=[];if(l.collider===t){let t=null!==(s=null===(i=e.owner)||void 0===i?void 0:i.get(iV))&&void 0!==s?s:new iV;c=o.map(e=>t.applyInverse(e))}else{let e=null!==(n=null===(r=t.owner)||void 0===r?void 0:r.get(iV))&&void 0!==n?n:new iV;c=o.map(t=>e.applyInverse(t))}return[new se(t,e,a.scale(-l.separation),a,h,o,c,l)]}return[]},FindContactSeparation(t,e){var i,s,r,n;let o=t.colliderA,a=null!==(s=null===(i=t.colliderA.owner)||void 0===i?void 0:i.get(iV))&&void 0!==s?s:new iV,l=t.colliderB,h=null!==(n=null===(r=t.colliderB.owner)||void 0===r?void 0:r.get(iV))&&void 0!==n?n:new iV;if(o instanceof st&&l instanceof st)return-(o.radius+l.radius-a.pos.distance(h.pos));if(o instanceof so&&l instanceof so&&t.info.localSide){let i,s;return t.info.collider===o?(i=new i6(a.apply(t.info.localSide.begin),a.apply(t.info.localSide.end)),s=h.apply(e)):(i=new i6(h.apply(t.info.localSide.begin),h.apply(t.info.localSide.end)),s=a.apply(e)),i.distanceToPoint(s,!0)}if(o instanceof so&&l instanceof st||l instanceof so&&o instanceof st){let i=a.apply(e);if(t.info.side)return t.info.side.distanceToPoint(i,!0)}if(o instanceof sr&&l instanceof so||l instanceof sr&&o instanceof so){let i;if(i=t.info.collider===o?h.apply(e):a.apply(e),t.info.side)return t.info.side.distanceToPoint(i,!0)}if(o instanceof st&&l instanceof sr||l instanceof st&&o instanceof sr){let i;let s=h.apply(e);o instanceof st&&(i=o.getFurthestPoint(t.normal));let r=s.distance(i);if(t.info.side)return r>0?-r:0}return 0}};class sr extends iJ{constructor(t){var e;super(),this._globalMatrix=t2.identity(),this.begin=t.begin||tN.Zero,this.end=t.end||tN.Zero,this.offset=null!==(e=t.offset)&&void 0!==e?e:tN.Zero}clone(){return new sr({begin:this.begin.clone(),end:this.end.clone()})}get worldPos(){var t;let e=this._transform;return null!==(t=null==e?void 0:e.globalPos.add(this.offset))&&void 0!==t?t:this.offset}get center(){let t=this._getTransformedBegin(),e=this._getTransformedEnd();return t.average(e)}_getTransformedBegin(){return this._globalMatrix.multiply(this.begin)}_getTransformedEnd(){return this._globalMatrix.multiply(this.end)}getSlope(){let t=this._getTransformedBegin(),e=this._getTransformedEnd(),i=t.distance(e);return e.sub(t).scale(1/i)}getLength(){let t=this._getTransformedBegin(),e=this._getTransformedEnd();return t.distance(e)}contains(){return!1}rayCast(t,e=1/0){var i;let s=this._getTransformedBegin().sub(t.pos);if(0===t.dir.cross(this.getSlope())&&0!==s.cross(t.dir))return null;let r=t.dir.cross(this.getSlope());if(0===r)return null;let n=s.cross(this.getSlope())/r;if(n>=0&&n<=e){let e=s.cross(t.dir)/r/this.getLength();if(e>=0&&e<=1)return{distance:n,normal:this.asLine().normal(),collider:this,body:null===(i=this.owner)||void 0===i?void 0:i.get(sh),point:t.getPoint(n)}}return null}getClosestLineBetween(t){if(t instanceof st)return i8.CircleEdgeClosestLine(t,this);if(t instanceof so)return i8.PolygonEdgeClosestLine(t,this).flip();if(t instanceof sr)return i8.EdgeEdgeClosestLine(this,t);throw Error(`Polygon could not collide with unknown CollisionShape ${typeof t}`)}collide(t){if(t instanceof st)return ss.CollideCircleEdge(t,this);if(t instanceof so)return ss.CollidePolygonEdge(t,this);if(t instanceof sr)return ss.CollideEdgeEdge();throw Error(`Edge could not collide with unknown CollisionShape ${typeof t}`)}getFurthestPoint(t){let e=this._getTransformedBegin(),i=this._getTransformedEnd();return t.dot(e)>0?e:i}_boundsFromBeginEnd(t,e,i=10){return new tq(Math.min(t.x,e.x)-i,Math.min(t.y,e.y)-i,Math.max(t.x,e.x)+i,Math.max(t.y,e.y)+i)}get bounds(){let t=this._getTransformedBegin(),e=this._getTransformedEnd();return this._boundsFromBeginEnd(t,e)}get localBounds(){return this._boundsFromBeginEnd(this.begin,this.end)}asLine(){return new i6(this._getTransformedBegin(),this._getTransformedEnd())}asLocalLine(){return new i6(this.begin,this.end)}get axes(){let t=this._getTransformedEnd().sub(this._getTransformedBegin()).normal(),e=[];return e.push(t),e.push(t.negate()),e.push(t.normal()),e.push(t.normal().negate()),e}getInertia(t){let e=this.end.sub(this.begin).distance()/2;return t*e*e}update(t){var e;this._transform=t,(null!==(e=t.matrix)&&void 0!==e?e:this._globalMatrix).clone(this._globalMatrix),this._globalMatrix.translate(this.offset.x,this.offset.y)}project(t){let e=[],i=[this._getTransformedBegin(),this._getTransformedEnd()],s=i.length;for(let r=0;r{i.debug.drawPoint(t,e)})}static drawLine(t,e,i){sn.draw(s=>{s.debug.drawLine(t,e,i)})}static drawLines(t,e){t.length>1&&sn.draw(i=>{for(let s=0;s{i.debug.drawText(t,e)})}static drawPolygon(t,e){t.length>1&&sn.draw(i=>{let s=t[0],r=[...t,s];for(let t=0;t{i.drawCircle(t,e,s,r,n)})}static drawBounds(t,e){sn.draw(i=>{i.debug.drawRect(t.left,t.top,t.width,t.height,e)})}static drawRay(t,e){let{distance:i,color:s}={color:tH.Blue,distance:10,...e};sn.draw(e=>{let r=t.pos,n=t.pos.add(t.dir.scale(i));e.debug.drawLine(r,n,{color:s})})}static flush(t){for(let e of(t.save(),t.z=sn.z,sn._drawCalls))e(t);t.restore(),sn.clear()}static clear(){sn._drawCalls.length=0}}sn._drawCalls=[],sn.z=1/0;class so extends iJ{flagDirty(){this._localBoundsDirty=!0,this._localSidesDirty=!0,this._transformedPointsDirty=!0,this._sidesDirty=!0}set points(t){this._points=t,this.flagDirty()}get points(){return this._points}constructor(t){var e,i;super(),this._logger=tW.getInstance(),this._transformedPoints=[],this._sides=[],this._localSides=[],this._globalMatrix=t2.identity(),this._transformedPointsDirty=!0,this._sidesDirty=!0,this._localSidesDirty=!0,this._localBoundsDirty=!0,this.offset=null!==(e=t.offset)&&void 0!==e?e:tN.Zero,this._globalMatrix.translate(this.offset.x,this.offset.y),this.points=null!==(i=t.points)&&void 0!==i?i:[],this._isCounterClockwiseWinding(this.points)||this.points.reverse(),this.isConvex()||t.suppressConvexWarning||this._logger.warn("Excalibur only supports convex polygon colliders and will not behave properly.Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles"),this._calculateTransformation()}_isCounterClockwiseWinding(t){let e=0;for(let i=0;iMath.PI&&(l-=2*Math.PI),0===o){if(0===l)return!1;r=l>0?1:-1}else if(r*l<=0)return!1;n+=l}return 1===Math.abs(Math.round(n/(2*Math.PI)))}tessellate(){let t=[];for(let e=1;esa.Polygon(t)))}triangulate(){if(this.points.length<3)throw Error("Invalid polygon");let t=[],e=[...this.points].reverse(),i=e.length;function s(t){return 0===t?i-1:t-1}function r(t){return t===i-1?0:t+1}function n(t){let i=s(t),n=r(t),o=e[i],a=e[t],l=e[n],h=o.sub(a),d=l.sub(a);return!(0>h.cross(d))}let o=e.map((t,e)=>n(e));for(;i>3;){!function(n){let a=s(n),l=r(n),h=e[a],d=e[n],c=e[l];t.push([h,d,c]),e.splice(n,1),o.splice(n,1),i--}(function(){for(let t=0;t0)&&!(c>0)&&!(u>0)}(e[s],a,l,h)){d=!1;break}if(d)return t}for(let t=0;tsa.Polygon(t,tN.Zero,!0)))}clone(){return new so({offset:this.offset.clone(),points:this.points.map(t=>t.clone())})}get worldPos(){return this._transform?this._transform.pos.add(this.offset):this.offset}get center(){return this.bounds.center}_calculateTransformation(){let t=this.points,e=t.length;this._transformedPoints.length=0;for(let i=0;is&&(i=n,s=o)}return i}findLocalSide(t){let e=this.getLocalSides(),i=e[0],s=-Number.MAX_VALUE;for(let r=0;rs&&(i=n,s=o)}return i}get axes(){let t=[],e=this.getSides();for(let i=0;i=0?t+1:t},0)%2!=0}getClosestLineBetween(t){if(t instanceof st)return i8.PolygonCircleClosestLine(this,t);if(t instanceof so)return i8.PolygonPolygonClosestLine(this,t);if(t instanceof sr)return i8.PolygonEdgeClosestLine(this,t);throw Error(`Polygon could not collide with unknown CollisionShape ${typeof t}`)}collide(t){if(t instanceof st)return ss.CollideCirclePolygon(t,this);if(t instanceof so)return ss.CollidePolygonPolygon(this,t);if(t instanceof sr)return ss.CollidePolygonEdge(this,t);throw Error(`Polygon could not collide with unknown CollisionShape ${typeof t}`)}getFurthestPoint(t){let e=this.getTransformedPoints(),i=null,s=-Number.MAX_VALUE;for(let r=0;rs&&(s=n,i=e[r])}return i}getFurthestLocalPoint(t){let e=this.points,i=e[0],s=-Number.MAX_VALUE;for(let r=0;rs&&(s=n,i=e[r])}return i}getClosestFace(t){let e=this.getSides(),i=Number.POSITIVE_INFINITY,s=-1,r=-1;for(let n=0;n=0&&n=0?{collider:this,distance:o,body:null===(i=this.owner)||void 0===i?void 0:i.get(sh),point:t.getPoint(o),normal:s.normal()}:null}project(t){let e=this.getTransformedPoints(),i=e.length,s=Number.MAX_VALUE,r=-Number.MAX_VALUE;for(let n=0;n=t)?[sa.Circle(t/2,tZ(0,-e/2+t/2).add(i)),sa.Box(t,e-t,tN.Half,i),sa.Circle(t/2,tZ(0,e/2-t/2).add(i))]:[sa.Circle(e/2,tZ(-t/2+e/2,0).add(i)),sa.Box(t-e,e,tN.Half,i),sa.Circle(e/2,tZ(t/2-e/2,0).add(i))])}}class sl extends iZ{constructor(t){super(),this.events=new tP,this.$colliderAdded=new iH,this.$colliderRemoved=new iH,this._collidersToRemove=[],this.set(t)}get(){return this._collider}set(t){return this.clear(),t&&(this._collider=t,this._collider.owner=this.owner,t.events.pipe(this.events),this.$colliderAdded.notifyAll(t),this.update()),t}clear(){this._collider&&(this._collidersToRemove.push(this._collider),this._collider=null)}processColliderRemoval(){for(let t of this._collidersToRemove)t.events.unpipe(this.events),this.$colliderRemoved.notifyAll(t),t.owner=null}clone(){return new sl(this._collider.clone())}get bounds(){var t,e;return null!==(e=null===(t=this._collider)||void 0===t?void 0:t.bounds)&&void 0!==e?e:new tq}get localBounds(){var t,e;return null!==(e=null===(t=this._collider)||void 0===t?void 0:t.localBounds)&&void 0!==e?e:new tq}update(){var t;let e=null===(t=this.owner)||void 0===t?void 0:t.get(iV);this._collider&&(this._collider.owner=this.owner,e&&this._collider.update(e.get()))}collide(t){let e=this._collider,i=t._collider;if(!e||!i)return[];let s=!1;if(i instanceof i9&&(e=i,i=this._collider,s=!0),this._collider){let r=e.collide(i);if(r)return s&&r.forEach(e=>{e.mtv=e.mtv.negate(),e.normal=e.normal.negate(),e.tangent=e.normal.perpendicular(),e.colliderA=this._collider,e.colliderB=t._collider}),r}return[]}onAdd(t){this._collider&&this.update(),this.events.on("precollision",e=>{t.events.emit("precollision",new ie(e.target.owner,e.other.owner,e.side,e.intersection,e.contact)),t instanceof sj&&t.onPreCollisionResolve(e.target,e.other,e.side,e.contact)}),this.events.on("postcollision",e=>{t.events.emit("postcollision",new ii(e.target.owner,e.other.owner,e.side,e.intersection,e.contact)),t instanceof sj&&t.onPostCollisionResolve(e.target,e.other,e.side,e.contact)}),this.events.on("collisionstart",e=>{t.events.emit("collisionstart",new il(e.target.owner,e.other.owner,e.side,e.contact)),t instanceof sj&&t.onCollisionStart(e.target,e.other,e.side,e.contact)}),this.events.on("collisionend",e=>{t.events.emit("collisionend",new ih(e.target.owner,e.other.owner,e.side,e.lastContact)),t instanceof sj&&t.onCollisionEnd(e.target,e.other,e.side,e.lastContact)})}onRemove(){this.events.clear(),this.$colliderRemoved.notifyAll(this._collider)}useBoxCollider(t,e,i=tN.Half,s=tN.Zero){let r=sa.Box(t,e,i,s);return this.set(r)}usePolygonCollider(t,e=tN.Zero){let i=sa.Polygon(t,e);return this.set(i)}useCircleCollider(t,e=tN.Zero){let i=sa.Circle(t,e);return this.set(i)}useEdgeCollider(t,e){let i=sa.Edge(t,e);return this.set(i)}useCompositeCollider(t){return this.set(new i9(t))}}(f=Y||(Y={})).Rotation="rotation",f.X="x",f.Y="y";class sh extends iZ{constructor(t){var e,i,s;super(),this.dependencies=[iV,iW],this.id=tA("body",sh._ID++),this.events=new tP,this.oldTransform=new iU,this.__oldTransformCaptured=!1,this.enableFixedUpdateInterpolate=!0,this.collisionType=G.PreventCollision,this.group=ij.All,this._sleeping=!1,this.bounciness=.2,this.friction=.99,this.useGravity=!0,this.limitDegreeOfFreedom=[],this.oldVel=new tN(0,0),this.oldAcc=tN.Zero,t?(this.collisionType=null!==(e=t.type)&&void 0!==e?e:this.collisionType,this.group=null!==(i=t.group)&&void 0!==i?i:this.group,this.useGravity=null!==(s=t.useGravity)&&void 0!==s?s:this.useGravity,this._bodyConfig={...i4.bodies,...t.config}):this._bodyConfig={...i4.bodies},this.updatePhysicsConfig(this._bodyConfig),this._mass=sh._DEFAULT_CONFIG.defaultMass}get matrix(){return this.transform.get().matrix}updatePhysicsConfig(t){this._bodyConfig={...i4.bodies,...t},this.canSleep=this._bodyConfig.canSleepByDefault,this.sleepMotion=5*this._bodyConfig.sleepEpsilon,this.wakeThreshold=this._bodyConfig.wakeThreshold}static updateDefaultPhysicsConfig(t){sh._DEFAULT_CONFIG=t}get mass(){return this._mass}set mass(t){this._mass=t,this._cachedInertia=void 0,this._cachedInverseInertia=void 0}get inverseMass(){return this.collisionType===G.Fixed?0:1/this.mass}get sleeping(){return this._sleeping}setSleeping(t){this._sleeping=t,t?(this.vel=tN.Zero,this.acc=tN.Zero,this.angularVelocity=0,this.sleepMotion=0):this.sleepMotion=5*this._bodyConfig.sleepEpsilon}updateMotion(){this._sleeping&&this.setSleeping(!0);let t=this.vel.size*this.vel.size+Math.abs(this.angularVelocity*this.angularVelocity),e=this._bodyConfig.sleepBias;this.sleepMotion=e*this.sleepMotion+(1-e)*t,this.sleepMotion=tF(this.sleepMotion,0,10*this._bodyConfig.sleepEpsilon),this.canSleep&&this.sleepMotion{this._cachedInertia=null}),t.$colliderRemoved.subscribe(()=>{this._cachedInertia=null});let e=t.get();if(e)return this._cachedInertia=e.getInertia(this.mass)}return 0}get inverseInertia(){return this._cachedInverseInertia?this._cachedInverseInertia:this._cachedInverseInertia=this.collisionType===G.Fixed?0:1/this.inertia}get active(){var t;return!!(null===(t=this.owner)||void 0===t?void 0:t.active)}get center(){return this.globalPos}get transform(){var t;return null===(t=this.owner)||void 0===t?void 0:t.get(iV)}get motion(){var t;return null===(t=this.owner)||void 0===t?void 0:t.get(iW)}get pos(){return this.transform.pos}set pos(t){this.transform.pos=t}get globalPos(){return this.transform.globalPos}set globalPos(t){this.transform.globalPos=t}get oldPos(){return this.oldTransform.pos}get vel(){return this.motion.vel}set vel(t){this.motion.vel=t}get acc(){return this.motion.acc}set acc(t){this.motion.acc=t}get torque(){return this.motion.torque}set torque(t){this.motion.torque=t}get oldRotation(){return this.oldTransform.rotation}get rotation(){return this.transform.globalRotation}set rotation(t){this.transform.globalRotation=t}get scale(){return this.transform.globalScale}set scale(t){this.transform.globalScale=t}get oldScale(){return this.oldTransform.scale}get scaleFactor(){return this.motion.scaleFactor}set scaleFactor(t){this.motion.scaleFactor=t}get angularVelocity(){return this.motion.angularVelocity}set angularVelocity(t){this.motion.angularVelocity=t}applyImpulse(t,e){if(this.collisionType!==G.Active)return;let i=e.scale(this.inverseMass);if(this.limitDegreeOfFreedom.includes(Y.X)&&(i.x=0),this.limitDegreeOfFreedom.includes(Y.Y)&&(i.y=0),this.vel.addEqual(i),!this.limitDegreeOfFreedom.includes(Y.Rotation)){let i=t.sub(this.globalPos);this.angularVelocity+=this.inverseInertia*i.cross(e)}}applyLinearImpulse(t){if(this.collisionType!==G.Active)return;let e=t.scale(this.inverseMass);this.limitDegreeOfFreedom.includes(Y.X)&&(e.x=0),this.limitDegreeOfFreedom.includes(Y.Y)&&(e.y=0),this.vel=this.vel.add(e)}applyAngularImpulse(t,e){if(this.collisionType===G.Active&&!this.limitDegreeOfFreedom.includes(Y.Rotation)){let i=t.sub(this.globalPos);this.angularVelocity+=this.inverseInertia*i.cross(e)}}captureOldTransform(){this.__oldTransformCaptured=!0;let t=this.transform.get();t.clone(this.oldTransform),this.oldTransform.parent=t.parent,this.oldVel.setTo(this.vel.x,this.vel.y),this.oldAcc.setTo(this.acc.x,this.acc.y)}clone(){return super.clone()}}sh._ID=0,sh._DEFAULT_CONFIG={...i4.bodies};class sd{constructor(t){this.data=t,this.type="Component Added"}}function sc(t){return!!t&&"Component Added"===t.type}class su{constructor(t){this.data=t,this.type="Component Removed"}}function sp(t){return!!t&&"Component Removed"===t.type}let sg={Initialize:"initialize",PreUpdate:"preupdate",PostUpdate:"postupdate",Kill:"kill"};class s_{constructor(t,e){let i,s;if(this.id=s_._ID++,this.name=`Entity#${this.id}`,this.events=new tP,this._tags=new Set,this.componentAdded$=new iH,this.componentRemoved$=new iH,this.tagAdded$=new iH,this.tagRemoved$=new iH,this.components=new Map,this._componentsToRemove=[],this._instanceOfComponentCacheDirty=!0,this._instanceOfComponentCache=new Map,this.scene=null,this.active=!0,this._parent=null,this.childrenAdded$=new iH,this.childrenRemoved$=new iH,this._children=[],this._isInitialized=!1,Array.isArray(t))i=t,s=e;else if(t&&"object"==typeof t){let{components:e,name:r}=t;i=e,s=r}if(s&&(this.name=s),i)for(let t of i)this.addComponent(t)}kill(){this.active&&(this.active=!1,this.unparent()),this.emit("kill",new eW(this))}isKilled(){return!this.active}get tags(){return this._tags}hasTag(t){return this._tags.has(t)}addTag(t){this._tags.add(t),this.tagAdded$.notifyAll(t)}removeTag(t){this._tags.delete(t),this.tagRemoved$.notifyAll(t)}get types(){return Array.from(this.components.keys())}getComponents(){return Array.from(this.components.values())}hasAll(t){for(let e=0;e=0;t--)this.removeChild(this.children[t]);return this}getAncestors(){let t=[this],e=this.parent;for(;e;)t.push(e),e=e.parent;return t.reverse()}getDescendants(){let t=[this],e=[this];for(;e.length>0;){let i=e.pop();i&&(e=e.concat(i.children),t=t.concat(i.children))}return t}clone(){let t=new s_;for(let e of this.types){let i=this.get(e);i&&t.addComponent(i.clone())}for(let e of this.children)t.addChild(e.clone());return t}addTemplate(t,e=!1){for(let i of t.getComponents())this.addComponent(i.clone(),e);for(let e of t.children)this.addChild(e.clone().addTemplate(e));return this}addComponent(t,e=!1){if(this._instanceOfComponentCacheDirty=!0,this.has(t.constructor)){if(!e)return this;this.removeComponent(t.constructor,!0)}if(t.dependencies&&t.dependencies.length)for(let e of t.dependencies)this.addComponent(new e);return t.owner=this,this.components.set(t.constructor,t),t.onAdd&&t.onAdd(this),this.componentAdded$.notifyAll(t),this}removeComponent(t,e=!1){let i;if(i=iN(t)?t:t.constructor,e){let t=this.components.get(i);t&&(this.componentRemoved$.notifyAll(t),t.owner=void 0,t.onRemove&&t.onRemove(this)),this.components.delete(i),this._instanceOfComponentCacheDirty=!0}else this._componentsToRemove.push(i);return this}clearComponents(){for(let t of this.types)this.removeComponent(t)}processComponentRemoval(){for(let t of this._componentsToRemove)this.removeComponent(t,!0);this._componentsToRemove.length=0}has(t){return this.components.has(t)}get isInitialized(){return this._isInitialized}_initialize(t){this.isInitialized||(this.onInitialize(t),this.events.emit("initialize",new id(t,this)),this._isInitialized=!0)}_preupdate(t,e){this.events.emit("preupdate",new e1(t,e,this)),this.onPreUpdate(t,e)}_postupdate(t,e){this.events.emit("postupdate",new e2(t,e,this)),this.onPostUpdate(t,e)}onInitialize(t){}onPreUpdate(t,e){}onPostUpdate(t,e){}update(t,e){for(let i of(this._initialize(t),this._preupdate(t,e),this.children))i.update(t,e);this._postupdate(t,e)}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){e?this.events.off(t,e):this.events.off(t)}}function sf(t){return!!t.tick}s_._ID=0;class sm extends iZ{get offset(){return new iO(this._offset,()=>{this.recalculateBounds()})}set offset(t){this._offset=t,this.recalculateBounds()}get anchor(){return new iO(this._anchor,()=>{this.recalculateBounds()})}set anchor(t){this._anchor=t,this.recalculateBounds()}constructor(t){super(),this._logger=tW.getInstance(),this._current="default",this._graphics={},this._options={},this.material=null,this.visible=!0,this.opacity=1,this._offset=tN.Zero,this._anchor=tN.Half,this.flipHorizontal=!1,this.flipVertical=!1,this.copyGraphics=!1,this._localBounds=null;let{current:e,anchor:i,opacity:s,visible:r,graphics:n,offset:o,copyGraphics:a,onPreDraw:l,onPostDraw:h,onPreTransformDraw:d,onPostTransformDraw:c}=t={visible:this.visible,graphics:{},...t};for(let[t,e]of Object.entries(n))e instanceof et?this._graphics[t]=e:(this._graphics[t]=e.graphic,this._options[t]=e.options);this.offset=null!=o?o:this.offset,this.opacity=null!=s?s:this.opacity,this.anchor=null!=i?i:this.anchor,this.copyGraphics=null!=a?a:this.copyGraphics,this.onPreDraw=null!=l?l:this.onPreDraw,this.onPostDraw=null!=h?h:this.onPostDraw,this.onPreDraw=null!=d?d:this.onPreTransformDraw,this.onPostTransformDraw=null!=c?c:this.onPostTransformDraw,this.visible=!!r,this._current=null!=e?e:this._current,e&&this._graphics[e]&&this.use(e)}getGraphic(t){return this._graphics[t]}getOptions(t){return this._options[t]}getNames(){return Object.keys(this._graphics)}get current(){return this._graphics[this._current]}get currentOptions(){return this._options[this._current]}get graphics(){return this._graphics}get options(){return this._options}add(t,e,i){let s,r="default",n=null;return"string"==typeof t&&e instanceof et&&(r=t,n=e,s=i),t instanceof et&&!(e instanceof et)&&(n=t,s=e),this._graphics[r]=this.copyGraphics?n.clone():n,this._options[r]=this.copyGraphics?{...s}:s,"default"===r&&this.use("default"),n}remove(t){delete this._graphics[t],delete this._options[t],this._current===t&&(this._current="default",this.recalculateBounds())}show(t,e){return this.use(t,e)}use(t,e){var i;if(t instanceof et){let i=t;this.copyGraphics&&(i=t.clone()),this._current="default",this._graphics[this._current]=i,this._options[this._current]=e}else this._current=t,this._options[this._current]=e,this._current in this._graphics||this._logger.warn(`Graphic ${this._current} is not registered with the graphics component owned by ${null===(i=this.owner)||void 0===i?void 0:i.name}. Nothing will be drawn.`);return this.recalculateBounds(),this.current}hide(){this._current="ex.none"}set localBounds(t){this._localBounds=t}recalculateBounds(){let t=new tq,e=this._graphics[this._current],i=this._options[this._current];if(!e){this._localBounds=t;return}let s=this.anchor,r=this.offset;(null==i?void 0:i.anchor)&&(s=i.anchor),(null==i?void 0:i.offset)&&(r=i.offset);let n=e.localBounds,o=-n.width*s.x+r.x,a=-n.height*s.y+r.y;t=null==e?void 0:e.localBounds.translate(tZ(o,a)).combine(t),this._localBounds=t}get localBounds(){return(!this._localBounds||this._localBounds.hasZeroDimensions())&&this.recalculateBounds(),this._localBounds}update(t,e=0){let i=this.current;i&&sf(i)&&i.tick(t,e)}clone(){let t=new sm;return t._graphics={...this._graphics},t._options={...this._options},t.offset=this.offset.clone(),t.opacity=this.opacity,t.anchor=this.anchor.clone(),t.copyGraphics=this.copyGraphics,t.onPreDraw=this.onPreDraw,t.onPostDraw=this.onPostDraw,t.visible=this.visible,t}}class sv extends eO{constructor(t){super(t),this.width=t.width,this.height=t.height,this.rasterize()}clone(){return new sv({width:this.width,height:this.height,...this.cloneGraphicOptions(),...this.cloneRasterOptions()})}execute(t){this.color&&t.fillRect(0,0,this.width,this.height),this.strokeColor&&t.strokeRect(0,0,this.width,this.height)}}class sy extends eO{get radius(){return this._radius}set radius(t){this._radius=t,this.width=2*this._radius,this.height=2*this._radius,this.flagDirty()}constructor(t){var e,i,s;super(t),this._radius=0;let r=null!==(e=t.lineWidth)&&void 0!==e?e:t.strokeColor?1:0;this.padding=null!==(i=t.padding)&&void 0!==i?i:2+r/2,this.radius=t.radius,this.filtering=null!==(s=t.filtering)&&void 0!==s?s:H.Blended,this.rasterize()}clone(){return new sy({radius:this.radius,...this.cloneGraphicOptions(),...this.cloneRasterOptions()})}execute(t){this.radius>0&&(t.beginPath(),t.arc(this.radius,this.radius,this.radius,0,2*Math.PI),this.color&&t.fill(),this.strokeColor&&t.stroke())}}class sx extends iZ{constructor(){super(...arguments),this.useColliderShape=!0,this.useGraphicsBounds=!0}}class sw{static CreateReversibleEasingFunction(t){return(e,i,s,r)=>snew tN(t(e,i.x,s.x,r),t(e,i.y,s.y,r))}}sw.Linear=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e)*t/s+e),sw.EaseInQuad=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e)*(t/=s)*t+e),sw.EaseOutQuad=sw.CreateReversibleEasingFunction((t,e,i,s)=>-(i-=e)*(t/=s)*(t-2)+e),sw.EaseInOutQuad=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e,(t/=s/2)<1)?i/2*t*t+e:-i/2*(--t*(t-2)-1)+e),sw.EaseInCubic=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e)*(t/=s)*t*t+e),sw.EaseOutCubic=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e,t/=s,i*(--t*t*t+1)+e)),sw.EaseInOutCubic=sw.CreateReversibleEasingFunction((t,e,i,s)=>(i-=e,(t/=s/2)<1)?i/2*t*t*t+e:i/2*((t-=2)*t*t+2)+e);class sb{constructor(t){this._actions=[],this._currentAction=null,this._completedActions=[],this._entity=t}add(t){this._actions.push(t)}remove(t){let e=this._actions.indexOf(t);this._actions.splice(e,1)}clearActions(){this._actions.length=0,this._completedActions.length=0,this._currentAction&&this._currentAction.stop()}getActions(){return this._actions.concat(this._completedActions)}hasNext(){return this._actions.length>0}isComplete(){return 0===this._actions.length}reset(){this._actions=this.getActions();let t=this._actions.length;for(let e=0;e0&&(this._currentAction!==this._actions[0]&&(this._currentAction=this._actions[0],this._entity.emit("actionstart",new iv(this._currentAction,this._entity))),this._currentAction.update(t),this._currentAction.isComplete(this._entity))){this._entity.emit("actioncomplete",new iy(this._currentAction,this._entity));let t=this._actions.shift();t&&this._completedActions.push(t)}}}class sC{constructor(t,e,i){this._stopped=!1,this._repeatBuilder=e,this._repeatContext=new sN(t),this._actionQueue=this._repeatContext.getQueue(),this._repeat=i,this._originalRepeat=i,this._repeatBuilder(this._repeatContext),this._repeat--}update(t){this._actionQueue.isComplete()&&(this._actionQueue.clearActions(),this._repeatBuilder(this._repeatContext),this._repeat--),this._actionQueue.update(t)}isComplete(){return this._stopped||this._repeat<=0&&this._actionQueue.isComplete()}stop(){this._stopped=!0}reset(){this._repeat=this._originalRepeat}}class sT{constructor(t,e){this._stopped=!1,this._repeatBuilder=e,this._repeatContext=new sN(t),this._actionQueue=this._repeatContext.getQueue(),this._repeatBuilder(this._repeatContext)}update(t){this._stopped||(this._actionQueue.isComplete()&&(this._actionQueue.clearActions(),this._repeatBuilder(this._repeatContext)),this._actionQueue.update(t))}isComplete(){return this._stopped}stop(){this._stopped=!0,this._actionQueue.clearActions()}reset(){}}class sS{constructor(t,e,i,s){if(this._started=!1,this._stopped=!1,this._entity=t,this._tx=t.get(iV),this._motion=t.get(iW),this._speed=s,this._offset=new tN(e,i),s<=0)throw tW.getInstance().error("Attempted to moveBy with speed less than or equal to zero : "+s),Error("Speed must be greater than 0 pixels per second")}update(t){this._started||(this._started=!0,this._start=new tN(this._tx.pos.x,this._tx.pos.y),this._end=this._start.add(this._offset),this._distance=this._offset.size,this._dir=this._end.sub(this._start).normalize()),this.isComplete(this._entity)?(this._tx.pos=tZ(this._end.x,this._end.y),this._motion.vel=tZ(0,0)):this._motion.vel=this._dir.scale(this._speed)}isComplete(t){let e=t.get(iV);return this._stopped||e.pos.distance(this._start)>=this._distance}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sA{constructor(t,e,i,s){this.entity=t,this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._end=new tN(e,i),this._speed=s}update(t){this._started||(this._started=!0,this._start=new tN(this._tx.pos.x,this._tx.pos.y),this._distance=this._start.distance(this._end),this._dir=this._end.sub(this._start).normalize());let e=this._dir.scale(this._speed);this._motion.vel=tZ(e.x,e.y),this.isComplete(this.entity)&&(this._tx.pos=tZ(this._end.x,this._end.y),this._motion.vel=tZ(0,0))}isComplete(t){let e=t.get(iV);return this._stopped||new tN(e.pos.x,e.pos.y).distance(this._start)>=this._distance}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}(m=Q||(Q={}))[m.ShortestPath=0]="ShortestPath",m[m.LongestPath=1]="LongestPath",m[m.Clockwise=2]="Clockwise",m[m.CounterClockwise=3]="CounterClockwise";class sE{constructor(t,e,i,s){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._end=e,this._speed=i,this._rotationType=s||Q.ShortestPath}update(t){if(!this._started){this._started=!0,this._start=this._tx.rotation,this._currentNonCannonAngle=this._tx.rotation;let t=Math.abs(this._end-this._start),e=tk-t;switch(t>e?(this._shortDistance=e,this._longDistance=t):(this._shortDistance=t,this._longDistance=e),this._shortestPathIsPositive=(this._start-this._end+tk)%tk>=Math.PI,this._rotationType){case Q.ShortestPath:this._distance=this._shortDistance,this._shortestPathIsPositive?this._direction=1:this._direction=-1;break;case Q.LongestPath:this._distance=this._longDistance,this._shortestPathIsPositive?this._direction=-1:this._direction=1;break;case Q.Clockwise:this._direction=1,this._shortestPathIsPositive?this._distance=this._shortDistance:this._distance=this._longDistance;break;case Q.CounterClockwise:this._direction=-1,this._shortestPathIsPositive?this._distance=this._longDistance:this._distance=this._shortDistance}}this._motion.angularVelocity=this._direction*this._speed,this._currentNonCannonAngle+=this._direction*this._speed*(t/1e3),this.isComplete()&&(this._tx.rotation=this._end,this._motion.angularVelocity=0,this._stopped=!0)}isComplete(){let t=Math.abs(this._currentNonCannonAngle-this._start);return this._stopped||t>=Math.abs(this._distance)}stop(){this._motion.angularVelocity=0,this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sP{constructor(t,e,i,s){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._speed=i,this._offset=e,this._rotationType=s||Q.ShortestPath}update(t){if(!this._started){this._started=!0,this._start=this._tx.rotation,this._currentNonCannonAngle=this._tx.rotation,this._end=this._start+this._offset;let t=Math.abs(this._end-this._start),e=tk-t;switch(t>e?(this._shortDistance=e,this._longDistance=t):(this._shortDistance=t,this._longDistance=e),this._shortestPathIsPositive=(this._start-this._end+tk)%tk>=Math.PI,this._rotationType){case Q.ShortestPath:this._distance=this._shortDistance,this._shortestPathIsPositive?this._direction=1:this._direction=-1;break;case Q.LongestPath:this._distance=this._longDistance,this._shortestPathIsPositive?this._direction=-1:this._direction=1;break;case Q.Clockwise:this._direction=1,this._shortDistance>=0?this._distance=this._shortDistance:this._distance=this._longDistance;break;case Q.CounterClockwise:this._direction=-1,this._shortDistance<=0?this._distance=this._shortDistance:this._distance=this._longDistance}}this._motion.angularVelocity=this._direction*this._speed,this._currentNonCannonAngle+=this._direction*this._speed*(t/1e3),this.isComplete()&&(this._tx.rotation=this._end,this._motion.angularVelocity=0,this._stopped=!0)}isComplete(){let t=Math.abs(this._currentNonCannonAngle-this._start);return this._stopped||t>=Math.abs(this._distance)}stop(){this._motion.angularVelocity=0,this._stopped=!0}reset(){this._started=!1,this._stopped=!1,this._start=void 0,this._currentNonCannonAngle=void 0,this._distance=void 0}}class sI{constructor(t,e,i,s,r){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._endX=e,this._endY=i,this._speedX=s,this._speedY=r}update(t){if(this._started||(this._started=!0,this._startX=this._tx.scale.x,this._startY=this._tx.scale.y,this._distanceX=Math.abs(this._endX-this._startX),this._distanceY=Math.abs(this._endY-this._startY)),Math.abs(this._tx.scale.x-this._startX)>=this._distanceX)this._motion.scaleFactor.x=0;else{let t=this._endY=this._distanceY)this._motion.scaleFactor.y=0;else{let t=this._endY=this._distanceX-.01&&Math.abs(this._tx.scale.y-this._startY)>=this._distanceY-.01}stop(){this._motion.scaleFactor.x=0,this._motion.scaleFactor.y=0,this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sk{constructor(t,e,i,s){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._offset=new tN(e,i),this._speedX=this._speedY=s}update(t){this._started||(this._started=!0,this._startScale=this._tx.scale.clone(),this._endScale=this._startScale.add(this._offset),this._distanceX=Math.abs(this._endScale.x-this._startScale.x),this._distanceY=Math.abs(this._endScale.y-this._startScale.y),this._directionX=this._endScale.x=this._distanceX-.01&&Math.abs(this._tx.scale.y-this._startScale.y)>=this._distanceY-.01}stop(){this._motion.scaleFactor.x=0,this._motion.scaleFactor.y=0,this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sD{constructor(t){this._method=null,this._hasBeenCalled=!1,this._method=t}update(t){this._method(),this._hasBeenCalled=!0}isComplete(){return this._hasBeenCalled}reset(){this._hasBeenCalled=!1}stop(){this._hasBeenCalled=!0}}class sR{constructor(t,e,i,s,r){this.easingFcn=r,this._currentLerpTime=0,this._lerpDuration=1e3,this._lerpStart=new tN(0,0),this._lerpEnd=new tN(0,0),this._initialized=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._lerpDuration=s,this._lerpEnd=new tN(e,i)}_initialize(){this._lerpStart=new tN(this._tx.pos.x,this._tx.pos.y),this._currentLerpTime=0}update(t){this._initialized||(this._initialize(),this._initialized=!0),this._currentLerpTime+=t;let e=this._tx.pos.x,i=this._tx.pos.y;this._currentLerpTime=this._lerpDuration}reset(){this._initialized=!1,this._stopped=!1,this._currentLerpTime=0}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}}class sF{constructor(t,e,i,s,r){this.easingFcn=r,this._currentLerpTime=0,this._lerpDuration=1e3,this._lerpStart=new tN(0,0),this._lerpEnd=new tN(0,0),this._initialized=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._lerpDuration=s,this._offset=new tN(e,i)}_initialize(){this._lerpStart=new tN(this._tx.pos.x,this._tx.pos.y),this._currentLerpTime=0,this._lerpEnd=this._lerpStart.add(this._offset)}update(t){this._initialized||(this._initialize(),this._initialized=!0),this._currentLerpTime+=t;let e=this._tx.pos.x,i=this._tx.pos.y;this._currentLerpTime=this._lerpDuration}reset(){this._initialized=!1,this._stopped=!1,this._currentLerpTime=0}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}}class sB{constructor(t,e,i,s=1){this._timeVisible=0,this._timeNotVisible=0,this._elapsedTime=0,this._totalTime=0,this._stopped=!1,this._started=!1,this._graphics=t.get(sm),this._timeVisible=e,this._timeNotVisible=i,this._duration=(e+i)*s}update(t){this._started||(this._started=!0,this._elapsedTime=0,this._totalTime=0),this._graphics&&(this._elapsedTime+=t,this._totalTime+=t,this._graphics.visible&&this._elapsedTime>=this._timeVisible&&(this._graphics.visible=!1,this._elapsedTime=0),!this._graphics.visible&&this._elapsedTime>=this._timeNotVisible&&(this._graphics.visible=!0,this._elapsedTime=0),this.isComplete()&&(this._graphics.visible=!0))}isComplete(){return this._stopped||this._totalTime>=this._duration}stop(){this._graphics&&(this._graphics.visible=!0),this._stopped=!0}reset(){this._started=!1,this._stopped=!1,this._elapsedTime=0,this._totalTime=0}}class sL{constructor(t,e,i){this._multiplier=1,this._started=!1,this._stopped=!1,this._graphics=t.get(sm),this._endOpacity=e,this._speed=this._ogspeed=i}update(t){this._graphics&&(this._started||(this._started=!0,this._speed=this._ogspeed,this._endOpacity0&&(this._graphics.opacity+=this._multiplier*(Math.abs(this._graphics.opacity-this._endOpacity)*t)/this._speed),this._speed-=t,this.isComplete()&&(this._graphics.opacity=this._endOpacity),tW.getInstance().debug("[Action fade] Actor opacity:",this._graphics.opacity))}isComplete(){return this._stopped||.05>Math.abs(this._graphics.opacity-this._endOpacity)}stop(){this._stopped=!0}reset(){this._started=!1,this._stopped=!1}}class sM{constructor(t){this._elapsedTime=0,this._started=!1,this._stopped=!1,this._delay=t}update(t){this._started||(this._started=!0),this._elapsedTime+=t}isComplete(){return this._stopped||this._elapsedTime>=this._delay}stop(){this._stopped=!0}reset(){this._elapsedTime=0,this._started=!1,this._stopped=!1}}class sz{constructor(t){this._stopped=!1,this._entity=t}update(t){this._entity.get(sZ).clearActions(),this._entity.kill(),this._stopped=!0}isComplete(){return this._stopped}stop(){}reset(){}}class sO{constructor(t,e,i){this._started=!1,this._stopped=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._followTx=e.get(iV),this._followMotion=e.get(iW),this._current=new tN(this._tx.pos.x,this._tx.pos.y),this._end=new tN(this._followTx.pos.x,this._followTx.pos.y),this._maximumDistance=void 0!==i?i:this._current.distance(this._end),this._speed=0}update(t){this._started||(this._started=!0,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.sub(this._current).normalize());let e=Math.sqrt(Math.pow(this._followMotion.vel.x,2)+Math.pow(this._followMotion.vel.y,2));if(0!==e&&(this._speed=e),this._current=tZ(this._tx.pos.x,this._tx.pos.y),this._end=tZ(this._followTx.pos.x,this._followTx.pos.y),this._distanceBetween=this._current.distance(this._end),this._dir=this._end.sub(this._current).normalize(),this._distanceBetween>=this._maximumDistance){let t=this._dir.scale(this._speed);this._motion.vel=tZ(t.x,t.y)}else this._motion.vel=tZ(0,0);this.isComplete()&&(this._tx.pos=tZ(this._end.x,this._end.y),this._motion.vel=tZ(0,0))}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}isComplete(){return this._stopped}reset(){this._started=!1,this._stopped=!1}}class sU{constructor(t,e,i){this._started=!1,this._stopped=!1,this._speedWasSpecified=!1,this._tx=t.get(iV),this._motion=t.get(iW),this._meetTx=e.get(iV),this._meetMotion=e.get(iW),this._current=new tN(this._tx.pos.x,this._tx.pos.y),this._end=new tN(this._meetTx.pos.x,this._meetTx.pos.y),this._speed=i||0,void 0!==i&&(this._speedWasSpecified=!0)}update(t){this._started||(this._started=!0,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.sub(this._current).normalize());let e=Math.sqrt(Math.pow(this._meetMotion.vel.x,2)+Math.pow(this._meetMotion.vel.y,2));0===e||this._speedWasSpecified||(this._speed=e),this._current=tZ(this._tx.pos.x,this._tx.pos.y),this._end=tZ(this._meetTx.pos.x,this._meetTx.pos.y),this._distanceBetween=this._current.distance(this._end),this._dir=this._end.sub(this._current).normalize();let i=this._dir.scale(this._speed);this._motion.vel=tZ(i.x,i.y),this.isComplete()&&(this._tx.pos=tZ(this._end.x,this._end.y),this._motion.vel=tZ(0,0))}isComplete(){return this._stopped||this._distanceBetween<=1}stop(){this._motion.vel=tZ(0,0),this._stopped=!0}reset(){this._started=!1,this._stopped=!1,this._distanceBetween=void 0}}class sN{constructor(t){this._entity=t,this._queue=new sb(t)}getQueue(){return this._queue}update(t){this._queue.update(t)}clearActions(){this._queue.clearActions()}runAction(t){return t.reset(),this._queue.add(t),this}easeTo(...t){var e,i;let s=0,r=0,n=0,o=sw.Linear;return t[0]instanceof tN?(s=t[0].x,r=t[0].y,n=t[1],o=null!==(e=t[2])&&void 0!==e?e:o):(s=t[0],r=t[1],n=t[2],o=null!==(i=t[3])&&void 0!==i?i:o),this._queue.add(new sR(this._entity,s,r,n,o)),this}easeBy(...t){var e,i;let s=0,r=0,n=0,o=sw.Linear;return t[0]instanceof tN?(s=t[0].x,r=t[0].y,n=t[1],o=null!==(e=t[2])&&void 0!==e?e:o):(s=t[0],r=t[1],n=t[2],o=null!==(i=t[3])&&void 0!==i?i:o),this._queue.add(new sF(this._entity,s,r,n,o)),this}moveTo(t,e,i){let s=0,r=0,n=0;return t instanceof tN?(s=t.x,r=t.y,n=e):(s=t,r=e,n=i),this._queue.add(new sA(this._entity,s,r,n)),this}moveBy(t,e,i){let s=0,r=0,n=0;return t instanceof tN?(s=t.x,r=t.y,n=e):(s=t,r=e,n=i),this._queue.add(new sS(this._entity,s,r,n)),this}rotateTo(t,e,i){return this._queue.add(new sE(this._entity,t,e,i)),this}rotateBy(t,e,i){return this._queue.add(new sP(this._entity,t,e,i)),this}scaleTo(t,e,i,s){let r=1,n=1,o=0,a=0;return t instanceof tN&&e instanceof tN&&(r=t.x,n=t.y,o=e.x,a=e.y),"number"==typeof t&&"number"==typeof e&&(r=t,n=e,o=i,a=s),this._queue.add(new sI(this._entity,r,n,o,a)),this}scaleBy(t,e,i){let s=1,r=1;return t instanceof tN&&(s=t.x,r=t.y,i=e),"number"==typeof t&&"number"==typeof e&&(s=t,r=e),this._queue.add(new sk(this._entity,s,r,i)),this}blink(t,e,i=1){return this._queue.add(new sB(this._entity,t,e,i)),this}fade(t,e){return this._queue.add(new sL(this._entity,t,e)),this}delay(t){return this._queue.add(new sM(t)),this}die(){return this._queue.add(new sz(this._entity)),this}callMethod(t){return this._queue.add(new sD(t)),this}repeat(t,e){return e?this._queue.add(new sC(this._entity,t,e)):this.repeatForever(t),this}repeatForever(t){return this._queue.add(new sT(this._entity,t)),this}follow(t,e){return void 0===e?this._queue.add(new sO(this._entity,t)):this._queue.add(new sO(this._entity,t,e)),this}meet(t,e){return void 0===e?this._queue.add(new sU(this._entity,t)):this._queue.add(new sU(this._entity,t,e)),this}toPromise(){return new Promise(t=>{this._queue.add(new sD(()=>{t()}))})}}class sZ extends iZ{constructor(){super(...arguments),this.dependencies=[iV,iW],this._ctx=null}onAdd(t){this._ctx=new sN(t)}onRemove(){this._ctx=null}_getCtx(){if(!this._ctx)throw Error("Actions component not attached to an entity, no context available");return this._ctx}getQueue(){if(!this._ctx)throw Error("Actions component not attached to an entity, no queue available");return this._ctx.getQueue()}runAction(t){if(!this._ctx)throw Error("Actions component not attached to an entity, cannot run action");return this._ctx.runAction(t)}update(t){var e;return null===(e=this._ctx)||void 0===e?void 0:e.update(t)}clearActions(){var t;null===(t=this._ctx)||void 0===t||t.clearActions()}easeTo(...t){return this._getCtx().easeTo.apply(this._ctx,t)}easeBy(...t){return this._getCtx().easeBy.apply(this._ctx,t)}moveTo(t,e,i){return this._getCtx().moveTo.apply(this._ctx,[t,e,i])}moveBy(t,e,i){return this._getCtx().moveBy.apply(this._ctx,[t,e,i])}rotateTo(t,e,i){return this._getCtx().rotateTo(t,e,i)}rotateBy(t,e,i){return this._getCtx().rotateBy(t,e,i)}scaleTo(t,e,i,s){return this._getCtx().scaleTo.apply(this._ctx,[t,e,i,s])}scaleBy(t,e,i){return this._getCtx().scaleBy.apply(this._ctx,[t,e,i])}blink(t,e,i){return this._getCtx().blink(t,e,i)}fade(t,e){return this._getCtx().fade(t,e)}delay(t){return this._getCtx().delay(t)}die(){return this._getCtx().die()}callMethod(t){return this._getCtx().callMethod(t)}repeat(t,e){return this._getCtx().repeat(t,e)}repeatForever(t){return this._getCtx().repeatForever(t)}follow(t,e){return this._getCtx().follow(t,e)}meet(t,e){return this._getCtx().meet(t,e)}toPromise(){return this._getCtx().toPromise()}}(v=J||(J={})).Em="em",v.Rem="rem",v.Px="px",v.Pt="pt",v.Percent="%",(y=tt||(tt={})).Left="left",y.Right="right",y.Center="center",y.Start="start",y.End="end",(x=te||(te={})).Top="top",x.Hanging="hanging",x.Middle="middle",x.Alphabetic="alphabetic",x.Ideographic="ideographic",x.Bottom="bottom",(w=ti||(ti={})).Normal="normal",w.Italic="italic",w.Oblique="oblique",(b=ts||(ts={})).LeftToRight="ltr",b.RightToLeft="rtl";class sH{constructor(t,e,i,s){this.font=t,this.text=e,this.color=i,this.maxWidth=s,this._textFragments=[],this.disposed=!1,this._dirty=!0,this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.dimensions=this.measureText(e),this._setDimension(this.dimensions,this.ctx),this._lastHashCode=this.getHashCode()}measureText(t,e){if(this.disposed)throw Error("Accessing disposed text instance! "+this.text);let i=null,s=(i=null!=e?this._getLinesFromText(t,e):t.split("\n")).reduce((t,e)=>t.length>e.length?t:e);this._applyFont(this.ctx);let r=this.ctx.measureText(s),n=Math.abs(r.actualBoundingBoxAscent)+Math.abs(r.actualBoundingBoxDescent),o=n*i.length;n=o;let a=o-Math.abs(r.actualBoundingBoxAscent);return new tq({left:0-Math.abs(r.actualBoundingBoxLeft)-this.font.padding,top:0-Math.abs(r.actualBoundingBoxAscent)-this.font.padding,bottom:0+a+this.font.padding,right:0+Math.abs(r.actualBoundingBoxRight)+this.font.padding})}_setDimension(t,e){let i=1;this.font.lineHeight&&(i=this.font.lineHeight/this.font.size),e.canvas.width=(t.width+2*this.font.padding)*2*this.font.quality,e.canvas.height=(t.height+2*this.font.padding)*2*this.font.quality*i}static getHashCode(t,e,i){var s;return e+"__hashcode__"+t.fontString+t.showDebug+t.textAlign+t.baseAlign+t.direction+t.lineHeight+JSON.stringify(t.shadow)+(t.padding.toString()+t.smoothing.toString()+t.lineWidth.toString()+t.lineDash.toString()+(null===(s=t.strokeColor)||void 0===s?void 0:s.toString())+(i?i.toString():t.color.toString()))}getHashCode(t=!0){return sH.getHashCode(this.font,this.text,t?this.color:void 0)}_applyRasterProperties(t){var e,i;t.translate(this.font.padding,this.font.padding),t.imageSmoothingEnabled=this.font.smoothing,t.lineWidth=this.font.lineWidth,t.setLineDash(null!==(e=this.font.lineDash)&&void 0!==e?e:t.getLineDash()),t.strokeStyle=null===(i=this.font.strokeColor)||void 0===i?void 0:i.toString(),t.fillStyle=this.color.toString()}_applyFont(t){t.resetTransform(),t.translate(this.font.padding+t.canvas.width/2,this.font.padding+t.canvas.height/2),t.scale(this.font.quality,this.font.quality),t.textAlign=this.font.textAlign,t.textBaseline=this.font.baseAlign,t.font=this.font.fontString,t.direction=this.font.direction,this.font.shadow&&(t.shadowColor=this.font.shadow.color.toString(),t.shadowBlur=this.font.shadow.blur,t.shadowOffsetX=this.font.shadow.offset.x,t.shadowOffsetY=this.font.shadow.offset.y)}_drawText(t,e,i){this._applyRasterProperties(t),this._applyFont(t);for(let s=0;se){for(;this.measureText(s).width>e;)r=s[s.length-1]+r,s=s.slice(0,-1);i[t]=s,i[t+1]=r}}return this._cachedText=t,this._cachedLines=i,this._cachedRenderWidth=e,i}}class sV{static measureText(t,e,i){let s=sH.getHashCode(e,t);if(sV._MEASURE_CACHE.has(s))return sV._MEASURE_CACHE.get(s);sV._LOGGER.debug("Font text measurement cache miss");let r=e.measureTextWithoutCache(t,i);return sV._MEASURE_CACHE.set(s,r),r}static getTextInstance(t,e,i){let s=sH.getHashCode(e,t,i),r=sV._TEXT_CACHE.get(s);return r||(r=new sH(e,t,i),sV._TEXT_CACHE.set(s,r),sV._LOGGER.debug("Font text instance cache miss")),sV._TEXT_USAGE.set(r,performance.now()),r}static checkAndClearCache(){let t=[],e=new Set;for(let[i,s]of sV._TEXT_USAGE.entries())if(s+sV.FONT_TIMEOUT{sV._TEXT_USAGE.delete(t)}),this._TEXT_CACHE.clear(),this._TEXT_USAGE.entries()))this._TEXT_CACHE.set(e.getHashCode(),e);let i=new Map;for(let t of e)sV._MEASURE_CACHE.has(t)&&i.set(t,sV._MEASURE_CACHE.get(t));this._MEASURE_CACHE.clear(),this._MEASURE_CACHE=i}static get cacheSize(){return sV._TEXT_USAGE.size}static clearCache(){for(let[t]of sV._TEXT_USAGE.entries())t.dispose();sV._TEXT_USAGE.clear(),sV._TEXT_CACHE.clear(),sV._MEASURE_CACHE.clear()}}sV.FONT_TIMEOUT=500,sV._LOGGER=tW.getInstance(),sV._TEXT_USAGE=new Map,sV._TEXT_CACHE=new Map,sV._MEASURE_CACHE=new Map;class sW extends et{constructor(t={}){var e,i,s,r,n,o,a,l,h,d,c,u,p,g,_,f,m,v,y,x;super(t),this.filtering=H.Blended,this.quality=2,this.padding=2,this.smoothing=!1,this.lineWidth=1,this.lineDash=[],this.color=tH.Black,this.family="sans-serif",this.style=ti.Normal,this.bold=!1,this.unit=J.Px,this.textAlign=tt.Left,this.baseAlign=te.Top,this.direction=ts.LeftToRight,this.lineHeight=void 0,this.size=10,this.shadow=null,this._textBounds=new tq,this._textMeasurement=new sH(this,"",tH.Black),this.smoothing=null!==(e=null==t?void 0:t.smoothing)&&void 0!==e?e:this.smoothing,this.padding=null!==(i=null==t?void 0:t.padding)&&void 0!==i?i:this.padding,this.color=null!==(s=null==t?void 0:t.color)&&void 0!==s?s:this.color,this.strokeColor=null!==(r=null==t?void 0:t.strokeColor)&&void 0!==r?r:this.strokeColor,this.lineDash=null!==(n=null==t?void 0:t.lineDash)&&void 0!==n?n:this.lineDash,this.lineWidth=null!==(o=null==t?void 0:t.lineWidth)&&void 0!==o?o:this.lineWidth,this.filtering=null!==(a=null==t?void 0:t.filtering)&&void 0!==a?a:this.filtering,this.family=null!==(l=null==t?void 0:t.family)&&void 0!==l?l:this.family,this.style=null!==(h=null==t?void 0:t.style)&&void 0!==h?h:this.style,this.bold=null!==(d=null==t?void 0:t.bold)&&void 0!==d?d:this.bold,this.size=null!==(c=null==t?void 0:t.size)&&void 0!==c?c:this.size,this.unit=null!==(u=null==t?void 0:t.unit)&&void 0!==u?u:this.unit,this.textAlign=null!==(p=null==t?void 0:t.textAlign)&&void 0!==p?p:this.textAlign,this.baseAlign=null!==(g=null==t?void 0:t.baseAlign)&&void 0!==g?g:this.baseAlign,this.direction=null!==(_=null==t?void 0:t.direction)&&void 0!==_?_:this.direction,this.lineHeight=null!==(f=null==t?void 0:t.lineHeight)&&void 0!==f?f:this.lineHeight,this.quality=null!==(m=null==t?void 0:t.quality)&&void 0!==m?m:this.quality,(null==t?void 0:t.shadow)&&(this.shadow={},this.shadow.blur=null!==(v=t.shadow.blur)&&void 0!==v?v:this.shadow.blur,this.shadow.offset=null!==(y=t.shadow.offset)&&void 0!==y?y:this.shadow.offset,this.shadow.color=null!==(x=t.shadow.color)&&void 0!==x?x:this.shadow.color)}clone(){return new sW({...this.cloneGraphicOptions(),size:this.size,unit:this.unit,family:this.family,style:this.style,bold:this.bold,textAlign:this.textAlign,baseAlign:this.baseAlign,direction:this.direction,shadow:this.shadow?{blur:this.shadow.blur,offset:this.shadow.offset,color:this.shadow.color}:null})}get fontString(){return`${this.style} ${this.bold?"bold":""} ${this.size}${this.unit} ${this.family}`}get localBounds(){return this._textBounds}_drawImage(t,e,i){}_rotate(t){var e;let i=null!==(e=this.origin)&&void 0!==e?e:this._textBounds.center;t.translate(i.x,i.y),t.rotate(this.rotation),t.translate(-i.x,-i.y)}_flip(t){this.flipHorizontal&&(t.translate(this._textBounds.width/this.scale.x,0),t.scale(-1,1)),this.flipVertical&&(t.translate(0,-this._textBounds.height/2/this.scale.y),t.scale(1,-1))}measureTextWithoutCache(t,e){return this._textMeasurement.measureText(t,e)}measureText(t,e){return sV.measureText(t,this,e)}_postDraw(t){t.restore()}render(t,e,i,s,r,n){let o=sV.getTextInstance(e,this,i);this._textBounds=o.dimensions,this._preDraw(t,s,r),o.render(t,s,r,n),this._postDraw(t)}}class sG extends et{constructor(t){var e,i;super(t),this._text="",this._textWidth=0,this._textHeight=0,this.font=null!==(e=t.font)&&void 0!==e?e:new sW,this.color=null!==(i=t.color)&&void 0!==i?i:this.color,this.text=t.text,this.maxWidth=t.maxWidth}clone(){var t,e;return new sG({text:this.text.slice(),color:null!==(e=null===(t=this.color)||void 0===t?void 0:t.clone())&&void 0!==e?e:tH.Black,font:this.font.clone(),maxWidth:this.maxWidth})}get text(){return this._text}set text(t){this._text=t,this._calculateDimension()}get font(){return this._font}set font(t){this._font=t}get width(){return 0===this._textWidth&&this._calculateDimension(),this._textWidth*this.scale.x}get height(){return 0===this._textHeight&&this._calculateDimension(),this._textHeight*this.scale.y}_calculateDimension(){let{width:t,height:e}=this.font.measureText(this._text,this.maxWidth);this._textWidth=t,this._textHeight=e}get localBounds(){return this.font.measureText(this._text,this.maxWidth).scale(this.scale)}_rotate(t){}_flip(t){}_preDraw(t,e,i){(this.isStale()||this.font.isStale())&&(this.font.flipHorizontal=this.flipHorizontal,this.font.flipVertical=this.flipVertical,this.font.rotation=this.rotation,this.font.origin=this.origin,this.font.opacity=this.opacity),this.font.tint=this.tint,super._preDraw(t,e,i)}_drawImage(t,e,i){var s;let r=tH.Black;this.font instanceof sW&&(r=null!==(s=this.color)&&void 0!==s?s:this.font.color);let{width:n,height:o}=this.font.measureText(this._text,this.maxWidth);this._textWidth=n,this._textHeight=o,this.font.render(t,this._text,r,e,i,this.maxWidth),this.font.showDebug&&(t.debug.drawRect(e-n,i-o,2*n,2*o),null!=this.maxWidth&&t.debug.drawRect(e,i,this.maxWidth,this.height,{color:tH.Yellow}))}}class sj extends s_{get pos(){return this.transform.pos}set pos(t){this.transform.pos=t.clone()}get oldPos(){return this.body.oldPos}set oldPos(t){this.body.oldPos.setTo(t.x,t.y)}get vel(){return this.motion.vel}set vel(t){this.motion.vel=t.clone()}get oldVel(){return this.body.oldVel}set oldVel(t){this.body.oldVel.setTo(t.x,t.y)}get acc(){return this.motion.acc}set acc(t){this.motion.acc=t.clone()}set oldAcc(t){this.body.oldAcc.setTo(t.x,t.y)}get oldAcc(){return this.body.oldAcc}get rotation(){return this.transform.rotation}set rotation(t){this.transform.rotation=t}get angularVelocity(){return this.motion.angularVelocity}set angularVelocity(t){this.motion.angularVelocity=t}get scale(){return this.get(iV).scale}set scale(t){this.get(iV).scale=t}get anchor(){return this._anchor}set anchor(t){this._anchor=t6(t,t=>this._handleAnchorChange(t)),this._handleAnchorChange(t)}_handleAnchorChange(t){this.graphics&&(this.graphics.anchor=t)}get offset(){return this._offset}set offset(t){this._offset=t6(t,t=>this._handleOffsetChange(t)),this._handleOffsetChange(t)}_handleOffsetChange(t){this.graphics&&(this.graphics.offset=t)}get isOffScreen(){return this.hasTag("ex.offscreen")}get draggable(){return this._draggable}set draggable(t){t&&(t&&!this._draggable?(this.events.on("pointerdragstart",this._pointerDragStartHandler),this.events.on("pointerdragend",this._pointerDragEndHandler),this.events.on("pointerdragmove",this._pointerDragMoveHandler),this.events.on("pointerdragleave",this._pointerDragLeaveHandler)):!t&&this._draggable&&(this.events.off("pointerdragstart",this._pointerDragStartHandler),this.events.off("pointerdragend",this._pointerDragEndHandler),this.events.off("pointerdragmove",this._pointerDragMoveHandler),this.events.off("pointerdragleave",this._pointerDragLeaveHandler)),this._draggable=t)}get color(){return this._color}set color(t){this._color=t.clone();let e=this.graphics.current;(e instanceof eO||e instanceof sG)&&(e.color=this._color)}constructor(t){super(),this.events=new tP,this._anchor=t6(tN.Half,t=>this._handleAnchorChange(t)),this._offset=t6(tN.Zero,t=>this._handleOffsetChange(t)),this.logger=tW.getInstance(),this._draggable=!1,this._dragging=!1,this._pointerDragStartHandler=()=>{this._dragging=!0},this._pointerDragEndHandler=()=>{this._dragging=!1},this._pointerDragMoveHandler=t=>{this._dragging&&(this.pos=t.worldPos)},this._pointerDragLeaveHandler=t=>{this._dragging&&(this.pos=t.worldPos)};let{name:e,x:i,y:s,pos:r,coordPlane:n,scale:o,width:a,height:l,radius:h,collider:d,vel:c,acc:u,rotation:p,angularVelocity:g,z:_,color:f,visible:m,opacity:v,anchor:y,offset:x,collisionType:w,collisionGroup:b}={...t};this.name=null!=e?e:this.name,this.anchor=null!=y?y:sj.defaults.anchor.clone(),this.offset=null!=x?x:tN.Zero,this.transform=new iV,this.addComponent(this.transform),this.pos=null!=r?r:tZ(null!=i?i:0,null!=s?s:0),this.rotation=null!=p?p:0,this.scale=null!=o?o:tZ(1,1),this.z=null!=_?_:0,this.transform.coordPlane=null!=n?n:j.World,this.pointer=new sx,this.addComponent(this.pointer),this.graphics=new sm({anchor:this.anchor,offset:this.offset,opacity:v}),this.addComponent(this.graphics),this.motion=new iW,this.addComponent(this.motion),this.vel=null!=c?c:tN.Zero,this.acc=null!=u?u:tN.Zero,this.angularVelocity=null!=g?g:0,this.actions=new sZ,this.addComponent(this.actions),this.body=new sh,this.addComponent(this.body),this.body.collisionType=null!=w?w:G.Passive,b&&(this.body.group=b),d?this.collider=new sl(d):h?this.collider=new sl(sa.Circle(h)):a>0&&l>0?this.collider=new sl(sa.Box(a,l,this.anchor)):this.collider=new sl,this.addComponent(this.collider),this.graphics.visible=null==m||m,f&&(this.color=f,a&&l?this.graphics.add(new sv({color:f,width:a,height:l})):h&&this.graphics.add(new sy({color:f,radius:h})))}clone(){let t=new sj({color:this.color.clone(),anchor:this.anchor.clone(),offset:this.offset.clone()});t.clearComponents(),t.processComponentRemoval(),t.addComponent(t.transform=this.transform.clone(),!0),t.addComponent(t.pointer=this.pointer.clone(),!0),t.addComponent(t.graphics=this.graphics.clone(),!0),t.addComponent(t.motion=this.motion.clone(),!0),t.addComponent(t.actions=this.actions.clone(),!0),t.addComponent(t.body=this.body.clone(),!0),t.addComponent(t.collider=this.collider.clone(),!0);let e=[this.transform,this.pointer,this.graphics,this.motion,this.actions,this.body,this.collider];for(let i of this.getComponents())e.includes(i)||t.addComponent(i.clone(),!0);return t}onInitialize(t){}_initialize(t){for(let e of(super._initialize(t),this.children))e._initialize(t)}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}_prekill(t){this.events.emit("prekill",new eG(this)),this.onPreKill(t)}onPreKill(t){}_postkill(t){this.events.emit("postkill",new ej(this)),this.onPostKill(t)}onPostKill(t){}kill(){this.scene?(this._prekill(this.scene),this.events.emit("kill",new eW(this)),super.kill(),this._postkill(this.scene)):this.logger.warn(`Cannot kill actor named "${this.name}", it was never added to the Scene`)}unkill(){this.active=!0}isKilled(){return!this.active}get z(){return this.get(iV).z}set z(t){this.get(iV).z=t}get center(){let t=this.getGlobalPos();return new tN(t.x+this.width/2-this.anchor.x*this.width,t.y+this.height/2-this.anchor.y*this.height)}get localCenter(){return new tN(this.pos.x+this.width/2-this.anchor.x*this.width,this.pos.y+this.height/2-this.anchor.y*this.height)}get width(){return this.collider.localBounds.width*this.getGlobalScale().x}get height(){return this.collider.localBounds.height*this.getGlobalScale().y}getGlobalRotation(){return this.get(iV).globalRotation}getGlobalPos(){return this.get(iV).globalPos}getGlobalScale(){return this.get(iV).globalScale}contains(t,e,i=!1){let s=tZ(t,e),r=this.get(sl);r.update();let n=r.get();if(!n)return!1;let o=n.contains(s);return i?o||this.children.some(i=>i.contains(t,e,!0)):o}within(t,e){let i=this.get(sl),s=t.get(sl),r=i.get(),n=s.get();return!!r&&!!n&&r.getClosestLineBetween(n).getLength()<=e}update(t,e){this._initialize(t),this._preupdate(t,e),this._postupdate(t,e)}onPreUpdate(t,e){}onPostUpdate(t,e){}onPreCollisionResolve(t,e,i,s){}onPostCollisionResolve(t,e,i,s){}onCollisionStart(t,e,i,s){}onCollisionEnd(t,e,i,s){}_preupdate(t,e){this.events.emit("preupdate",new e1(t,e,this)),this.onPreUpdate(t,e)}_postupdate(t,e){this.events.emit("postupdate",new e2(t,e,this)),this.onPostUpdate(t,e)}}function sq(t){return t instanceof sX}sj.defaults={anchor:tN.Half};class sX extends sj{constructor(t){var e,i;super({...t}),this.get(iV).coordPlane=j.Screen,this.anchor=null!==(e=null==t?void 0:t.anchor)&&void 0!==e?e:tZ(0,0),this.body.collisionType=null!==(i=null==t?void 0:t.collisionType)&&void 0!==i?i:G.PreventCollision,this.pointer.useGraphicsBounds=!0,this.pointer.useColliderShape=!1,!(null==t?void 0:t.collider)&&(null==t?void 0:t.width)>0&&(null==t?void 0:t.height)>0&&this.collider.useBoxCollider(this.width,this.height,this.anchor)}_initialize(t){this._engine=t,super._initialize(t)}contains(t,e,i=!0){if(i)return super.contains(t,e);let s=this._engine.worldToScreenCoordinates(new tN(t,e));return super.contains(s.x,s.y)}}class s${get complete(){return this._complete}constructor(t,e,i,s,r,n){if(this._logger=tW.getInstance(),this.id=0,this._elapsedTime=0,this._totalTimeAlive=0,this._running=!1,this._numberOfTicks=0,this.interval=10,this.repeats=!1,this.maxNumberOfRepeats=-1,this.randomRange=[0,0],this._baseInterval=10,this._generateRandomInterval=()=>this._baseInterval+this.random.integer(this.randomRange[0],this.randomRange[1]),this._complete=!1,this.scene=null,"function"!=typeof t){let o=t;t=o.fcn,e=o.interval,i=o.repeats,s=o.numberOfRepeats,r=o.randomRange,n=o.random}if(s&&s>=0&&(this.maxNumberOfRepeats=s,!i))throw Error("repeats must be set to true if numberOfRepeats is set");if(this.id=s$._MAX_ID++,this._callbacks=[],this._baseInterval=this.interval=e,r){if(r[0]>r[1])throw Error("min value must be lower than max value for range");this.random=null!=n?n:new tI,this.randomRange=r,this.interval=this._generateRandomInterval(),this.on(()=>{this.interval=this._generateRandomInterval()})}this.repeats=i||this.repeats,t&&this.on(t)}on(t){this._callbacks.push(t)}off(t){let e=this._callbacks.indexOf(t);this._callbacks.splice(e,1)}update(t){this._running&&(this._totalTimeAlive+=t,this._elapsedTime+=t,this.maxNumberOfRepeats>-1&&this._numberOfTicks>=this.maxNumberOfRepeats&&(this._complete=!0,this._running=!1,this._elapsedTime=0),!this.complete&&this._elapsedTime>=this.interval&&(this._callbacks.forEach(t=>{t.call(this)}),this._numberOfTicks++,this.repeats||(this._complete=!0,this._running=!1),this._elapsedTime=0))}reset(t,e){if(t&&t>=0&&(this._baseInterval=this.interval=t),this.maxNumberOfRepeats&&this.maxNumberOfRepeats>=0&&(this.maxNumberOfRepeats=e,!this.repeats))throw Error("repeats must be set to true if numberOfRepeats is set");this._complete=!1,this._elapsedTime=0,this._numberOfTicks=0}get timesRepeated(){return this._numberOfTicks}getTimeRunning(){return this._totalTimeAlive}get timeToNextAction(){return this.complete?0:this.interval-this._elapsedTime}get timeElapsedTowardNextAction(){return this._elapsedTime}get isRunning(){return this._running}pause(){return this._running=!1,this}resume(){return this._running=!0,this}start(){return this.scene||this._logger.warn("Cannot start a timer not part of a scene, timer wont start until added"),this._running=!0,this.complete&&(this._complete=!1,this._elapsedTime=0,this._numberOfTicks=0),this}stop(){return this._running=!1,this._elapsedTime=0,this._numberOfTicks=0,this}cancel(){this.pause(),this.scene&&this.scene.cancelTimer(this)}}s$._MAX_ID=0;class sK extends iZ{constructor(t){super(),this.parallaxFactor=tZ(1,1),this.parallaxFactor=null!=t?t:this.parallaxFactor}}class sY extends iZ{constructor(t,e=!0){super(),this.draw=t,this.useTransform=e}}let sQ={PreUpdate:"preupdate",PostUpdate:"postupdate",PreDraw:"predraw",PostDraw:"postdraw"};class sJ extends s_{flagCollidersDirty(){this._collidersDirty=!0}flagTilesDirty(){for(let t=0;tthis.draw(t,e)})),this.addComponent(new sY((t,e)=>this.debug(t,e),!1)),this.addComponent(new sl),this._graphics=this.get(sm),this.transform=this.get(iV),this._motion=this.get(iW),this.collider=this.get(sl),this._composite=this.collider.useCompositeCollider([]),this.transform.pos=null!==(i=t.pos)&&void 0!==i?i:tN.Zero,this._oldPos=this.transform.pos.clone(),this._oldScale=this.transform.scale.clone(),this.renderFromTopOfGraphic=null!==(s=t.renderFromTopOfGraphic)&&void 0!==s?s:this.renderFromTopOfGraphic,this.tileWidth=t.tileWidth,this.tileHeight=t.tileHeight,this.rows=t.rows,this.columns=t.columns,this.tiles=Array(this.rows*this.columns),this._rows=Array(this.rows),this._cols=Array(this.columns);let r=[];for(let t=0;t!!t&&!!e&&t.top===e.top&&t.bottom===e.bottom&&t.right===e.left,s=(t,e,s=this.meshingLookBehind)=>{if(!t)return!1;for(let r=e.length-1;r>=0&&!(s--<0);r--){let s=e[r];if(i(s,t))return e[r]=s.combine(t),!0}return!1};for(let i=0;i0){for(let t of n.getColliders()){let e=this._getOrSetColliderOriginalOffset(t);t.offset=tZ(n.x*this.tileWidth*this.scale.x,n.y*this.tileHeight*this.scale.y).add(e),t.owner=this,this._composite.addCollider(t)}t&&!s(t,e)&&e.push(t),t=null}else t=t?t.combine(n.defaultGeometry):n.defaultGeometry}else t&&!s(t,e)&&e.push(t),t=null}t&&!s(t,e)&&e.push(t),t=null}for(let t of e){let e=sa.Box(t.width,t.height,tN.Zero,tZ(t.left-this.pos.x,t.top-this.pos.y));e.owner=this,this._composite.addCollider(e)}this.collider.update(),this.collider.$colliderAdded.notifyAll(this._composite)}getTileByIndex(t){return this.tiles[t]}getTile(t,e){return t<0||e<0||t>=this.columns||e>=this.rows?null:this.tiles[t+e*this.columns]}getTileByPoint(t){let{x:e,y:i}=this._getTileCoordinates(t),s=this.getTile(e,i);return e>=0&&i>=0&&e-1&&(this._graphics.splice(e,1),this._offsets.splice(e,1))}clearGraphics(){this._graphics.length=0,this._offsets.length=0}getColliders(){return this._colliders}addCollider(t){this._colliders.push(t),this.map.flagCollidersDirty()}removeCollider(t){let e=this._colliders.indexOf(t);e>-1&&this._colliders.splice(e,1),this.map.flagCollidersDirty()}clearColliders(){this._colliders.length=0,this.map.flagCollidersDirty()}constructor(t){var e,i;super(),this._posDirty=!1,this._solid=!1,this._graphics=[],this._offsets=[],this._colliders=[],this.data=new Map,this.x=t.x,this.y=t.y,this.map=t.map,this._width=t.map.tileWidth*this.map.scale.x,this._height=t.map.tileHeight*this.map.scale.y,this.solid=null!==(e=t.solid)&&void 0!==e?e:this.solid,this._graphics=null!==(i=t.graphics)&&void 0!==i?i:[],this._recalculate()}flagDirty(){return this._posDirty=!0}_recalculate(){let t=this.map.pos.add(tZ(this.x*this.map.tileWidth,this.y*this.map.tileHeight));this._geometry=new tq(t.x,t.y,t.x+this.map.tileWidth,t.y+this.map.tileHeight),this._width=this.map.tileWidth*this.map.scale.x,this._height=this.map.tileHeight*this.map.scale.y,this._pos=this.map.pos.add(tZ(this.x*this._width,this.y*this._height)),this._bounds=new tq(this._pos.x,this._pos.y,this._pos.x+this._width,this._pos.y+this._height),this.map.rotation&&(this._bounds=this._bounds.rotate(this.map.rotation,this.map.pos)),this._posDirty=!1}get bounds(){return this._posDirty&&this._recalculate(),this._bounds}get defaultGeometry(){return this._geometry}get center(){return this._posDirty&&this._recalculate(),new tN(this._pos.x+this._width/2,this._pos.y+this._height/2)}}class s1{constructor(t){this.camera=t}lockToActor(t){this.camera.addStrategy(new s2(t))}lockToActorAxis(t,e){this.camera.addStrategy(new s5(t,e))}elasticToActor(t,e,i){this.camera.addStrategy(new s4(t,e,i))}radiusAroundActor(t,e){this.camera.addStrategy(new s3(t,e))}limitCameraBounds(t){this.camera.addStrategy(new s9(t))}}(C=tr||(tr={}))[C.X=0]="X",C[C.Y=1]="Y";class s2{constructor(t){this.target=t,this.action=(t,e,i,s)=>t.center}}class s5{constructor(t,e){this.target=t,this.axis=e,this.action=(t,e,i,s)=>{let r=t.center,n=e.getFocus();return this.axis===tr.X?new tN(r.x,n.y):new tN(n.x,r.y)}}}class s4{constructor(t,e,i){this.target=t,this.cameraElasticity=e,this.cameraFriction=i,this.action=(t,e,i,s)=>{let r=t.center,n=e.getFocus(),o=e.vel.clone(),a=r.sub(n).scale(this.cameraElasticity),l=(o=o.add(a)).scale(-1).scale(this.cameraFriction);return o=o.add(l),n=n.add(o)}}}class s3{constructor(t,e){this.target=t,this.radius=e,this.action=(t,e,i,s)=>{let r=t.center,n=e.getFocus(),o=r.sub(n),a=o.size;if(a>=this.radius){let t=a-this.radius;return n.add(o.normalize().scale(t))}return n}}}class s9{constructor(t){this.target=t,this.boundSizeChecked=!1,this.action=(t,e,i,s)=>{let r=e.getFocus();this.boundSizeChecked||((t.bottom-t.topt.right-i.halfDrawWidth&&(n=t.right-i.halfDrawWidth),r.yt.bottom-i.halfDrawHeight&&(o=t.bottom-i.halfDrawHeight),tZ(n,o)}}}let s6={Initialize:"initialize",PreUpdate:"preupdate",PostUpdate:"postupdate"};class s7{constructor(){this.events=new tP,this.transform=t2.identity(),this.inverse=t2.identity(),this._cameraStrategies=[],this.strategy=new s1(this),this._z=1,this.dz=0,this.az=0,this.rotation=0,this._angularVelocity=0,this._posChanged=!1,this._pos=t8(tN.Zero,()=>this._posChanged=!0),this.drawPos=this.pos.clone(),this._oldPos=this.pos.clone(),this.vel=tN.Zero,this.acc=tN.Zero,this._cameraMoving=!1,this._currentLerpTime=0,this._lerpDuration=1e3,this._lerpStart=null,this._lerpEnd=null,this._isShaking=!1,this._shakeMagnitudeX=0,this._shakeMagnitudeY=0,this._shakeDuration=0,this._elapsedShakeTime=0,this._xShake=0,this._yShake=0,this._isZooming=!1,this._zoomStart=1,this._zoomEnd=1,this._currentZoomTime=0,this._zoomDuration=0,this._zoomEasing=sw.EaseInOutCubic,this._easing=sw.EaseInOutCubic,this._halfWidth=0,this._halfHeight=0,this._viewport=null,this._isInitialized=!1,this._snapPos=tZ(0,0)}get zoom(){return this._z}set zoom(t){this._z=t,this._engine&&(this._halfWidth=this._engine.halfDrawWidth,this._halfHeight=this._engine.halfDrawHeight)}get angularVelocity(){return this._angularVelocity}set angularVelocity(t){this._angularVelocity=t}get pos(){return this._pos}set pos(t){this._pos=t8(t,()=>this._posChanged=!0),this._posChanged=!0}get x(){return this.pos.x}set x(t){this._follow||this._cameraMoving||(this.pos=tZ(t,this.pos.y))}get y(){return this.pos.y}set y(t){this._follow||this._cameraMoving||(this.pos=tZ(this.pos.x,t))}get dx(){return this.vel.x}set dx(t){this.vel=tZ(t,this.vel.y)}get dy(){return this.vel.y}set dy(t){this.vel=tZ(this.vel.x,t)}get ax(){return this.acc.x}set ax(t){this.acc=tZ(t,this.acc.y)}get ay(){return this.acc.y}set ay(t){this.acc=tZ(this.acc.x,t)}getFocus(){return this.pos}move(t,e,i=sw.EaseInOutCubic){if("function"!=typeof i)throw"Please specify an EasingFunction";return this._follow?Promise.reject(t):(this._lerpPromise&&this._lerpResolve&&this._lerpResolve(t),this._lerpPromise=new Promise(t=>{this._lerpResolve=t}),this._lerpStart=this.getFocus().clone(),this._lerpDuration=e,this._lerpEnd=t,this._currentLerpTime=0,this._cameraMoving=!0,this._easing=i,this._lerpPromise)}shake(t,e,i){this._isShaking=!0,this._shakeMagnitudeX=t,this._shakeMagnitudeY=e,this._shakeDuration=i}zoomOverTime(t,e=0,i=sw.EaseInOutCubic){return(this._zoomPromise=new Promise(t=>{this._zoomResolve=t}),e)?(this._isZooming=!0,this._zoomEasing=i,this._currentZoomTime=0,this._zoomDuration=e,this._zoomStart=this.zoom,this._zoomEnd=t,this._zoomPromise):(this._isZooming=!1,this.zoom=t,Promise.resolve(!0))}get viewport(){return this._viewport?this._viewport:new tq(0,0,0,0)}addStrategy(t){this._cameraStrategies.push(t)}removeStrategy(t){tK(t,this._cameraStrategies)}clearAllStrategies(){this._cameraStrategies.length=0}_preupdate(t,e){this.events.emit("preupdate",new e1(t,e,this)),this.onPreUpdate(t,e)}onPreUpdate(t,e){}_postupdate(t,e){this.events.emit("postupdate",new e2(t,e,this)),this.onPostUpdate(t,e)}onPostUpdate(t,e){}get isInitialized(){return this._isInitialized}_initialize(t){if(!this.isInitialized){this._engine=t,this._screen=t.screen;let e=this._screen.contentArea,i=tZ(e.width/2,e.height/2);if(!this._engine.loadingComplete){let t=this._screen.peekResolution();t&&(i=tZ(t.width/2,t.height/2))}this._halfWidth=i.x,this._halfHeight=i.y,this._posChanged||(this.pos=i),this.pos.clone(this.drawPos),this.updateTransform(this.pos),this.runStrategies(t,t.clock.elapsed()),this.updateViewport(),this.updateTransform(this.pos),this.pos.clone(this._oldPos),this.onInitialize(t),this.events.emit("initialize",new id(t,this)),this._isInitialized=!0}}onInitialize(t){}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}runStrategies(t,e){for(let i of this._cameraStrategies)this.pos=i.action.call(i,i.target,this,t,e)}updateViewport(){this._viewport=new tq(this.x-this._halfWidth,this.y-this._halfHeight,this.x+this._halfWidth,this.y+this._halfHeight)}update(t,e){if(this._initialize(t),this._preupdate(t,e),this.pos.clone(this._oldPos),this.pos=this.pos.add(this.vel.scale(e/1e3)),this.zoom+=this.dz*e/1e3,this.vel=this.vel.add(this.acc.scale(e/1e3)),this.dz+=this.az*e/1e3,this.rotation+=this.angularVelocity*e/1e3,this._isZooming){if(this._currentZoomTime=this._shakeDuration}}let s8={ExitTrigger:"exit",EnterTrigger:"enter"},rt={pos:tN.Zero,width:10,height:10,visible:!1,action:()=>{},filter:()=>!0,repeat:-1};class re extends sj{constructor(t){super({x:t.pos.x,y:t.pos.y,width:t.width,height:t.height}),this.events=new tP,this.action=()=>{},this.filter=()=>!0,this.repeat=-1,t={...rt,...t},this.filter=t.filter||this.filter,this.repeat=t.repeat||this.repeat,this.action=t.action||this.action,t.target&&(this.target=t.target),this.graphics.visible=t.visible,this.body.collisionType=G.Passive,this.events.on("collisionstart",t=>{this.filter(t.other)&&(this.events.emit("enter",new i_(this,t.other)),this._dispatchAction(),0===this.repeat&&this.kill())}),this.events.on("collisionend",t=>{this.filter(t.other)&&this.events.emit("exit",new im(this,t.other))})}set target(t){this._target=t,this.filter=e=>e===t}get target(){return this._target}_initialize(t){super._initialize(t)}_dispatchAction(){0!==this.repeat&&(this.action.call(this),this.repeat--)}}let ri={Highest:-1/0,Higher:-5,Average:0,Lower:5,Lowest:1/0};(T=tn||(tn={})).Update="update",T.Draw="draw";class rs{constructor(){this.priority=ri.Average}}class rr{constructor(t){this._world=t,this.entities=[],this._entityIndex={},this._entitiesToRemove=[]}updateEntities(t,e){for(let i of this.entities)i.update(t.engine,e),i.active||this.removeEntity(i)}findEntitiesForRemoval(){for(let t of this.entities)t.active||this.removeEntity(t)}addEntity(t){t.active=!0,t.scene=this._world.scene,t&&!this._entityIndex[t.id]&&(this._entityIndex[t.id]=t,this.entities.push(t),this._world.queryManager.addEntity(t),t.children.forEach(e=>{e.scene=t.scene,this.addEntity(e)}),t.childrenAdded$.register({notify:t=>{this.addEntity(t)}}),t.childrenRemoved$.register({notify:t=>{this.removeEntity(t,!1)}}))}removeEntity(t,e=!0){var i,s;let r=0;r=t instanceof s_?t.id:t;let n=this._entityIndex[r];if(n&&n.active&&(n.active=!1),n&&e){this._entitiesToRemove.push(n);return}delete this._entityIndex[r],n&&(n.scene=null,tK(n,this.entities),this._world.queryManager.removeEntity(n),n.children.forEach(t=>{t.scene=null,this.removeEntity(t,e)}),n.childrenAdded$.clear(),n.childrenRemoved$.clear(),(null===(s=null===(i=this._world)||void 0===i?void 0:i.scene)||void 0===s?void 0:s.engine)&&this._world.scene.engine.stats.currFrame.actors.killed++)}processEntityRemovals(){for(let t of this._entitiesToRemove)t.active||this.removeEntity(t,!1);this._entitiesToRemove.length=0}processComponentRemovals(){for(let t of this.entities)t.processComponentRemoval()}getById(t){return this._entityIndex[t]}getByName(t){return this.entities.filter(e=>e.name===t)}clear(){for(let t=this.entities.length-1;t>=0;t--)this.removeEntity(this.entities[t])}}class rn{constructor(t){if(this.requiredComponents=t,this.components=new Set,this.entities=[],this.entityAdded$=new iH,this.entityRemoved$=new iH,0===t.length)throw Error("Cannot create query without components");for(let e of t)this.components.add(e);this.id=rn.createId(t)}static createId(t){return t.slice().map(t=>t.name).sort().join("-")}checkAndAdd(t){return!!(!this.entities.includes(t)&&t.hasAll(Array.from(this.components)))&&(this.entities.push(t),this.entityAdded$.notifyAll(t),!0)}removeEntity(t){let e=this.entities.indexOf(t);e>-1&&(this.entities.splice(e,1),this.entityRemoved$.notifyAll(t))}getEntities(t){return t&&this.entities.sort(t),this.entities}}class ro{constructor(t){if(this.requiredTags=t,this.tags=new Set,this.entities=[],this.entityAdded$=new iH,this.entityRemoved$=new iH,0===t.length)throw Error("Cannot create tag query without tags");for(let e of t)this.tags.add(e);this.id=ro.createId(t)}static createId(t){return t.slice().sort().join("-")}checkAndAdd(t){return!!(!this.entities.includes(t)&&t.hasAllTags(Array.from(this.tags)))&&(this.entities.push(t),this.entityAdded$.notifyAll(t),!0)}removeEntity(t){let e=this.entities.indexOf(t);e>-1&&(this.entities.splice(e,1),this.entityRemoved$.notifyAll(t))}getEntities(t){return t&&this.entities.sort(t),this.entities}}class ra{constructor(t){this._world=t,this._queries=new Map,this._addComponentHandlers=new Map,this._removeComponentHandlers=new Map,this._componentToQueriesIndex=new Map,this._tagQueries=new Map,this._addTagHandlers=new Map,this._removeTagHandlers=new Map,this._tagToQueriesIndex=new Map,this._createAddComponentHandler=t=>e=>{this.addComponent(t,e)},this._createRemoveComponentHandler=t=>e=>{this.removeComponent(t,e)},this._createAddTagHandler=t=>e=>{this.addTag(t,e)},this._createRemoveTagHandler=t=>e=>{this.removeTag(t,e)}}createQuery(t){let e=rn.createId(t);if(this._queries.has(e))return this._queries.get(e);let i=new rn(t);for(let e of(this._queries.set(i.id,i),t)){let t=this._componentToQueriesIndex.get(e);t?t.push(i):this._componentToQueriesIndex.set(e,[i])}for(let t of this._world.entities)this.addEntity(t);return i}createTagQuery(t){let e=ro.createId(t);if(this._tagQueries.has(e))return this._tagQueries.get(e);let i=new ro(t);for(let e of(this._tagQueries.set(i.id,i),t)){let t=this._tagToQueriesIndex.get(e);t?t.push(i):this._tagToQueriesIndex.set(e,[i])}for(let t of this._world.entities)this.addEntity(t);return i}addEntity(t){let e=this._addComponentHandlers.get(t),i=this._removeComponentHandlers.get(t),s=null!=e?e:this._createAddComponentHandler(t),r=null!=i?i:this._createRemoveComponentHandler(t);this._addComponentHandlers.set(t,s),this._removeComponentHandlers.set(t,r);let n=this._addTagHandlers.get(t),o=this._removeTagHandlers.get(t),a=null!=n?n:this._createAddTagHandler(t),l=null!=o?o:this._createRemoveTagHandler(t);for(let e of(this._addTagHandlers.set(t,a),this._removeTagHandlers.set(t,l),this._queries.values()))e.checkAndAdd(t);for(let e of this._tagQueries.values())e.checkAndAdd(t);t.componentAdded$.subscribe(s),t.componentRemoved$.subscribe(r),t.tagAdded$.subscribe(a),t.tagRemoved$.subscribe(l)}removeEntity(t){let e=this._addComponentHandlers.get(t),i=this._removeComponentHandlers.get(t);for(let e of this._queries.values())e.removeEntity(t);e&&t.componentAdded$.unsubscribe(e),i&&t.componentRemoved$.unsubscribe(i);let s=this._addTagHandlers.get(t),r=this._removeTagHandlers.get(t);for(let e of this._tagQueries.values())e.removeEntity(t);s&&t.tagAdded$.unsubscribe(s),r&&t.tagRemoved$.unsubscribe(r)}addComponent(t,e){var i;for(let s of null!==(i=this._componentToQueriesIndex.get(e.constructor))&&void 0!==i?i:[])s.checkAndAdd(t)}removeComponent(t,e){var i;for(let s of null!==(i=this._componentToQueriesIndex.get(e.constructor))&&void 0!==i?i:[])s.removeEntity(t)}addTag(t,e){var i;for(let s of null!==(i=this._tagToQueriesIndex.get(e))&&void 0!==i?i:[])s.checkAndAdd(t)}removeTag(t,e){var i;for(let s of null!==(i=this._tagToQueriesIndex.get(e))&&void 0!==i?i:[])s.removeEntity(t)}}function rl(t){var e,i;return!!(null==t?void 0:t.prototype)&&!!(null===(i=null===(e=null==t?void 0:t.prototype)||void 0===e?void 0:e.constructor)||void 0===i?void 0:i.name)}class rh{constructor(t){this._world=t,this.systems=[],this.initialized=!1}get(t){return this.systems.find(e=>e instanceof t)}addSystem(t){let e;e=t instanceof rs?t:new t(this._world),this.systems.push(e),this.systems.sort((t,e)=>t.priority-e.priority),this.initialized&&e.initialize&&e.initialize(this._world,this._world.scene)}removeSystem(t){tK(t,this.systems)}initialize(){if(!this.initialized)for(let t of(this.initialized=!0,this.systems))t.initialize&&t.initialize(this._world,this._world.scene)}updateSystems(t,e,i){let s=this.systems.filter(e=>e.systemType===t);for(let t of s)t.preupdate&&t.preupdate(e,i);for(let t of s)t.update(i);for(let t of s)t.postupdate&&t.postupdate(e,i)}clear(){for(let t=this.systems.length-1;t>=0;t--)this.removeSystem(this.systems[t])}}class rd{constructor(t){this.scene=t,this.queryManager=new ra(this),this.entityManager=new rr(this),this.systemManager=new rh(this)}query(t){return this.queryManager.createQuery(t)}queryTags(t){return this.queryManager.createTagQuery(t)}update(t,e){t===tn.Update&&this.entityManager.updateEntities(this.scene,e),this.systemManager.updateSystems(t,this.scene,e),this.entityManager.findEntitiesForRemoval(),this.entityManager.processComponentRemovals(),this.entityManager.processEntityRemovals()}add(t){t instanceof s_&&this.entityManager.addEntity(t),(t instanceof rs||rl(t))&&this.systemManager.addSystem(t)}get(t){return this.systemManager.get(t)}remove(t,e=!0){t instanceof s_&&this.entityManager.removeEntity(t,e),t instanceof rs&&this.systemManager.removeSystem(t)}get entities(){return this.entityManager.entities}clearEntities(){this.entityManager.clear()}clearSystems(){this.systemManager.clear()}}class rc{static integrate(t,e,i,s){let r=s/1e3;e.vel.addEqual(i.scale(r,rc._ACC)),t.pos.add(e.vel.scale(r,rc._VEL),rc._POS).addEqual(i.scale(.5*r*r,rc._VEL_ACC)),e.angularVelocity+=e.torque*(1/e.inertia)*r;let n=t.rotation+e.angularVelocity*r;t.scale.add(e.scaleFactor.scale(r,this._SCALE_FACTOR),rc._SCALE),t.get().setTransform(rc._POS,n,rc._SCALE)}}rc._POS=new tN(0,0),rc._SCALE=new tN(1,1),rc._ACC=new tN(0,0),rc._VEL=new tN(0,0),rc._VEL_ACC=new tN(0,0),rc._SCALE_FACTOR=new tN(0,0);class ru extends rs{constructor(t,e){super(),this.world=t,this.physics=e,this.systemType=tn.Update,this.priority=ri.Higher,this._physicsConfigDirty=!1,e.$configUpdate.subscribe(()=>this._physicsConfigDirty=!0),this.query=this.world.query([iV,iW])}update(t){let e,i;let s=this.query.entities;for(let r=0;r!t.isCanceled()),this.config.contactSolveBias){case K.HorizontalFirst:e=i2;break;case K.VerticalFirst:e=i1;break;default:e=i5}for(let i of(t.sort((t,i)=>{let s=this.directionMap.get(t.id),r=this.directionMap.get(i.id),n=this.distanceMap.get(t.id),o=this.distanceMap.get(i.id);return e[s]-e[r]||n-o}),t))this.solvePosition(i),this.solveVelocity(i);return this.postSolve(t),t}preSolve(t){for(let e of t){if(1e-4>Math.abs(e.mtv.x)&&1e-4>Math.abs(e.mtv.y)){e.cancel();continue}let t=N.fromDirection(e.mtv),i=e.mtv.negate(),s=e.colliderA.worldPos.squareDistance(e.colliderB.worldPos);this.distanceMap.set(e.id,s),this.directionMap.set(e.id,t===N.Left||t===N.Right?"horizontal":"vertical"),e.colliderA.events.emit("precollision",new ie(e.colliderA,e.colliderB,t,i,e)),e.colliderB.events.emit("precollision",new ie(e.colliderB,e.colliderA,N.getOpposite(t),i.negate(),e))}}postSolve(t){var e,i;for(let s of t){if(s.isCanceled())continue;let t=s.colliderA,r=s.colliderB,n=null===(e=t.owner)||void 0===e?void 0:e.get(sh),o=null===(i=r.owner)||void 0===i?void 0:i.get(sh);if(n&&o&&(n.collisionType===G.Passive||o.collisionType===G.Passive))continue;let a=N.fromDirection(s.mtv),l=s.mtv.negate();s.colliderA.events.emit("postcollision",new ii(s.colliderA,s.colliderB,a,l,s)),s.colliderB.events.emit("postcollision",new ii(s.colliderB,s.colliderA,N.getOpposite(a),l.negate(),s))}}solvePosition(t){var e,i;if(!t.colliderA.bounds.overlaps(t.colliderB.bounds,1e-4)||1e-4>Math.abs(t.mtv.x)&&1e-4>Math.abs(t.mtv.y)){t.cancel();return}let s=t.mtv,r=t.colliderA,n=t.colliderB,o=null===(e=r.owner)||void 0===e?void 0:e.get(sh),a=null===(i=n.owner)||void 0===i?void 0:i.get(sh);if(o&&a){if(o.collisionType===G.Passive||a.collisionType===G.Passive)return;o.collisionType===G.Active&&a.collisionType===G.Active&&(s=s.scale(.5)),o.collisionType===G.Active&&(o.globalPos.x-=s.x,o.globalPos.y-=s.y,r.update(o.transform.get())),a.collisionType===G.Active&&(a.globalPos.x+=s.x,a.globalPos.y+=s.y,n.update(a.transform.get()))}}solveVelocity(t){var e,i;if(t.isCanceled())return;let s=t.colliderA,r=t.colliderB,n=null===(e=s.owner)||void 0===e?void 0:e.get(sh),o=null===(i=r.owner)||void 0===i?void 0:i.get(sh);if(n&&o){if(n.collisionType===G.Passive||o.collisionType===G.Passive)return;let e=t.normal,i=e.negate();if(n.collisionType===G.Active&&0>n.vel.normalize().dot(i)){let t=e.scale(e.dot(n.vel.negate()));n.vel=n.vel.add(t)}if(o.collisionType===G.Active&&0>o.vel.normalize().dot(e)){let t=i.scale(i.dot(o.vel.negate()));o.vel=o.vel.add(t)}}}}class rg{constructor(t,e,i){this.point=t,this.local=e,this.contact=i,this.normalImpulse=0,this.tangentImpulse=0,this.normalMass=0,this.tangentMass=0,this.aToContact=new tN(0,0),this.bToContact=new tN(0,0),this.originalVelocityAndRestitution=0,this.update()}update(){var t,e;let i=null===(t=this.contact.colliderA.owner)||void 0===t?void 0:t.get(sh),s=null===(e=this.contact.colliderB.owner)||void 0===e?void 0:e.get(sh);if(i&&s){let t=this.contact.normal,e=this.contact.tangent;this.aToContact=this.point.sub(i.globalPos),this.bToContact=this.point.sub(s.globalPos);let r=this.aToContact.cross(t),n=this.bToContact.cross(t);this.normalMass=i.inverseMass+s.inverseMass+i.inverseInertia*r*r+s.inverseInertia*n*n;let o=this.aToContact.cross(e),a=this.bToContact.cross(e);this.tangentMass=i.inverseMass+s.inverseMass+i.inverseInertia*o*o+s.inverseInertia*a*a}return this}getRelativeVelocity(){var t,e;let i=null===(t=this.contact.colliderA.owner)||void 0===t?void 0:t.get(sh),s=null===(e=this.contact.colliderB.owner)||void 0===e?void 0:e.get(sh);if(i&&s){let t=i.vel.add(tN.cross(i.angularVelocity,this.aToContact));return s.vel.add(tN.cross(s.angularVelocity,this.bToContact)).sub(t)}return tN.Zero}}class r_{constructor(t){this.config=t,this.lastFrameContacts=new Map,this.idToContactConstraint=new Map}getContactConstraints(t){var e;return null!==(e=this.idToContactConstraint.get(t))&&void 0!==e?e:[]}solve(t){return this.preSolve(t),t=t.filter(t=>!t.isCanceled()),this.solveVelocity(t),this.solvePosition(t),this.postSolve(t),t}preSolve(t){var e,i,s;for(let e of t){if(1e-4>Math.abs(e.mtv.x)&&1e-4>Math.abs(e.mtv.y)){e.cancel();continue}let t=N.fromDirection(e.mtv);e.colliderA.events.emit("precollision",new ie(e.colliderA,e.colliderB,t,e.mtv,e)),e.colliderA.events.emit("beforecollisionresolve",new io(e.colliderA,e.colliderB,t,e.mtv,e)),e.colliderB.events.emit("precollision",new ie(e.colliderB,e.colliderA,N.getOpposite(t),e.mtv.negate(),e)),e.colliderB.events.emit("beforecollisionresolve",new io(e.colliderB,e.colliderA,N.getOpposite(t),e.mtv.negate(),e)),e.matchAwake()}let r=Array.from(this.idToContactConstraint.keys());for(let n of t){let t=r.indexOf(n.id);t>-1&&r.splice(t,1);let o=null!==(e=this.idToContactConstraint.get(n.id))&&void 0!==e?e:[],a=0,l=n.colliderA.owner.get(sh),h=n.colliderB.owner.get(sh);if(l&&h)for(let t of n.points){let e=n.normal,r=n.tangent,d=t.sub(l.globalPos),c=t.sub(h.globalPos),u=d.cross(e),p=c.cross(e),g=l.inverseMass+h.inverseMass+l.inverseInertia*u*u+h.inverseInertia*p*p,_=d.cross(r),f=c.cross(r),m=l.inverseMass+h.inverseMass+l.inverseInertia*_*_+h.inverseInertia*f*f;o[a]&&(null===(s=null===(i=o[a])||void 0===i?void 0:i.point)||void 0===s?void 0:s.squareDistance(t))<4?(o[a].point=t,o[a].local=n.localPoints[a]):o[a]=new rg(t,n.localPoints[a],n),o[a].aToContact=d,o[a].bToContact=c,o[a].normalMass=1/g,o[a].tangentMass=1/m;let v=l.bounciness>h.bounciness?l.bounciness:h.bounciness,y=n.normal.dot(o[a].getRelativeVelocity());o[a].originalVelocityAndRestitution=0,y<-.1&&(o[a].originalVelocityAndRestitution=-v*y),a++}this.idToContactConstraint.set(n.id,o)}for(let t of r)this.idToContactConstraint.delete(t);if(this.config.warmStart)this.warmStart(t);else for(let e of t)for(let t of this.getContactConstraints(e.id))t.normalImpulse=0,t.tangentImpulse=0}postSolve(t){for(let e of t){let t=e.colliderA.owner.get(sh),i=e.colliderB.owner.get(sh);if(t&&i){if(t.collisionType===G.Passive||i.collisionType===G.Passive)continue;t.updateMotion(),i.updateMotion()}let s=N.fromDirection(e.mtv);e.colliderA.events.emit("postcollision",new ii(e.colliderA,e.colliderB,s,e.mtv,e)),e.colliderA.events.emit("aftercollisionresolve",new ia(e.colliderA,e.colliderB,s,e.mtv,e)),e.colliderB.events.emit("postcollision",new ii(e.colliderB,e.colliderA,N.getOpposite(s),e.mtv.negate(),e)),e.colliderB.events.emit("aftercollisionresolve",new ia(e.colliderB,e.colliderA,N.getOpposite(s),e.mtv.negate(),e))}for(let e of(this.lastFrameContacts.clear(),t))this.lastFrameContacts.set(e.id,e)}warmStart(t){var e,i,s;for(let r of t){let t=null===(e=r.colliderA.owner)||void 0===e?void 0:e.get(sh),n=null===(i=r.colliderB.owner)||void 0===i?void 0:i.get(sh);if(t&&n)for(let e of null!==(s=this.idToContactConstraint.get(r.id))&&void 0!==s?s:[])if(this.config.warmStart){let i=r.normal.scale(e.normalImpulse),s=r.tangent.scale(e.tangentImpulse),o=i.add(s);t.applyImpulse(e.point,o.negate()),n.applyImpulse(e.point,o)}else e.normalImpulse=0,e.tangentImpulse=0}}solvePosition(t){var e,i,s;for(let r=0;rthis._configDirty=!0),this._trackCollider=t=>this._processor.track(t),this._untrackCollider=t=>this._processor.untrack(t),this.query=t.query([iV,iW,sl]),this.query.entityAdded$.subscribe(t=>{let e=t.get(sl);e.$colliderAdded.subscribe(this._trackCollider),e.$colliderRemoved.subscribe(this._untrackCollider);let i=e.get();i&&this._processor.track(i)}),this.query.entityRemoved$.subscribe(t=>{let e=t.get(sl),i=e.get();e&&i&&this._processor.untrack(i)})}initialize(t,e){this._engine=e.engine}update(t){var e,i,s,r;if(!this._physics.config.enabled)return;let n=[];for(let t of this.query.entities){let i=t.get(sl),s=null==i?void 0:i.get();if(i&&(null===(e=i.owner)||void 0===e?void 0:e.active)&&s){if(i.update(),s instanceof i9){let t=s.getColliders();s.compositeStrategy||(s.compositeStrategy=this._physics.config.colliders.compositeStrategy),n=n.concat(t)}else n.push(s)}}this._processor.update(n);let o=this._processor.broadphase(n,t);this._currentFrameContacts.clear();let a=this._processor.narrowphase(o,null===(r=null===(s=null===(i=this._engine)||void 0===i?void 0:i.debug)||void 0===s?void 0:s.stats)||void 0===r?void 0:r.currFrame);for(let t of a=this.getSolver().solve(a)){if(t.isCanceled())continue;let e=t.id.indexOf("|");if(e>0){let i=t.id.substring(e+1);this._currentFrameContacts.set(i,t)}else this._currentFrameContacts.set(t.id,t)}for(let t of(this.runContactStartEnd(),this._lastFrameContacts.clear(),this._lastFrameContacts=new Map(this._currentFrameContacts),this.query.entities)){let e=t.get(sl);e&&e.processColliderRemoval()}}getSolver(){return this._configDirty&&(this._configDirty=!1,this._arcadeSolver=new rp(this._physics.config.arcade),this._realisticSolver=new r_(this._physics.config.realistic)),this._physics.config.solver===q.Realistic?this._realisticSolver:this._arcadeSolver}debug(t){this._processor.debug(t)}runContactStartEnd(){for(let[t,e]of this._currentFrameContacts)if(!this._lastFrameContacts.has(t)){let t=e.colliderA,i=e.colliderB,s=N.fromDirection(e.mtv),r=N.getOpposite(s);t.events.emit("collisionstart",new il(t,i,s,e)),t.events.emit("contactstart",new is(t,i,s,e)),i.events.emit("collisionstart",new il(i,t,r,e)),i.events.emit("contactstart",new is(i,t,r,e))}for(let[t,e]of this._lastFrameContacts)if(!this._currentFrameContacts.has(t)){let t=e.colliderA,i=e.colliderB,s=N.fromDirection(e.mtv),r=N.getOpposite(s);t.events.emit("collisionend",new ih(t,i,s,e)),t.events.emit("contactend",new ir(t,i,s,e)),i.events.emit("collisionend",new ih(i,t,r,e)),i.events.emit("contactend",new ir(i,t,r,e))}}}(S=to||(to={})).Forward="forward",S.Backward="backward",(A=ta||(ta={})).End="end",A.Loop="loop",A.PingPong="pingpong",A.Freeze="freeze";let rm={Frame:"frame",Loop:"loop",End:"end"};class rv extends et{constructor(t){var e,i,s;super(t),this.events=new tP,this.frames=[],this.strategy=ta.Loop,this.frameDuration=100,this._idempotencyToken=-1,this._firstTick=!0,this._currentFrame=0,this._timeLeftInFrame=0,this._pingPongDirection=1,this._done=!1,this._playing=!0,this._speed=1,this._reversed=!1,this.frames=t.frames,this.speed=null!==(e=t.speed)&&void 0!==e?e:this.speed,this.strategy=null!==(i=t.strategy)&&void 0!==i?i:this.strategy,this.frameDuration=t.totalDuration?t.totalDuration/this.frames.length:null!==(s=t.frameDuration)&&void 0!==s?s:this.frameDuration,t.reverse&&this.reverse(),this.goToFrame(0)}clone(){return new rv({frames:this.frames.map(t=>({...t})),frameDuration:this.frameDuration,speed:this.speed,reverse:this._reversed,strategy:this.strategy,...this.cloneGraphicOptions()})}get width(){let t=this.currentFrame;return t?Math.abs(t.graphic.width*this.scale.x):0}get height(){let t=this.currentFrame;return t?Math.abs(t.graphic.height*this.scale.y):0}static fromSpriteSheet(t,e,i,s=ta.Loop){let r=t.sprites.length-1,n=e.filter(t=>t<0||t>r);return n.length&&rv._LOGGER.warn(`Indices into SpriteSheet were provided that don't exist: ${n.join(",")} no frame will be shown`),new rv({frames:t.sprites.filter((t,i)=>e.indexOf(i)>-1).map(t=>({graphic:t,duration:i})),strategy:s})}static fromSpriteSheetCoordinates(t){let{spriteSheet:e,frameCoordinates:i,durationPerFrameMs:s,speed:r,strategy:n,reverse:o}=t,a=null!=s?s:100,l=[];for(let t of i){let{x:i,y:s,duration:r,options:n}=t,o=e.getSprite(i,s,n);o?l.push({graphic:o,duration:null!=r?r:a}):rv._LOGGER.warn(`Skipping frame! SpriteSheet does not have coordinate (${i}, ${s}), please check your SpriteSheet to confirm that sprite exists`)}return new rv({frames:l,strategy:n,speed:r,reverse:o})}get speed(){return this._speed}set speed(t){this._speed=tF(Math.abs(t),0,1/0)}get currentFrame(){return this._currentFrame>=0&&this._currentFrame=this.frames.length&&(this._done=!0,this._currentFrame=this.frames.length,this.events.emit("end",this));break;case ta.Freeze:(e=tF(t+1,0,this.frames.length-1))>=this.frames.length-1&&(this._done=!0,this.events.emit("end",this));break;case ta.PingPong:t+this._pingPongDirection>=this.frames.length&&(this._pingPongDirection=-1,this.events.emit("loop",this)),t+this._pingPongDirection<0&&(this._pingPongDirection=1,this.events.emit("loop",this)),e=t+this._pingPongDirection%this.frames.length}return e}tick(t,e=0){this._idempotencyToken!==e&&(this._idempotencyToken=e,this._playing&&(this._firstTick&&(this._firstTick=!1,this.events.emit("frame",{...this.currentFrame,frameIndex:this.currentFrameIndex})),this._timeLeftInFrame-=t*this._speed,this._timeLeftInFrame<=0&&this.goToFrame(this._nextFrame())))}_drawImage(t,e,i){this.currentFrame&&this.currentFrame.graphic.draw(t,e,i)}}rv._LOGGER=tW.getInstance();class ry extends et{constructor(t){super(t),this._logger=tW.getInstance(),this.members=[],this.members=t.members,this._updateDimensions()}clone(){return new ry({members:[...this.members],...this.cloneGraphicOptions()})}_updateDimensions(){let t=this.localBounds;return this.width=t.width,this.height=t.height,t}get localBounds(){let t=new tq;for(let e of this.members)if(e instanceof et)t=e.localBounds.combine(t);else{let{graphic:i,offset:s,useBounds:r}=e,n=void 0===r||r;i?n&&(t=i.localBounds.translate(s).combine(t)):this._logger.warnOnce(`Graphics group member has an null or undefined graphic, member definition: ${JSON.stringify(e)}.`)}return t}_isAnimationOrGroup(t){return t instanceof rv||t instanceof ry}tick(t,e){for(let i of this.members){let s;s=i instanceof et?i:i.graphic,this._isAnimationOrGroup(s)&&s.tick(t,e)}}reset(){for(let t of this.members){let e;e=t instanceof et?t:t.graphic,this._isAnimationOrGroup(e)&&e.reset()}}_preDraw(t,e,i){this._updateDimensions(),super._preDraw(t,e,i)}_drawImage(t,e,i){let s=tN.Zero;for(let r of this.members){let n;r instanceof et?n=r:(n=r.graphic,r.offset.clone(s)),n&&(t.save(),t.translate(e,i),n.draw(t,s.x,s.y),this.showDebug&&t.debug.drawRect(0,0,this.width,this.height),t.restore())}}}function rx(t){return class extends t{assign(t){for(let e in t)"function"!=typeof this[e]&&(this[e]=t[e])}constructor(...t){super(...t),1!==t.filter(function(t){return void 0!==t}).length||!t[0]||"object"!=typeof t[0]||t[0]instanceof Array||this.assign(t[0])}}}(E=tl||(tl={}))[E.Circle=0]="Circle",E[E.Rectangle=1]="Rectangle";class rw extends s_{constructor(t,e,i,s,r,n,o,a,l,h,d){super(),this.position=new tN(0,0),this.velocity=new tN(0,0),this.acceleration=new tN(0,0),this.particleRotationalVelocity=0,this.currentRotation=0,this.focus=null,this.focusAccel=0,this.opacity=1,this.beginColor=tH.White,this.endColor=tH.White,this.life=300,this.fadeFlag=!1,this._rRate=1,this._gRate=1,this._bRate=1,this._aRate=0,this._currentColor=tH.White,this.emitter=null,this.particleSize=5,this.particleSprite=null,this.sizeRate=0,this.elapsedMultiplier=0,this.visible=!0,this.isOffscreen=!1;let c=t;if(!c||t instanceof rC||(c=t.emitter,e=t.life,i=t.opacity,r=t.endColor,s=t.beginColor,n=t.position,o=t.velocity,a=t.acceleration,l=t.startSize,h=t.endSize,d=t.particleSprite),this.emitter=c,this.life=e||this.life,this.opacity=i||this.opacity,this.endColor=r||this.endColor.clone(),this.beginColor=s||this.beginColor.clone(),this._currentColor=this.beginColor.clone(),this.particleSprite=d,this.emitter.particleTransform===th.Global){let t=this.emitter.transform.globalPos;this.position=(n||this.position).add(t),this.velocity=(o||this.velocity).rotate(this.emitter.transform.globalRotation)}else this.velocity=o||this.velocity,this.position=n||this.position;this.acceleration=a||this.acceleration,this._rRate=(this.endColor.r-this.beginColor.r)/this.life,this._gRate=(this.endColor.g-this.beginColor.g)/this.life,this._bRate=(this.endColor.b-this.beginColor.b)/this.life,this._aRate=this.opacity/this.life,this.startSize=l||0,this.endSize=h||0,this.endSize>0&&this.startSize>0&&(this.sizeRate=(this.endSize-this.startSize)/this.life,this.particleSize=this.startSize),this.addComponent(this.transform=new iV),this.addComponent(this.graphics=new sm),this.transform.pos=this.position,this.transform.rotation=this.currentRotation,this.transform.scale=tZ(1,1),this.particleSprite?(this.graphics.opacity=this.opacity,this.graphics.use(this.particleSprite)):(this.graphics.localBounds=tq.fromDimension(this.particleSize,this.particleSize,tN.Half),this.graphics.onPostDraw=t=>{t.save(),this.graphics.opacity=this.opacity;let e=this._currentColor.clone();e.a=1,t.debug.drawPoint(tZ(0,0),{color:e,size:this.particleSize}),t.restore()})}kill(){this.emitter.removeParticle(this)}update(t,e){if(this.life=this.life-e,this.elapsedMultiplier=this.elapsedMultiplier+e,this.life<0&&this.kill(),this.fadeFlag&&(this.opacity=tF(this._aRate*this.life,1e-4,1)),this.startSize>0&&this.endSize>0&&(this.particleSize=tF(this.sizeRate*e+this.particleSize,Math.min(this.startSize,this.endSize),Math.max(this.startSize,this.endSize))),this._currentColor.r=tF(this._currentColor.r+this._rRate*e,0,255),this._currentColor.g=tF(this._currentColor.g+this._gRate*e,0,255),this._currentColor.b=tF(this._currentColor.b+this._bRate*e,0,255),this._currentColor.a=tF(this.opacity,1e-4,1),this.focus){let t=this.focus.sub(this.position).normalize().scale(this.focusAccel).scale(e/1e3);this.velocity=this.velocity.add(t)}else this.velocity=this.velocity.add(this.acceleration.scale(e/1e3));this.position=this.position.add(this.velocity.scale(e/1e3)),this.particleRotationalVelocity&&(this.currentRotation=(this.currentRotation+this.particleRotationalVelocity*e/1e3)%(2*Math.PI)),this.transform.pos=this.position,this.transform.rotation=this.currentRotation,this.transform.scale=tZ(1,1),this.graphics.opacity=this.opacity}}class rb extends rx(rw){constructor(t,e,i,s,r,n,o,a,l,h,d){super(t,e,i,s,r,n,o,a,l,h,d)}}(P=th||(th={})).Global="global",P.Local="local";class rC extends sj{get opacity(){return this.graphics.opacity}set opacity(t){this.graphics.opacity=t}get particleSprite(){return this._sprite}set particleSprite(t){t&&(this._sprite=t)}constructor(t){var e,i;super({width:null!==(e=t.width)&&void 0!==e?e:0,height:null!==(i=t.height)&&void 0!==i?i:0}),this._particlesToEmit=0,this.numParticles=0,this.isEmitting=!0,this.particles=[],this.deadParticles=[],this.minVel=0,this.maxVel=0,this.acceleration=new tN(0,0),this.minAngle=0,this.maxAngle=0,this.emitRate=1,this.particleLife=2e3,this.fadeFlag=!1,this.focus=null,this.focusAccel=null,this.startSize=null,this.endSize=null,this.minSize=5,this.maxSize=5,this.beginColor=tH.White,this.endColor=tH.White,this._sprite=null,this.emitterType=tl.Rectangle,this.radius=0,this.particleRotationalVelocity=0,this.randomRotation=!1,this.particleTransform=th.Global;let{x:s,y:r,pos:n,isEmitting:o,minVel:a,maxVel:l,acceleration:h,minAngle:d,maxAngle:c,emitRate:u,particleLife:p,opacity:g,fadeFlag:_,focus:f,focusAccel:m,startSize:v,endSize:y,minSize:x,maxSize:w,beginColor:b,endColor:C,particleSprite:T,emitterType:S,radius:A,particleRotationalVelocity:E,particleTransform:P,randomRotation:I,random:k}={...t};this.pos=null!=n?n:tZ(null!=s?s:0,null!=r?r:0),this.isEmitting=null!=o?o:this.isEmitting,this.minVel=null!=a?a:this.minVel,this.maxVel=null!=l?l:this.maxVel,this.acceleration=null!=h?h:this.acceleration,this.minAngle=null!=d?d:this.minAngle,this.maxAngle=null!=c?c:this.maxAngle,this.emitRate=null!=u?u:this.emitRate,this.particleLife=null!=p?p:this.particleLife,this.opacity=null!=g?g:this.opacity,this.fadeFlag=null!=_?_:this.fadeFlag,this.focus=null!=f?f:this.focus,this.focusAccel=null!=m?m:this.focusAccel,this.startSize=null!=v?v:this.startSize,this.endSize=null!=y?y:this.endSize,this.minSize=null!=x?x:this.minSize,this.maxSize=null!=w?w:this.maxSize,this.beginColor=null!=b?b:this.beginColor,this.endColor=null!=C?C:this.endColor,this.particleSprite=null!=T?T:this.particleSprite,this.emitterType=null!=S?S:this.emitterType,this.radius=null!=A?A:this.radius,this.particleRotationalVelocity=null!=E?E:this.particleRotationalVelocity,this.randomRotation=null!=I?I:this.randomRotation,this.particleTransform=null!=P?P:this.particleTransform,this.body.collisionType=G.PreventCollision,this.random=null!=k?k:new tI}removeParticle(t){this.deadParticles.push(t)}emitParticles(t){var e;for(let i=0;i1&&(this.emitParticles(Math.floor(this._particlesToEmit)),this._particlesToEmit=this._particlesToEmit-Math.floor(this._particlesToEmit)));for(let t=0;t{this._zHasChanged=!0},this._targetInterpolationTransform=new iU,this.query=this.world.query([iV,sm]),this.query.entityAdded$.subscribe(t=>{let e=t.get(iV);this._sortedTransforms.push(e),e.zIndexChanged$.subscribe(this._zIndexUpdate),this._zHasChanged=!0}),this.query.entityRemoved$.subscribe(t=>{let e=t.get(iV);e.zIndexChanged$.unsubscribe(this._zIndexUpdate);let i=this._sortedTransforms.indexOf(e);i>-1&&this._sortedTransforms.splice(i,1)})}initialize(t,e){this._camera=e.camera,this._engine=e.engine}preupdate(){this._graphicsContext=this._engine.graphicsContext,this._zHasChanged&&(this._sortedTransforms.sort((t,e)=>t.z-e.z),this._zHasChanged=!1)}update(t){let e;for(let i of(this._token++,sV.checkAndClearCache(),this._graphicsContext.save(),this._camera&&this._camera.draw(this._graphicsContext),this._sortedTransforms)){let s=i.owner;if(s.hasTag("ex.offscreen")||!(e=s.get(sm)).visible)continue;e.onPreTransformDraw&&e.onPreTransformDraw(this._graphicsContext,t),s.events.emit("pretransformdraw",new eY(this._graphicsContext,t,s)),i.coordPlane===j.Screen&&this._graphicsContext.restore(),this._graphicsContext.save(),i.coordPlane===j.Screen&&this._graphicsContext.translate(this._engine.screen.contentArea.left,this._engine.screen.contentArea.top),e.update(t,this._token);let r=s.get(sK);if(r){let t=tN.One.sub(r.parallaxFactor),e=this._camera.drawPos.scale(t);this._graphicsContext.translate(e.x,e.y)}this._applyTransform(s),e.material&&(this._graphicsContext.material=e.material),e.onPreDraw&&e.onPreDraw(this._graphicsContext,t),s.events.emit("predraw",new e$(this._graphicsContext,t,s));let n=s instanceof rb?s.opacity:1;this._graphicsContext.opacity*=e.opacity*n,this._drawGraphicsComponent(e,i),e.onPostDraw&&e.onPostDraw(this._graphicsContext,t),s.events.emit("postdraw",new eK(this._graphicsContext,t,s)),this._graphicsContext.restore(),i.coordPlane===j.Screen&&(this._graphicsContext.save(),this._camera&&this._camera.draw(this._graphicsContext)),e.onPostTransformDraw&&e.onPostTransformDraw(this._graphicsContext,t),s.events.emit("posttransformdraw",new eQ(this._graphicsContext,t,s))}this._graphicsContext.restore()}_drawGraphicsComponent(t,e){var i,s;if(t.visible){let r=t.flipHorizontal,n=t.flipVertical,o=t.current,a=null!==(i=t.currentOptions)&&void 0!==i?i:{};if(o){let i=t.anchor,l=t.offset,h=1,d=1;(null==a?void 0:a.anchor)&&(i=a.anchor),(null==a?void 0:a.offset)&&(l=a.offset);let c=e.globalScale;h*=o.scale.x*c.x,d*=o.scale.y*c.y;let u=-o.width*i.x+l.x*h,p=-o.height*i.y+l.y*d,g=o.flipHorizontal,_=o.flipVertical;if((r||n)&&(o.flipHorizontal=r?!g:g,o.flipVertical=n?!_:_),null==o||o.draw(this._graphicsContext,u,p),(r||n)&&(o.flipHorizontal=g,o.flipVertical=_),(null===(s=this._engine)||void 0===s?void 0:s.isDebug)&&this._engine.debug.graphics.showBounds){let t=tZ(u,p);if(o instanceof ry)for(let e of o.members){let i;let s=tN.Zero;e instanceof et?i=e:(i=e.graphic,s=e.offset),null==i||i.localBounds.translate(t.add(s)).draw(this._graphicsContext,this._engine.debug.graphics.boundsColor)}else null==o||o.localBounds.translate(t).draw(this._graphicsContext,this._engine.debug.graphics.boundsColor)}}}}_applyTransform(t){for(let e of t.getAncestors()){let t=null==e?void 0:e.get(iV),i=null==e?void 0:e.get(sh),s=t.get();if(i&&this._engine.fixedUpdateFps&&i.__oldTransformCaptured&&i.enableFixedUpdateInterpolate){let e=this._engine.currentFrameLagMs/(1e3/this._engine.fixedUpdateFps);s=function(t,e,i,s){if(t.parent!==e.parent){let i=t.clone(),s=t.globalPos.clone(),r=t.globalScale.clone(),n=t.globalRotation;i.parent=e.parent,i.globalPos=s,i.globalScale=r,i.globalRotation=n,t=i}let r=e.pos,n=e.scale,o=e.rotation;r=e.pos.scale(i).add(t.pos.scale(1-i)),n=e.scale.scale(i).add(t.scale.scale(1-i));let a=(1-i)*Math.cos(t.rotation)+i*Math.cos(e.rotation);o=Math.atan2((1-i)*Math.sin(t.rotation)+i*Math.sin(e.rotation),a);let l=null!=s?s:new iU;return l.setTransform(r,o,n),l}(i.oldTransform,t.get(),e,this._targetInterpolationTransform)}t&&(this._graphicsContext.z=t.z,this._graphicsContext.translate(s.pos.x,s.pos.y),this._graphicsContext.scale(s.scale.x,s.scale.y),this._graphicsContext.rotate(s.rotation))}}}class rS extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Draw,this.priority=ri.Lowest,this.query=this.world.query([iV])}initialize(t,e){this._graphicsContext=e.engine.graphicsContext,this._camera=e.camera,this._engine=e.engine,this._collisionSystem=t.systemManager.get(rf)}update(){var t;let e,i,s,r,n,o,a,l;if(!this._engine.isDebug)return;let h=this._engine.debug.filter,d=this._engine.debug.entity,c=this._engine.debug.transform,u=this._engine.debug.motion,p=this._engine.debug.collider,g=this._engine.debug.physics,_=this._engine.debug.graphics,f=this._engine.debug.body,m=this._engine.debug.camera;for(let g of this.query.entities){if(g.hasTag("offscreen")||g instanceof rb||h.useFilter&&(!(0===h.ids.length||h.ids.includes(g.id))||!(""===h.nameQuery||g.name.includes(h.nameQuery))))continue;let m=tN.Zero,v=tZ(0,16);if(e=g.id,i=g.name,s=g.get(iV),this._pushCameraTransform(s),this._graphicsContext.save(),s.coordPlane===j.Screen&&this._graphicsContext.translate(this._engine.screen.contentArea.left,this._engine.screen.contentArea.top),this._graphicsContext.z=c.debugZIndex,this._applyTransform(g),s&&((c.showAll||c.showPosition)&&this._graphicsContext.debug.drawPoint(tN.Zero,{size:4,color:c.positionColor}),(c.showAll||c.showPositionLabel)&&(this._graphicsContext.debug.drawText(`pos${s.pos.toString(2)}`,m),m=m.add(v)),(c.showAll||c.showZIndex)&&(this._graphicsContext.debug.drawText(`z(${s.z.toFixed(1)})`,m),m=m.add(v)),(d.showAll||d.showId)&&(this._graphicsContext.debug.drawText(`id(${e}) ${g.parent?"child of id("+(null===(t=g.parent)||void 0===t?void 0:t.id)+")":""}`,m),m=m.add(v)),(d.showAll||d.showName)&&(this._graphicsContext.debug.drawText(`name(${i})`,m),m=m.add(v)),(c.showAll||c.showRotation)&&(this._graphicsContext.drawLine(tN.Zero,tN.fromAngle(s.rotation).scale(50).add(tN.Zero),c.rotationColor,2),this._graphicsContext.debug.drawText(`rot deg(${tL(s.rotation).toFixed(2)})`,m),m=m.add(v)),(c.showAll||c.showScale)&&this._graphicsContext.drawLine(tN.Zero,s.scale.add(tN.Zero),c.scaleColor,2)),(o=g.get(sm))&&(_.showAll||_.showBounds)&&o.localBounds.draw(this._graphicsContext,_.boundsColor),(a=g.get(sY))&&(a.useTransform||this._graphicsContext.restore(),a.draw(this._graphicsContext,this._engine.debug),a.useTransform||(this._graphicsContext.save(),this._applyTransform(g))),(l=g.get(sh))&&((f.showAll||f.showCollisionGroup)&&(this._graphicsContext.debug.drawText(`collision group(${l.group.name})`,m),m=m.add(v)),(f.showAll||f.showCollisionType)&&(this._graphicsContext.debug.drawText(`collision type(${l.collisionType})`,m),m=m.add(v)),(f.showAll||f.showMass)&&(this._graphicsContext.debug.drawText(`mass(${l.mass})`,m),m=m.add(v)),(f.showAll||f.showMotion)&&(this._graphicsContext.debug.drawText(`motion(${l.sleepMotion})`,m),m=m.add(v)),(f.showAll||f.showSleeping)&&(this._graphicsContext.debug.drawText(`sleeping(${l.canSleep?l.sleeping:"cant sleep"})`,m),m=m.add(v))),this._graphicsContext.restore(),this._graphicsContext.save(),s.coordPlane===j.Screen&&this._graphicsContext.translate(this._engine.screen.contentArea.left,this._engine.screen.contentArea.top),this._graphicsContext.z=c.debugZIndex,(r=g.get(iW))&&((u.showAll||u.showVelocity)&&(this._graphicsContext.debug.drawText(`vel${r.vel.toString(2)}`,m.add(s.globalPos)),this._graphicsContext.drawLine(s.globalPos,s.globalPos.add(r.vel),u.velocityColor,2),m=m.add(v)),(u.showAll||u.showAcceleration)&&this._graphicsContext.drawLine(s.globalPos,s.globalPos.add(r.acc),u.accelerationColor,2)),n=g.get(sl)){let t=n.get();if((p.showAll||p.showGeometry)&&t&&t.debug(this._graphicsContext,p.geometryColor,{lineWidth:p.geometryLineWidth,pointSize:p.geometryPointSize}),p.showAll||p.showBounds){if(t instanceof i9){for(let e of t.getColliders()){let t=e.bounds,i=tZ(t.left,t.top);this._graphicsContext.debug.drawRect(i.x,i.y,t.width,t.height,{color:p.boundsColor}),(p.showAll||p.showOwner)&&this._graphicsContext.debug.drawText(`owner id(${e.owner.id})`,i)}n.bounds.draw(this._graphicsContext,p.boundsColor)}else if(t){let t=n.bounds,e=tZ(t.left,t.top);this._graphicsContext.debug.drawRect(e.x,e.y,t.width,t.height,{color:p.boundsColor}),(p.showAll||p.showOwner)&&this._graphicsContext.debug.drawText(`owner id(${n.owner.id})`,e)}}}this._graphicsContext.restore(),this._popCameraTransform(s)}if(this._graphicsContext.save(),this._camera.draw(this._graphicsContext),(g.showAll||g.showBroadphaseSpacePartitionDebug)&&this._collisionSystem.debug(this._graphicsContext),g.showAll||g.showCollisionContacts||g.showCollisionNormals)for(let[t,e]of this._engine.debug.stats.currFrame.physics.contacts){if(g.showAll||g.showCollisionContacts)for(let t of e.points)this._graphicsContext.debug.drawPoint(t,{size:g.contactSize,color:g.collisionContactColor});if(g.showAll||g.showCollisionNormals)for(let t of e.points)this._graphicsContext.debug.drawLine(t,e.normal.scale(30).add(t),{color:g.collisionNormalColor})}this._graphicsContext.restore(),m&&(this._graphicsContext.save(),this._camera.draw(this._graphicsContext),(m.showAll||m.showFocus)&&this._graphicsContext.drawCircle(this._camera.pos,4,m.focusColor),(m.showAll||m.showZoom)&&this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`,this._camera.pos),this._graphicsContext.restore()),this._graphicsContext.flush()}postupdate(t,e){this._engine.isDebug&&(this._graphicsContext.save(),this._camera&&this._camera.draw(this._graphicsContext),sn.flush(this._graphicsContext),this._graphicsContext.restore())}_applyTransform(t){for(let e of t.getAncestors()){let t=null==e?void 0:e.get(iV);t&&(this._graphicsContext.translate(t.pos.x,t.pos.y),this._graphicsContext.scale(t.scale.x,t.scale.y),this._graphicsContext.rotate(t.rotation))}}_pushCameraTransform(t){t.coordPlane===j.World&&(this._graphicsContext.save(),this._camera&&this._camera.draw(this._graphicsContext))}_popCameraTransform(t){t.coordPlane===j.World&&this._graphicsContext.restore()}}class rA extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Update,this.priority=ri.Higher,this.overrideUseColliderShape=!1,this.overrideUseGraphicsBounds=!1,this.lastFrameEntityToPointers=new Map,this.currentFrameEntityToPointers=new Map,this._sortedTransforms=[],this._sortedEntities=[],this._zHasChanged=!1,this._zIndexUpdate=()=>{this._zHasChanged=!0},this.query=this.world.query([iV,sx]),this.query.entityAdded$.subscribe(t=>{let e=t.get(iV);this._sortedTransforms.push(e),this._sortedEntities.push(e.owner),e.zIndexChanged$.subscribe(this._zIndexUpdate),this._zHasChanged=!0}),this.query.entityRemoved$.subscribe(t=>{let e=t.get(iV);e.zIndexChanged$.unsubscribe(this._zIndexUpdate);let i=this._sortedTransforms.indexOf(e);i>-1&&(this._sortedTransforms.splice(i,1),this._sortedEntities.splice(i,1))})}initialize(t,e){this._engine=e.engine,this._scene=e}preupdate(){this._receivers=[this._engine.input.pointers,this._scene.input.pointers],this._engineReceiver=this._engine.input.pointers,this._zHasChanged&&(this._sortedTransforms.sort((t,e)=>e.z-t.z),this._sortedEntities=this._sortedTransforms.map(t=>t.owner),this._zHasChanged=!1)}entityCurrentlyUnderPointer(t,e){return this.currentFrameEntityToPointers.has(t.id)&&this.currentFrameEntityToPointers.get(t.id).includes(e)}entityWasUnderPointer(t,e){return this.lastFrameEntityToPointers.has(t.id)&&this.lastFrameEntityToPointers.get(t.id).includes(e)}entered(t,e){return this.entityCurrentlyUnderPointer(t,e)&&!this.lastFrameEntityToPointers.has(t.id)}left(t,e){return!this.currentFrameEntityToPointers.has(t.id)&&this.entityWasUnderPointer(t,e)}addPointerToEntity(t,e){if(!this.currentFrameEntityToPointers.has(t.id)){this.currentFrameEntityToPointers.set(t.id,[e]);return}let i=this.currentFrameEntityToPointers.get(t.id);this.currentFrameEntityToPointers.set(t.id,i.concat(e))}update(){this._processPointerToEntity(this._sortedEntities),this._dispatchEvents(this._sortedEntities),this._receivers.forEach(t=>t.update()),this.lastFrameEntityToPointers.clear(),this.lastFrameEntityToPointers=new Map(this.currentFrameEntityToPointers),this.currentFrameEntityToPointers.clear(),this._receivers.forEach(t=>t.clear())}_processPointerToEntity(t){var e;let i,s,r,n;let o=this._engineReceiver;for(let a of t){if(i=a.get(iV),n=null!==(e=a.get(sx))&&void 0!==e?e:new sx,(s=a.get(sl))&&(n.useColliderShape||this.overrideUseColliderShape)){s.update();let t=s.get();if(t)for(let[e,s]of o.currentFramePointerCoords.entries())t.contains(i.coordPlane===j.World?s.worldPos:s.screenPos)&&this.addPointerToEntity(a,e)}if((r=a.get(sm))&&(n.useGraphicsBounds||this.overrideUseGraphicsBounds)){let t=r.localBounds.transform(i.get().matrix);for(let[e,s]of o.currentFramePointerCoords.entries())t.contains(i.coordPlane===j.World?s.worldPos:s.screenPos)&&this.addPointerToEntity(a,e)}}}_processDownAndEmit(t){let e=this._engineReceiver,i=new Map;for(let s of e.currentFrameDown)s.active&&t.active&&this.entityCurrentlyUnderPointer(t,s.pointerId)&&(t.events.emit("pointerdown",s),e.isDragStart(s.pointerId)&&t.events.emit("pointerdragstart",s)),i.set(s.pointerId,s);return i}_processUpAndEmit(t){let e=this._engineReceiver,i=new Map;for(let s of e.currentFrameUp)s.active&&t.active&&this.entityCurrentlyUnderPointer(t,s.pointerId)&&(t.events.emit("pointerup",s),e.isDragEnd(s.pointerId)&&t.events.emit("pointerdragend",s)),i.set(s.pointerId,s);return i}_processMoveAndEmit(t){let e=this._engineReceiver,i=new Map;for(let s of e.currentFrameMove)s.active&&t.active&&this.entityCurrentlyUnderPointer(t,s.pointerId)&&(t.events.emit("pointermove",s),e.isDragging(s.pointerId)&&t.events.emit("pointerdragmove",s)),i.set(s.pointerId,s);return i}_processEnterLeaveAndEmit(t,e){let i=this._engineReceiver;for(let s of e){if(s.active&&t.active&&this.entered(t,s.pointerId)){t.events.emit("pointerenter",s),i.isDragging(s.pointerId)&&t.events.emit("pointerdragenter",s);break}if(s.active&&t.active&&(this.left(t,s.pointerId)||this.entityCurrentlyUnderPointer(t,s.pointerId)&&"up"===s.type)){t.events.emit("pointerleave",s),i.isDragging(s.pointerId)&&t.events.emit("pointerdragleave",s);break}}}_processCancelAndEmit(t){for(let e of this._engineReceiver.currentFrameCancel)e.active&&t.active&&this.entityCurrentlyUnderPointer(t,e.pointerId)&&t.events.emit("pointercancel",e)}_processWheelAndEmit(t){for(let e of this._engineReceiver.currentFrameWheel)e.active&&t.active&&this.entityCurrentlyUnderPointer(t,0)&&t.events.emit("pointerwheel",e)}_dispatchEvents(t){let e,i;let s=new Set(this.lastFrameEntityToPointers.keys()),r=new Set(this.currentFrameEntityToPointers.keys());for(let n of t.filter(t=>s.has(t.id)||r.has(t.id))){i=this._processDownAndEmit(n),e=this._processUpAndEmit(n);let t=[...this._processMoveAndEmit(n).values(),...i.values(),...e.values()];this._processEnterLeaveAndEmit(n,t),this._processCancelAndEmit(n),this._processWheelAndEmit(n)}}}class rE extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Update,this.priority=ri.Higher,this._actions=[],this.query=this.world.query([sZ]),this.query.entityAdded$.subscribe(t=>this._actions.push(t.get(sZ))),this.query.entityRemoved$.subscribe(t=>{let e=t.get(sZ),i=this._actions.indexOf(e);i>-1&&this._actions.splice(i,1)})}update(t){for(let e of this._actions)e.update(t)}}class rP extends iZ{constructor(t){super(),this.elevation=0,this.columns=t.columns,this.rows=t.rows,this.tileWidth=t.tileWidth,this.tileHeight=t.tileHeight}}class rI extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Update,this.priority=ri.Lower,this.query=this.world.query([iV,rP])}update(){let t,e;for(let i of this.query.entities){t=i.get(iV);let s=Math.max((e=i.get(rP)).columns*e.tileWidth,e.rows*e.tileHeight)*e.elevation+t.pos.y;t.z=s}}}class rk extends rs{constructor(t){super(),this.world=t,this.systemType=tn.Draw,this.priority=ri.Higher,this.query=this.world.query([iV,sm])}initialize(t,e){this._camera=e.camera,this._screen=e.engine.screen}update(){let t,e,i;for(let s of(this._worldBounds=this._screen.getWorldBounds(),this.query.entities)){let r;if(e=s.get(sm),t=s.get(iV),i=s.get(sK)){let t=tN.One.sub(i.parallaxFactor);r=this._camera.pos.scale(t)}let n=this._isOffscreen(t,e,r);n&&!s.hasTag("ex.offscreen")&&(s.events.emit("exitviewport",new ip(s)),s.addTag("ex.offscreen")),!n&&s.hasTag("ex.offscreen")&&(s.events.emit("enterviewport",new ig(s)),s.removeTag("ex.offscreen"))}}_isOffscreen(t,e,i){if(t.coordPlane!==j.World)return!1;{let s=e.localBounds;i&&(s=s.translate(i));let r=s.transform(t.get().matrix);return!this._worldBounds.overlaps(r)}}}class rD{get config(){var t;return(t=this._config)&&void 0===t.__isProxy?new Proxy(t,t7([],t=>{this.$configUpdate.notifyAll(t)},t)):t}set config(t){this._config=t,this.$configUpdate.notifyAll(t)}get collisionProcessor(){if(this._configDirty){this._configDirty=!1;let t=this._collisionProcessor.getColliders();for(let e of(this._collisionProcessor=new iQ(this._config),t))this._collisionProcessor.track(e)}return this._collisionProcessor}constructor(t){this.$configUpdate=new iH,this._configDirty=!1,this.config=t,this.$configUpdate.subscribe(t=>{this._configDirty=!0,sh.updateDefaultPhysicsConfig(t.bodies)}),this._collisionProcessor=new iQ(this.config)}rayCast(t,e){return this.collisionProcessor.rayCast(t,e)}}class rR{constructor(){this.events=new tP,this.enabled=!1,this.supported=!!navigator.getGamepads,this._gamePadTimeStamps=[0,0,0,0],this._oldPads=[],this._pads=[],this._initSuccess=!1,this._navigator=navigator,this._minimumConfiguration=null,this._enabled=!0}init(){this.supported&&!this._initSuccess&&(this._oldPads=this._clonePads(this._navigator.getGamepads()),this._oldPads.length&&this._oldPads[0]&&(this._initSuccess=!0))}toggleEnabled(t){this._enabled=t}setMinimumGamepadConfiguration(t){this._enableAndUpdate(),this._minimumConfiguration=t}_enableAndUpdate(){this.enabled||(this.enabled=!0,this.update())}_isGamepadValid(t){if(!this._minimumConfiguration)return!0;if(!t)return!1;let e=t.axes.filter(t=>!0).length,i=t.buttons.filter(t=>!0).length;return e>=this._minimumConfiguration.axis&&i>=this._minimumConfiguration.buttons&&t.connected}emit(t,e){this.events.emit(t,e)}on(t,e){return this._enableAndUpdate(),this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this._enableAndUpdate(),this.events.off(t,e)}update(){if(!this.enabled||!this.supported||!this._enabled)return;this.init();let t=this._navigator.getGamepads();for(let e=0;e=this._pads.length)for(let e=this._pads.length-1;et.connected).length}_clonePads(t){let e=[];for(let i=0,s=t.length;i=e}isButtonHeld(t,e=1){return this._buttons[t]>=e}wasButtonPressed(t,e=1){return this._buttonsDown[t]>=e}wasButtonReleased(t){return!!this._buttonsUp[t]}getButton(t){return this._buttons[t]}getAxes(t){let e=this._axes[t];return Math.abs(e){};window.top.addEventListener("blur",t),window.top.removeEventListener("blur",t)}catch(t){return!0}return!1}(D=tu||(tu={})).Num0="Numpad0",D.Num1="Numpad1",D.Num2="Numpad2",D.Num3="Numpad3",D.Num4="Numpad4",D.Num5="Numpad5",D.Num6="Numpad6",D.Num7="Numpad7",D.Num8="Numpad8",D.Num9="Numpad9",D.NumAdd="NumpadAdd",D.NumSubtract="NumpadSubtract",D.NumMultiply="NumpadMultiply",D.NumDivide="NumpadDivide",D.NumDecimal="NumpadDecimal",D.Numpad0="Numpad0",D.Numpad1="Numpad1",D.Numpad2="Numpad2",D.Numpad3="Numpad3",D.Numpad4="Numpad4",D.Numpad5="Numpad5",D.Numpad6="Numpad6",D.Numpad7="Numpad7",D.Numpad8="Numpad8",D.Numpad9="Numpad9",D.NumpadAdd="NumpadAdd",D.NumpadSubtract="NumpadSubtract",D.NumpadMultiply="NumpadMultiply",D.NumpadDivide="NumpadDivide",D.NumpadDecimal="NumpadDecimal",D.NumLock="NumLock",D.ShiftLeft="ShiftLeft",D.ShiftRight="ShiftRight",D.AltLeft="AltLeft",D.AltRight="AltRight",D.ControlLeft="ControlLeft",D.ControlRight="ControlRight",D.MetaLeft="MetaLeft",D.MetaRight="MetaRight",D.Key0="Digit0",D.Key1="Digit1",D.Key2="Digit2",D.Key3="Digit3",D.Key4="Digit4",D.Key5="Digit5",D.Key6="Digit6",D.Key7="Digit7",D.Key8="Digit8",D.Key9="Digit9",D.Digit0="Digit0",D.Digit1="Digit1",D.Digit2="Digit2",D.Digit3="Digit3",D.Digit4="Digit4",D.Digit5="Digit5",D.Digit6="Digit6",D.Digit7="Digit7",D.Digit8="Digit8",D.Digit9="Digit9",D.F1="F1",D.F2="F2",D.F3="F3",D.F4="F4",D.F5="F5",D.F6="F6",D.F7="F7",D.F8="F8",D.F9="F9",D.F10="F10",D.F11="F11",D.F12="F12",D.A="KeyA",D.B="KeyB",D.C="KeyC",D.D="KeyD",D.E="KeyE",D.F="KeyF",D.G="KeyG",D.H="KeyH",D.I="KeyI",D.J="KeyJ",D.K="KeyK",D.L="KeyL",D.M="KeyM",D.N="KeyN",D.O="KeyO",D.P="KeyP",D.Q="KeyQ",D.R="KeyR",D.S="KeyS",D.T="KeyT",D.U="KeyU",D.V="KeyV",D.W="KeyW",D.X="KeyX",D.Y="KeyY",D.Z="KeyZ",D.KeyA="KeyA",D.KeyB="KeyB",D.KeyC="KeyC",D.KeyD="KeyD",D.KeyE="KeyE",D.KeyF="KeyF",D.KeyG="KeyG",D.KeyH="KeyH",D.KeyI="KeyI",D.KeyJ="KeyJ",D.KeyK="KeyK",D.KeyL="KeyL",D.KeyM="KeyM",D.KeyN="KeyN",D.KeyO="KeyO",D.KeyP="KeyP",D.KeyQ="KeyQ",D.KeyR="KeyR",D.KeyS="KeyS",D.KeyT="KeyT",D.KeyU="KeyU",D.KeyV="KeyV",D.KeyW="KeyW",D.KeyX="KeyX",D.KeyY="KeyY",D.KeyZ="KeyZ",D.Semicolon="Semicolon",D.Quote="Quote",D.Comma="Comma",D.Minus="Minus",D.Period="Period",D.Slash="Slash",D.Equal="Equal",D.BracketLeft="BracketLeft",D.Backslash="Backslash",D.BracketRight="BracketRight",D.Backquote="Backquote",D.Up="ArrowUp",D.Down="ArrowDown",D.Left="ArrowLeft",D.Right="ArrowRight",D.ArrowUp="ArrowUp",D.ArrowDown="ArrowDown",D.ArrowLeft="ArrowLeft",D.ArrowRight="ArrowRight",D.Space="Space",D.Backspace="Backspace",D.Delete="Delete",D.Esc="Escape",D.Escape="Escape",D.Enter="Enter",D.NumpadEnter="NumpadEnter",D.ContextMenu="ContextMenu";class rM extends eV{constructor(t,e,i){super(),this.key=t,this.value=e,this.originalEvent=i}}class rz{constructor(){this.events=new tP,this._enabled=!0,this._keys=[],this._keysUp=[],this._keysDown=[],this._releaseAllKeys=t=>{for(let e of this._keys){let i=new rM(e,t.key,t);this.events.emit("up",i),this.events.emit("release",i)}this._keysUp=Array.from(new Set(this._keys.concat(this._keysUp))),this._keys.length=0},this._handleKeyDown=t=>{if(!this._enabled)return;!t.metaKey&&(this._keys.includes(tu.MetaLeft)||this._keys.includes(tu.MetaRight))&&this._releaseAllKeys(t);let e=t.code;if(-1===this._keys.indexOf(e)){this._keys.push(e),this._keysDown.push(e);let i=new rM(e,t.key,t);this.events.emit("down",i),this.events.emit("press",i)}},this._handleKeyUp=t=>{if(!this._enabled)return;let e=t.code,i=this._keys.indexOf(e);this._keys.splice(i,1),this._keysUp.push(e);let s=new rM(e,t.key,t);this.events.emit("up",s),this.events.emit("release",s),"Meta"===t.key&&this._releaseAllKeys(t)}}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}init(t){let{global:e}=t,{grabWindowFocus:i}=t;e||(rL()?(e=window,i&&window.focus(),tW.getInstance().warn("Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus")):e=window.top),e.addEventListener("blur",()=>{this._keys.length=0}),e.addEventListener("keyup",this._handleKeyUp),e.addEventListener("keydown",this._handleKeyDown)}toggleEnabled(t){this._enabled=t}update(){this._keysDown.length=0,this._keysUp.length=0;for(let t=0;t-1}isHeld(t){return this._keys.indexOf(t)>-1}wasReleased(t){return this._keysUp.indexOf(t)>-1}triggerEvent(t,e,i){"down"===t&&this._handleKeyDown(new KeyboardEvent("keydown",{code:e,key:null!=i?i:null})),"up"===t&&this._handleKeyUp(new KeyboardEvent("keyup",{code:e,key:null!=i?i:null}))}}class rO{static fromPagePosition(t,e,i){let s,r;3==arguments.length?(s=new tN(t,e),r=i):((s=t).x,s.y,r=e);let n=r.screen.pageToScreenCoordinates(s);return new rO(r.screen.screenToWorldCoordinates(n),s,n)}constructor(t,e,i){this.worldPos=t,this.pagePos=e,this.screenPos=i}}class rU{cancel(){this.active=!1}get pagePos(){return this.coordinates.pagePos}get screenPos(){return this.coordinates.screenPos}get worldPos(){return this.coordinates.worldPos}constructor(t,e,i,s,r,n){this.type=t,this.pointerId=e,this.button=i,this.pointerType=s,this.coordinates=r,this.nativeEvent=n,this.active=!0}}class rN{cancel(){this.active=!1}constructor(t,e,i,s,r,n,o,a,l,h,d,c){this.x=t,this.y=e,this.pageX=i,this.pageY=s,this.screenX=r,this.screenY=n,this.index=o,this.deltaX=a,this.deltaY=l,this.deltaZ=h,this.deltaMode=d,this.ev=c,this.active=!0}}class rZ{constructor(){this.events=new tP,this.lastPagePos=tN.Zero,this.lastScreenPos=tN.Zero,this.lastWorldPos=tN.Zero,this._onPointerMove=t=>{this.lastPagePos=new tN(t.pagePos.x,t.pagePos.y),this.lastScreenPos=new tN(t.screenPos.x,t.screenPos.y),this.lastWorldPos=new tN(t.worldPos.x,t.worldPos.y)},this._onPointerDown=t=>{this.lastPagePos=new tN(t.pagePos.x,t.pagePos.y),this.lastScreenPos=new tN(t.screenPos.x,t.screenPos.y),this.lastWorldPos=new tN(t.worldPos.x,t.worldPos.y)},this.on("move",this._onPointerMove),this.on("down",this._onPointerDown)}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}}(R=tp||(tp={})).Pixel="Pixel",R.Line="Line",R.Page="Page",(F=tg||(tg={}))[F.NoButton=-1]="NoButton",F[F.Left=0]="Left",F[F.Middle=1]="Middle",F[F.Right=2]="Right",F[F.Unknown=3]="Unknown",(B=t_||(t_={})).Left="Left",B.Middle="Middle",B.Right="Right",B.Unknown="Unknown",B.NoButton="NoButton",(L=tf||(tf={})).Touch="Touch",L.Mouse="Mouse",L.Pen="Pen",L.Unknown="Unknown";class rH{constructor(t,e){this.target=t,this.engine=e,this.events=new tP,this.primary=new rZ,this._activeNativePointerIdsToNormalized=new Map,this.lastFramePointerCoords=new Map,this.currentFramePointerCoords=new Map,this.currentFramePointerDown=new Map,this.lastFramePointerDown=new Map,this.currentFrameDown=[],this.currentFrameUp=[],this.currentFrameMove=[],this.currentFrameCancel=[],this.currentFrameWheel=[],this._enabled=!0,this._pointers=[this.primary],this._boundHandle=this._handle.bind(this),this._boundWheel=this._handleWheel.bind(this)}toggleEnabled(t){this._enabled=t}recreate(t,e){let i=new rH(t,e);return i.primary=this.primary,i._pointers=this._pointers,i}at(t){if(t>=this._pointers.length)for(let e=this._pointers.length-1;e{window.focus()};window.PointerEvent?this.target.addEventListener("pointerdown",t):(this.target.addEventListener("touchstart",t),this.target.addEventListener("mousedown",t))}}detach(){window.PointerEvent?(this.target.removeEventListener("pointerdown",this._boundHandle),this.target.removeEventListener("pointerup",this._boundHandle),this.target.removeEventListener("pointermove",this._boundHandle),this.target.removeEventListener("pointercancel",this._boundHandle)):(this.target.removeEventListener("touchstart",this._boundHandle),this.target.removeEventListener("touchend",this._boundHandle),this.target.removeEventListener("touchmove",this._boundHandle),this.target.removeEventListener("touchcancel",this._boundHandle),this.target.removeEventListener("mousedown",this._boundHandle),this.target.removeEventListener("mouseup",this._boundHandle),this.target.removeEventListener("mousemove",this._boundHandle)),"onwheel"in document.createElement("div")?this.target.removeEventListener("wheel",this._boundWheel):void 0!==document.onmousewheel?this.target.addEventListener("mousewheel",this._boundWheel):this.target.addEventListener("MozMousePixelScroll",this._boundWheel)}_normalizePointerId(t){this._activeNativePointerIdsToNormalized.set(t,-1);let e=Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((t,e)=>t-e).findIndex(e=>e===t);return this._activeNativePointerIdsToNormalized.set(t,e),e}_handle(t){let e,i;if(!this._enabled)return;t.preventDefault();let s=new Map;if(globalThis.TouchEvent&&t instanceof globalThis.TouchEvent){e=t_.Unknown,i=tf.Touch;for(let e=0;et instanceof sj)}get entities(){return this.world.entityManager.entities}get triggers(){return this.world.entityManager.entities.filter(t=>t instanceof re)}get tileMaps(){return this.world.entityManager.entities.filter(t=>t instanceof sJ)}get timers(){return this._timers}constructor(){this._logger=tW.getInstance(),this.events=new tP,this.camera=new s7,this.world=new rd(this),this.physics=new rD(i4),this._isInitialized=!1,this._timers=[],this._cancelQueue=[],this.world.add(rE),this.world.add(new ru(this.world,this.physics)),this.world.add(new rf(this.world,this.physics)),this.world.add(rA),this.world.add(rI),this.world.add(rk),this.world.add(rT),this.world.add(rS)}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}onPreLoad(t){}onTransition(t){}onInitialize(t){}onActivate(t){}onDeactivate(t){}onPreUpdate(t,e){}onPostUpdate(t,e){}onPreDraw(t,e){}onPostDraw(t,e){}_initializeChildren(){for(let t of this.entities)t._initialize(this.engine)}get isInitialized(){return this._isInitialized}async _initialize(t){var e;if(!this.isInitialized){try{this.engine=t,this.physics.config=this.engine.physics,this.input=new rV({pointerTarget:t.pointerScope===O.Canvas?t.canvas:document,grabWindowFocus:t.grabWindowFocus,engine:t}),this.camera._initialize(t),this.world.systemManager.initialize(),await this.onInitialize(t),this._initializeChildren(),this._logger.debug("Scene.onInitialize",this,t),this.events.emit("initialize",new id(t,this))}catch(i){throw this._logger.error(`Error during scene initialization for scene ${null===(e=t.director)||void 0===e?void 0:e.getSceneName(this)}!`),i}this._isInitialized=!0}}async _activate(t){var e,i;try{this._logger.debug("Scene.onActivate",this),this.input.toggleEnabled(!0),await this.onActivate(t)}catch(t){throw this._logger.error(`Error during scene activation for scene ${null===(i=null===(e=this.engine)||void 0===e?void 0:e.director)||void 0===i?void 0:i.getSceneName(this)}!`),t}}async _deactivate(t){this._logger.debug("Scene.onDeactivate",this),this.input.toggleEnabled(!1),await this.onDeactivate(t)}_preupdate(t,e){this.emit("preupdate",new e1(t,e,this)),this.onPreUpdate(t,e)}_postupdate(t,e){this.emit("postupdate",new e2(t,e,this)),this.onPostUpdate(t,e)}_predraw(t,e){this.emit("predraw",new e$(t,e,this)),this.onPreDraw(t,e)}_postdraw(t,e){this.emit("postdraw",new eK(t,e,this)),this.onPostDraw(t,e)}update(t,e){var i;let s,r;if(!this.isInitialized){this._logger.warnOnce(`Scene update called before initialize for scene ${null===(i=t.director)||void 0===i?void 0:i.getSceneName(this)}!`);return}for(this._preupdate(t,e),s=0,r=this._cancelQueue.length;s-1}add(t){if(this.emit("entityadded",{target:t}),this.world.add(t),t.scene=this,t instanceof s$){tY(this._timers,t)||this.addTimer(t);return}}transfer(t){let e;t instanceof s_&&t.scene&&t.scene!==this&&(e=t.scene,t.scene.world.remove(t,!1)),t instanceof s$&&t.scene&&(e=t.scene,t.scene.removeTimer(t)),null==e||e.emit("entityremoved",{target:t}),this.add(t)}remove(t){t instanceof s_&&(this.emit("entityremoved",{target:t}),t.active&&t.kill(),this.world.remove(t)),t instanceof s$&&this.removeTimer(t)}clear(t=!0){for(let e=this.entities.length-1;e>=0;e--)this.world.remove(this.entities[e],t);for(let t=this.timers.length-1;t>=0;t--)this.removeTimer(this.timers[t])}addTimer(t){return this._timers.push(t),t.scene=this,t}removeTimer(t){let e=this._timers.indexOf(t);return -1!==e&&this._timers.splice(e,1),t}cancelTimer(t){return this._cancelQueue.push(t),t}isTimerActive(t){return this._timers.indexOf(t)>-1&&!t.complete}isCurrentScene(){return!!this.engine&&this.engine.currentScene===this}_collectActorStats(t){for(let e of this.actors.filter(t=>t instanceof sX))t.stats.currFrame.actors.ui++;for(let e of this.actors)for(let i of(t.stats.currFrame.actors.alive++,e.children))sq(i)?t.stats.currFrame.actors.ui++:t.stats.currFrame.actors.alive++}}(M=tm||(tm={})).Protanope="Protanope",M.Deuteranope="Deuteranope",M.Tritanope="Tritanope";class rX{constructor(t,e){this._shader=new eu({gl:t,vertexSource:`#version 300 es in vec2 a_position; in vec2 a_texcoord; out vec2 v_texcoord; @@ -215,9 +215,9 @@ mask: ${(this.mask>>>0).toString(2).padStart(32,"0")} gl_Position = vec4(a_position, 0.0, 1.0); // Pass the texcoord to the fragment shader. v_texcoord = a_texcoord; - }`,fragmentSource:e}),this._shader.compile(),this._buffer=new ep({gl:t,type:"static",data:new Float32Array([-1,-1,0,0,-1,1,0,1,1,-1,1,0,1,-1,1,0,-1,1,0,1,1,1,1,1])}),this._layout=new eg({gl:t,shader:this._shader,vertexBuffer:this._buffer,attributes:[["a_position",2],["a_texcoord",2]]}),this._buffer.upload()}getShader(){return this._shader}getLayout(){return this._layout}}class r${constructor(t,e=!1){this._colorBlindnessMode=t,this._simulate=!1,this._simulate=e}initialize(t){this._shader=new rX(t,"#version 300 es\r\nprecision mediump float;\r\n// our texture\r\nuniform sampler2D u_image;\r\n// the texCoords passed in from the vertex shader.\r\nin vec2 v_texcoord;\r\n\r\n// color blind type\r\nuniform int u_type;\r\n\r\n// simulation?\r\nuniform bool u_simulate;\r\n\r\nout vec4 fragColor;\r\n\r\nvoid main() {\r\n vec4 o = texture(u_image, v_texcoord);\r\n // RGB to LMS matrix conversion\r\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\r\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\r\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\r\n // Simulate color blindness\r\n float l;\r\n float m;\r\n float s;\r\n //MODE CODE//\r\n if (u_type == 0) {\r\n // Protanope\r\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\r\n m = 0.0 * L + 1.0 * M + 0.0 * S;\r\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\r\n } else if (u_type == 1) {\r\n // Deuteranope\r\n l = 1.0 * L + 0.0 * M + 0.0 * S;\r\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\r\n s = 0.0 * L + 0.0 * M + 1.0 * S;\r\n } else if (u_type == 2) {\r\n // Tritanope\r\n l = 1.0 * L + 0.0 * M + 0.0 * S;\r\n m = 0.0 * L + 1.0 * M + 0.0 * S;\r\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\r\n }\r\n\r\n // LMS to RGB matrix conversion\r\n vec4 error; // simulate the colors\r\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\r\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\r\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\r\n error.a = 1.0;\r\n vec4 diff = o - error;\r\n vec4 correction; // correct the colors\r\n correction.r = 0.0;\r\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\r\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\r\n correction = o + correction;\r\n correction.a = o.a;\r\n //SIMULATE//\r\n\r\n // sim \r\n if (u_simulate) {\r\n fragColor = error.rgba;\r\n } else {\r\n fragColor = correction.rgba;\r\n }\r\n}"),this.simulate=this._simulate,this.colorBlindnessMode=this._colorBlindnessMode}getShader(){return this._shader.getShader()}getLayout(){return this._shader.getLayout()}set colorBlindnessMode(t){if(this._colorBlindnessMode=t,this._shader){let t=this._shader.getShader();t.use(),this._colorBlindnessMode===tm.Protanope?t.setUniformInt("u_type",0):this._colorBlindnessMode===tm.Deuteranope?t.setUniformInt("u_type",1):this._colorBlindnessMode===tm.Tritanope&&t.setUniformInt("u_type",2)}}get colorBlindnessMode(){return this._colorBlindnessMode}set simulate(t){if(this._simulate=t,this._shader){let e=this._shader.getShader();e.use(),e.setUniformBoolean("u_simulate",t)}}get simulate(){return this._simulate}}class rK{constructor(t){this._engine=t,this._colorBlindPostProcessor=new r$(tm.Protanope)}correct(t){this._engine.graphicsContext instanceof ek&&(this.clear(),this._colorBlindPostProcessor.colorBlindnessMode=t,this._colorBlindPostProcessor.simulate=!1,this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor))}simulate(t){this._engine.graphicsContext instanceof ek&&(this.clear(),this._colorBlindPostProcessor.colorBlindnessMode=t,this._colorBlindPostProcessor.simulate=!0,this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor))}clear(){this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor)}}class rY{constructor(t){this.stats={currFrame:new rQ,prevFrame:new rQ},this.filter={useFilter:!1,nameQuery:"",ids:[]},this.entity={showAll:!1,showId:!1,showName:!1},this.transform={showAll:!1,debugZIndex:1e7,showPosition:!1,showPositionLabel:!1,positionColor:tH.Yellow,showZIndex:!1,showScale:!1,scaleColor:tH.Green,showRotation:!1,rotationColor:tH.Blue},this.graphics={showAll:!1,showBounds:!1,boundsColor:tH.Yellow},this.collider={showAll:!1,showBounds:!1,boundsColor:tH.Blue,showOwner:!1,showGeometry:!0,geometryColor:tH.Green,geometryLineWidth:1,geometryPointSize:.5},this.physics={showAll:!1,showBroadphaseSpacePartitionDebug:!1,showCollisionNormals:!1,collisionNormalColor:tH.Cyan,showCollisionContacts:!0,contactSize:2,collisionContactColor:tH.Red},this.motion={showAll:!1,showVelocity:!1,velocityColor:tH.Yellow,showAcceleration:!1,accelerationColor:tH.Red},this.body={showAll:!1,showCollisionGroup:!1,showCollisionType:!1,showSleeping:!1,showMotion:!1,showMass:!1},this.camera={showAll:!1,showFocus:!1,focusColor:tH.Red,showZoom:!1},this.tilemap={showAll:!1,showGrid:!1,gridColor:tH.Red,gridWidth:.5,showSolidBounds:!1,solidBoundsColor:tH.fromHex("#8080807F"),showColliderGeometry:!0},this.isometric={showAll:!1,showPosition:!1,positionColor:tH.Yellow,positionSize:1,showGrid:!1,gridColor:tH.Red,gridWidth:1,showColliderGeometry:!0},this._engine=t,this.colorBlindMode=new rK(this._engine)}useTestClock(){let t=this._engine.clock,e=t.isRunning();t.stop();let i=t.toTestClock();return e&&i.start(),this._engine.clock=i,i}useStandardClock(){let t=this._engine.clock,e=t.isRunning();t.stop();let i=t.toStandardClock();return e&&i.start(),this._engine.clock=i,i}}class rQ{constructor(){this._id=0,this._delta=0,this._fps=0,this._actorStats={alive:0,killed:0,ui:0,get remaining(){return this.alive-this.killed},get total(){return this.remaining+this.ui}},this._durationStats={update:0,draw:0,get total(){return this.update+this.draw}},this._physicsStats=new rJ,this._graphicsStats={drawCalls:0,drawnImages:0}}reset(t){t?(this.id=t.id,this.delta=t.delta,this.fps=t.fps,this.actors.alive=t.actors.alive,this.actors.killed=t.actors.killed,this.actors.ui=t.actors.ui,this.duration.update=t.duration.update,this.duration.draw=t.duration.draw,this._physicsStats.reset(t.physics),this.graphics.drawCalls=t.graphics.drawCalls,this.graphics.drawnImages=t.graphics.drawnImages):(this.id=this.delta=this.fps=0,this.actors.alive=this.actors.killed=this.actors.ui=0,this.duration.update=this.duration.draw=0,this._physicsStats.reset(),this.graphics.drawnImages=this.graphics.drawCalls=0)}clone(){let t=new rQ;return t.reset(this),t}get id(){return this._id}set id(t){this._id=t}get delta(){return this._delta}set delta(t){this._delta=t}get fps(){return this._fps}set fps(t){this._fps=t}get actors(){return this._actorStats}get duration(){return this._durationStats}get physics(){return this._physicsStats}get graphics(){return this._graphicsStats}}class rJ{constructor(){this._pairs=0,this._collisions=0,this._contacts=new Map,this._fastBodies=0,this._fastBodyCollisions=0,this._broadphase=0,this._narrowphase=0}reset(t){t?(this.pairs=t.pairs,this.collisions=t.collisions,this.contacts=t.contacts,this.fastBodies=t.fastBodies,this.fastBodyCollisions=t.fastBodyCollisions,this.broadphase=t.broadphase,this.narrowphase=t.narrowphase):(this.pairs=this.collisions=this.fastBodies=0,this.fastBodyCollisions=this.broadphase=this.narrowphase=0,this.contacts.clear())}clone(){let t=new rJ;return t.reset(this),t}get pairs(){return this._pairs}set pairs(t){this._pairs=t}get collisions(){return this._collisions}set collisions(t){this._collisions=t}get contacts(){return this._contacts}set contacts(t){this._contacts=t}get fastBodies(){return this._fastBodies}set fastBodies(t){this._fastBodies=t}get fastBodyCollisions(){return this._fastBodyCollisions}set fastBodyCollisions(t){this._fastBodyCollisions=t}get broadphase(){return this._broadphase}set broadphase(t){this._broadphase=t}get narrowphase(){return this._narrowphase}set narrowphase(t){this._narrowphase=t}}class r0{on(t,e){this._nativeHandlers[t]&&this.off(t,this._nativeHandlers[t]),this._nativeHandlers[t]=this._decorate(e),this.nativeComponent.addEventListener(t,this._nativeHandlers[t])}off(t,e){e||(e=this._nativeHandlers[t]),this.nativeComponent.removeEventListener(t,e),this._nativeHandlers[t]=null}_decorate(t){return e=>{this._paused||t(e)}}pause(){this._paused=!0}resume(){this._paused=!1}clear(){for(let t in this._nativeHandlers)this.off(t)}constructor(t){this.nativeComponent=t,this._paused=!1,this._nativeHandlers={}}}class r1{constructor(t,e){this._windowGlobal=t,this._documentGlobal=e,this._windowComponent=new r0(this._windowGlobal),this._documentComponent=new r0(this._documentGlobal)}get window(){return this._windowComponent}get document(){return this._documentComponent}pause(){this.window.pause(),this.document.pause()}resume(){this.window.resume(),this.document.resume()}clear(){this.window.clear(),this.document.clear()}}let r2={pixelArtSampler:!1,nativeContextAntialiasing:!1,multiSampleAntialiasing:!0,filtering:H.Blended,canvasImageRendering:"auto"},r5={pixelArtSampler:!0,nativeContextAntialiasing:!1,multiSampleAntialiasing:!0,filtering:H.Blended,canvasImageRendering:"auto"};class r4{constructor(t){var e;this._samplePeriod=100,this._currentFrameTime=0,this._frames=0,this._previousSampleTime=0,this._beginFrameTime=0,this._fps=t.initialFps,this._samplePeriod=null!==(e=t.samplePeriod)&&void 0!==e?e:this._samplePeriod,this._currentFrameTime=1e3/t.initialFps,this._nowFn=t.nowFn,this._previousSampleTime=this._nowFn()}start(){this._beginFrameTime=this._nowFn()}end(){this._frames++;let t=this._nowFn();this._currentFrameTime=t-this._beginFrameTime,t>=this._previousSampleTime+this._samplePeriod&&(this._fps=1e3*this._frames/(t-this._previousSampleTime),this._previousSampleTime=t,this._frames=0)}get fps(){return this._fps}get instant(){return 1e3/this._currentFrameTime}}class r3{constructor(t){var e,i,s;this._onFatalException=()=>{},this._maxFps=1/0,this._lastTime=0,this._elapsed=1,this._scheduledCbs=[],this._totalElapsed=0,this._options=t,this.tick=t.tick,this._lastTime=null!==(e=this.now())&&void 0!==e?e:0,this._maxFps=null!==(i=t.maxFps)&&void 0!==i?i:this._maxFps,this._onFatalException=null!==(s=t.onFatalException)&&void 0!==s?s:this._onFatalException,this.fpsSampler=new r4({initialFps:60,nowFn:()=>this.now()})}elapsed(){return this._elapsed}now(){return performance.now()}toTestClock(){return new r6({...this._options,defaultUpdateMs:16.6})}toStandardClock(){return new r9({...this._options})}setFatalExceptionHandler(t){this._onFatalException=t}schedule(t,e=0){let i=this._totalElapsed+e;this._scheduledCbs.push([t,i])}_runScheduledCbs(){for(let t=this._scheduledCbs.length-1;t>-1;t--)this._scheduledCbs[t][1]<=this._totalElapsed&&(this._scheduledCbs[t][0](this._elapsed),this._scheduledCbs.splice(t,1))}update(t){try{this.fpsSampler.start();let e=this.now(),i=e-this._lastTime||1,s=1e3/this._maxFps;if(i>=s){let r=0;0!==s&&(r=i%s,i-=r),i>200&&(i=1),this._elapsed=t||i,this._totalElapsed+=this._elapsed,this._runScheduledCbs(),this.tick(t||i),0!==s?this._lastTime=e-r:this._lastTime=e,this.fpsSampler.end()}}catch(t){this._onFatalException(t),this.stop()}}}class r9 extends r3{constructor(t){super(t),this._running=!1}isRunning(){return this._running}start(){if(this._running)return;this._running=!0;let t=()=>{if(this._running)try{this._requestId=window.requestAnimationFrame(t),this.update()}catch(t){throw window.cancelAnimationFrame(this._requestId),t}};t()}stop(){window.cancelAnimationFrame(this._requestId),this._running=!1}}class r6 extends r3{constructor(t){super({...t}),this._logger=tW.getInstance(),this._running=!1,this._currentTime=0,this._updateMs=t.defaultUpdateMs}now(){var t;return null!==(t=this._currentTime)&&void 0!==t?t:0}isRunning(){return this._running}start(){this._running=!0}stop(){this._running=!1}step(t){let e=null!=t?t:this._updateMs;this._running?(this.update(e),this._currentTime+=e):this._logger.warn("The clock is not running, no step will be performed")}run(t,e){for(let i=0;ithis._createFragment(t));if(e){let t=document.createElement("a");t.href=e,i?t.innerText=i:t.innerText=e,r.splice(1,0,t)}let n=document.createElement("div");r.forEach(t=>{n.appendChild(t)}),s.appendChild(n);let o=document.createElement("button");o.innerText="x",o.addEventListener("click",()=>{this._container.removeChild(s)}),s.appendChild(o);let a=t=>{if("Escape"===t.key)try{this._container.removeChild(s)}catch(t){}document.removeEventListener("keydown",a)};document.addEventListener("keydown",a);let l=this._container.firstChild;this._container.insertBefore(s,l)}}let nt={NavigationStart:"navigationstart",Navigation:"navigation",NavigationEnd:"navigationend"};class ne{get isTransitioning(){return this._isTransitioning}constructor(t,e){for(let i in this._engine=t,this.events=new tP,this._logger=tW.getInstance(),this._initialized=!1,this.scenes={},this._sceneToInstance=new Map,this._sceneToLoader=new Map,this._sceneToTransition=new Map,this._loadedScenes=new Set,this._isTransitioning=!1,this.rootScene=this.currentScene=new rq,this.add("root",this.rootScene),this.currentScene=this.rootScene,this.currentSceneName="root",e){let t=e[i];this.add(i,t),"root"===i&&(this.rootScene=this.getSceneInstance("root"),this.currentScene=this.rootScene)}}async onInitialize(){if(!this._initialized){if(this._initialized=!0,this._deferredGoto){let t=this._deferredGoto;this._deferredGoto=null,await this.swapScene(t)}else await this.swapScene("root")}}get isInitialized(){return this._initialized}configureStart(t,e){let i;let s=null==e?void 0:e.loader;if(s instanceof iE?this.mainLoader=s:iA(s)?this.mainLoader=new s:this.mainLoader=new iB,e){let{inTransition:t}=e;i=t}this.startScene=t,i?(this.swapScene(this.startScene),this.playTransition(i)):this.swapScene(this.startScene),this.currentSceneName=this.startScene}_getLoader(t){return this._sceneToLoader.get(t)}_getInTransition(t){var e;let i=this.scenes[t];return i instanceof rq||rj(i)?null:null===(e=null==i?void 0:i.transitions)||void 0===e?void 0:e.in}_getOutTransition(t){var e;let i=this.scenes[t];return i instanceof rq||rj(i)?null:null===(e=null==i?void 0:i.transitions)||void 0===e?void 0:e.out}getDeferredScene(){let t=this.getSceneDefinition(this._deferredGoto);return this._deferredGoto&&t?t:null}getSceneDefinition(t){let e=this.scenes[t];return e instanceof rq||rj(e)?e:e?e.scene:void 0}getSceneName(t){for(let[e,i]of this._sceneToInstance)if(t===i)return e;return"unknown scene name"}assertAdded(t){return this}assertRemoved(t){return this}add(t,e){if(!(e instanceof rq)&&!rj(e)){let{loader:i,transitions:s}=e,{in:r,out:n}=null!=s?s:{};this._sceneToTransition.set(t,{in:r,out:n}),iA(i)?this._sceneToLoader.set(t,new i):this._sceneToLoader.set(t,i)}return this.scenes[t]&&this._logger.warn("Scene",t,"already exists overwriting"),this.scenes[t]=e,this.assertAdded(t)}remove(t){if(t instanceof rq||rj(t)){for(let e in this.scenes)if(this.scenes.hasOwnProperty(e)){let i=this.scenes[e];if((i instanceof rq||rj(i)?i:i.scene)===t){if(e===this.currentSceneName)throw Error(`Cannot remove a currently active scene: ${e}`);this._sceneToTransition.delete(e),this._sceneToLoader.delete(e),delete this.scenes[e]}}}if("string"==typeof t){if(t===this.currentSceneName)throw Error(`Cannot remove a currently active scene: ${t}`);this._sceneToTransition.delete(t),this._sceneToLoader.delete(t),delete this.scenes[t]}}async goto(t,e){var i,s,r,n,o,a;let l=this.getSceneInstance(t);if(!l){this._logger.warn(`Scene ${t} does not exist! Check the name, are you sure you added it?`);return}let h=this.currentSceneName,d=null===(s=null===(i=this._engine.input)||void 0===i?void 0:i.enabled)||void 0===s||s;this._isTransitioning=!0;let c=null===(r=this.getSceneInstance(h))||void 0===r?void 0:r.onTransition("out"),u=null==l?void 0:l.onTransition("in"),{sourceOut:p,destinationIn:g,sceneActivationData:_}=e={sourceOut:null!==(n=this._getOutTransition(this.currentSceneName))&&void 0!==n?n:c,destinationIn:null!==(o=this._getInTransition(t))&&void 0!==o?o:u,...e},f=null!=p?p:this._getOutTransition(this.currentSceneName),m=null!=g?g:this._getInTransition(t),v=(null==f?void 0:f.hideLoader)||(null==m?void 0:m.hideLoader);v&&this.maybeLoadScene(t,v),this._emitEvent("navigationstart",h,t),await this.playTransition(f),await this.maybeLoadScene(t,v),await (null==m?void 0:m.onPreviousSceneDeactivate(this.currentScene)),await this.swapScene(t,_),this._emitEvent("navigation",h,t),await this.playTransition(m),this._emitEvent("navigationend",h,t),null===(a=this._engine.input)||void 0===a||a.toggleEnabled(d),this._isTransitioning=!1}getSceneInstance(t){let e=this.getSceneDefinition(t);if(!e)return;if(this._sceneToInstance.has(t))return this._sceneToInstance.get(t);if(e instanceof rq)return this._sceneToInstance.set(t,e),e;let i=new e;return this._sceneToInstance.set(t,i),i}async maybeLoadScene(t,e=!1){var i;let s=null!==(i=this._getLoader(t))&&void 0!==i?i:new iE,r=this.getSceneDefinition(t),n=this.getSceneInstance(t);r&&n&&!this._loadedScenes.has(n)&&(n.onPreLoad(s),n.events.emit("preload",{loader:s}),e?this._engine.load(s,e):await this._engine.load(s),this._loadedScenes.add(n))}async playTransition(t){var e,i,s,r,n,o,a;if(t){this.currentTransition=t;let o=this._engine.currentScene,a=null===(i=null===(e=o.input)||void 0===e?void 0:e.enabled)||void 0===i||i;null===(s=o.input)||void 0===s||s.toggleEnabled(!t.blockInput),null===(r=this._engine.input)||void 0===r||r.toggleEnabled(!t.blockInput),await this.currentTransition.play(this._engine),null===(n=o.input)||void 0===n||n.toggleEnabled(a)}null===(o=this.currentTransition)||void 0===o||o.kill(),null===(a=this.currentTransition)||void 0===a||a.reset(),this.currentTransition=null}async swapScene(t,e){let i=this._engine;if(!this.isInitialized){this._deferredGoto=t;return}let s=this.getSceneInstance(t);if(s){let r=this.currentScene;if(this._logger.debug("Going to scene:",t),this.currentScene.isInitialized){let t={engine:i,previousScene:r,nextScene:s};await this.currentScene._deactivate(t),this.currentScene.events.emit("deactivate",new iu(t,this.currentScene))}let n=this._sceneToLoader.get(t);await (null==n?void 0:n.areResourcesLoaded()),this.currentScene=s,this.currentSceneName=t,i.screen.setCurrentCamera(s.camera),await this.currentScene._initialize(i);let o={engine:i,previousScene:r,nextScene:s,data:e};await this.currentScene._activate(o),this.currentScene.events.emit("activate",new ic(o,this.currentScene))}else this._logger.error("Scene",t,"does not exist!")}_emitEvent(t,e,i){let s=this.getSceneDefinition(e),r=this.getSceneDefinition(i);this.events.emit(t,{sourceScene:s,sourceName:e,destinationScene:r,destinationName:i})}}tT();let ni={FallbackGraphicsContext:"fallbackgraphicscontext",Initialize:"initialize",Visible:"visible",Hidden:"hidden",Start:"start",Stop:"stop",PreUpdate:"preupdate",PostUpdate:"postupdate",PreFrame:"preframe",PostFrame:"postframe",PreDraw:"predraw",PostDraw:"postdraw"};(z=tv||(tv={}))[z.None=0]="None",z[z.Canvas=1]="Canvas",z[z.All=2]="All";class ns{get canvasWidth(){return this.screen.canvasWidth}get halfCanvasWidth(){return this.screen.halfCanvasWidth}get canvasHeight(){return this.screen.canvasHeight}get halfCanvasHeight(){return this.screen.halfCanvasHeight}get drawWidth(){return this.screen.drawWidth}get halfDrawWidth(){return this.screen.halfDrawWidth}get drawHeight(){return this.screen.drawHeight}get halfDrawHeight(){return this.screen.halfDrawHeight}get isHiDpi(){return this.screen.isHiDpi}get stats(){return this.debug.stats}get currentScene(){return this.director.currentScene}get currentSceneName(){return this.director.currentSceneName}get rootScene(){return this.director.rootScene}get scenes(){return this.director.scenes}get isFullscreen(){return this.screen.isFullScreen}get displayMode(){return this.screen.displayMode}get pixelRatio(){return this.screen.pixelRatio}get isDebug(){return this._isDebug}get snapToPixel(){return this.graphicsContext.snapToPixel}set snapToPixel(t){this.graphicsContext.snapToPixel=t}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}constructor(t){var e,i,s,r,n,o,a;let l,h,d,c,u,p;this.version=nU,this.events=new tP,this.maxFps=Number.POSITIVE_INFINITY,this._inputEnabled=!0,this._suppressPlayButton=!1,this.pauseAudioWhenHidden=!0,this._isDebug=!1,this.enableCanvasTransparency=!0,this.onFatalException=t=>{tW.getInstance().fatal(t,t.stack)},this._toaster=new r8,this._timescale=1,this._isInitialized=!1,this._originalOptions={},this._performanceThresholdTriggered=!1,this._fpsSamples=[],this._disposed=!1,this._isLoading=!1,this._hideLoader=!1,this._isReadyFuture=new tE,this.currentFrameElapsedMs=0,this.currentFrameLagMs=0,this._lagMs=0,this._screenShotRequests=[],t={...ns._DEFAULT_ENGINE_OPTIONS,...t},this._originalOptions=t,tS.freeze(),this.browser=new r1(window,document);let g=new iL;if(t.suppressMinimumBrowserFeatureDetection||(this._compatible=g.test()))this._compatible=!0;else{let e=document.createElement("div");if(e.innerText="Sorry, your browser does not support all the features needed for Excalibur",document.body.appendChild(e),g.failedTests.forEach(function(t){let e=document.createElement("div");e.innerText="Browser feature missing "+t,document.body.appendChild(e)}),t.canvasElementId){let e=document.getElementById(t.canvasElementId);e&&e.parentElement.removeChild(e)}return}if(console.log&&!t.suppressConsoleBootMessage&&(console.log(`%cPowered by Excalibur.js (v${nU})`,"background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;"),console.log("\n /| ________________\nO|===|* >________________>\n \\|"),console.log("Visit","http://excaliburjs.com","for more information")),t.suppressPlayButton&&(this._suppressPlayButton=!0),this._logger=tW.getInstance(),this._logger.defaultLevel===U.Debug&&g.logBrowserFeatures(),this._logger.debug("Building engine..."),this.canvasElementId=t.canvasElementId,t.canvasElementId){if(this._logger.debug("Using Canvas element specified: "+t.canvasElementId),null===document.getElementById(t.canvasElementId))throw Error("Cannot find existing element in the DOM, please ensure element is created prior to engine creation.");this.canvas=document.getElementById(t.canvasElementId)}else t.canvasElement?(this._logger.debug("Using Canvas element specified:",t.canvasElement),this.canvas=t.canvasElement):(this._logger.debug("Using generated canvas element"),this.canvas=document.createElement("canvas"));let _=null!==(e=t.displayMode)&&void 0!==e?e:V.Fixed;t.width&&t.height||t.viewport?(void 0===t.displayMode&&(_=V.Fixed),this._logger.debug("Engine viewport is size "+t.width+" x "+t.height)):t.displayMode||(this._logger.debug("Engine viewport is fit"),_=V.FitScreen),this._originalDisplayMode=_,"object"==typeof t.antialiasing?{pixelArtSampler:l,nativeContextAntialiasing:d,multiSampleAntialiasing:p,filtering:u,canvasImageRendering:c}={...t.pixelArt?r5:r2,...t.antialiasing}:(l=!!t.pixelArt,d=!1,p=t.antialiasing,c=t.antialiasing?"auto":"pixelated",u=t.antialiasing?H.Blended:H.Pixel),d&&p&&this._logger.warnOnce("Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing at the same time, they are incompatible settings. If you aren't sure use multiSampleAntialiasing"),t.pixelArt&&(h=.25),t.antialiasing&&u!==H.Pixel||(h=0),h=null!==(s=null!==(i=t.uvPadding)&&void 0!==i?i:h)&&void 0!==s?s:.01;let f=tS.isEnabled("use-canvas-context");if(!f)try{this.graphicsContext=new ek({canvasElement:this.canvas,enableTransparency:this.enableCanvasTransparency,pixelArtSampler:l,antialiasing:d,multiSampleAntialiasing:p,uvPadding:h,powerPreference:t.powerPreference,backgroundColor:t.backgroundColor,snapToPixel:t.snapToPixel,useDrawSorting:t.useDrawSorting})}catch(t){this._logger.warn(`Excalibur could not load webgl for some reason (${t.message}) and loaded a Canvas 2D fallback. Some features of Excalibur will not work in this mode. + }`,fragmentSource:e}),this._shader.compile(),this._buffer=new ep({gl:t,type:"static",data:new Float32Array([-1,-1,0,0,-1,1,0,1,1,-1,1,0,1,-1,1,0,-1,1,0,1,1,1,1,1])}),this._layout=new eg({gl:t,shader:this._shader,vertexBuffer:this._buffer,attributes:[["a_position",2],["a_texcoord",2]]}),this._buffer.upload()}getShader(){return this._shader}getLayout(){return this._layout}}class r${constructor(t,e=!1){this._colorBlindnessMode=t,this._simulate=!1,this._simulate=e}initialize(t){this._shader=new rX(t,"#version 300 es\r\nprecision mediump float;\r\n// our texture\r\nuniform sampler2D u_image;\r\n// the texCoords passed in from the vertex shader.\r\nin vec2 v_texcoord;\r\n\r\n// color blind type\r\nuniform int u_type;\r\n\r\n// simulation?\r\nuniform bool u_simulate;\r\n\r\nout vec4 fragColor;\r\n\r\nvoid main() {\r\n vec4 o = texture(u_image, v_texcoord);\r\n // RGB to LMS matrix conversion\r\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\r\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\r\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\r\n // Simulate color blindness\r\n float l;\r\n float m;\r\n float s;\r\n //MODE CODE//\r\n if (u_type == 0) {\r\n // Protanope\r\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\r\n m = 0.0 * L + 1.0 * M + 0.0 * S;\r\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\r\n } else if (u_type == 1) {\r\n // Deuteranope\r\n l = 1.0 * L + 0.0 * M + 0.0 * S;\r\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\r\n s = 0.0 * L + 0.0 * M + 1.0 * S;\r\n } else if (u_type == 2) {\r\n // Tritanope\r\n l = 1.0 * L + 0.0 * M + 0.0 * S;\r\n m = 0.0 * L + 1.0 * M + 0.0 * S;\r\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\r\n }\r\n\r\n // LMS to RGB matrix conversion\r\n vec4 error; // simulate the colors\r\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\r\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\r\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\r\n error.a = 1.0;\r\n vec4 diff = o - error;\r\n vec4 correction; // correct the colors\r\n correction.r = 0.0;\r\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\r\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\r\n correction = o + correction;\r\n correction.a = o.a;\r\n //SIMULATE//\r\n\r\n // sim \r\n if (u_simulate) {\r\n fragColor = error.rgba;\r\n } else {\r\n fragColor = correction.rgba;\r\n }\r\n}"),this.simulate=this._simulate,this.colorBlindnessMode=this._colorBlindnessMode}getShader(){return this._shader.getShader()}getLayout(){return this._shader.getLayout()}set colorBlindnessMode(t){if(this._colorBlindnessMode=t,this._shader){let t=this._shader.getShader();t.use(),this._colorBlindnessMode===tm.Protanope?t.setUniformInt("u_type",0):this._colorBlindnessMode===tm.Deuteranope?t.setUniformInt("u_type",1):this._colorBlindnessMode===tm.Tritanope&&t.setUniformInt("u_type",2)}}get colorBlindnessMode(){return this._colorBlindnessMode}set simulate(t){if(this._simulate=t,this._shader){let e=this._shader.getShader();e.use(),e.setUniformBoolean("u_simulate",t)}}get simulate(){return this._simulate}}class rK{constructor(t){this._engine=t,this._colorBlindPostProcessor=new r$(tm.Protanope)}correct(t){this._engine.graphicsContext instanceof ek&&(this.clear(),this._colorBlindPostProcessor.colorBlindnessMode=t,this._colorBlindPostProcessor.simulate=!1,this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor))}simulate(t){this._engine.graphicsContext instanceof ek&&(this.clear(),this._colorBlindPostProcessor.colorBlindnessMode=t,this._colorBlindPostProcessor.simulate=!0,this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor))}clear(){this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor)}}class rY{constructor(t){this.stats={currFrame:new rQ,prevFrame:new rQ},this.filter={useFilter:!1,nameQuery:"",ids:[]},this.entity={showAll:!1,showId:!1,showName:!1},this.transform={showAll:!1,debugZIndex:1e7,showPosition:!1,showPositionLabel:!1,positionColor:tH.Yellow,showZIndex:!1,showScale:!1,scaleColor:tH.Green,showRotation:!1,rotationColor:tH.Blue},this.graphics={showAll:!1,showBounds:!1,boundsColor:tH.Yellow},this.collider={showAll:!1,showBounds:!1,boundsColor:tH.Blue,showOwner:!1,showGeometry:!0,geometryColor:tH.Green,geometryLineWidth:1,geometryPointSize:.5},this.physics={showAll:!1,showBroadphaseSpacePartitionDebug:!1,showCollisionNormals:!1,collisionNormalColor:tH.Cyan,showCollisionContacts:!0,contactSize:2,collisionContactColor:tH.Red},this.motion={showAll:!1,showVelocity:!1,velocityColor:tH.Yellow,showAcceleration:!1,accelerationColor:tH.Red},this.body={showAll:!1,showCollisionGroup:!1,showCollisionType:!1,showSleeping:!1,showMotion:!1,showMass:!1},this.camera={showAll:!1,showFocus:!1,focusColor:tH.Red,showZoom:!1},this.tilemap={showAll:!1,showGrid:!1,gridColor:tH.Red,gridWidth:.5,showSolidBounds:!1,solidBoundsColor:tH.fromHex("#8080807F"),showColliderGeometry:!0},this.isometric={showAll:!1,showPosition:!1,positionColor:tH.Yellow,positionSize:1,showGrid:!1,gridColor:tH.Red,gridWidth:1,showColliderGeometry:!0},this._engine=t,this.colorBlindMode=new rK(this._engine)}useTestClock(){let t=this._engine.clock,e=t.isRunning();t.stop();let i=t.toTestClock();return e&&i.start(),this._engine.clock=i,i}useStandardClock(){let t=this._engine.clock,e=t.isRunning();t.stop();let i=t.toStandardClock();return e&&i.start(),this._engine.clock=i,i}}class rQ{constructor(){this._id=0,this._delta=0,this._fps=0,this._actorStats={alive:0,killed:0,ui:0,get remaining(){return this.alive-this.killed},get total(){return this.remaining+this.ui}},this._durationStats={update:0,draw:0,get total(){return this.update+this.draw}},this._physicsStats=new rJ,this._graphicsStats={drawCalls:0,drawnImages:0}}reset(t){t?(this.id=t.id,this.delta=t.delta,this.fps=t.fps,this.actors.alive=t.actors.alive,this.actors.killed=t.actors.killed,this.actors.ui=t.actors.ui,this.duration.update=t.duration.update,this.duration.draw=t.duration.draw,this._physicsStats.reset(t.physics),this.graphics.drawCalls=t.graphics.drawCalls,this.graphics.drawnImages=t.graphics.drawnImages):(this.id=this.delta=this.fps=0,this.actors.alive=this.actors.killed=this.actors.ui=0,this.duration.update=this.duration.draw=0,this._physicsStats.reset(),this.graphics.drawnImages=this.graphics.drawCalls=0)}clone(){let t=new rQ;return t.reset(this),t}get id(){return this._id}set id(t){this._id=t}get delta(){return this._delta}set delta(t){this._delta=t}get fps(){return this._fps}set fps(t){this._fps=t}get actors(){return this._actorStats}get duration(){return this._durationStats}get physics(){return this._physicsStats}get graphics(){return this._graphicsStats}}class rJ{constructor(){this._pairs=0,this._collisions=0,this._contacts=new Map,this._fastBodies=0,this._fastBodyCollisions=0,this._broadphase=0,this._narrowphase=0}reset(t){t?(this.pairs=t.pairs,this.collisions=t.collisions,this.contacts=t.contacts,this.fastBodies=t.fastBodies,this.fastBodyCollisions=t.fastBodyCollisions,this.broadphase=t.broadphase,this.narrowphase=t.narrowphase):(this.pairs=this.collisions=this.fastBodies=0,this.fastBodyCollisions=this.broadphase=this.narrowphase=0,this.contacts.clear())}clone(){let t=new rJ;return t.reset(this),t}get pairs(){return this._pairs}set pairs(t){this._pairs=t}get collisions(){return this._collisions}set collisions(t){this._collisions=t}get contacts(){return this._contacts}set contacts(t){this._contacts=t}get fastBodies(){return this._fastBodies}set fastBodies(t){this._fastBodies=t}get fastBodyCollisions(){return this._fastBodyCollisions}set fastBodyCollisions(t){this._fastBodyCollisions=t}get broadphase(){return this._broadphase}set broadphase(t){this._broadphase=t}get narrowphase(){return this._narrowphase}set narrowphase(t){this._narrowphase=t}}class r0{on(t,e){this._nativeHandlers[t]&&this.off(t,this._nativeHandlers[t]),this._nativeHandlers[t]=this._decorate(e),this.nativeComponent.addEventListener(t,this._nativeHandlers[t])}off(t,e){e||(e=this._nativeHandlers[t]),this.nativeComponent.removeEventListener(t,e),this._nativeHandlers[t]=null}_decorate(t){return e=>{this._paused||t(e)}}pause(){this._paused=!0}resume(){this._paused=!1}clear(){for(let t in this._nativeHandlers)this.off(t)}constructor(t){this.nativeComponent=t,this._paused=!1,this._nativeHandlers={}}}class r1{constructor(t,e){this._windowGlobal=t,this._documentGlobal=e,this._windowComponent=new r0(this._windowGlobal),this._documentComponent=new r0(this._documentGlobal)}get window(){return this._windowComponent}get document(){return this._documentComponent}pause(){this.window.pause(),this.document.pause()}resume(){this.window.resume(),this.document.resume()}clear(){this.window.clear(),this.document.clear()}}let r2={pixelArtSampler:!1,nativeContextAntialiasing:!1,multiSampleAntialiasing:!0,filtering:H.Blended,canvasImageRendering:"auto"},r5={pixelArtSampler:!0,nativeContextAntialiasing:!1,multiSampleAntialiasing:!0,filtering:H.Blended,canvasImageRendering:"auto"};class r4{constructor(t){var e;this._samplePeriod=100,this._currentFrameTime=0,this._frames=0,this._previousSampleTime=0,this._beginFrameTime=0,this._fps=t.initialFps,this._samplePeriod=null!==(e=t.samplePeriod)&&void 0!==e?e:this._samplePeriod,this._currentFrameTime=1e3/t.initialFps,this._nowFn=t.nowFn,this._previousSampleTime=this._nowFn()}start(){this._beginFrameTime=this._nowFn()}end(){this._frames++;let t=this._nowFn();this._currentFrameTime=t-this._beginFrameTime,t>=this._previousSampleTime+this._samplePeriod&&(this._fps=1e3*this._frames/(t-this._previousSampleTime),this._previousSampleTime=t,this._frames=0)}get fps(){return this._fps}get instant(){return 1e3/this._currentFrameTime}}class r3{constructor(t){var e,i,s;this._onFatalException=()=>{},this._maxFps=1/0,this._lastTime=0,this._elapsed=1,this._scheduledCbs=[],this._totalElapsed=0,this._options=t,this.tick=t.tick,this._lastTime=null!==(e=this.now())&&void 0!==e?e:0,this._maxFps=null!==(i=t.maxFps)&&void 0!==i?i:this._maxFps,this._onFatalException=null!==(s=t.onFatalException)&&void 0!==s?s:this._onFatalException,this.fpsSampler=new r4({initialFps:60,nowFn:()=>this.now()})}elapsed(){return this._elapsed}now(){return performance.now()}toTestClock(){return new r6({...this._options,defaultUpdateMs:16.6})}toStandardClock(){return new r9({...this._options})}setFatalExceptionHandler(t){this._onFatalException=t}schedule(t,e=0){let i=this._totalElapsed+e;this._scheduledCbs.push([t,i])}_runScheduledCbs(){for(let t=this._scheduledCbs.length-1;t>-1;t--)this._scheduledCbs[t][1]<=this._totalElapsed&&(this._scheduledCbs[t][0](this._elapsed),this._scheduledCbs.splice(t,1))}update(t){try{this.fpsSampler.start();let e=this.now(),i=e-this._lastTime||1,s=1e3/this._maxFps;if(i>=s){let r=0;0!==s&&(r=i%s,i-=r),i>200&&(i=1),this._elapsed=t||i,this._totalElapsed+=this._elapsed,this._runScheduledCbs(),this.tick(t||i),0!==s?this._lastTime=e-r:this._lastTime=e,this.fpsSampler.end()}}catch(t){this._onFatalException(t),this.stop()}}}class r9 extends r3{constructor(t){super(t),this._running=!1}isRunning(){return this._running}start(){if(this._running)return;this._running=!0;let t=()=>{if(this._running)try{this._requestId=window.requestAnimationFrame(t),this.update()}catch(t){throw window.cancelAnimationFrame(this._requestId),t}};t()}stop(){window.cancelAnimationFrame(this._requestId),this._running=!1}}class r6 extends r3{constructor(t){super({...t}),this._logger=tW.getInstance(),this._running=!1,this._currentTime=0,this._updateMs=t.defaultUpdateMs}now(){var t;return null!==(t=this._currentTime)&&void 0!==t?t:0}isRunning(){return this._running}start(){this._running=!0}stop(){this._running=!1}step(t){let e=null!=t?t:this._updateMs;this._running?(this.update(e),this._currentTime+=e):this._logger.warn("The clock is not running, no step will be performed")}run(t,e){for(let i=0;ithis._createFragment(t));if(e){let t=document.createElement("a");t.href=e,i?t.innerText=i:t.innerText=e,r.splice(1,0,t)}let n=document.createElement("div");r.forEach(t=>{n.appendChild(t)}),s.appendChild(n);let o=document.createElement("button");o.innerText="x",o.addEventListener("click",()=>{this._container.removeChild(s)}),s.appendChild(o);let a=t=>{if("Escape"===t.key)try{this._container.removeChild(s)}catch(t){}document.removeEventListener("keydown",a)};document.addEventListener("keydown",a);let l=this._container.firstChild;this._container.insertBefore(s,l)}}let nt={NavigationStart:"navigationstart",Navigation:"navigation",NavigationEnd:"navigationend"};class ne{get isTransitioning(){return this._isTransitioning}constructor(t,e){for(let i in this._engine=t,this.events=new tP,this._logger=tW.getInstance(),this._initialized=!1,this.scenes={},this._sceneToInstance=new Map,this._sceneToLoader=new Map,this._sceneToTransition=new Map,this._loadedScenes=new Set,this._isTransitioning=!1,this.rootScene=this.currentScene=new rq,this.add("root",this.rootScene),this.currentScene=this.rootScene,this.currentSceneName="root",e){let t=e[i];this.add(i,t),"root"===i&&(this.rootScene=this.getSceneInstance("root"),this.currentScene=this.rootScene)}}async onInitialize(){if(!this._initialized){if(this._initialized=!0,this._deferredGoto){let t=this._deferredGoto,e=this._deferredTransition;this._deferredGoto=null,this._deferredTransition=null,await this.swapScene(t),e&&await this.playTransition(e)}else await this.swapScene("root")}}get isInitialized(){return this._initialized}configureStart(t,e){let i;let s=null==e?void 0:e.loader;if(s instanceof iE?this.mainLoader=s:iA(s)?this.mainLoader=new s:this.mainLoader=new iB,e){let{inTransition:t}=e;i=t}this.startScene=t,i?this.swapScene(this.startScene).then(()=>{this.playTransition(i)}):this.swapScene(this.startScene),this.currentSceneName=this.startScene}_getLoader(t){return this._sceneToLoader.get(t)}_getInTransition(t){var e;let i=this.scenes[t];return i instanceof rq||rj(i)?null:null===(e=null==i?void 0:i.transitions)||void 0===e?void 0:e.in}_getOutTransition(t){var e;let i=this.scenes[t];return i instanceof rq||rj(i)?null:null===(e=null==i?void 0:i.transitions)||void 0===e?void 0:e.out}getDeferredScene(){let t=this.getSceneDefinition(this._deferredGoto);return this._deferredGoto&&t?t:null}getSceneDefinition(t){let e=this.scenes[t];return e instanceof rq||rj(e)?e:e?e.scene:void 0}getSceneName(t){for(let[e,i]of this._sceneToInstance)if(t===i)return e;return"unknown scene name"}assertAdded(t){return this}assertRemoved(t){return this}add(t,e){if(!(e instanceof rq)&&!rj(e)){let{loader:i,transitions:s}=e,{in:r,out:n}=null!=s?s:{};this._sceneToTransition.set(t,{in:r,out:n}),iA(i)?this._sceneToLoader.set(t,new i):this._sceneToLoader.set(t,i)}return this.scenes[t]&&this._logger.warn("Scene",t,"already exists overwriting"),this.scenes[t]=e,this.assertAdded(t)}remove(t){if(t instanceof rq||rj(t)){for(let e in this.scenes)if(this.scenes.hasOwnProperty(e)){let i=this.scenes[e];if((i instanceof rq||rj(i)?i:i.scene)===t){if(e===this.currentSceneName)throw Error(`Cannot remove a currently active scene: ${e}`);this._sceneToTransition.delete(e),this._sceneToLoader.delete(e),delete this.scenes[e]}}}if("string"==typeof t){if(t===this.currentSceneName)throw Error(`Cannot remove a currently active scene: ${t}`);this._sceneToTransition.delete(t),this._sceneToLoader.delete(t),delete this.scenes[t]}}async goto(t,e){var i,s,r,n,o,a;let l=this.getSceneInstance(t);if(!l){this._logger.warn(`Scene ${t} does not exist! Check the name, are you sure you added it?`);return}let h=this.currentSceneName,d=null===(s=null===(i=this._engine.input)||void 0===i?void 0:i.enabled)||void 0===s||s;this._isTransitioning=!0;let c=null===(r=this.getSceneInstance(h))||void 0===r?void 0:r.onTransition("out"),u=null==l?void 0:l.onTransition("in"),{sourceOut:p,destinationIn:g,sceneActivationData:_}=e={sourceOut:null!==(n=this._getOutTransition(this.currentSceneName))&&void 0!==n?n:c,destinationIn:null!==(o=this._getInTransition(t))&&void 0!==o?o:u,...e},f=null!=p?p:this._getOutTransition(this.currentSceneName),m=null!=g?g:this._getInTransition(t),v=(null==f?void 0:f.hideLoader)||(null==m?void 0:m.hideLoader);v&&this.maybeLoadScene(t,v),this._emitEvent("navigationstart",h,t),await this.playTransition(f),await this.maybeLoadScene(t,v),await (null==m?void 0:m.onPreviousSceneDeactivate(this.currentScene)),await this.swapScene(t,_),this._emitEvent("navigation",h,t),await this.playTransition(m),this._emitEvent("navigationend",h,t),null===(a=this._engine.input)||void 0===a||a.toggleEnabled(d),this._isTransitioning=!1}getSceneInstance(t){let e=this.getSceneDefinition(t);if(!e)return;if(this._sceneToInstance.has(t))return this._sceneToInstance.get(t);if(e instanceof rq)return this._sceneToInstance.set(t,e),e;let i=new e;return this._sceneToInstance.set(t,i),i}async maybeLoadScene(t,e=!1){var i;let s=null!==(i=this._getLoader(t))&&void 0!==i?i:new iE,r=this.getSceneDefinition(t),n=this.getSceneInstance(t);r&&n&&!this._loadedScenes.has(n)&&(n.onPreLoad(s),n.events.emit("preload",{loader:s}),e?this._engine.load(s,e):await this._engine.load(s),this._loadedScenes.add(n))}async playTransition(t){var e,i,s,r,n,o,a;if(!this.isInitialized){this._deferredTransition=t;return}if(t){this.currentTransition=t;let o=this._engine.currentScene,a=null===(i=null===(e=o.input)||void 0===e?void 0:e.enabled)||void 0===i||i;null===(s=o.input)||void 0===s||s.toggleEnabled(!t.blockInput),null===(r=this._engine.input)||void 0===r||r.toggleEnabled(!t.blockInput),await this.currentTransition.play(this._engine),null===(n=o.input)||void 0===n||n.toggleEnabled(a)}null===(o=this.currentTransition)||void 0===o||o.kill(),null===(a=this.currentTransition)||void 0===a||a.reset(),this.currentTransition=null}async swapScene(t,e){let i=this._engine;if(!this.isInitialized){this._deferredGoto=t;return}let s=this.getSceneInstance(t);if(s){let r=this.currentScene;if(this._logger.debug("Going to scene:",t),this.currentScene.isInitialized){let t={engine:i,previousScene:r,nextScene:s};await this.currentScene._deactivate(t),this.currentScene.events.emit("deactivate",new iu(t,this.currentScene))}let n=this._sceneToLoader.get(t);await (null==n?void 0:n.areResourcesLoaded()),this.currentScene=s,this.currentSceneName=t,i.screen.setCurrentCamera(s.camera),await this.currentScene._initialize(i);let o={engine:i,previousScene:r,nextScene:s,data:e};await this.currentScene._activate(o),this.currentScene.events.emit("activate",new ic(o,this.currentScene))}else this._logger.error("Scene",t,"does not exist!")}_emitEvent(t,e,i){let s=this.getSceneDefinition(e),r=this.getSceneDefinition(i);this.events.emit(t,{sourceScene:s,sourceName:e,destinationScene:r,destinationName:i})}}tT();let ni={FallbackGraphicsContext:"fallbackgraphicscontext",Initialize:"initialize",Visible:"visible",Hidden:"hidden",Start:"start",Stop:"stop",PreUpdate:"preupdate",PostUpdate:"postupdate",PreFrame:"preframe",PostFrame:"postframe",PreDraw:"predraw",PostDraw:"postdraw"};(z=tv||(tv={}))[z.None=0]="None",z[z.Canvas=1]="Canvas",z[z.All=2]="All";class ns{get canvasWidth(){return this.screen.canvasWidth}get halfCanvasWidth(){return this.screen.halfCanvasWidth}get canvasHeight(){return this.screen.canvasHeight}get halfCanvasHeight(){return this.screen.halfCanvasHeight}get drawWidth(){return this.screen.drawWidth}get halfDrawWidth(){return this.screen.halfDrawWidth}get drawHeight(){return this.screen.drawHeight}get halfDrawHeight(){return this.screen.halfDrawHeight}get isHiDpi(){return this.screen.isHiDpi}get stats(){return this.debug.stats}get currentScene(){return this.director.currentScene}get currentSceneName(){return this.director.currentSceneName}get rootScene(){return this.director.rootScene}get scenes(){return this.director.scenes}get isFullscreen(){return this.screen.isFullScreen}get displayMode(){return this.screen.displayMode}get pixelRatio(){return this.screen.pixelRatio}get isDebug(){return this._isDebug}get snapToPixel(){return this.graphicsContext.snapToPixel}set snapToPixel(t){this.graphicsContext.snapToPixel=t}emit(t,e){this.events.emit(t,e)}on(t,e){return this.events.on(t,e)}once(t,e){return this.events.once(t,e)}off(t,e){this.events.off(t,e)}constructor(t){var e,i,s,r,n,o,a;let l,h,d,c,u,p;this.version=nU,this.events=new tP,this.maxFps=Number.POSITIVE_INFINITY,this._inputEnabled=!0,this._suppressPlayButton=!1,this.pauseAudioWhenHidden=!0,this._isDebug=!1,this.enableCanvasTransparency=!0,this.onFatalException=t=>{tW.getInstance().fatal(t,t.stack)},this._toaster=new r8,this._timescale=1,this._isInitialized=!1,this._originalOptions={},this._performanceThresholdTriggered=!1,this._fpsSamples=[],this._disposed=!1,this._isLoading=!1,this._hideLoader=!1,this._isReadyFuture=new tE,this.currentFrameElapsedMs=0,this.currentFrameLagMs=0,this._lagMs=0,this._screenShotRequests=[],t={...ns._DEFAULT_ENGINE_OPTIONS,...t},this._originalOptions=t,tS.freeze(),this.browser=new r1(window,document);let g=new iM;if(t.suppressMinimumBrowserFeatureDetection||(this._compatible=g.test()))this._compatible=!0;else{let e=document.createElement("div");if(e.innerText="Sorry, your browser does not support all the features needed for Excalibur",document.body.appendChild(e),g.failedTests.forEach(function(t){let e=document.createElement("div");e.innerText="Browser feature missing "+t,document.body.appendChild(e)}),t.canvasElementId){let e=document.getElementById(t.canvasElementId);e&&e.parentElement.removeChild(e)}return}if(console.log&&!t.suppressConsoleBootMessage&&(console.log(`%cPowered by Excalibur.js (v${nU})`,"background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;"),console.log("\n /| ________________\nO|===|* >________________>\n \\|"),console.log("Visit","http://excaliburjs.com","for more information")),t.suppressPlayButton&&(this._suppressPlayButton=!0),this._logger=tW.getInstance(),this._logger.defaultLevel===U.Debug&&g.logBrowserFeatures(),this._logger.debug("Building engine..."),this.canvasElementId=t.canvasElementId,t.canvasElementId){if(this._logger.debug("Using Canvas element specified: "+t.canvasElementId),null===document.getElementById(t.canvasElementId))throw Error("Cannot find existing element in the DOM, please ensure element is created prior to engine creation.");this.canvas=document.getElementById(t.canvasElementId)}else t.canvasElement?(this._logger.debug("Using Canvas element specified:",t.canvasElement),this.canvas=t.canvasElement):(this._logger.debug("Using generated canvas element"),this.canvas=document.createElement("canvas"));let _=null!==(e=t.displayMode)&&void 0!==e?e:V.Fixed;t.width&&t.height||t.viewport?(void 0===t.displayMode&&(_=V.Fixed),this._logger.debug("Engine viewport is size "+t.width+" x "+t.height)):t.displayMode||(this._logger.debug("Engine viewport is fit"),_=V.FitScreen),this._originalDisplayMode=_,"object"==typeof t.antialiasing?{pixelArtSampler:l,nativeContextAntialiasing:d,multiSampleAntialiasing:p,filtering:u,canvasImageRendering:c}={...t.pixelArt?r5:r2,...t.antialiasing}:(l=!!t.pixelArt,d=!1,p=t.antialiasing,c=t.antialiasing?"auto":"pixelated",u=t.antialiasing?H.Blended:H.Pixel),d&&p&&this._logger.warnOnce("Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing at the same time, they are incompatible settings. If you aren't sure use multiSampleAntialiasing"),t.pixelArt&&(h=.25),t.antialiasing&&u!==H.Pixel||(h=0),h=null!==(s=null!==(i=t.uvPadding)&&void 0!==i?i:h)&&void 0!==s?s:.01;let f=tS.isEnabled("use-canvas-context");if(!f)try{this.graphicsContext=new ek({canvasElement:this.canvas,enableTransparency:this.enableCanvasTransparency,pixelArtSampler:l,antialiasing:d,multiSampleAntialiasing:p,uvPadding:h,powerPreference:t.powerPreference,backgroundColor:t.backgroundColor,snapToPixel:t.snapToPixel,useDrawSorting:t.useDrawSorting})}catch(t){this._logger.warn(`Excalibur could not load webgl for some reason (${t.message}) and loaded a Canvas 2D fallback. Some features of Excalibur will not work in this mode. -Read more about this issue at https://excaliburjs.com/docs/webgl`),f=!0}f&&(this.graphicsContext=new eR({canvasElement:this.canvas,enableTransparency:this.enableCanvasTransparency,antialiasing:d,backgroundColor:t.backgroundColor,snapToPixel:t.snapToPixel,useDrawSorting:t.useDrawSorting})),this.screen=new eM({canvas:this.canvas,context:this.graphicsContext,antialiasing:d,canvasImageRendering:c,browser:this.browser,viewport:null!==(r=t.viewport)&&void 0!==r?r:t.width&&t.height?{width:t.width,height:t.height}:eF.SVGA,resolution:t.resolution,displayMode:_,pixelRatio:t.suppressHiDPIScaling?1:null!==(n=t.pixelRatio)&&void 0!==n?n:null}),ei.filtering=u,t.backgroundColor&&(this.backgroundColor=t.backgroundColor.clone()),this.grabWindowFocus=t.grabWindowFocus,this.pointerScope=t.pointerScope,this.maxFps=null!==(o=t.maxFps)&&void 0!==o?o:this.maxFps,this.fixedUpdateFps=null!==(a=t.fixedUpdateFps)&&void 0!==a?a:this.fixedUpdateFps,this.clock=new r9({maxFps:this.maxFps,tick:this._mainloop.bind(this),onFatalException:t=>this.onFatalException(t)}),this.enableCanvasTransparency=t.enableCanvasTransparency,"boolean"==typeof t.physics?this.physics={...i4,...i3(),enabled:t.physics}:this.physics={...i4,...i3(),...t.physics},this.debug=new rY(this),this.director=new ne(this,t.scenes),this._initialize(t),window.___EXCALIBUR_DEVTOOL=this}_monitorPerformanceThresholdAndTriggerFallback(){let{allow:t}=this._originalOptions.configurePerformanceCanvas2DFallback,{threshold:e,showPlayerMessage:i}=this._originalOptions.configurePerformanceCanvas2DFallback;if(void 0===e&&(e=ns._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold),void 0===i&&(i=ns._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage),!tS.isEnabled("use-canvas-context")&&t&&this.ready&&!this._performanceThresholdTriggered){this._fpsSamples.length===e.numberOfFrames&&this._fpsSamples.splice(0,1),this._fpsSamples.push(this.clock.fpsSampler.fps);let t=0;for(let e=0;ethis.onFatalException(t)}),this.enableCanvasTransparency=t.enableCanvasTransparency,"boolean"==typeof t.physics?this.physics={...i4,...i3(),enabled:t.physics}:this.physics={...i4,...i3(),...t.physics},this.debug=new rY(this),this.director=new ne(this,t.scenes),this._initialize(t),window.___EXCALIBUR_DEVTOOL=this}_monitorPerformanceThresholdAndTriggerFallback(){let{allow:t}=this._originalOptions.configurePerformanceCanvas2DFallback,{threshold:e,showPlayerMessage:i}=this._originalOptions.configurePerformanceCanvas2DFallback;if(void 0===e&&(e=ns._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold),void 0===i&&(i=ns._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage),!tS.isEnabled("use-canvas-context")&&t&&this.ready&&!this._performanceThresholdTriggered){this._fpsSamples.length===e.numberOfFrames&&this._fpsSamples.splice(0,1),this._fpsSamples.push(this.clock.fpsSampler.fps);let t=0;for(let e=0;e{"hidden"===document.visibilityState?(this.events.emit("hidden",new it(this)),this._logger.debug("Window hidden")):"visible"===document.visibilityState&&(this.events.emit("visible",new e8(this)),this._logger.debug("Window visible"))}),this.canvasElementId||t.canvasElement||document.body.appendChild(this.canvas)}toggleInputEnabled(t){this._inputEnabled=t,this.input.toggleEnabled(this._inputEnabled)}onInitialize(t){}setAntialiasing(t){this.screen.antialiasing=t}getAntialiasing(){return this.screen.antialiasing}get isInitialized(){return this._isInitialized}async _overrideInitialize(t){this.isInitialized||(await this.director.onInitialize(),await this.onInitialize(t),this.events.emit("initialize",new id(t,this)),this._isInitialized=!0)}_update(t){var e;if(this._isLoading){null===(e=this._loader)||void 0===e||e.onUpdate(this,t),this.input.update();return}this._preupdate(t),this.currentScene.update(this,t),this.graphicsContext.updatePostProcessors(t),this._postupdate(t),this.input.update()}_preupdate(t){this.emit("preupdate",new e1(this,t,this)),this.onPreUpdate(this,t)}onPreUpdate(t,e){}_postupdate(t){this.emit("postupdate",new e2(this,t,this)),this.onPostUpdate(this,t)}onPostUpdate(t,e){}_draw(t){var e,i;if(this.graphicsContext.beginDrawLifecycle(),this.graphicsContext.clear(),this._predraw(this.graphicsContext,t),this._isLoading){this._hideLoader||(null===(e=this._loader)||void 0===e||e.canvas.draw(this.graphicsContext,0,0),this.graphicsContext.flush(),this.graphicsContext.endDrawLifecycle());return}this.graphicsContext.backgroundColor=null!==(i=this.currentScene.backgroundColor)&&void 0!==i?i:this.backgroundColor,this.currentScene.draw(this.graphicsContext,t),this._postdraw(this.graphicsContext,t),this.graphicsContext.flush(),this.graphicsContext.endDrawLifecycle(),this._checkForScreenShots()}_predraw(t,e){this.emit("predraw",new e$(t,e,this)),this.onPreDraw(t,e)}onPreDraw(t,e){}_postdraw(t,e){this.emit("postdraw",new eK(t,e,this)),this.onPostDraw(t,e)}onPostDraw(t,e){}showDebug(t){this._isDebug=t}toggleDebug(){return this._isDebug=!this._isDebug,this._isDebug}get loadingComplete(){return!this._isLoading}get ready(){return this._isReadyFuture.isCompleted}isReady(){return this._isReadyFuture.promise}async start(t,e){let i;if(!this._compatible)throw Error("Excalibur is incompatible with your browser");return this._isLoading=!0,t instanceof iE?i=t:"string"==typeof t&&(this.director.configureStart(t,e),i=this.director.mainLoader),this._logger.debug("Starting game clock..."),this.browser.resume(),this.clock.start(),this._logger.debug("Game clock started"),await this.load(null!=i?i:new iB),await this._overrideInitialize(this),this._isReadyFuture.resolve(),this.emit("start",new eq(this)),this._isReadyFuture.promise}_mainloop(t){this.emit("preframe",new e5(this,this.stats.prevFrame));let e=t*this.timescale;this.currentFrameElapsedMs=e;let i=this.stats.prevFrame.id+1;this.stats.currFrame.reset(),this.stats.currFrame.id=i,this.stats.currFrame.delta=e,this.stats.currFrame.fps=this.clock.fpsSampler.fps,e_.clear();let s=this.clock.now(),r=1e3/this.fixedUpdateFps;if(this.fixedUpdateFps)for(this._lagMs+=e;this._lagMs>=r;)this._update(r),this._lagMs-=r;else this._update(e);let n=this.clock.now();this.currentFrameLagMs=this._lagMs,this._draw(e);let o=this.clock.now();this.stats.currFrame.duration.update=n-s,this.stats.currFrame.duration.draw=o-n,this.stats.currFrame.graphics.drawnImages=e_.DrawnImagesCount,this.stats.currFrame.graphics.drawCalls=e_.DrawCallCount,this.emit("postframe",new e4(this,this.stats.currFrame)),this.stats.prevFrame.reset(this.stats.currFrame),this._monitorPerformanceThresholdAndTriggerFallback()}stop(){this.clock.isRunning()&&(this.emit("stop",new eX(this)),this.browser.pause(),this.clock.stop(),this._logger.debug("Game stopped"))}isRunning(){return this.clock.isRunning()}screenshot(t=!1){return new Promise(e=>{this._screenShotRequests.push({preserveHiDPIResolution:t,resolve:e})})}_checkForScreenShots(){for(let t of this._screenShotRequests){let e=t.preserveHiDPIResolution?this.canvas.width:this.screen.resolution.width,i=t.preserveHiDPIResolution?this.canvas.height:this.screen.resolution.height,s=document.createElement("canvas");s.width=e,s.height=i;let r=s.getContext("2d");r.imageSmoothingEnabled=this.screen.antialiasing,r.drawImage(this.canvas,0,0,e,i);let n=new Image,o=s.toDataURL("image/png");n.src=o,t.resolve(n)}this._screenShotRequests.length=0}async load(t,e=!1){try{if(t.isLoaded())return;this._loader=t,this._isLoading=!0,this._hideLoader=e,t instanceof iB&&(t.suppressPlayButton=this._suppressPlayButton),this._loader.onInitialize(this),await t.load()}catch(t){this._logger.error("Error loading resources, things may not behave properly",t),await Promise.resolve()}finally{this._isLoading=!1,this._hideLoader=!1,this._loader=null}}}ns._DEFAULT_ENGINE_OPTIONS={width:0,height:0,enableCanvasTransparency:!0,useDrawSorting:!0,configurePerformanceCanvas2DFallback:{allow:!1,showPlayerMessage:!1,threshold:{fps:20,numberOfFrames:100}},canvasElementId:"",canvasElement:void 0,snapToPixel:!1,antialiasing:!0,pixelArt:!1,powerPreference:"high-performance",pointerScope:O.Canvas,suppressConsoleBootMessage:null,suppressMinimumBrowserFeatureDetection:null,suppressHiDPIScaling:null,suppressPlayButton:null,grabWindowFocus:!0,scrollPreventionMode:tv.Canvas,backgroundColor:tH.fromHex("#2185d0")};class nr{constructor(){this._handlers={},this._wiredEventDispatchers=[],this._deferedHandlerRemovals=[]}clear(){this._handlers={},this._wiredEventDispatchers=[]}_processDeferredHandlerRemovals(){for(let t of this._deferedHandlerRemovals)this._removeHandler(t.name,t.handler);this._deferedHandlerRemovals.length=0}emit(t,e){let i,s;if(this._processDeferredHandlerRemovals(),t){if(t=t.toLowerCase(),null==e&&(e=new eV),this._handlers[t])for(i=0,s=this._handlers[t].length;i-1&&this._handlers[t].splice(s,1)}else this._handlers[t].length=0}}once(t,e){this._processDeferredHandlerRemovals();let i=s=>{let r=s||new eV;this.off(t,i),e(r)};this.on(t,i)}wire(t){t._wiredEventDispatchers.push(this)}unwire(t){let e=t._wiredEventDispatchers.indexOf(this);e>-1&&t._wiredEventDispatchers.splice(e,1)}}class nn extends sj{get font(){return this._font}set font(t){this._font=t,this._text.font=t}get text(){return this._text.text}set text(t){this._text.text=t}get color(){return this._text.color}set color(t){this._text&&(this._text.color=t)}get opacity(){return this._text.opacity}set opacity(t){this._text.opacity=t}get spriteFont(){return this._spriteFont}set spriteFont(t){t&&(this._spriteFont=t,this._text.font=this._spriteFont)}constructor(t){super(t),this._font=new sW,this._text=new sG({text:"",font:this._font});let{text:e,pos:i,x:s,y:r,spriteFont:n,font:o,color:a}={text:"",...t};this.pos=null!=i?i:s&&r?tZ(s,r):this.pos,this.text=null!=e?e:this.text,this.font=null!=o?o:this.font,this.spriteFont=null!=n?n:this.spriteFont,this._text.color=null!=a?a:this.color;let l=this.get(sm);l.anchor=tN.Zero,l.use(this._text)}_initialize(t){super._initialize(t)}getTextWidth(){return this._text.width}}class no extends s_{getGraphics(){return this._graphics}addGraphic(t,e){this._graphics.push(t),this._gfx.visible=this.map.visible,this._gfx.opacity=this.map.opacity,(null==e?void 0:e.offset)&&(this._gfx.offset=e.offset),this._gfx.localBounds=this._recalculateBounds()}_recalculateBounds(){let t=this._tileBounds.clone();for(let e of this._graphics){let i=tZ(this.map.graphicsOffset.x-this.map.tileWidth/2,this.map.graphicsOffset.y-(this.map.renderFromTopOfGraphic?0:e.height-this.map.tileHeight));t=t.combine(e.localBounds.translate(i))}return t}removeGraphic(t){let e=this._graphics.indexOf(t);e>-1&&this._graphics.splice(e,1),this._gfx.localBounds=this._recalculateBounds()}clearGraphics(){this._graphics.length=0,this._gfx.visible=!1,this._gfx.localBounds=this._recalculateBounds()}getColliders(){return this._colliders}addCollider(t){this._colliders.push(t),this.map.flagCollidersDirty()}removeCollider(t){let e=this._colliders.indexOf(t);e>-1&&this._colliders.splice(e,1),this.map.flagCollidersDirty()}clearColliders(){this._colliders.length=0,this.map.flagCollidersDirty()}get pos(){return this.map.tileToWorld(tZ(this.x,this.y))}get center(){return this.pos.add(tZ(0,this.map.tileHeight/2))}constructor(t,e,i,s){super([new iV,new sm({offset:null!=i?i:tN.Zero,onPostDraw:(t,e)=>this.draw(t,e)}),new rP(s)]),this.solid=!1,this._tileBounds=new tq,this._graphics=[],this._colliders=[],this.data=new Map,this.x=t,this.y=e,this.map=s,this._transform=this.get(iV),this._isometricEntityComponent=this.get(rP);let r=this.map.tileWidth/2,n=this.map.tileHeight/2,o=(this.x-this.y)*r,a=(this.x+this.y)*n;this._transform.pos=tZ(o,a),this._isometricEntityComponent.elevation=s.elevation,this._gfx=this.get(sm),this._gfx.visible=!1;let l=this.map.tileWidth,h=this.map.tileHeight,d=tZ(0,this.map.renderFromTopOfGraphic?h:0);this._gfx.localBounds=this._tileBounds=new tq({left:-l/2,top:-h,right:l/2,bottom:h}).translate(d)}draw(t,e){let i=this.map.tileWidth/2;for(let e of(t.save(),t.translate(-i,0),this._graphics))e.draw(t,this.map.graphicsOffset.x,this.map.graphicsOffset.y-(this.map.renderFromTopOfGraphic?0:e.height-this.map.tileHeight));t.restore()}}class na extends s_{constructor(t){super([new iV,new sh({type:G.Fixed}),new sl,new sY((t,e)=>this.debug(t,e),!1)],t.name),this.elevation=0,this.visible=!0,this.opacity=1,this.renderFromTopOfGraphic=!1,this.graphicsOffset=tZ(0,0),this._collidersDirty=!1,this._originalOffsets=new WeakMap;let{pos:e,tileWidth:i,tileHeight:s,columns:r,rows:n,renderFromTopOfGraphic:o,graphicsOffset:a,elevation:l}=t;this.transform=this.get(iV),e&&(this.transform.pos=e),this.collider=this.get(sl),this.collider&&this.collider.set(this._composite=new i9([])),this.renderFromTopOfGraphic=null!=o?o:this.renderFromTopOfGraphic,this.graphicsOffset=null!=a?a:this.graphicsOffset,this.elevation=null!=l?l:this.elevation,this.tileWidth=i,this.tileHeight=s,this.columns=r,this.rows=n,this.tiles=Array(r*n);for(let t=0;t=this.columns||e>=this.rows?null:this.tiles[t+e*this.columns]}getTileByPoint(t){let e=this.worldToTile(t);return this.getTile(e.x,e.y)}_getMaxZIndex(){let t=Number.NEGATIVE_INFINITY;for(let e of this.tiles){let i=e.get(iV).z;i>t&&(t=i)}return t}debug(t,e){let{showAll:i,showPosition:s,positionColor:r,positionSize:n,showGrid:o,gridColor:a,gridWidth:l,showColliderGeometry:h}=e.isometric,{geometryColor:d,geometryLineWidth:c,geometryPointSize:u}=e.collider;if(t.save(),t.z=this._getMaxZIndex()+.5,i||o){for(let e=0;ee.isComplete(t))}reset(){this._actions.forEach(t=>t.reset())}stop(){this._actions.forEach(t=>t.stop())}}class nd{constructor(t,e){this.bounds=t,this.options=e,this._defaultOptions={maxDepth:10,capacity:10,level:0},this.items=[],this._isDivided=!1,this.topLeft=null,this.topRight=null,this.bottomLeft=null,this.bottomRight=null,this.options={...this._defaultOptions,...e},this.halfWidth=t.width/2,this.halfHeight=t.height/2}_split(){this._isDivided=!0;let t={maxDepth:this.options.maxDepth,capacity:this.options.capacity,level:this.options.level+1};this.topLeft=new nd(new tq({left:this.bounds.left,top:this.bounds.top,right:this.bounds.left+this.halfWidth,bottom:this.bounds.top+this.halfHeight}),t),this.topRight=new nd(new tq({left:this.bounds.left+this.halfWidth,top:this.bounds.top,right:this.bounds.right,bottom:this.bounds.top+this.halfHeight}),t),this.bottomLeft=new nd(new tq({left:this.bounds.left,top:this.bounds.top+this.halfHeight,right:this.bounds.left+this.halfWidth,bottom:this.bounds.bottom}),t),this.bottomRight=new nd(new tq({left:this.bounds.left+this.halfWidth,top:this.bounds.top+this.halfHeight,right:this.bounds.right,bottom:this.bounds.bottom}),t)}_insertIntoSubNodes(t){var e,i,s,r;(null===(e=this.topLeft)||void 0===e?void 0:e.bounds.overlaps(t.bounds))&&this.topLeft.insert(t),(null===(i=this.topRight)||void 0===i?void 0:i.bounds.overlaps(t.bounds))&&this.topRight.insert(t),(null===(s=this.bottomLeft)||void 0===s?void 0:s.bounds.overlaps(t.bounds))&&this.bottomLeft.insert(t),(null===(r=this.bottomRight)||void 0===r?void 0:r.bounds.overlaps(t.bounds))&&this.bottomRight.insert(t)}insert(t){if(this._isDivided){this._insertIntoSubNodes(t);return}if(this.items.push(t),this.items.length>this.options.capacity&&this.options.level-1&&this.items.splice(e,1);return}(null===(e=this.topLeft)||void 0===e?void 0:e.bounds.overlaps(t.bounds))&&this.topLeft.remove(t),(null===(i=this.topRight)||void 0===i?void 0:i.bounds.overlaps(t.bounds))&&this.topRight.remove(t),(null===(s=this.bottomLeft)||void 0===s?void 0:s.bounds.overlaps(t.bounds))&&this.bottomLeft.remove(t),(null===(r=this.bottomRight)||void 0===r?void 0:r.bounds.overlaps(t.bounds))&&this.bottomRight.remove(t)}}query(t){let e=this.items;return this._isDivided&&(this.topLeft.bounds.overlaps(t)&&(e=e.concat(this.topLeft.query(t))),this.topRight.bounds.overlaps(t)&&(e=e.concat(this.topRight.query(t))),this.bottomLeft.bounds.overlaps(t)&&(e=e.concat(this.bottomLeft.query(t))),this.bottomRight.bounds.overlaps(t)&&(e=e.concat(this.bottomRight.query(t)))),e=e.filter((t,i)=>e.indexOf(t)>=i)}clear(){this.items=[],this._isDivided=!1,this.topLeft=null,this.topRight=null,this.bottomLeft=null,this.bottomRight=null}getAllItems(){let t=this.items;return this._isDivided&&(t=(t=(t=(t=t.concat(this.topLeft.getAllItems())).concat(this.topRight.getAllItems())).concat(this.bottomLeft.getAllItems())).concat(this.bottomRight.getAllItems())),t=t.filter((e,i)=>t.indexOf(e)>=i)}getTreeDepth(){return this._isDivided?1+Math.max(this.topLeft.getTreeDepth(),this.topRight.getTreeDepth(),this.bottomLeft.getTreeDepth(),this.bottomRight.getTreeDepth()):0}debug(t){this.bounds.draw(t,tH.Yellow),this._isDivided&&(this.topLeft.bounds.draw(t,tH.Yellow),this.topRight.bounds.draw(t,tH.Yellow),this.bottomLeft.bounds.draw(t,tH.Yellow),this.bottomRight.bounds.draw(t,tH.Yellow))}}function nc(t){return!!t._initialize}function nu(t){return!!t.onInitialize}function np(t){return!!t._preupdate}function ng(t){return!!t.onPreUpdate}function n_(t){return!!t.onPostUpdate}function nf(t){return!!t.onPostUpdate}function nm(t){return!!t.onPreDraw}function nv(t){return!!t.onPostDraw}class ny{constructor(t,e=tH.Magenta,i=!1){this.path=t,this.color=e,this._stream=null,this._gif=null,this._textures=[],this._animation=null,this._transparentColor=null,this._resource=new t9(t,"arraybuffer",i),this._transparentColor=e}get bustCache(){return this._resource.bustCache}set bustCache(t){this._resource.bustCache=t}async load(){let t=await this._resource.load();this._stream=new nb(t),this._gif=new nT(this._stream,this._transparentColor);let e=this._gif.images.map(t=>new es(t.src,!1));return await Promise.all(e.map(t=>t.load())),this.data=this._textures=e}isLoaded(){return!!this.data}toSprite(t=0){return this._textures[t].toSprite()}toSpriteSheet(){return new en({sprites:this._textures.map(t=>t.toSprite())})}toAnimation(t){let e=this.toSpriteSheet(),i=e.sprites.length;return this._animation=rv.fromSpriteSheet(e,tz(0,i),t),this._animation}get readCheckBytes(){return this._gif.checkBytes}}let nx=t=>t.reduce(function(t,e){return 2*t+e},0),nw=t=>{let e=[];for(let i=7;i>=0;i--)e.push(!!(t&1<{if(this.position>=this.data.byteLength)throw Error("Attempted to read past end of stream.");return this.data[this.position++]},this.readBytes=t=>{let e=[];for(let i=0;i{let e="";for(let i=0;i{let t=this.readBytes(2);return(t[1]<<8)+t[0]},this.data=new Uint8Array(t),this.len=this.data.byteLength,0===this.len)throw Error("No data loaded from file")}}let nC=function(t,e){let i,s,r=0,n=[],o=1<>3)&1<<(7&r)&&(i|=1<{let e=[];for(let i=0;i{let e=t.toString(16);return 1===e.length?"0"+e:e}).join("");e.push(t)}return e},this.readSubBlocks=()=>{let t,e;e="";do t=this._st.readByte(),e+=this._st.read(t);while(0!==t)return e},this.parseHeader=()=>{let t={sig:null,ver:null,width:null,height:null,colorRes:null,globalColorTableSize:null,gctFlag:null,sorted:null,globalColorTable:[],bgColor:null,pixelAspectRatio:null};if(t.sig=this._st.read(3),t.ver=this._st.read(3),"GIF"!==t.sig)throw Error("Not a GIF file.");t.width=this._st.readUnsigned(),t.height=this._st.readUnsigned();let e=nw(this._st.readByte());t.gctFlag=e.shift(),t.colorRes=nx(e.splice(0,3)),t.sorted=e.shift(),t.globalColorTableSize=nx(e.splice(0,3)),t.bgColor=this._st.readByte(),t.pixelAspectRatio=this._st.readByte(),t.gctFlag&&(t.globalColorTable=this.parseColorTable(1<{switch(t.label=this._st.readByte(),t.label){case 249:t.extType="gce",(t=>{this.checkBytes.push(this._st.readByte());let e=nw(this._st.readByte());t.reserved=e.splice(0,3),t.disposalMethod=nx(e.splice(0,3)),t.userInput=e.shift(),t.transparencyGiven=e.shift(),t.delayTime=this._st.readUnsigned(),t.transparencyIndex=this._st.readByte(),t.terminator=this._st.readByte(),this._handler.gce&&this._handler.gce(t)&&this.checkBytes.push(this._handler.gce)})(t);break;case 254:t.extType="com",(t=>{t.comment=this.readSubBlocks(),this._handler.com&&this._handler.com(t)&&this.checkBytes.push(this._handler.com)})(t);break;case 1:t.extType="pte",(t=>{this.checkBytes.push(this._st.readByte()),t.ptHeader=this._st.readBytes(12),t.ptData=this.readSubBlocks(),this._handler.pte&&this._handler.pte(t)&&this.checkBytes.push(this._handler.pte)})(t);break;case 255:t.extType="app",(t=>{(this.checkBytes.push(this._st.readByte()),t.identifier=this._st.read(8),t.authCode=this._st.read(3),"NETSCAPE"===t.identifier)?(t=>{this.checkBytes.push(this._st.readByte()),t.unknown=this._st.readByte(),t.iterations=this._st.readUnsigned(),t.terminator=this._st.readByte(),this._handler.app&&this._handler.app.NETSCAPE&&this._handler.app.NETSCAPE(t)&&this.checkBytes.push(this._handler.app)})(t):(t=>{t.appData=this.readSubBlocks(),this._handler.app&&this._handler.app[t.identifier]&&this._handler.app[t.identifier](t)&&this.checkBytes.push(this._handler.app[t.identifier])})(t)})(t);break;default:t.extType="unknown",(t=>{t.data=this.readSubBlocks(),this._handler.unknown&&this._handler.unknown(t)&&this.checkBytes.push(this._handler.unknown)})(t)}},this.parseImg=t=>{t.leftPos=this._st.readUnsigned(),t.topPos=this._st.readUnsigned(),t.width=this._st.readUnsigned(),t.height=this._st.readUnsigned();let e=nw(this._st.readByte());t.lctFlag=e.shift(),t.interlaced=e.shift(),t.sorted=e.shift(),t.reserved=e.splice(0,2),t.lctSize=nx(e.splice(0,3)),t.lctFlag&&(t.lct=this.parseColorTable(1<{let i=Array(t.length),s=t.length/e,r=(s,r)=>{let n=t.slice(r*e,(r+1)*e);i.splice.apply(i,[s*e,e].concat(n))},n=[0,4,2,1],o=[8,8,4,2],a=0;for(let t=0;t<4;t++)for(let e=n[t];e{let t={sentinel:this._st.readByte(),type:""};switch(String.fromCharCode(t.sentinel)){case"!":t.type="ext",this.parseExt(t);break;case",":t.type="img",this.parseImg(t);break;case";":t.type="eof",this._handler.eof&&this._handler.eof(t)&&this.checkBytes.push(this._handler.eof);break;default:throw Error("Unknown block: 0x"+t.sentinel.toString(16))}"eof"!==t.type&&this.parseBlock()},this.arrayToImage=t=>{let e=0,i=document.createElement("canvas");i.id=e.toString(),i.width=t.width,i.height=t.height,e++;let s=i.getContext("2d"),r=0,n=0;for(let e=0;e{let r=e(),n=e=>{try{let{done:s,value:o}=r.next(e);s&&i(),o instanceof Promise?o.then(()=>{t.clock.schedule(n)}):void 0===o||void 0===o?t.clock.schedule(n):t.clock.schedule(n,o||0)}catch(t){s(t)}};n(t.clock.elapsed())})}class nE extends s_{get progress(){return this._currentProgress}get complete(){return"out"===this.direction?this.progress>=1:this.progress<=0}constructor(t){var e,i,s,r;super(),this._logger=tW.getInstance(),this.transform=new iV,this.graphics=new sm,this._completeFuture=new tE,this.started=!1,this._currentDistance=0,this._currentProgress=0,this.done=this._completeFuture.promise,this.name=`Transition#${this.id}`,this.duration=t.duration,this.easing=null!==(e=t.easing)&&void 0!==e?e:sw.Linear,this.direction=null!==(i=t.direction)&&void 0!==i?i:"out",this.hideLoader=null!==(s=t.hideLoader)&&void 0!==s&&s,this.blockInput=null!==(r=t.blockInput)&&void 0!==r&&r,this.transform.coordPlane=j.Screen,this.transform.pos=tN.Zero,this.transform.z=1/0,this.graphics.anchor=tN.Zero,this.addComponent(this.transform),this.addComponent(this.graphics),"out"===this.direction?this._currentProgress=0:this._currentProgress=1}updateTransition(t,e){this.complete||(this._currentDistance+=tF(e/this.duration,0,1),this._currentDistance>=1&&(this._currentDistance=1),"out"===this.direction?this._currentProgress=tF(this.easing(this._currentDistance,0,1,1),0,1):this._currentProgress=tF(this.easing(this._currentDistance,1,0,1),0,1))}async onPreviousSceneDeactivate(t){}onStart(t){}onUpdate(t){}onEnd(t){}onReset(){}reset(){this.started=!1,this._completeFuture=new tE,this.done=this._completeFuture.promise,this._currentDistance=0,"out"===this.direction?this._currentProgress=0:this._currentProgress=1,this.onReset()}play(t){if(this.started)return this._logger.warn(`Attempted to play a transition ${this.name} that is already playing`),Promise.resolve();t.add(this);let e=this;return nA(t,function*(){for(;!e.complete;){let i=yield;e.updateTransition(t,i),e.execute()}})}execute(){this.isInitialized&&(this.started||(this.started=!0,this.onStart(this.progress)),this.onUpdate(this.progress),this.complete&&!this._completeFuture.isCompleted&&(this.onEnd(this.progress),this._completeFuture.resolve()))}}class nP extends nE{constructor(t){var e,i;super({...t,duration:null!==(e=t.duration)&&void 0!==e?e:2e3}),this.name=`FadeInOut#${this.id}`,this.color=null!==(i=t.color)&&void 0!==i?i:tH.Black}onInitialize(t){let e=t.screen.getWorldBounds();this.transform.pos=tZ(e.left,e.top),this.screenCover=new sv({width:e.width,height:e.height,color:this.color}),this.graphics.add(this.screenCover),this.graphics.opacity=this.progress}onReset(){this.graphics.opacity=this.progress}onStart(t){this.graphics.opacity=t}onEnd(t){this.graphics.opacity=t}onUpdate(t){this.graphics.opacity=t}}class nI extends nE{constructor(t){super({direction:"in",...t}),this.name=`CrossFade#${this.id}`}async onPreviousSceneDeactivate(t){this.image=await t.engine.screenshot(!0),await this.image.decode()}onInitialize(t){this.engine=t;let e=t.screen.getWorldBounds();this.transform.pos=tZ(e.left,e.top),this.screenCover=es.fromHtmlImageElement(this.image).toSprite(),this.graphics.add(this.screenCover),this.transform.scale=tZ(1/t.screen.pixelRatio,1/t.screen.pixelRatio),this.graphics.opacity=this.progress}onStart(t){this.graphics.opacity=this.progress}onReset(){this.graphics.opacity=this.progress}onEnd(t){this.graphics.opacity=t}onUpdate(t){this.graphics.opacity=t}}class nk extends et{constructor(t){super(),this.color=tH.Black,this.thickness=1;let{start:e,end:i,color:s,thickness:r}=t;this.start=e,this.end=i,this.color=null!=s?s:this.color,this.thickness=null!=r?r:this.thickness,this._localBounds=this._calculateBounds();let{width:n,height:o}=this._localBounds;this.width=n,this.height=o}get localBounds(){return this._localBounds}_calculateBounds(){let t=this.end.sub(this.start).normal(),e=this.thickness/2,i=[this.start.add(t.scale(e)),this.end.add(t.scale(e)),this.end.add(t.scale(-e)),this.start.add(t.scale(-e))];return tq.fromPoints(i)}_drawImage(t,e,i){t.drawLine(this.start,this.end,this.color,this.thickness)}clone(){return new nk({start:this.start,end:this.end,color:this.color,thickness:this.thickness})}}class nD extends eO{get points(){return this._points}set points(t){this._points=t;let e=this.minPoint;this.width=this._points.reduce((t,e)=>Math.max(e.x,t),0)-e.x,this.height=this._points.reduce((t,e)=>Math.max(e.y,t),0)-e.y,this.flagDirty()}get minPoint(){return tZ(this._points.reduce((t,e)=>Math.min(e.x,t),1/0),this._points.reduce((t,e)=>Math.min(e.y,t),1/0))}constructor(t){super(t),this.points=t.points,this.filtering=H.Blended,this.rasterize()}clone(){return new nD({points:this.points.map(t=>t.clone()),...this.cloneGraphicOptions(),...this.cloneRasterOptions()})}execute(t){if(this.points&&this.points.length){t.beginPath();let e=this.minPoint.negate(),i=this.points[0].add(e);t.moveTo(i.x,i.y),this.points.forEach(i=>{t.lineTo(i.x+e.x,i.y+e.y)}),t.lineTo(i.x,i.y),t.closePath(),this.color&&t.fill(),this.strokeColor&&t.stroke()}}}let nR=5,nF={},nB=()=>{for(let t in nF)nF[t]=0},nM=(t,e)=>{let i=tS.isEnabled("suppress-obsolete-message");nF[t]{var e={445:(t,e,i)=>{i.r(e),i.d(e,{compare:()=>d,compareVersions:()=>h,satisfies:()=>g,validate:()=>_,validateStrict:()=>f});let s=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i,r=t=>{if("string"!=typeof t)throw TypeError("Invalid argument expected string");let e=t.match(s);if(!e)throw Error(`Invalid argument not valid semver ('${t}' received)`);return e.shift(),e},n=t=>"*"===t||"x"===t||"X"===t,o=t=>{let e=parseInt(t,10);return isNaN(e)?t:e},a=(t,e)=>{let i,s;if(n(t)||n(e))return 0;let[r,a]=typeof(i=o(t))!=typeof(s=o(e))?[String(i),String(s)]:[i,s];return r>a?1:r{for(let i=0;i{let i=r(t),s=r(e),n=i.pop(),o=s.pop(),a=l(i,s);return 0!==a?a:n&&o?l(n.split("."),o.split(".")):n||o?n?-1:1:0},d=(t,e,i)=>{p(i);let s=h(t,e);return c[i].includes(s)},c={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1],"!=":[-1,1]},u=Object.keys(c),p=t=>{if("string"!=typeof t)throw TypeError("Invalid operator type, expected string but got "+typeof t);if(-1===u.indexOf(t))throw Error(`Invalid operator, expected one of ${u.join("|")}`)},g=(t,e)=>{if((e=e.replace(/([><=]+)\s+/g,"$1")).includes("||"))return e.split("||").some(e=>g(t,e));if(e.includes(" - ")){let[i,s]=e.split(" - ",2);return g(t,`>=${i} <=${s}`)}if(e.includes(" "))return e.trim().replace(/\s{2,}/g," ").split(" ").every(e=>g(t,e));let i=e.match(/^([<>=~^]+)/),s=i?i[1]:"=";if("^"!==s&&"~"!==s)return d(t,e,s);let[n,o,a,,h]=r(t),[c,u,p,,_]=r(e),f=[n,o,a],m=[c,null!=u?u:"x",null!=p?p:"x"];if(_&&(!h||0!==l(f,m)||-1===l(h.split("."),_.split("."))))return!1;let v=m.findIndex(t=>"0"!==t)+1,y="~"===s?2:v>1?v:1;return 0===l(f.slice(0,y),m.slice(0,y))&&-1!==l(f.slice(y),m.slice(y))},_=t=>"string"==typeof t&&/^[v\d]/.test(t)&&s.test(t),f=t=>"string"==typeof t&&/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(t)},961:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.EntityLayer=void 0;let s=i(205);e.EntityLayer=class{constructor(t,e,i,r){var n,o;if(this.ldtkLayer=e,this.resource=i,this.order=r,this.entities=[],this.ldtkToEntity=new Map,this.entityToLdtk=new Map,this.worldPos=(0,s.vec)(t.ldtkLevel.worldX,t.ldtkLevel.worldY),this.offset=(0,s.vec)(e.__pxTotalOffsetX,e.__pxTotalOffsetY),e.entityInstances)for(let t of e.entityInstances){let e=i.projectMetadata.defs.entities.find(e=>e.identifier===t.__identifier);if(i.factories.has(t.__identifier)){let r=i.factories.get(t.__identifier);if(r){let i=r({type:t.__identifier,worldPos:(0,s.vec)(t.px[0],t.px[1]).add(this.worldPos.add(this.offset)),entity:t,definition:e,layer:this});i&&(this.entities.push(i),this.ldtkToEntity.set(t,i),this.entityToLdtk.set(i,t))}}else{let a=new s.Actor({name:t.__identifier,pos:(0,s.vec)(t.px[0],t.px[1]).add(this.worldPos.add(this.offset)),width:t.width,height:t.height,anchor:(0,s.vec)(null!==(n=null==e?void 0:e.pivotX)&&void 0!==n?n:0,null!==(o=null==e?void 0:e.pivotY)&&void 0!==o?o:0),z:r});if(t.__tile){let e=i.tilesets.get(t.__tile.tilesetUid);if(e){let i=Math.floor(t.__tile.x/t.__tile.w),s=Math.floor(t.__tile.y/t.__tile.h),r=e.spritesheet.getSprite(i,s);r&&a.graphics.use(r)}}this.entities.push(a),this.ldtkToEntity.set(t,a),this.entityToLdtk.set(a,t)}}}runFactory(t){if(this.resource.factories.has(t)&&this.ldtkLayer.entityInstances)for(let t of this.ldtkLayer.entityInstances){let e=this.resource.projectMetadata.defs.entities.find(e=>e.identifier===t.__identifier),i=this.resource.factories.get(t.__identifier);if(i){let r=i({type:t.__identifier,worldPos:(0,s.vec)(t.px[0],t.px[1]).add(this.worldPos.add(this.offset)),entity:t,definition:e,layer:this});if(r){let e=this.ldtkToEntity.get(t);if(e){let i=this.entities.indexOf(e);i>-1&&(this.entities.splice(i,1),this.ldtkToEntity.delete(t),this.entityToLdtk.delete(e))}return this.entities.push(r),this.ldtkToEntity.set(t,r),this.entityToLdtk.set(r,t),r}}}}getEntitiesByIdentifier(t){let e=this.getLdtkEntitiesByIdentifier(t),i=[];for(let t of e){let e=this.ldtkToEntity.get(t);e&&i.push(e)}return i}getEntitiesByField(t,e){let i=this.getLdtkEntitiesByField(t,e),s=[];for(let t of i){let e=this.ldtkToEntity.get(t);e&&s.push(e)}return s}getLdtkEntitiesByIdentifier(t){return this.ldtkLayer.entityInstances.filter(e=>e.__identifier.toLocaleLowerCase()===t.toLowerCase())}getLdtkEntitiesByField(t,e){return this.ldtkLayer.entityInstances.filter(i=>{if(void 0!==e){let s=e;"string"==typeof e&&(s=e.toLocaleLowerCase());let r=i.fieldInstances.find(e=>e.__identifier.toLocaleLowerCase()===t.toLocaleLowerCase());return!!r&&r.__value===s}return!!i.fieldInstances.find(e=>e.__identifier.toLocaleLowerCase()===t.toLocaleLowerCase())})}}},710:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.FetchLoader=void 0,e.FetchLoader=async(t,e)=>{let i=await fetch(t);switch(e.toLowerCase()){case"xml":default:return await i.text();case"json":return await i.json()}}},607:function(t,e,i){var s=this&&this.__createBinding||(Object.create?function(t,e,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(e,i);r&&!("get"in r?!e.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return e[i]}}),Object.defineProperty(t,s,r)}:function(t,e,i,s){void 0===s&&(s=i),t[s]=e[i]}),r=this&&this.__exportStar||function(t,e){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(e,i)||s(e,t,i)};Object.defineProperty(e,"__esModule",{value:!0}),r(i(398),e),r(i(961),e),r(i(710),e),r(i(920),e),r(i(515),e),r(i(512),e),r(i(289),e),r(i(32),e),r(i(692),e),r(i(245),e),r(i(699),e)},920:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.IntGridLayer=void 0;let s=i(205);e.IntGridLayer=class{constructor(t,e,i,r){if(this.order=r,this.worldPos=(0,s.vec)(t.ldtkLevel.worldX,t.ldtkLevel.worldY),this.offset=(0,s.vec)(e.__pxTotalOffsetX,e.__pxTotalOffsetY),this.ldtkLayer=e,e.intGridCsv.length){let t=e.__cHei,r=e.__cWid;this.tilemap=new s.TileMap({name:e.__identifier,pos:this.worldPos.add(this.offset),tileWidth:e.__gridSize,tileHeight:e.__gridSize,rows:t,columns:r});let n=i.projectMetadata.defs.layers.find(t=>e.__identifier===t.identifier);if(n){let t=n.intGridValues.find(t=>{var e;return"solid"===(null===(e=null==t?void 0:t.identifier)||void 0===e?void 0:e.toLocaleLowerCase())});for(let i=0;i{Object.defineProperty(e,"__esModule",{value:!0}),e.LdtkResource=void 0;let s=i(692),r=i(32),n=i(710),o=i(699),a=i(445),l=i(289),h=i(205),d=i(515),c=i(245),u=i(512),p=i(961),g=i(920);class _{constructor(t,e){this.path=t,this.tilesets=new Map,this.levels=new Map,this.levelsByName=new Map,this.factories=new Map,this.fileLoader=n.FetchLoader,this._imageLoader=new l.LoaderCache(h.ImageSource),this._levelLoader=new l.LoaderCache(d.LevelResource),this.startZIndex=0,this.textQuality=4,this.useExcaliburWiring=!0,this.useMapBackgroundColor=!1,this.useTilemapCameraStrategy=!1,this.headless=!1,this.strict=!0;let{useExcaliburWiring:i,useTilemapCameraStrategy:s,entityIdentifierFactories:r,pathMap:o,useMapBackgroundColor:a,fileLoader:c,strict:u,headless:p,startZIndex:g}={...e};for(let t in this.strict=null!=u?u:this.strict,this.headless=null!=p?p:this.headless,this.useExcaliburWiring=null!=i?i:this.useExcaliburWiring,this.useTilemapCameraStrategy=null!=s?s:this.useTilemapCameraStrategy,this.useMapBackgroundColor=null!=a?a:this.useMapBackgroundColor,this.startZIndex=null!=g?g:this.startZIndex,this.fileLoader=null!=c?c:this.fileLoader,this.pathMap=o,r)this.registerEntityIdentifierFactory(t,r[t])}async load(){var t;let e=await this.fileLoader(this.path,"json");if(this.strict)try{this.projectMetadata=o.LdtkProjectMetadata.parse(e)}catch(t){throw console.error(`Could not parse LDtk map from location ${this.path}. -Excalibur only supports the latest version of LDtk formats as of the plugin's release.`),console.error("Is your map file corrupted or being interpreted as the wrong type?"),t}else this.projectMetadata=e;for(let e of((0,a.compare)(_.supportedLdtkVersion,null!==(t=this.projectMetadata.jsonVersion)&&void 0!==t?t:"0.0.0",">")&&console.warn(`The excalibur ldtk plugin officially supports ${_.supportedLdtkVersion}+, the current map has LDtk version ${this.projectMetadata.jsonVersion}`),this.projectMetadata.defs.tilesets))if(e.relPath){let t=(0,r.pathRelativeToBase)(this.path,e.relPath,this.pathMap),i=this._imageLoader.getOrAdd(t),s=new c.Tileset({image:i,ldtkTileset:e});this.tilesets.set(e.uid,s)}else"Internal_Icons"!==e.identifier&&console.warn(`No tileset image provided for ${e.identifier}`);for(let t of this.projectMetadata.levels)if(t.externalRelPath){let e=(0,r.pathRelativeToBase)(this.path,t.externalRelPath,this.pathMap);this._levelLoader.getOrAdd(e,this,{headless:this.headless,strict:this.strict,fileLoader:this.fileLoader,imageLoader:this._imageLoader,pathMap:this.pathMap})}else{let e=new u.Level(t,this);this.levels.set(t.uid,e),this.levelsByName.set(t.identifier,e)}return await Promise.all([this._imageLoader.load(),this._levelLoader.load()]),this._levelLoader.values().forEach(t=>{this.levels.set(t.data.ldtkLevel.uid,t.data),this.levelsByName.set(t.data.ldtkLevel.identifier,t.data)}),this.data=this.projectMetadata}isLoaded(){return!!this.data}registerEntityIdentifierFactory(t,e){if(this.factories.set(t,e),this.isLoaded())for(let e of this.getEntityLayers())e.runFactory(t)}getLevel(t){return this.levelsByName.get(t)}getEntityLayers(t){let e=[];if(t){let i=this.getLevel(t);if(i)for(let t of i.layers)t instanceof p.EntityLayer&&e.push(t)}else for(let t of this.levels.values())for(let i of t.layers)i instanceof p.EntityLayer&&e.push(i);return e}getTileLayers(t){let e=[];if(t){let i=this.getLevel(t);if(i)for(let t of i.layers)t instanceof s.TileLayer&&e.push(t)}else for(let t of this.levels.values())for(let i of t.layers)i instanceof s.TileLayer&&e.push(i);return e}getIntGridLayers(t){let e=[];if(t){let i=this.getLevel(t);if(i)for(let t of i.layers)t instanceof g.IntGridLayer&&e.push(t)}else for(let t of this.levels.values())for(let i of t.layers)i instanceof g.IntGridLayer&&e.push(i);return e}getLdtkEntitiesByIdentifier(t){let e=[];for(let i of this.getEntityLayers())e=e.concat(i.getLdtkEntitiesByIdentifier(t));return e}getLdtkEntitiesByField(t,e){let i=[];for(let s of this.getEntityLayers())i=i.concat(s.getLdtkEntitiesByField(t,e));return i}addToScene(t,e){var i,r;let{pos:n,useLevelOffsets:o}={pos:(0,h.vec)(0,0),useLevelOffsets:!0,...e};for(let[r,a]of this.levels.entries())if(!(null===(i=null==e?void 0:e.levelFilter)||void 0===i?void 0:i.length)||e.levelFilter.includes(a.ldtkLevel.identifier))for(let e of a.layers)if(e instanceof s.TileLayer||e instanceof g.IntGridLayer)e.tilemap.pos=e.tilemap.pos.add(n),o||(e.tilemap.pos=e.tilemap.pos.sub(e.worldPos)),t.add(e.tilemap);else for(let i of e.entities){let s=i.get(h.TransformComponent);s&&(s.pos=s.pos.add(n),o||(s.pos=s.pos.sub(e.worldPos))),t.add(i)}if(this.useExcaliburWiring){let e=this.getLdtkEntitiesByField("camera",!0)[0];if(e){t.camera.pos=(0,h.vec)(e.px[0],e.px[0]);let i=e.fieldInstances.find(t=>"zoom"===t.__identifier.toLocaleLowerCase());i&&(t.camera.zoom=+i.__value)}}if(this.useTilemapCameraStrategy){let e=new h.BoundingBox;for(let t of this.levels.values()){let i=this.getTileLayers(t.ldtkLevel.identifier)[0];i&&(e=e.combine(h.BoundingBox.fromDimension(i.tilemap.tileWidth*i.tilemap.columns,i.tilemap.tileHeight*i.tilemap.rows,h.Vector.Zero,i.tilemap.pos)))}t.camera.strategy.limitCameraBounds(e)}if(this.useMapBackgroundColor){for(let[i,s]of this.levels.entries())if(!(null===(r=null==e?void 0:e.levelFilter)||void 0===r?void 0:r.length)||e.levelFilter.includes(s.ldtkLevel.identifier)){t.backgroundColor=s.backgroundColor;break}}}}e.LdtkResource=_,_.supportedLdtkVersion="1.5.3"},515:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.LevelResource=void 0;let s=i(205),r=i(289),n=i(710),o=i(512),a=i(699);e.LevelResource=class{constructor(t,e,i){this.path=t,this.resource=e,this.fileLoader=n.FetchLoader,this.strict=!0,this.headless=!1;let{headless:o,strict:a,fileLoader:l,imageLoader:h,pathMap:d}={...i};this.fileLoader=null!=l?l:this.fileLoader,this.strict=null!=a?a:this.strict,this.headless=null!=o?o:this.headless,this.imageLoader=null!=h?h:new r.LoaderCache(s.ImageSource),this.pathMap=null!=d?d:this.pathMap}async load(){let t;let e=await this.fileLoader(this.path,"json");if(this.strict)try{t=a.LdtkLevel.parse(e)}catch(t){throw console.error(`Could not parse LDtk level data at ${this.path} are you sure a level is there and not corrupt?`),t}else t=e;return this.data=new o.Level(t,this.resource)}isLoaded(){return!!this.data}}},512:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Level=void 0;let s=i(205),r=i(961),n=i(920),o=i(692);e.Level=class{constructor(t,e){var i,a,l;if(this.ldtkLevel=t,this.resource=e,this.layers=[],t.__bgColor&&(this.backgroundColor=s.Color.fromHex(t.__bgColor)),t.layerInstances){let s=e.startZIndex;for(let h of t.layerInstances.slice().reverse())0!==(null===(i=h.entityInstances)||void 0===i?void 0:i.length)&&this.layers.push(new r.EntityLayer(this,h,e,s)),0!==(null===(a=h.gridTiles)||void 0===a?void 0:a.length)&&this.layers.push(new o.TileLayer(this,h,e,s)),0!==(null===(l=h.intGridCsv)||void 0===l?void 0:l.length)&&this.layers.push(new n.IntGridLayer(this,h,e,s)),s++}}}},289:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.LoaderCache=void 0,e.LoaderCache=class{constructor(t){this.type=t,this._loaded=!1,this.cache=new Map}getOrAdd(...t){let e=this.cache.get(t.join("+"));return e||(e=new this.type(...t),this.cache.set(t.join("+"),e),e)}values(){if(this._loaded)return Array.from(this.cache.values());throw Error("Read through cache not yet loaded! No values to return!")}async load(){let t=Array.from(this.cache.entries()),e=await Promise.allSettled(t.map(t=>t[1].load())),i=0;for(let s=0;s{function i(t,e){for(let{path:i,output:s}of e)if("string"==typeof i){if(t.includes(i))return s}else{let e=t.match(i);if(e)return s.replace("[match]",e[0])}return t}function s(t,e){if(!e)return!1;for(let{path:i,output:s}of e)if("string"==typeof i){if(t.includes(i))return!0}else if(t.match(i))return!0;return!1}Object.defineProperty(e,"__esModule",{value:!0}),e.pathRelativeToBase=e.pathInMap=e.mapPath=e.filenameFromPath=void 0,e.filenameFromPath=function(t){let e=t.match(/[^/\\&\?]+\.\w{2,4}(?=([\#\?&].*$|$))/gi);if(e)return e[0];throw Error(`Could not locate filename from path: ${t}`)},e.mapPath=i,e.pathInMap=s,e.pathRelativeToBase=function(t,e,r){if(s(e,r)&&r)return i(e,r);if(0===e.indexOf("/"))return e;let n=t.split("/"),o=e.split("/");return n[n.length-1].includes(".")&&n.pop(),n.concat(o).join("/")}},692:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.TileLayer=void 0;let s=i(205);e.TileLayer=class{constructor(t,e,i,r){for(let n of(this.order=r,this.worldPos=(0,s.vec)(t.ldtkLevel.worldX,t.ldtkLevel.worldY),this.offset=(0,s.vec)(e.__pxTotalOffsetX,e.__pxTotalOffsetY),this.ldtkLayer=e,this.tilemap=new s.TileMap({name:e.__identifier,pos:this.worldPos.add(this.offset),tileWidth:e.__gridSize,tileHeight:e.__gridSize,rows:e.__cHei,columns:e.__cWid}),this.tilemap.z=r,e.gridTiles)){let t=Math.floor(n.px[0]/e.__gridSize),s=Math.floor(n.px[1]/e.__gridSize),r=this.tilemap.getTile(t,s);if(e.__tilesetDefUid){let t=i.tilesets.get(e.__tilesetDefUid);if(t){let e=Math.floor(n.src[0]/t.ldtkTileset.tileGridSize),i=Math.floor(n.src[1]/t.ldtkTileset.tileGridSize),s=t.spritesheet.getSprite(e,i);s?r.addGraphic(s):console.error("Could not find sprite in LDtk spritesheet at",e,i)}}else console.error("Could not tileset in LDtk",e.__tilesetDefUid,e.__tilesetRelPath)}}}},245:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Tileset=void 0;let s=i(205);e.Tileset=class{constructor(t){let{image:e,ldtkTileset:i}=t;this.image=e,this.ldtkTileset=i,this.spritesheet=s.SpriteSheet.fromImageSource({image:e,grid:{rows:i.pxHei/i.tileGridSize,columns:i.pxWid/i.tileGridSize,spriteHeight:i.tileGridSize,spriteWidth:i.tileGridSize}})}}},699:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.LdtkProjectMetadata=e.LdtkEntityDefinition=e.LdtkLayerDefinition=e.LdtkLevel=e.LdtkLayerInstance=e.LdtkEntityInstance=void 0;let s=i(754),r=s.z.object({h:s.z.number(),tilesetUid:s.z.number(),w:s.z.number(),x:s.z.number(),y:s.z.number()}),n=s.z.tuple([s.z.number(),s.z.number()]),o=s.z.object({__identifier:s.z.string(),__tile:r.nullable(),__type:s.z.string(),__value:s.z.any(),defUid:s.z.number()}),a=s.z.object({a:s.z.number(),f:s.z.number(),px:n,src:n,t:s.z.number()});e.LdtkEntityInstance=s.z.object({__grid:n,__identifier:s.z.string(),__pivot:n,__smartColor:s.z.string(),__tags:s.z.array(s.z.string()),__tile:r.nullable(),__worldX:s.z.number().nullable(),__worldY:s.z.number().nullable(),defUid:s.z.number(),fieldInstances:s.z.array(o),height:s.z.number(),iid:s.z.string(),px:n,width:s.z.number()}),e.LdtkLayerInstance=s.z.object({__cHei:s.z.number(),__cWid:s.z.number(),__gridSize:s.z.number(),__identifier:s.z.string(),__opacity:s.z.number(),__pxTotalOffsetX:s.z.number(),__pxTotalOffsetY:s.z.number(),__tilesetDefUid:s.z.number().nullable(),__tilesetRelPath:s.z.string().nullable(),__type:s.z.union([s.z.literal("IntGrid"),s.z.literal("Entities"),s.z.literal("Tiles"),s.z.literal("AutoLayer")]),autoLayerTiles:s.z.array(a),entityInstances:s.z.array(e.LdtkEntityInstance),gridTiles:s.z.array(a),iid:s.z.string(),intGridCsv:s.z.array(s.z.number()),layerDefUid:s.z.number(),levelId:s.z.number(),overrideTilesetUid:s.z.number().nullable(),pxOffsetX:s.z.number(),pxOffsetY:s.z.number(),visible:s.z.boolean()}),e.LdtkLevel=s.z.object({__bgColor:s.z.string().nullable(),bgColor:s.z.string().nullable(),__bgPos:s.z.object({cropRect:s.z.array(s.z.tuple([s.z.number(),s.z.number(),s.z.number(),s.z.number()])),scale:s.z.tuple([s.z.number(),s.z.number()]),topLeftPx:n}).nullable(),__neighbours:s.z.array(s.z.object({dir:s.z.union([s.z.literal("n"),s.z.literal("s"),s.z.literal("w"),s.z.literal("e"),s.z.literal("ne"),s.z.literal("nw"),s.z.literal("se"),s.z.literal("sw"),s.z.literal("o"),s.z.literal("<"),s.z.literal(">")]),levelIid:s.z.string()})),bgRelPath:s.z.string().nullable(),externalRelPath:s.z.string().nullable(),fieldInstances:s.z.array(o),identifier:s.z.string(),iid:s.z.string(),layerInstances:s.z.array(e.LdtkLayerInstance).nullable(),pxHei:s.z.number(),pxWid:s.z.number(),uid:s.z.number(),worldDepth:s.z.number(),worldX:s.z.number(),worldY:s.z.number()});let l=s.z.object({identifier:s.z.string(),iid:s.z.string(),levels:s.z.array(e.LdtkLevel),worldGridHeight:s.z.number(),worldGridWidth:s.z.number(),worldLayout:s.z.union([s.z.literal("Free"),s.z.literal("GridVania"),s.z.literal("LinearHorizontal"),s.z.literal("LinearVertical")])}),h=s.z.object({color:s.z.number(),id:s.z.string(),tileRect:r.nullable()}),d=s.z.object({externalRelPath:s.z.string().nullable(),iconTilesetUid:s.z.number().nullable(),identifier:s.z.string(),tags:s.z.array(s.z.string()),uid:s.z.number(),values:s.z.array(h)}),c=s.z.object({__cHei:s.z.number(),__cWid:s.z.number(),customData:s.z.array(s.z.object({data:s.z.string(),tileId:s.z.number()})),embedAtlas:s.z.string().nullable(),enumsTags:s.z.optional(s.z.array(s.z.object({enumValueId:s.z.string(),tileIds:s.z.array(s.z.number())}))),identifier:s.z.string(),padding:s.z.number(),pxHei:s.z.number(),pxWid:s.z.number(),relPath:s.z.string().nullable(),spacing:s.z.number(),tags:s.z.array(s.z.string()),tagsSourceEnumUid:s.z.number().nullable(),tileGridSize:s.z.number(),uid:s.z.number()});e.LdtkLayerDefinition=s.z.object({__type:s.z.union([s.z.literal("IntGrid"),s.z.literal("Entities"),s.z.literal("Tiles"),s.z.literal("AutoLayer")]),autoSourceLayerDefUid:s.z.number().nullable(),displayOpacity:s.z.number(),gridSize:s.z.number(),identifier:s.z.string(),intGridValues:s.z.array(s.z.object({color:s.z.string(),groupUid:s.z.number(),identifier:s.z.string().nullable(),tile:r.nullable(),value:s.z.number()})),intGridValuesGroups:s.z.array(s.z.object({color:s.z.string().nullable(),identifier:s.z.string().nullable(),uid:s.z.number()})),parallaxFactorX:s.z.number(),parallaxFactorY:s.z.number(),parallaxScaling:s.z.boolean(),pxOffsetX:s.z.number(),pxOffsetY:s.z.number(),tilesetDefUid:s.z.number().nullable(),uid:s.z.number()}),e.LdtkEntityDefinition=s.z.object({color:s.z.string(),height:s.z.number(),identifier:s.z.string(),nineSliceBorders:s.z.array(s.z.number()),pivotX:s.z.number(),pivotY:s.z.number(),tileRect:r.nullable(),tileRenderMode:s.z.union([s.z.literal("Cover"),s.z.literal("FitInside"),s.z.literal("Repeat"),s.z.literal("Stretch"),s.z.literal("FullSizeCropped"),s.z.literal("FullSizeUncropped"),s.z.literal("NineSlice")]),tilesetId:s.z.number().nullable(),uiTileRect:r.nullable(),uid:s.z.number(),width:s.z.number()});let u=s.z.object({tilesets:s.z.array(c),enums:s.z.array(d),layers:s.z.array(e.LdtkLayerDefinition),entities:s.z.array(e.LdtkEntityDefinition)});e.LdtkProjectMetadata=s.z.object({iid:s.z.string(),bgColor:s.z.string().nullable(),defs:u,externalLevels:s.z.boolean(),jsonVersion:s.z.string(),levels:s.z.array(e.LdtkLevel),toc:s.z.array(s.z.object({identifier:s.z.string(),instancesData:s.z.array(s.z.object({fields:s.z.any(),heiPx:s.z.number(),iids:s.z.string(),widPix:s.z.number(),worldX:s.z.number(),worldY:s.z.number()}))})),worldGridHeight:s.z.number().nullable(),worldGridWidth:s.z.number().nullable(),worldLayout:s.z.union([s.z.literal("Free"),s.z.literal("GridVania"),s.z.literal("LinearHorizontal"),s.z.literal("LinearVertical")]).nullable(),worlds:s.z.array(l)})},280:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.ZodError=e.quotelessJson=e.ZodIssueCode=void 0;let s=i(110);e.ZodIssueCode=s.util.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]),e.quotelessJson=t=>JSON.stringify(t,null,2).replace(/"([^"]+)":/g,"$1:");class r extends Error{constructor(t){super(),this.issues=[],this.addIssue=t=>{this.issues=[...this.issues,t]},this.addIssues=(t=[])=>{this.issues=[...this.issues,...t]};let e=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,e):this.__proto__=e,this.name="ZodError",this.issues=t}get errors(){return this.issues}format(t){let e=t||function(t){return t.message},i={_errors:[]},s=t=>{for(let r of t.issues)if("invalid_union"===r.code)r.unionErrors.map(s);else if("invalid_return_type"===r.code)s(r.returnTypeError);else if("invalid_arguments"===r.code)s(r.argumentsError);else if(0===r.path.length)i._errors.push(e(r));else{let t=i,s=0;for(;st.message){let e={},i=[];for(let s of this.issues)s.path.length>0?(e[s.path[0]]=e[s.path[0]]||[],e[s.path[0]].push(t(s))):i.push(t(s));return{formErrors:i,fieldErrors:e}}get formErrors(){return this.flatten()}}e.ZodError=r,r.create=t=>new r(t)},996:function(t,e,i){var s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.getErrorMap=e.setErrorMap=e.defaultErrorMap=void 0;let r=s(i(325));e.defaultErrorMap=r.default;let n=r.default;e.setErrorMap=function(t){n=t},e.getErrorMap=function(){return n}},349:function(t,e,i){var s=this&&this.__createBinding||(Object.create?function(t,e,i,s){void 0===s&&(s=i),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[i]}})}:function(t,e,i,s){void 0===s&&(s=i),t[s]=e[i]}),r=this&&this.__exportStar||function(t,e){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(e,i)||s(e,t,i)};Object.defineProperty(e,"__esModule",{value:!0}),r(i(996),e),r(i(187),e),r(i(116),e),r(i(110),e),r(i(433),e),r(i(280),e)},762:(t,e)=>{var i;Object.defineProperty(e,"__esModule",{value:!0}),e.errorUtil=void 0,(i=e.errorUtil||(e.errorUtil={})).errToObj=t=>"string"==typeof t?{message:t}:t||{},i.toString=t=>"string"==typeof t?t:null==t?void 0:t.message},187:function(t,e,i){var s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.isAsync=e.isValid=e.isDirty=e.isAborted=e.OK=e.DIRTY=e.INVALID=e.ParseStatus=e.addIssueToContext=e.EMPTY_PATH=e.makeIssue=void 0;let r=i(996),n=s(i(325));e.makeIssue=t=>{let{data:e,path:i,errorMaps:s,issueData:r}=t,n=[...i,...r.path||[]],o={...r,path:n},a="";for(let t of s.filter(t=>!!t).slice().reverse())a=t(o,{data:e,defaultError:a}).message;return{...r,path:n,message:r.message||a}},e.EMPTY_PATH=[],e.addIssueToContext=function(t,i){let s=(0,e.makeIssue)({issueData:i,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,(0,r.getErrorMap)(),n.default].filter(t=>!!t)});t.common.issues.push(s)};class o{constructor(){this.value="valid"}dirty(){"valid"===this.value&&(this.value="dirty")}abort(){"aborted"!==this.value&&(this.value="aborted")}static mergeArray(t,i){let s=[];for(let r of i){if("aborted"===r.status)return e.INVALID;"dirty"===r.status&&t.dirty(),s.push(r.value)}return{status:t.value,value:s}}static async mergeObjectAsync(t,e){let i=[];for(let t of e)i.push({key:await t.key,value:await t.value});return o.mergeObjectSync(t,i)}static mergeObjectSync(t,i){let s={};for(let r of i){let{key:i,value:n}=r;if("aborted"===i.status||"aborted"===n.status)return e.INVALID;"dirty"===i.status&&t.dirty(),"dirty"===n.status&&t.dirty(),"__proto__"!==i.value&&(void 0!==n.value||r.alwaysSet)&&(s[i.value]=n.value)}return{status:t.value,value:s}}}e.ParseStatus=o,e.INVALID=Object.freeze({status:"aborted"}),e.DIRTY=t=>({status:"dirty",value:t}),e.OK=t=>({status:"valid",value:t}),e.isAborted=t=>"aborted"===t.status,e.isDirty=t=>"dirty"===t.status,e.isValid=t=>"valid"===t.status,e.isAsync=t=>"undefined"!=typeof Promise&&t instanceof Promise},116:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},110:(t,e)=>{var i,s;Object.defineProperty(e,"__esModule",{value:!0}),e.getParsedType=e.ZodParsedType=e.objectUtil=e.util=void 0,(s=i=e.util||(e.util={})).assertEqual=t=>t,s.assertIs=function(t){},s.assertNever=function(t){throw Error()},s.arrayToEnum=t=>{let e={};for(let i of t)e[i]=i;return e},s.getValidEnumValues=t=>{let e=s.objectKeys(t).filter(e=>"number"!=typeof t[t[e]]),i={};for(let s of e)i[s]=t[s];return s.objectValues(i)},s.objectValues=t=>s.objectKeys(t).map(function(e){return t[e]}),s.objectKeys="function"==typeof Object.keys?t=>Object.keys(t):t=>{let e=[];for(let i in t)Object.prototype.hasOwnProperty.call(t,i)&&e.push(i);return e},s.find=(t,e)=>{for(let i of t)if(e(i))return i},s.isInteger="function"==typeof Number.isInteger?t=>Number.isInteger(t):t=>"number"==typeof t&&isFinite(t)&&Math.floor(t)===t,s.joinValues=function(t,e=" | "){return t.map(t=>"string"==typeof t?`'${t}'`:t).join(e)},s.jsonStringifyReplacer=(t,e)=>"bigint"==typeof e?e.toString():e,(e.objectUtil||(e.objectUtil={})).mergeShapes=(t,e)=>({...t,...e}),e.ZodParsedType=i.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),e.getParsedType=t=>{switch(typeof t){case"undefined":return e.ZodParsedType.undefined;case"string":return e.ZodParsedType.string;case"number":return isNaN(t)?e.ZodParsedType.nan:e.ZodParsedType.number;case"boolean":return e.ZodParsedType.boolean;case"function":return e.ZodParsedType.function;case"bigint":return e.ZodParsedType.bigint;case"symbol":return e.ZodParsedType.symbol;case"object":return Array.isArray(t)?e.ZodParsedType.array:null===t?e.ZodParsedType.null:t.then&&"function"==typeof t.then&&t.catch&&"function"==typeof t.catch?e.ZodParsedType.promise:"undefined"!=typeof Map&&t instanceof Map?e.ZodParsedType.map:"undefined"!=typeof Set&&t instanceof Set?e.ZodParsedType.set:"undefined"!=typeof Date&&t instanceof Date?e.ZodParsedType.date:e.ZodParsedType.object;default:return e.ZodParsedType.unknown}}},754:function(t,e,i){var s=this&&this.__createBinding||(Object.create?function(t,e,i,s){void 0===s&&(s=i),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[i]}})}:function(t,e,i,s){void 0===s&&(s=i),t[s]=e[i]}),r=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),n=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)"default"!==i&&Object.prototype.hasOwnProperty.call(t,i)&&s(e,t,i);return r(e,t),e},o=this&&this.__exportStar||function(t,e){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(e,i)||s(e,t,i)};Object.defineProperty(e,"__esModule",{value:!0}),e.z=void 0;let a=n(i(349));e.z=a,o(i(349),e),e.default=a},325:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});let s=i(110),r=i(280);e.default=(t,e)=>{let i;switch(t.code){case r.ZodIssueCode.invalid_type:i=t.received===s.ZodParsedType.undefined?"Required":`Expected ${t.expected}, received ${t.received}`;break;case r.ZodIssueCode.invalid_literal:i=`Invalid literal value, expected ${JSON.stringify(t.expected,s.util.jsonStringifyReplacer)}`;break;case r.ZodIssueCode.unrecognized_keys:i=`Unrecognized key(s) in object: ${s.util.joinValues(t.keys,", ")}`;break;case r.ZodIssueCode.invalid_union:i="Invalid input";break;case r.ZodIssueCode.invalid_union_discriminator:i=`Invalid discriminator value. Expected ${s.util.joinValues(t.options)}`;break;case r.ZodIssueCode.invalid_enum_value:i=`Invalid enum value. Expected ${s.util.joinValues(t.options)}, received '${t.received}'`;break;case r.ZodIssueCode.invalid_arguments:i="Invalid function arguments";break;case r.ZodIssueCode.invalid_return_type:i="Invalid function return type";break;case r.ZodIssueCode.invalid_date:i="Invalid date";break;case r.ZodIssueCode.invalid_string:"object"==typeof t.validation?"includes"in t.validation?(i=`Invalid input: must include "${t.validation.includes}"`,"number"==typeof t.validation.position&&(i=`${i} at one or more positions greater than or equal to ${t.validation.position}`)):"startsWith"in t.validation?i=`Invalid input: must start with "${t.validation.startsWith}"`:"endsWith"in t.validation?i=`Invalid input: must end with "${t.validation.endsWith}"`:s.util.assertNever(t.validation):i="regex"!==t.validation?`Invalid ${t.validation}`:"Invalid";break;case r.ZodIssueCode.too_small:i="array"===t.type?`Array must contain ${t.exact?"exactly":t.inclusive?"at least":"more than"} ${t.minimum} element(s)`:"string"===t.type?`String must contain ${t.exact?"exactly":t.inclusive?"at least":"over"} ${t.minimum} character(s)`:"number"===t.type?`Number must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${t.minimum}`:"date"===t.type?`Date must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(t.minimum))}`:"Invalid input";break;case r.ZodIssueCode.too_big:i="array"===t.type?`Array must contain ${t.exact?"exactly":t.inclusive?"at most":"less than"} ${t.maximum} element(s)`:"string"===t.type?`String must contain ${t.exact?"exactly":t.inclusive?"at most":"under"} ${t.maximum} character(s)`:"number"===t.type?`Number must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:"bigint"===t.type?`BigInt must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:"date"===t.type?`Date must be ${t.exact?"exactly":t.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(t.maximum))}`:"Invalid input";break;case r.ZodIssueCode.custom:i="Invalid input";break;case r.ZodIssueCode.invalid_intersection_types:i="Intersection results could not be merged";break;case r.ZodIssueCode.not_multiple_of:i=`Number must be a multiple of ${t.multipleOf}`;break;case r.ZodIssueCode.not_finite:i="Number must be finite";break;default:i=e.defaultError,s.util.assertNever(t)}return{message:i}}},433:(t,e,i)=>{var s,r;let n;Object.defineProperty(e,"__esModule",{value:!0}),e.date=e.boolean=e.bigint=e.array=e.any=e.coerce=e.ZodFirstPartyTypeKind=e.late=e.ZodSchema=e.Schema=e.custom=e.ZodReadonly=e.ZodPipeline=e.ZodBranded=e.BRAND=e.ZodNaN=e.ZodCatch=e.ZodDefault=e.ZodNullable=e.ZodOptional=e.ZodTransformer=e.ZodEffects=e.ZodPromise=e.ZodNativeEnum=e.ZodEnum=e.ZodLiteral=e.ZodLazy=e.ZodFunction=e.ZodSet=e.ZodMap=e.ZodRecord=e.ZodTuple=e.ZodIntersection=e.ZodDiscriminatedUnion=e.ZodUnion=e.ZodObject=e.ZodArray=e.ZodVoid=e.ZodNever=e.ZodUnknown=e.ZodAny=e.ZodNull=e.ZodUndefined=e.ZodSymbol=e.ZodDate=e.ZodBoolean=e.ZodBigInt=e.ZodNumber=e.ZodString=e.ZodType=void 0,e.NEVER=e.void=e.unknown=e.union=e.undefined=e.tuple=e.transformer=e.symbol=e.string=e.strictObject=e.set=e.record=e.promise=e.preprocess=e.pipeline=e.ostring=e.optional=e.onumber=e.oboolean=e.object=e.number=e.nullable=e.null=e.never=e.nativeEnum=e.nan=e.map=e.literal=e.lazy=e.intersection=e.instanceof=e.function=e.enum=e.effect=e.discriminatedUnion=void 0;let o=i(996),a=i(762),l=i(187),h=i(110),d=i(280);class c{constructor(t,e,i,s){this._cachedPath=[],this.parent=t,this.data=e,this._path=i,this._key=s}get path(){return this._cachedPath.length||(this._key instanceof Array?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}}let u=(t,e)=>{if((0,l.isValid)(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;let e=new d.ZodError(t.common.issues);return this._error=e,this._error}}};function p(t){if(!t)return{};let{errorMap:e,invalid_type_error:i,required_error:s,description:r}=t;if(e&&(i||s))throw Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.');return e?{errorMap:e,description:r}:{errorMap:(t,e)=>"invalid_type"!==t.code?{message:e.defaultError}:void 0===e.data?{message:null!=s?s:e.defaultError}:{message:null!=i?i:e.defaultError},description:r}}class g{constructor(t){this.spa=this.safeParseAsync,this._def=t,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this)}get description(){return this._def.description}_getType(t){return(0,h.getParsedType)(t.data)}_getOrReturnCtx(t,e){return e||{common:t.parent.common,data:t.data,parsedType:(0,h.getParsedType)(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}_processInputParams(t){return{status:new l.ParseStatus,ctx:{common:t.parent.common,data:t.data,parsedType:(0,h.getParsedType)(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}}_parseSync(t){let e=this._parse(t);if((0,l.isAsync)(e))throw Error("Synchronous parse encountered promise.");return e}_parseAsync(t){return Promise.resolve(this._parse(t))}parse(t,e){let i=this.safeParse(t,e);if(i.success)return i.data;throw i.error}safeParse(t,e){var i;let s={common:{issues:[],async:null!==(i=null==e?void 0:e.async)&&void 0!==i&&i,contextualErrorMap:null==e?void 0:e.errorMap},path:(null==e?void 0:e.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:(0,h.getParsedType)(t)},r=this._parseSync({data:t,path:s.path,parent:s});return u(s,r)}async parseAsync(t,e){let i=await this.safeParseAsync(t,e);if(i.success)return i.data;throw i.error}async safeParseAsync(t,e){let i={common:{issues:[],contextualErrorMap:null==e?void 0:e.errorMap,async:!0},path:(null==e?void 0:e.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:(0,h.getParsedType)(t)},s=this._parse({data:t,path:i.path,parent:i});return u(i,await ((0,l.isAsync)(s)?s:Promise.resolve(s)))}refine(t,e){let i=t=>"string"==typeof e||void 0===e?{message:e}:"function"==typeof e?e(t):e;return this._refinement((e,s)=>{let r=t(e),n=()=>s.addIssue({code:d.ZodIssueCode.custom,...i(e)});return"undefined"!=typeof Promise&&r instanceof Promise?r.then(t=>!!t||(n(),!1)):!!r||(n(),!1)})}refinement(t,e){return this._refinement((i,s)=>!!t(i)||(s.addIssue("function"==typeof e?e(i,s):e),!1))}_refinement(t){return new Y({schema:this,typeName:s.ZodEffects,effect:{type:"refinement",refinement:t}})}superRefine(t){return this._refinement(t)}optional(){return Q.create(this,this._def)}nullable(){return J.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return B.create(this,this._def)}promise(){return K.create(this,this._def)}or(t){return L.create([this,t],this._def)}and(t){return U.create(this,t,this._def)}transform(t){return new Y({...p(this._def),schema:this,typeName:s.ZodEffects,effect:{type:"transform",transform:t}})}default(t){return new tt({...p(this._def),innerType:this,defaultValue:"function"==typeof t?t:()=>t,typeName:s.ZodDefault})}brand(){return new ts({typeName:s.ZodBranded,type:this,...p(this._def)})}catch(t){return new te({...p(this._def),innerType:this,catchValue:"function"==typeof t?t:()=>t,typeName:s.ZodCatch})}describe(t){return new this.constructor({...this._def,description:t})}pipe(t){return tr.create(this,t)}readonly(){return tn.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}}e.ZodType=g,e.Schema=g,e.ZodSchema=g;let _=/^c[^\s-]{8,}$/i,f=/^[a-z][a-z0-9]*$/,m=/^[0-9A-HJKMNP-TV-Z]{26}$/,v=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,y=/^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,x=/^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/,w=/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;class b extends g{_parse(t){var e,i;let s;if(this._def.coerce&&(t.data=String(t.data)),this._getType(t)!==h.ZodParsedType.string){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.string,received:e.parsedType}),l.INVALID}let r=new l.ParseStatus;for(let o of this._def.checks)if("min"===o.kind)t.data.lengtho.value&&(s=this._getOrReturnCtx(t,s),(0,l.addIssueToContext)(s,{code:d.ZodIssueCode.too_big,maximum:o.value,type:"string",inclusive:!0,exact:!1,message:o.message}),r.dirty());else if("length"===o.kind){let e=t.data.length>o.value,i=t.data.lengtht.test(e),{validation:e,code:d.ZodIssueCode.invalid_string,...a.errorUtil.errToObj(i)})}_addCheck(t){return new b({...this._def,checks:[...this._def.checks,t]})}email(t){return this._addCheck({kind:"email",...a.errorUtil.errToObj(t)})}url(t){return this._addCheck({kind:"url",...a.errorUtil.errToObj(t)})}emoji(t){return this._addCheck({kind:"emoji",...a.errorUtil.errToObj(t)})}uuid(t){return this._addCheck({kind:"uuid",...a.errorUtil.errToObj(t)})}cuid(t){return this._addCheck({kind:"cuid",...a.errorUtil.errToObj(t)})}cuid2(t){return this._addCheck({kind:"cuid2",...a.errorUtil.errToObj(t)})}ulid(t){return this._addCheck({kind:"ulid",...a.errorUtil.errToObj(t)})}ip(t){return this._addCheck({kind:"ip",...a.errorUtil.errToObj(t)})}datetime(t){var e;return"string"==typeof t?this._addCheck({kind:"datetime",precision:null,offset:!1,message:t}):this._addCheck({kind:"datetime",precision:void 0===(null==t?void 0:t.precision)?null:null==t?void 0:t.precision,offset:null!==(e=null==t?void 0:t.offset)&&void 0!==e&&e,...a.errorUtil.errToObj(null==t?void 0:t.message)})}regex(t,e){return this._addCheck({kind:"regex",regex:t,...a.errorUtil.errToObj(e)})}includes(t,e){return this._addCheck({kind:"includes",value:t,position:null==e?void 0:e.position,...a.errorUtil.errToObj(null==e?void 0:e.message)})}startsWith(t,e){return this._addCheck({kind:"startsWith",value:t,...a.errorUtil.errToObj(e)})}endsWith(t,e){return this._addCheck({kind:"endsWith",value:t,...a.errorUtil.errToObj(e)})}min(t,e){return this._addCheck({kind:"min",value:t,...a.errorUtil.errToObj(e)})}max(t,e){return this._addCheck({kind:"max",value:t,...a.errorUtil.errToObj(e)})}length(t,e){return this._addCheck({kind:"length",value:t,...a.errorUtil.errToObj(e)})}nonempty(t){return this.min(1,a.errorUtil.errToObj(t))}trim(){return new b({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new b({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new b({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(t=>"datetime"===t.kind)}get isEmail(){return!!this._def.checks.find(t=>"email"===t.kind)}get isURL(){return!!this._def.checks.find(t=>"url"===t.kind)}get isEmoji(){return!!this._def.checks.find(t=>"emoji"===t.kind)}get isUUID(){return!!this._def.checks.find(t=>"uuid"===t.kind)}get isCUID(){return!!this._def.checks.find(t=>"cuid"===t.kind)}get isCUID2(){return!!this._def.checks.find(t=>"cuid2"===t.kind)}get isULID(){return!!this._def.checks.find(t=>"ulid"===t.kind)}get isIP(){return!!this._def.checks.find(t=>"ip"===t.kind)}get minLength(){let t=null;for(let e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxLength(){let t=null;for(let e of this._def.checks)"max"===e.kind&&(null===t||e.value{var e;return new b({checks:[],typeName:s.ZodString,coerce:null!==(e=null==t?void 0:t.coerce)&&void 0!==e&&e,...p(t)})};class C extends g{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){let e;if(this._def.coerce&&(t.data=Number(t.data)),this._getType(t)!==h.ZodParsedType.number){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.number,received:e.parsedType}),l.INVALID}let i=new l.ParseStatus;for(let s of this._def.checks)"int"===s.kind?h.util.isInteger(t.data)||(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:"integer",received:"float",message:s.message}),i.dirty()):"min"===s.kind?(s.inclusive?t.datas.value:t.data>=s.value)&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.too_big,maximum:s.value,type:"number",inclusive:s.inclusive,exact:!1,message:s.message}),i.dirty()):"multipleOf"===s.kind?0!==function(t,e){let i=(t.toString().split(".")[1]||"").length,s=(e.toString().split(".")[1]||"").length,r=i>s?i:s;return parseInt(t.toFixed(r).replace(".",""))%parseInt(e.toFixed(r).replace(".",""))/Math.pow(10,r)}(t.data,s.value)&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.not_multiple_of,multipleOf:s.value,message:s.message}),i.dirty()):"finite"===s.kind?Number.isFinite(t.data)||(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.not_finite,message:s.message}),i.dirty()):h.util.assertNever(s);return{status:i.value,value:t.data}}gte(t,e){return this.setLimit("min",t,!0,a.errorUtil.toString(e))}gt(t,e){return this.setLimit("min",t,!1,a.errorUtil.toString(e))}lte(t,e){return this.setLimit("max",t,!0,a.errorUtil.toString(e))}lt(t,e){return this.setLimit("max",t,!1,a.errorUtil.toString(e))}setLimit(t,e,i,s){return new C({...this._def,checks:[...this._def.checks,{kind:t,value:e,inclusive:i,message:a.errorUtil.toString(s)}]})}_addCheck(t){return new C({...this._def,checks:[...this._def.checks,t]})}int(t){return this._addCheck({kind:"int",message:a.errorUtil.toString(t)})}positive(t){return this._addCheck({kind:"min",value:0,inclusive:!1,message:a.errorUtil.toString(t)})}negative(t){return this._addCheck({kind:"max",value:0,inclusive:!1,message:a.errorUtil.toString(t)})}nonpositive(t){return this._addCheck({kind:"max",value:0,inclusive:!0,message:a.errorUtil.toString(t)})}nonnegative(t){return this._addCheck({kind:"min",value:0,inclusive:!0,message:a.errorUtil.toString(t)})}multipleOf(t,e){return this._addCheck({kind:"multipleOf",value:t,message:a.errorUtil.toString(e)})}finite(t){return this._addCheck({kind:"finite",message:a.errorUtil.toString(t)})}safe(t){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:a.errorUtil.toString(t)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:a.errorUtil.toString(t)})}get minValue(){let t=null;for(let e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxValue(){let t=null;for(let e of this._def.checks)"max"===e.kind&&(null===t||e.value"int"===t.kind||"multipleOf"===t.kind&&h.util.isInteger(t.value))}get isFinite(){let t=null,e=null;for(let i of this._def.checks){if("finite"===i.kind||"int"===i.kind||"multipleOf"===i.kind)return!0;"min"===i.kind?(null===e||i.value>e)&&(e=i.value):"max"===i.kind&&(null===t||i.valuenew C({checks:[],typeName:s.ZodNumber,coerce:(null==t?void 0:t.coerce)||!1,...p(t)});class T extends g{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){let e;if(this._def.coerce&&(t.data=BigInt(t.data)),this._getType(t)!==h.ZodParsedType.bigint){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.bigint,received:e.parsedType}),l.INVALID}let i=new l.ParseStatus;for(let s of this._def.checks)"min"===s.kind?(s.inclusive?t.datas.value:t.data>=s.value)&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.too_big,type:"bigint",maximum:s.value,inclusive:s.inclusive,message:s.message}),i.dirty()):"multipleOf"===s.kind?t.data%s.value!==BigInt(0)&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.not_multiple_of,multipleOf:s.value,message:s.message}),i.dirty()):h.util.assertNever(s);return{status:i.value,value:t.data}}gte(t,e){return this.setLimit("min",t,!0,a.errorUtil.toString(e))}gt(t,e){return this.setLimit("min",t,!1,a.errorUtil.toString(e))}lte(t,e){return this.setLimit("max",t,!0,a.errorUtil.toString(e))}lt(t,e){return this.setLimit("max",t,!1,a.errorUtil.toString(e))}setLimit(t,e,i,s){return new T({...this._def,checks:[...this._def.checks,{kind:t,value:e,inclusive:i,message:a.errorUtil.toString(s)}]})}_addCheck(t){return new T({...this._def,checks:[...this._def.checks,t]})}positive(t){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:a.errorUtil.toString(t)})}negative(t){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:a.errorUtil.toString(t)})}nonpositive(t){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:a.errorUtil.toString(t)})}nonnegative(t){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:a.errorUtil.toString(t)})}multipleOf(t,e){return this._addCheck({kind:"multipleOf",value:t,message:a.errorUtil.toString(e)})}get minValue(){let t=null;for(let e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxValue(){let t=null;for(let e of this._def.checks)"max"===e.kind&&(null===t||e.value{var e;return new T({checks:[],typeName:s.ZodBigInt,coerce:null!==(e=null==t?void 0:t.coerce)&&void 0!==e&&e,...p(t)})};class S extends g{_parse(t){if(this._def.coerce&&(t.data=!!t.data),this._getType(t)!==h.ZodParsedType.boolean){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.boolean,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodBoolean=S,S.create=t=>new S({typeName:s.ZodBoolean,coerce:(null==t?void 0:t.coerce)||!1,...p(t)});class A extends g{_parse(t){let e;if(this._def.coerce&&(t.data=new Date(t.data)),this._getType(t)!==h.ZodParsedType.date){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.date,received:e.parsedType}),l.INVALID}if(isNaN(t.data.getTime())){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_date}),l.INVALID}let i=new l.ParseStatus;for(let s of this._def.checks)"min"===s.kind?t.data.getTime()s.value&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.too_big,message:s.message,inclusive:!0,exact:!1,maximum:s.value,type:"date"}),i.dirty()):h.util.assertNever(s);return{status:i.value,value:new Date(t.data.getTime())}}_addCheck(t){return new A({...this._def,checks:[...this._def.checks,t]})}min(t,e){return this._addCheck({kind:"min",value:t.getTime(),message:a.errorUtil.toString(e)})}max(t,e){return this._addCheck({kind:"max",value:t.getTime(),message:a.errorUtil.toString(e)})}get minDate(){let t=null;for(let e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return null!=t?new Date(t):null}get maxDate(){let t=null;for(let e of this._def.checks)"max"===e.kind&&(null===t||e.valuenew A({checks:[],coerce:(null==t?void 0:t.coerce)||!1,typeName:s.ZodDate,...p(t)});class E extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.symbol){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.symbol,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodSymbol=E,E.create=t=>new E({typeName:s.ZodSymbol,...p(t)});class P extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.undefined){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.undefined,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodUndefined=P,P.create=t=>new P({typeName:s.ZodUndefined,...p(t)});class I extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.null){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.null,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodNull=I,I.create=t=>new I({typeName:s.ZodNull,...p(t)});class k extends g{constructor(){super(...arguments),this._any=!0}_parse(t){return(0,l.OK)(t.data)}}e.ZodAny=k,k.create=t=>new k({typeName:s.ZodAny,...p(t)});class D extends g{constructor(){super(...arguments),this._unknown=!0}_parse(t){return(0,l.OK)(t.data)}}e.ZodUnknown=D,D.create=t=>new D({typeName:s.ZodUnknown,...p(t)});class R extends g{_parse(t){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.never,received:e.parsedType}),l.INVALID}}e.ZodNever=R,R.create=t=>new R({typeName:s.ZodNever,...p(t)});class F extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.undefined){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.void,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodVoid=F,F.create=t=>new F({typeName:s.ZodVoid,...p(t)});class B extends g{_parse(t){let{ctx:e,status:i}=this._processInputParams(t),s=this._def;if(e.parsedType!==h.ZodParsedType.array)return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.array,received:e.parsedType}),l.INVALID;if(null!==s.exactLength){let t=e.data.length>s.exactLength.value,r=e.data.lengths.maxLength.value&&((0,l.addIssueToContext)(e,{code:d.ZodIssueCode.too_big,maximum:s.maxLength.value,type:"array",inclusive:!0,exact:!1,message:s.maxLength.message}),i.dirty()),e.common.async)return Promise.all([...e.data].map((t,i)=>s.type._parseAsync(new c(e,t,e.path,i)))).then(t=>l.ParseStatus.mergeArray(i,t));let r=[...e.data].map((t,i)=>s.type._parseSync(new c(e,t,e.path,i)));return l.ParseStatus.mergeArray(i,r)}get element(){return this._def.type}min(t,e){return new B({...this._def,minLength:{value:t,message:a.errorUtil.toString(e)}})}max(t,e){return new B({...this._def,maxLength:{value:t,message:a.errorUtil.toString(e)}})}length(t,e){return new B({...this._def,exactLength:{value:t,message:a.errorUtil.toString(e)}})}nonempty(t){return this.min(1,t)}}e.ZodArray=B,B.create=(t,e)=>new B({type:t,minLength:null,maxLength:null,exactLength:null,typeName:s.ZodArray,...p(e)});class M extends g{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;let t=this._def.shape(),e=h.util.objectKeys(t);return this._cached={shape:t,keys:e}}_parse(t){if(this._getType(t)!==h.ZodParsedType.object){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.object,received:e.parsedType}),l.INVALID}let{status:e,ctx:i}=this._processInputParams(t),{shape:s,keys:r}=this._getCached(),n=[];if(!(this._def.catchall instanceof R&&"strip"===this._def.unknownKeys))for(let t in i.data)r.includes(t)||n.push(t);let o=[];for(let t of r){let e=s[t],r=i.data[t];o.push({key:{status:"valid",value:t},value:e._parse(new c(i,r,i.path,t)),alwaysSet:t in i.data})}if(this._def.catchall instanceof R){let t=this._def.unknownKeys;if("passthrough"===t)for(let t of n)o.push({key:{status:"valid",value:t},value:{status:"valid",value:i.data[t]}});else if("strict"===t)n.length>0&&((0,l.addIssueToContext)(i,{code:d.ZodIssueCode.unrecognized_keys,keys:n}),e.dirty());else if("strip"!==t)throw Error("Internal ZodObject error: invalid unknownKeys value.")}else{let t=this._def.catchall;for(let e of n){let s=i.data[e];o.push({key:{status:"valid",value:e},value:t._parse(new c(i,s,i.path,e)),alwaysSet:e in i.data})}}return i.common.async?Promise.resolve().then(async()=>{let t=[];for(let e of o){let i=await e.key;t.push({key:i,value:await e.value,alwaysSet:e.alwaysSet})}return t}).then(t=>l.ParseStatus.mergeObjectSync(e,t)):l.ParseStatus.mergeObjectSync(e,o)}get shape(){return this._def.shape()}strict(t){return a.errorUtil.errToObj,new M({...this._def,unknownKeys:"strict",...void 0!==t?{errorMap:(e,i)=>{var s,r,n,o;let l=null!==(n=null===(r=(s=this._def).errorMap)||void 0===r?void 0:r.call(s,e,i).message)&&void 0!==n?n:i.defaultError;return"unrecognized_keys"===e.code?{message:null!==(o=a.errorUtil.errToObj(t).message)&&void 0!==o?o:l}:{message:l}}}:{}})}strip(){return new M({...this._def,unknownKeys:"strip"})}passthrough(){return new M({...this._def,unknownKeys:"passthrough"})}extend(t){return new M({...this._def,shape:()=>({...this._def.shape(),...t})})}merge(t){return new M({unknownKeys:t._def.unknownKeys,catchall:t._def.catchall,shape:()=>({...this._def.shape(),...t._def.shape()}),typeName:s.ZodObject})}setKey(t,e){return this.augment({[t]:e})}catchall(t){return new M({...this._def,catchall:t})}pick(t){let e={};return h.util.objectKeys(t).forEach(i=>{t[i]&&this.shape[i]&&(e[i]=this.shape[i])}),new M({...this._def,shape:()=>e})}omit(t){let e={};return h.util.objectKeys(this.shape).forEach(i=>{t[i]||(e[i]=this.shape[i])}),new M({...this._def,shape:()=>e})}deepPartial(){return function t(e){if(e instanceof M){let i={};for(let s in e.shape){let r=e.shape[s];i[s]=Q.create(t(r))}return new M({...e._def,shape:()=>i})}return e instanceof B?new B({...e._def,type:t(e.element)}):e instanceof Q?Q.create(t(e.unwrap())):e instanceof J?J.create(t(e.unwrap())):e instanceof N?N.create(e.items.map(e=>t(e))):e}(this)}partial(t){let e={};return h.util.objectKeys(this.shape).forEach(i=>{let s=this.shape[i];t&&!t[i]?e[i]=s:e[i]=s.optional()}),new M({...this._def,shape:()=>e})}required(t){let e={};return h.util.objectKeys(this.shape).forEach(i=>{if(t&&!t[i])e[i]=this.shape[i];else{let t=this.shape[i];for(;t instanceof Q;)t=t._def.innerType;e[i]=t}}),new M({...this._def,shape:()=>e})}keyof(){return q(h.util.objectKeys(this.shape))}}e.ZodObject=M,M.create=(t,e)=>new M({shape:()=>t,unknownKeys:"strip",catchall:R.create(),typeName:s.ZodObject,...p(e)}),M.strictCreate=(t,e)=>new M({shape:()=>t,unknownKeys:"strict",catchall:R.create(),typeName:s.ZodObject,...p(e)}),M.lazycreate=(t,e)=>new M({shape:t,unknownKeys:"strip",catchall:R.create(),typeName:s.ZodObject,...p(e)});class L extends g{_parse(t){let{ctx:e}=this._processInputParams(t),i=this._def.options;if(e.common.async)return Promise.all(i.map(async t=>{let i={...e,common:{...e.common,issues:[]},parent:null};return{result:await t._parseAsync({data:e.data,path:e.path,parent:i}),ctx:i}})).then(function(t){for(let e of t)if("valid"===e.result.status)return e.result;for(let i of t)if("dirty"===i.result.status)return e.common.issues.push(...i.ctx.common.issues),i.result;let i=t.map(t=>new d.ZodError(t.ctx.common.issues));return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_union,unionErrors:i}),l.INVALID});{let t;let s=[];for(let r of i){let i={...e,common:{...e.common,issues:[]},parent:null},n=r._parseSync({data:e.data,path:e.path,parent:i});if("valid"===n.status)return n;"dirty"!==n.status||t||(t={result:n,ctx:i}),i.common.issues.length&&s.push(i.common.issues)}if(t)return e.common.issues.push(...t.ctx.common.issues),t.result;let r=s.map(t=>new d.ZodError(t));return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_union,unionErrors:r}),l.INVALID}}get options(){return this._def.options}}e.ZodUnion=L,L.create=(t,e)=>new L({options:t,typeName:s.ZodUnion,...p(e)});let z=t=>t instanceof G?z(t.schema):t instanceof Y?z(t.innerType()):t instanceof j?[t.value]:t instanceof X?t.options:t instanceof $?Object.keys(t.enum):t instanceof tt?z(t._def.innerType):t instanceof P?[void 0]:t instanceof I?[null]:null;class O extends g{_parse(t){let{ctx:e}=this._processInputParams(t);if(e.parsedType!==h.ZodParsedType.object)return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.object,received:e.parsedType}),l.INVALID;let i=this.discriminator,s=e.data[i],r=this.optionsMap.get(s);return r?e.common.async?r._parseAsync({data:e.data,path:e.path,parent:e}):r._parseSync({data:e.data,path:e.path,parent:e}):((0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[i]}),l.INVALID)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(t,e,i){let r=new Map;for(let i of e){let e=z(i.shape[t]);if(!e)throw Error(`A discriminator value for key \`${t}\` could not be extracted from all schema options`);for(let s of e){if(r.has(s))throw Error(`Discriminator property ${String(t)} has duplicate value ${String(s)}`);r.set(s,i)}}return new O({typeName:s.ZodDiscriminatedUnion,discriminator:t,options:e,optionsMap:r,...p(i)})}}e.ZodDiscriminatedUnion=O;class U extends g{_parse(t){let{status:e,ctx:i}=this._processInputParams(t),s=(t,s)=>{if((0,l.isAborted)(t)||(0,l.isAborted)(s))return l.INVALID;let r=function t(e,i){let s=(0,h.getParsedType)(e),r=(0,h.getParsedType)(i);if(e===i)return{valid:!0,data:e};if(s===h.ZodParsedType.object&&r===h.ZodParsedType.object){let s=h.util.objectKeys(i),r=h.util.objectKeys(e).filter(t=>-1!==s.indexOf(t)),n={...e,...i};for(let s of r){let r=t(e[s],i[s]);if(!r.valid)return{valid:!1};n[s]=r.data}return{valid:!0,data:n}}if(s===h.ZodParsedType.array&&r===h.ZodParsedType.array){if(e.length!==i.length)return{valid:!1};let s=[];for(let r=0;rs(t,e)):s(this._def.left._parseSync({data:i.data,path:i.path,parent:i}),this._def.right._parseSync({data:i.data,path:i.path,parent:i}))}}e.ZodIntersection=U,U.create=(t,e,i)=>new U({left:t,right:e,typeName:s.ZodIntersection,...p(i)});class N extends g{_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.parsedType!==h.ZodParsedType.array)return(0,l.addIssueToContext)(i,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.array,received:i.parsedType}),l.INVALID;if(i.data.lengththis._def.items.length&&((0,l.addIssueToContext)(i,{code:d.ZodIssueCode.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),e.dirty());let s=[...i.data].map((t,e)=>{let s=this._def.items[e]||this._def.rest;return s?s._parse(new c(i,t,i.path,e)):null}).filter(t=>!!t);return i.common.async?Promise.all(s).then(t=>l.ParseStatus.mergeArray(e,t)):l.ParseStatus.mergeArray(e,s)}get items(){return this._def.items}rest(t){return new N({...this._def,rest:t})}}e.ZodTuple=N,N.create=(t,e)=>{if(!Array.isArray(t))throw Error("You must pass an array of schemas to z.tuple([ ... ])");return new N({items:t,typeName:s.ZodTuple,rest:null,...p(e)})};class Z extends g{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.parsedType!==h.ZodParsedType.object)return(0,l.addIssueToContext)(i,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.object,received:i.parsedType}),l.INVALID;let s=[],r=this._def.keyType,n=this._def.valueType;for(let t in i.data)s.push({key:r._parse(new c(i,t,i.path,t)),value:n._parse(new c(i,i.data[t],i.path,t))});return i.common.async?l.ParseStatus.mergeObjectAsync(e,s):l.ParseStatus.mergeObjectSync(e,s)}get element(){return this._def.valueType}static create(t,e,i){return new Z(e instanceof g?{keyType:t,valueType:e,typeName:s.ZodRecord,...p(i)}:{keyType:b.create(),valueType:t,typeName:s.ZodRecord,...p(e)})}}e.ZodRecord=Z;class H extends g{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.parsedType!==h.ZodParsedType.map)return(0,l.addIssueToContext)(i,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.map,received:i.parsedType}),l.INVALID;let s=this._def.keyType,r=this._def.valueType,n=[...i.data.entries()].map(([t,e],n)=>({key:s._parse(new c(i,t,i.path,[n,"key"])),value:r._parse(new c(i,e,i.path,[n,"value"]))}));if(i.common.async){let t=new Map;return Promise.resolve().then(async()=>{for(let i of n){let s=await i.key,r=await i.value;if("aborted"===s.status||"aborted"===r.status)return l.INVALID;"dirty"!==s.status&&"dirty"!==r.status||e.dirty(),t.set(s.value,r.value)}return{status:e.value,value:t}})}{let t=new Map;for(let i of n){let s=i.key,r=i.value;if("aborted"===s.status||"aborted"===r.status)return l.INVALID;"dirty"!==s.status&&"dirty"!==r.status||e.dirty(),t.set(s.value,r.value)}return{status:e.value,value:t}}}}e.ZodMap=H,H.create=(t,e,i)=>new H({valueType:e,keyType:t,typeName:s.ZodMap,...p(i)});class V extends g{_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.parsedType!==h.ZodParsedType.set)return(0,l.addIssueToContext)(i,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.set,received:i.parsedType}),l.INVALID;let s=this._def;null!==s.minSize&&i.data.sizes.maxSize.value&&((0,l.addIssueToContext)(i,{code:d.ZodIssueCode.too_big,maximum:s.maxSize.value,type:"set",inclusive:!0,exact:!1,message:s.maxSize.message}),e.dirty());let r=this._def.valueType;function n(t){let i=new Set;for(let s of t){if("aborted"===s.status)return l.INVALID;"dirty"===s.status&&e.dirty(),i.add(s.value)}return{status:e.value,value:i}}let o=[...i.data.values()].map((t,e)=>r._parse(new c(i,t,i.path,e)));return i.common.async?Promise.all(o).then(t=>n(t)):n(o)}min(t,e){return new V({...this._def,minSize:{value:t,message:a.errorUtil.toString(e)}})}max(t,e){return new V({...this._def,maxSize:{value:t,message:a.errorUtil.toString(e)}})}size(t,e){return this.min(t,e).max(t,e)}nonempty(t){return this.min(1,t)}}e.ZodSet=V,V.create=(t,e)=>new V({valueType:t,minSize:null,maxSize:null,typeName:s.ZodSet,...p(e)});class W extends g{constructor(){super(...arguments),this.validate=this.implement}_parse(t){let{ctx:e}=this._processInputParams(t);if(e.parsedType!==h.ZodParsedType.function)return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.function,received:e.parsedType}),l.INVALID;function i(t,i){return(0,l.makeIssue)({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,(0,o.getErrorMap)(),o.defaultErrorMap].filter(t=>!!t),issueData:{code:d.ZodIssueCode.invalid_arguments,argumentsError:i}})}function s(t,i){return(0,l.makeIssue)({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,(0,o.getErrorMap)(),o.defaultErrorMap].filter(t=>!!t),issueData:{code:d.ZodIssueCode.invalid_return_type,returnTypeError:i}})}let r={errorMap:e.common.contextualErrorMap},n=e.data;if(this._def.returns instanceof K){let t=this;return(0,l.OK)(async function(...e){let o=new d.ZodError([]),a=await t._def.args.parseAsync(e,r).catch(t=>{throw o.addIssue(i(e,t)),o}),l=await Reflect.apply(n,this,a);return await t._def.returns._def.type.parseAsync(l,r).catch(t=>{throw o.addIssue(s(l,t)),o})})}{let t=this;return(0,l.OK)(function(...e){let o=t._def.args.safeParse(e,r);if(!o.success)throw new d.ZodError([i(e,o.error)]);let a=Reflect.apply(n,this,o.data),l=t._def.returns.safeParse(a,r);if(!l.success)throw new d.ZodError([s(a,l.error)]);return l.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...t){return new W({...this._def,args:N.create(t).rest(D.create())})}returns(t){return new W({...this._def,returns:t})}implement(t){return this.parse(t)}strictImplement(t){return this.parse(t)}static create(t,e,i){return new W({args:t||N.create([]).rest(D.create()),returns:e||D.create(),typeName:s.ZodFunction,...p(i)})}}e.ZodFunction=W;class G extends g{get schema(){return this._def.getter()}_parse(t){let{ctx:e}=this._processInputParams(t);return this._def.getter()._parse({data:e.data,path:e.path,parent:e})}}e.ZodLazy=G,G.create=(t,e)=>new G({getter:t,typeName:s.ZodLazy,...p(e)});class j extends g{_parse(t){if(t.data!==this._def.value){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{received:e.data,code:d.ZodIssueCode.invalid_literal,expected:this._def.value}),l.INVALID}return{status:"valid",value:t.data}}get value(){return this._def.value}}function q(t,e){return new X({values:t,typeName:s.ZodEnum,...p(e)})}e.ZodLiteral=j,j.create=(t,e)=>new j({value:t,typeName:s.ZodLiteral,...p(e)});class X extends g{_parse(t){if("string"!=typeof t.data){let e=this._getOrReturnCtx(t),i=this._def.values;return(0,l.addIssueToContext)(e,{expected:h.util.joinValues(i),received:e.parsedType,code:d.ZodIssueCode.invalid_type}),l.INVALID}if(-1===this._def.values.indexOf(t.data)){let e=this._getOrReturnCtx(t),i=this._def.values;return(0,l.addIssueToContext)(e,{received:e.data,code:d.ZodIssueCode.invalid_enum_value,options:i}),l.INVALID}return(0,l.OK)(t.data)}get options(){return this._def.values}get enum(){let t={};for(let e of this._def.values)t[e]=e;return t}get Values(){let t={};for(let e of this._def.values)t[e]=e;return t}get Enum(){let t={};for(let e of this._def.values)t[e]=e;return t}extract(t){return X.create(t)}exclude(t){return X.create(this.options.filter(e=>!t.includes(e)))}}e.ZodEnum=X,X.create=q;class $ extends g{_parse(t){let e=h.util.getValidEnumValues(this._def.values),i=this._getOrReturnCtx(t);if(i.parsedType!==h.ZodParsedType.string&&i.parsedType!==h.ZodParsedType.number){let t=h.util.objectValues(e);return(0,l.addIssueToContext)(i,{expected:h.util.joinValues(t),received:i.parsedType,code:d.ZodIssueCode.invalid_type}),l.INVALID}if(-1===e.indexOf(t.data)){let t=h.util.objectValues(e);return(0,l.addIssueToContext)(i,{received:i.data,code:d.ZodIssueCode.invalid_enum_value,options:t}),l.INVALID}return(0,l.OK)(t.data)}get enum(){return this._def.values}}e.ZodNativeEnum=$,$.create=(t,e)=>new $({values:t,typeName:s.ZodNativeEnum,...p(e)});class K extends g{unwrap(){return this._def.type}_parse(t){let{ctx:e}=this._processInputParams(t);if(e.parsedType!==h.ZodParsedType.promise&&!1===e.common.async)return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.promise,received:e.parsedType}),l.INVALID;let i=e.parsedType===h.ZodParsedType.promise?e.data:Promise.resolve(e.data);return(0,l.OK)(i.then(t=>this._def.type.parseAsync(t,{path:e.path,errorMap:e.common.contextualErrorMap})))}}e.ZodPromise=K,K.create=(t,e)=>new K({type:t,typeName:s.ZodPromise,...p(e)});class Y extends g{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===s.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){let{status:e,ctx:i}=this._processInputParams(t),s=this._def.effect||null,r={addIssue:t=>{(0,l.addIssueToContext)(i,t),t.fatal?e.abort():e.dirty()},get path(){return i.path}};if(r.addIssue=r.addIssue.bind(r),"preprocess"===s.type){let t=s.transform(i.data,r);return i.common.issues.length?{status:"dirty",value:i.data}:i.common.async?Promise.resolve(t).then(t=>this._def.schema._parseAsync({data:t,path:i.path,parent:i})):this._def.schema._parseSync({data:t,path:i.path,parent:i})}if("refinement"===s.type){let t=t=>{let e=s.refinement(t,r);if(i.common.async)return Promise.resolve(e);if(e instanceof Promise)throw Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return t};if(!1===i.common.async){let s=this._def.schema._parseSync({data:i.data,path:i.path,parent:i});return"aborted"===s.status?l.INVALID:("dirty"===s.status&&e.dirty(),t(s.value),{status:e.value,value:s.value})}return this._def.schema._parseAsync({data:i.data,path:i.path,parent:i}).then(i=>"aborted"===i.status?l.INVALID:("dirty"===i.status&&e.dirty(),t(i.value).then(()=>({status:e.value,value:i.value}))))}if("transform"===s.type){if(!1===i.common.async){let t=this._def.schema._parseSync({data:i.data,path:i.path,parent:i});if(!(0,l.isValid)(t))return t;let n=s.transform(t.value,r);if(n instanceof Promise)throw Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:e.value,value:n}}return this._def.schema._parseAsync({data:i.data,path:i.path,parent:i}).then(t=>(0,l.isValid)(t)?Promise.resolve(s.transform(t.value,r)).then(t=>({status:e.value,value:t})):t)}h.util.assertNever(s)}}e.ZodEffects=Y,e.ZodTransformer=Y,Y.create=(t,e,i)=>new Y({schema:t,typeName:s.ZodEffects,effect:e,...p(i)}),Y.createWithPreprocess=(t,e,i)=>new Y({schema:e,effect:{type:"preprocess",transform:t},typeName:s.ZodEffects,...p(i)});class Q extends g{_parse(t){return this._getType(t)===h.ZodParsedType.undefined?(0,l.OK)(void 0):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}}e.ZodOptional=Q,Q.create=(t,e)=>new Q({innerType:t,typeName:s.ZodOptional,...p(e)});class J extends g{_parse(t){return this._getType(t)===h.ZodParsedType.null?(0,l.OK)(null):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}}e.ZodNullable=J,J.create=(t,e)=>new J({innerType:t,typeName:s.ZodNullable,...p(e)});class tt extends g{_parse(t){let{ctx:e}=this._processInputParams(t),i=e.data;return e.parsedType===h.ZodParsedType.undefined&&(i=this._def.defaultValue()),this._def.innerType._parse({data:i,path:e.path,parent:e})}removeDefault(){return this._def.innerType}}e.ZodDefault=tt,tt.create=(t,e)=>new tt({innerType:t,typeName:s.ZodDefault,defaultValue:"function"==typeof e.default?e.default:()=>e.default,...p(e)});class te extends g{_parse(t){let{ctx:e}=this._processInputParams(t),i={...e,common:{...e.common,issues:[]}},s=this._def.innerType._parse({data:i.data,path:i.path,parent:{...i}});return(0,l.isAsync)(s)?s.then(t=>({status:"valid",value:"valid"===t.status?t.value:this._def.catchValue({get error(){return new d.ZodError(i.common.issues)},input:i.data})})):{status:"valid",value:"valid"===s.status?s.value:this._def.catchValue({get error(){return new d.ZodError(i.common.issues)},input:i.data})}}removeCatch(){return this._def.innerType}}e.ZodCatch=te,te.create=(t,e)=>new te({innerType:t,typeName:s.ZodCatch,catchValue:"function"==typeof e.catch?e.catch:()=>e.catch,...p(e)});class ti extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.nan){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.nan,received:e.parsedType}),l.INVALID}return{status:"valid",value:t.data}}}e.ZodNaN=ti,ti.create=t=>new ti({typeName:s.ZodNaN,...p(t)}),e.BRAND=Symbol("zod_brand");class ts extends g{_parse(t){let{ctx:e}=this._processInputParams(t),i=e.data;return this._def.type._parse({data:i,path:e.path,parent:e})}unwrap(){return this._def.type}}e.ZodBranded=ts;class tr extends g{_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.common.async)return(async()=>{let t=await this._def.in._parseAsync({data:i.data,path:i.path,parent:i});return"aborted"===t.status?l.INVALID:"dirty"===t.status?(e.dirty(),(0,l.DIRTY)(t.value)):this._def.out._parseAsync({data:t.value,path:i.path,parent:i})})();{let t=this._def.in._parseSync({data:i.data,path:i.path,parent:i});return"aborted"===t.status?l.INVALID:"dirty"===t.status?(e.dirty(),{status:"dirty",value:t.value}):this._def.out._parseSync({data:t.value,path:i.path,parent:i})}}static create(t,e){return new tr({in:t,out:e,typeName:s.ZodPipeline})}}e.ZodPipeline=tr;class tn extends g{_parse(t){let e=this._def.innerType._parse(t);return(0,l.isValid)(e)&&(e.value=Object.freeze(e.value)),e}}e.ZodReadonly=tn,tn.create=(t,e)=>new tn({innerType:t,typeName:s.ZodReadonly,...p(e)}),e.custom=(t,e={},i)=>t?k.create().superRefine((s,r)=>{var n,o;if(!t(s)){let t="function"==typeof e?e(s):"string"==typeof e?{message:e}:e,a=null===(o=null!==(n=t.fatal)&&void 0!==n?n:i)||void 0===o||o;r.addIssue({code:"custom",..."string"==typeof t?{message:t}:t,fatal:a})}}):k.create(),e.late={object:M.lazycreate},(r=s=e.ZodFirstPartyTypeKind||(e.ZodFirstPartyTypeKind={})).ZodString="ZodString",r.ZodNumber="ZodNumber",r.ZodNaN="ZodNaN",r.ZodBigInt="ZodBigInt",r.ZodBoolean="ZodBoolean",r.ZodDate="ZodDate",r.ZodSymbol="ZodSymbol",r.ZodUndefined="ZodUndefined",r.ZodNull="ZodNull",r.ZodAny="ZodAny",r.ZodUnknown="ZodUnknown",r.ZodNever="ZodNever",r.ZodVoid="ZodVoid",r.ZodArray="ZodArray",r.ZodObject="ZodObject",r.ZodUnion="ZodUnion",r.ZodDiscriminatedUnion="ZodDiscriminatedUnion",r.ZodIntersection="ZodIntersection",r.ZodTuple="ZodTuple",r.ZodRecord="ZodRecord",r.ZodMap="ZodMap",r.ZodSet="ZodSet",r.ZodFunction="ZodFunction",r.ZodLazy="ZodLazy",r.ZodLiteral="ZodLiteral",r.ZodEnum="ZodEnum",r.ZodEffects="ZodEffects",r.ZodNativeEnum="ZodNativeEnum",r.ZodOptional="ZodOptional",r.ZodNullable="ZodNullable",r.ZodDefault="ZodDefault",r.ZodCatch="ZodCatch",r.ZodPromise="ZodPromise",r.ZodBranded="ZodBranded",r.ZodPipeline="ZodPipeline",r.ZodReadonly="ZodReadonly",e.instanceof=(t,i={message:`Input not instance of ${t.name}`})=>(0,e.custom)(e=>e instanceof t,i);let to=b.create;e.string=to;let ta=C.create;e.number=ta;let tl=ti.create;e.nan=tl;let th=T.create;e.bigint=th;let td=S.create;e.boolean=td;let tc=A.create;e.date=tc;let tu=E.create;e.symbol=tu;let tp=P.create;e.undefined=tp;let tg=I.create;e.null=tg;let t_=k.create;e.any=t_;let tf=D.create;e.unknown=tf;let tm=R.create;e.never=tm;let tv=F.create;e.void=tv;let ty=B.create;e.array=ty;let tx=M.create;e.object=tx;let tw=M.strictCreate;e.strictObject=tw;let tb=L.create;e.union=tb;let tC=O.create;e.discriminatedUnion=tC;let tT=U.create;e.intersection=tT;let tS=N.create;e.tuple=tS;let tA=Z.create;e.record=tA;let tE=H.create;e.map=tE;let tP=V.create;e.set=tP;let tI=W.create;e.function=tI;let tk=G.create;e.lazy=tk;let tD=j.create;e.literal=tD;let tR=X.create;e.enum=tR;let tF=$.create;e.nativeEnum=tF;let tB=K.create;e.promise=tB;let tM=Y.create;e.effect=tM,e.transformer=tM;let tL=Q.create;e.optional=tL;let tz=J.create;e.nullable=tz;let tO=Y.createWithPreprocess;e.preprocess=tO;let tU=tr.create;e.pipeline=tU,e.ostring=()=>to().optional(),e.onumber=()=>ta().optional(),e.oboolean=()=>td().optional(),e.coerce={string:t=>b.create({...t,coerce:!0}),number:t=>C.create({...t,coerce:!0}),boolean:t=>S.create({...t,coerce:!0}),bigint:t=>T.create({...t,coerce:!0}),date:t=>A.create({...t,coerce:!0})},e.NEVER=l.INVALID},205:e=>{e.exports=t}},i={};function s(t){var r=i[t];if(void 0!==r)return r.exports;var n=i[t]={exports:{}};return e[t].call(n.exports,n,n.exports,s),n.exports}return s.d=(t,e)=>{for(var i in e)s.o(e,i)&&!s.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s(607)})();var h={};h=new URL("Hero 01.0a89e3b5.png",import.meta.url).toString();var d={};d=new URL("Solaria Demo Update 01.c847244e.png",import.meta.url).toString();var c={};c=new URL("Level_0.076f9bf4.ldtkl",import.meta.url).toString();var u={};u=new URL("Level_1.fb97a422.ldtkl",import.meta.url).toString();var p={};p=new URL("top-down.8a075006.ldtk",import.meta.url).toString();const g={HeroSpriteSheetPng:new a.ImageSource(i(h),!1,a.ImageFiltering.Pixel),LdtkResource:new l.LdtkResource(i(p),{useTilemapCameraStrategy:!0,useMapBackgroundColor:!0,pathMap:[{path:"Hero 01.png",output:i(h)},{path:"Level_0.ldtkl",output:i(c)},{path:"Level_1.ldtkl",output:i(u)},{path:"Solaria Demo Update 01.png",output:i(d)}]})},_=new a.Loader;for(let t of Object.values(g))_.addResource(t);const f={PlayerSpeed:32,PlayerFrameSpeed:200};class m extends a.Actor{constructor(t){super({...t,collisionType:a.CollisionType.Active})}onInitialize(t){let e=a.SpriteSheet.fromImageSource({image:g.HeroSpriteSheetPng,grid:{spriteWidth:16,spriteHeight:16,rows:8,columns:8}}),i=new a.Animation({frames:[{graphic:e.getSprite(0,1),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(1,1),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(2,1),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(3,1),duration:f.PlayerFrameSpeed}]});this.graphics.add("left-idle",i);let s=new a.Animation({frames:[{graphic:e.getSprite(0,2),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(1,2),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(2,2),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(3,2),duration:f.PlayerFrameSpeed}]});this.graphics.add("right-idle",s);let r=new a.Animation({frames:[{graphic:e.getSprite(0,3),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(1,3),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(2,3),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(3,3),duration:f.PlayerFrameSpeed}]});this.graphics.add("up-idle",r);let n=new a.Animation({frames:[{graphic:e.getSprite(0,0),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(1,0),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(2,0),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(3,0),duration:f.PlayerFrameSpeed}]});this.graphics.add("down-idle",n);let o=new a.Animation({frames:[{graphic:e.getSprite(0,5),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(1,5),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(2,5),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(3,5),duration:f.PlayerFrameSpeed}]});this.graphics.add("left-walk",o);let l=new a.Animation({frames:[{graphic:e.getSprite(0,6),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(1,6),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(2,6),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(3,6),duration:f.PlayerFrameSpeed}]});this.graphics.add("right-walk",l);let h=new a.Animation({frames:[{graphic:e.getSprite(0,7),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(1,7),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(2,7),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(3,7),duration:f.PlayerFrameSpeed}]});this.graphics.add("up-walk",h);let d=new a.Animation({frames:[{graphic:e.getSprite(0,4),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(1,4),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(2,4),duration:f.PlayerFrameSpeed},{graphic:e.getSprite(3,4),duration:f.PlayerFrameSpeed}]});this.graphics.add("down-walk",d)}onPreUpdate(t,e){this.vel=a.Vector.Zero,this.graphics.use("down-idle"),t.input.keyboard.isHeld(a.Input.Keys.ArrowRight)&&(this.vel=a.vec(f.PlayerSpeed,0),this.graphics.use("right-walk")),t.input.keyboard.isHeld(a.Input.Keys.ArrowLeft)&&(this.vel=a.vec(-f.PlayerSpeed,0),this.graphics.use("left-walk")),t.input.keyboard.isHeld(a.Input.Keys.ArrowUp)&&(this.vel=a.vec(0,-f.PlayerSpeed),this.graphics.use("up-walk")),t.input.keyboard.isHeld(a.Input.Keys.ArrowDown)&&(this.vel=a.vec(0,f.PlayerSpeed),this.graphics.use("down-walk"))}}const v=new a.Engine({resolution:{width:256,height:256},viewport:{width:1024,height:1024},suppressPlayButton:!0,pixelArt:!0,pixelRatio:4});v.start(_).then(()=>{console.log("Game start!"),g.LdtkResource.registerEntityIdentifierFactory("PlayerStart",t=>{let e=new m({name:"player",anchor:a.vec(t.entity.__pivot[0],t.entity.__pivot[1]),width:t.entity.width,height:t.entity.height,pos:t.worldPos,z:t.layer.order});return v.currentScene.camera.strategy.lockToActor(e),e}),g.LdtkResource.addToScene(v.currentScene,{pos:a.vec(0,0)})}); -//# sourceMappingURL=index.c2a0b4ac.js.map +Read more about this issue at https://excaliburjs.com/docs/performance`),i&&this._toaster.toast("Excalibur is encountering performance issues. It's possible that your browser doesn't have hardware acceleration enabled. Visit [LINK] for more information and potential solutions.","https://excaliburjs.com/docs/performance"),this.useCanvas2DFallback(),this.emit("fallbackgraphicscontext",this.graphicsContext))}}useCanvas2DFallback(){var t,e,i;let s=this.canvas.cloneNode(!1);this.canvas.parentNode.replaceChild(s,this.canvas),this.canvas=s;let r={...this._originalOptions,antialiasing:this.getAntialiasing()},n=this._originalDisplayMode;this.graphicsContext=new eR({canvasElement:this.canvas,enableTransparency:this.enableCanvasTransparency,antialiasing:r.antialiasing,backgroundColor:r.backgroundColor,snapToPixel:r.snapToPixel,useDrawSorting:r.useDrawSorting}),this.screen&&this.screen.dispose(),this.screen=new eL({canvas:this.canvas,context:this.graphicsContext,antialiasing:null===(t=r.antialiasing)||void 0===t||t,browser:this.browser,viewport:null!==(e=r.viewport)&&void 0!==e?e:r.width&&r.height?{width:r.width,height:r.height}:eF.SVGA,resolution:r.resolution,displayMode:n,pixelRatio:r.suppressHiDPIScaling?1:null!==(i=r.pixelRatio)&&void 0!==i?i:null}),this.screen.setCurrentCamera(this.currentScene.camera),this.input.pointers.detach();let o=r&&r.pointerScope===O.Document?document:this.canvas;this.input.pointers=this.input.pointers.recreate(o,this),this.input.pointers.init()}dispose(){this._disposed||(this._disposed=!0,this.stop(),this.input.toggleEnabled(!1),this.canvas.parentNode.removeChild(this.canvas),this.canvas=null,this.screen.dispose(),this.graphicsContext.dispose(),this.graphicsContext=null)}getWorldBounds(){return this.screen.getWorldBounds()}get timescale(){return this._timescale}set timescale(t){if(t<=0){tW.getInstance().error("Cannot set engine.timescale to a value of 0 or less than 0.");return}this._timescale=t}addTimer(t){return this.currentScene.addTimer(t)}removeTimer(t){return this.currentScene.removeTimer(t)}addScene(t,e){return this.director.add(t,e),this}removeScene(t){this.director.remove(t)}add(t){if(2==arguments.length){this.director.add(arguments[0],arguments[1]);return}let e=this.director.getDeferredScene();e instanceof rq?e.add(t):this.currentScene.add(t)}remove(t){t instanceof s_&&this.currentScene.remove(t),(t instanceof rq||rj(t))&&this.removeScene(t),"string"==typeof t&&this.removeScene(t)}async goto(t,e){await this.director.goto(t,e)}async goToScene(t,e){await this.director.goto(t,e)}screenToWorldCoordinates(t){return this.screen.screenToWorldCoordinates(t)}worldToScreenCoordinates(t){return this.screen.worldToScreenCoordinates(t)}_initialize(t){var e,i;this.pageScrollPreventionMode=t.scrollPreventionMode;let s=t&&t.pointerScope===O.Document?document:this.canvas,r=null===(i=null===(e=this._originalOptions)||void 0===e?void 0:e.grabWindowFocus)||void 0===i||i;this.input=new rV({pointerTarget:s,grabWindowFocus:r,engine:this}),this.inputMapper=this.input.inputMapper,this.browser.document.on("visibilitychange",()=>{"hidden"===document.visibilityState?(this.events.emit("hidden",new it(this)),this._logger.debug("Window hidden")):"visible"===document.visibilityState&&(this.events.emit("visible",new e8(this)),this._logger.debug("Window visible"))}),this.canvasElementId||t.canvasElement||document.body.appendChild(this.canvas)}toggleInputEnabled(t){this._inputEnabled=t,this.input.toggleEnabled(this._inputEnabled)}onInitialize(t){}setAntialiasing(t){this.screen.antialiasing=t}getAntialiasing(){return this.screen.antialiasing}get isInitialized(){return this._isInitialized}async _overrideInitialize(t){this.isInitialized||(await this.director.onInitialize(),await this.onInitialize(t),this.events.emit("initialize",new id(t,this)),this._isInitialized=!0)}_update(t){var e;if(this._isLoading){null===(e=this._loader)||void 0===e||e.onUpdate(this,t),this.input.update();return}this._preupdate(t),this.currentScene.update(this,t),this.graphicsContext.updatePostProcessors(t),this._postupdate(t),this.input.update()}_preupdate(t){this.emit("preupdate",new e1(this,t,this)),this.onPreUpdate(this,t)}onPreUpdate(t,e){}_postupdate(t){this.emit("postupdate",new e2(this,t,this)),this.onPostUpdate(this,t)}onPostUpdate(t,e){}_draw(t){var e,i;if(this.graphicsContext.beginDrawLifecycle(),this.graphicsContext.clear(),this._predraw(this.graphicsContext,t),this._isLoading){this._hideLoader||(null===(e=this._loader)||void 0===e||e.canvas.draw(this.graphicsContext,0,0),this.graphicsContext.flush(),this.graphicsContext.endDrawLifecycle());return}this.graphicsContext.backgroundColor=null!==(i=this.currentScene.backgroundColor)&&void 0!==i?i:this.backgroundColor,this.currentScene.draw(this.graphicsContext,t),this._postdraw(this.graphicsContext,t),this.graphicsContext.flush(),this.graphicsContext.endDrawLifecycle(),this._checkForScreenShots()}_predraw(t,e){this.emit("predraw",new e$(t,e,this)),this.onPreDraw(t,e)}onPreDraw(t,e){}_postdraw(t,e){this.emit("postdraw",new eK(t,e,this)),this.onPostDraw(t,e)}onPostDraw(t,e){}showDebug(t){this._isDebug=t}toggleDebug(){return this._isDebug=!this._isDebug,this._isDebug}get loadingComplete(){return!this._isLoading}get ready(){return this._isReadyFuture.isCompleted}isReady(){return this._isReadyFuture.promise}async start(t,e){let i;if(!this._compatible)throw Error("Excalibur is incompatible with your browser");return this._isLoading=!0,t instanceof iE?i=t:"string"==typeof t&&(this.director.configureStart(t,e),i=this.director.mainLoader),this._logger.debug("Starting game clock..."),this.browser.resume(),this.clock.start(),this._logger.debug("Game clock started"),await this.load(null!=i?i:new iB),await this._overrideInitialize(this),this._isReadyFuture.resolve(),this.emit("start",new eq(this)),this._isReadyFuture.promise}_mainloop(t){this.emit("preframe",new e5(this,this.stats.prevFrame));let e=t*this.timescale;this.currentFrameElapsedMs=e;let i=this.stats.prevFrame.id+1;this.stats.currFrame.reset(),this.stats.currFrame.id=i,this.stats.currFrame.delta=e,this.stats.currFrame.fps=this.clock.fpsSampler.fps,e_.clear();let s=this.clock.now(),r=1e3/this.fixedUpdateFps;if(this.fixedUpdateFps)for(this._lagMs+=e;this._lagMs>=r;)this._update(r),this._lagMs-=r;else this._update(e);let n=this.clock.now();this.currentFrameLagMs=this._lagMs,this._draw(e);let o=this.clock.now();this.stats.currFrame.duration.update=n-s,this.stats.currFrame.duration.draw=o-n,this.stats.currFrame.graphics.drawnImages=e_.DrawnImagesCount,this.stats.currFrame.graphics.drawCalls=e_.DrawCallCount,this.emit("postframe",new e4(this,this.stats.currFrame)),this.stats.prevFrame.reset(this.stats.currFrame),this._monitorPerformanceThresholdAndTriggerFallback()}stop(){this.clock.isRunning()&&(this.emit("stop",new eX(this)),this.browser.pause(),this.clock.stop(),this._logger.debug("Game stopped"))}isRunning(){return this.clock.isRunning()}screenshot(t=!1){return new Promise(e=>{this._screenShotRequests.push({preserveHiDPIResolution:t,resolve:e})})}_checkForScreenShots(){for(let t of this._screenShotRequests){let e=t.preserveHiDPIResolution?this.canvas.width:this.screen.resolution.width,i=t.preserveHiDPIResolution?this.canvas.height:this.screen.resolution.height,s=document.createElement("canvas");s.width=e,s.height=i;let r=s.getContext("2d");r.imageSmoothingEnabled=this.screen.antialiasing,r.drawImage(this.canvas,0,0,e,i);let n=new Image,o=s.toDataURL("image/png");n.src=o,t.resolve(n)}this._screenShotRequests.length=0}async load(t,e=!1){try{if(t.isLoaded())return;this._loader=t,this._isLoading=!0,this._hideLoader=e,t instanceof iB&&(t.suppressPlayButton=this._suppressPlayButton),this._loader.onInitialize(this),await t.load()}catch(t){this._logger.error("Error loading resources, things may not behave properly",t),await Promise.resolve()}finally{this._isLoading=!1,this._hideLoader=!1,this._loader=null}}}ns._DEFAULT_ENGINE_OPTIONS={width:0,height:0,enableCanvasTransparency:!0,useDrawSorting:!0,configurePerformanceCanvas2DFallback:{allow:!1,showPlayerMessage:!1,threshold:{fps:20,numberOfFrames:100}},canvasElementId:"",canvasElement:void 0,snapToPixel:!1,antialiasing:!0,pixelArt:!1,powerPreference:"high-performance",pointerScope:O.Canvas,suppressConsoleBootMessage:null,suppressMinimumBrowserFeatureDetection:null,suppressHiDPIScaling:null,suppressPlayButton:null,grabWindowFocus:!0,scrollPreventionMode:tv.Canvas,backgroundColor:tH.fromHex("#2185d0")};class nr{constructor(){this._handlers={},this._wiredEventDispatchers=[],this._deferedHandlerRemovals=[]}clear(){this._handlers={},this._wiredEventDispatchers=[]}_processDeferredHandlerRemovals(){for(let t of this._deferedHandlerRemovals)this._removeHandler(t.name,t.handler);this._deferedHandlerRemovals.length=0}emit(t,e){let i,s;if(this._processDeferredHandlerRemovals(),t){if(t=t.toLowerCase(),null==e&&(e=new eV),this._handlers[t])for(i=0,s=this._handlers[t].length;i-1&&this._handlers[t].splice(s,1)}else this._handlers[t].length=0}}once(t,e){this._processDeferredHandlerRemovals();let i=s=>{let r=s||new eV;this.off(t,i),e(r)};this.on(t,i)}wire(t){t._wiredEventDispatchers.push(this)}unwire(t){let e=t._wiredEventDispatchers.indexOf(this);e>-1&&t._wiredEventDispatchers.splice(e,1)}}class nn extends sj{get font(){return this._font}set font(t){this._font=t,this._text.font=t}get text(){return this._text.text}set text(t){this._text.text=t}get color(){return this._text.color}set color(t){this._text&&(this._text.color=t)}get opacity(){return this._text.opacity}set opacity(t){this._text.opacity=t}get spriteFont(){return this._spriteFont}set spriteFont(t){t&&(this._spriteFont=t,this._text.font=this._spriteFont)}constructor(t){super(t),this._font=new sW,this._text=new sG({text:"",font:this._font});let{text:e,pos:i,x:s,y:r,spriteFont:n,font:o,color:a}={text:"",...t};this.pos=null!=i?i:s&&r?tZ(s,r):this.pos,this.text=null!=e?e:this.text,this.font=null!=o?o:this.font,this.spriteFont=null!=n?n:this.spriteFont,this._text.color=null!=a?a:this.color;let l=this.get(sm);l.anchor=tN.Zero,l.use(this._text)}_initialize(t){super._initialize(t)}getTextWidth(){return this._text.width}}class no extends s_{getGraphics(){return this._graphics}addGraphic(t,e){this._graphics.push(t),this._gfx.visible=this.map.visible,this._gfx.opacity=this.map.opacity,(null==e?void 0:e.offset)&&(this._gfx.offset=e.offset),this._gfx.localBounds=this._recalculateBounds()}_recalculateBounds(){let t=this._tileBounds.clone();for(let e of this._graphics){let i=tZ(this.map.graphicsOffset.x-this.map.tileWidth/2,this.map.graphicsOffset.y-(this.map.renderFromTopOfGraphic?0:e.height-this.map.tileHeight));t=t.combine(e.localBounds.translate(i))}return t}removeGraphic(t){let e=this._graphics.indexOf(t);e>-1&&this._graphics.splice(e,1),this._gfx.localBounds=this._recalculateBounds()}clearGraphics(){this._graphics.length=0,this._gfx.visible=!1,this._gfx.localBounds=this._recalculateBounds()}getColliders(){return this._colliders}addCollider(t){this._colliders.push(t),this.map.flagCollidersDirty()}removeCollider(t){let e=this._colliders.indexOf(t);e>-1&&this._colliders.splice(e,1),this.map.flagCollidersDirty()}clearColliders(){this._colliders.length=0,this.map.flagCollidersDirty()}get pos(){return this.map.tileToWorld(tZ(this.x,this.y))}get center(){return this.pos.add(tZ(0,this.map.tileHeight/2))}constructor(t,e,i,s){super([new iV,new sm({offset:null!=i?i:tN.Zero,onPostDraw:(t,e)=>this.draw(t,e)}),new rP(s)]),this.solid=!1,this._tileBounds=new tq,this._graphics=[],this._colliders=[],this.data=new Map,this.x=t,this.y=e,this.map=s,this._transform=this.get(iV),this._isometricEntityComponent=this.get(rP);let r=this.map.tileWidth/2,n=this.map.tileHeight/2,o=(this.x-this.y)*r,a=(this.x+this.y)*n;this._transform.pos=tZ(o,a),this._isometricEntityComponent.elevation=s.elevation,this._gfx=this.get(sm),this._gfx.visible=!1;let l=this.map.tileWidth,h=this.map.tileHeight,d=tZ(0,this.map.renderFromTopOfGraphic?h:0);this._gfx.localBounds=this._tileBounds=new tq({left:-l/2,top:-h,right:l/2,bottom:h}).translate(d)}draw(t,e){let i=this.map.tileWidth/2;for(let e of(t.save(),t.translate(-i,0),this._graphics))e.draw(t,this.map.graphicsOffset.x,this.map.graphicsOffset.y-(this.map.renderFromTopOfGraphic?0:e.height-this.map.tileHeight));t.restore()}}class na extends s_{constructor(t){super([new iV,new sh({type:G.Fixed}),new sl,new sY((t,e)=>this.debug(t,e),!1)],t.name),this.elevation=0,this.visible=!0,this.opacity=1,this.renderFromTopOfGraphic=!1,this.graphicsOffset=tZ(0,0),this._collidersDirty=!1,this._originalOffsets=new WeakMap;let{pos:e,tileWidth:i,tileHeight:s,columns:r,rows:n,renderFromTopOfGraphic:o,graphicsOffset:a,elevation:l}=t;this.transform=this.get(iV),e&&(this.transform.pos=e),this.collider=this.get(sl),this.collider&&this.collider.set(this._composite=new i9([])),this.renderFromTopOfGraphic=null!=o?o:this.renderFromTopOfGraphic,this.graphicsOffset=null!=a?a:this.graphicsOffset,this.elevation=null!=l?l:this.elevation,this.tileWidth=i,this.tileHeight=s,this.columns=r,this.rows=n,this.tiles=Array(r*n);for(let t=0;t=this.columns||e>=this.rows?null:this.tiles[t+e*this.columns]}getTileByPoint(t){let e=this.worldToTile(t);return this.getTile(e.x,e.y)}_getMaxZIndex(){let t=Number.NEGATIVE_INFINITY;for(let e of this.tiles){let i=e.get(iV).z;i>t&&(t=i)}return t}debug(t,e){let{showAll:i,showPosition:s,positionColor:r,positionSize:n,showGrid:o,gridColor:a,gridWidth:l,showColliderGeometry:h}=e.isometric,{geometryColor:d,geometryLineWidth:c,geometryPointSize:u}=e.collider;if(t.save(),t.z=this._getMaxZIndex()+.5,i||o){for(let e=0;ee.isComplete(t))}reset(){this._actions.forEach(t=>t.reset())}stop(){this._actions.forEach(t=>t.stop())}}class nd{constructor(t,e){this.bounds=t,this.options=e,this._defaultOptions={maxDepth:10,capacity:10,level:0},this.items=[],this._isDivided=!1,this.topLeft=null,this.topRight=null,this.bottomLeft=null,this.bottomRight=null,this.options={...this._defaultOptions,...e},this.halfWidth=t.width/2,this.halfHeight=t.height/2}_split(){this._isDivided=!0;let t={maxDepth:this.options.maxDepth,capacity:this.options.capacity,level:this.options.level+1};this.topLeft=new nd(new tq({left:this.bounds.left,top:this.bounds.top,right:this.bounds.left+this.halfWidth,bottom:this.bounds.top+this.halfHeight}),t),this.topRight=new nd(new tq({left:this.bounds.left+this.halfWidth,top:this.bounds.top,right:this.bounds.right,bottom:this.bounds.top+this.halfHeight}),t),this.bottomLeft=new nd(new tq({left:this.bounds.left,top:this.bounds.top+this.halfHeight,right:this.bounds.left+this.halfWidth,bottom:this.bounds.bottom}),t),this.bottomRight=new nd(new tq({left:this.bounds.left+this.halfWidth,top:this.bounds.top+this.halfHeight,right:this.bounds.right,bottom:this.bounds.bottom}),t)}_insertIntoSubNodes(t){var e,i,s,r;(null===(e=this.topLeft)||void 0===e?void 0:e.bounds.overlaps(t.bounds))&&this.topLeft.insert(t),(null===(i=this.topRight)||void 0===i?void 0:i.bounds.overlaps(t.bounds))&&this.topRight.insert(t),(null===(s=this.bottomLeft)||void 0===s?void 0:s.bounds.overlaps(t.bounds))&&this.bottomLeft.insert(t),(null===(r=this.bottomRight)||void 0===r?void 0:r.bounds.overlaps(t.bounds))&&this.bottomRight.insert(t)}insert(t){if(this._isDivided){this._insertIntoSubNodes(t);return}if(this.items.push(t),this.items.length>this.options.capacity&&this.options.level-1&&this.items.splice(e,1);return}(null===(e=this.topLeft)||void 0===e?void 0:e.bounds.overlaps(t.bounds))&&this.topLeft.remove(t),(null===(i=this.topRight)||void 0===i?void 0:i.bounds.overlaps(t.bounds))&&this.topRight.remove(t),(null===(s=this.bottomLeft)||void 0===s?void 0:s.bounds.overlaps(t.bounds))&&this.bottomLeft.remove(t),(null===(r=this.bottomRight)||void 0===r?void 0:r.bounds.overlaps(t.bounds))&&this.bottomRight.remove(t)}}query(t){let e=this.items;return this._isDivided&&(this.topLeft.bounds.overlaps(t)&&(e=e.concat(this.topLeft.query(t))),this.topRight.bounds.overlaps(t)&&(e=e.concat(this.topRight.query(t))),this.bottomLeft.bounds.overlaps(t)&&(e=e.concat(this.bottomLeft.query(t))),this.bottomRight.bounds.overlaps(t)&&(e=e.concat(this.bottomRight.query(t)))),e=e.filter((t,i)=>e.indexOf(t)>=i)}clear(){this.items=[],this._isDivided=!1,this.topLeft=null,this.topRight=null,this.bottomLeft=null,this.bottomRight=null}getAllItems(){let t=this.items;return this._isDivided&&(t=(t=(t=(t=t.concat(this.topLeft.getAllItems())).concat(this.topRight.getAllItems())).concat(this.bottomLeft.getAllItems())).concat(this.bottomRight.getAllItems())),t=t.filter((e,i)=>t.indexOf(e)>=i)}getTreeDepth(){return this._isDivided?1+Math.max(this.topLeft.getTreeDepth(),this.topRight.getTreeDepth(),this.bottomLeft.getTreeDepth(),this.bottomRight.getTreeDepth()):0}debug(t){this.bounds.draw(t,tH.Yellow),this._isDivided&&(this.topLeft.bounds.draw(t,tH.Yellow),this.topRight.bounds.draw(t,tH.Yellow),this.bottomLeft.bounds.draw(t,tH.Yellow),this.bottomRight.bounds.draw(t,tH.Yellow))}}function nc(t){return!!t._initialize}function nu(t){return!!t.onInitialize}function np(t){return!!t._preupdate}function ng(t){return!!t.onPreUpdate}function n_(t){return!!t.onPostUpdate}function nf(t){return!!t.onPostUpdate}function nm(t){return!!t.onPreDraw}function nv(t){return!!t.onPostDraw}class ny{constructor(t,e=tH.Magenta,i=!1){this.path=t,this.color=e,this._stream=null,this._gif=null,this._textures=[],this._animation=null,this._transparentColor=null,this._resource=new t9(t,"arraybuffer",i),this._transparentColor=e}get bustCache(){return this._resource.bustCache}set bustCache(t){this._resource.bustCache=t}async load(){let t=await this._resource.load();this._stream=new nb(t),this._gif=new nT(this._stream,this._transparentColor);let e=this._gif.images.map(t=>new es(t.src,!1));return await Promise.all(e.map(t=>t.load())),this.data=this._textures=e}isLoaded(){return!!this.data}toSprite(t=0){return this._textures[t].toSprite()}toSpriteSheet(){return new en({sprites:this._textures.map(t=>t.toSprite())})}toAnimation(t){let e=this.toSpriteSheet(),i=e.sprites.length;return this._animation=rv.fromSpriteSheet(e,tz(0,i),t),this._animation}get readCheckBytes(){return this._gif.checkBytes}}let nx=t=>t.reduce(function(t,e){return 2*t+e},0),nw=t=>{let e=[];for(let i=7;i>=0;i--)e.push(!!(t&1<{if(this.position>=this.data.byteLength)throw Error("Attempted to read past end of stream.");return this.data[this.position++]},this.readBytes=t=>{let e=[];for(let i=0;i{let e="";for(let i=0;i{let t=this.readBytes(2);return(t[1]<<8)+t[0]},this.data=new Uint8Array(t),this.len=this.data.byteLength,0===this.len)throw Error("No data loaded from file")}}let nC=function(t,e){let i,s,r=0,n=[],o=1<>3)&1<<(7&r)&&(i|=1<{let e=[];for(let i=0;i{let e=t.toString(16);return 1===e.length?"0"+e:e}).join("");e.push(t)}return e},this.readSubBlocks=()=>{let t,e;e="";do t=this._st.readByte(),e+=this._st.read(t);while(0!==t)return e},this.parseHeader=()=>{let t={sig:null,ver:null,width:null,height:null,colorRes:null,globalColorTableSize:null,gctFlag:null,sorted:null,globalColorTable:[],bgColor:null,pixelAspectRatio:null};if(t.sig=this._st.read(3),t.ver=this._st.read(3),"GIF"!==t.sig)throw Error("Not a GIF file.");t.width=this._st.readUnsigned(),t.height=this._st.readUnsigned();let e=nw(this._st.readByte());t.gctFlag=e.shift(),t.colorRes=nx(e.splice(0,3)),t.sorted=e.shift(),t.globalColorTableSize=nx(e.splice(0,3)),t.bgColor=this._st.readByte(),t.pixelAspectRatio=this._st.readByte(),t.gctFlag&&(t.globalColorTable=this.parseColorTable(1<{switch(t.label=this._st.readByte(),t.label){case 249:t.extType="gce",(t=>{this.checkBytes.push(this._st.readByte());let e=nw(this._st.readByte());t.reserved=e.splice(0,3),t.disposalMethod=nx(e.splice(0,3)),t.userInput=e.shift(),t.transparencyGiven=e.shift(),t.delayTime=this._st.readUnsigned(),t.transparencyIndex=this._st.readByte(),t.terminator=this._st.readByte(),this._handler.gce&&this._handler.gce(t)&&this.checkBytes.push(this._handler.gce)})(t);break;case 254:t.extType="com",(t=>{t.comment=this.readSubBlocks(),this._handler.com&&this._handler.com(t)&&this.checkBytes.push(this._handler.com)})(t);break;case 1:t.extType="pte",(t=>{this.checkBytes.push(this._st.readByte()),t.ptHeader=this._st.readBytes(12),t.ptData=this.readSubBlocks(),this._handler.pte&&this._handler.pte(t)&&this.checkBytes.push(this._handler.pte)})(t);break;case 255:t.extType="app",(t=>{(this.checkBytes.push(this._st.readByte()),t.identifier=this._st.read(8),t.authCode=this._st.read(3),"NETSCAPE"===t.identifier)?(t=>{this.checkBytes.push(this._st.readByte()),t.unknown=this._st.readByte(),t.iterations=this._st.readUnsigned(),t.terminator=this._st.readByte(),this._handler.app&&this._handler.app.NETSCAPE&&this._handler.app.NETSCAPE(t)&&this.checkBytes.push(this._handler.app)})(t):(t=>{t.appData=this.readSubBlocks(),this._handler.app&&this._handler.app[t.identifier]&&this._handler.app[t.identifier](t)&&this.checkBytes.push(this._handler.app[t.identifier])})(t)})(t);break;default:t.extType="unknown",(t=>{t.data=this.readSubBlocks(),this._handler.unknown&&this._handler.unknown(t)&&this.checkBytes.push(this._handler.unknown)})(t)}},this.parseImg=t=>{t.leftPos=this._st.readUnsigned(),t.topPos=this._st.readUnsigned(),t.width=this._st.readUnsigned(),t.height=this._st.readUnsigned();let e=nw(this._st.readByte());t.lctFlag=e.shift(),t.interlaced=e.shift(),t.sorted=e.shift(),t.reserved=e.splice(0,2),t.lctSize=nx(e.splice(0,3)),t.lctFlag&&(t.lct=this.parseColorTable(1<{let i=Array(t.length),s=t.length/e,r=(s,r)=>{let n=t.slice(r*e,(r+1)*e);i.splice.apply(i,[s*e,e].concat(n))},n=[0,4,2,1],o=[8,8,4,2],a=0;for(let t=0;t<4;t++)for(let e=n[t];e{let t={sentinel:this._st.readByte(),type:""};switch(String.fromCharCode(t.sentinel)){case"!":t.type="ext",this.parseExt(t);break;case",":t.type="img",this.parseImg(t);break;case";":t.type="eof",this._handler.eof&&this._handler.eof(t)&&this.checkBytes.push(this._handler.eof);break;default:throw Error("Unknown block: 0x"+t.sentinel.toString(16))}"eof"!==t.type&&this.parseBlock()},this.arrayToImage=t=>{let e=0,i=document.createElement("canvas");i.id=e.toString(),i.width=t.width,i.height=t.height,e++;let s=i.getContext("2d"),r=0,n=0;for(let e=0;e{let r=e(),n=e=>{try{let{done:s,value:o}=r.next(e);s&&i(),o instanceof Promise?o.then(()=>{t.clock.schedule(n)}):void 0===o||void 0===o?t.clock.schedule(n):t.clock.schedule(n,o||0)}catch(t){s(t)}};n(t.clock.elapsed())})}class nE extends s_{get progress(){return this._currentProgress}get complete(){return"out"===this.direction?this.progress>=1:this.progress<=0}constructor(t){var e,i,s,r;super(),this._logger=tW.getInstance(),this.transform=new iV,this.graphics=new sm,this._completeFuture=new tE,this.started=!1,this._currentDistance=0,this._currentProgress=0,this.done=this._completeFuture.promise,this.name=`Transition#${this.id}`,this.duration=t.duration,this.easing=null!==(e=t.easing)&&void 0!==e?e:sw.Linear,this.direction=null!==(i=t.direction)&&void 0!==i?i:"out",this.hideLoader=null!==(s=t.hideLoader)&&void 0!==s&&s,this.blockInput=null!==(r=t.blockInput)&&void 0!==r&&r,this.transform.coordPlane=j.Screen,this.transform.pos=tN.Zero,this.transform.z=1/0,this.graphics.anchor=tN.Zero,this.addComponent(this.transform),this.addComponent(this.graphics),"out"===this.direction?this._currentProgress=0:this._currentProgress=1}updateTransition(t,e){this.complete||(this._currentDistance+=tF(e/this.duration,0,1),this._currentDistance>=1&&(this._currentDistance=1),"out"===this.direction?this._currentProgress=tF(this.easing(this._currentDistance,0,1,1),0,1):this._currentProgress=tF(this.easing(this._currentDistance,1,0,1),0,1))}async onPreviousSceneDeactivate(t){}onStart(t){}onUpdate(t){}onEnd(t){}onReset(){}reset(){this.started=!1,this._completeFuture=new tE,this.done=this._completeFuture.promise,this._currentDistance=0,"out"===this.direction?this._currentProgress=0:this._currentProgress=1,this.onReset()}play(t,e){this.started&&(this.reset(),this._logger.warn(`Attempted to play a transition ${this.name} that is already playing, reset transition.`)),(null!=e?e:t.currentScene).add(this);let i=this;return nA(t,function*(){for(;!i.complete;){let e=yield;i.updateTransition(t,e),i.execute()}})}execute(){this.isInitialized&&(this.started||(this.started=!0,this.onStart(this.progress)),this.onUpdate(this.progress),this.complete&&!this._completeFuture.isCompleted&&(this.onEnd(this.progress),this._completeFuture.resolve()))}}class nP extends nE{constructor(t){var e,i;super({...t,duration:null!==(e=t.duration)&&void 0!==e?e:2e3}),this.name=`FadeInOut#${this.id}`,this.color=null!==(i=t.color)&&void 0!==i?i:tH.Black}onInitialize(t){this.transform.pos=t.screen.unsafeArea.topLeft,this.screenCover=new sv({width:t.screen.resolution.width,height:t.screen.resolution.height,color:this.color}),this.graphics.add(this.screenCover),this.graphics.opacity=this.progress}onReset(){this.graphics.opacity=this.progress}onStart(t){this.graphics.opacity=t}onEnd(t){this.graphics.opacity=t}onUpdate(t){this.graphics.opacity=t}}class nI extends nE{constructor(t){super({direction:"in",...t}),this.name=`CrossFade#${this.id}`}async onPreviousSceneDeactivate(t){this.image=await t.engine.screenshot(!0),await this.image.decode()}onInitialize(t){this.engine=t,this.transform.pos=t.screen.unsafeArea.topLeft,this.screenCover=es.fromHtmlImageElement(this.image).toSprite(),this.graphics.add(this.screenCover),this.transform.scale=tZ(1/t.screen.pixelRatio,1/t.screen.pixelRatio),this.graphics.opacity=this.progress}onStart(t){this.graphics.opacity=this.progress}onReset(){this.graphics.opacity=this.progress}onEnd(t){this.graphics.opacity=t}onUpdate(t){this.graphics.opacity=t}}class nk extends et{constructor(t){super(),this.color=tH.Black,this.thickness=1;let{start:e,end:i,color:s,thickness:r}=t;this.start=e,this.end=i,this.color=null!=s?s:this.color,this.thickness=null!=r?r:this.thickness,this._localBounds=this._calculateBounds();let{width:n,height:o}=this._localBounds;this.width=n,this.height=o}get localBounds(){return this._localBounds}_calculateBounds(){let t=this.end.sub(this.start).normal(),e=this.thickness/2,i=[this.start.add(t.scale(e)),this.end.add(t.scale(e)),this.end.add(t.scale(-e)),this.start.add(t.scale(-e))];return tq.fromPoints(i)}_drawImage(t,e,i){t.drawLine(this.start,this.end,this.color,this.thickness)}clone(){return new nk({start:this.start,end:this.end,color:this.color,thickness:this.thickness})}}class nD extends eO{get points(){return this._points}set points(t){this._points=t;let e=this.minPoint;this.width=this._points.reduce((t,e)=>Math.max(e.x,t),0)-e.x,this.height=this._points.reduce((t,e)=>Math.max(e.y,t),0)-e.y,this.flagDirty()}get minPoint(){return tZ(this._points.reduce((t,e)=>Math.min(e.x,t),1/0),this._points.reduce((t,e)=>Math.min(e.y,t),1/0))}constructor(t){super(t),this.points=t.points,this.filtering=H.Blended,this.rasterize()}clone(){return new nD({points:this.points.map(t=>t.clone()),...this.cloneGraphicOptions(),...this.cloneRasterOptions()})}execute(t){if(this.points&&this.points.length){t.beginPath();let e=this.minPoint.negate(),i=this.points[0].add(e);t.moveTo(i.x,i.y),this.points.forEach(i=>{t.lineTo(i.x+e.x,i.y+e.y)}),t.lineTo(i.x,i.y),t.closePath(),this.color&&t.fill(),this.strokeColor&&t.stroke()}}}let nR=5,nF={},nB=()=>{for(let t in nF)nF[t]=0},nL=(t,e)=>{let i=tS.isEnabled("suppress-obsolete-message");nF[t]{var e={445:(t,e,i)=>{i.r(e),i.d(e,{compare:()=>d,compareVersions:()=>h,satisfies:()=>g,validate:()=>_,validateStrict:()=>f});let s=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i,r=t=>{if("string"!=typeof t)throw TypeError("Invalid argument expected string");let e=t.match(s);if(!e)throw Error(`Invalid argument not valid semver ('${t}' received)`);return e.shift(),e},n=t=>"*"===t||"x"===t||"X"===t,o=t=>{let e=parseInt(t,10);return isNaN(e)?t:e},a=(t,e)=>{let i,s;if(n(t)||n(e))return 0;let[r,a]=typeof(i=o(t))!=typeof(s=o(e))?[String(i),String(s)]:[i,s];return r>a?1:r{for(let i=0;i{let i=r(t),s=r(e),n=i.pop(),o=s.pop(),a=l(i,s);return 0!==a?a:n&&o?l(n.split("."),o.split(".")):n||o?n?-1:1:0},d=(t,e,i)=>{p(i);let s=h(t,e);return c[i].includes(s)},c={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1],"!=":[-1,1]},u=Object.keys(c),p=t=>{if("string"!=typeof t)throw TypeError("Invalid operator type, expected string but got "+typeof t);if(-1===u.indexOf(t))throw Error(`Invalid operator, expected one of ${u.join("|")}`)},g=(t,e)=>{if((e=e.replace(/([><=]+)\s+/g,"$1")).includes("||"))return e.split("||").some(e=>g(t,e));if(e.includes(" - ")){let[i,s]=e.split(" - ",2);return g(t,`>=${i} <=${s}`)}if(e.includes(" "))return e.trim().replace(/\s{2,}/g," ").split(" ").every(e=>g(t,e));let i=e.match(/^([<>=~^]+)/),s=i?i[1]:"=";if("^"!==s&&"~"!==s)return d(t,e,s);let[n,o,a,,h]=r(t),[c,u,p,,_]=r(e),f=[n,o,a],m=[c,null!=u?u:"x",null!=p?p:"x"];if(_&&(!h||0!==l(f,m)||-1===l(h.split("."),_.split("."))))return!1;let v=m.findIndex(t=>"0"!==t)+1,y="~"===s?2:v>1?v:1;return 0===l(f.slice(0,y),m.slice(0,y))&&-1!==l(f.slice(y),m.slice(y))},_=t=>"string"==typeof t&&/^[v\d]/.test(t)&&s.test(t),f=t=>"string"==typeof t&&/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(t)},961:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.EntityLayer=void 0;let s=i(205);e.EntityLayer=class{constructor(t,e,i,r){var n,o;if(this.ldtkLayer=e,this.resource=i,this.order=r,this.entities=[],this.ldtkToEntity=new Map,this.entityToLdtk=new Map,this.worldPos=(0,s.vec)(t.ldtkLevel.worldX,t.ldtkLevel.worldY),this.offset=(0,s.vec)(e.__pxTotalOffsetX,e.__pxTotalOffsetY),e.entityInstances)for(let t of e.entityInstances){let e=i.projectMetadata.defs.entities.find(e=>e.identifier===t.__identifier);if(i.factories.has(t.__identifier)){let r=i.factories.get(t.__identifier);if(r){let i=r({type:t.__identifier,worldPos:(0,s.vec)(t.px[0],t.px[1]).add(this.worldPos.add(this.offset)),entity:t,definition:e,layer:this});i&&(this.entities.push(i),this.ldtkToEntity.set(t,i),this.entityToLdtk.set(i,t))}}else{let a=new s.Actor({name:t.__identifier,pos:(0,s.vec)(t.px[0],t.px[1]).add(this.worldPos.add(this.offset)),width:t.width,height:t.height,anchor:(0,s.vec)(null!==(n=null==e?void 0:e.pivotX)&&void 0!==n?n:0,null!==(o=null==e?void 0:e.pivotY)&&void 0!==o?o:0),z:r});if(t.__tile){let e=i.tilesets.get(t.__tile.tilesetUid);if(e){let i=Math.floor(t.__tile.x/t.__tile.w),s=Math.floor(t.__tile.y/t.__tile.h),r=e.spritesheet.getSprite(i,s);r&&a.graphics.use(r)}}this.entities.push(a),this.ldtkToEntity.set(t,a),this.entityToLdtk.set(a,t)}}}runFactory(t){if(this.resource.factories.has(t)&&this.ldtkLayer.entityInstances)for(let t of this.ldtkLayer.entityInstances){let e=this.resource.projectMetadata.defs.entities.find(e=>e.identifier===t.__identifier),i=this.resource.factories.get(t.__identifier);if(i){let r=i({type:t.__identifier,worldPos:(0,s.vec)(t.px[0],t.px[1]).add(this.worldPos.add(this.offset)),entity:t,definition:e,layer:this});if(r){let e=this.ldtkToEntity.get(t);if(e){let i=this.entities.indexOf(e);i>-1&&(this.entities.splice(i,1),this.ldtkToEntity.delete(t),this.entityToLdtk.delete(e))}return this.entities.push(r),this.ldtkToEntity.set(t,r),this.entityToLdtk.set(r,t),r}}}}getEntitiesByIdentifier(t){let e=this.getLdtkEntitiesByIdentifier(t),i=[];for(let t of e){let e=this.ldtkToEntity.get(t);e&&i.push(e)}return i}getEntitiesByField(t,e){let i=this.getLdtkEntitiesByField(t,e),s=[];for(let t of i){let e=this.ldtkToEntity.get(t);e&&s.push(e)}return s}getLdtkEntitiesByIdentifier(t){return this.ldtkLayer.entityInstances.filter(e=>e.__identifier.toLocaleLowerCase()===t.toLowerCase())}getLdtkEntitiesByField(t,e){return this.ldtkLayer.entityInstances.filter(i=>{if(void 0!==e){let s=e;"string"==typeof e&&(s=e.toLocaleLowerCase());let r=i.fieldInstances.find(e=>e.__identifier.toLocaleLowerCase()===t.toLocaleLowerCase());return!!r&&r.__value===s}return!!i.fieldInstances.find(e=>e.__identifier.toLocaleLowerCase()===t.toLocaleLowerCase())})}}},710:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.FetchLoader=void 0,e.FetchLoader=async(t,e)=>{let i=await fetch(t);switch(e.toLowerCase()){case"xml":default:return await i.text();case"json":return await i.json()}}},607:function(t,e,i){var s=this&&this.__createBinding||(Object.create?function(t,e,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(e,i);r&&!("get"in r?!e.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return e[i]}}),Object.defineProperty(t,s,r)}:function(t,e,i,s){void 0===s&&(s=i),t[s]=e[i]}),r=this&&this.__exportStar||function(t,e){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(e,i)||s(e,t,i)};Object.defineProperty(e,"__esModule",{value:!0}),r(i(398),e),r(i(961),e),r(i(710),e),r(i(920),e),r(i(515),e),r(i(512),e),r(i(289),e),r(i(32),e),r(i(692),e),r(i(245),e),r(i(699),e)},920:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.IntGridLayer=void 0;let s=i(205);e.IntGridLayer=class{constructor(t,e,i,r){if(this.order=r,this.worldPos=(0,s.vec)(t.ldtkLevel.worldX,t.ldtkLevel.worldY),this.offset=(0,s.vec)(e.__pxTotalOffsetX,e.__pxTotalOffsetY),this.ldtkLayer=e,e.intGridCsv.length){let t=e.__cHei,r=e.__cWid;this.tilemap=new s.TileMap({name:e.__identifier,pos:this.worldPos.add(this.offset),tileWidth:e.__gridSize,tileHeight:e.__gridSize,rows:t,columns:r});let n=i.projectMetadata.defs.layers.find(t=>e.__identifier===t.identifier);if(n){let t=n.intGridValues.find(t=>{var e;return"solid"===(null===(e=null==t?void 0:t.identifier)||void 0===e?void 0:e.toLocaleLowerCase())});for(let i=0;i{Object.defineProperty(e,"__esModule",{value:!0}),e.LdtkResource=void 0;let s=i(692),r=i(32),n=i(710),o=i(699),a=i(445),l=i(289),h=i(205),d=i(515),c=i(245),u=i(512),p=i(961),g=i(920);class _{constructor(t,e){this.path=t,this.tilesets=new Map,this.levels=new Map,this.levelsByName=new Map,this.factories=new Map,this.fileLoader=n.FetchLoader,this._imageLoader=new l.LoaderCache(h.ImageSource),this._levelLoader=new l.LoaderCache(d.LevelResource),this.startZIndex=0,this.textQuality=4,this.useExcaliburWiring=!0,this.useMapBackgroundColor=!1,this.useTilemapCameraStrategy=!1,this.headless=!1,this.strict=!0;let{useExcaliburWiring:i,useTilemapCameraStrategy:s,entityIdentifierFactories:r,pathMap:o,useMapBackgroundColor:a,fileLoader:c,strict:u,headless:p,startZIndex:g}={...e};for(let t in this.strict=null!=u?u:this.strict,this.headless=null!=p?p:this.headless,this.useExcaliburWiring=null!=i?i:this.useExcaliburWiring,this.useTilemapCameraStrategy=null!=s?s:this.useTilemapCameraStrategy,this.useMapBackgroundColor=null!=a?a:this.useMapBackgroundColor,this.startZIndex=null!=g?g:this.startZIndex,this.fileLoader=null!=c?c:this.fileLoader,this.pathMap=o,r)this.registerEntityIdentifierFactory(t,r[t])}async load(){var t;let e=await this.fileLoader(this.path,"json");if(this.strict)try{this.projectMetadata=o.LdtkProjectMetadata.parse(e)}catch(t){throw console.error(`Could not parse LDtk map from location ${this.path}. +Excalibur only supports the latest version of LDtk formats as of the plugin's release.`),console.error("Is your map file corrupted or being interpreted as the wrong type?"),t}else this.projectMetadata=e;for(let e of((0,a.compare)(_.supportedLdtkVersion,null!==(t=this.projectMetadata.jsonVersion)&&void 0!==t?t:"0.0.0",">")&&console.warn(`The excalibur ldtk plugin officially supports ${_.supportedLdtkVersion}+, the current map has LDtk version ${this.projectMetadata.jsonVersion}`),this.projectMetadata.defs.tilesets))if(e.relPath){let t=(0,r.pathRelativeToBase)(this.path,e.relPath,this.pathMap),i=this._imageLoader.getOrAdd(t),s=new c.Tileset({image:i,ldtkTileset:e});this.tilesets.set(e.uid,s)}else"Internal_Icons"!==e.identifier&&console.warn(`No tileset image provided for ${e.identifier}`);for(let t of this.projectMetadata.levels)if(t.externalRelPath){let e=(0,r.pathRelativeToBase)(this.path,t.externalRelPath,this.pathMap);this._levelLoader.getOrAdd(e,this,{headless:this.headless,strict:this.strict,fileLoader:this.fileLoader,imageLoader:this._imageLoader,pathMap:this.pathMap})}else{let e=new u.Level(t,this);this.levels.set(t.uid,e),this.levelsByName.set(t.identifier.toLowerCase(),e)}return await Promise.all([this._imageLoader.load(),this._levelLoader.load()]),this._levelLoader.values().forEach(t=>{this.levels.set(t.data.ldtkLevel.uid,t.data),this.levelsByName.set(t.data.ldtkLevel.identifier.toLowerCase(),t.data)}),this.data=this.projectMetadata}isLoaded(){return!!this.data}registerEntityIdentifierFactory(t,e){if(this.factories.set(t,e),this.isLoaded())for(let e of this.getEntityLayers())e.runFactory(t)}getLevel(t){return this.levelsByName.get(t.toLowerCase())}getEntityLayers(t){let e=[];if(t){let i=this.getLevel(t);if(i)for(let t of i.layers)t instanceof p.EntityLayer&&e.push(t)}else for(let t of this.levels.values())for(let i of t.layers)i instanceof p.EntityLayer&&e.push(i);return e}getTileLayers(t){let e=[];if(t){let i=this.getLevel(t);if(i)for(let t of i.layers)t instanceof s.TileLayer&&e.push(t)}else for(let t of this.levels.values())for(let i of t.layers)i instanceof s.TileLayer&&e.push(i);return e}getIntGridLayers(t){let e=[];if(t){let i=this.getLevel(t);if(i)for(let t of i.layers)t instanceof g.IntGridLayer&&e.push(t)}else for(let t of this.levels.values())for(let i of t.layers)i instanceof g.IntGridLayer&&e.push(i);return e}getLdtkEntitiesByIdentifier(t,e){let i=[];for(let s of null!=e?e:Array.from(this.levels.values()).map(t=>t.ldtkLevel.identifier))for(let e of this.getEntityLayers(s))i=i.concat(e.getLdtkEntitiesByIdentifier(t));return i}getLdtkEntitiesByField(t,e,i){let s=[];for(let r of null!=i?i:Array.from(this.levels.values()).map(t=>t.ldtkLevel.identifier))for(let i of this.getEntityLayers(r))s=s.concat(i.getLdtkEntitiesByField(t,e));return s}getEntitiesByIdentifier(t,e){let i=[];for(let s of null!=e?e:Array.from(this.levels.values()).map(t=>t.ldtkLevel.identifier))for(let e of this.getEntityLayers(s))i=i.concat(e.getEntitiesByIdentifier(t));return i}getEntitiesByField(t,e,i){let s=[];for(let r of null!=i?i:Array.from(this.levels.values()).map(t=>t.ldtkLevel.identifier))for(let i of this.getEntityLayers(r))s=s.concat(i.getEntitiesByField(t,e));return s}getLevelBounds(t){t=null!=t?t:Array.from(this.levelsByName.keys());let e=new h.BoundingBox;for(let i of this.levels.values()){if(!t.includes(i.ldtkLevel.identifier))continue;let s=this.getTileLayers(i.ldtkLevel.identifier)[0];s&&(e=e.combine(h.BoundingBox.fromDimension(s.tilemap.tileWidth*s.tilemap.columns,s.tilemap.tileHeight*s.tilemap.rows,h.Vector.Zero,s.tilemap.pos)))}return e}addToScene(t,e){var i,r;let{pos:n,useLevelOffsets:o}={pos:(0,h.vec)(0,0),useLevelOffsets:!0,...e};for(let[r,a]of this.levels.entries())if(!(null===(i=null==e?void 0:e.levelFilter)||void 0===i?void 0:i.length)||e.levelFilter.includes(a.ldtkLevel.identifier))for(let e of a.layers)if(e instanceof s.TileLayer||e instanceof g.IntGridLayer)e.tilemap.pos=e.tilemap.pos.add(n),o||(e.tilemap.pos=e.tilemap.pos.sub(e.worldPos)),t.add(e.tilemap);else for(let i of e.entities){let s=i.get(h.TransformComponent);s&&(s.pos=s.pos.add(n),o||(s.pos=s.pos.sub(e.worldPos))),t.add(i)}if(this.useExcaliburWiring){let e=this.getLdtkEntitiesByField("camera",!0)[0];if(e){t.camera.pos=(0,h.vec)(e.px[0],e.px[0]);let i=e.fieldInstances.find(t=>"zoom"===t.__identifier.toLocaleLowerCase());i&&(t.camera.zoom=+i.__value)}}if(this.useTilemapCameraStrategy){let i=this.getLevelBounds(null==e?void 0:e.levelFilter);t.camera.strategy.limitCameraBounds(i)}if(this.useMapBackgroundColor){for(let[i,s]of this.levels.entries())if(!(null===(r=null==e?void 0:e.levelFilter)||void 0===r?void 0:r.length)||e.levelFilter.includes(s.ldtkLevel.identifier)){t.backgroundColor=s.backgroundColor;break}}}}e.LdtkResource=_,_.supportedLdtkVersion="1.5.3"},515:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.LevelResource=void 0;let s=i(205),r=i(289),n=i(710),o=i(512),a=i(699);e.LevelResource=class{constructor(t,e,i){this.path=t,this.resource=e,this.fileLoader=n.FetchLoader,this.strict=!0,this.headless=!1;let{headless:o,strict:a,fileLoader:l,imageLoader:h,pathMap:d}={...i};this.fileLoader=null!=l?l:this.fileLoader,this.strict=null!=a?a:this.strict,this.headless=null!=o?o:this.headless,this.imageLoader=null!=h?h:new r.LoaderCache(s.ImageSource),this.pathMap=null!=d?d:this.pathMap}async load(){let t;let e=await this.fileLoader(this.path,"json");if(this.strict)try{t=a.LdtkLevel.parse(e)}catch(t){throw console.error(`Could not parse LDtk level data at ${this.path} are you sure a level is there and not corrupt?`),t}else t=e;return this.data=new o.Level(t,this.resource)}isLoaded(){return!!this.data}}},512:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Level=void 0;let s=i(205),r=i(961),n=i(920),o=i(692);e.Level=class{constructor(t,e){var i,a,l;if(this.ldtkLevel=t,this.resource=e,this.layers=[],t.__bgColor&&(this.backgroundColor=s.Color.fromHex(t.__bgColor)),t.layerInstances){let s=e.startZIndex;for(let h of t.layerInstances.slice().reverse())0!==(null===(i=h.entityInstances)||void 0===i?void 0:i.length)&&this.layers.push(new r.EntityLayer(this,h,e,s)),0!==(null===(a=h.gridTiles)||void 0===a?void 0:a.length)&&this.layers.push(new o.TileLayer(this,h,e,s)),0!==(null===(l=h.intGridCsv)||void 0===l?void 0:l.length)&&this.layers.push(new n.IntGridLayer(this,h,e,s)),s++}}}},289:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.LoaderCache=void 0,e.LoaderCache=class{constructor(t){this.type=t,this._loaded=!1,this.cache=new Map}getOrAdd(...t){let e=this.cache.get(t.join("+"));return e||(e=new this.type(...t),this.cache.set(t.join("+"),e),e)}values(){if(this._loaded)return Array.from(this.cache.values());throw Error("Read through cache not yet loaded! No values to return!")}async load(){let t=Array.from(this.cache.entries()),e=await Promise.allSettled(t.map(t=>t[1].load())),i=0;for(let s=0;s{function i(t,e){for(let{path:i,output:s}of e)if("string"==typeof i){if(t.includes(i))return s}else{let e=t.match(i);if(e)return s.replace("[match]",e[0])}return t}function s(t,e){if(!e)return!1;for(let{path:i,output:s}of e)if("string"==typeof i){if(t.includes(i))return!0}else if(t.match(i))return!0;return!1}Object.defineProperty(e,"__esModule",{value:!0}),e.pathRelativeToBase=e.pathInMap=e.mapPath=e.filenameFromPath=void 0,e.filenameFromPath=function(t){let e=t.match(/[^/\\&\?]+\.\w{2,4}(?=([\#\?&].*$|$))/gi);if(e)return e[0];throw Error(`Could not locate filename from path: ${t}`)},e.mapPath=i,e.pathInMap=s,e.pathRelativeToBase=function(t,e,r){if(s(e,r)&&r)return i(e,r);if(0===e.indexOf("/"))return e;let n=t.split("/"),o=e.split("/");return n[n.length-1].includes(".")&&n.pop(),n.concat(o).join("/")}},692:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.TileLayer=void 0;let s=i(205);e.TileLayer=class{constructor(t,e,i,r){for(let n of(this.order=r,this.worldPos=(0,s.vec)(t.ldtkLevel.worldX,t.ldtkLevel.worldY),this.offset=(0,s.vec)(e.__pxTotalOffsetX,e.__pxTotalOffsetY),this.ldtkLayer=e,this.tilemap=new s.TileMap({name:e.__identifier,pos:this.worldPos.add(this.offset),tileWidth:e.__gridSize,tileHeight:e.__gridSize,rows:e.__cHei,columns:e.__cWid}),this.tilemap.z=r,e.gridTiles)){let t=Math.floor(n.px[0]/e.__gridSize),s=Math.floor(n.px[1]/e.__gridSize),r=this.tilemap.getTile(t,s);if(e.__tilesetDefUid){let t=i.tilesets.get(e.__tilesetDefUid);if(t){let e=Math.floor(n.src[0]/t.ldtkTileset.tileGridSize),i=Math.floor(n.src[1]/t.ldtkTileset.tileGridSize),s=t.spritesheet.getSprite(e,i);s?r.addGraphic(s):console.error("Could not find sprite in LDtk spritesheet at",e,i)}}else console.error("Could not tileset in LDtk",e.__tilesetDefUid,e.__tilesetRelPath)}}}},245:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Tileset=void 0;let s=i(205);e.Tileset=class{constructor(t){let{image:e,ldtkTileset:i}=t;this.image=e,this.ldtkTileset=i,this.spritesheet=s.SpriteSheet.fromImageSource({image:e,grid:{rows:i.pxHei/i.tileGridSize,columns:i.pxWid/i.tileGridSize,spriteHeight:i.tileGridSize,spriteWidth:i.tileGridSize}})}}},699:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.LdtkProjectMetadata=e.LdtkEntityDefinition=e.LdtkLayerDefinition=e.LdtkLevel=e.LdtkLayerInstance=e.LdtkEntityInstance=void 0;let s=i(754),r=s.z.object({h:s.z.number(),tilesetUid:s.z.number(),w:s.z.number(),x:s.z.number(),y:s.z.number()}),n=s.z.tuple([s.z.number(),s.z.number()]),o=s.z.object({__identifier:s.z.string(),__tile:r.nullable(),__type:s.z.string(),__value:s.z.any(),defUid:s.z.number()}),a=s.z.object({a:s.z.number(),f:s.z.number(),px:n,src:n,t:s.z.number()});e.LdtkEntityInstance=s.z.object({__grid:n,__identifier:s.z.string(),__pivot:n,__smartColor:s.z.string(),__tags:s.z.array(s.z.string()),__tile:r.nullable(),__worldX:s.z.number().nullable(),__worldY:s.z.number().nullable(),defUid:s.z.number(),fieldInstances:s.z.array(o),height:s.z.number(),iid:s.z.string(),px:n,width:s.z.number()}),e.LdtkLayerInstance=s.z.object({__cHei:s.z.number(),__cWid:s.z.number(),__gridSize:s.z.number(),__identifier:s.z.string(),__opacity:s.z.number(),__pxTotalOffsetX:s.z.number(),__pxTotalOffsetY:s.z.number(),__tilesetDefUid:s.z.number().nullable(),__tilesetRelPath:s.z.string().nullable(),__type:s.z.union([s.z.literal("IntGrid"),s.z.literal("Entities"),s.z.literal("Tiles"),s.z.literal("AutoLayer")]),autoLayerTiles:s.z.array(a),entityInstances:s.z.array(e.LdtkEntityInstance),gridTiles:s.z.array(a),iid:s.z.string(),intGridCsv:s.z.array(s.z.number()),layerDefUid:s.z.number(),levelId:s.z.number(),overrideTilesetUid:s.z.number().nullable(),pxOffsetX:s.z.number(),pxOffsetY:s.z.number(),visible:s.z.boolean()}),e.LdtkLevel=s.z.object({__bgColor:s.z.string().nullable(),bgColor:s.z.string().nullable(),__bgPos:s.z.object({cropRect:s.z.array(s.z.tuple([s.z.number(),s.z.number(),s.z.number(),s.z.number()])),scale:s.z.tuple([s.z.number(),s.z.number()]),topLeftPx:n}).nullable(),__neighbours:s.z.array(s.z.object({dir:s.z.union([s.z.literal("n"),s.z.literal("s"),s.z.literal("w"),s.z.literal("e"),s.z.literal("ne"),s.z.literal("nw"),s.z.literal("se"),s.z.literal("sw"),s.z.literal("o"),s.z.literal("<"),s.z.literal(">")]),levelIid:s.z.string()})),bgRelPath:s.z.string().nullable(),externalRelPath:s.z.string().nullable(),fieldInstances:s.z.array(o),identifier:s.z.string(),iid:s.z.string(),layerInstances:s.z.array(e.LdtkLayerInstance).nullable(),pxHei:s.z.number(),pxWid:s.z.number(),uid:s.z.number(),worldDepth:s.z.number(),worldX:s.z.number(),worldY:s.z.number()});let l=s.z.object({identifier:s.z.string(),iid:s.z.string(),levels:s.z.array(e.LdtkLevel),worldGridHeight:s.z.number(),worldGridWidth:s.z.number(),worldLayout:s.z.union([s.z.literal("Free"),s.z.literal("GridVania"),s.z.literal("LinearHorizontal"),s.z.literal("LinearVertical")])}),h=s.z.object({color:s.z.number(),id:s.z.string(),tileRect:r.nullable()}),d=s.z.object({externalRelPath:s.z.string().nullable(),iconTilesetUid:s.z.number().nullable(),identifier:s.z.string(),tags:s.z.array(s.z.string()),uid:s.z.number(),values:s.z.array(h)}),c=s.z.object({__cHei:s.z.number(),__cWid:s.z.number(),customData:s.z.array(s.z.object({data:s.z.string(),tileId:s.z.number()})),embedAtlas:s.z.string().nullable(),enumsTags:s.z.optional(s.z.array(s.z.object({enumValueId:s.z.string(),tileIds:s.z.array(s.z.number())}))),identifier:s.z.string(),padding:s.z.number(),pxHei:s.z.number(),pxWid:s.z.number(),relPath:s.z.string().nullable(),spacing:s.z.number(),tags:s.z.array(s.z.string()),tagsSourceEnumUid:s.z.number().nullable(),tileGridSize:s.z.number(),uid:s.z.number()});e.LdtkLayerDefinition=s.z.object({__type:s.z.union([s.z.literal("IntGrid"),s.z.literal("Entities"),s.z.literal("Tiles"),s.z.literal("AutoLayer")]),autoSourceLayerDefUid:s.z.number().nullable(),displayOpacity:s.z.number(),gridSize:s.z.number(),identifier:s.z.string(),intGridValues:s.z.array(s.z.object({color:s.z.string(),groupUid:s.z.number(),identifier:s.z.string().nullable(),tile:r.nullable(),value:s.z.number()})),intGridValuesGroups:s.z.array(s.z.object({color:s.z.string().nullable(),identifier:s.z.string().nullable(),uid:s.z.number()})),parallaxFactorX:s.z.number(),parallaxFactorY:s.z.number(),parallaxScaling:s.z.boolean(),pxOffsetX:s.z.number(),pxOffsetY:s.z.number(),tilesetDefUid:s.z.number().nullable(),uid:s.z.number()}),e.LdtkEntityDefinition=s.z.object({color:s.z.string(),height:s.z.number(),identifier:s.z.string(),nineSliceBorders:s.z.array(s.z.number()),pivotX:s.z.number(),pivotY:s.z.number(),tileRect:r.nullable(),tileRenderMode:s.z.union([s.z.literal("Cover"),s.z.literal("FitInside"),s.z.literal("Repeat"),s.z.literal("Stretch"),s.z.literal("FullSizeCropped"),s.z.literal("FullSizeUncropped"),s.z.literal("NineSlice")]),tilesetId:s.z.number().nullable(),uiTileRect:r.nullable(),uid:s.z.number(),width:s.z.number()});let u=s.z.object({tilesets:s.z.array(c),enums:s.z.array(d),layers:s.z.array(e.LdtkLayerDefinition),entities:s.z.array(e.LdtkEntityDefinition)});e.LdtkProjectMetadata=s.z.object({iid:s.z.string(),bgColor:s.z.string().nullable(),defs:u,externalLevels:s.z.boolean(),jsonVersion:s.z.string(),levels:s.z.array(e.LdtkLevel),toc:s.z.array(s.z.object({identifier:s.z.string(),instancesData:s.z.array(s.z.object({fields:s.z.any(),heiPx:s.z.number(),iids:s.z.string(),widPix:s.z.number(),worldX:s.z.number(),worldY:s.z.number()}))})),worldGridHeight:s.z.number().nullable(),worldGridWidth:s.z.number().nullable(),worldLayout:s.z.union([s.z.literal("Free"),s.z.literal("GridVania"),s.z.literal("LinearHorizontal"),s.z.literal("LinearVertical")]).nullable(),worlds:s.z.array(l)})},280:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.ZodError=e.quotelessJson=e.ZodIssueCode=void 0;let s=i(110);e.ZodIssueCode=s.util.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]),e.quotelessJson=t=>JSON.stringify(t,null,2).replace(/"([^"]+)":/g,"$1:");class r extends Error{constructor(t){super(),this.issues=[],this.addIssue=t=>{this.issues=[...this.issues,t]},this.addIssues=(t=[])=>{this.issues=[...this.issues,...t]};let e=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,e):this.__proto__=e,this.name="ZodError",this.issues=t}get errors(){return this.issues}format(t){let e=t||function(t){return t.message},i={_errors:[]},s=t=>{for(let r of t.issues)if("invalid_union"===r.code)r.unionErrors.map(s);else if("invalid_return_type"===r.code)s(r.returnTypeError);else if("invalid_arguments"===r.code)s(r.argumentsError);else if(0===r.path.length)i._errors.push(e(r));else{let t=i,s=0;for(;st.message){let e={},i=[];for(let s of this.issues)s.path.length>0?(e[s.path[0]]=e[s.path[0]]||[],e[s.path[0]].push(t(s))):i.push(t(s));return{formErrors:i,fieldErrors:e}}get formErrors(){return this.flatten()}}e.ZodError=r,r.create=t=>new r(t)},996:function(t,e,i){var s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.getErrorMap=e.setErrorMap=e.defaultErrorMap=void 0;let r=s(i(325));e.defaultErrorMap=r.default;let n=r.default;e.setErrorMap=function(t){n=t},e.getErrorMap=function(){return n}},349:function(t,e,i){var s=this&&this.__createBinding||(Object.create?function(t,e,i,s){void 0===s&&(s=i),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[i]}})}:function(t,e,i,s){void 0===s&&(s=i),t[s]=e[i]}),r=this&&this.__exportStar||function(t,e){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(e,i)||s(e,t,i)};Object.defineProperty(e,"__esModule",{value:!0}),r(i(996),e),r(i(187),e),r(i(116),e),r(i(110),e),r(i(433),e),r(i(280),e)},762:(t,e)=>{var i;Object.defineProperty(e,"__esModule",{value:!0}),e.errorUtil=void 0,(i=e.errorUtil||(e.errorUtil={})).errToObj=t=>"string"==typeof t?{message:t}:t||{},i.toString=t=>"string"==typeof t?t:null==t?void 0:t.message},187:function(t,e,i){var s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.isAsync=e.isValid=e.isDirty=e.isAborted=e.OK=e.DIRTY=e.INVALID=e.ParseStatus=e.addIssueToContext=e.EMPTY_PATH=e.makeIssue=void 0;let r=i(996),n=s(i(325));e.makeIssue=t=>{let{data:e,path:i,errorMaps:s,issueData:r}=t,n=[...i,...r.path||[]],o={...r,path:n},a="";for(let t of s.filter(t=>!!t).slice().reverse())a=t(o,{data:e,defaultError:a}).message;return{...r,path:n,message:r.message||a}},e.EMPTY_PATH=[],e.addIssueToContext=function(t,i){let s=(0,e.makeIssue)({issueData:i,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,(0,r.getErrorMap)(),n.default].filter(t=>!!t)});t.common.issues.push(s)};class o{constructor(){this.value="valid"}dirty(){"valid"===this.value&&(this.value="dirty")}abort(){"aborted"!==this.value&&(this.value="aborted")}static mergeArray(t,i){let s=[];for(let r of i){if("aborted"===r.status)return e.INVALID;"dirty"===r.status&&t.dirty(),s.push(r.value)}return{status:t.value,value:s}}static async mergeObjectAsync(t,e){let i=[];for(let t of e)i.push({key:await t.key,value:await t.value});return o.mergeObjectSync(t,i)}static mergeObjectSync(t,i){let s={};for(let r of i){let{key:i,value:n}=r;if("aborted"===i.status||"aborted"===n.status)return e.INVALID;"dirty"===i.status&&t.dirty(),"dirty"===n.status&&t.dirty(),"__proto__"!==i.value&&(void 0!==n.value||r.alwaysSet)&&(s[i.value]=n.value)}return{status:t.value,value:s}}}e.ParseStatus=o,e.INVALID=Object.freeze({status:"aborted"}),e.DIRTY=t=>({status:"dirty",value:t}),e.OK=t=>({status:"valid",value:t}),e.isAborted=t=>"aborted"===t.status,e.isDirty=t=>"dirty"===t.status,e.isValid=t=>"valid"===t.status,e.isAsync=t=>"undefined"!=typeof Promise&&t instanceof Promise},116:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},110:(t,e)=>{var i,s;Object.defineProperty(e,"__esModule",{value:!0}),e.getParsedType=e.ZodParsedType=e.objectUtil=e.util=void 0,(s=i=e.util||(e.util={})).assertEqual=t=>t,s.assertIs=function(t){},s.assertNever=function(t){throw Error()},s.arrayToEnum=t=>{let e={};for(let i of t)e[i]=i;return e},s.getValidEnumValues=t=>{let e=s.objectKeys(t).filter(e=>"number"!=typeof t[t[e]]),i={};for(let s of e)i[s]=t[s];return s.objectValues(i)},s.objectValues=t=>s.objectKeys(t).map(function(e){return t[e]}),s.objectKeys="function"==typeof Object.keys?t=>Object.keys(t):t=>{let e=[];for(let i in t)Object.prototype.hasOwnProperty.call(t,i)&&e.push(i);return e},s.find=(t,e)=>{for(let i of t)if(e(i))return i},s.isInteger="function"==typeof Number.isInteger?t=>Number.isInteger(t):t=>"number"==typeof t&&isFinite(t)&&Math.floor(t)===t,s.joinValues=function(t,e=" | "){return t.map(t=>"string"==typeof t?`'${t}'`:t).join(e)},s.jsonStringifyReplacer=(t,e)=>"bigint"==typeof e?e.toString():e,(e.objectUtil||(e.objectUtil={})).mergeShapes=(t,e)=>({...t,...e}),e.ZodParsedType=i.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),e.getParsedType=t=>{switch(typeof t){case"undefined":return e.ZodParsedType.undefined;case"string":return e.ZodParsedType.string;case"number":return isNaN(t)?e.ZodParsedType.nan:e.ZodParsedType.number;case"boolean":return e.ZodParsedType.boolean;case"function":return e.ZodParsedType.function;case"bigint":return e.ZodParsedType.bigint;case"symbol":return e.ZodParsedType.symbol;case"object":return Array.isArray(t)?e.ZodParsedType.array:null===t?e.ZodParsedType.null:t.then&&"function"==typeof t.then&&t.catch&&"function"==typeof t.catch?e.ZodParsedType.promise:"undefined"!=typeof Map&&t instanceof Map?e.ZodParsedType.map:"undefined"!=typeof Set&&t instanceof Set?e.ZodParsedType.set:"undefined"!=typeof Date&&t instanceof Date?e.ZodParsedType.date:e.ZodParsedType.object;default:return e.ZodParsedType.unknown}}},754:function(t,e,i){var s=this&&this.__createBinding||(Object.create?function(t,e,i,s){void 0===s&&(s=i),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[i]}})}:function(t,e,i,s){void 0===s&&(s=i),t[s]=e[i]}),r=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),n=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)"default"!==i&&Object.prototype.hasOwnProperty.call(t,i)&&s(e,t,i);return r(e,t),e},o=this&&this.__exportStar||function(t,e){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(e,i)||s(e,t,i)};Object.defineProperty(e,"__esModule",{value:!0}),e.z=void 0;let a=n(i(349));e.z=a,o(i(349),e),e.default=a},325:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});let s=i(110),r=i(280);e.default=(t,e)=>{let i;switch(t.code){case r.ZodIssueCode.invalid_type:i=t.received===s.ZodParsedType.undefined?"Required":`Expected ${t.expected}, received ${t.received}`;break;case r.ZodIssueCode.invalid_literal:i=`Invalid literal value, expected ${JSON.stringify(t.expected,s.util.jsonStringifyReplacer)}`;break;case r.ZodIssueCode.unrecognized_keys:i=`Unrecognized key(s) in object: ${s.util.joinValues(t.keys,", ")}`;break;case r.ZodIssueCode.invalid_union:i="Invalid input";break;case r.ZodIssueCode.invalid_union_discriminator:i=`Invalid discriminator value. Expected ${s.util.joinValues(t.options)}`;break;case r.ZodIssueCode.invalid_enum_value:i=`Invalid enum value. Expected ${s.util.joinValues(t.options)}, received '${t.received}'`;break;case r.ZodIssueCode.invalid_arguments:i="Invalid function arguments";break;case r.ZodIssueCode.invalid_return_type:i="Invalid function return type";break;case r.ZodIssueCode.invalid_date:i="Invalid date";break;case r.ZodIssueCode.invalid_string:"object"==typeof t.validation?"includes"in t.validation?(i=`Invalid input: must include "${t.validation.includes}"`,"number"==typeof t.validation.position&&(i=`${i} at one or more positions greater than or equal to ${t.validation.position}`)):"startsWith"in t.validation?i=`Invalid input: must start with "${t.validation.startsWith}"`:"endsWith"in t.validation?i=`Invalid input: must end with "${t.validation.endsWith}"`:s.util.assertNever(t.validation):i="regex"!==t.validation?`Invalid ${t.validation}`:"Invalid";break;case r.ZodIssueCode.too_small:i="array"===t.type?`Array must contain ${t.exact?"exactly":t.inclusive?"at least":"more than"} ${t.minimum} element(s)`:"string"===t.type?`String must contain ${t.exact?"exactly":t.inclusive?"at least":"over"} ${t.minimum} character(s)`:"number"===t.type?`Number must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${t.minimum}`:"date"===t.type?`Date must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(t.minimum))}`:"Invalid input";break;case r.ZodIssueCode.too_big:i="array"===t.type?`Array must contain ${t.exact?"exactly":t.inclusive?"at most":"less than"} ${t.maximum} element(s)`:"string"===t.type?`String must contain ${t.exact?"exactly":t.inclusive?"at most":"under"} ${t.maximum} character(s)`:"number"===t.type?`Number must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:"bigint"===t.type?`BigInt must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:"date"===t.type?`Date must be ${t.exact?"exactly":t.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(t.maximum))}`:"Invalid input";break;case r.ZodIssueCode.custom:i="Invalid input";break;case r.ZodIssueCode.invalid_intersection_types:i="Intersection results could not be merged";break;case r.ZodIssueCode.not_multiple_of:i=`Number must be a multiple of ${t.multipleOf}`;break;case r.ZodIssueCode.not_finite:i="Number must be finite";break;default:i=e.defaultError,s.util.assertNever(t)}return{message:i}}},433:(t,e,i)=>{var s,r;let n;Object.defineProperty(e,"__esModule",{value:!0}),e.date=e.boolean=e.bigint=e.array=e.any=e.coerce=e.ZodFirstPartyTypeKind=e.late=e.ZodSchema=e.Schema=e.custom=e.ZodReadonly=e.ZodPipeline=e.ZodBranded=e.BRAND=e.ZodNaN=e.ZodCatch=e.ZodDefault=e.ZodNullable=e.ZodOptional=e.ZodTransformer=e.ZodEffects=e.ZodPromise=e.ZodNativeEnum=e.ZodEnum=e.ZodLiteral=e.ZodLazy=e.ZodFunction=e.ZodSet=e.ZodMap=e.ZodRecord=e.ZodTuple=e.ZodIntersection=e.ZodDiscriminatedUnion=e.ZodUnion=e.ZodObject=e.ZodArray=e.ZodVoid=e.ZodNever=e.ZodUnknown=e.ZodAny=e.ZodNull=e.ZodUndefined=e.ZodSymbol=e.ZodDate=e.ZodBoolean=e.ZodBigInt=e.ZodNumber=e.ZodString=e.ZodType=void 0,e.NEVER=e.void=e.unknown=e.union=e.undefined=e.tuple=e.transformer=e.symbol=e.string=e.strictObject=e.set=e.record=e.promise=e.preprocess=e.pipeline=e.ostring=e.optional=e.onumber=e.oboolean=e.object=e.number=e.nullable=e.null=e.never=e.nativeEnum=e.nan=e.map=e.literal=e.lazy=e.intersection=e.instanceof=e.function=e.enum=e.effect=e.discriminatedUnion=void 0;let o=i(996),a=i(762),l=i(187),h=i(110),d=i(280);class c{constructor(t,e,i,s){this._cachedPath=[],this.parent=t,this.data=e,this._path=i,this._key=s}get path(){return this._cachedPath.length||(this._key instanceof Array?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}}let u=(t,e)=>{if((0,l.isValid)(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;let e=new d.ZodError(t.common.issues);return this._error=e,this._error}}};function p(t){if(!t)return{};let{errorMap:e,invalid_type_error:i,required_error:s,description:r}=t;if(e&&(i||s))throw Error('Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.');return e?{errorMap:e,description:r}:{errorMap:(t,e)=>"invalid_type"!==t.code?{message:e.defaultError}:void 0===e.data?{message:null!=s?s:e.defaultError}:{message:null!=i?i:e.defaultError},description:r}}class g{constructor(t){this.spa=this.safeParseAsync,this._def=t,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this)}get description(){return this._def.description}_getType(t){return(0,h.getParsedType)(t.data)}_getOrReturnCtx(t,e){return e||{common:t.parent.common,data:t.data,parsedType:(0,h.getParsedType)(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}_processInputParams(t){return{status:new l.ParseStatus,ctx:{common:t.parent.common,data:t.data,parsedType:(0,h.getParsedType)(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}}_parseSync(t){let e=this._parse(t);if((0,l.isAsync)(e))throw Error("Synchronous parse encountered promise.");return e}_parseAsync(t){return Promise.resolve(this._parse(t))}parse(t,e){let i=this.safeParse(t,e);if(i.success)return i.data;throw i.error}safeParse(t,e){var i;let s={common:{issues:[],async:null!==(i=null==e?void 0:e.async)&&void 0!==i&&i,contextualErrorMap:null==e?void 0:e.errorMap},path:(null==e?void 0:e.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:(0,h.getParsedType)(t)},r=this._parseSync({data:t,path:s.path,parent:s});return u(s,r)}async parseAsync(t,e){let i=await this.safeParseAsync(t,e);if(i.success)return i.data;throw i.error}async safeParseAsync(t,e){let i={common:{issues:[],contextualErrorMap:null==e?void 0:e.errorMap,async:!0},path:(null==e?void 0:e.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:(0,h.getParsedType)(t)},s=this._parse({data:t,path:i.path,parent:i});return u(i,await ((0,l.isAsync)(s)?s:Promise.resolve(s)))}refine(t,e){let i=t=>"string"==typeof e||void 0===e?{message:e}:"function"==typeof e?e(t):e;return this._refinement((e,s)=>{let r=t(e),n=()=>s.addIssue({code:d.ZodIssueCode.custom,...i(e)});return"undefined"!=typeof Promise&&r instanceof Promise?r.then(t=>!!t||(n(),!1)):!!r||(n(),!1)})}refinement(t,e){return this._refinement((i,s)=>!!t(i)||(s.addIssue("function"==typeof e?e(i,s):e),!1))}_refinement(t){return new Y({schema:this,typeName:s.ZodEffects,effect:{type:"refinement",refinement:t}})}superRefine(t){return this._refinement(t)}optional(){return Q.create(this,this._def)}nullable(){return J.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return B.create(this,this._def)}promise(){return K.create(this,this._def)}or(t){return M.create([this,t],this._def)}and(t){return U.create(this,t,this._def)}transform(t){return new Y({...p(this._def),schema:this,typeName:s.ZodEffects,effect:{type:"transform",transform:t}})}default(t){return new tt({...p(this._def),innerType:this,defaultValue:"function"==typeof t?t:()=>t,typeName:s.ZodDefault})}brand(){return new ts({typeName:s.ZodBranded,type:this,...p(this._def)})}catch(t){return new te({...p(this._def),innerType:this,catchValue:"function"==typeof t?t:()=>t,typeName:s.ZodCatch})}describe(t){return new this.constructor({...this._def,description:t})}pipe(t){return tr.create(this,t)}readonly(){return tn.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}}e.ZodType=g,e.Schema=g,e.ZodSchema=g;let _=/^c[^\s-]{8,}$/i,f=/^[a-z][a-z0-9]*$/,m=/^[0-9A-HJKMNP-TV-Z]{26}$/,v=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,y=/^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,x=/^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/,w=/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;class b extends g{_parse(t){var e,i;let s;if(this._def.coerce&&(t.data=String(t.data)),this._getType(t)!==h.ZodParsedType.string){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.string,received:e.parsedType}),l.INVALID}let r=new l.ParseStatus;for(let o of this._def.checks)if("min"===o.kind)t.data.lengtho.value&&(s=this._getOrReturnCtx(t,s),(0,l.addIssueToContext)(s,{code:d.ZodIssueCode.too_big,maximum:o.value,type:"string",inclusive:!0,exact:!1,message:o.message}),r.dirty());else if("length"===o.kind){let e=t.data.length>o.value,i=t.data.lengtht.test(e),{validation:e,code:d.ZodIssueCode.invalid_string,...a.errorUtil.errToObj(i)})}_addCheck(t){return new b({...this._def,checks:[...this._def.checks,t]})}email(t){return this._addCheck({kind:"email",...a.errorUtil.errToObj(t)})}url(t){return this._addCheck({kind:"url",...a.errorUtil.errToObj(t)})}emoji(t){return this._addCheck({kind:"emoji",...a.errorUtil.errToObj(t)})}uuid(t){return this._addCheck({kind:"uuid",...a.errorUtil.errToObj(t)})}cuid(t){return this._addCheck({kind:"cuid",...a.errorUtil.errToObj(t)})}cuid2(t){return this._addCheck({kind:"cuid2",...a.errorUtil.errToObj(t)})}ulid(t){return this._addCheck({kind:"ulid",...a.errorUtil.errToObj(t)})}ip(t){return this._addCheck({kind:"ip",...a.errorUtil.errToObj(t)})}datetime(t){var e;return"string"==typeof t?this._addCheck({kind:"datetime",precision:null,offset:!1,message:t}):this._addCheck({kind:"datetime",precision:void 0===(null==t?void 0:t.precision)?null:null==t?void 0:t.precision,offset:null!==(e=null==t?void 0:t.offset)&&void 0!==e&&e,...a.errorUtil.errToObj(null==t?void 0:t.message)})}regex(t,e){return this._addCheck({kind:"regex",regex:t,...a.errorUtil.errToObj(e)})}includes(t,e){return this._addCheck({kind:"includes",value:t,position:null==e?void 0:e.position,...a.errorUtil.errToObj(null==e?void 0:e.message)})}startsWith(t,e){return this._addCheck({kind:"startsWith",value:t,...a.errorUtil.errToObj(e)})}endsWith(t,e){return this._addCheck({kind:"endsWith",value:t,...a.errorUtil.errToObj(e)})}min(t,e){return this._addCheck({kind:"min",value:t,...a.errorUtil.errToObj(e)})}max(t,e){return this._addCheck({kind:"max",value:t,...a.errorUtil.errToObj(e)})}length(t,e){return this._addCheck({kind:"length",value:t,...a.errorUtil.errToObj(e)})}nonempty(t){return this.min(1,a.errorUtil.errToObj(t))}trim(){return new b({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new b({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new b({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(t=>"datetime"===t.kind)}get isEmail(){return!!this._def.checks.find(t=>"email"===t.kind)}get isURL(){return!!this._def.checks.find(t=>"url"===t.kind)}get isEmoji(){return!!this._def.checks.find(t=>"emoji"===t.kind)}get isUUID(){return!!this._def.checks.find(t=>"uuid"===t.kind)}get isCUID(){return!!this._def.checks.find(t=>"cuid"===t.kind)}get isCUID2(){return!!this._def.checks.find(t=>"cuid2"===t.kind)}get isULID(){return!!this._def.checks.find(t=>"ulid"===t.kind)}get isIP(){return!!this._def.checks.find(t=>"ip"===t.kind)}get minLength(){let t=null;for(let e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxLength(){let t=null;for(let e of this._def.checks)"max"===e.kind&&(null===t||e.value{var e;return new b({checks:[],typeName:s.ZodString,coerce:null!==(e=null==t?void 0:t.coerce)&&void 0!==e&&e,...p(t)})};class C extends g{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){let e;if(this._def.coerce&&(t.data=Number(t.data)),this._getType(t)!==h.ZodParsedType.number){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.number,received:e.parsedType}),l.INVALID}let i=new l.ParseStatus;for(let s of this._def.checks)"int"===s.kind?h.util.isInteger(t.data)||(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:"integer",received:"float",message:s.message}),i.dirty()):"min"===s.kind?(s.inclusive?t.datas.value:t.data>=s.value)&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.too_big,maximum:s.value,type:"number",inclusive:s.inclusive,exact:!1,message:s.message}),i.dirty()):"multipleOf"===s.kind?0!==function(t,e){let i=(t.toString().split(".")[1]||"").length,s=(e.toString().split(".")[1]||"").length,r=i>s?i:s;return parseInt(t.toFixed(r).replace(".",""))%parseInt(e.toFixed(r).replace(".",""))/Math.pow(10,r)}(t.data,s.value)&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.not_multiple_of,multipleOf:s.value,message:s.message}),i.dirty()):"finite"===s.kind?Number.isFinite(t.data)||(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.not_finite,message:s.message}),i.dirty()):h.util.assertNever(s);return{status:i.value,value:t.data}}gte(t,e){return this.setLimit("min",t,!0,a.errorUtil.toString(e))}gt(t,e){return this.setLimit("min",t,!1,a.errorUtil.toString(e))}lte(t,e){return this.setLimit("max",t,!0,a.errorUtil.toString(e))}lt(t,e){return this.setLimit("max",t,!1,a.errorUtil.toString(e))}setLimit(t,e,i,s){return new C({...this._def,checks:[...this._def.checks,{kind:t,value:e,inclusive:i,message:a.errorUtil.toString(s)}]})}_addCheck(t){return new C({...this._def,checks:[...this._def.checks,t]})}int(t){return this._addCheck({kind:"int",message:a.errorUtil.toString(t)})}positive(t){return this._addCheck({kind:"min",value:0,inclusive:!1,message:a.errorUtil.toString(t)})}negative(t){return this._addCheck({kind:"max",value:0,inclusive:!1,message:a.errorUtil.toString(t)})}nonpositive(t){return this._addCheck({kind:"max",value:0,inclusive:!0,message:a.errorUtil.toString(t)})}nonnegative(t){return this._addCheck({kind:"min",value:0,inclusive:!0,message:a.errorUtil.toString(t)})}multipleOf(t,e){return this._addCheck({kind:"multipleOf",value:t,message:a.errorUtil.toString(e)})}finite(t){return this._addCheck({kind:"finite",message:a.errorUtil.toString(t)})}safe(t){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:a.errorUtil.toString(t)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:a.errorUtil.toString(t)})}get minValue(){let t=null;for(let e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxValue(){let t=null;for(let e of this._def.checks)"max"===e.kind&&(null===t||e.value"int"===t.kind||"multipleOf"===t.kind&&h.util.isInteger(t.value))}get isFinite(){let t=null,e=null;for(let i of this._def.checks){if("finite"===i.kind||"int"===i.kind||"multipleOf"===i.kind)return!0;"min"===i.kind?(null===e||i.value>e)&&(e=i.value):"max"===i.kind&&(null===t||i.valuenew C({checks:[],typeName:s.ZodNumber,coerce:(null==t?void 0:t.coerce)||!1,...p(t)});class T extends g{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){let e;if(this._def.coerce&&(t.data=BigInt(t.data)),this._getType(t)!==h.ZodParsedType.bigint){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.bigint,received:e.parsedType}),l.INVALID}let i=new l.ParseStatus;for(let s of this._def.checks)"min"===s.kind?(s.inclusive?t.datas.value:t.data>=s.value)&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.too_big,type:"bigint",maximum:s.value,inclusive:s.inclusive,message:s.message}),i.dirty()):"multipleOf"===s.kind?t.data%s.value!==BigInt(0)&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.not_multiple_of,multipleOf:s.value,message:s.message}),i.dirty()):h.util.assertNever(s);return{status:i.value,value:t.data}}gte(t,e){return this.setLimit("min",t,!0,a.errorUtil.toString(e))}gt(t,e){return this.setLimit("min",t,!1,a.errorUtil.toString(e))}lte(t,e){return this.setLimit("max",t,!0,a.errorUtil.toString(e))}lt(t,e){return this.setLimit("max",t,!1,a.errorUtil.toString(e))}setLimit(t,e,i,s){return new T({...this._def,checks:[...this._def.checks,{kind:t,value:e,inclusive:i,message:a.errorUtil.toString(s)}]})}_addCheck(t){return new T({...this._def,checks:[...this._def.checks,t]})}positive(t){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:a.errorUtil.toString(t)})}negative(t){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:a.errorUtil.toString(t)})}nonpositive(t){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:a.errorUtil.toString(t)})}nonnegative(t){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:a.errorUtil.toString(t)})}multipleOf(t,e){return this._addCheck({kind:"multipleOf",value:t,message:a.errorUtil.toString(e)})}get minValue(){let t=null;for(let e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return t}get maxValue(){let t=null;for(let e of this._def.checks)"max"===e.kind&&(null===t||e.value{var e;return new T({checks:[],typeName:s.ZodBigInt,coerce:null!==(e=null==t?void 0:t.coerce)&&void 0!==e&&e,...p(t)})};class S extends g{_parse(t){if(this._def.coerce&&(t.data=!!t.data),this._getType(t)!==h.ZodParsedType.boolean){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.boolean,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodBoolean=S,S.create=t=>new S({typeName:s.ZodBoolean,coerce:(null==t?void 0:t.coerce)||!1,...p(t)});class A extends g{_parse(t){let e;if(this._def.coerce&&(t.data=new Date(t.data)),this._getType(t)!==h.ZodParsedType.date){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.date,received:e.parsedType}),l.INVALID}if(isNaN(t.data.getTime())){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_date}),l.INVALID}let i=new l.ParseStatus;for(let s of this._def.checks)"min"===s.kind?t.data.getTime()s.value&&(e=this._getOrReturnCtx(t,e),(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.too_big,message:s.message,inclusive:!0,exact:!1,maximum:s.value,type:"date"}),i.dirty()):h.util.assertNever(s);return{status:i.value,value:new Date(t.data.getTime())}}_addCheck(t){return new A({...this._def,checks:[...this._def.checks,t]})}min(t,e){return this._addCheck({kind:"min",value:t.getTime(),message:a.errorUtil.toString(e)})}max(t,e){return this._addCheck({kind:"max",value:t.getTime(),message:a.errorUtil.toString(e)})}get minDate(){let t=null;for(let e of this._def.checks)"min"===e.kind&&(null===t||e.value>t)&&(t=e.value);return null!=t?new Date(t):null}get maxDate(){let t=null;for(let e of this._def.checks)"max"===e.kind&&(null===t||e.valuenew A({checks:[],coerce:(null==t?void 0:t.coerce)||!1,typeName:s.ZodDate,...p(t)});class E extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.symbol){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.symbol,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodSymbol=E,E.create=t=>new E({typeName:s.ZodSymbol,...p(t)});class P extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.undefined){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.undefined,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodUndefined=P,P.create=t=>new P({typeName:s.ZodUndefined,...p(t)});class I extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.null){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.null,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodNull=I,I.create=t=>new I({typeName:s.ZodNull,...p(t)});class k extends g{constructor(){super(...arguments),this._any=!0}_parse(t){return(0,l.OK)(t.data)}}e.ZodAny=k,k.create=t=>new k({typeName:s.ZodAny,...p(t)});class D extends g{constructor(){super(...arguments),this._unknown=!0}_parse(t){return(0,l.OK)(t.data)}}e.ZodUnknown=D,D.create=t=>new D({typeName:s.ZodUnknown,...p(t)});class R extends g{_parse(t){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.never,received:e.parsedType}),l.INVALID}}e.ZodNever=R,R.create=t=>new R({typeName:s.ZodNever,...p(t)});class F extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.undefined){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.void,received:e.parsedType}),l.INVALID}return(0,l.OK)(t.data)}}e.ZodVoid=F,F.create=t=>new F({typeName:s.ZodVoid,...p(t)});class B extends g{_parse(t){let{ctx:e,status:i}=this._processInputParams(t),s=this._def;if(e.parsedType!==h.ZodParsedType.array)return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.array,received:e.parsedType}),l.INVALID;if(null!==s.exactLength){let t=e.data.length>s.exactLength.value,r=e.data.lengths.maxLength.value&&((0,l.addIssueToContext)(e,{code:d.ZodIssueCode.too_big,maximum:s.maxLength.value,type:"array",inclusive:!0,exact:!1,message:s.maxLength.message}),i.dirty()),e.common.async)return Promise.all([...e.data].map((t,i)=>s.type._parseAsync(new c(e,t,e.path,i)))).then(t=>l.ParseStatus.mergeArray(i,t));let r=[...e.data].map((t,i)=>s.type._parseSync(new c(e,t,e.path,i)));return l.ParseStatus.mergeArray(i,r)}get element(){return this._def.type}min(t,e){return new B({...this._def,minLength:{value:t,message:a.errorUtil.toString(e)}})}max(t,e){return new B({...this._def,maxLength:{value:t,message:a.errorUtil.toString(e)}})}length(t,e){return new B({...this._def,exactLength:{value:t,message:a.errorUtil.toString(e)}})}nonempty(t){return this.min(1,t)}}e.ZodArray=B,B.create=(t,e)=>new B({type:t,minLength:null,maxLength:null,exactLength:null,typeName:s.ZodArray,...p(e)});class L extends g{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;let t=this._def.shape(),e=h.util.objectKeys(t);return this._cached={shape:t,keys:e}}_parse(t){if(this._getType(t)!==h.ZodParsedType.object){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.object,received:e.parsedType}),l.INVALID}let{status:e,ctx:i}=this._processInputParams(t),{shape:s,keys:r}=this._getCached(),n=[];if(!(this._def.catchall instanceof R&&"strip"===this._def.unknownKeys))for(let t in i.data)r.includes(t)||n.push(t);let o=[];for(let t of r){let e=s[t],r=i.data[t];o.push({key:{status:"valid",value:t},value:e._parse(new c(i,r,i.path,t)),alwaysSet:t in i.data})}if(this._def.catchall instanceof R){let t=this._def.unknownKeys;if("passthrough"===t)for(let t of n)o.push({key:{status:"valid",value:t},value:{status:"valid",value:i.data[t]}});else if("strict"===t)n.length>0&&((0,l.addIssueToContext)(i,{code:d.ZodIssueCode.unrecognized_keys,keys:n}),e.dirty());else if("strip"!==t)throw Error("Internal ZodObject error: invalid unknownKeys value.")}else{let t=this._def.catchall;for(let e of n){let s=i.data[e];o.push({key:{status:"valid",value:e},value:t._parse(new c(i,s,i.path,e)),alwaysSet:e in i.data})}}return i.common.async?Promise.resolve().then(async()=>{let t=[];for(let e of o){let i=await e.key;t.push({key:i,value:await e.value,alwaysSet:e.alwaysSet})}return t}).then(t=>l.ParseStatus.mergeObjectSync(e,t)):l.ParseStatus.mergeObjectSync(e,o)}get shape(){return this._def.shape()}strict(t){return a.errorUtil.errToObj,new L({...this._def,unknownKeys:"strict",...void 0!==t?{errorMap:(e,i)=>{var s,r,n,o;let l=null!==(n=null===(r=(s=this._def).errorMap)||void 0===r?void 0:r.call(s,e,i).message)&&void 0!==n?n:i.defaultError;return"unrecognized_keys"===e.code?{message:null!==(o=a.errorUtil.errToObj(t).message)&&void 0!==o?o:l}:{message:l}}}:{}})}strip(){return new L({...this._def,unknownKeys:"strip"})}passthrough(){return new L({...this._def,unknownKeys:"passthrough"})}extend(t){return new L({...this._def,shape:()=>({...this._def.shape(),...t})})}merge(t){return new L({unknownKeys:t._def.unknownKeys,catchall:t._def.catchall,shape:()=>({...this._def.shape(),...t._def.shape()}),typeName:s.ZodObject})}setKey(t,e){return this.augment({[t]:e})}catchall(t){return new L({...this._def,catchall:t})}pick(t){let e={};return h.util.objectKeys(t).forEach(i=>{t[i]&&this.shape[i]&&(e[i]=this.shape[i])}),new L({...this._def,shape:()=>e})}omit(t){let e={};return h.util.objectKeys(this.shape).forEach(i=>{t[i]||(e[i]=this.shape[i])}),new L({...this._def,shape:()=>e})}deepPartial(){return function t(e){if(e instanceof L){let i={};for(let s in e.shape){let r=e.shape[s];i[s]=Q.create(t(r))}return new L({...e._def,shape:()=>i})}return e instanceof B?new B({...e._def,type:t(e.element)}):e instanceof Q?Q.create(t(e.unwrap())):e instanceof J?J.create(t(e.unwrap())):e instanceof N?N.create(e.items.map(e=>t(e))):e}(this)}partial(t){let e={};return h.util.objectKeys(this.shape).forEach(i=>{let s=this.shape[i];t&&!t[i]?e[i]=s:e[i]=s.optional()}),new L({...this._def,shape:()=>e})}required(t){let e={};return h.util.objectKeys(this.shape).forEach(i=>{if(t&&!t[i])e[i]=this.shape[i];else{let t=this.shape[i];for(;t instanceof Q;)t=t._def.innerType;e[i]=t}}),new L({...this._def,shape:()=>e})}keyof(){return q(h.util.objectKeys(this.shape))}}e.ZodObject=L,L.create=(t,e)=>new L({shape:()=>t,unknownKeys:"strip",catchall:R.create(),typeName:s.ZodObject,...p(e)}),L.strictCreate=(t,e)=>new L({shape:()=>t,unknownKeys:"strict",catchall:R.create(),typeName:s.ZodObject,...p(e)}),L.lazycreate=(t,e)=>new L({shape:t,unknownKeys:"strip",catchall:R.create(),typeName:s.ZodObject,...p(e)});class M extends g{_parse(t){let{ctx:e}=this._processInputParams(t),i=this._def.options;if(e.common.async)return Promise.all(i.map(async t=>{let i={...e,common:{...e.common,issues:[]},parent:null};return{result:await t._parseAsync({data:e.data,path:e.path,parent:i}),ctx:i}})).then(function(t){for(let e of t)if("valid"===e.result.status)return e.result;for(let i of t)if("dirty"===i.result.status)return e.common.issues.push(...i.ctx.common.issues),i.result;let i=t.map(t=>new d.ZodError(t.ctx.common.issues));return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_union,unionErrors:i}),l.INVALID});{let t;let s=[];for(let r of i){let i={...e,common:{...e.common,issues:[]},parent:null},n=r._parseSync({data:e.data,path:e.path,parent:i});if("valid"===n.status)return n;"dirty"!==n.status||t||(t={result:n,ctx:i}),i.common.issues.length&&s.push(i.common.issues)}if(t)return e.common.issues.push(...t.ctx.common.issues),t.result;let r=s.map(t=>new d.ZodError(t));return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_union,unionErrors:r}),l.INVALID}}get options(){return this._def.options}}e.ZodUnion=M,M.create=(t,e)=>new M({options:t,typeName:s.ZodUnion,...p(e)});let z=t=>t instanceof G?z(t.schema):t instanceof Y?z(t.innerType()):t instanceof j?[t.value]:t instanceof X?t.options:t instanceof $?Object.keys(t.enum):t instanceof tt?z(t._def.innerType):t instanceof P?[void 0]:t instanceof I?[null]:null;class O extends g{_parse(t){let{ctx:e}=this._processInputParams(t);if(e.parsedType!==h.ZodParsedType.object)return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.object,received:e.parsedType}),l.INVALID;let i=this.discriminator,s=e.data[i],r=this.optionsMap.get(s);return r?e.common.async?r._parseAsync({data:e.data,path:e.path,parent:e}):r._parseSync({data:e.data,path:e.path,parent:e}):((0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[i]}),l.INVALID)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(t,e,i){let r=new Map;for(let i of e){let e=z(i.shape[t]);if(!e)throw Error(`A discriminator value for key \`${t}\` could not be extracted from all schema options`);for(let s of e){if(r.has(s))throw Error(`Discriminator property ${String(t)} has duplicate value ${String(s)}`);r.set(s,i)}}return new O({typeName:s.ZodDiscriminatedUnion,discriminator:t,options:e,optionsMap:r,...p(i)})}}e.ZodDiscriminatedUnion=O;class U extends g{_parse(t){let{status:e,ctx:i}=this._processInputParams(t),s=(t,s)=>{if((0,l.isAborted)(t)||(0,l.isAborted)(s))return l.INVALID;let r=function t(e,i){let s=(0,h.getParsedType)(e),r=(0,h.getParsedType)(i);if(e===i)return{valid:!0,data:e};if(s===h.ZodParsedType.object&&r===h.ZodParsedType.object){let s=h.util.objectKeys(i),r=h.util.objectKeys(e).filter(t=>-1!==s.indexOf(t)),n={...e,...i};for(let s of r){let r=t(e[s],i[s]);if(!r.valid)return{valid:!1};n[s]=r.data}return{valid:!0,data:n}}if(s===h.ZodParsedType.array&&r===h.ZodParsedType.array){if(e.length!==i.length)return{valid:!1};let s=[];for(let r=0;rs(t,e)):s(this._def.left._parseSync({data:i.data,path:i.path,parent:i}),this._def.right._parseSync({data:i.data,path:i.path,parent:i}))}}e.ZodIntersection=U,U.create=(t,e,i)=>new U({left:t,right:e,typeName:s.ZodIntersection,...p(i)});class N extends g{_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.parsedType!==h.ZodParsedType.array)return(0,l.addIssueToContext)(i,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.array,received:i.parsedType}),l.INVALID;if(i.data.lengththis._def.items.length&&((0,l.addIssueToContext)(i,{code:d.ZodIssueCode.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),e.dirty());let s=[...i.data].map((t,e)=>{let s=this._def.items[e]||this._def.rest;return s?s._parse(new c(i,t,i.path,e)):null}).filter(t=>!!t);return i.common.async?Promise.all(s).then(t=>l.ParseStatus.mergeArray(e,t)):l.ParseStatus.mergeArray(e,s)}get items(){return this._def.items}rest(t){return new N({...this._def,rest:t})}}e.ZodTuple=N,N.create=(t,e)=>{if(!Array.isArray(t))throw Error("You must pass an array of schemas to z.tuple([ ... ])");return new N({items:t,typeName:s.ZodTuple,rest:null,...p(e)})};class Z extends g{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.parsedType!==h.ZodParsedType.object)return(0,l.addIssueToContext)(i,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.object,received:i.parsedType}),l.INVALID;let s=[],r=this._def.keyType,n=this._def.valueType;for(let t in i.data)s.push({key:r._parse(new c(i,t,i.path,t)),value:n._parse(new c(i,i.data[t],i.path,t))});return i.common.async?l.ParseStatus.mergeObjectAsync(e,s):l.ParseStatus.mergeObjectSync(e,s)}get element(){return this._def.valueType}static create(t,e,i){return new Z(e instanceof g?{keyType:t,valueType:e,typeName:s.ZodRecord,...p(i)}:{keyType:b.create(),valueType:t,typeName:s.ZodRecord,...p(e)})}}e.ZodRecord=Z;class H extends g{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.parsedType!==h.ZodParsedType.map)return(0,l.addIssueToContext)(i,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.map,received:i.parsedType}),l.INVALID;let s=this._def.keyType,r=this._def.valueType,n=[...i.data.entries()].map(([t,e],n)=>({key:s._parse(new c(i,t,i.path,[n,"key"])),value:r._parse(new c(i,e,i.path,[n,"value"]))}));if(i.common.async){let t=new Map;return Promise.resolve().then(async()=>{for(let i of n){let s=await i.key,r=await i.value;if("aborted"===s.status||"aborted"===r.status)return l.INVALID;"dirty"!==s.status&&"dirty"!==r.status||e.dirty(),t.set(s.value,r.value)}return{status:e.value,value:t}})}{let t=new Map;for(let i of n){let s=i.key,r=i.value;if("aborted"===s.status||"aborted"===r.status)return l.INVALID;"dirty"!==s.status&&"dirty"!==r.status||e.dirty(),t.set(s.value,r.value)}return{status:e.value,value:t}}}}e.ZodMap=H,H.create=(t,e,i)=>new H({valueType:e,keyType:t,typeName:s.ZodMap,...p(i)});class V extends g{_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.parsedType!==h.ZodParsedType.set)return(0,l.addIssueToContext)(i,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.set,received:i.parsedType}),l.INVALID;let s=this._def;null!==s.minSize&&i.data.sizes.maxSize.value&&((0,l.addIssueToContext)(i,{code:d.ZodIssueCode.too_big,maximum:s.maxSize.value,type:"set",inclusive:!0,exact:!1,message:s.maxSize.message}),e.dirty());let r=this._def.valueType;function n(t){let i=new Set;for(let s of t){if("aborted"===s.status)return l.INVALID;"dirty"===s.status&&e.dirty(),i.add(s.value)}return{status:e.value,value:i}}let o=[...i.data.values()].map((t,e)=>r._parse(new c(i,t,i.path,e)));return i.common.async?Promise.all(o).then(t=>n(t)):n(o)}min(t,e){return new V({...this._def,minSize:{value:t,message:a.errorUtil.toString(e)}})}max(t,e){return new V({...this._def,maxSize:{value:t,message:a.errorUtil.toString(e)}})}size(t,e){return this.min(t,e).max(t,e)}nonempty(t){return this.min(1,t)}}e.ZodSet=V,V.create=(t,e)=>new V({valueType:t,minSize:null,maxSize:null,typeName:s.ZodSet,...p(e)});class W extends g{constructor(){super(...arguments),this.validate=this.implement}_parse(t){let{ctx:e}=this._processInputParams(t);if(e.parsedType!==h.ZodParsedType.function)return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.function,received:e.parsedType}),l.INVALID;function i(t,i){return(0,l.makeIssue)({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,(0,o.getErrorMap)(),o.defaultErrorMap].filter(t=>!!t),issueData:{code:d.ZodIssueCode.invalid_arguments,argumentsError:i}})}function s(t,i){return(0,l.makeIssue)({data:t,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,(0,o.getErrorMap)(),o.defaultErrorMap].filter(t=>!!t),issueData:{code:d.ZodIssueCode.invalid_return_type,returnTypeError:i}})}let r={errorMap:e.common.contextualErrorMap},n=e.data;if(this._def.returns instanceof K){let t=this;return(0,l.OK)(async function(...e){let o=new d.ZodError([]),a=await t._def.args.parseAsync(e,r).catch(t=>{throw o.addIssue(i(e,t)),o}),l=await Reflect.apply(n,this,a);return await t._def.returns._def.type.parseAsync(l,r).catch(t=>{throw o.addIssue(s(l,t)),o})})}{let t=this;return(0,l.OK)(function(...e){let o=t._def.args.safeParse(e,r);if(!o.success)throw new d.ZodError([i(e,o.error)]);let a=Reflect.apply(n,this,o.data),l=t._def.returns.safeParse(a,r);if(!l.success)throw new d.ZodError([s(a,l.error)]);return l.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...t){return new W({...this._def,args:N.create(t).rest(D.create())})}returns(t){return new W({...this._def,returns:t})}implement(t){return this.parse(t)}strictImplement(t){return this.parse(t)}static create(t,e,i){return new W({args:t||N.create([]).rest(D.create()),returns:e||D.create(),typeName:s.ZodFunction,...p(i)})}}e.ZodFunction=W;class G extends g{get schema(){return this._def.getter()}_parse(t){let{ctx:e}=this._processInputParams(t);return this._def.getter()._parse({data:e.data,path:e.path,parent:e})}}e.ZodLazy=G,G.create=(t,e)=>new G({getter:t,typeName:s.ZodLazy,...p(e)});class j extends g{_parse(t){if(t.data!==this._def.value){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{received:e.data,code:d.ZodIssueCode.invalid_literal,expected:this._def.value}),l.INVALID}return{status:"valid",value:t.data}}get value(){return this._def.value}}function q(t,e){return new X({values:t,typeName:s.ZodEnum,...p(e)})}e.ZodLiteral=j,j.create=(t,e)=>new j({value:t,typeName:s.ZodLiteral,...p(e)});class X extends g{_parse(t){if("string"!=typeof t.data){let e=this._getOrReturnCtx(t),i=this._def.values;return(0,l.addIssueToContext)(e,{expected:h.util.joinValues(i),received:e.parsedType,code:d.ZodIssueCode.invalid_type}),l.INVALID}if(-1===this._def.values.indexOf(t.data)){let e=this._getOrReturnCtx(t),i=this._def.values;return(0,l.addIssueToContext)(e,{received:e.data,code:d.ZodIssueCode.invalid_enum_value,options:i}),l.INVALID}return(0,l.OK)(t.data)}get options(){return this._def.values}get enum(){let t={};for(let e of this._def.values)t[e]=e;return t}get Values(){let t={};for(let e of this._def.values)t[e]=e;return t}get Enum(){let t={};for(let e of this._def.values)t[e]=e;return t}extract(t){return X.create(t)}exclude(t){return X.create(this.options.filter(e=>!t.includes(e)))}}e.ZodEnum=X,X.create=q;class $ extends g{_parse(t){let e=h.util.getValidEnumValues(this._def.values),i=this._getOrReturnCtx(t);if(i.parsedType!==h.ZodParsedType.string&&i.parsedType!==h.ZodParsedType.number){let t=h.util.objectValues(e);return(0,l.addIssueToContext)(i,{expected:h.util.joinValues(t),received:i.parsedType,code:d.ZodIssueCode.invalid_type}),l.INVALID}if(-1===e.indexOf(t.data)){let t=h.util.objectValues(e);return(0,l.addIssueToContext)(i,{received:i.data,code:d.ZodIssueCode.invalid_enum_value,options:t}),l.INVALID}return(0,l.OK)(t.data)}get enum(){return this._def.values}}e.ZodNativeEnum=$,$.create=(t,e)=>new $({values:t,typeName:s.ZodNativeEnum,...p(e)});class K extends g{unwrap(){return this._def.type}_parse(t){let{ctx:e}=this._processInputParams(t);if(e.parsedType!==h.ZodParsedType.promise&&!1===e.common.async)return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.promise,received:e.parsedType}),l.INVALID;let i=e.parsedType===h.ZodParsedType.promise?e.data:Promise.resolve(e.data);return(0,l.OK)(i.then(t=>this._def.type.parseAsync(t,{path:e.path,errorMap:e.common.contextualErrorMap})))}}e.ZodPromise=K,K.create=(t,e)=>new K({type:t,typeName:s.ZodPromise,...p(e)});class Y extends g{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===s.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){let{status:e,ctx:i}=this._processInputParams(t),s=this._def.effect||null,r={addIssue:t=>{(0,l.addIssueToContext)(i,t),t.fatal?e.abort():e.dirty()},get path(){return i.path}};if(r.addIssue=r.addIssue.bind(r),"preprocess"===s.type){let t=s.transform(i.data,r);return i.common.issues.length?{status:"dirty",value:i.data}:i.common.async?Promise.resolve(t).then(t=>this._def.schema._parseAsync({data:t,path:i.path,parent:i})):this._def.schema._parseSync({data:t,path:i.path,parent:i})}if("refinement"===s.type){let t=t=>{let e=s.refinement(t,r);if(i.common.async)return Promise.resolve(e);if(e instanceof Promise)throw Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return t};if(!1===i.common.async){let s=this._def.schema._parseSync({data:i.data,path:i.path,parent:i});return"aborted"===s.status?l.INVALID:("dirty"===s.status&&e.dirty(),t(s.value),{status:e.value,value:s.value})}return this._def.schema._parseAsync({data:i.data,path:i.path,parent:i}).then(i=>"aborted"===i.status?l.INVALID:("dirty"===i.status&&e.dirty(),t(i.value).then(()=>({status:e.value,value:i.value}))))}if("transform"===s.type){if(!1===i.common.async){let t=this._def.schema._parseSync({data:i.data,path:i.path,parent:i});if(!(0,l.isValid)(t))return t;let n=s.transform(t.value,r);if(n instanceof Promise)throw Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:e.value,value:n}}return this._def.schema._parseAsync({data:i.data,path:i.path,parent:i}).then(t=>(0,l.isValid)(t)?Promise.resolve(s.transform(t.value,r)).then(t=>({status:e.value,value:t})):t)}h.util.assertNever(s)}}e.ZodEffects=Y,e.ZodTransformer=Y,Y.create=(t,e,i)=>new Y({schema:t,typeName:s.ZodEffects,effect:e,...p(i)}),Y.createWithPreprocess=(t,e,i)=>new Y({schema:e,effect:{type:"preprocess",transform:t},typeName:s.ZodEffects,...p(i)});class Q extends g{_parse(t){return this._getType(t)===h.ZodParsedType.undefined?(0,l.OK)(void 0):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}}e.ZodOptional=Q,Q.create=(t,e)=>new Q({innerType:t,typeName:s.ZodOptional,...p(e)});class J extends g{_parse(t){return this._getType(t)===h.ZodParsedType.null?(0,l.OK)(null):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}}e.ZodNullable=J,J.create=(t,e)=>new J({innerType:t,typeName:s.ZodNullable,...p(e)});class tt extends g{_parse(t){let{ctx:e}=this._processInputParams(t),i=e.data;return e.parsedType===h.ZodParsedType.undefined&&(i=this._def.defaultValue()),this._def.innerType._parse({data:i,path:e.path,parent:e})}removeDefault(){return this._def.innerType}}e.ZodDefault=tt,tt.create=(t,e)=>new tt({innerType:t,typeName:s.ZodDefault,defaultValue:"function"==typeof e.default?e.default:()=>e.default,...p(e)});class te extends g{_parse(t){let{ctx:e}=this._processInputParams(t),i={...e,common:{...e.common,issues:[]}},s=this._def.innerType._parse({data:i.data,path:i.path,parent:{...i}});return(0,l.isAsync)(s)?s.then(t=>({status:"valid",value:"valid"===t.status?t.value:this._def.catchValue({get error(){return new d.ZodError(i.common.issues)},input:i.data})})):{status:"valid",value:"valid"===s.status?s.value:this._def.catchValue({get error(){return new d.ZodError(i.common.issues)},input:i.data})}}removeCatch(){return this._def.innerType}}e.ZodCatch=te,te.create=(t,e)=>new te({innerType:t,typeName:s.ZodCatch,catchValue:"function"==typeof e.catch?e.catch:()=>e.catch,...p(e)});class ti extends g{_parse(t){if(this._getType(t)!==h.ZodParsedType.nan){let e=this._getOrReturnCtx(t);return(0,l.addIssueToContext)(e,{code:d.ZodIssueCode.invalid_type,expected:h.ZodParsedType.nan,received:e.parsedType}),l.INVALID}return{status:"valid",value:t.data}}}e.ZodNaN=ti,ti.create=t=>new ti({typeName:s.ZodNaN,...p(t)}),e.BRAND=Symbol("zod_brand");class ts extends g{_parse(t){let{ctx:e}=this._processInputParams(t),i=e.data;return this._def.type._parse({data:i,path:e.path,parent:e})}unwrap(){return this._def.type}}e.ZodBranded=ts;class tr extends g{_parse(t){let{status:e,ctx:i}=this._processInputParams(t);if(i.common.async)return(async()=>{let t=await this._def.in._parseAsync({data:i.data,path:i.path,parent:i});return"aborted"===t.status?l.INVALID:"dirty"===t.status?(e.dirty(),(0,l.DIRTY)(t.value)):this._def.out._parseAsync({data:t.value,path:i.path,parent:i})})();{let t=this._def.in._parseSync({data:i.data,path:i.path,parent:i});return"aborted"===t.status?l.INVALID:"dirty"===t.status?(e.dirty(),{status:"dirty",value:t.value}):this._def.out._parseSync({data:t.value,path:i.path,parent:i})}}static create(t,e){return new tr({in:t,out:e,typeName:s.ZodPipeline})}}e.ZodPipeline=tr;class tn extends g{_parse(t){let e=this._def.innerType._parse(t);return(0,l.isValid)(e)&&(e.value=Object.freeze(e.value)),e}}e.ZodReadonly=tn,tn.create=(t,e)=>new tn({innerType:t,typeName:s.ZodReadonly,...p(e)}),e.custom=(t,e={},i)=>t?k.create().superRefine((s,r)=>{var n,o;if(!t(s)){let t="function"==typeof e?e(s):"string"==typeof e?{message:e}:e,a=null===(o=null!==(n=t.fatal)&&void 0!==n?n:i)||void 0===o||o;r.addIssue({code:"custom",..."string"==typeof t?{message:t}:t,fatal:a})}}):k.create(),e.late={object:L.lazycreate},(r=s=e.ZodFirstPartyTypeKind||(e.ZodFirstPartyTypeKind={})).ZodString="ZodString",r.ZodNumber="ZodNumber",r.ZodNaN="ZodNaN",r.ZodBigInt="ZodBigInt",r.ZodBoolean="ZodBoolean",r.ZodDate="ZodDate",r.ZodSymbol="ZodSymbol",r.ZodUndefined="ZodUndefined",r.ZodNull="ZodNull",r.ZodAny="ZodAny",r.ZodUnknown="ZodUnknown",r.ZodNever="ZodNever",r.ZodVoid="ZodVoid",r.ZodArray="ZodArray",r.ZodObject="ZodObject",r.ZodUnion="ZodUnion",r.ZodDiscriminatedUnion="ZodDiscriminatedUnion",r.ZodIntersection="ZodIntersection",r.ZodTuple="ZodTuple",r.ZodRecord="ZodRecord",r.ZodMap="ZodMap",r.ZodSet="ZodSet",r.ZodFunction="ZodFunction",r.ZodLazy="ZodLazy",r.ZodLiteral="ZodLiteral",r.ZodEnum="ZodEnum",r.ZodEffects="ZodEffects",r.ZodNativeEnum="ZodNativeEnum",r.ZodOptional="ZodOptional",r.ZodNullable="ZodNullable",r.ZodDefault="ZodDefault",r.ZodCatch="ZodCatch",r.ZodPromise="ZodPromise",r.ZodBranded="ZodBranded",r.ZodPipeline="ZodPipeline",r.ZodReadonly="ZodReadonly",e.instanceof=(t,i={message:`Input not instance of ${t.name}`})=>(0,e.custom)(e=>e instanceof t,i);let to=b.create;e.string=to;let ta=C.create;e.number=ta;let tl=ti.create;e.nan=tl;let th=T.create;e.bigint=th;let td=S.create;e.boolean=td;let tc=A.create;e.date=tc;let tu=E.create;e.symbol=tu;let tp=P.create;e.undefined=tp;let tg=I.create;e.null=tg;let t_=k.create;e.any=t_;let tf=D.create;e.unknown=tf;let tm=R.create;e.never=tm;let tv=F.create;e.void=tv;let ty=B.create;e.array=ty;let tx=L.create;e.object=tx;let tw=L.strictCreate;e.strictObject=tw;let tb=M.create;e.union=tb;let tC=O.create;e.discriminatedUnion=tC;let tT=U.create;e.intersection=tT;let tS=N.create;e.tuple=tS;let tA=Z.create;e.record=tA;let tE=H.create;e.map=tE;let tP=V.create;e.set=tP;let tI=W.create;e.function=tI;let tk=G.create;e.lazy=tk;let tD=j.create;e.literal=tD;let tR=X.create;e.enum=tR;let tF=$.create;e.nativeEnum=tF;let tB=K.create;e.promise=tB;let tL=Y.create;e.effect=tL,e.transformer=tL;let tM=Q.create;e.optional=tM;let tz=J.create;e.nullable=tz;let tO=Y.createWithPreprocess;e.preprocess=tO;let tU=tr.create;e.pipeline=tU,e.ostring=()=>to().optional(),e.onumber=()=>ta().optional(),e.oboolean=()=>td().optional(),e.coerce={string:t=>b.create({...t,coerce:!0}),number:t=>C.create({...t,coerce:!0}),boolean:t=>S.create({...t,coerce:!0}),bigint:t=>T.create({...t,coerce:!0}),date:t=>A.create({...t,coerce:!0})},e.NEVER=l.INVALID},205:e=>{e.exports=t}},i={};function s(t){var r=i[t];if(void 0!==r)return r.exports;var n=i[t]={exports:{}};return e[t].call(n.exports,n,n.exports,s),n.exports}return s.d=(t,e)=>{for(var i in e)s.o(e,i)&&!s.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s(607)})();var h={};h=new URL("Hero 01.0a89e3b5.png",import.meta.url).toString();var d={};d=new URL("Solaria Demo Update 01.c847244e.png",import.meta.url).toString();var c={};c=new URL("Level_0.4121d29c.ldtkl",import.meta.url).toString();var u={};u=new URL("Level_1.0859d067.ldtkl",import.meta.url).toString();var p={};p=new URL("House.9ff42634.ldtkl",import.meta.url).toString();var g={};g=new URL("top-down.3490dc55.ldtk",import.meta.url).toString();const _={HeroSpriteSheetPng:new a.ImageSource(i(h)),LdtkResource:new l.LdtkResource(i(g),{useTilemapCameraStrategy:!0,useMapBackgroundColor:!0,pathMap:[{path:"Hero 01.png",output:i(h)},{path:"Level_0.ldtkl",output:i(c)},{path:"Level_1.ldtkl",output:i(u)},{path:"House.ldtkl",output:i(p)},{path:"Solaria Demo Update 01.png",output:i(d)}]})},f=new a.Loader;for(let t of Object.values(_))f.addResource(t);const m={PlayerSpeed:32,PlayerFrameSpeed:200};class v extends a.Actor{constructor(t){super({...t,collisionType:a.CollisionType.Active})}onInitialize(t){let e=a.SpriteSheet.fromImageSource({image:_.HeroSpriteSheetPng,grid:{spriteWidth:16,spriteHeight:16,rows:8,columns:8}}),i=new a.Animation({frames:[{graphic:e.getSprite(0,1),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(1,1),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(2,1),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(3,1),duration:m.PlayerFrameSpeed}]});this.graphics.add("left-idle",i);let s=new a.Animation({frames:[{graphic:e.getSprite(0,2),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(1,2),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(2,2),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(3,2),duration:m.PlayerFrameSpeed}]});this.graphics.add("right-idle",s);let r=new a.Animation({frames:[{graphic:e.getSprite(0,3),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(1,3),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(2,3),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(3,3),duration:m.PlayerFrameSpeed}]});this.graphics.add("up-idle",r);let n=new a.Animation({frames:[{graphic:e.getSprite(0,0),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(1,0),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(2,0),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(3,0),duration:m.PlayerFrameSpeed}]});this.graphics.add("down-idle",n);let o=new a.Animation({frames:[{graphic:e.getSprite(0,5),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(1,5),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(2,5),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(3,5),duration:m.PlayerFrameSpeed}]});this.graphics.add("left-walk",o);let l=new a.Animation({frames:[{graphic:e.getSprite(0,6),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(1,6),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(2,6),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(3,6),duration:m.PlayerFrameSpeed}]});this.graphics.add("right-walk",l);let h=new a.Animation({frames:[{graphic:e.getSprite(0,7),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(1,7),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(2,7),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(3,7),duration:m.PlayerFrameSpeed}]});this.graphics.add("up-walk",h);let d=new a.Animation({frames:[{graphic:e.getSprite(0,4),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(1,4),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(2,4),duration:m.PlayerFrameSpeed},{graphic:e.getSprite(3,4),duration:m.PlayerFrameSpeed}]});this.graphics.add("down-walk",d)}onPreUpdate(t,e){this.vel=a.Vector.Zero,this.graphics.use("down-idle"),t.input.keyboard.isHeld(a.Input.Keys.ArrowRight)&&(this.vel=a.vec(m.PlayerSpeed,0),this.graphics.use("right-walk")),t.input.keyboard.isHeld(a.Input.Keys.ArrowLeft)&&(this.vel=a.vec(-m.PlayerSpeed,0),this.graphics.use("left-walk")),t.input.keyboard.isHeld(a.Input.Keys.ArrowUp)&&(this.vel=a.vec(0,-m.PlayerSpeed),this.graphics.use("up-walk")),t.input.keyboard.isHeld(a.Input.Keys.ArrowDown)&&(this.vel=a.vec(0,m.PlayerSpeed),this.graphics.use("down-walk"))}}var a=o("3MXpL");class y extends a.Scene{onPreLoad(t){}onInitialize(t){_.LdtkResource.addToScene(this,{levelFilter:["House"]});let e=_.LdtkResource.getEntityLayers("House")[0].getLdtkEntitiesByIdentifier("PlayerStart")[0];this.playerSpawnLocation=(0,a.vec)(e.__worldX??0,e.__worldY??0)}onActivate(t){let e=this.world.entityManager.getByName("player")[0];e.get(a.TransformComponent).pos=this.playerSpawnLocation,e instanceof v&&this.camera.strategy.lockToActor(e);let i=_.LdtkResource.getLevelBounds(["House"]);this.camera.strategy.limitCameraBounds(i)}constructor(...t){super(...t),this.playerSpawnLocation=(0,a.vec)(0,0)}}var a=o("3MXpL");class x extends a.Scene{onInitialize(t){_.LdtkResource.addToScene(this,{pos:(0,a.vec)(0,0),levelFilter:["Level_0","Level_1"]})}onActivate(t){let e=this.world.entityManager.getByName("player")[0];e instanceof v&&this.camera.strategy.lockToActor(e);let i=_.LdtkResource.getLevelBounds(["Level_0","Level_1"]);this.camera.strategy.limitCameraBounds(i)}}const w=new a.Engine({resolution:{width:256,height:256},suppressPlayButton:!0,displayMode:a.DisplayMode.FitScreenAndFill,pixelArt:!0,pixelRatio:4,scenes:{overworld:{scene:x,transitions:{out:new a.FadeInOut({direction:"out",duration:1e3,color:a.Color.Black}),in:new a.FadeInOut({direction:"in",duration:1e3,color:a.Color.Black})}},house:{scene:y,transitions:{out:new a.FadeInOut({direction:"out",duration:1e3,color:a.Color.Black}),in:new a.FadeInOut({direction:"in",duration:1e3,color:a.Color.Black})}}}});_.LdtkResource.registerEntityIdentifierFactory("PlayerStart",t=>new v({name:"player",anchor:a.vec(t.entity.__pivot[0],t.entity.__pivot[1]),width:t.entity.width,height:t.entity.height,pos:t.worldPos,z:t.layer.order})),_.LdtkResource.registerEntityIdentifierFactory("Door",t=>new a.Trigger({width:t.entity.width,height:t.entity.height,pos:t.worldPos.add(a.vec(t.entity.width/2,t.entity.height/2)),filter:t=>t instanceof v,action:()=>{w.goToScene(t.entity.fieldInstances[0].__value)}}));const b=new a.FadeInOut({duration:1e3,direction:"in",color:a.Color.ExcaliburBlue});w.start("overworld",{loader:f,inTransition:b}); +//# sourceMappingURL=index.a78842eb.js.map diff --git a/index.a78842eb.js.map b/index.a78842eb.js.map new file mode 100644 index 0000000..13fcdea --- /dev/null +++ b/index.a78842eb.js.map @@ -0,0 +1 @@ +{"mappings":"IgVSUwwK,E,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,S,E,C,E,O,G,E,U,C,E,O,C,C,C,I,E,W,E,C,E,E,C,E,E,E,iB,A,O,I,A,C,E,S,C,E,G,K,E,O,C,C,E,C,O,C,G,K,E,C,I,E,C,C,E,A,Q,C,C,E,C,I,E,C,G,E,Q,C,C,E,O,C,C,E,C,E,E,I,C,E,O,C,E,E,O,E,E,O,A,C,I,E,A,M,uB,E,I,O,E,I,C,mB,C,C,E,Q,C,S,C,C,C,E,C,C,E,C,C,E,E,iB,C,G,A,C,E,E,Q,A,E,Q,S,C,C,C,E,E,E,O,C,sB,I,G,E,E,O,C,gB,I,G,E,E,O,C,c,I,G,E,E,O,C,iB,I,G,E,E,O,C,mB,I,G,E,E,O,C,mB,I,G,E,E,O,C,gB,I,G,E,E,O,C,gB,I,G,E,E,O,C,Q,I,G,E,E,O,C,iB,I,G,E,E,O,C,e,I,G,E,E,O,C,Y,I,G,E,E,O,C,qB,I,G,E,E,O,C,kB,I,G,E,E,O,C,oB,I,G,E,E,O,C,e,I,G,E,E,O,C,sB,I,G,E,E,O,C,O,I,G,E,E,O,C,O,I,G,E,E,O,C,Y,I,G,E,E,O,C,Q,I,G,E,E,O,C,gB,I,G,E,E,O,C,c,I,G,E,E,O,C,qB,I,G,E,E,O,C,mB,I,G,E,E,O,C,gB,I,G,E,E,O,C,U,I,G,E,E,O,C,S,I,G,E,E,O,C,e,I,G,E,E,O,C,S,I,G,E,E,O,C,S,I,G,E,E,O,C,iB,I,G,E,E,O,C,Q,I,G,E,E,O,C,c,I,G,E,E,O,C,uB,I,G,E,E,O,C,W,I,G,E,E,O,C,oB,I,G,E,E,O,C,mB,I,G,E,E,O,C,oB,I,G,E,E,O,C,iB,I,G,E,E,O,C,wB,I,G,E,E,O,C,qB,I,G,E,E,O,C,0B,I,G,E,E,O,C,yB,I,G,E,E,O,C,sB,I,G,E,E,O,C,kB,I,G,E,E,O,C,gB,I,G,E,E,O,C,Q,I,I,E,E,O,C,kB,I,I,E,E,O,C,qB,I,I,E,E,O,C,8B,I,I,E,E,O,C,Y,I,I,E,E,O,C,oB,I,I,E,E,O,C,e,I,I,E,E,O,C,kB,I,I,E,E,O,C,yB,I,I,E,E,O,C,kB,I,I,E,E,O,C,mB,I,I,E,E,O,C,oB,I,I,E,E,O,C,a,I,I,E,E,O,C,Y,I,I,E,E,O,C,kB,I,I,E,E,O,C,Q,I,I,E,E,O,C,c,I,I,E,E,O,C,yB,I,I,E,E,O,C,c,I,I,E,E,O,C,Y,I,I,E,E,O,C,0B,I,I,E,E,O,C,gB,I,I,E,E,O,C,uB,I,I,E,E,O,C,yB,I,I,E,E,O,C,kB,I,I,E,E,O,C,Q,I,I,E,E,O,C,2B,I,I,E,E,O,C,W,I,I,E,E,O,C,M,I,I,E,E,O,C,Y,I,I,E,E,O,C,W,I,I,E,E,O,C,iB,I,I,E,E,O,C,c,I,I,E,E,O,C,c,I,I,E,E,O,C,gC,I,I,E,E,O,C,a,I,I,E,E,O,C,S,I,I,E,E,O,C,S,I,I,E,E,O,C,kB,I,I,E,E,O,C,e,I,I,E,E,O,C,yB,I,I,E,E,O,C,c,I,I,E,E,O,C,S,I,I,E,E,O,C,e,I,I,E,E,O,C,oB,I,I,E,E,O,C,qB,I,I,E,E,O,C,S,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,kB,I,I,E,E,O,C,e,I,I,E,E,O,C,a,I,I,E,E,O,C,S,I,I,E,E,O,C,a,I,I,E,E,O,C,mC,I,I,E,E,O,C,gC,I,I,E,E,O,C,mB,I,I,E,E,O,C,oB,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,Q,I,I,E,E,O,C,S,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,a,I,I,E,E,O,C,Y,I,I,E,E,O,C,W,I,I,E,E,O,C,a,I,I,E,E,O,C,a,I,I,E,E,O,C,S,I,I,E,E,O,C,Y,I,I,E,E,O,C,iB,I,I,E,E,O,C,gB,I,I,E,E,O,C,U,I,I,E,E,O,C,mB,I,I,E,E,O,C,qB,I,I,E,E,O,C,sB,I,I,E,E,O,C,yB,I,I,E,E,O,C,W,I,I,E,E,O,C,M,I,I,E,E,O,C,oB,I,I,E,E,O,C,U,I,I,E,E,O,C,oB,I,I,E,E,O,C,gB,I,I,E,E,O,C,iB,I,I,E,E,O,C,c,I,I,E,E,O,C,kB,I,I,E,E,O,C,iB,I,I,E,E,O,C,c,I,I,E,E,O,C,kB,I,I,E,E,O,C,Q,I,I,E,E,O,C,Y,I,I,E,E,O,C,c,I,I,E,E,O,C,a,I,I,E,E,O,C,2B,I,I,E,E,O,C,wB,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,W,I,I,E,E,O,C,W,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,Q,I,I,E,E,O,C,4B,I,I,E,E,O,C,O,I,I,E,E,O,C,c,I,I,E,E,O,C,S,I,I,E,E,O,C,e,I,I,E,E,O,C,gC,I,I,E,E,O,C,4B,I,I,E,E,O,C,W,I,I,E,E,O,C,S,I,I,E,E,O,C,W,I,I,E,E,O,C,S,I,I,E,E,O,C,kB,I,I,E,E,O,C,a,I,I,E,E,O,C,O,I,I,E,E,O,C,kB,I,I,E,E,O,C,e,I,I,E,E,O,C,S,I,I,E,E,O,C,S,I,I,E,E,O,C,sB,I,I,E,E,O,C,mB,I,I,E,E,O,C,4B,I,I,E,E,O,C,O,I,I,E,E,O,C,a,I,I,E,E,O,C,kB,I,I,E,E,O,C,O,I,I,E,E,O,C,oB,I,I,E,E,O,C,kB,I,I,E,E,O,C,W,I,I,E,E,O,C,W,I,I,E,E,O,C,kB,I,I,E,E,O,C,oB,I,I,E,E,O,C,U,I,I,E,E,O,C,e,I,I,E,E,O,C,e,I,I,E,E,O,C,qB,I,I,E,E,O,C,gB,I,I,E,E,O,C,mB,I,I,E,E,O,C,e,I,I,E,E,O,C,uB,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,c,I,I,E,E,O,C,U,I,I,E,E,O,C,kB,I,I,E,E,O,C,O,I,I,E,E,O,C,qB,I,I,E,E,O,C,qB,I,I,E,E,O,C,gB,I,I,E,E,O,C,iB,I,I,E,E,O,C,gB,I,I,E,E,O,C,yB,I,I,E,E,O,C,kB,I,I,E,E,O,C,oB,I,I,E,E,O,C,oB,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,e,I,I,E,E,O,C,e,I,I,E,E,O,C,wB,I,I,E,E,O,C,iB,I,I,E,E,O,C,a,I,I,E,E,O,C,kB,I,I,E,E,O,C,W,I,I,E,E,O,C,Q,I,I,E,E,O,C,e,I,I,E,E,O,C,4B,I,I,E,E,O,C,S,I,I,E,E,O,C,S,I,I,E,E,O,C,M,I,I,E,E,O,C,kB,I,I,E,E,O,C,Y,I,I,E,E,O,C,mB,I,I,E,E,O,C,S,I,I,E,E,O,C,gB,I,I,E,E,O,C,a,I,I,E,E,O,C,W,I,I,E,E,O,C,iB,I,I,E,E,O,C,W,I,I,E,E,O,C,W,I,I,E,E,O,C,e,I,I,E,E,O,C,U,I,I,E,E,O,C,U,I,I,E,E,O,C,Q,I,I,E,E,O,C,c,I,I,E,E,O,C,S,I,I,E,E,O,C,iB,I,I,E,E,O,C,gB,I,I,E,E,O,C,e,I,I,E,E,O,C,e,I,I,E,E,O,C,uB,I,I,E,E,O,C,Y,I,I,E,E,O,C,S,I,I,E,E,O,C,Q,I,I,E,E,O,C,O,I,I,E,E,O,C,iB,I,I,E,E,O,C,Q,I,I,E,E,O,C,c,I,I,E,E,O,C,S,I,I,E,E,O,C,a,I,I,E,E,O,C,c,I,I,E,E,O,C,gB,I,I,E,E,O,C,e,I,I,E,E,O,C,oB,I,I,E,E,O,C,S,I,I,E,E,O,C,S,I,I,E,E,O,C,gB,I,I,E,E,O,C,iB,I,I,E,E,O,C,a,I,I,E,E,O,C,W,I,I,E,E,O,C,Y,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,gB,I,I,E,E,O,C,O,I,I,E,E,O,C,U,I,I,E,E,O,C,gB,I,I,E,E,O,C,Q,I,I,E,E,O,C,U,I,I,E,E,O,C,Y,I,I,E,E,O,C,qB,I,I,E,E,O,C,a,I,I,E,E,O,C,W,I,I,E,E,O,C,U,I,I,E,E,O,C,gB,I,I,E,E,O,C,Q,I,I,E,E,O,C,O,I,I,E,E,O,C,S,I,I,E,E,O,C,a,I,I,E,E,O,C,e,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,e,I,I,E,E,O,C,W,I,I,E,E,O,C,mB,I,I,E,E,O,C,iB,I,I,E,E,O,C,a,I,I,E,E,O,C,Q,I,I,E,E,O,C,oB,I,I,E,E,O,C,Q,I,I,E,E,O,C,Y,I,I,E,E,O,C,W,I,I,E,E,O,C,O,I,I,E,E,O,C,kB,I,I,E,E,O,C,kB,I,I,E,E,O,C,kB,I,I,E,E,O,C,iB,I,I,E,E,O,C,c,I,I,E,E,O,C,a,I,I,E,E,O,C,iB,I,I,E,E,O,C,iB,I,I,E,E,O,C,gB,I,I,E,E,O,C,mB,I,I,E,E,O,C,kB,I,I,E,E,O,C,sB,I,I,E,E,O,C,qB,I,I,E,E,O,C,qB,I,I,E,E,O,C,kB,I,I,E,E,O,C,sB,I,I,E,E,O,C,c,I,I,E,E,O,C,W,I,I,E,E,O,C,mB,I,I,E,E,O,C,gB,I,I,E,E,O,C,mB,I,I,E,E,O,C,Q,I,I,E,E,O,C,uB,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,Y,I,I,E,E,O,C,M,I,I,E,E,O,C,Q,I,G;;;;;;C,E,I,E,C,K,C,E,E,K,E,C,C,E,C,E,I,C,G,I,E,E,K,E,E,C,C,G,E,E,M9UNV,EAA8B,A,E,C,C,KAA4B,KAE1D,EAAA,IAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0HA,CAAA,CAAA,GAAA,CAAO,QAAA,EAAA,QAAA,CAAA,kCAAA,CAAA,MAAA,EAAA,CAAA,SAAA,09BAAoiC,eAAA,CAAA,+/EAAihF,CAAA,WAAA,EAAA,EAA5jH,EAEA,IAAA,EAAe,C,E,K,C,E,E,K,E,C,C,E,C,E,I,C,G,I,E,E,K,E,E,C,C,G,E,E,MC9Hf,EAA8B,A,E,C,C,KAA4B,KAE1D,EAAA,IAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BC,CAAA,CAAA,GAAA,CAAO,QAAA,EAAA,QAAA,CAAA,+BAAA,CAAA,MAAA,EAAA,CAAA,SAAA,wOAA8S,eAAA,CAAA,ihBAAwiB,CAAA,WAAA,EAAA,EAA91B,EAEA,IAAA,EAAe,C,E,K,A,IC7Bf,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,IAAA,EAAA,EAAA,CA4EA,OAzEA,EAAA,QAAA,CAAA,WACA,OAAA,IAAA,CAAA,GAAA,CAAA,SAAA,CAAA,EACA,IAAA,EAAA,GACA,EAAA,AAAA,KAAA,IAAA,CAAA,CAAA,EAAA,CAoBA,OAnBA,CAAA,CAAA,EAAA,EACA,CAAA,GAAA,cAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,MADA,EAGA,CAAA,CAAA,EAAA,EACA,CAAA,GAAA,UAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,KADA,EAGA,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A,EAAA,CAAA,CAAA,EAAA,IAAA,CAAA,EAAA,CAAA,CAAA,EAAA,IACA,OAAA,cAAA,CAAA,EAAA,EAAA,CAAyC,WAAA,CAAA,EAAA,IAAA,CAAA,CAAA,EAAA,AAAA,EAGzC,ECPA,EAAA,CAAA,CAAA,WACA,GAAA,AAAA,UAAA,OAAA,WAAA,OAAA,WACA,GAAA,CACA,OAAA,IAAA,EAAA,AAAA,SAAA,gBACA,CAAG,MAAH,EAAA,CACA,GAAA,AAAA,UAAA,OAAA,OAAA,OAAA,MACA,CACA,ICPA,EAAA,CAAA,CAAA,CAAA,EAAA,IAAA,OAAA,SAAA,CAAA,cAAA,CAAA,IAAA,CAAA,EAAA,GCCA,EAAA,CAAA,CAAA,AAAA,IACA,aAAA,OAAA,QAAA,OAAA,WAAA,EACA,OAAA,cAAA,CAAA,EAAA,OAAA,WAAA,CAAA,CAAuD,MAAA,QAAA,GAEvD,OAAA,cAAA,CAAA,EAAA,aAAA,CAAgD,MAAA,CAAA,CAAA,EAChD,E,I,E,C,E,A,C,K,E,C,C,E,C,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,G,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,G,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,G,IMFY,EKKA,ECJA,EAQE,EGTF,EQAA,EuCUA,EQGA,ESdA,ECAA,EgBMA,ECCA,EAQA,ECdA,EckBA,EYnBA,EgBMA,EA0BA,EA4BA,EAoCA,EASA,EWdA,EGvFA,EaSA,EAWA,EGTA,EAwOA,EUqKA,EAsEA,EG7dA,EKPA,ECEA,ECAA,ECAA,EIDA,EYwFA,EzMtFA,EKKA,ECJA,EGDA,EQAA,EuCUA,EQGA,ESdA,ECAA,EgBMA,ECCA,EAQA,ECdA,EckBA,EYnBA,EgBMA,EA0BA,GA4BA,GAoCA,GASA,GWdA,GGvFA,GaSA,GAWA,GGTA,GAwOA,GUqKA,GAsEA,GG7dA,GKPA,GCEA,GCAA,GCAA,GIDA,GYwFA,G,G,C,E,E,C,C,I,E,C,C,G,C,0B,I,G,wB,I,G,mB,I,E,G,I,G,C,E,E,C,C,I,E,C,C,G,C,oB,I,G,iB,I,G,c,I,G,kB,I,G,wB,I,G,uB,I,G,oB,I,G,gB,I,G,kB,I,G,gB,I,G,kB,I,G,mB,I,G,W,I,E,iB,I,G,kB,I,G,U,I,G,e,I,G,c,I,G,iB,I,G,mB,I,G,oB,I,G,uB,I,G,Y,I,G,gB,I,G,U,I,G,mB,I,G,mB,I,G,c,I,G,e,I,G,c,I,G,uB,I,G,gB,I,G,kB,I,G,kB,I,G,a,I,G,c,I,G,a,I,G,sB,I,G,e,I,G,a,I,E,G,I,G,C,E,E,C,C,I,E,C,C,G,C,O,I,G,K,I,G,M,I,G,U,I,G,O,I,E,G,I,G,C,E,E,C,C,I,E,C,C,G,C,K,I,G,Q,I,G,Q,I,G,S,I,G,S,I,G,S,I,G,K,I,G,oB,I,G,c,I,G,iB,I,G,a,I,G,qB,I,G,a,I,E,c,I,G,Y,I,G,e,I,G,W,I,E,G,I,G,C,E9MpFL,SAAS,KA4Bd,GA1BsB,aAAlB,OAAO,QACT,CAAA,OAAc,CACZ,aAAc,WAEd,CACD,CAAA,EAGmB,aAAlB,OAAO,QAA2B,OAAO,qBAAqB,EAC1D,CAAA,OAAQ,qBAAqB,CAC3B,OAAQ,2BAA2B,EACnC,OAAQ,wBAAwB,EACtC,SAAU,CAAkB,EA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CAAG,IAAI,EACa,CAEtC,IAAW,OAAX,CACE,OAAO,IAAI,CAAC,MAAM,AACpB,CAEA,IAAW,SAAX,CACE,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,AAC/B,CAGO,MAAM,OAAN,QACL,AAAI,AAAgB,IAAhB,IAAI,CAAC,MAAM,EACb,IAAI,CAAC,MAAM,GACJ,QAAQ,OAAO,IAEjB,IAAI,CAAC,UAAU,CAAC,OAAO,EAChC,CAEO,KAAK,EAAgB,CAAC,CAAtB,CACL,GAAI,AAAU,IAAV,GAGJ,KAAO,AAAU,IAAV,GAAe,AAA2B,IAA3B,IAAI,CAAC,UAAU,CAAC,MAAM,EAC1C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MACxB,GAEF,CAAA,IAAI,CAAC,MAAM,EAAI,EACjB,CACD,CCvDM,IAAM,GAAa,SAE1B,I,C,I,I,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,E,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,E,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,A,G,I,G,E,S,E,S,E,U,E,C,EKGG1vJ,KAAO0vJ,EAPRjvK,EAAAA,SAAAA,E,A,C,K,I,E,C,I,C,E,E,K,E,C,C,G,E,C,C,E,C,Q,I,E,gB,I,E,U,I,E,S,I,E,e,I,C,GCFK,IAAMkvK,EAAS,6IACTC,EAAoBvyJ,AAAAA,IAC7B,GAAuB,UAAA,OAAZA,EACP,MAAM,AAAIvF,UAAU,oCAExB,IAAMmF,EAAQI,EAAQJ,KAAAA,CAAM0yJ,GAC5B,GAAA,CAAK1yJ,EACD,MAAM,AAAIrc,MAAM,CAAA,oCAAA,EAAuCyc,EAAAA,WAAAA,CAAAA,EAG3D,OADAJ,EAAM67E,KAAAA,GACC77E,CAAK,EAEV4yJ,EAAcvwK,AAAAA,GAAY,MAANA,GAAmB,MAANA,GAAmB,MAANA,EAC9CwwK,EAAYzwK,AAAAA,IACd,IAAMD,EAAI09C,SAASz9C,EAAG,IACtB,OAAO26C,MAAM56C,GAAKC,EAAID,CAAC,EAGrB2wK,EAAiB,CAACjwK,EAAGioB,SADRjoB,EAAGioB,EAElB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,C,E,K,I,G,C,E,C,E,I,E,O,wB,C,E,E,C,G,C,C,Q,E,C,E,U,C,E,Q,E,E,Y,A,G,C,E,C,W,C,E,I,W,O,C,C,E,A,C,C,E,O,c,C,E,E,E,E,S,C,C,C,C,C,C,C,E,K,I,G,C,E,C,E,C,C,E,C,C,C,E,A,C,E,E,I,E,I,C,Y,E,S,C,C,C,E,I,I,K,E,Y,G,O,S,C,c,C,I,C,E,I,E,E,E,E,C,C,O,c,C,E,a,C,M,C,C,GCPzC,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,IAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,E,E,I,C,E,E,K,O,c,C,E,a,C,M,C,C,G,E,Y,C,K,ECXA,IAAA,EAAA,EAAA,IAKA,CAAA,EAAA,YAAA,CAAA,MAMI,YAAYv9B,CAAAA,CAAc8sG,CAAAA,CAA8BzmE,CAAAA,CAAwC0mE,CAAAA,CAAAA,CAI5F,GAJ4F,IAAA,CAAAA,KAAAA,CAAAA,EAC5FujB,IAAAA,CAAKz1E,QAAAA,CAAAA,AAAW,CAAA,EAAA,EAAA7qD,GAAAA,AAAAA,EAAIgQ,EAAMktG,SAAAA,CAAUC,MAAAA,CAAQntG,EAAMktG,SAAAA,CAAUE,MAAAA,EAC5DkjB,IAAAA,CAAKh5G,MAAAA,CAAAA,AAAS,CAAA,EAAA,EAAAtnB,GAAAA,AAAAA,EAAI88G,EAAUO,gBAAAA,CAAkBP,EAAUQ,gBAAAA,EACxDgjB,IAAAA,CAAKxjB,SAAAA,CAAYA,EACbA,EAAUkC,UAAAA,CAAW15I,MAAAA,CAAQ,CAE7B,IAAMqiD,EAAOm1F,EAAUmC,MAAAA,CACjBr3F,EAAUk1F,EAAUoC,MAAAA,AAC1BohB,CAAAA,IAAAA,CAAKjnD,OAAAA,CAAU,IAAI,EAAAjgF,OAAAA,CAAQ,CACvB7tB,KAAMuxI,EAAUY,YAAAA,CAChB9qG,IAAK0tH,IAAAA,CAAKz1E,QAAAA,CAASrgD,GAAAA,CAAI81H,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","sources":["","node_modules/excalibur/build/esm/excalibur.js","node_modules/excalibur/build/esm/webpack:/Director/Loader.css","node_modules/excalibur/build/esm/webpack:/Util/Toaster.css","node_modules/excalibur/build/node_modules/css-loader/dist/runtime/api.js","node_modules/excalibur/build/node_modules/css-loader/dist/runtime/sourceMaps.js","node_modules/excalibur/build/node_modules/core-js/es/array/sort.js","node_modules/excalibur/build/node_modules/core-js/es/object/keys.js","node_modules/excalibur/build/node_modules/core-js/internals/a-callable.js","node_modules/excalibur/build/node_modules/core-js/internals/an-object.js","node_modules/excalibur/build/node_modules/core-js/internals/array-includes.js","node_modules/excalibur/build/node_modules/core-js/internals/array-method-is-strict.js","node_modules/excalibur/build/node_modules/core-js/internals/array-slice.js","node_modules/excalibur/build/node_modules/core-js/internals/array-sort.js","node_modules/excalibur/build/node_modules/core-js/internals/classof-raw.js","node_modules/excalibur/build/node_modules/core-js/internals/classof.js","node_modules/excalibur/build/node_modules/core-js/internals/copy-constructor-properties.js","node_modules/excalibur/build/node_modules/core-js/internals/create-non-enumerable-property.js","node_modules/excalibur/build/node_modules/core-js/internals/create-property-descriptor.js","node_modules/excalibur/build/node_modules/core-js/internals/define-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/define-global-property.js","node_modules/excalibur/build/node_modules/core-js/internals/delete-property-or-throw.js","node_modules/excalibur/build/node_modules/core-js/internals/descriptors.js","node_modules/excalibur/build/node_modules/core-js/internals/document-create-element.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-ff-version.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-is-ie-or-edge.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-user-agent.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-v8-version.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-webkit-version.js","node_modules/excalibur/build/node_modules/core-js/internals/entry-unbind.js","node_modules/excalibur/build/node_modules/core-js/internals/enum-bug-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/export.js","node_modules/excalibur/build/node_modules/core-js/internals/fails.js","node_modules/excalibur/build/node_modules/core-js/internals/function-bind-native.js","node_modules/excalibur/build/node_modules/core-js/internals/function-call.js","node_modules/excalibur/build/node_modules/core-js/internals/function-name.js","node_modules/excalibur/build/node_modules/core-js/internals/function-uncurry-this.js","node_modules/excalibur/build/node_modules/core-js/internals/get-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/get-method.js","node_modules/excalibur/build/node_modules/core-js/internals/global.js","node_modules/excalibur/build/node_modules/core-js/internals/has-own-property.js","node_modules/excalibur/build/node_modules/core-js/internals/hidden-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/ie8-dom-define.js","node_modules/excalibur/build/node_modules/core-js/internals/indexed-object.js","node_modules/excalibur/build/node_modules/core-js/internals/inspect-source.js","node_modules/excalibur/build/node_modules/core-js/internals/internal-state.js","node_modules/excalibur/build/node_modules/core-js/internals/is-callable.js","node_modules/excalibur/build/node_modules/core-js/internals/is-forced.js","node_modules/excalibur/build/node_modules/core-js/internals/is-null-or-undefined.js","node_modules/excalibur/build/node_modules/core-js/internals/is-object.js","node_modules/excalibur/build/node_modules/core-js/internals/is-pure.js","node_modules/excalibur/build/node_modules/core-js/internals/is-symbol.js","node_modules/excalibur/build/node_modules/core-js/internals/length-of-array-like.js","node_modules/excalibur/build/node_modules/core-js/internals/make-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/math-trunc.js","node_modules/excalibur/build/node_modules/core-js/internals/object-define-property.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-descriptor.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-names.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-symbols.js","node_modules/excalibur/build/node_modules/core-js/internals/object-is-prototype-of.js","node_modules/excalibur/build/node_modules/core-js/internals/object-keys-internal.js","node_modules/excalibur/build/node_modules/core-js/internals/object-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/object-property-is-enumerable.js","node_modules/excalibur/build/node_modules/core-js/internals/ordinary-to-primitive.js","node_modules/excalibur/build/node_modules/core-js/internals/own-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/path.js","node_modules/excalibur/build/node_modules/core-js/internals/require-object-coercible.js","node_modules/excalibur/build/node_modules/core-js/internals/shared-key.js","node_modules/excalibur/build/node_modules/core-js/internals/shared-store.js","node_modules/excalibur/build/node_modules/core-js/internals/shared.js","node_modules/excalibur/build/node_modules/core-js/internals/symbol-constructor-detection.js","node_modules/excalibur/build/node_modules/core-js/internals/to-absolute-index.js","node_modules/excalibur/build/node_modules/core-js/internals/to-indexed-object.js","node_modules/excalibur/build/node_modules/core-js/internals/to-integer-or-infinity.js","node_modules/excalibur/build/node_modules/core-js/internals/to-length.js","node_modules/excalibur/build/node_modules/core-js/internals/to-object.js","node_modules/excalibur/build/node_modules/core-js/internals/to-primitive.js","node_modules/excalibur/build/node_modules/core-js/internals/to-property-key.js","node_modules/excalibur/build/node_modules/core-js/internals/to-string-tag-support.js","node_modules/excalibur/build/node_modules/core-js/internals/to-string.js","node_modules/excalibur/build/node_modules/core-js/internals/try-to-string.js","node_modules/excalibur/build/node_modules/core-js/internals/uid.js","node_modules/excalibur/build/node_modules/core-js/internals/use-symbol-as-uid.js","node_modules/excalibur/build/node_modules/core-js/internals/v8-prototype-define-bug.js","node_modules/excalibur/build/node_modules/core-js/internals/weak-map-basic-detection.js","node_modules/excalibur/build/node_modules/core-js/internals/well-known-symbol.js","node_modules/excalibur/build/node_modules/core-js/modules/es.array.sort.js","node_modules/excalibur/build/node_modules/core-js/modules/es.object.keys.js","node_modules/excalibur/build/esm/webpack:/webpack/bootstrap","node_modules/excalibur/build/esm/webpack:/webpack/runtime/compat get default export","node_modules/excalibur/build/esm/webpack:/webpack/runtime/define property getters","node_modules/excalibur/build/esm/webpack:/webpack/runtime/global","node_modules/excalibur/build/esm/webpack:/webpack/runtime/hasOwnProperty shorthand","node_modules/excalibur/build/esm/webpack:/webpack/runtime/make namespace object","node_modules/excalibur/build/esm/webpack:/Polyfill.ts","node_modules/excalibur/build/esm/webpack:/Flags.ts","node_modules/excalibur/build/esm/webpack:/Id.ts","node_modules/excalibur/build/esm/webpack:/Util/Future.ts","node_modules/excalibur/build/esm/webpack:/EventEmitter.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerScope.ts","node_modules/excalibur/build/esm/webpack:/Math/Random.ts","node_modules/excalibur/build/esm/webpack:/Math/util.ts","node_modules/excalibur/build/esm/webpack:/Math/vector.ts","node_modules/excalibur/build/esm/webpack:/Color.ts","node_modules/excalibur/build/esm/webpack:/Util/Log.ts","node_modules/excalibur/build/esm/webpack:/Collision/Side.ts","node_modules/excalibur/build/esm/webpack:/Collision/BoundingBox.ts","node_modules/excalibur/build/esm/webpack:/Util/Util.ts","node_modules/excalibur/build/esm/webpack:/Math/matrix.ts","node_modules/excalibur/build/esm/webpack:/Math/affine-matrix.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/transform-stack.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/state-stack.ts","node_modules/excalibur/build/esm/webpack:/Resources/Resource.ts","node_modules/excalibur/build/esm/webpack:/Util/Watch.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Graphic.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Sprite.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Filtering.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/texture-loader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/ImageSource.ts","node_modules/excalibur/build/esm/webpack:/Graphics/SpriteFont.ts","node_modules/excalibur/build/esm/webpack:/Graphics/SpriteSheet.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/debug-font.png","node_modules/excalibur/build/esm/webpack:/Graphics/Context/debug-text.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/render-source.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/render-target.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/webgl-util.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/shader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/vertex-buffer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/vertex-layout.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsDiagnostics.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-pass-painter.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/quad-index-buffer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.ts","node_modules/excalibur/build/esm/webpack:/Util/Pool.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/draw-call.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/material.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/material-renderer/material-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/ExcaliburGraphicsContextWebGL.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts","node_modules/excalibur/build/esm/webpack:/Screen.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/AudioContext.ts","node_modules/excalibur/build/esm/webpack:/Util/WebAudio.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Raster.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Canvas.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/AudioImplementation.ts","node_modules/excalibur/build/esm/webpack:/Util/StateMachine.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/WebAudioInstance.ts","node_modules/excalibur/build/esm/webpack:/Events.ts","node_modules/excalibur/build/esm/webpack:/Events/MediaEvents.ts","node_modules/excalibur/build/esm/webpack:/Util/Sound.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/Sound.ts","node_modules/excalibur/build/esm/webpack:/Director/DefaultLoader.ts","node_modules/excalibur/build/esm/webpack:/Util/DrawUtil.ts","node_modules/excalibur/build/esm/webpack:/Director/Loader.logo.png","node_modules/excalibur/build/esm/webpack:/Director/Loader.ts","node_modules/excalibur/build/esm/webpack:/Util/Detector.ts","node_modules/excalibur/build/esm/webpack:/Collision/CollisionType.ts","node_modules/excalibur/build/esm/webpack:/Math/coord-plane.ts","node_modules/excalibur/build/esm/webpack:/Math/vector-view.ts","node_modules/excalibur/build/esm/webpack:/Math/watch-vector.ts","node_modules/excalibur/build/esm/webpack:/Math/transform.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Component.ts","node_modules/excalibur/build/esm/webpack:/Util/Observable.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Components/TransformComponent.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Components/MotionComponent.ts","node_modules/excalibur/build/esm/webpack:/Collision/Group/CollisionGroupManager.ts","node_modules/excalibur/build/esm/webpack:/Collision/Group/CollisionGroup.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/Pair.ts","node_modules/excalibur/build/esm/webpack:/Math/projection.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/DynamicTree.ts","node_modules/excalibur/build/esm/webpack:/Math/ray.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/DynamicTreeCollisionProcessor.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/Collider.ts","node_modules/excalibur/build/esm/webpack:/Collision/SolverStrategy.ts","node_modules/excalibur/build/esm/webpack:/Collision/Physics.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/ContactBias.ts","node_modules/excalibur/build/esm/webpack:/Collision/PhysicsConfig.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CompositeCollider.ts","node_modules/excalibur/build/esm/webpack:/Math/line-segment.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/ClosestLineJumpTable.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CircleCollider.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/CollisionContact.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/SeparatingAxis.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CollisionJumpTable.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/EdgeCollider.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Debug.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/PolygonCollider.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/Shape.ts","node_modules/excalibur/build/esm/webpack:/Collision/ColliderComponent.ts","node_modules/excalibur/build/esm/webpack:/Collision/BodyComponent.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Entity.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Rectangle.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Circle.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerComponent.ts","node_modules/excalibur/build/esm/webpack:/Util/EasingFunctions.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionQueue.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Repeat.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RepeatForever.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/MoveBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/MoveTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/RotationType.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RotateTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RotateBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ScaleTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ScaleBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/CallMethod.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/EaseTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/EaseBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Blink.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Fade.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Delay.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Die.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Follow.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Meet.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionContext.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionsComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontCommon.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontTextInstance.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontCache.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Font.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Text.ts","node_modules/excalibur/build/esm/webpack:/Actor.ts","node_modules/excalibur/build/esm/webpack:/ScreenElement.ts","node_modules/excalibur/build/esm/webpack:/Timer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/ParallaxComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/DebugGraphicsComponent.ts","node_modules/excalibur/build/esm/webpack:/TileMap/TileMap.ts","node_modules/excalibur/build/esm/webpack:/Camera.ts","node_modules/excalibur/build/esm/webpack:/Trigger.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Priority.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/System.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/EntityManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Query.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/TagQuery.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/QueryManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/SystemManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/World.ts","node_modules/excalibur/build/esm/webpack:/Collision/Integrator.ts","node_modules/excalibur/build/esm/webpack:/Collision/MotionSystem.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/ArcadeSolver.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/ContactConstraintPoint.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/RealisticSolver.ts","node_modules/excalibur/build/esm/webpack:/Collision/CollisionSystem.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Animation.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsGroup.ts","node_modules/excalibur/build/esm/webpack:/Configurable.ts","node_modules/excalibur/build/esm/webpack:/Particles.ts","node_modules/excalibur/build/esm/webpack:/Graphics/TransformInterpolation.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsSystem.ts","node_modules/excalibur/build/esm/webpack:/Debug/DebugSystem.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerSystem.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionsSystem.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricEntityComponent.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricEntitySystem.ts","node_modules/excalibur/build/esm/webpack:/Graphics/OffscreenSystem.ts","node_modules/excalibur/build/esm/webpack:/Collision/PhysicsWorld.ts","node_modules/excalibur/build/esm/webpack:/Input/Gamepad.ts","node_modules/excalibur/build/esm/webpack:/Input/InputMapper.ts","node_modules/excalibur/build/esm/webpack:/Util/IFrame.ts","node_modules/excalibur/build/esm/webpack:/Input/Keyboard.ts","node_modules/excalibur/build/esm/webpack:/Math/global-coordinates.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerEvent.ts","node_modules/excalibur/build/esm/webpack:/Input/WheelEvent.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerAbstraction.ts","node_modules/excalibur/build/esm/webpack:/Input/WheelDeltaMode.ts","node_modules/excalibur/build/esm/webpack:/Input/NativePointerButton.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerButton.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerType.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerEventReceiver.ts","node_modules/excalibur/build/esm/webpack:/Input/InputHost.ts","node_modules/excalibur/build/esm/webpack:/Scene.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ColorBlindnessMode.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/color-blind-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ScreenShader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ColorBlindnessPostProcessor.ts","node_modules/excalibur/build/esm/webpack:/Debug/DebugFlags.ts","node_modules/excalibur/build/esm/webpack:/Debug/DebugConfig.ts","node_modules/excalibur/build/esm/webpack:/Util/Browser.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/ExcaliburGraphicsContext.ts","node_modules/excalibur/build/esm/webpack:/Util/Fps.ts","node_modules/excalibur/build/esm/webpack:/Util/Clock.ts","node_modules/excalibur/build/esm/webpack:/Util/Toaster.ts","node_modules/excalibur/build/esm/webpack:/Director/Director.ts","node_modules/excalibur/build/esm/webpack:/Engine.ts","node_modules/excalibur/build/esm/webpack:/Math/Index.ts","node_modules/excalibur/build/esm/webpack:/Debug/index.ts","node_modules/excalibur/build/esm/webpack:/EventDispatcher.ts","node_modules/excalibur/build/esm/webpack:/Label.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricMap.ts","node_modules/excalibur/build/esm/webpack:/TileMap/index.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ActionSequence.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ParallelActions.ts","node_modules/excalibur/build/esm/webpack:/Actions/Index.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/QuadTree.ts","node_modules/excalibur/build/esm/webpack:/Collision/Index.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/LifecycleEvents.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/Index.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/Index.ts","node_modules/excalibur/build/esm/webpack:/Resources/Gif.ts","node_modules/excalibur/build/esm/webpack:/Resources/Font.ts","node_modules/excalibur/build/esm/webpack:/Resources/Index.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/index.ts","node_modules/excalibur/build/esm/webpack:/Util/Coroutine.ts","node_modules/excalibur/build/esm/webpack:/Director/Transition.ts","node_modules/excalibur/build/esm/webpack:/Director/FadeInOut.ts","node_modules/excalibur/build/esm/webpack:/Director/CrossFade.ts","node_modules/excalibur/build/esm/webpack:/Director/index.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Line.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Polygon.ts","node_modules/excalibur/build/esm/webpack:/Graphics/index.ts","node_modules/excalibur/build/esm/webpack:/Input/Index.ts","node_modules/excalibur/build/esm/webpack:/Util/Index.ts","node_modules/excalibur/build/esm/webpack:/Util/Decorators.ts","node_modules/excalibur/build/esm/webpack:/Util/Semaphore.ts","node_modules/excalibur/build/esm/webpack:/index.ts","src/main.ts","src/player.ts","src/resources.ts","node_modules/@excaliburjs/plugin-ldtk/dist/excalibur-ldtk.min.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/universalModuleDefinition","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/utils.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/compareVersions.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/compare.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/satisfies.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/validate.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/entity-layer.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/file-loader.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/index.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/intgrid-layer.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/ldtk-resource.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/level-resource.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/level.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/loader-cache.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/path-util.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/tile-layer.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/tileset.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/types.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/ZodError.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/errors.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/external.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/helpers/errorUtil.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/helpers/parseUtil.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/helpers/typeAliases.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/helpers/util.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/index.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/locales/en.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/types.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/external umd {\"commonjs\":\"excalibur\",\"commonjs2\":\"excalibur\",\"amd\":\"excalibur\",\"root\":\"ex\"}","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/bootstrap","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/runtime/define property getters","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/runtime/hasOwnProperty shorthand","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/runtime/make namespace object","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/startup","node_modules/@parcel/runtime-js/lib/runtime-ff40237c10907382.js","node_modules/@parcel/runtime-js/lib/runtime-6179d0fd6488673c.js","node_modules/@parcel/runtime-js/lib/runtime-98d03baec8dc2a57.js","node_modules/@parcel/runtime-js/lib/runtime-55a51091189a0419.js","node_modules/@parcel/runtime-js/lib/runtime-70a0fc7cb45e8c31.js","node_modules/@parcel/runtime-js/lib/runtime-88268e1a7c58dd66.js","src/config.ts","src/house.ts","src/overworld.ts"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\nfunction $parcel$interopDefault(a) {\n return a && a.__esModule ? a.default : a;\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequire4b3c\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequire4b3c\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"3MXpL\", function(module, exports) {\n\n$parcel$export(module.exports, \"ActionCompleteEvent\", () => $2c23f148d58cd887$export$f05c91211c084e80);\n$parcel$export(module.exports, \"ActionContext\", () => $2c23f148d58cd887$export$e04e17a44f37debc);\n$parcel$export(module.exports, \"ActionQueue\", () => $2c23f148d58cd887$export$dfcd1bb88f6d711b);\n$parcel$export(module.exports, \"ActionSequence\", () => $2c23f148d58cd887$export$89f31cec7c284d42);\n$parcel$export(module.exports, \"ActionStartEvent\", () => $2c23f148d58cd887$export$a3f070f3e473c3b);\n$parcel$export(module.exports, \"ActionsComponent\", () => $2c23f148d58cd887$export$856e7d6d9d698871);\n$parcel$export(module.exports, \"ActionsSystem\", () => $2c23f148d58cd887$export$caffe607ed29fca1);\n$parcel$export(module.exports, \"ActivateEvent\", () => $2c23f148d58cd887$export$adc62e83dbcda319);\n$parcel$export(module.exports, \"Actor\", () => $2c23f148d58cd887$export$f73d3eb6fd876d80);\n$parcel$export(module.exports, \"AddedComponent\", () => $2c23f148d58cd887$export$da248c61eea53296);\n$parcel$export(module.exports, \"AffineMatrix\", () => $2c23f148d58cd887$export$f0455ab08e3fbd0e);\n$parcel$export(module.exports, \"Animation\", () => $2c23f148d58cd887$export$c35d437ae5945fcd);\n$parcel$export(module.exports, \"AnimationDirection\", () => $2c23f148d58cd887$export$67ee29bab3792d4c);\n$parcel$export(module.exports, \"AnimationEvents\", () => $2c23f148d58cd887$export$d230853e97069d46);\n$parcel$export(module.exports, \"AnimationStrategy\", () => $2c23f148d58cd887$export$6cfd78ddb48c90c6);\n$parcel$export(module.exports, \"ArcadeSolver\", () => $2c23f148d58cd887$export$3769e64eb87b5ecc);\n$parcel$export(module.exports, \"AudioContextFactory\", () => $2c23f148d58cd887$export$54dc36bc2fac5425);\n$parcel$export(module.exports, \"Axes\", () => $2c23f148d58cd887$export$387a78ab20784494);\n$parcel$export(module.exports, \"Axis\", () => $2c23f148d58cd887$export$d06866a9fb0606da);\n$parcel$export(module.exports, \"BaseAlign\", () => $2c23f148d58cd887$export$83c931ba0d3bbaf5);\n$parcel$export(module.exports, \"Blink\", () => $2c23f148d58cd887$export$1a553341cd0b8415);\n$parcel$export(module.exports, \"BodyComponent\", () => $2c23f148d58cd887$export$43416332cf06b1f);\n$parcel$export(module.exports, \"BoundingBox\", () => $2c23f148d58cd887$export$63080c4de6cfc362);\n$parcel$export(module.exports, \"BroadphaseStrategy\", () => $2c23f148d58cd887$export$fa45ecb18b97ae89);\n$parcel$export(module.exports, \"BrowserComponent\", () => $2c23f148d58cd887$export$c24f8f35353a1e26);\n$parcel$export(module.exports, \"BrowserEvents\", () => $2c23f148d58cd887$export$8688def55452cbca);\n$parcel$export(module.exports, \"Buttons\", () => $2c23f148d58cd887$export$665d5a662b7213f3);\n$parcel$export(module.exports, \"Camera\", () => $2c23f148d58cd887$export$79f141de891a5fed);\n$parcel$export(module.exports, \"CameraEvents\", () => $2c23f148d58cd887$export$41606648ac8a293c);\n$parcel$export(module.exports, \"Canvas\", () => $2c23f148d58cd887$export$8d01c972ee8b14a9);\n$parcel$export(module.exports, \"Circle\", () => $2c23f148d58cd887$export$c89a927ffc67e6fa);\n$parcel$export(module.exports, \"CircleCollider\", () => $2c23f148d58cd887$export$e2395b697f5a931f);\n$parcel$export(module.exports, \"Clock\", () => $2c23f148d58cd887$export$9735c82c4bae3302);\n$parcel$export(module.exports, \"ClosestLine\", () => $2c23f148d58cd887$export$44e6803d1d57f89a);\n$parcel$export(module.exports, \"ClosestLineJumpTable\", () => $2c23f148d58cd887$export$1ed419d47673a225);\n$parcel$export(module.exports, \"Collider\", () => $2c23f148d58cd887$export$b7c6eef0ebb06133);\n$parcel$export(module.exports, \"ColliderComponent\", () => $2c23f148d58cd887$export$3c9e91dc1b611d2e);\n$parcel$export(module.exports, \"CollisionContact\", () => $2c23f148d58cd887$export$ce0ca64520c7bfd2);\n$parcel$export(module.exports, \"CollisionEndEvent\", () => $2c23f148d58cd887$export$83caf30c40e9d4b8);\n$parcel$export(module.exports, \"CollisionGroup\", () => $2c23f148d58cd887$export$4df0464d8c812c98);\n$parcel$export(module.exports, \"CollisionGroupManager\", () => $2c23f148d58cd887$export$55e924fc640a8405);\n$parcel$export(module.exports, \"CollisionJumpTable\", () => $2c23f148d58cd887$export$fbd6eb86d6a3f08);\n$parcel$export(module.exports, \"CollisionPostSolveEvent\", () => $2c23f148d58cd887$export$7cd2649c3408da6c);\n$parcel$export(module.exports, \"CollisionPreSolveEvent\", () => $2c23f148d58cd887$export$897cd666d936ac4c);\n$parcel$export(module.exports, \"CollisionStartEvent\", () => $2c23f148d58cd887$export$cf976780b3106589);\n$parcel$export(module.exports, \"CollisionSystem\", () => $2c23f148d58cd887$export$5dcfde0f6b96512b);\n$parcel$export(module.exports, \"CollisionType\", () => $2c23f148d58cd887$export$ddb2ed749236e720);\n$parcel$export(module.exports, \"Color\", () => $2c23f148d58cd887$export$892596cec99bc70e);\n$parcel$export(module.exports, \"ColorBlindFlags\", () => $2c23f148d58cd887$export$8ed4b5bb5352fe14);\n$parcel$export(module.exports, \"ColorBlindnessMode\", () => $2c23f148d58cd887$export$c46090c9df657074);\n$parcel$export(module.exports, \"ColorBlindnessPostProcessor\", () => $2c23f148d58cd887$export$b3bf2ffaa538264b);\n$parcel$export(module.exports, \"Component\", () => $2c23f148d58cd887$export$16fa2f45be04daa8);\n$parcel$export(module.exports, \"CompositeCollider\", () => $2c23f148d58cd887$export$d16a7c95008e315d);\n$parcel$export(module.exports, \"Configurable\", () => $2c23f148d58cd887$export$abda45806f5adbae);\n$parcel$export(module.exports, \"ConsoleAppender\", () => $2c23f148d58cd887$export$e5a30aa3d28b26e2);\n$parcel$export(module.exports, \"ContactConstraintPoint\", () => $2c23f148d58cd887$export$de7807bd8bd828df);\n$parcel$export(module.exports, \"ContactEndEvent\", () => $2c23f148d58cd887$export$1bdfb0c7c42d632d);\n$parcel$export(module.exports, \"ContactSolveBias\", () => $2c23f148d58cd887$export$bf92f329076cd7a3);\n$parcel$export(module.exports, \"ContactStartEvent\", () => $2c23f148d58cd887$export$71de6146fb6d69d2);\n$parcel$export(module.exports, \"CoordPlane\", () => $2c23f148d58cd887$export$71efaa2be447940c);\n$parcel$export(module.exports, \"CrossFade\", () => $2c23f148d58cd887$export$d78c8c6074541cf2);\n$parcel$export(module.exports, \"DeactivateEvent\", () => $2c23f148d58cd887$export$7d34ad93c25aa8e7);\n$parcel$export(module.exports, \"Debug\", () => $2c23f148d58cd887$export$153e5dc2c098b35c);\n$parcel$export(module.exports, \"DebugConfig\", () => $2c23f148d58cd887$export$f7c1896972d6c454);\n$parcel$export(module.exports, \"DebugGraphicsComponent\", () => $2c23f148d58cd887$export$c3e6e677dda8521a);\n$parcel$export(module.exports, \"DebugSystem\", () => $2c23f148d58cd887$export$e52858e61b0ea117);\n$parcel$export(module.exports, \"DebugText\", () => $2c23f148d58cd887$export$3d1f12550a40f54d);\n$parcel$export(module.exports, \"DefaultAntialiasOptions\", () => $2c23f148d58cd887$export$4544b2d7eff33859);\n$parcel$export(module.exports, \"DefaultLoader\", () => $2c23f148d58cd887$export$dd6b48f99ee8a36);\n$parcel$export(module.exports, \"DefaultPhysicsConfig\", () => $2c23f148d58cd887$export$aafe01318a900193);\n$parcel$export(module.exports, \"DefaultPixelArtOptions\", () => $2c23f148d58cd887$export$fd69b6a3b7f47e29);\n$parcel$export(module.exports, \"DegreeOfFreedom\", () => $2c23f148d58cd887$export$e1545123b54f6785);\n$parcel$export(module.exports, \"Delay\", () => $2c23f148d58cd887$export$7419ff430885d61c);\n$parcel$export(module.exports, \"DeprecatedStaticToConfig\", () => $2c23f148d58cd887$export$a340d4e5571cbd07);\n$parcel$export(module.exports, \"Detector\", () => $2c23f148d58cd887$export$e695250628cde35);\n$parcel$export(module.exports, \"Die\", () => $2c23f148d58cd887$export$c5e124f7bab3d492);\n$parcel$export(module.exports, \"Direction\", () => $2c23f148d58cd887$export$cacd6541cfeeb6c1);\n$parcel$export(module.exports, \"Director\", () => $2c23f148d58cd887$export$a74d557191881f82);\n$parcel$export(module.exports, \"DirectorEvents\", () => $2c23f148d58cd887$export$99bf88c530739783);\n$parcel$export(module.exports, \"DisplayMode\", () => $2c23f148d58cd887$export$4b7264771109adb6);\n$parcel$export(module.exports, \"DynamicTree\", () => $2c23f148d58cd887$export$62053d374d83dfb1);\n$parcel$export(module.exports, \"DynamicTreeCollisionProcessor\", () => $2c23f148d58cd887$export$d7078bb1ea3ba3f2);\n$parcel$export(module.exports, \"EX_VERSION\", () => $2c23f148d58cd887$export$86ae8da356d53161);\n$parcel$export(module.exports, \"EaseBy\", () => $2c23f148d58cd887$export$62230588c4867d28);\n$parcel$export(module.exports, \"EaseTo\", () => $2c23f148d58cd887$export$df007b1d5b86e25a);\n$parcel$export(module.exports, \"EasingFunctions\", () => $2c23f148d58cd887$export$6ff391a2049fdf40);\n$parcel$export(module.exports, \"EdgeCollider\", () => $2c23f148d58cd887$export$89e5ccdc4c19a8f6);\n$parcel$export(module.exports, \"ElasticToActorStrategy\", () => $2c23f148d58cd887$export$2cbc8fe61dd10773);\n$parcel$export(module.exports, \"EmitterType\", () => $2c23f148d58cd887$export$d45269226a4bbdc1);\n$parcel$export(module.exports, \"Engine\", () => $2c23f148d58cd887$export$2c3b404bf3a77a1f);\n$parcel$export(module.exports, \"EngineEvents\", () => $2c23f148d58cd887$export$20434e7e042d306a);\n$parcel$export(module.exports, \"EnterTriggerEvent\", () => $2c23f148d58cd887$export$462adefbb095232e);\n$parcel$export(module.exports, \"EnterViewPortEvent\", () => $2c23f148d58cd887$export$83f8212621739c1f);\n$parcel$export(module.exports, \"Entity\", () => $2c23f148d58cd887$export$bc644a473284d944);\n$parcel$export(module.exports, \"EntityEvents\", () => $2c23f148d58cd887$export$66b8a9cb33a156c);\n$parcel$export(module.exports, \"EntityManager\", () => $2c23f148d58cd887$export$c7b7134fd828a5);\n$parcel$export(module.exports, \"EventDispatcher\", () => $2c23f148d58cd887$export$ec8b666c5fe2c75a);\n$parcel$export(module.exports, \"EventEmitter\", () => $2c23f148d58cd887$export$4fae95256245c8c0);\n$parcel$export(module.exports, \"EventTypes\", () => $2c23f148d58cd887$export$86d9a347f2bf71d6);\n$parcel$export(module.exports, \"Events\", () => $2c23f148d58cd887$export$ada873a34909da65);\n$parcel$export(module.exports, \"ExResponse\", () => $2c23f148d58cd887$export$afee3afd6be961ec);\n$parcel$export(module.exports, \"ExcaliburGraphicsContext2DCanvas\", () => $2c23f148d58cd887$export$c03216fb3a7a2f87);\n$parcel$export(module.exports, \"ExcaliburGraphicsContextWebGL\", () => $2c23f148d58cd887$export$81940238f313e11f);\n$parcel$export(module.exports, \"ExitTriggerEvent\", () => $2c23f148d58cd887$export$40f8f9a8f94db930);\n$parcel$export(module.exports, \"ExitViewPortEvent\", () => $2c23f148d58cd887$export$c579e21b95165414);\n$parcel$export(module.exports, \"Fade\", () => $2c23f148d58cd887$export$c983850c6c9d8b0e);\n$parcel$export(module.exports, \"FadeInOut\", () => $2c23f148d58cd887$export$be5b6c6ac24b4683);\n$parcel$export(module.exports, \"Flags\", () => $2c23f148d58cd887$export$434ba092ed0eee4e);\n$parcel$export(module.exports, \"Follow\", () => $2c23f148d58cd887$export$455f05776f1ba8ba);\n$parcel$export(module.exports, \"Font\", () => $2c23f148d58cd887$export$89abf52a030e56ee);\n$parcel$export(module.exports, \"FontCache\", () => $2c23f148d58cd887$export$549c899505235621);\n$parcel$export(module.exports, \"FontSource\", () => $2c23f148d58cd887$export$1f6d1255105a925c);\n$parcel$export(module.exports, \"FontStyle\", () => $2c23f148d58cd887$export$23b468d4ca3f8c96);\n$parcel$export(module.exports, \"FontUnit\", () => $2c23f148d58cd887$export$6976e674e6d5804c);\n$parcel$export(module.exports, \"FpsSampler\", () => $2c23f148d58cd887$export$420acfc1740638d3);\n$parcel$export(module.exports, \"FrameStats\", () => $2c23f148d58cd887$export$e84927905accfe51);\n$parcel$export(module.exports, \"Future\", () => $2c23f148d58cd887$export$c9d7bf589772a8ce);\n$parcel$export(module.exports, \"GameEvent\", () => $2c23f148d58cd887$export$d5011a4647754c9b);\n$parcel$export(module.exports, \"GameStartEvent\", () => $2c23f148d58cd887$export$b8c6aa234afa01bc);\n$parcel$export(module.exports, \"GameStopEvent\", () => $2c23f148d58cd887$export$6c3776220abeb931);\n$parcel$export(module.exports, \"Gamepad\", () => $2c23f148d58cd887$export$27a9cd7ebdd38262);\n$parcel$export(module.exports, \"GamepadAxisEvent\", () => $2c23f148d58cd887$export$fb1b94e06ba8ebc8);\n$parcel$export(module.exports, \"GamepadButtonEvent\", () => $2c23f148d58cd887$export$3d953a2d86354b5f);\n$parcel$export(module.exports, \"GamepadConnectEvent\", () => $2c23f148d58cd887$export$88528019d270f582);\n$parcel$export(module.exports, \"GamepadDisconnectEvent\", () => $2c23f148d58cd887$export$402da60b1c009e43);\n$parcel$export(module.exports, \"Gamepads\", () => $2c23f148d58cd887$export$757ccd1717b77f48);\n$parcel$export(module.exports, \"Gif\", () => $2c23f148d58cd887$export$48ebf29bc7cb1dd7);\n$parcel$export(module.exports, \"GlobalCoordinates\", () => $2c23f148d58cd887$export$3c8c04bde7eed7cb);\n$parcel$export(module.exports, \"Graphic\", () => $2c23f148d58cd887$export$adfa9d260876eca5);\n$parcel$export(module.exports, \"GraphicsComponent\", () => $2c23f148d58cd887$export$6c043ed3a716859a);\n$parcel$export(module.exports, \"GraphicsGroup\", () => $2c23f148d58cd887$export$9f9afb456a8bef30);\n$parcel$export(module.exports, \"GraphicsSystem\", () => $2c23f148d58cd887$export$1033a6fa0779f4f5);\n$parcel$export(module.exports, \"HiddenEvent\", () => $2c23f148d58cd887$export$38f8109d2b8f43ef);\n$parcel$export(module.exports, \"HorizontalFirst\", () => $2c23f148d58cd887$export$b5aa7fe3676b74a9);\n$parcel$export(module.exports, \"ImageFiltering\", () => $2c23f148d58cd887$export$5213deb2877a09f2);\n$parcel$export(module.exports, \"ImageSource\", () => $2c23f148d58cd887$export$280e9a68c3ffd919);\n$parcel$export(module.exports, \"InitializeEvent\", () => $2c23f148d58cd887$export$49a1ecce8d203);\n$parcel$export(module.exports, \"Input\", () => $2c23f148d58cd887$export$f5b8910cec6cf069);\n$parcel$export(module.exports, \"InputHost\", () => $2c23f148d58cd887$export$99f13cbf742a0580);\n$parcel$export(module.exports, \"InputMapper\", () => $2c23f148d58cd887$export$2ae6ec0f10d96242);\n$parcel$export(module.exports, \"Integrator\", () => $2c23f148d58cd887$export$d379657aa3df1705);\n$parcel$export(module.exports, \"IsometricEntityComponent\", () => $2c23f148d58cd887$export$ffed6a4cd9a88787);\n$parcel$export(module.exports, \"IsometricEntitySystem\", () => $2c23f148d58cd887$export$7705889256a9371a);\n$parcel$export(module.exports, \"IsometricMap\", () => $2c23f148d58cd887$export$539f65e788a82c62);\n$parcel$export(module.exports, \"IsometricTile\", () => $2c23f148d58cd887$export$851e6d93385b6ad2);\n$parcel$export(module.exports, \"KeyEvent\", () => $2c23f148d58cd887$export$4b0c1c390bf9a356);\n$parcel$export(module.exports, \"Keyboard\", () => $2c23f148d58cd887$export$16e4d70cc375e707);\n$parcel$export(module.exports, \"Keys\", () => $2c23f148d58cd887$export$4b0075e5ea5e1f26);\n$parcel$export(module.exports, \"KillEvent\", () => $2c23f148d58cd887$export$f3a6c1ca682fd40f);\n$parcel$export(module.exports, \"Label\", () => $2c23f148d58cd887$export$b04be29aa201d4f5);\n$parcel$export(module.exports, \"LimitCameraBoundsStrategy\", () => $2c23f148d58cd887$export$b3509fba7d85d294);\n$parcel$export(module.exports, \"Line\", () => $2c23f148d58cd887$export$17d680238e50603e);\n$parcel$export(module.exports, \"LineSegment\", () => $2c23f148d58cd887$export$8b98feb4a2766c75);\n$parcel$export(module.exports, \"Loader\", () => $2c23f148d58cd887$export$3b0d6d7590275603);\n$parcel$export(module.exports, \"LoaderEvents\", () => $2c23f148d58cd887$export$38d47553764a3d88);\n$parcel$export(module.exports, \"LockCameraToActorAxisStrategy\", () => $2c23f148d58cd887$export$1c4c6d3f8d56581);\n$parcel$export(module.exports, \"LockCameraToActorStrategy\", () => $2c23f148d58cd887$export$fc869739b2177284);\n$parcel$export(module.exports, \"LogLevel\", () => $2c23f148d58cd887$export$243e62d78d3b544d);\n$parcel$export(module.exports, \"Logger\", () => $2c23f148d58cd887$export$efa9a398d6368992);\n$parcel$export(module.exports, \"Material\", () => $2c23f148d58cd887$export$a2d8b23205c25948);\n$parcel$export(module.exports, \"Matrix\", () => $2c23f148d58cd887$export$5b12bf1653c0dd85);\n$parcel$export(module.exports, \"MatrixLocations\", () => $2c23f148d58cd887$export$9f9b2346169b00c0);\n$parcel$export(module.exports, \"MediaEvent\", () => $2c23f148d58cd887$export$8c37b217b84d3f89);\n$parcel$export(module.exports, \"Meet\", () => $2c23f148d58cd887$export$35624b13e79b24a9);\n$parcel$export(module.exports, \"MotionComponent\", () => $2c23f148d58cd887$export$f75e7304717c9cbc);\n$parcel$export(module.exports, \"MotionSystem\", () => $2c23f148d58cd887$export$ec1251c88c8bd5c9);\n$parcel$export(module.exports, \"MoveBy\", () => $2c23f148d58cd887$export$d17844835b0fe8a8);\n$parcel$export(module.exports, \"MoveTo\", () => $2c23f148d58cd887$export$d1d8cb3d5c2a5671);\n$parcel$export(module.exports, \"NativePointerButton\", () => $2c23f148d58cd887$export$4d607ef791645d6);\n$parcel$export(module.exports, \"NativeSoundEvent\", () => $2c23f148d58cd887$export$f0b55daf9f154b55);\n$parcel$export(module.exports, \"NativeSoundProcessedEvent\", () => $2c23f148d58cd887$export$fa9699e41ba6faff);\n$parcel$export(module.exports, \"None\", () => $2c23f148d58cd887$export$57ca7e07b341709d);\n$parcel$export(module.exports, \"Observable\", () => $2c23f148d58cd887$export$77cea355fa80b5f4);\n$parcel$export(module.exports, \"OffscreenSystem\", () => $2c23f148d58cd887$export$8844adde4348f85c);\n$parcel$export(module.exports, \"Pair\", () => $2c23f148d58cd887$export$d63d7cff08fe4dc9);\n$parcel$export(module.exports, \"ParallaxComponent\", () => $2c23f148d58cd887$export$a960801e47624f4f);\n$parcel$export(module.exports, \"ParallelActions\", () => $2c23f148d58cd887$export$ed6a63ee685a4d78);\n$parcel$export(module.exports, \"ParseGif\", () => $2c23f148d58cd887$export$4fe52ae24ae61d51);\n$parcel$export(module.exports, \"Particle\", () => $2c23f148d58cd887$export$c36c68baa13912a5);\n$parcel$export(module.exports, \"ParticleEmitter\", () => $2c23f148d58cd887$export$616c632b282478dd);\n$parcel$export(module.exports, \"ParticleTransform\", () => $2c23f148d58cd887$export$459b1801e3134a24);\n$parcel$export(module.exports, \"Physics\", () => $2c23f148d58cd887$export$2f09efa5b67124a7);\n$parcel$export(module.exports, \"PhysicsStats\", () => $2c23f148d58cd887$export$618424ba3f30cd41);\n$parcel$export(module.exports, \"PhysicsWorld\", () => $2c23f148d58cd887$export$4a963ea7a16edf21);\n$parcel$export(module.exports, \"PointerAbstraction\", () => $2c23f148d58cd887$export$a4017560efebe97d);\n$parcel$export(module.exports, \"PointerButton\", () => $2c23f148d58cd887$export$982e5de016bedff1);\n$parcel$export(module.exports, \"PointerComponent\", () => $2c23f148d58cd887$export$6860c0696b73f79b);\n$parcel$export(module.exports, \"PointerEvent\", () => $2c23f148d58cd887$export$94806efd9890932f);\n$parcel$export(module.exports, \"PointerEventReceiver\", () => $2c23f148d58cd887$export$3bee0b2628b43478);\n$parcel$export(module.exports, \"PointerScope\", () => $2c23f148d58cd887$export$caed39dbb767d548);\n$parcel$export(module.exports, \"PointerSystem\", () => $2c23f148d58cd887$export$7e5ab4f7f9fd407);\n$parcel$export(module.exports, \"PointerType\", () => $2c23f148d58cd887$export$330520496d871ecf);\n$parcel$export(module.exports, \"Polygon\", () => $2c23f148d58cd887$export$7d31b617c820d435);\n$parcel$export(module.exports, \"PolygonCollider\", () => $2c23f148d58cd887$export$f23a2a272a8df60);\n$parcel$export(module.exports, \"Pool\", () => $2c23f148d58cd887$export$14963ee5c8637e11);\n$parcel$export(module.exports, \"PostCollisionEvent\", () => $2c23f148d58cd887$export$1d2c184034fc4cc2);\n$parcel$export(module.exports, \"PostDebugDrawEvent\", () => $2c23f148d58cd887$export$fea21a521a6360c1);\n$parcel$export(module.exports, \"PostDrawEvent\", () => $2c23f148d58cd887$export$8c15bdf7e3727f73);\n$parcel$export(module.exports, \"PostFrameEvent\", () => $2c23f148d58cd887$export$6eb043bf81d89752);\n$parcel$export(module.exports, \"PostKillEvent\", () => $2c23f148d58cd887$export$e390b859365a3d5b);\n$parcel$export(module.exports, \"PostTransformDrawEvent\", () => $2c23f148d58cd887$export$82a33120f6a0d987);\n$parcel$export(module.exports, \"PostUpdateEvent\", () => $2c23f148d58cd887$export$1ec85152758537e0);\n$parcel$export(module.exports, \"PreCollisionEvent\", () => $2c23f148d58cd887$export$a8584993858a18df);\n$parcel$export(module.exports, \"PreDebugDrawEvent\", () => $2c23f148d58cd887$export$906049a3747337a6);\n$parcel$export(module.exports, \"PreDrawEvent\", () => $2c23f148d58cd887$export$dbd8a6303ac26a42);\n$parcel$export(module.exports, \"PreFrameEvent\", () => $2c23f148d58cd887$export$9f68b6f37a444556);\n$parcel$export(module.exports, \"PreKillEvent\", () => $2c23f148d58cd887$export$fe2b6ac465da985d);\n$parcel$export(module.exports, \"PreLoadEvent\", () => $2c23f148d58cd887$export$4c3c82f4dcd79fcc);\n$parcel$export(module.exports, \"PreTransformDrawEvent\", () => $2c23f148d58cd887$export$e4ce43ec0499fb8f);\n$parcel$export(module.exports, \"PreUpdateEvent\", () => $2c23f148d58cd887$export$e44279b5c44add28);\n$parcel$export(module.exports, \"Projection\", () => $2c23f148d58cd887$export$dfa3a012bb2ef2e1);\n$parcel$export(module.exports, \"QuadIndexBuffer\", () => $2c23f148d58cd887$export$8201b979875baf73);\n$parcel$export(module.exports, \"QuadTree\", () => $2c23f148d58cd887$export$b82688eb02220411);\n$parcel$export(module.exports, \"Query\", () => $2c23f148d58cd887$export$62297b13309008b2);\n$parcel$export(module.exports, \"QueryManager\", () => $2c23f148d58cd887$export$b986383a50b53ea4);\n$parcel$export(module.exports, \"RadiusAroundActorStrategy\", () => $2c23f148d58cd887$export$ad5b3d166367714c);\n$parcel$export(module.exports, \"Random\", () => $2c23f148d58cd887$export$a92776769f460054);\n$parcel$export(module.exports, \"Raster\", () => $2c23f148d58cd887$export$eeb71495ca594706);\n$parcel$export(module.exports, \"Ray\", () => $2c23f148d58cd887$export$a186db52eed6d40e);\n$parcel$export(module.exports, \"RealisticSolver\", () => $2c23f148d58cd887$export$c07ce6d13c46df49);\n$parcel$export(module.exports, \"Rectangle\", () => $2c23f148d58cd887$export$4617fb02663045ef);\n$parcel$export(module.exports, \"RemovedComponent\", () => $2c23f148d58cd887$export$32437fc39ad02208);\n$parcel$export(module.exports, \"Repeat\", () => $2c23f148d58cd887$export$f9d61a2a6155ab51);\n$parcel$export(module.exports, \"RepeatForever\", () => $2c23f148d58cd887$export$9bd81f7d9b69ccb3);\n$parcel$export(module.exports, \"Resolution\", () => $2c23f148d58cd887$export$3e4ff2216a90b8a4);\n$parcel$export(module.exports, \"Resource\", () => $2c23f148d58cd887$export$39a853cfb5a94a63);\n$parcel$export(module.exports, \"ResourceEvents\", () => $2c23f148d58cd887$export$62833702c6700187);\n$parcel$export(module.exports, \"RotateBy\", () => $2c23f148d58cd887$export$a43177620e7a9310);\n$parcel$export(module.exports, \"RotateTo\", () => $2c23f148d58cd887$export$a16b6ef1fd362a19);\n$parcel$export(module.exports, \"RotationType\", () => $2c23f148d58cd887$export$91397be43fc980cc);\n$parcel$export(module.exports, \"ScaleBy\", () => $2c23f148d58cd887$export$23b9d128e61caefd);\n$parcel$export(module.exports, \"ScaleTo\", () => $2c23f148d58cd887$export$ab681471d41eeddc);\n$parcel$export(module.exports, \"Scene\", () => $2c23f148d58cd887$export$38af1803e3442a7f);\n$parcel$export(module.exports, \"SceneEvents\", () => $2c23f148d58cd887$export$c1825d965cf69ea3);\n$parcel$export(module.exports, \"Screen\", () => $2c23f148d58cd887$export$a98515d67472a41f);\n$parcel$export(module.exports, \"ScreenAppender\", () => $2c23f148d58cd887$export$57486627f01aaaf3);\n$parcel$export(module.exports, \"ScreenElement\", () => $2c23f148d58cd887$export$77630fcd7c3f2eb6);\n$parcel$export(module.exports, \"ScreenEvents\", () => $2c23f148d58cd887$export$3bf088dd0bb7575);\n$parcel$export(module.exports, \"ScreenShader\", () => $2c23f148d58cd887$export$2f3ac66e390c188b);\n$parcel$export(module.exports, \"ScrollPreventionMode\", () => $2c23f148d58cd887$export$d160a188872e1e4e);\n$parcel$export(module.exports, \"Semaphore\", () => $2c23f148d58cd887$export$5c7bd08c630c970c);\n$parcel$export(module.exports, \"Shader\", () => $2c23f148d58cd887$export$462bb059fed9d9e5);\n$parcel$export(module.exports, \"Shape\", () => $2c23f148d58cd887$export$6428a7f2611ef1fa);\n$parcel$export(module.exports, \"Side\", () => $2c23f148d58cd887$export$80a00690bda7f17e);\n$parcel$export(module.exports, \"SolverStrategy\", () => $2c23f148d58cd887$export$50994fad4c4676f4);\n$parcel$export(module.exports, \"Sound\", () => $2c23f148d58cd887$export$85990f0f98a390bb);\n$parcel$export(module.exports, \"SoundEvents\", () => $2c23f148d58cd887$export$5bff0d6cc6200d64);\n$parcel$export(module.exports, \"Sprite\", () => $2c23f148d58cd887$export$3075603db8e6204c);\n$parcel$export(module.exports, \"SpriteFont\", () => $2c23f148d58cd887$export$e1896ac0c4970221);\n$parcel$export(module.exports, \"SpriteSheet\", () => $2c23f148d58cd887$export$bd73ddfe5f8475d8);\n$parcel$export(module.exports, \"StandardClock\", () => $2c23f148d58cd887$export$f62bb2892382b3dd);\n$parcel$export(module.exports, \"StateMachine\", () => $2c23f148d58cd887$export$cbf2d83d1eab018a);\n$parcel$export(module.exports, \"StrategyContainer\", () => $2c23f148d58cd887$export$9ad53eded130cce4);\n$parcel$export(module.exports, \"Stream\", () => $2c23f148d58cd887$export$6a4eb2e7fc9e8903);\n$parcel$export(module.exports, \"System\", () => $2c23f148d58cd887$export$e1dae5660003ffa7);\n$parcel$export(module.exports, \"SystemManager\", () => $2c23f148d58cd887$export$a12e67a4b4590901);\n$parcel$export(module.exports, \"SystemPriority\", () => $2c23f148d58cd887$export$7c88eb83095afadd);\n$parcel$export(module.exports, \"SystemType\", () => $2c23f148d58cd887$export$c586aa7b67d94d19);\n$parcel$export(module.exports, \"TagQuery\", () => $2c23f148d58cd887$export$47b45ce774071a36);\n$parcel$export(module.exports, \"TestClock\", () => $2c23f148d58cd887$export$9440a22058545f9a);\n$parcel$export(module.exports, \"Text\", () => $2c23f148d58cd887$export$5f1af8db9871e1d6);\n$parcel$export(module.exports, \"TextAlign\", () => $2c23f148d58cd887$export$3720eb13f948f394);\n$parcel$export(module.exports, \"TextureLoader\", () => $2c23f148d58cd887$export$fd1bfc71f64c538c);\n$parcel$export(module.exports, \"Tile\", () => $2c23f148d58cd887$export$235cb65c20ad2b7);\n$parcel$export(module.exports, \"TileMap\", () => $2c23f148d58cd887$export$16ec26812de3ce7a);\n$parcel$export(module.exports, \"TileMapEvents\", () => $2c23f148d58cd887$export$dac3abbdc575ce73);\n$parcel$export(module.exports, \"Timer\", () => $2c23f148d58cd887$export$c57e9b2d8b9e4de);\n$parcel$export(module.exports, \"Toaster\", () => $2c23f148d58cd887$export$fb98e3a2a4cd92d7);\n$parcel$export(module.exports, \"Transform\", () => $2c23f148d58cd887$export$563a914cafbdc389);\n$parcel$export(module.exports, \"TransformComponent\", () => $2c23f148d58cd887$export$1def2aa75b7c7fe0);\n$parcel$export(module.exports, \"Transition\", () => $2c23f148d58cd887$export$be58926105124dd4);\n$parcel$export(module.exports, \"TreeNode\", () => $2c23f148d58cd887$export$2eba8ec3a333fdbb);\n$parcel$export(module.exports, \"Trigger\", () => $2c23f148d58cd887$export$41fb9f06171c75f4);\n$parcel$export(module.exports, \"TriggerEvents\", () => $2c23f148d58cd887$export$14963f945d6d59f0);\n$parcel$export(module.exports, \"TwoPI\", () => $2c23f148d58cd887$export$ba8651401a8a2b84);\n$parcel$export(module.exports, \"Util\", () => $2c23f148d58cd887$export$f8f26dd395d7e1bd);\n$parcel$export(module.exports, \"Vector\", () => $2c23f148d58cd887$export$9b781de7bf37bf48);\n$parcel$export(module.exports, \"VectorView\", () => $2c23f148d58cd887$export$ab650c8e5b9b9f2c);\n$parcel$export(module.exports, \"VertexBuffer\", () => $2c23f148d58cd887$export$41825a1ed6473903);\n$parcel$export(module.exports, \"VertexLayout\", () => $2c23f148d58cd887$export$f5ae2f144b95ebf4);\n$parcel$export(module.exports, \"VerticalFirst\", () => $2c23f148d58cd887$export$31ac8f65680039dd);\n$parcel$export(module.exports, \"VisibleEvent\", () => $2c23f148d58cd887$export$d5c6f73f7a77b9d);\n$parcel$export(module.exports, \"WebAudio\", () => $2c23f148d58cd887$export$8bfbf00b5dba81f6);\n$parcel$export(module.exports, \"WebAudioInstance\", () => $2c23f148d58cd887$export$2af5ef044257da25);\n$parcel$export(module.exports, \"WheelDeltaMode\", () => $2c23f148d58cd887$export$8c3375c231593a9d);\n$parcel$export(module.exports, \"WheelEvent\", () => $2c23f148d58cd887$export$9a4eae43f302c46e);\n$parcel$export(module.exports, \"World\", () => $2c23f148d58cd887$export$812cd9544993280d);\n$parcel$export(module.exports, \"canonicalizeAngle\", () => $2c23f148d58cd887$export$a4913eafbb02ceb4);\n$parcel$export(module.exports, \"clamp\", () => $2c23f148d58cd887$export$7d15b64cf5a3a4c4);\n$parcel$export(module.exports, \"coroutine\", () => $2c23f148d58cd887$export$c372a5d5a3996cbf);\n$parcel$export(module.exports, \"createId\", () => $2c23f148d58cd887$export$7149c6ffc9994c32);\n$parcel$export(module.exports, \"frac\", () => $2c23f148d58cd887$export$d436988b04cb99a5);\n$parcel$export(module.exports, \"hasGraphicsTick\", () => $2c23f148d58cd887$export$3ba9f2e94585ecc6);\n$parcel$export(module.exports, \"hasOnInitialize\", () => $2c23f148d58cd887$export$25dac40984956196);\n$parcel$export(module.exports, \"hasOnPostUpdate\", () => $2c23f148d58cd887$export$57932b71da6538b7);\n$parcel$export(module.exports, \"hasOnPreUpdate\", () => $2c23f148d58cd887$export$a17402ef5f32064d);\n$parcel$export(module.exports, \"hasPostDraw\", () => $2c23f148d58cd887$export$d5dea09620a858fd);\n$parcel$export(module.exports, \"hasPreDraw\", () => $2c23f148d58cd887$export$1377812d73ae3cab);\n$parcel$export(module.exports, \"has_initialize\", () => $2c23f148d58cd887$export$331f4c7ef74a9752);\n$parcel$export(module.exports, \"has_postupdate\", () => $2c23f148d58cd887$export$5f4e18965661d41f);\n$parcel$export(module.exports, \"has_preupdate\", () => $2c23f148d58cd887$export$817667946f51142b);\n$parcel$export(module.exports, \"isAddedComponent\", () => $2c23f148d58cd887$export$adc479603c39b28);\n$parcel$export(module.exports, \"isComponentCtor\", () => $2c23f148d58cd887$export$ba30ba18962891e7);\n$parcel$export(module.exports, \"isLoaderConstructor\", () => $2c23f148d58cd887$export$bcf8f1355133000b);\n$parcel$export(module.exports, \"isRemovedComponent\", () => $2c23f148d58cd887$export$256576ea924e6c90);\n$parcel$export(module.exports, \"isSceneConstructor\", () => $2c23f148d58cd887$export$786d9ab531bddbaa);\n$parcel$export(module.exports, \"isScreenElement\", () => $2c23f148d58cd887$export$e87630d8ef35465d);\n$parcel$export(module.exports, \"isSystemConstructor\", () => $2c23f148d58cd887$export$c3cedacda2d7ce48);\n$parcel$export(module.exports, \"maxMessages\", () => $2c23f148d58cd887$export$5a62d8eea226ddc);\n$parcel$export(module.exports, \"obsolete\", () => $2c23f148d58cd887$export$640d107500a3202a);\n$parcel$export(module.exports, \"pixelSnapEpsilon\", () => $2c23f148d58cd887$export$506bf22710a79182);\n$parcel$export(module.exports, \"randomInRange\", () => $2c23f148d58cd887$export$8b958c8ecd94a804);\n$parcel$export(module.exports, \"randomIntInRange\", () => $2c23f148d58cd887$export$816343276f749e02);\n$parcel$export(module.exports, \"range\", () => $2c23f148d58cd887$export$d02631cccf789723);\n$parcel$export(module.exports, \"resetObsoleteCounter\", () => $2c23f148d58cd887$export$5dc5812d8b390c43);\n$parcel$export(module.exports, \"sign\", () => $2c23f148d58cd887$export$c5552dfdbc7cec71);\n$parcel$export(module.exports, \"toDegrees\", () => $2c23f148d58cd887$export$56cb859c01fa134d);\n$parcel$export(module.exports, \"toRadians\", () => $2c23f148d58cd887$export$cba01ba138429a1d);\n$parcel$export(module.exports, \"vec\", () => $2c23f148d58cd887$export$202e0172ed3c7be0);\n$parcel$export(module.exports, \"webgl\", () => $2c23f148d58cd887$export$d55298c9efc5ed14);\n/*!\n * excalibur - 0.29.1 - 2024-2-23\n * https://github.com/excaliburjs/Excalibur\n * Copyright (c) 2024 Excalibur.js \n * Licensed BSD-2-Clause\n * @preserve\n */ /******/ var $2c23f148d58cd887$var$__webpack_modules__ = {\n /***/ 7835: /***/ (module, __webpack_exports__, __webpack_require__)=>{\n /* harmony export */ __webpack_require__.d(__webpack_exports__, {\n /* harmony export */ Z: ()=>__WEBPACK_DEFAULT_EXPORT__\n });\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n // Imports\n var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default());\n // Module\n ___CSS_LOADER_EXPORT___.push([\n module.id,\n `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`,\n \"\",\n {\n \"version\": 3,\n \"sources\": [\n \"webpack://./Director/Loader.css\"\n ],\n \"names\": [],\n \"mappings\": \"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\n \"sourcesContent\": [\n \"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"\n ],\n \"sourceRoot\": \"\"\n }\n ]);\n // Exports\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ___CSS_LOADER_EXPORT___;\n /***/ },\n /***/ 7379: /***/ (module, __webpack_exports__, __webpack_require__)=>{\n /* harmony export */ __webpack_require__.d(__webpack_exports__, {\n /* harmony export */ Z: ()=>__WEBPACK_DEFAULT_EXPORT__\n });\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n // Imports\n var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default());\n // Module\n ___CSS_LOADER_EXPORT___.push([\n module.id,\n `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`,\n \"\",\n {\n \"version\": 3,\n \"sources\": [\n \"webpack://./Util/Toaster.css\"\n ],\n \"names\": [],\n \"mappings\": \";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\n \"sourcesContent\": [\n \"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"\n ],\n \"sourceRoot\": \"\"\n }\n ]);\n // Exports\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ___CSS_LOADER_EXPORT___;\n /***/ },\n /***/ 2609: /***/ (module)=>{\n /*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/ module.exports = function(cssWithMappingToString) {\n var list = [];\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function(item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) content += \"@supports (\".concat(item[4], \") {\");\n if (item[2]) content += \"@media \".concat(item[2], \" {\");\n if (needLayer) content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n content += cssWithMappingToString(item);\n if (needLayer) content += \"}\";\n if (item[2]) content += \"}\";\n if (item[4]) content += \"}\";\n return content;\n }).join(\"\");\n };\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") modules = [\n [\n null,\n modules,\n undefined\n ]\n ];\n var alreadyImportedModules = {};\n if (dedupe) for(var k = 0; k < this.length; k++){\n var id = this[k][0];\n if (id != null) alreadyImportedModules[id] = true;\n }\n for(var _k = 0; _k < modules.length; _k++){\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) continue;\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") item[5] = layer;\n else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) item[2] = media;\n else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) item[4] = \"\".concat(supports);\n else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n };\n /***/ },\n /***/ 272: /***/ (module)=>{\n module.exports = function(item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) return content;\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [\n content\n ].concat([\n sourceMapping\n ]).join(\"\\n\");\n }\n return [\n content\n ].join(\"\\n\");\n };\n /***/ },\n /***/ 1324: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n __webpack_require__(7206);\n var entryUnbind = __webpack_require__(8193);\n module.exports = entryUnbind(\"Array\", \"sort\");\n /***/ },\n /***/ 3571: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n __webpack_require__(9867);\n var path = __webpack_require__(8588);\n module.exports = path.Object.keys;\n /***/ },\n /***/ 1052: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(688);\n var tryToString = __webpack_require__(3397);\n var $TypeError = TypeError;\n // `Assert: IsCallable(argument) is true`\n module.exports = function(argument) {\n if (isCallable(argument)) return argument;\n throw new $TypeError(tryToString(argument) + \" is not a function\");\n };\n /***/ },\n /***/ 9175: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isObject = __webpack_require__(5309);\n var $String = String;\n var $TypeError = TypeError;\n // `Assert: Type(argument) is Object`\n module.exports = function(argument) {\n if (isObject(argument)) return argument;\n throw new $TypeError($String(argument) + \" is not an object\");\n };\n /***/ },\n /***/ 1138: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIndexedObject = __webpack_require__(6854);\n var toAbsoluteIndex = __webpack_require__(7352);\n var lengthOfArrayLike = __webpack_require__(8344);\n // `Array.prototype.{ indexOf, includes }` methods implementation\n var createMethod = function(IS_INCLUDES) {\n return function($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el !== el) while(length > index){\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value !== value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n }\n else for(; length > index; index++){\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n }\n return !IS_INCLUDES && -1;\n };\n };\n module.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n };\n /***/ },\n /***/ 567: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4694);\n module.exports = function(METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function() {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function() {\n return 1;\n }, 1);\n });\n };\n /***/ },\n /***/ 7686: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n module.exports = uncurryThis([].slice);\n /***/ },\n /***/ 3097: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var arraySlice = __webpack_require__(7686);\n var floor = Math.floor;\n var sort = function(array, comparefn) {\n var length = array.length;\n if (length < 8) {\n // insertion sort\n var i = 1;\n var element, j;\n while(i < length){\n j = i;\n element = array[i];\n while(j && comparefn(array[j - 1], element) > 0)array[j] = array[--j];\n if (j !== i++) array[j] = element;\n }\n } else {\n // merge sort\n var middle = floor(length / 2);\n var left = sort(arraySlice(array, 0, middle), comparefn);\n var right = sort(arraySlice(array, middle), comparefn);\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n while(lindex < llength || rindex < rlength)array[lindex + rindex] = lindex < llength && rindex < rlength ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++] : lindex < llength ? left[lindex++] : right[rindex++];\n }\n return array;\n };\n module.exports = sort;\n /***/ },\n /***/ 2177: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var toString = uncurryThis({}.toString);\n var stringSlice = uncurryThis(\"\".slice);\n module.exports = function(it) {\n return stringSlice(toString(it), 8, -1);\n };\n /***/ },\n /***/ 1566: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var TO_STRING_TAG_SUPPORT = __webpack_require__(2522);\n var isCallable = __webpack_require__(688);\n var classofRaw = __webpack_require__(2177);\n var wellKnownSymbol = __webpack_require__(2032);\n var TO_STRING_TAG = wellKnownSymbol(\"toStringTag\");\n var $Object = Object;\n // ES3 wrong here\n var CORRECT_ARGUMENTS = classofRaw(function() {\n return arguments;\n }()) === \"Arguments\";\n // fallback for IE11 Script Access Denied error\n var tryGet = function(it, key) {\n try {\n return it[key];\n } catch (error) {}\n };\n // getting tag from ES6+ `Object.prototype.toString`\n module.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) {\n var O, tag, result;\n return it === undefined ? \"Undefined\" : it === null ? \"Null\" : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == \"string\" ? tag : CORRECT_ARGUMENTS ? classofRaw(O) : (result = classofRaw(O)) === \"Object\" && isCallable(O.callee) ? \"Arguments\" : result;\n };\n /***/ },\n /***/ 3891: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var hasOwn = __webpack_require__(4678);\n var ownKeys = __webpack_require__(990);\n var getOwnPropertyDescriptorModule = __webpack_require__(7537);\n var definePropertyModule = __webpack_require__(2131);\n module.exports = function(target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for(var i = 0; i < keys.length; i++){\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n };\n /***/ },\n /***/ 2385: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var definePropertyModule = __webpack_require__(2131);\n var createPropertyDescriptor = __webpack_require__(7781);\n module.exports = DESCRIPTORS ? function(object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n } : function(object, key, value) {\n object[key] = value;\n return object;\n };\n /***/ },\n /***/ 7781: /***/ (module)=>{\n module.exports = function(bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n };\n /***/ },\n /***/ 2470: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(688);\n var definePropertyModule = __webpack_require__(2131);\n var makeBuiltIn = __webpack_require__(1135);\n var defineGlobalProperty = __webpack_require__(1604);\n module.exports = function(O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) {}\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n }\n return O;\n };\n /***/ },\n /***/ 1604: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var defineProperty = Object.defineProperty;\n module.exports = function(key, value) {\n try {\n defineProperty(global, key, {\n value: value,\n configurable: true,\n writable: true\n });\n } catch (error) {\n global[key] = value;\n }\n return value;\n };\n /***/ },\n /***/ 955: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var tryToString = __webpack_require__(3397);\n var $TypeError = TypeError;\n module.exports = function(O, P) {\n if (!delete O[P]) throw new $TypeError(\"Cannot delete property \" + tryToString(P) + \" of \" + tryToString(O));\n };\n /***/ },\n /***/ 9924: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4694);\n // Detect IE8's incomplete defineProperty implementation\n module.exports = !fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, {\n get: function() {\n return 7;\n }\n })[1] !== 7;\n });\n /***/ },\n /***/ 1442: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var isObject = __webpack_require__(5309);\n var document1 = global.document;\n // typeof document.createElement is 'object' in old IE\n var EXISTS = isObject(document1) && isObject(document1.createElement);\n module.exports = function(it) {\n return EXISTS ? document1.createElement(it) : {};\n };\n /***/ },\n /***/ 9016: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var userAgent = __webpack_require__(1370);\n var firefox = userAgent.match(/firefox\\/(\\d+)/i);\n module.exports = !!firefox && +firefox[1];\n /***/ },\n /***/ 821: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var UA = __webpack_require__(1370);\n module.exports = /MSIE|Trident/.test(UA);\n /***/ },\n /***/ 1370: /***/ (module)=>{\n module.exports = typeof navigator != \"undefined\" && String(navigator.userAgent) || \"\";\n /***/ },\n /***/ 7067: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var userAgent = __webpack_require__(1370);\n var process = global.process;\n var Deno = global.Deno;\n var versions = process && process.versions || Deno && Deno.version;\n var v8 = versions && versions.v8;\n var match, version;\n if (v8) {\n match = v8.split(\".\");\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n }\n // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n // so check `userAgent` even if `.v8` exists, but 0\n if (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n }\n module.exports = version;\n /***/ },\n /***/ 4389: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var userAgent = __webpack_require__(1370);\n var webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n module.exports = !!webkit && +webkit[1];\n /***/ },\n /***/ 8193: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var uncurryThis = __webpack_require__(9668);\n module.exports = function(CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n };\n /***/ },\n /***/ 2367: /***/ (module)=>{\n // IE8- don't enum bug keys\n module.exports = [\n \"constructor\",\n \"hasOwnProperty\",\n \"isPrototypeOf\",\n \"propertyIsEnumerable\",\n \"toLocaleString\",\n \"toString\",\n \"valueOf\"\n ];\n /***/ },\n /***/ 5532: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var getOwnPropertyDescriptor = __webpack_require__(7537).f;\n var createNonEnumerableProperty = __webpack_require__(2385);\n var defineBuiltIn = __webpack_require__(2470);\n var defineGlobalProperty = __webpack_require__(1604);\n var copyConstructorProperties = __webpack_require__(3891);\n var isForced = __webpack_require__(1633);\n /*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/ module.exports = function(options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) target = global;\n else if (STATIC) target = global[TARGET] || defineGlobalProperty(TARGET, {});\n else target = global[TARGET] && global[TARGET].prototype;\n if (target) for(key in source){\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? \".\" : \"#\") + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || targetProperty && targetProperty.sham) createNonEnumerableProperty(sourceProperty, \"sham\", true);\n defineBuiltIn(target, key, sourceProperty, options);\n }\n };\n /***/ },\n /***/ 4694: /***/ (module)=>{\n module.exports = function(exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n };\n /***/ },\n /***/ 6398: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4694);\n module.exports = !fails(function() {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function() {}).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != \"function\" || test.hasOwnProperty(\"prototype\");\n });\n /***/ },\n /***/ 8724: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_BIND = __webpack_require__(6398);\n var call = Function.prototype.call;\n module.exports = NATIVE_BIND ? call.bind(call) : function() {\n return call.apply(call, arguments);\n };\n /***/ },\n /***/ 453: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var hasOwn = __webpack_require__(4678);\n var FunctionPrototype = Function.prototype;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n var EXISTS = hasOwn(FunctionPrototype, \"name\");\n // additional protection from minified / mangled / dropped function names\n var PROPER = EXISTS && (function something() {}).name === \"something\";\n var CONFIGURABLE = EXISTS && (!DESCRIPTORS || DESCRIPTORS && getDescriptor(FunctionPrototype, \"name\").configurable);\n module.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n };\n /***/ },\n /***/ 9668: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_BIND = __webpack_require__(6398);\n var FunctionPrototype = Function.prototype;\n var call = FunctionPrototype.call;\n var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n module.exports = NATIVE_BIND ? uncurryThisWithBind : function(fn) {\n return function() {\n return call.apply(fn, arguments);\n };\n };\n /***/ },\n /***/ 2160: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var isCallable = __webpack_require__(688);\n var aFunction = function(argument) {\n return isCallable(argument) ? argument : undefined;\n };\n module.exports = function(namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n };\n /***/ },\n /***/ 5383: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var aCallable = __webpack_require__(1052);\n var isNullOrUndefined = __webpack_require__(5268);\n // `GetMethod` abstract operation\n // https://tc39.es/ecma262/#sec-getmethod\n module.exports = function(V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n };\n /***/ },\n /***/ 2150: /***/ function(module, __unused_webpack_exports, __webpack_require__) {\n var check = function(it) {\n return it && it.Math === Math && it;\n };\n // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\n module.exports = // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == \"object\" && globalThis) || check(typeof window == \"object\" && window) || // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == \"object\" && self) || check(typeof __webpack_require__.g == \"object\" && __webpack_require__.g) || check(typeof this == \"object\" && this) || // eslint-disable-next-line no-new-func -- fallback\n function() {\n return this;\n }() || Function(\"return this\")();\n /***/ },\n /***/ 4678: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var toObject = __webpack_require__(298);\n var hasOwnProperty = uncurryThis({}.hasOwnProperty);\n // `HasOwnProperty` abstract operation\n // https://tc39.es/ecma262/#sec-hasownproperty\n // eslint-disable-next-line es/no-object-hasown -- safe\n module.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n };\n /***/ },\n /***/ 7390: /***/ (module)=>{\n module.exports = {};\n /***/ },\n /***/ 7913: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var fails = __webpack_require__(4694);\n var createElement = __webpack_require__(1442);\n // Thanks to IE8 for its funny defineProperty\n module.exports = !DESCRIPTORS && !fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement(\"div\"), \"a\", {\n get: function() {\n return 7;\n }\n }).a !== 7;\n });\n /***/ },\n /***/ 4347: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var fails = __webpack_require__(4694);\n var classof = __webpack_require__(2177);\n var $Object = Object;\n var split = uncurryThis(\"\".split);\n // fallback for non-array-like ES3 and non-enumerable old V8 strings\n module.exports = fails(function() {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object(\"z\").propertyIsEnumerable(0);\n }) ? function(it) {\n return classof(it) === \"String\" ? split(it, \"\") : $Object(it);\n } : $Object;\n /***/ },\n /***/ 1881: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var isCallable = __webpack_require__(688);\n var store = __webpack_require__(6762);\n var functionToString = uncurryThis(Function.toString);\n // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\n if (!isCallable(store.inspectSource)) store.inspectSource = function(it) {\n return functionToString(it);\n };\n module.exports = store.inspectSource;\n /***/ },\n /***/ 7804: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_WEAK_MAP = __webpack_require__(4724);\n var global = __webpack_require__(2150);\n var isObject = __webpack_require__(5309);\n var createNonEnumerableProperty = __webpack_require__(2385);\n var hasOwn = __webpack_require__(4678);\n var shared = __webpack_require__(6762);\n var sharedKey = __webpack_require__(1962);\n var hiddenKeys = __webpack_require__(7390);\n var OBJECT_ALREADY_INITIALIZED = \"Object already initialized\";\n var TypeError1 = global.TypeError;\n var WeakMap1 = global.WeakMap;\n var set, get, has;\n var enforce = function(it) {\n return has(it) ? get(it) : set(it, {});\n };\n var getterFor = function(TYPE) {\n return function(it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) throw new TypeError1(\"Incompatible receiver, \" + TYPE + \" required\");\n return state;\n };\n };\n if (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap1());\n /* eslint-disable no-self-assign -- prototype methods protection */ store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */ set = function(it, metadata) {\n if (store.has(it)) throw new TypeError1(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function(it) {\n return store.get(it) || {};\n };\n has = function(it) {\n return store.has(it);\n };\n } else {\n var STATE = sharedKey(\"state\");\n hiddenKeys[STATE] = true;\n set = function(it, metadata) {\n if (hasOwn(it, STATE)) throw new TypeError1(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function(it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function(it) {\n return hasOwn(it, STATE);\n };\n }\n module.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n };\n /***/ },\n /***/ 688: /***/ (module)=>{\n // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\n var documentAll = typeof document == \"object\" && document.all;\n // `IsCallable` abstract operation\n // https://tc39.es/ecma262/#sec-iscallable\n // eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\n module.exports = typeof documentAll == \"undefined\" && documentAll !== undefined ? function(argument) {\n return typeof argument == \"function\" || argument === documentAll;\n } : function(argument) {\n return typeof argument == \"function\";\n };\n /***/ },\n /***/ 1633: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4694);\n var isCallable = __webpack_require__(688);\n var replacement = /#|\\.prototype\\./;\n var isForced = function(feature, detection) {\n var value = data[normalize(feature)];\n return value === POLYFILL ? true : value === NATIVE ? false : isCallable(detection) ? fails(detection) : !!detection;\n };\n var normalize = isForced.normalize = function(string) {\n return String(string).replace(replacement, \".\").toLowerCase();\n };\n var data = isForced.data = {};\n var NATIVE = isForced.NATIVE = \"N\";\n var POLYFILL = isForced.POLYFILL = \"P\";\n module.exports = isForced;\n /***/ },\n /***/ 5268: /***/ (module)=>{\n // we can't use just `it == null` since of `document.all` special case\n // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\n module.exports = function(it) {\n return it === null || it === undefined;\n };\n /***/ },\n /***/ 5309: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(688);\n module.exports = function(it) {\n return typeof it == \"object\" ? it !== null : isCallable(it);\n };\n /***/ },\n /***/ 6555: /***/ (module)=>{\n module.exports = false;\n /***/ },\n /***/ 7935: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var getBuiltIn = __webpack_require__(2160);\n var isCallable = __webpack_require__(688);\n var isPrototypeOf = __webpack_require__(6148);\n var USE_SYMBOL_AS_UID = __webpack_require__(4866);\n var $Object = Object;\n module.exports = USE_SYMBOL_AS_UID ? function(it) {\n return typeof it == \"symbol\";\n } : function(it) {\n var $Symbol = getBuiltIn(\"Symbol\");\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n };\n /***/ },\n /***/ 8344: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toLength = __webpack_require__(7331);\n // `LengthOfArrayLike` abstract operation\n // https://tc39.es/ecma262/#sec-lengthofarraylike\n module.exports = function(obj) {\n return toLength(obj.length);\n };\n /***/ },\n /***/ 1135: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var fails = __webpack_require__(4694);\n var isCallable = __webpack_require__(688);\n var hasOwn = __webpack_require__(4678);\n var DESCRIPTORS = __webpack_require__(9924);\n var CONFIGURABLE_FUNCTION_NAME = __webpack_require__(453).CONFIGURABLE;\n var inspectSource = __webpack_require__(1881);\n var InternalStateModule = __webpack_require__(7804);\n var enforceInternalState = InternalStateModule.enforce;\n var getInternalState = InternalStateModule.get;\n var $String = String;\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var defineProperty = Object.defineProperty;\n var stringSlice = uncurryThis(\"\".slice);\n var replace = uncurryThis(\"\".replace);\n var join = uncurryThis([].join);\n var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {\n return defineProperty(function() {}, \"length\", {\n value: 8\n }).length !== 8;\n });\n var TEMPLATE = String(String).split(\"String\");\n var makeBuiltIn = module.exports = function(value, name, options) {\n if (stringSlice($String(name), 0, 7) === \"Symbol(\") name = \"[\" + replace($String(name), /^Symbol\\(([^)]*)\\).*$/, \"$1\") + \"]\";\n if (options && options.getter) name = \"get \" + name;\n if (options && options.setter) name = \"set \" + name;\n if (!hasOwn(value, \"name\") || CONFIGURABLE_FUNCTION_NAME && value.name !== name) {\n if (DESCRIPTORS) defineProperty(value, \"name\", {\n value: name,\n configurable: true\n });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, \"arity\") && value.length !== options.arity) defineProperty(value, \"length\", {\n value: options.arity\n });\n try {\n if (options && hasOwn(options, \"constructor\") && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, \"prototype\", {\n writable: false\n });\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) {}\n var state = enforceInternalState(value);\n if (!hasOwn(state, \"source\")) state.source = join(TEMPLATE, typeof name == \"string\" ? name : \"\");\n return value;\n };\n // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n // eslint-disable-next-line no-extend-native -- required\n Function.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n }, \"toString\");\n /***/ },\n /***/ 1787: /***/ (module)=>{\n var ceil = Math.ceil;\n var floor = Math.floor;\n // `Math.trunc` method\n // https://tc39.es/ecma262/#sec-math.trunc\n // eslint-disable-next-line es/no-math-trunc -- safe\n module.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n };\n /***/ },\n /***/ 2131: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var IE8_DOM_DEFINE = __webpack_require__(7913);\n var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(2666);\n var anObject = __webpack_require__(9175);\n var toPropertyKey = __webpack_require__(2358);\n var $TypeError = TypeError;\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var $defineProperty = Object.defineProperty;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n var ENUMERABLE = \"enumerable\";\n var CONFIGURABLE = \"configurable\";\n var WRITABLE = \"writable\";\n // `Object.defineProperty` method\n // https://tc39.es/ecma262/#sec-object.defineproperty\n exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === \"function\" && P === \"prototype\" && \"value\" in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n }\n return $defineProperty(O, P, Attributes);\n } : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) {}\n if (\"get\" in Attributes || \"set\" in Attributes) throw new $TypeError(\"Accessors not supported\");\n if (\"value\" in Attributes) O[P] = Attributes.value;\n return O;\n };\n /***/ },\n /***/ 7537: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var call = __webpack_require__(8724);\n var propertyIsEnumerableModule = __webpack_require__(8208);\n var createPropertyDescriptor = __webpack_require__(7781);\n var toIndexedObject = __webpack_require__(6854);\n var toPropertyKey = __webpack_require__(2358);\n var hasOwn = __webpack_require__(4678);\n var IE8_DOM_DEFINE = __webpack_require__(7913);\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n // `Object.getOwnPropertyDescriptor` method\n // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\n exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) {}\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n };\n /***/ },\n /***/ 6217: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var internalObjectKeys = __webpack_require__(1528);\n var enumBugKeys = __webpack_require__(2367);\n var hiddenKeys = enumBugKeys.concat(\"length\", \"prototype\");\n // `Object.getOwnPropertyNames` method\n // https://tc39.es/ecma262/#sec-object.getownpropertynames\n // eslint-disable-next-line es/no-object-getownpropertynames -- safe\n exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n };\n /***/ },\n /***/ 5168: /***/ (__unused_webpack_module, exports)=>{\n // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\n exports.f = Object.getOwnPropertySymbols;\n /***/ },\n /***/ 6148: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n module.exports = uncurryThis({}.isPrototypeOf);\n /***/ },\n /***/ 1528: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var hasOwn = __webpack_require__(4678);\n var toIndexedObject = __webpack_require__(6854);\n var indexOf = __webpack_require__(1138).indexOf;\n var hiddenKeys = __webpack_require__(7390);\n var push = uncurryThis([].push);\n module.exports = function(object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for(key in O)!hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while(names.length > i)if (hasOwn(O, key = names[i++])) ~indexOf(result, key) || push(result, key);\n return result;\n };\n /***/ },\n /***/ 1728: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var internalObjectKeys = __webpack_require__(1528);\n var enumBugKeys = __webpack_require__(2367);\n // `Object.keys` method\n // https://tc39.es/ecma262/#sec-object.keys\n // eslint-disable-next-line es/no-object-keys -- safe\n module.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n };\n /***/ },\n /***/ 8208: /***/ (__unused_webpack_module, exports)=>{\n var $propertyIsEnumerable = {}.propertyIsEnumerable;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n // Nashorn ~ JDK8 bug\n var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({\n 1: 2\n }, 1);\n // `Object.prototype.propertyIsEnumerable` method implementation\n // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\n exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n } : $propertyIsEnumerable;\n /***/ },\n /***/ 110: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var call = __webpack_require__(8724);\n var isCallable = __webpack_require__(688);\n var isObject = __webpack_require__(5309);\n var $TypeError = TypeError;\n // `OrdinaryToPrimitive` abstract operation\n // https://tc39.es/ecma262/#sec-ordinarytoprimitive\n module.exports = function(input, pref) {\n var fn, val;\n if (pref === \"string\" && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== \"string\" && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw new $TypeError(\"Can't convert object to primitive value\");\n };\n /***/ },\n /***/ 990: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var getBuiltIn = __webpack_require__(2160);\n var uncurryThis = __webpack_require__(9668);\n var getOwnPropertyNamesModule = __webpack_require__(6217);\n var getOwnPropertySymbolsModule = __webpack_require__(5168);\n var anObject = __webpack_require__(9175);\n var concat = uncurryThis([].concat);\n // all object keys, includes non-enumerable and symbols\n module.exports = getBuiltIn(\"Reflect\", \"ownKeys\") || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n };\n /***/ },\n /***/ 8588: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n module.exports = global;\n /***/ },\n /***/ 1166: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isNullOrUndefined = __webpack_require__(5268);\n var $TypeError = TypeError;\n // `RequireObjectCoercible` abstract operation\n // https://tc39.es/ecma262/#sec-requireobjectcoercible\n module.exports = function(it) {\n if (isNullOrUndefined(it)) throw new $TypeError(\"Can't call method on \" + it);\n return it;\n };\n /***/ },\n /***/ 1962: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var shared = __webpack_require__(2645);\n var uid = __webpack_require__(5736);\n var keys = shared(\"keys\");\n module.exports = function(key) {\n return keys[key] || (keys[key] = uid(key));\n };\n /***/ },\n /***/ 6762: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var defineGlobalProperty = __webpack_require__(1604);\n var SHARED = \"__core-js_shared__\";\n var store = global[SHARED] || defineGlobalProperty(SHARED, {});\n module.exports = store;\n /***/ },\n /***/ 2645: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var IS_PURE = __webpack_require__(6555);\n var store = __webpack_require__(6762);\n (module.exports = function(key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n })(\"versions\", []).push({\n version: \"3.35.1\",\n mode: IS_PURE ? \"pure\" : \"global\",\n copyright: \"\\xa9 2014-2024 Denis Pushkarev (zloirock.ru)\",\n license: \"https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE\",\n source: \"https://github.com/zloirock/core-js\"\n });\n /***/ },\n /***/ 4112: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n /* eslint-disable es/no-symbol -- required for testing */ var V8_VERSION = __webpack_require__(7067);\n var fails = __webpack_require__(4694);\n var global = __webpack_require__(2150);\n var $String = global.String;\n // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\n module.exports = !!Object.getOwnPropertySymbols && !fails(function() {\n var symbol = Symbol(\"symbol detection\");\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n });\n /***/ },\n /***/ 7352: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIntegerOrInfinity = __webpack_require__(1680);\n var max = Math.max;\n var min = Math.min;\n // Helper for a popular repeating case of the spec:\n // Let integer be ? ToInteger(index).\n // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\n module.exports = function(index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n };\n /***/ },\n /***/ 6854: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n // toObject with fallback for non-array-like ES3 strings\n var IndexedObject = __webpack_require__(4347);\n var requireObjectCoercible = __webpack_require__(1166);\n module.exports = function(it) {\n return IndexedObject(requireObjectCoercible(it));\n };\n /***/ },\n /***/ 1680: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var trunc = __webpack_require__(1787);\n // `ToIntegerOrInfinity` abstract operation\n // https://tc39.es/ecma262/#sec-tointegerorinfinity\n module.exports = function(argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n };\n /***/ },\n /***/ 7331: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIntegerOrInfinity = __webpack_require__(1680);\n var min = Math.min;\n // `ToLength` abstract operation\n // https://tc39.es/ecma262/#sec-tolength\n module.exports = function(argument) {\n var len = toIntegerOrInfinity(argument);\n return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n };\n /***/ },\n /***/ 298: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var requireObjectCoercible = __webpack_require__(1166);\n var $Object = Object;\n // `ToObject` abstract operation\n // https://tc39.es/ecma262/#sec-toobject\n module.exports = function(argument) {\n return $Object(requireObjectCoercible(argument));\n };\n /***/ },\n /***/ 1272: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var call = __webpack_require__(8724);\n var isObject = __webpack_require__(5309);\n var isSymbol = __webpack_require__(7935);\n var getMethod = __webpack_require__(5383);\n var ordinaryToPrimitive = __webpack_require__(110);\n var wellKnownSymbol = __webpack_require__(2032);\n var $TypeError = TypeError;\n var TO_PRIMITIVE = wellKnownSymbol(\"toPrimitive\");\n // `ToPrimitive` abstract operation\n // https://tc39.es/ecma262/#sec-toprimitive\n module.exports = function(input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = \"default\";\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw new $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = \"number\";\n return ordinaryToPrimitive(input, pref);\n };\n /***/ },\n /***/ 2358: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toPrimitive = __webpack_require__(1272);\n var isSymbol = __webpack_require__(7935);\n // `ToPropertyKey` abstract operation\n // https://tc39.es/ecma262/#sec-topropertykey\n module.exports = function(argument) {\n var key = toPrimitive(argument, \"string\");\n return isSymbol(key) ? key : key + \"\";\n };\n /***/ },\n /***/ 2522: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var wellKnownSymbol = __webpack_require__(2032);\n var TO_STRING_TAG = wellKnownSymbol(\"toStringTag\");\n var test = {};\n test[TO_STRING_TAG] = \"z\";\n module.exports = String(test) === \"[object z]\";\n /***/ },\n /***/ 599: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var classof = __webpack_require__(1566);\n var $String = String;\n module.exports = function(argument) {\n if (classof(argument) === \"Symbol\") throw new TypeError(\"Cannot convert a Symbol value to a string\");\n return $String(argument);\n };\n /***/ },\n /***/ 3397: /***/ (module)=>{\n var $String = String;\n module.exports = function(argument) {\n try {\n return $String(argument);\n } catch (error) {\n return \"Object\";\n }\n };\n /***/ },\n /***/ 5736: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var id = 0;\n var postfix = Math.random();\n var toString = uncurryThis(1.0.toString);\n module.exports = function(key) {\n return \"Symbol(\" + (key === undefined ? \"\" : key) + \")_\" + toString(++id + postfix, 36);\n };\n /***/ },\n /***/ 4866: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n /* eslint-disable es/no-symbol -- required for testing */ var NATIVE_SYMBOL = __webpack_require__(4112);\n module.exports = NATIVE_SYMBOL && !Symbol.sham && typeof Symbol.iterator == \"symbol\";\n /***/ },\n /***/ 2666: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var fails = __webpack_require__(4694);\n // V8 ~ Chrome 36-\n // https://bugs.chromium.org/p/v8/issues/detail?id=3334\n module.exports = DESCRIPTORS && fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function() {}, \"prototype\", {\n value: 42,\n writable: false\n }).prototype !== 42;\n });\n /***/ },\n /***/ 4724: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var isCallable = __webpack_require__(688);\n var WeakMap1 = global.WeakMap;\n module.exports = isCallable(WeakMap1) && /native code/.test(String(WeakMap1));\n /***/ },\n /***/ 2032: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var shared = __webpack_require__(2645);\n var hasOwn = __webpack_require__(4678);\n var uid = __webpack_require__(5736);\n var NATIVE_SYMBOL = __webpack_require__(4112);\n var USE_SYMBOL_AS_UID = __webpack_require__(4866);\n var Symbol1 = global.Symbol;\n var WellKnownSymbolsStore = shared(\"wks\");\n var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol1[\"for\"] || Symbol1 : Symbol1 && Symbol1.withoutSetter || uid;\n module.exports = function(name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol1, name) ? Symbol1[name] : createWellKnownSymbol(\"Symbol.\" + name);\n return WellKnownSymbolsStore[name];\n };\n /***/ },\n /***/ 7206: /***/ (__unused_webpack_module, __unused_webpack_exports, __webpack_require__)=>{\n var $ = __webpack_require__(5532);\n var uncurryThis = __webpack_require__(9668);\n var aCallable = __webpack_require__(1052);\n var toObject = __webpack_require__(298);\n var lengthOfArrayLike = __webpack_require__(8344);\n var deletePropertyOrThrow = __webpack_require__(955);\n var toString = __webpack_require__(599);\n var fails = __webpack_require__(4694);\n var internalSort = __webpack_require__(3097);\n var arrayMethodIsStrict = __webpack_require__(567);\n var FF = __webpack_require__(9016);\n var IE_OR_EDGE = __webpack_require__(821);\n var V8 = __webpack_require__(7067);\n var WEBKIT = __webpack_require__(4389);\n var test = [];\n var nativeSort = uncurryThis(test.sort);\n var push = uncurryThis(test.push);\n // IE8-\n var FAILS_ON_UNDEFINED = fails(function() {\n test.sort(undefined);\n });\n // V8 bug\n var FAILS_ON_NULL = fails(function() {\n test.sort(null);\n });\n // Old WebKit\n var STRICT_METHOD = arrayMethodIsStrict(\"sort\");\n var STABLE_SORT = !fails(function() {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n var result = \"\";\n var code, chr, value, index;\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for(code = 65; code < 76; code++){\n chr = String.fromCharCode(code);\n switch(code){\n case 66:\n case 69:\n case 70:\n case 72:\n value = 3;\n break;\n case 68:\n case 71:\n value = 4;\n break;\n default:\n value = 2;\n }\n for(index = 0; index < 47; index++)test.push({\n k: chr + index,\n v: value\n });\n }\n test.sort(function(a, b) {\n return b.v - a.v;\n });\n for(index = 0; index < test.length; index++){\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n return result !== \"DGBEFHACIJK\";\n });\n var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n var getSortCompare = function(comparefn) {\n return function(x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n };\n // `Array.prototype.sort` method\n // https://tc39.es/ecma262/#sec-array.prototype.sort\n $({\n target: \"Array\",\n proto: true,\n forced: FORCED\n }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n var array = toObject(this);\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n for(index = 0; index < arrayLength; index++)if (index in array) push(items, array[index]);\n internalSort(items, getSortCompare(comparefn));\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n while(index < itemsLength)array[index] = items[index++];\n while(index < arrayLength)deletePropertyOrThrow(array, index++);\n return array;\n }\n });\n /***/ },\n /***/ 9867: /***/ (__unused_webpack_module, __unused_webpack_exports, __webpack_require__)=>{\n var $ = __webpack_require__(5532);\n var toObject = __webpack_require__(298);\n var nativeKeys = __webpack_require__(1728);\n var fails = __webpack_require__(4694);\n var FAILS_ON_PRIMITIVES = fails(function() {\n nativeKeys(1);\n });\n // `Object.keys` method\n // https://tc39.es/ecma262/#sec-object.keys\n $({\n target: \"Object\",\n stat: true,\n forced: FAILS_ON_PRIMITIVES\n }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n });\n /***/ }\n};\n/************************************************************************/ /******/ // The module cache\n/******/ var $2c23f148d58cd887$var$__webpack_module_cache__ = {};\n/******/ /******/ // The require function\n/******/ function $2c23f148d58cd887$var$__webpack_require__(moduleId) {\n /******/ // Check if module is in cache\n /******/ var cachedModule = $2c23f148d58cd887$var$__webpack_module_cache__[moduleId];\n /******/ if (cachedModule !== undefined) /******/ return cachedModule.exports;\n /******/ // Create a new module (and put it into the cache)\n /******/ var module = $2c23f148d58cd887$var$__webpack_module_cache__[moduleId] = {\n /******/ id: moduleId,\n /******/ // no module.loaded needed\n /******/ exports: {}\n };\n /******/ /******/ // Execute the module function\n /******/ $2c23f148d58cd887$var$__webpack_modules__[moduleId].call(module.exports, module, module.exports, $2c23f148d58cd887$var$__webpack_require__);\n /******/ /******/ // Return the exports of the module\n /******/ return module.exports;\n/******/ }\n/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (()=>{\n /******/ // getDefaultExport function for compatibility with non-harmony modules\n /******/ $2c23f148d58cd887$var$__webpack_require__.n = (module)=>{\n /******/ var getter = module && module.__esModule ? /******/ ()=>module[\"default\"] : /******/ ()=>module;\n /******/ $2c23f148d58cd887$var$__webpack_require__.d(getter, {\n a: getter\n });\n /******/ return getter;\n /******/ };\n/******/ })();\n/******/ /******/ /* webpack/runtime/define property getters */ /******/ (()=>{\n /******/ // define getter functions for harmony exports\n /******/ $2c23f148d58cd887$var$__webpack_require__.d = (exports, definition)=>{\n /******/ for(var key in definition)/******/ if ($2c23f148d58cd887$var$__webpack_require__.o(definition, key) && !$2c23f148d58cd887$var$__webpack_require__.o(exports, key)) /******/ Object.defineProperty(exports, key, {\n enumerable: true,\n get: definition[key]\n });\n /******/ };\n/******/ })();\n/******/ /******/ /* webpack/runtime/global */ /******/ (()=>{\n /******/ $2c23f148d58cd887$var$__webpack_require__.g = function() {\n /******/ if (typeof globalThis === \"object\") return globalThis;\n /******/ try {\n /******/ return this || new Function(\"return this\")();\n /******/ } catch (e) {\n /******/ if (typeof window === \"object\") return window;\n /******/ }\n /******/ }();\n/******/ })();\n/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (()=>{\n /******/ $2c23f148d58cd887$var$__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);\n/******/ })();\n/******/ /******/ /* webpack/runtime/make namespace object */ /******/ (()=>{\n /******/ // define __esModule on exports\n /******/ $2c23f148d58cd887$var$__webpack_require__.r = (exports)=>{\n /******/ if (typeof Symbol !== \"undefined\" && Symbol.toStringTag) /******/ Object.defineProperty(exports, Symbol.toStringTag, {\n value: \"Module\"\n });\n /******/ Object.defineProperty(exports, \"__esModule\", {\n value: true\n });\n /******/ };\n/******/ })();\n/******/ /************************************************************************/ var $2c23f148d58cd887$var$__webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(()=>{\n // EXPORTS\n $2c23f148d58cd887$var$__webpack_require__.d($2c23f148d58cd887$var$__webpack_exports__, {\n y1j: ()=>/* reexport */ ActionCompleteEvent,\n fWn: ()=>/* reexport */ ActionContext,\n Ia8: ()=>/* reexport */ ActionQueue,\n rqv: ()=>/* reexport */ ActionSequence,\n zH6: ()=>/* reexport */ ActionStartEvent,\n hLI: ()=>/* reexport */ ActionsComponent,\n yyv: ()=>/* reexport */ ActionsSystem,\n tX5: ()=>/* reexport */ ActivateEvent,\n vtX: ()=>/* reexport */ Actor,\n r7K: ()=>/* reexport */ AddedComponent,\n cE4: ()=>/* reexport */ AffineMatrix,\n fwF: ()=>/* reexport */ Animation,\n sce: ()=>/* reexport */ AnimationDirection,\n AQ6: ()=>/* reexport */ AnimationEvents,\n _c7: ()=>/* reexport */ AnimationStrategy,\n KUs: ()=>/* reexport */ ArcadeSolver,\n Ajp: ()=>/* reexport */ AudioContextFactory,\n dkO: ()=>/* reexport */ Axes,\n RDh: ()=>/* reexport */ Axis,\n _H9: ()=>/* reexport */ BaseAlign,\n mxs: ()=>/* reexport */ Blink,\n OmD: ()=>/* reexport */ BodyComponent,\n kBf: ()=>/* reexport */ BoundingBox,\n C4F: ()=>/* reexport */ BroadphaseStrategy,\n NQt: ()=>/* reexport */ BrowserComponent,\n JjN: ()=>/* reexport */ BrowserEvents,\n EK_: ()=>/* reexport */ Buttons,\n V1s: ()=>/* reexport */ Camera,\n xHm: ()=>/* reexport */ CameraEvents,\n Xz7: ()=>/* reexport */ Canvas,\n Cdc: ()=>/* reexport */ Circle,\n FKn: ()=>/* reexport */ CircleCollider,\n SUY: ()=>/* reexport */ Clock,\n ab2: ()=>/* reexport */ ClosestLine,\n GfZ: ()=>/* reexport */ ClosestLineJumpTable,\n YMS: ()=>/* reexport */ Collider,\n oyv: ()=>/* reexport */ ColliderComponent,\n aUb: ()=>/* reexport */ CollisionContact,\n SdD: ()=>/* reexport */ CollisionEndEvent,\n JUv: ()=>/* reexport */ CollisionGroup,\n jEj: ()=>/* reexport */ CollisionGroupManager,\n TFq: ()=>/* reexport */ CollisionJumpTable,\n HDU: ()=>/* reexport */ CollisionPostSolveEvent,\n R_y: ()=>/* reexport */ CollisionPreSolveEvent,\n t50: ()=>/* reexport */ CollisionStartEvent,\n s$$: ()=>/* reexport */ CollisionSystem,\n v2G: ()=>/* reexport */ CollisionType,\n Ilk: ()=>/* reexport */ Color,\n s9i: ()=>/* reexport */ ColorBlindFlags,\n dxL: ()=>/* reexport */ ColorBlindnessMode,\n LLX: ()=>/* reexport */ ColorBlindnessPostProcessor,\n wA2: ()=>/* reexport */ Component,\n R_p: ()=>/* reexport */ CompositeCollider,\n IQ$: ()=>/* reexport */ Configurable,\n I5F: ()=>/* reexport */ ConsoleAppender,\n X8$: ()=>/* reexport */ ContactConstraintPoint,\n FR6: ()=>/* reexport */ ContactEndEvent,\n pTZ: ()=>/* reexport */ ContactSolveBias,\n U8o: ()=>/* reexport */ ContactStartEvent,\n kbG: ()=>/* reexport */ CoordPlane,\n FEv: ()=>/* reexport */ CrossFade,\n iS_: ()=>/* reexport */ DeactivateEvent,\n cGG: ()=>/* reexport */ Debug,\n ETM: ()=>/* reexport */ DebugConfig,\n RPN: ()=>/* reexport */ DebugGraphicsComponent,\n skb: ()=>/* reexport */ DebugSystem,\n SLU: ()=>/* reexport */ DebugText,\n Q3w: ()=>/* reexport */ DefaultAntialiasOptions,\n xK2: ()=>/* reexport */ DefaultLoader,\n vrO: ()=>/* reexport */ DefaultPhysicsConfig,\n EA2: ()=>/* reexport */ DefaultPixelArtOptions,\n RdJ: ()=>/* reexport */ DegreeOfFreedom,\n cNu: ()=>/* reexport */ Delay,\n wtG: ()=>/* reexport */ DeprecatedStaticToConfig,\n gU7: ()=>/* reexport */ Detector,\n LSk: ()=>/* reexport */ Die,\n Nmp: ()=>/* reexport */ Direction,\n twX: ()=>/* reexport */ Director,\n UND: ()=>/* reexport */ DirectorEvents,\n d1Y: ()=>/* reexport */ DisplayMode,\n xrL: ()=>/* reexport */ DynamicTree,\n sRW: ()=>/* reexport */ DynamicTreeCollisionProcessor,\n cmV: ()=>/* binding */ EX_VERSION,\n qWz: ()=>/* reexport */ EaseBy,\n N0Q: ()=>/* reexport */ EaseTo,\n q8b: ()=>/* reexport */ EasingFunctions,\n ynB: ()=>/* reexport */ EdgeCollider,\n jT9: ()=>/* reexport */ ElasticToActorStrategy,\n wAz: ()=>/* reexport */ EmitterType,\n D4V: ()=>/* reexport */ Engine,\n NLr: ()=>/* reexport */ EngineEvents,\n N6H: ()=>/* reexport */ EnterTriggerEvent,\n W1A: ()=>/* reexport */ EnterViewPortEvent,\n JHW: ()=>/* reexport */ Entity,\n ZZ$: ()=>/* reexport */ EntityEvents,\n v2K: ()=>/* reexport */ EntityManager,\n pBf: ()=>/* reexport */ EventDispatcher,\n vpe: ()=>/* reexport */ EventEmitter,\n GMl: ()=>/* reexport */ EventTypes,\n zW2: ()=>/* reexport */ Events_namespaceObject,\n B0K: ()=>/* reexport */ ExResponse,\n Nv7: ()=>/* reexport */ ExcaliburGraphicsContext2DCanvas,\n C_p: ()=>/* reexport */ ExcaliburGraphicsContextWebGL,\n MUA: ()=>/* reexport */ ExitTriggerEvent,\n xqU: ()=>/* reexport */ ExitViewPortEvent,\n pTp: ()=>/* reexport */ Fade,\n trb: ()=>/* reexport */ FadeInOut,\n vUK: ()=>/* reexport */ Flags,\n j9l: ()=>/* reexport */ Follow,\n Zxw: ()=>/* reexport */ Font,\n v51: ()=>/* reexport */ FontCache,\n gYv: ()=>/* reexport */ FontSource,\n Hdx: ()=>/* reexport */ FontStyle,\n Z$d: ()=>/* reexport */ FontUnit,\n iqV: ()=>/* reexport */ FpsSampler,\n o$7: ()=>/* reexport */ FrameStats,\n olM: ()=>/* reexport */ Future,\n Zm$: ()=>/* reexport */ GameEvent,\n $QH: ()=>/* reexport */ GameStartEvent,\n i78: ()=>/* reexport */ GameStopEvent,\n nJg: ()=>/* reexport */ Gamepad,\n h6u: ()=>/* reexport */ GamepadAxisEvent,\n hts: ()=>/* reexport */ GamepadButtonEvent,\n j88: ()=>/* reexport */ GamepadConnectEvent,\n VME: ()=>/* reexport */ GamepadDisconnectEvent,\n fy2: ()=>/* reexport */ Gamepads,\n nt: ()=>/* reexport */ Gif,\n Ukr: ()=>/* reexport */ GlobalCoordinates,\n zsu: ()=>/* reexport */ Graphic,\n oA6: ()=>/* reexport */ GraphicsComponent,\n TVh: ()=>/* reexport */ GraphicsGroup,\n xxj: ()=>/* reexport */ GraphicsSystem,\n XdK: ()=>/* reexport */ HiddenEvent,\n fBD: ()=>/* reexport */ HorizontalFirst,\n Jmb: ()=>/* reexport */ ImageFiltering,\n cXo: ()=>/* reexport */ ImageSource,\n Dm5: ()=>/* reexport */ InitializeEvent,\n IIB: ()=>/* reexport */ Input_Index_namespaceObject,\n IX$: ()=>/* reexport */ InputHost,\n ebW: ()=>/* reexport */ InputMapper,\n zI0: ()=>/* reexport */ Integrator,\n LYD: ()=>/* reexport */ IsometricEntityComponent,\n cEG: ()=>/* reexport */ IsometricEntitySystem,\n SEl: ()=>/* reexport */ IsometricMap,\n t9V: ()=>/* reexport */ IsometricTile,\n ez5: ()=>/* reexport */ KeyEvent,\n N1d: ()=>/* reexport */ Keyboard,\n R8U: ()=>/* reexport */ Keys,\n SKZ: ()=>/* reexport */ KillEvent,\n __J: ()=>/* reexport */ Label,\n RI$: ()=>/* reexport */ LimitCameraBoundsStrategy,\n x12: ()=>/* reexport */ Line,\n ccz: ()=>/* reexport */ LineSegment,\n aNw: ()=>/* reexport */ Loader,\n XrL: ()=>/* reexport */ LoaderEvents,\n xwn: ()=>/* reexport */ LockCameraToActorAxisStrategy,\n dNK: ()=>/* reexport */ LockCameraToActorStrategy,\n ini: ()=>/* reexport */ LogLevel,\n YdH: ()=>/* reexport */ Logger,\n F5T: ()=>/* reexport */ Material,\n y3G: ()=>/* reexport */ Matrix,\n l57: ()=>/* reexport */ MatrixLocations,\n xn0: ()=>/* reexport */ MediaEvent,\n t2V: ()=>/* reexport */ Meet,\n uxB: ()=>/* reexport */ MotionComponent,\n cpd: ()=>/* reexport */ MotionSystem,\n fiy: ()=>/* reexport */ MoveBy,\n $XZ: ()=>/* reexport */ MoveTo,\n UG6: ()=>/* reexport */ NativePointerButton,\n uqK: ()=>/* reexport */ NativeSoundEvent,\n STE: ()=>/* reexport */ NativeSoundProcessedEvent,\n Hq9: ()=>/* reexport */ None,\n y$z: ()=>/* reexport */ Observable,\n mAD: ()=>/* reexport */ OffscreenSystem,\n sOq: ()=>/* reexport */ Pair,\n hUw: ()=>/* reexport */ ParallaxComponent,\n _0G: ()=>/* reexport */ ParallelActions,\n Sqs: ()=>/* reexport */ ParseGif,\n hpZ: ()=>/* reexport */ Particle,\n Vol: ()=>/* reexport */ ParticleEmitter,\n vYX: ()=>/* reexport */ ParticleTransform,\n wIZ: ()=>/* reexport */ Physics,\n cBi: ()=>/* reexport */ PhysicsStats,\n c30: ()=>/* reexport */ PhysicsWorld,\n PGK: ()=>/* reexport */ PointerAbstraction,\n MPV: ()=>/* reexport */ PointerButton,\n RFv: ()=>/* reexport */ PointerComponent,\n Ux6: ()=>/* reexport */ PointerEvent,\n rxy: ()=>/* reexport */ PointerEventReceiver,\n I$c: ()=>/* reexport */ PointerScope,\n kfC: ()=>/* reexport */ PointerSystem,\n VjY: ()=>/* reexport */ PointerType,\n mgq: ()=>/* reexport */ Polygon,\n YVA: ()=>/* reexport */ PolygonCollider,\n Kgp: ()=>/* reexport */ Pool,\n HH$: ()=>/* reexport */ PostCollisionEvent,\n M_d: ()=>/* reexport */ PostDebugDrawEvent,\n rgh: ()=>/* reexport */ PostDrawEvent,\n Ra6: ()=>/* reexport */ PostFrameEvent,\n KhR: ()=>/* reexport */ PostKillEvent,\n gvQ: ()=>/* reexport */ PostTransformDrawEvent,\n BS5: ()=>/* reexport */ PostUpdateEvent,\n xhz: ()=>/* reexport */ PreCollisionEvent,\n xOq: ()=>/* reexport */ PreDebugDrawEvent,\n a9j: ()=>/* reexport */ PreDrawEvent,\n bHk: ()=>/* reexport */ PreFrameEvent,\n CgK: ()=>/* reexport */ PreKillEvent,\n A0M: ()=>/* reexport */ PreLoadEvent,\n cEd: ()=>/* reexport */ PreTransformDrawEvent,\n cuY: ()=>/* reexport */ PreUpdateEvent,\n kvE: ()=>/* reexport */ Projection,\n SBu: ()=>/* reexport */ QuadIndexBuffer,\n PsT: ()=>/* reexport */ QuadTree,\n AE_: ()=>/* reexport */ Query,\n ctO: ()=>/* reexport */ QueryManager,\n OLH: ()=>/* reexport */ RadiusAroundActorStrategy,\n kky: ()=>/* reexport */ Random,\n nSF: ()=>/* reexport */ Raster,\n zHn: ()=>/* reexport */ Ray,\n zwx: ()=>/* reexport */ RealisticSolver,\n AeJ: ()=>/* reexport */ Rectangle,\n hLz: ()=>/* reexport */ RemovedComponent,\n wA: ()=>/* reexport */ Repeat,\n jhr: ()=>/* reexport */ RepeatForever,\n GVs: ()=>/* reexport */ Resolution,\n _zO: ()=>/* reexport */ Resource,\n LXZ: ()=>/* reexport */ ResourceEvents,\n w6$: ()=>/* reexport */ RotateBy,\n mhV: ()=>/* reexport */ RotateTo,\n MOD: ()=>/* reexport */ RotationType,\n kwd: ()=>/* reexport */ ScaleBy,\n Lmr: ()=>/* reexport */ ScaleTo,\n xsS: ()=>/* reexport */ Scene,\n K5l: ()=>/* reexport */ SceneEvents,\n lLr: ()=>/* reexport */ Screen,\n Z$r: ()=>/* reexport */ ScreenAppender,\n IXb: ()=>/* reexport */ ScreenElement,\n Xsu: ()=>/* reexport */ ScreenEvents,\n SGH: ()=>/* reexport */ ScreenShader,\n SMj: ()=>/* reexport */ ScrollPreventionMode,\n L34: ()=>/* reexport */ Semaphore,\n exe: ()=>/* reexport */ Shader,\n bnF: ()=>/* reexport */ Shape,\n MFA: ()=>/* reexport */ Side,\n kPj: ()=>/* reexport */ SolverStrategy,\n $uU: ()=>/* reexport */ Sound,\n Sap: ()=>/* reexport */ SoundEvents,\n jyi: ()=>/* reexport */ Sprite,\n E03: ()=>/* reexport */ SpriteFont,\n V6q: ()=>/* reexport */ SpriteSheet,\n rg2: ()=>/* reexport */ StandardClock,\n DVW: ()=>/* reexport */ StateMachine,\n nVo: ()=>/* reexport */ StrategyContainer,\n F6N: ()=>/* reexport */ Stream,\n xP7: ()=>/* reexport */ System,\n Odq: ()=>/* reexport */ SystemManager,\n uY9: ()=>/* reexport */ SystemPriority,\n Zif: ()=>/* reexport */ SystemType,\n c_d: ()=>/* reexport */ TagQuery,\n MJk: ()=>/* reexport */ TestClock,\n xvT: ()=>/* reexport */ Text,\n PHM: ()=>/* reexport */ TextAlign,\n dpR: ()=>/* reexport */ TextureLoader,\n n9L: ()=>/* reexport */ Tile,\n KwO: ()=>/* reexport */ TileMap,\n SxM: ()=>/* reexport */ TileMapEvents,\n B7y: ()=>/* reexport */ Timer,\n x7r: ()=>/* reexport */ Toaster,\n wx7: ()=>/* reexport */ transform_Transform,\n Uvn: ()=>/* reexport */ TransformComponent,\n uTP: ()=>/* reexport */ Transition,\n OFT: ()=>/* reexport */ TreeNode,\n xzN: ()=>/* reexport */ Trigger,\n CcZ: ()=>/* reexport */ TriggerEvents,\n M5Z: ()=>/* reexport */ TwoPI,\n ZrN: ()=>/* reexport */ Util_Index_namespaceObject,\n OWs: ()=>/* reexport */ Vector,\n dF9: ()=>/* reexport */ VectorView,\n oZy: ()=>/* reexport */ VertexBuffer,\n rD2: ()=>/* reexport */ VertexLayout,\n KmN: ()=>/* reexport */ VerticalFirst,\n VHo: ()=>/* reexport */ VisibleEvent,\n ohE: ()=>/* reexport */ WebAudio,\n R$E: ()=>/* reexport */ WebAudioInstance,\n xQN: ()=>/* reexport */ WheelDeltaMode,\n AdJ: ()=>/* reexport */ WheelEvent,\n q3I: ()=>/* reexport */ World,\n Pab: ()=>/* reexport */ canonicalizeAngle,\n uZ5: ()=>/* reexport */ clamp,\n TAE: ()=>/* reexport */ coroutine,\n McK: ()=>/* reexport */ createId,\n F9c: ()=>/* reexport */ frac,\n k0b: ()=>/* reexport */ hasGraphicsTick,\n hnT: ()=>/* reexport */ hasOnInitialize,\n RSJ: ()=>/* reexport */ hasOnPostUpdate,\n Mku: ()=>/* reexport */ hasOnPreUpdate,\n h90: ()=>/* reexport */ hasPostDraw,\n rms: ()=>/* reexport */ hasPreDraw,\n ErP: ()=>/* reexport */ has_initialize,\n aVg: ()=>/* reexport */ has_postupdate,\n lPc: ()=>/* reexport */ has_preupdate,\n Z8E: ()=>/* reexport */ isAddedComponent,\n k15: ()=>/* reexport */ isComponentCtor,\n YsU: ()=>/* reexport */ isLoaderConstructor,\n lNv: ()=>/* reexport */ isRemovedComponent,\n Xyg: ()=>/* reexport */ isSceneConstructor,\n cu9: ()=>/* reexport */ isScreenElement,\n p88: ()=>/* reexport */ isSystemConstructor,\n MZQ: ()=>/* reexport */ maxMessages,\n FUM: ()=>/* reexport */ obsolete,\n BxR: ()=>/* reexport */ pixelSnapEpsilon,\n vdf: ()=>/* reexport */ randomInRange,\n iaL: ()=>/* reexport */ randomIntInRange,\n w6H: ()=>/* reexport */ range,\n Q4c: ()=>/* reexport */ resetObsoleteCounter,\n Xxe: ()=>/* reexport */ sign,\n Uxb: ()=>/* reexport */ toDegrees,\n Yr5: ()=>/* reexport */ toRadians,\n Bhw: ()=>/* reexport */ vec,\n yOA: ()=>/* reexport */ webgl_util_namespaceObject\n });\n // NAMESPACE OBJECT: ./Graphics/Context/webgl-util.ts\n var webgl_util_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(webgl_util_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(webgl_util_namespaceObject, {\n getAttributeComponentSize: ()=>getAttributeComponentSize,\n getAttributePointerType: ()=>getAttributePointerType,\n getGlTypeSizeBytes: ()=>getGlTypeSizeBytes\n });\n // NAMESPACE OBJECT: ./Events.ts\n var Events_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Events_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Events_namespaceObject, {\n ActionCompleteEvent: ()=>ActionCompleteEvent,\n ActionStartEvent: ()=>ActionStartEvent,\n ActivateEvent: ()=>ActivateEvent,\n CollisionEndEvent: ()=>CollisionEndEvent,\n CollisionPostSolveEvent: ()=>CollisionPostSolveEvent,\n CollisionPreSolveEvent: ()=>CollisionPreSolveEvent,\n CollisionStartEvent: ()=>CollisionStartEvent,\n ContactEndEvent: ()=>ContactEndEvent,\n ContactStartEvent: ()=>ContactStartEvent,\n DeactivateEvent: ()=>DeactivateEvent,\n EnterTriggerEvent: ()=>EnterTriggerEvent,\n EnterViewPortEvent: ()=>EnterViewPortEvent,\n EventTypes: ()=>EventTypes,\n ExitTriggerEvent: ()=>ExitTriggerEvent,\n ExitViewPortEvent: ()=>ExitViewPortEvent,\n GameEvent: ()=>GameEvent,\n GameStartEvent: ()=>GameStartEvent,\n GameStopEvent: ()=>GameStopEvent,\n GamepadAxisEvent: ()=>GamepadAxisEvent,\n GamepadButtonEvent: ()=>GamepadButtonEvent,\n GamepadConnectEvent: ()=>GamepadConnectEvent,\n GamepadDisconnectEvent: ()=>GamepadDisconnectEvent,\n HiddenEvent: ()=>HiddenEvent,\n InitializeEvent: ()=>InitializeEvent,\n KillEvent: ()=>KillEvent,\n PostCollisionEvent: ()=>PostCollisionEvent,\n PostDebugDrawEvent: ()=>PostDebugDrawEvent,\n PostDrawEvent: ()=>PostDrawEvent,\n PostFrameEvent: ()=>PostFrameEvent,\n PostKillEvent: ()=>PostKillEvent,\n PostTransformDrawEvent: ()=>PostTransformDrawEvent,\n PostUpdateEvent: ()=>PostUpdateEvent,\n PreCollisionEvent: ()=>PreCollisionEvent,\n PreDebugDrawEvent: ()=>PreDebugDrawEvent,\n PreDrawEvent: ()=>PreDrawEvent,\n PreFrameEvent: ()=>PreFrameEvent,\n PreKillEvent: ()=>PreKillEvent,\n PreTransformDrawEvent: ()=>PreTransformDrawEvent,\n PreUpdateEvent: ()=>PreUpdateEvent,\n VisibleEvent: ()=>VisibleEvent\n });\n // NAMESPACE OBJECT: ./Util/DrawUtil.ts\n var DrawUtil_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(DrawUtil_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(DrawUtil_namespaceObject, {\n circle: ()=>circle,\n line: ()=>line,\n point: ()=>point,\n roundRect: ()=>roundRect,\n vector: ()=>vector\n });\n // NAMESPACE OBJECT: ./Input/Index.ts\n var Input_Index_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Input_Index_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Input_Index_namespaceObject, {\n Axes: ()=>Axes,\n Buttons: ()=>Buttons,\n Gamepad: ()=>Gamepad,\n Gamepads: ()=>Gamepads,\n KeyEvent: ()=>KeyEvent,\n Keyboard: ()=>Keyboard,\n Keys: ()=>Keys,\n NativePointerButton: ()=>NativePointerButton,\n PointerButton: ()=>PointerButton,\n PointerComponent: ()=>PointerComponent,\n PointerEvent: ()=>PointerEvent,\n PointerEventReceiver: ()=>PointerEventReceiver,\n PointerScope: ()=>PointerScope,\n PointerSystem: ()=>PointerSystem,\n PointerType: ()=>PointerType,\n WheelDeltaMode: ()=>WheelDeltaMode,\n WheelEvent: ()=>WheelEvent\n });\n // NAMESPACE OBJECT: ./Util/Index.ts\n var Util_Index_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Util_Index_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Util_Index_namespaceObject, {\n ConsoleAppender: ()=>ConsoleAppender,\n DrawUtil: ()=>DrawUtil_namespaceObject,\n EasingFunctions: ()=>EasingFunctions,\n LogLevel: ()=>LogLevel,\n Logger: ()=>Logger,\n Observable: ()=>Observable,\n ScreenAppender: ()=>ScreenAppender,\n addItemToArray: ()=>addItemToArray,\n contains: ()=>contains,\n delay: ()=>delay,\n fail: ()=>fail,\n getPosition: ()=>getPosition,\n omit: ()=>omit,\n removeItemFromArray: ()=>removeItemFromArray\n });\n // EXTERNAL MODULE: ../../node_modules/core-js/es/array/sort.js\n var sort = $2c23f148d58cd887$var$__webpack_require__(1324);\n // EXTERNAL MODULE: ../../node_modules/core-js/es/object/keys.js\n var keys = $2c23f148d58cd887$var$__webpack_require__(3571);\n /**\n * Polyfill adding function\n */ function polyfill() {\n /* istanbul ignore next */ if (typeof window === \"undefined\") window = {\n audioContext: function() {\n return;\n }\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.requestAnimationFrame) window.requestAnimationFrame = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {\n window.setInterval(callback, 1000 / 60);\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.cancelAnimationFrame) window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function() {\n return;\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.AudioContext) {\n if (window.webkitAudioContext) {\n const ctx = window.webkitAudioContext;\n const replaceMe = ctx.prototype.decodeAudioData;\n window.webkitAudioContext.prototype.decodeAudioData = function(arrayBuffer) {\n return new Promise((resolve, reject)=>{\n replaceMe.call(this, arrayBuffer, resolve, reject);\n });\n };\n }\n window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext || window.oAudioContext;\n }\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.devicePixelRatio) window.devicePixelRatio = window.devicePixelRatio || 1;\n }\n /**\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\n * after which they are frozen and are read-only.\n *\n * Flags are used to enable experimental or preview features in Excalibur.\n */ class Flags {\n /**\n * Force excalibur to load the Canvas 2D graphics context fallback\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\n */ static useCanvasGraphicsContext() {\n Flags.enable(\"use-canvas-context\");\n }\n /**\n * Freeze all flag modifications making them readonly\n */ static freeze() {\n Flags._FROZEN = true;\n }\n /**\n * Resets internal flag state, not meant to be called by users. Only used for testing.\n *\n * Calling this in your game is UNSUPPORTED\n * @internal\n */ static _reset() {\n Flags._FROZEN = false;\n Flags._FLAGS = {};\n }\n /**\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\n * @param flagName\n */ static enable(flagName) {\n if (this._FROZEN) throw Error(\"Feature flags can only be enabled before Engine constructor time\");\n Flags._FLAGS[flagName] = true;\n }\n /**\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\n * @param flagName\n */ static disable(flagName) {\n if (this._FROZEN) throw Error(\"Feature flags can only be disabled before Engine constructor time\");\n Flags._FLAGS[flagName] = false;\n }\n /**\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\n * @param flagName\n */ static isEnabled(flagName) {\n return !!Flags._FLAGS[flagName];\n }\n /**\n * Show a list of currently known flags\n */ static show() {\n return Object.keys(Flags._FLAGS);\n }\n }\n Flags._FROZEN = false;\n Flags._FLAGS = {};\n /**\n * Create a branded ID type from a number\n */ function createId(type, value) {\n return {\n type: type,\n value: value\n };\n }\n /**\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\n */ class Future {\n constructor(){\n this._isCompleted = false;\n this.promise = new Promise((resolve, reject)=>{\n this._resolver = resolve;\n this._rejecter = reject;\n });\n }\n get isCompleted() {\n return this._isCompleted;\n }\n resolve(value) {\n if (this._isCompleted) return;\n this._isCompleted = true;\n this._resolver(value);\n }\n reject(error) {\n if (this._isCompleted) return;\n this._isCompleted = true;\n this._rejecter(error);\n }\n }\n /**\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\n */ class EventEmitter {\n constructor(){\n this._paused = false;\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes = [];\n }\n clear() {\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes.length = 0;\n }\n on(eventName, handler) {\n var _a;\n this._listeners[eventName] = (_a = this._listeners[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listeners[eventName].push(handler);\n return {\n close: ()=>this.off(eventName, handler)\n };\n }\n once(eventName, handler) {\n var _a;\n this._listenersOnce[eventName] = (_a = this._listenersOnce[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listenersOnce[eventName].push(handler);\n return {\n close: ()=>this.off(eventName, handler)\n };\n }\n off(eventName, handler) {\n var _a, _b;\n if (handler) {\n const newListeners = (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.filter((h)=>h !== handler);\n this._listeners[eventName] = newListeners;\n const newOnceListeners = (_b = this._listenersOnce[eventName]) === null || _b === void 0 ? void 0 : _b.filter((h)=>h !== handler);\n this._listenersOnce[eventName] = newOnceListeners;\n } else delete this._listeners[eventName];\n }\n emit(eventName, event) {\n var _a;\n if (this._paused) return;\n (_a = this._listeners[eventName]) === null || _a === void 0 || _a.forEach((fn)=>fn(event));\n const onces = this._listenersOnce[eventName];\n this._listenersOnce[eventName] = [];\n if (onces) onces.forEach((fn)=>fn(event));\n this._pipes.forEach((pipe)=>{\n pipe.emit(eventName, event);\n });\n }\n pipe(emitter) {\n if (this === emitter) throw Error(\"Cannot pipe to self\");\n this._pipes.push(emitter);\n return {\n close: ()=>{\n const i = this._pipes.indexOf(emitter);\n if (i > -1) this._pipes.splice(i, 1);\n }\n };\n }\n unpipe(emitter) {\n const i = this._pipes.indexOf(emitter);\n if (i > -1) this._pipes.splice(i, 1);\n }\n pause() {\n this._paused = true;\n }\n unpause() {\n this._paused = false;\n }\n }\n /**\n * Determines the scope of handling mouse/touch events.\n */ var PointerScope;\n (function(PointerScope) {\n /**\n * Handle events on the `canvas` element only. Events originating outside the\n * `canvas` will not be handled.\n */ PointerScope[\"Canvas\"] = \"Canvas\";\n /**\n * Handles events on the entire document. All events will be handled by Excalibur.\n */ PointerScope[\"Document\"] = \"Document\";\n })(PointerScope || (PointerScope = {}));\n /**\n * @module\n * Pseudo-Random Utility\n *\n * A pseudo-random utility to add seeded random support for help in\n * generating things like terrain or reproducible randomness. Uses the\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\n */ /**\n * 32-bit mask\n */ const BITMASK32 = 0xffffffff;\n /**\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\n * of numbers each time it is called.\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\n *\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\n */ class Random {\n /**\n * If no seed is specified, the Date.now() is used\n */ constructor(seed){\n this.seed = seed;\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\n this._lowerMask = 0x7fffffff; // 31 bits same as _r\n this._upperMask = 0x80000000; // 34 high bits\n // Word size, 64 bits\n this._w = 32;\n // Degree of recurrence\n this._n = 624;\n // Middle word, an offset used in the recurrence defining the series x, 1<=m>> 0;\n for(let i = 1; i < this._n; i++){\n const s = this._mt[i - 1] ^ this._mt[i - 1] >>> this._w - 2;\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\n this._mt[i] = (this._f * ((s & 0xffff0000) >>> 16) << 16) + this._f * (s & 0xffff) + i >>> 0;\n }\n this._index = this._n;\n }\n /**\n * Apply the twist\n */ _twist() {\n const mag01 = [\n 0x0,\n this._a\n ];\n let y = 0, i = 0;\n for(; i < this._n - this._m; i++){\n y = this._mt[i] & this._upperMask | this._mt[i + 1] & this._lowerMask;\n this._mt[i] = this._mt[i + this._m] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n }\n for(; i < this._n - 1; i++){\n y = this._mt[i] & this._upperMask | this._mt[i + 1] & this._lowerMask;\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n }\n y = this._mt[this._n - 1] & this._upperMask | this._mt[0] & this._lowerMask;\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n this._index = 0;\n }\n /**\n * Return next 32 bit integer number in sequence\n */ nextInt() {\n if (this._index >= this._n) this._twist();\n let y = this._mt[this._index++];\n y ^= y >>> this._u;\n y ^= y << this._s & this._b;\n y ^= y << this._t & this._c;\n y ^= y >>> this._l;\n return y >>> 0;\n }\n /**\n * Return a random floating point number between [0, 1)\n */ next() {\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\n }\n /**\n * Return a random floating point in range [min, max) min is included, max is not included\n */ floating(min, max) {\n return (max - min) * this.next() + min;\n }\n /**\n * Return a random integer in range [min, max] min is included, max is included.\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\n */ integer(min, max) {\n return Math.floor((max - min + 1) * this.next() + min);\n }\n /**\n * Returns true or false randomly with 50/50 odds by default.\n * By default the likelihood of returning a true is .5 (50%).\n * @param likelihood takes values between [0, 1]\n */ bool(likelihood = 0.5) {\n return this.next() <= likelihood;\n }\n /**\n * Returns one element from an array at random\n */ pickOne(array) {\n return array[this.integer(0, array.length - 1)];\n }\n /**\n * Returns a new array random picking elements from the original\n * @param array Original array to pick from\n * @param numPicks can be any positive number\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\n * just that it is possible)\n */ pickSet(array, numPicks, allowDuplicates = false) {\n if (allowDuplicates) return this._pickSetWithDuplicates(array, numPicks);\n else return this._pickSetWithoutDuplicates(array, numPicks);\n }\n /**\n * Returns a new array randomly picking elements in the original (not reused)\n * @param array Array to pick elements out of\n * @param numPicks must be less than or equal to the number of elements in the array.\n */ _pickSetWithoutDuplicates(array, numPicks) {\n if (numPicks > array.length || numPicks < 0) throw new Error(\"Invalid number of elements to pick, must pick a value 0 < n <= length\");\n if (numPicks === array.length) return array;\n const result = new Array(numPicks);\n let currentPick = 0;\n const tempArray = array.slice(0);\n while(currentPick < numPicks){\n const index = this.integer(0, tempArray.length - 1);\n result[currentPick++] = tempArray[index];\n tempArray.splice(index, 1);\n }\n return result;\n }\n /**\n * Returns a new array random picking elements from the original allowing duplicates\n * @param array Array to pick elements out of\n * @param numPicks can be any positive number\n */ _pickSetWithDuplicates(array, numPicks) {\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\n if (numPicks < 0) throw new Error(\"Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT\");\n const result = new Array(numPicks);\n for(let i = 0; i < numPicks; i++)result[i] = this.pickOne(array);\n return result;\n }\n /**\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\n */ shuffle(array) {\n const tempArray = array.slice(0);\n let swap = null;\n for(let i = 0; i < tempArray.length - 2; i++){\n const randomIndex = this.integer(i, tempArray.length - 1);\n swap = tempArray[i];\n tempArray[i] = tempArray[randomIndex];\n tempArray[randomIndex] = swap;\n }\n return tempArray;\n }\n /**\n * Generate a list of random integer numbers\n * @param length the length of the final array\n * @param min the minimum integer number to generate inclusive\n * @param max the maximum integer number to generate inclusive\n */ range(length, min, max) {\n const result = new Array(length);\n for(let i = 0; i < length; i++)result[i] = this.integer(min, max);\n return result;\n }\n /**\n * Returns the result of a d4 dice roll\n */ d4() {\n return this.integer(1, 4);\n }\n /**\n * Returns the result of a d6 dice roll\n */ d6() {\n return this.integer(1, 6);\n }\n /**\n * Returns the result of a d8 dice roll\n */ d8() {\n return this.integer(1, 8);\n }\n /**\n * Returns the result of a d10 dice roll\n */ d10() {\n return this.integer(1, 10);\n }\n /**\n * Returns the result of a d12 dice roll\n */ d12() {\n return this.integer(1, 12);\n }\n /**\n * Returns the result of a d20 dice roll\n */ d20() {\n return this.integer(1, 20);\n }\n }\n /**\n * Two PI constant\n */ const TwoPI = Math.PI * 2;\n /**\n * Returns the fractional part of a number\n * @param x\n */ function frac(x) {\n if (x >= 0) return x - Math.floor(x);\n else return x - Math.ceil(x);\n }\n /**\n * Returns the sign of a number, if 0 returns 0\n */ function sign(val) {\n if (val === 0) return 0;\n return val < 0 ? -1 : 1;\n }\n /**\n * Clamps a value between a min and max inclusive\n */ function clamp(val, min, max) {\n return Math.min(Math.max(min, val), max);\n }\n /**\n * Convert an angle to be the equivalent in the range [0, 2PI]\n */ function canonicalizeAngle(angle) {\n let tmpAngle = angle;\n if (angle > TwoPI) while(tmpAngle > TwoPI)tmpAngle -= TwoPI;\n if (angle < 0) while(tmpAngle < 0)tmpAngle += TwoPI;\n return tmpAngle;\n }\n /**\n * Convert radians to degrees\n */ function toDegrees(radians) {\n return 180 / Math.PI * radians;\n }\n /**\n * Convert degrees to radians\n */ function toRadians(degrees) {\n return degrees / 180 * Math.PI;\n }\n /**\n * Generate a range of numbers\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\n * @param from inclusive\n * @param to inclusive\n */ const range = (from, to)=>Array.from(new Array(to - from + 1), (_x, i)=>i + from);\n /**\n * Find a random floating point number in range\n */ function randomInRange(min, max, random = new Random()) {\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\n }\n /**\n * Find a random integer in a range\n */ function randomIntInRange(min, max, random = new Random()) {\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\n }\n /**\n * A 2D vector on a plane.\n */ class Vector {\n /**\n * A (0, 0) vector\n */ static get Zero() {\n return new Vector(0, 0);\n }\n /**\n * A (1, 1) vector\n */ static get One() {\n return new Vector(1, 1);\n }\n /**\n * A (0.5, 0.5) vector\n */ static get Half() {\n return new Vector(0.5, 0.5);\n }\n /**\n * A unit vector pointing up (0, -1)\n */ static get Up() {\n return new Vector(0, -1);\n }\n /**\n * A unit vector pointing down (0, 1)\n */ static get Down() {\n return new Vector(0, 1);\n }\n /**\n * A unit vector pointing left (-1, 0)\n */ static get Left() {\n return new Vector(-1, 0);\n }\n /**\n * A unit vector pointing right (1, 0)\n */ static get Right() {\n return new Vector(1, 0);\n }\n /**\n * Returns a vector of unit length in the direction of the specified angle in Radians.\n * @param angle The angle to generate the vector\n */ static fromAngle(angle) {\n return new Vector(Math.cos(angle), Math.sin(angle));\n }\n /**\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\n */ static isValid(vec) {\n if (vec === null || vec === undefined) return false;\n if (isNaN(vec.x) || isNaN(vec.y)) return false;\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) return false;\n return true;\n }\n /**\n * Calculates distance between two Vectors\n * @param vec1\n * @param vec2\n */ static distance(vec1, vec2) {\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\n }\n static min(vec1, vec2) {\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\n }\n static max(vec1, vec2) {\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\n }\n /**\n * @param x X component of the Vector\n * @param y Y component of the Vector\n */ constructor(x, y){\n this._x = 0;\n this._y = 0;\n this._x = x;\n this._y = y;\n }\n /**\n * Get the x component of the vector\n */ get x() {\n return this._x;\n }\n /**\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\n */ set x(val) {\n this._x = val;\n }\n /**\n * Get the y component of the vector\n */ get y() {\n return this._y;\n }\n /**\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\n */ set y(val) {\n this._y = val;\n }\n /**\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\n */ setTo(x, y) {\n this.x = x;\n this.y = y;\n }\n /**\n * Compares this point against another and tests for equality\n * @param vector The other point to compare to\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\n */ equals(vector, tolerance = 0.001) {\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\n }\n /**\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\n * @param v The other vector. Leave blank to use origin vector.\n */ distance(v) {\n if (!v) return Math.sqrt(this.x * this.x + this.y * this.y);\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n }\n squareDistance(v) {\n if (!v) v = Vector.Zero;\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return deltaX * deltaX + deltaY * deltaY;\n }\n /**\n * Clamps the current vector's magnitude mutating it\n * @param magnitude\n */ clampMagnitude(magnitude) {\n const size = this.size;\n const newSize = clamp(size, 0, magnitude);\n this.size = newSize;\n return this;\n }\n /**\n * The size (magnitude) of the Vector\n */ get size() {\n return this.distance();\n }\n /**\n * Setting the size mutates the current vector\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\n */ set size(newLength) {\n const v = this.normalize().scale(newLength);\n this.setTo(v.x, v.y);\n }\n /**\n * Normalizes a vector to have a magnitude of 1.\n */ normalize() {\n const d = this.distance();\n if (d > 0) return new Vector(this.x / d, this.y / d);\n else return new Vector(0, 1);\n }\n /**\n * Returns the average (midpoint) between the current point and the specified\n */ average(vec) {\n return this.add(vec).scale(0.5);\n }\n scale(sizeOrScale, dest) {\n const result = dest || new Vector(0, 0);\n if (sizeOrScale instanceof Vector) {\n result.x = this.x * sizeOrScale.x;\n result.y = this.y * sizeOrScale.y;\n } else {\n result.x = this.x * sizeOrScale;\n result.y = this.y * sizeOrScale;\n }\n return result;\n }\n /**\n * Adds one vector to another\n * @param v The vector to add\n * @param dest Optionally copy the result into a provided vector\n */ add(v, dest) {\n if (dest) {\n dest.x = this.x + v.x;\n dest.y = this.y + v.y;\n return dest;\n }\n return new Vector(this.x + v.x, this.y + v.y);\n }\n /**\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\n * @param v The vector to subtract\n */ sub(v) {\n return new Vector(this.x - v.x, this.y - v.y);\n }\n /**\n * Adds one vector to this one modifying the original\n * @param v The vector to add\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */ addEqual(v) {\n this.setTo(this.x + v.x, this.y + v.y);\n return this;\n }\n /**\n * Subtracts a vector from this one modifying the original\n * @param v The vector to subtract\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */ subEqual(v) {\n this.setTo(this.x - v.x, this.y - v.y);\n return this;\n }\n /**\n * Scales this vector by a factor of size and modifies the original\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */ scaleEqual(size) {\n this.setTo(this.x * size, this.y * size);\n return this;\n }\n /**\n * Performs a dot product with another vector\n * @param v The vector to dot\n */ dot(v) {\n return this.x * v.x + this.y * v.y;\n }\n cross(v) {\n if (v instanceof Vector) return this.x * v.y - this.y * v.x;\n else if (typeof v === \"number\") return new Vector(v * this.y, -v * this.x);\n }\n static cross(num, vec) {\n return new Vector(-num * vec.y, num * vec.x);\n }\n /**\n * Returns the perpendicular vector to this one\n */ perpendicular() {\n return new Vector(this.y, -this.x);\n }\n /**\n * Returns the normal vector to this one, same as the perpendicular of length 1\n */ normal() {\n return this.perpendicular().normalize();\n }\n /**\n * Negate the current vector\n */ negate() {\n return this.scale(-1);\n }\n /**\n * Returns the angle of this vector.\n */ toAngle() {\n return Math.atan2(this.y, this.x);\n }\n /**\n * Rotates the current vector around a point by a certain number of\n * degrees in radians\n */ rotate(angle, anchor) {\n if (!anchor) anchor = new Vector(0, 0);\n const sinAngle = Math.sin(angle);\n const cosAngle = Math.cos(angle);\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\n return new Vector(x, y);\n }\n /**\n * Creates new vector that has the same values as the previous.\n */ clone(dest) {\n const v = dest !== null && dest !== void 0 ? dest : new Vector(0, 0);\n v.x = this.x;\n v.y = this.y;\n return v;\n }\n /**\n * Returns a string representation of the vector.\n */ toString(fixed) {\n if (fixed) return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\n return `(${this.x}, ${this.y})`;\n }\n }\n /**\n * Shorthand for creating new Vectors - returns a new Vector instance with the\n * provided X and Y components.\n * @param x X component of the Vector\n * @param y Y component of the Vector\n */ function vec(x, y) {\n return new Vector(x, y);\n }\n /**\n * Provides standard colors (e.g. [[Color.Black]])\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\n */ class Color {\n /**\n * Creates a new instance of Color from an r, g, b, a\n * @param r The red component of color (0-255)\n * @param g The green component of color (0-255)\n * @param b The blue component of color (0-255)\n * @param a The alpha component of color (0-1.0)\n */ constructor(r, g, b, a){\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a != null ? a : 1;\n }\n /**\n * Creates a new instance of Color from an r, g, b, a\n * @param r The red component of color (0-255)\n * @param g The green component of color (0-255)\n * @param b The blue component of color (0-255)\n * @param a The alpha component of color (0-1.0)\n */ static fromRGB(r, g, b, a) {\n return new Color(r, g, b, a);\n }\n /**\n * Creates a new instance of Color from a rgb string\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\n */ static fromRGBString(string) {\n const rgbaRegEx = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\n let match = null;\n if (match = string.match(rgbaRegEx)) {\n const r = parseInt(match[1], 10);\n const g = parseInt(match[2], 10);\n const b = parseInt(match[3], 10);\n let a = 1;\n if (match[4]) a = parseFloat(match[4]);\n return new Color(r, g, b, a);\n } else throw new Error(\"Invalid rgb/a string: \" + string);\n }\n /**\n * Creates a new instance of Color from a hex string\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\n */ static fromHex(hex) {\n const hexRegEx = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\n let match = null;\n if (match = hex.match(hexRegEx)) {\n const r = parseInt(match[1], 16);\n const g = parseInt(match[2], 16);\n const b = parseInt(match[3], 16);\n let a = 1;\n if (match[4]) a = parseInt(match[4], 16) / 255;\n return new Color(r, g, b, a);\n } else throw new Error(\"Invalid hex string: \" + hex);\n }\n /**\n * Creates a new instance of Color from hsla values\n * @param h Hue is represented [0-1]\n * @param s Saturation is represented [0-1]\n * @param l Luminance is represented [0-1]\n * @param a Alpha is represented [0-1]\n */ static fromHSL(h, s, l, a = 1.0) {\n const temp = new HSLColor(h, s, l, a);\n return temp.toRGBA();\n }\n /**\n * Lightens the current color by a specified amount\n * @param factor The amount to lighten by [0-1]\n */ lighten(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l += (1 - temp.l) * factor;\n return temp.toRGBA();\n }\n /**\n * Darkens the current color by a specified amount\n * @param factor The amount to darken by [0-1]\n */ darken(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l -= temp.l * factor;\n return temp.toRGBA();\n }\n /**\n * Saturates the current color by a specified amount\n * @param factor The amount to saturate by [0-1]\n */ saturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s += temp.s * factor;\n return temp.toRGBA();\n }\n /**\n * Desaturates the current color by a specified amount\n * @param factor The amount to desaturate by [0-1]\n */ desaturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s -= temp.s * factor;\n return temp.toRGBA();\n }\n /**\n * Multiplies a color by another, results in a darker color\n * @param color The other color\n */ multiply(color) {\n const newR = color.r / 255 * this.r / 255 * 255;\n const newG = color.g / 255 * this.g / 255 * 255;\n const newB = color.b / 255 * this.b / 255 * 255;\n const newA = color.a * this.a;\n return new Color(newR, newG, newB, newA);\n }\n /**\n * Screens a color by another, results in a lighter color\n * @param color The other color\n */ screen(color) {\n const color1 = color.invert();\n const color2 = color.invert();\n return color1.multiply(color2).invert();\n }\n /**\n * Inverts the current color\n */ invert() {\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\n }\n /**\n * Averages the current color with another\n * @param color The other color\n */ average(color) {\n const newR = (color.r + this.r) / 2;\n const newG = (color.g + this.g) / 2;\n const newB = (color.b + this.b) / 2;\n const newA = (color.a + this.a) / 2;\n return new Color(newR, newG, newB, newA);\n }\n equal(color) {\n return this.toString() === color.toString();\n }\n /**\n * Returns a CSS string representation of a color.\n * @param format Color representation, accepts: rgb, hsl, or hex\n */ toString(format = \"rgb\") {\n switch(format){\n case \"rgb\":\n return this.toRGBA();\n case \"hsl\":\n return this.toHSLA();\n case \"hex\":\n return this.toHex();\n default:\n throw new Error(\"Invalid Color format\");\n }\n }\n /**\n * Returns Hex Value of a color component\n * @param c color component\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\n */ _componentToHex(c) {\n const hex = c.toString(16);\n return hex.length === 1 ? \"0\" + hex : hex;\n }\n /**\n * Return Hex representation of a color.\n */ toHex() {\n return \"#\" + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\n }\n /**\n * Return RGBA representation of a color.\n */ toRGBA() {\n const result = String(this.r.toFixed(0)) + \", \" + String(this.g.toFixed(0)) + \", \" + String(this.b.toFixed(0));\n if (this.a !== undefined || this.a !== null) return \"rgba(\" + result + \", \" + String(this.a) + \")\";\n return \"rgb(\" + result + \")\";\n }\n /**\n * Return HSLA representation of a color.\n */ toHSLA() {\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\n }\n /**\n * Returns a CSS string representation of a color.\n */ fillStyle() {\n return this.toString();\n }\n /**\n * Returns a clone of the current color.\n */ clone() {\n return new Color(this.r, this.g, this.b, this.a);\n }\n /**\n * Black (#000000)\n */ static get Black() {\n return Color.fromHex(\"#000000\");\n }\n /**\n * White (#FFFFFF)\n */ static get White() {\n return Color.fromHex(\"#FFFFFF\");\n }\n /**\n * Gray (#808080)\n */ static get Gray() {\n return Color.fromHex(\"#808080\");\n }\n /**\n * Light gray (#D3D3D3)\n */ static get LightGray() {\n return Color.fromHex(\"#D3D3D3\");\n }\n /**\n * Dark gray (#A9A9A9)\n */ static get DarkGray() {\n return Color.fromHex(\"#A9A9A9\");\n }\n /**\n * Yellow (#FFFF00)\n */ static get Yellow() {\n return Color.fromHex(\"#FFFF00\");\n }\n /**\n * Orange (#FFA500)\n */ static get Orange() {\n return Color.fromHex(\"#FFA500\");\n }\n /**\n * Red (#FF0000)\n */ static get Red() {\n return Color.fromHex(\"#FF0000\");\n }\n /**\n * Vermilion (#FF5B31)\n */ static get Vermilion() {\n return Color.fromHex(\"#FF5B31\");\n }\n /**\n * Rose (#FF007F)\n */ static get Rose() {\n return Color.fromHex(\"#FF007F\");\n }\n /**\n * Magenta (#FF00FF)\n */ static get Magenta() {\n return Color.fromHex(\"#FF00FF\");\n }\n /**\n * Violet (#7F00FF)\n */ static get Violet() {\n return Color.fromHex(\"#7F00FF\");\n }\n /**\n * Blue (#0000FF)\n */ static get Blue() {\n return Color.fromHex(\"#0000FF\");\n }\n /**\n * Azure (#007FFF)\n */ static get Azure() {\n return Color.fromHex(\"#007FFF\");\n }\n /**\n * Cyan (#00FFFF)\n */ static get Cyan() {\n return Color.fromHex(\"#00FFFF\");\n }\n /**\n * Viridian (#59978F)\n */ static get Viridian() {\n return Color.fromHex(\"#59978F\");\n }\n /**\n * Green (#00FF00)\n */ static get Green() {\n return Color.fromHex(\"#00FF00\");\n }\n /**\n * Chartreuse (#7FFF00)\n */ static get Chartreuse() {\n return Color.fromHex(\"#7FFF00\");\n }\n /**\n * Transparent (#FFFFFF00)\n */ static get Transparent() {\n return Color.fromHex(\"#FFFFFF00\");\n }\n /**\n * ExcaliburBlue (#176BAA)\n */ static get ExcaliburBlue() {\n return Color.fromHex(\"#176BAA\");\n }\n }\n /**\n * Internal HSL Color representation\n *\n * http://en.wikipedia.org/wiki/HSL_and_HSV\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\n */ class HSLColor {\n constructor(h, s, l, a){\n this.h = h;\n this.s = s;\n this.l = l;\n this.a = a;\n }\n static hue2rgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 0.5) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n }\n static fromRGBA(r, g, b, a) {\n r /= 255;\n g /= 255;\n b /= 255;\n const max = Math.max(r, g, b), min = Math.min(r, g, b);\n let h, s;\n const l = (max + min) / 2;\n if (max === min) h = s = 0; // achromatic\n else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch(max){\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n return new HSLColor(h, s, l, a);\n }\n toRGBA() {\n let r, g, b;\n if (this.s === 0) r = g = b = this.l; // achromatic\n else {\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\n const p = 2 * this.l - q;\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\n g = HSLColor.hue2rgb(p, q, this.h);\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\n }\n return new Color(r * 255, g * 255, b * 255, this.a);\n }\n toString() {\n const h = this.h.toFixed(0), s = this.s.toFixed(0), l = this.l.toFixed(0), a = this.a.toFixed(0);\n return `hsla(${h}, ${s}, ${l}, ${a})`;\n }\n }\n /* eslint-disable no-console */ /**\n * Logging level that Excalibur will tag\n */ var LogLevel;\n (function(LogLevel) {\n LogLevel[LogLevel[\"Debug\"] = 0] = \"Debug\";\n LogLevel[LogLevel[\"Info\"] = 1] = \"Info\";\n LogLevel[LogLevel[\"Warn\"] = 2] = \"Warn\";\n LogLevel[LogLevel[\"Error\"] = 3] = \"Error\";\n LogLevel[LogLevel[\"Fatal\"] = 4] = \"Fatal\";\n })(LogLevel || (LogLevel = {}));\n /**\n * Static singleton that represents the logging facility for Excalibur.\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\n * Derive from [[Appender]] to create your own logging appenders.\n */ class Logger {\n constructor(){\n this._appenders = [];\n /**\n * Gets or sets the default logging level. Excalibur will only log\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\n */ this.defaultLevel = LogLevel.Info;\n this._logOnceSet = new Set();\n if (Logger._INSTANCE) throw new Error(\"Logger is a singleton\");\n Logger._INSTANCE = this;\n // Default console appender\n Logger._INSTANCE.addAppender(new ConsoleAppender());\n return Logger._INSTANCE;\n }\n /**\n * Gets the current static instance of Logger\n */ static getInstance() {\n if (Logger._INSTANCE == null) Logger._INSTANCE = new Logger();\n return Logger._INSTANCE;\n }\n /**\n * Adds a new [[Appender]] to the list of appenders to write to\n */ addAppender(appender) {\n this._appenders.push(appender);\n }\n /**\n * Clears all appenders from the logger\n */ clearAppenders() {\n this._appenders.length = 0;\n }\n /**\n * Logs a message at a given LogLevel\n * @param level The LogLevel`to log the message at\n * @param args An array of arguments to write to an appender\n */ _log(level, args) {\n if (level == null) level = this.defaultLevel;\n const len = this._appenders.length;\n for(let i = 0; i < len; i++)if (level >= this.defaultLevel) this._appenders[i].log(level, args);\n }\n _logOnce(level, args) {\n const serialized = level + args.join(\"+\");\n if (this._logOnceSet.has(serialized)) return;\n else {\n this._logOnceSet.add(serialized);\n this._log(level, args);\n }\n }\n /**\n * Writes a log message at the [[LogLevel.Debug]] level\n * @param args Accepts any number of arguments\n */ debug(...args) {\n this._log(LogLevel.Debug, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it wont log\n * @param args Accepts any number of arguments\n */ debugOnce(...args) {\n this._logOnce(LogLevel.Debug, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Info]] level\n * @param args Accepts any number of arguments\n */ info(...args) {\n this._log(LogLevel.Info, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Info]] level, if it sees the same args again it wont log\n * @param args Accepts any number of arguments\n */ infoOnce(...args) {\n this._logOnce(LogLevel.Info, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Warn]] level\n * @param args Accepts any number of arguments\n */ warn(...args) {\n this._log(LogLevel.Warn, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Warn]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */ warnOnce(...args) {\n this._logOnce(LogLevel.Warn, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Error]] level\n * @param args Accepts any number of arguments\n */ error(...args) {\n this._log(LogLevel.Error, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Error]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */ errorOnce(...args) {\n this._logOnce(LogLevel.Error, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Fatal]] level\n * @param args Accepts any number of arguments\n */ fatal(...args) {\n this._log(LogLevel.Fatal, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */ fatalOnce(...args) {\n this._logOnce(LogLevel.Fatal, args);\n }\n }\n Logger._INSTANCE = null;\n /**\n * Console appender for browsers (i.e. `console.log`)\n */ class ConsoleAppender {\n /**\n * Logs a message at the given [[LogLevel]]\n * @param level Level to log at\n * @param args Arguments to log\n */ log(level, args) {\n // Check for console support\n if (!console && !console.log && console.warn && console.error) // todo maybe do something better than nothing\n return;\n // Create a new console args array\n const consoleArgs = [];\n consoleArgs.unshift.apply(consoleArgs, args);\n consoleArgs.unshift(\"[\" + LogLevel[level] + \"] : \");\n if (level < LogLevel.Warn) {\n // Call .log for Debug/Info\n if (console.log.apply) // this is required on some older browsers that don't support apply on console.log :(\n console.log.apply(console, consoleArgs);\n else console.log(consoleArgs.join(\" \"));\n } else if (level < LogLevel.Error) {\n // Call .warn for Warn\n if (console.warn.apply) console.warn.apply(console, consoleArgs);\n else console.warn(consoleArgs.join(\" \"));\n } else // Call .error for Error/Fatal\n if (console.error.apply) console.error.apply(console, consoleArgs);\n else console.error(consoleArgs.join(\" \"));\n }\n }\n /**\n * On-screen (canvas) appender\n */ class ScreenAppender {\n constructor(options){\n var _a, _b;\n this._messages = [];\n this._pos = 10;\n this._color = Color.Black;\n this._options = options;\n this.canvas = document.createElement(\"canvas\");\n this._ctx = this.canvas.getContext(\"2d\");\n this.canvas.style.position = \"absolute\";\n this.canvas.style.zIndex = (_b = (_a = options.zIndex) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : \"99\";\n document.body.appendChild(this.canvas);\n this._positionScreenAppenderCanvas();\n options.engine.screen.events.on(\"resize\", ()=>{\n this._positionScreenAppenderCanvas();\n });\n }\n _positionScreenAppenderCanvas() {\n var _a, _b, _c, _d;\n const options = this._options;\n this.canvas.width = (_a = options.width) !== null && _a !== void 0 ? _a : options.engine.screen.resolution.width;\n this.canvas.height = (_b = options.height) !== null && _b !== void 0 ? _b : options.engine.screen.resolution.height;\n this.canvas.style.position = \"absolute\";\n const pagePos = options.engine.screen.screenToPageCoordinates(vec(0, 0));\n this.canvas.style.left = pagePos.x + \"px\";\n this.canvas.style.top = pagePos.y + \"px\";\n this._pos = (_c = options.xPos) !== null && _c !== void 0 ? _c : this._pos;\n this._color = (_d = options.color) !== null && _d !== void 0 ? _d : this._color;\n }\n /**\n * Logs a message at the given [[LogLevel]]\n * @param level Level to log at\n * @param args Arguments to log\n */ log(level, args) {\n const message = args.join(\",\");\n this._ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this._messages.unshift(\"[\" + LogLevel[level] + \"] : \" + message);\n let pos = 10;\n this._messages = this._messages.slice(0, 1000);\n for(let i = 0; i < this._messages.length; i++){\n this._ctx.fillStyle = this._color.toRGBA();\n this._ctx.fillText(this._messages[i], this._pos, pos);\n pos += 10;\n }\n }\n }\n /**\n * An enum that describes the sides of an axis aligned box for collision\n */ var Side;\n (function(Side) {\n Side[\"None\"] = \"None\";\n Side[\"Top\"] = \"Top\";\n Side[\"Bottom\"] = \"Bottom\";\n Side[\"Left\"] = \"Left\";\n Side[\"Right\"] = \"Right\";\n })(Side || (Side = {}));\n (function(Side) {\n /**\n * Returns the opposite side from the current\n */ function getOpposite(side) {\n if (side === Side.Top) return Side.Bottom;\n if (side === Side.Bottom) return Side.Top;\n if (side === Side.Left) return Side.Right;\n if (side === Side.Right) return Side.Left;\n return Side.None;\n }\n Side.getOpposite = getOpposite;\n /**\n * Given a vector, return the Side most in that direction (via dot product)\n */ function fromDirection(direction) {\n const directions = [\n Vector.Left,\n Vector.Right,\n Vector.Up,\n Vector.Down\n ];\n const directionEnum = [\n Side.Left,\n Side.Right,\n Side.Top,\n Side.Bottom\n ];\n let max = -Number.MAX_VALUE;\n let maxIndex = -1;\n for(let i = 0; i < directions.length; i++)if (directions[i].dot(direction) > max) {\n max = directions[i].dot(direction);\n maxIndex = i;\n }\n return directionEnum[maxIndex];\n }\n Side.fromDirection = fromDirection;\n })(Side || (Side = {}));\n /**\n * Axis Aligned collision primitive for Excalibur.\n */ class BoundingBox {\n /**\n * Constructor allows passing of either an object with all coordinate components,\n * or the coordinate components passed separately.\n * @param leftOrOptions Either x coordinate of the left edge or an options object\n * containing the four coordinate components.\n * @param top y coordinate of the top edge\n * @param right x coordinate of the right edge\n * @param bottom y coordinate of the bottom edge\n */ constructor(leftOrOptions = 0, top = 0, right = 0, bottom = 0){\n // Cache bounding box point returns\n this._points = [];\n if (typeof leftOrOptions === \"object\") {\n this.left = leftOrOptions.left;\n this.top = leftOrOptions.top;\n this.right = leftOrOptions.right;\n this.bottom = leftOrOptions.bottom;\n } else if (typeof leftOrOptions === \"number\") {\n this.left = leftOrOptions;\n this.top = top;\n this.right = right;\n this.bottom = bottom;\n }\n }\n /**\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\n */ clone() {\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\n }\n /**\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\n * @param intersection Intersection vector between 2 bounding boxes\n */ static getSideFromIntersection(intersection) {\n if (!intersection) return Side.None;\n if (intersection) {\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\n if (intersection.x < 0) return Side.Right;\n return Side.Left;\n } else {\n if (intersection.y < 0) return Side.Bottom;\n return Side.Top;\n }\n }\n return Side.None;\n }\n static fromPoints(points) {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for(let i = 0; i < points.length; i++){\n if (points[i].x < minX) minX = points[i].x;\n if (points[i].x > maxX) maxX = points[i].x;\n if (points[i].y < minY) minY = points[i].y;\n if (points[i].y > maxY) maxY = points[i].y;\n }\n return new BoundingBox(minX, minY, maxX, maxY);\n }\n /**\n * Creates a bounding box from a width and height\n * @param width\n * @param height\n * @param anchor Default Vector.Half\n * @param pos Default Vector.Zero\n */ static fromDimension(width, height, anchor = Vector.Half, pos = Vector.Zero) {\n return new BoundingBox(-width * anchor.x + pos.x, -height * anchor.y + pos.y, width - width * anchor.x + pos.x, height - height * anchor.y + pos.y);\n }\n /**\n * Returns the calculated width of the bounding box\n */ get width() {\n return this.right - this.left;\n }\n /**\n * Returns the calculated height of the bounding box\n */ get height() {\n return this.bottom - this.top;\n }\n /**\n * Return whether the bounding box has zero dimensions in height,width or both\n */ hasZeroDimensions() {\n return this.width === 0 || this.height === 0;\n }\n /**\n * Returns the center of the bounding box\n */ get center() {\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\n }\n get topLeft() {\n return new Vector(this.left, this.top);\n }\n get bottomRight() {\n return new Vector(this.right, this.bottom);\n }\n get topRight() {\n return new Vector(this.right, this.top);\n }\n get bottomLeft() {\n return new Vector(this.left, this.bottom);\n }\n translate(pos) {\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\n }\n /**\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\n */ rotate(angle, point = Vector.Zero) {\n const points = this.getPoints().map((p)=>p.rotate(angle, point));\n return BoundingBox.fromPoints(points);\n }\n /**\n * Scale a bounding box by a scale factor, optionally provide a point\n * @param scale\n * @param point\n */ scale(scale, point = Vector.Zero) {\n const shifted = this.translate(point);\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\n }\n /**\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\n * @param matrix\n */ transform(matrix) {\n // inlined these calculations to not use vectors would speed it up slightly\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\n // const xa = matFirstColumn.scale(this.left);\n const xa1 = matrix.data[0] * this.left;\n const xa2 = matrix.data[1] * this.left;\n // const xb = matFirstColumn.scale(this.right);\n const xb1 = matrix.data[0] * this.right;\n const xb2 = matrix.data[1] * this.right;\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\n // const ya = matSecondColumn.scale(this.top);\n const ya1 = matrix.data[2] * this.top;\n const ya2 = matrix.data[3] * this.top;\n // const yb = matSecondColumn.scale(this.bottom);\n const yb1 = matrix.data[2] * this.bottom;\n const yb2 = matrix.data[3] * this.bottom;\n const matrixPos = matrix.getPosition();\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\n return new BoundingBox({\n left: left,\n top: top,\n right: right,\n bottom: bottom //: bottomRight.y\n });\n }\n /**\n * Returns the perimeter of the bounding box\n */ getPerimeter() {\n const wx = this.width;\n const wy = this.height;\n return 2 * (wx + wy);\n }\n /**\n * Returns the world space points that make up the corners of the bounding box as a polygon\n */ getPoints() {\n if (this._left !== this.left || this._right !== this.right || this._top !== this.top || this._bottom !== this.bottom) {\n this._points.length = 0;\n this._points.push(new Vector(this.left, this.top));\n this._points.push(new Vector(this.right, this.top));\n this._points.push(new Vector(this.right, this.bottom));\n this._points.push(new Vector(this.left, this.bottom));\n this._left = this.left;\n this._right = this.right;\n this._top = this.top;\n this._bottom = this.bottom;\n }\n return this._points;\n }\n /**\n * Determines whether a ray intersects with a bounding box\n */ rayCast(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\n }\n rayCastTime(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) return tmin;\n return -1;\n }\n contains(val) {\n if (val instanceof Vector) return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\n else if (val instanceof BoundingBox) {\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) return true;\n return false;\n }\n return false;\n }\n /**\n * Combines this bounding box and another together returning a new bounding box\n * @param other The bounding box to combine\n */ combine(other) {\n const compositeBB = new BoundingBox(Math.min(this.left, other.left), Math.min(this.top, other.top), Math.max(this.right, other.right), Math.max(this.bottom, other.bottom));\n return compositeBB;\n }\n get dimensions() {\n return new Vector(this.width, this.height);\n }\n /**\n * Returns true if the bounding boxes overlap.\n * @param other\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\n * This epsilon is useful in stable collision simulations.\n */ overlaps(other, epsilon) {\n const e = epsilon || 0;\n if (other.hasZeroDimensions()) return this.contains(other);\n if (this.hasZeroDimensions()) return other.contains(this);\n const totalBoundingBox = this.combine(other);\n return totalBoundingBox.width + e < other.width + this.width && totalBoundingBox.height + e < other.height + this.height;\n }\n /**\n * Test wether this bounding box intersects with another returning\n * the intersection vector that can be used to resolve the collision. If there\n * is no intersection null is returned.\n * @param other Other [[BoundingBox]] to test intersection with\n * @returns A Vector in the direction of the current BoundingBox, this <- other\n */ intersect(other) {\n const totalBoundingBox = this.combine(other);\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\n if (totalBoundingBox.width < other.width + this.width && totalBoundingBox.height < other.height + this.height && !totalBoundingBox.dimensions.equals(other.dimensions) && !totalBoundingBox.dimensions.equals(this.dimensions)) {\n // collision\n let overlapX = 0;\n // right edge is between the other's left and right edge\n /**\n * +-this-+\n * | |\n * | +-other-+\n * +----|-+ |\n * | |\n * +-------+\n * <---\n * ^ overlap\n */ if (this.right >= other.left && this.right <= other.right) overlapX = other.left - this.right;\n else overlapX = other.right - this.left;\n let overlapY = 0;\n // top edge is between the other's top and bottom edge\n /**\n * +-other-+\n * | |\n * | +-this-+ | <- overlap\n * +----|--+ | |\n * | | \\ /\n * +------+ '\n */ if (this.top <= other.bottom && this.top >= other.top) overlapY = other.bottom - this.top;\n else overlapY = other.top - this.bottom;\n if (Math.abs(overlapX) < Math.abs(overlapY)) return new Vector(overlapX, 0);\n else return new Vector(0, overlapY);\n // Case of total containment of one bounding box by another\n } else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\n let overlapX = 0;\n // this is wider than the other\n if (this.width - other.width >= 0) {\n // This right edge is closest to the others right edge\n if (this.right - other.right <= other.left - this.left) overlapX = other.left - this.right;\n else overlapX = other.right - this.left;\n } else // This right edge is closest to the others right edge\n if (other.right - this.right <= this.left - other.left) overlapX = this.left - other.right;\n else overlapX = this.right - other.left;\n let overlapY = 0;\n // this is taller than other\n if (this.height - other.height >= 0) {\n // The bottom edge is closest to the others bottom edge\n if (this.bottom - other.bottom <= other.top - this.top) overlapY = other.top - this.bottom;\n else overlapY = other.bottom - this.top;\n } else // The bottom edge is closest to the others bottom edge\n if (other.bottom - this.bottom <= this.top - other.top) overlapY = this.top - other.bottom;\n else overlapY = this.bottom - other.top;\n if (Math.abs(overlapX) < Math.abs(overlapY)) return new Vector(overlapX, 0);\n else return new Vector(0, overlapY);\n } else return null;\n }\n /**\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\n * @param bb The other actor to test\n */ intersectWithSide(bb) {\n const intersect = this.intersect(bb);\n return BoundingBox.getSideFromIntersection(intersect);\n }\n /**\n * Draw a debug bounding box\n * @param ex\n * @param color\n */ draw(ex, color = Color.Yellow) {\n ex.debug.drawRect(this.left, this.top, this.width, this.height, {\n color: color\n });\n }\n }\n /**\n * Find the screen position of an HTML element\n */ function getPosition(el) {\n // do we need the scroll too? technically the offset method before did that\n const rect = el.getBoundingClientRect();\n return vec(rect.x + window.scrollX, rect.y + window.scrollY);\n }\n /**\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\n * @deprecated Will be removed in v0.26.0\n */ function addItemToArray(item, array) {\n if (array.indexOf(item) === -1) {\n array.push(item);\n return true;\n }\n return false;\n }\n /**\n * Remove an item from an list\n * @deprecated Will be removed in v0.26.0\n */ function removeItemFromArray(item, array) {\n let index = -1;\n if ((index = array.indexOf(item)) > -1) {\n array.splice(index, 1);\n return true;\n }\n return false;\n }\n /**\n * See if an array contains something\n */ function contains(array, obj) {\n for(let i = 0; i < array.length; i++){\n if (array[i] === obj) return true;\n }\n return false;\n }\n /**\n * Used for exhaustive checks at compile time\n */ function fail(message) {\n throw new Error(message);\n }\n /**\n * Create a promise that resolves after a certain number of milliseconds\n *\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\n * excalibur clock which would be unaffected by stop/pause.\n * @param milliseconds\n * @param clock\n */ function delay(milliseconds, clock) {\n var _a;\n const future = new Future();\n const schedule = (_a = clock === null || clock === void 0 ? void 0 : clock.schedule.bind(clock)) !== null && _a !== void 0 ? _a : setTimeout;\n schedule(()=>{\n future.resolve();\n }, milliseconds);\n return future.promise;\n }\n /**\n * Remove keys from object literals\n * @param object\n * @param keys\n */ function omit(object, keys) {\n const newObj = {};\n for(const key in object)if (!keys.includes(key)) newObj[key] = object[key];\n return newObj;\n }\n var MatrixLocations;\n (function(MatrixLocations) {\n MatrixLocations[MatrixLocations[\"X\"] = 12] = \"X\";\n MatrixLocations[MatrixLocations[\"Y\"] = 13] = \"Y\";\n })(MatrixLocations || (MatrixLocations = {}));\n /**\n * Excalibur Matrix helper for 4x4 matrices\n *\n * Useful for webgl 4x4 matrices\n */ class Matrix {\n constructor(){\n /**\n * 4x4 matrix in column major order\n *\n * | | | | |\n * | ------- | ------- | -------- | -------- |\n * | data[0] | data[4] | data[8] | data[12] |\n * | data[1] | data[5] | data[9] | data[13] |\n * | data[2] | data[6] | data[10] | data[14] |\n * | data[3] | data[7] | data[11] | data[15] |\n *\n */ this.data = new Float32Array(16);\n this._scaleX = 1;\n this._scaleSignX = 1;\n this._scaleY = 1;\n this._scaleSignY = 1;\n }\n /**\n * Creates an orthographic (flat non-perspective) projection\n * https://en.wikipedia.org/wiki/Orthographic_projection\n * @param left\n * @param right\n * @param bottom\n * @param top\n * @param near\n * @param far\n */ static ortho(left, right, bottom, top, near, far) {\n const mat = new Matrix();\n mat.data[0] = 2 / (right - left);\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 2 / (top - bottom);\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = -2 / (far - near);\n mat.data[11] = 0;\n mat.data[12] = -(right + left) / (right - left);\n mat.data[13] = -(top + bottom) / (top - bottom);\n mat.data[14] = -(far + near) / (far - near);\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a new Matrix with the same data as the current 4x4\n */ clone(dest) {\n const mat = dest || new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n mat.data[6] = this.data[6];\n mat.data[7] = this.data[7];\n mat.data[8] = this.data[8];\n mat.data[9] = this.data[9];\n mat.data[10] = this.data[10];\n mat.data[11] = this.data[11];\n mat.data[12] = this.data[12];\n mat.data[13] = this.data[13];\n mat.data[14] = this.data[14];\n mat.data[15] = this.data[15];\n return mat;\n }\n /**\n * Converts the current matrix into a DOMMatrix\n *\n * This is useful when working with the browser Canvas context\n * @returns {DOMMatrix} DOMMatrix\n */ toDOMMatrix() {\n return new DOMMatrix([\n ...this.data\n ]);\n }\n static fromFloat32Array(data) {\n const matrix = new Matrix();\n matrix.data = data;\n return matrix;\n }\n /**\n * Creates a new identity matrix (a matrix that when applied does nothing)\n */ static identity() {\n const mat = new Matrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Resets the current matrix to the identity matrix, mutating it\n * @returns {Matrix} Current matrix as identity\n */ reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a brand new translation matrix at the specified 3d point\n * @param x\n * @param y\n */ static translation(x, y) {\n const mat = Matrix.identity();\n mat.data[12] = x;\n mat.data[13] = y;\n return mat;\n }\n /**\n * Creates a brand new scaling matrix with the specified scaling factor\n * @param sx\n * @param sy\n */ static scale(sx, sy) {\n const mat = Matrix.identity();\n mat.data[0] = sx;\n mat.data[5] = sy;\n mat.data[10] = 1;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a brand new rotation matrix with the specified angle\n * @param angleRadians\n */ static rotation(angleRadians) {\n const mat = Matrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[4] = -Math.sin(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[5] = Math.cos(angleRadians);\n return mat;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\n result.x = resultX;\n result.y = resultY;\n return result;\n } else {\n const result = dest || new Matrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n const b11 = other.data[0];\n const b21 = other.data[1];\n const b31 = other.data[2];\n const b41 = other.data[3];\n const b12 = other.data[4];\n const b22 = other.data[5];\n const b32 = other.data[6];\n const b42 = other.data[7];\n const b13 = other.data[8];\n const b23 = other.data[9];\n const b33 = other.data[10];\n const b43 = other.data[11];\n const b14 = other.data[12];\n const b24 = other.data[13];\n const b34 = other.data[14];\n const b44 = other.data[15];\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n /**\n * Applies translation to the current matrix mutating it\n * @param x\n * @param y\n */ translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n // Doesn't change z\n const z = 0;\n const w = 1;\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\n return this;\n }\n setPosition(x, y) {\n this.data[12] = x;\n this.data[13] = y;\n }\n getPosition() {\n return vec(this.data[12], this.data[13]);\n }\n /**\n * Applies rotation to the current matrix mutating it\n * @param angle in Radians\n */ rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a31 + sine * a32;\n this.data[3] = cosine * a41 + sine * a42;\n this.data[4] = cosine * a12 - sine * a11;\n this.data[5] = cosine * a22 - sine * a21;\n this.data[6] = cosine * a32 - sine * a31;\n this.data[7] = cosine * a42 - sine * a41;\n return this;\n }\n /**\n * Applies scaling to the current matrix mutating it\n * @param x\n * @param y\n */ scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a31 * x;\n this.data[3] = a41 * x;\n this.data[4] = a12 * y;\n this.data[5] = a22 * y;\n this.data[6] = a32 * y;\n this.data[7] = a42 * y;\n return this;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[4] = -sine * currentScale.x;\n this.data[5] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[4]).size;\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[5]).size;\n return this._scaleSignY * yscale;\n }\n /**\n * Get the scale of the matrix\n */ getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (this._scaleX === val) return;\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[4] = xscale.y * val;\n this._scaleX = val;\n }\n setScaleY(val) {\n if (this._scaleY === val) return;\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[5] = yscale.y * val;\n this._scaleY = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n /**\n * Determinant of the upper left 2x2 matrix\n */ getBasisDeterminant() {\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\n }\n /**\n * Return the affine inverse, optionally store it in a target matrix.\n *\n * It's recommended you call .reset() the target unless you know what you're doing\n * @param target\n */ getAffineInverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.getBasisDeterminant();\n const inverseDet = 1 / det; // todo zero check\n const a = this.data[0];\n const b = this.data[4];\n const c = this.data[1];\n const d = this.data[5];\n const m = target || Matrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[4] = -b * inverseDet;\n m.data[5] = a * inverseDet;\n const tx = this.data[12];\n const ty = this.data[13];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\n return m;\n }\n isIdentity() {\n return this.data[0] === 1 && this.data[1] === 0 && this.data[2] === 0 && this.data[3] === 0 && this.data[4] === 0 && this.data[5] === 1 && this.data[6] === 0 && this.data[7] === 0 && this.data[8] === 0 && this.data[9] === 0 && this.data[10] === 1 && this.data[11] === 0 && this.data[12] === 0 && this.data[13] === 0 && this.data[14] === 0 && this.data[15] === 1;\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\n }\n }\n class AffineMatrix {\n constructor(){\n /**\n * | | | |\n * | ------- | ------- | -------- |\n * | data[0] | data[2] | data[4] |\n * | data[1] | data[3] | data[5] |\n * | 0 | 0 | 1 |\n */ this.data = new Float64Array(6);\n this._scale = new Float64Array([\n 1,\n 1\n ]);\n this._scaleSignX = 1;\n this._scaleSignY = 1;\n }\n /**\n * Converts the current matrix into a DOMMatrix\n *\n * This is useful when working with the browser Canvas context\n * @returns {DOMMatrix} DOMMatrix\n */ toDOMMatrix() {\n return new DOMMatrix([\n ...this.data\n ]);\n }\n static identity() {\n const mat = new AffineMatrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\n * Creates a brand new translation matrix at the specified 3d point\n * @param x\n * @param y\n */ static translation(x, y) {\n const mat = AffineMatrix.identity();\n mat.data[4] = x;\n mat.data[5] = y;\n return mat;\n }\n /**\n * Creates a brand new scaling matrix with the specified scaling factor\n * @param sx\n * @param sy\n */ static scale(sx, sy) {\n const mat = AffineMatrix.identity();\n mat.data[0] = sx;\n mat.data[3] = sy;\n mat._scale[0] = sx;\n mat._scale[1] = sy;\n return mat;\n }\n /**\n * Creates a brand new rotation matrix with the specified angle\n * @param angleRadians\n */ static rotation(angleRadians) {\n const mat = AffineMatrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[2] = -Math.sin(angleRadians);\n mat.data[3] = Math.cos(angleRadians);\n return mat;\n }\n setPosition(x, y) {\n this.data[4] = x;\n this.data[5] = y;\n }\n getPosition() {\n return vec(this.data[4], this.data[5]);\n }\n /**\n * Applies rotation to the current matrix mutating it\n * @param angle in Radians\n */ rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a12 - sine * a11;\n this.data[3] = cosine * a22 - sine * a21;\n return this;\n }\n /**\n * Applies translation to the current matrix mutating it\n * @param x\n * @param y\n */ translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n // Doesn't change z\n this.data[4] = a11 * x + a12 * y + a13;\n this.data[5] = a21 * x + a22 * y + a23;\n return this;\n }\n /**\n * Applies scaling to the current matrix mutating it\n * @param x\n * @param y\n */ scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a12 * y;\n this.data[3] = a22 * y;\n this._scale[0] = x;\n this._scale[1] = y;\n return this;\n }\n determinant() {\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\n }\n /**\n * Return the affine inverse, optionally store it in a target matrix.\n *\n * It's recommended you call .reset() the target unless you know what you're doing\n * @param target\n */ inverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.determinant();\n const inverseDet = 1 / det; // TODO zero check\n const a = this.data[0];\n const b = this.data[2];\n const c = this.data[1];\n const d = this.data[3];\n const m = target || AffineMatrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[2] = -b * inverseDet;\n m.data[3] = a * inverseDet;\n const tx = this.data[4];\n const ty = this.data[5];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\n return m;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\n result.x = resultX;\n result.y = resultY;\n return result;\n } else {\n const result = dest || new AffineMatrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n const b11 = other.data[0];\n const b21 = other.data[1];\n // const b31 = 0;\n const b12 = other.data[2];\n const b22 = other.data[3];\n // const b32 = 0;\n const b13 = other.data[4];\n const b23 = other.data[5];\n // const b33 = 1;\n result.data[0] = a11 * b11 + a12 * b21; // + a13 * b31; // zero\n result.data[1] = a21 * b11 + a22 * b21; // + a23 * b31; // zero\n result.data[2] = a11 * b12 + a12 * b22; // + a13 * b32; // zero\n result.data[3] = a21 * b12 + a22 * b22; // + a23 * b32; // zero\n result.data[4] = a11 * b13 + a12 * b23 + a13; // * b33; // one\n result.data[5] = a21 * b13 + a22 * b23 + a23; // * b33; // one\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n to4x4() {\n const mat = new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = this.data[2];\n mat.data[5] = this.data[3];\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = this.data[4];\n mat.data[13] = this.data[5];\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[2] = -sine * currentScale.x;\n this.data[3] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[2]).distance();\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[3]).distance();\n return this._scaleSignY * yscale;\n }\n /**\n * Get the scale of the matrix\n */ getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (val === this._scale[0]) return;\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[2] = xscale.y * val;\n this._scale[0] = val;\n }\n setScaleY(val) {\n if (val === this._scale[1]) return;\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[3] = yscale.y * val;\n this._scale[1] = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n isIdentity() {\n return this.data[0] === 1 && this.data[1] === 0 && this.data[2] === 0 && this.data[3] === 1 && this.data[4] === 0 && this.data[5] === 0;\n }\n /**\n * Resets the current matrix to the identity matrix, mutating it\n * @returns {AffineMatrix} Current matrix as identity\n */ reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\n * Creates a new Matrix with the same data as the current 4x4\n */ clone(dest) {\n const mat = dest || new AffineMatrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n return mat;\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\n }\n }\n class TransformStack {\n constructor(){\n this._transforms = [];\n this._currentTransform = AffineMatrix.identity();\n }\n save() {\n this._transforms.push(this._currentTransform);\n this._currentTransform = this._currentTransform.clone();\n }\n restore() {\n this._currentTransform = this._transforms.pop();\n }\n translate(x, y) {\n return this._currentTransform.translate(x, y);\n }\n rotate(angle) {\n return this._currentTransform.rotate(angle);\n }\n scale(x, y) {\n return this._currentTransform.scale(x, y);\n }\n set current(matrix) {\n this._currentTransform = matrix;\n }\n get current() {\n return this._currentTransform;\n }\n }\n class StateStack {\n constructor(){\n this._states = [];\n this._currentState = this._getDefaultState();\n }\n _getDefaultState() {\n return {\n opacity: 1,\n z: 0,\n tint: Color.White,\n material: null\n };\n }\n _cloneState() {\n return {\n opacity: this._currentState.opacity,\n z: this._currentState.z,\n tint: this._currentState.tint.clone(),\n material: this._currentState.material // TODO is this going to cause problems when cloning\n };\n }\n save() {\n this._states.push(this._currentState);\n this._currentState = this._cloneState();\n }\n restore() {\n this._currentState = this._states.pop();\n }\n get current() {\n return this._currentState;\n }\n set current(val) {\n this._currentState = val;\n }\n }\n const ResourceEvents = {\n Complete: \"complete\",\n Load: \"load\",\n LoadStart: \"loadstart\",\n Progress: \"progress\",\n Error: \"error\"\n };\n /**\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\n */ class Resource {\n /**\n * @param path Path to the remote resource\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\n * @param bustCache Whether or not to cache-bust requests\n */ constructor(path, responseType, bustCache = false){\n this.path = path;\n this.responseType = responseType;\n this.bustCache = bustCache;\n this.data = null;\n this.logger = Logger.getInstance();\n this.events = new EventEmitter();\n }\n /**\n * Returns true if the Resource is completely loaded and is ready\n * to be drawn.\n */ isLoaded() {\n return this.data !== null;\n }\n _cacheBust(uri) {\n const query = /\\?\\w*=\\w*/;\n if (query.test(uri)) uri += \"&__=\" + Date.now();\n else uri += \"?__=\" + Date.now();\n return uri;\n }\n /**\n * Begin loading the resource and returns a promise to be resolved on completion\n */ load() {\n return new Promise((resolve, reject)=>{\n // Exit early if we already have data\n if (this.data !== null) {\n this.logger.debug(\"Already have data for resource\", this.path);\n this.events.emit(\"complete\", this.data);\n resolve(this.data);\n return;\n }\n const request = new XMLHttpRequest();\n request.open(\"GET\", this.bustCache ? this._cacheBust(this.path) : this.path, true);\n request.responseType = this.responseType;\n request.addEventListener(\"loadstart\", (e)=>this.events.emit(\"loadstart\", e));\n request.addEventListener(\"progress\", (e)=>this.events.emit(\"progress\", e));\n request.addEventListener(\"error\", (e)=>this.events.emit(\"error\", e));\n request.addEventListener(\"load\", (e)=>this.events.emit(\"load\", e));\n request.addEventListener(\"load\", ()=>{\n // XHR on file:// success status is 0, such as with PhantomJS\n if (request.status !== 0 && request.status !== 200) {\n this.logger.error(\"Failed to load resource \", this.path, \" server responded with error code\", request.status);\n this.events.emit(\"error\", request.response);\n reject(new Error(request.statusText));\n return;\n }\n this.data = request.response;\n this.events.emit(\"complete\", this.data);\n this.logger.debug(\"Completed loading resource\", this.path);\n resolve(this.data);\n });\n request.send();\n });\n }\n }\n /**\n * Watch an object with a proxy, only fires if property value is different\n */ function watch(type, change) {\n if (!type) return type;\n if (type.__isProxy === undefined) // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value)=>{\n // The default behavior to store the value\n if (obj[prop] !== value) {\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === \"string\") {\n if (prop[0] !== \"_\") change(obj);\n }\n }\n // Indicate success\n return true;\n },\n get: (obj, prop)=>{\n if (prop !== \"__isProxy\") return obj[prop];\n return true;\n }\n });\n return type;\n }\n const createHandler = (path = [], change, typeType)=>({\n get: (target, key)=>{\n if (key === \"__isProxy\") return true;\n if (typeof target[key] === \"object\" && target[key] != null) return new Proxy(target[key], createHandler([\n ...path,\n key\n ], change, typeType));\n return target[key];\n },\n set: (target, key, value)=>{\n if (typeof key === \"string\") {\n if (key[0] !== \"_\") change(typeType);\n }\n target[key] = value;\n return true;\n }\n });\n /**\n *\n */ function watchDeep(type, change) {\n if (!type) return type;\n if (type.__isProxy === undefined) // expando hack to mark a proxy\n return new Proxy(type, createHandler([], change, type));\n return type;\n }\n /**\n * Watch an object with a proxy, fires change on any property value change\n */ function watchAny(type, change) {\n if (!type) return type;\n if (type.__isProxy === undefined) // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value)=>{\n // The default behavior to store the value\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === \"string\") {\n if (prop[0] !== \"_\") change(obj);\n }\n // Indicate success\n return true;\n },\n get: (obj, prop)=>{\n if (prop !== \"__isProxy\") return obj[prop];\n return true;\n }\n });\n return type;\n }\n /**\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\n * [[Graphic]] abstract class.\n *\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\n */ class Graphic {\n isStale() {\n return this._transformStale;\n }\n /**\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\n */ get flipHorizontal() {\n return this._flipHorizontal;\n }\n set flipHorizontal(value) {\n this._flipHorizontal = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\n */ get flipVertical() {\n return this._flipVertical;\n }\n set flipVertical(value) {\n this._flipVertical = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the rotation of the graphic\n */ get rotation() {\n return this._rotation;\n }\n set rotation(value) {\n this._rotation = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the scale of the graphic, this affects the width and\n */ get scale() {\n return this._scale;\n }\n set scale(value) {\n this._scale = watch(value, ()=>{\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n /**\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\n */ get origin() {\n return this._origin;\n }\n set origin(value) {\n this._origin = watch(value, ()=>{\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n constructor(options){\n var _a, _b, _c, _d, _e, _f, _g;\n this.id = Graphic._ID++;\n this.transform = AffineMatrix.identity();\n this.tint = null;\n this._transformStale = true;\n /**\n * Gets or sets wether to show debug information about the graphic\n */ this.showDebug = false;\n this._flipHorizontal = false;\n this._flipVertical = false;\n this._rotation = 0;\n /**\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\n */ this.opacity = 1;\n this._scale = Vector.One;\n this._origin = null;\n this._width = 0;\n this._height = 0;\n if (options) {\n this.origin = (_a = options.origin) !== null && _a !== void 0 ? _a : this.origin;\n this.flipHorizontal = (_b = options.flipHorizontal) !== null && _b !== void 0 ? _b : this.flipHorizontal;\n this.flipVertical = (_c = options.flipVertical) !== null && _c !== void 0 ? _c : this.flipVertical;\n this.rotation = (_d = options.rotation) !== null && _d !== void 0 ? _d : this.rotation;\n this.opacity = (_e = options.opacity) !== null && _e !== void 0 ? _e : this.opacity;\n this.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : this.scale;\n this.tint = (_g = options.tint) !== null && _g !== void 0 ? _g : this.tint;\n }\n }\n cloneGraphicOptions() {\n return {\n width: this.width / this.scale.x,\n height: this.height / this.scale.y,\n origin: this.origin ? this.origin.clone() : null,\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n rotation: this.rotation,\n opacity: this.opacity,\n scale: this.scale ? this.scale.clone() : null,\n tint: this.tint ? this.tint.clone() : null\n };\n }\n /**\n * Gets or sets the width of the graphic (always positive)\n */ get width() {\n return Math.abs(this._width * this.scale.x);\n }\n /**\n * Gets or sets the height of the graphic (always positive)\n */ get height() {\n return Math.abs(this._height * this.scale.y);\n }\n set width(value) {\n this._width = value;\n this._transformStale = true;\n }\n set height(value) {\n this._height = value;\n this._transformStale = true;\n }\n /**\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\n */ get localBounds() {\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\n }\n /**\n * Draw the whole graphic to the context including transform\n * @param ex The excalibur graphics context\n * @param x\n * @param y\n */ draw(ex, x, y) {\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0);\n this._postDraw(ex);\n }\n /**\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\n * @param ex\n * @param x\n * @param y\n */ _preDraw(ex, x, y) {\n ex.save();\n ex.translate(x, y);\n if (this._transformStale) {\n this.transform.reset();\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\n this._rotate(this.transform);\n this._flip(this.transform);\n this._transformStale = false;\n }\n ex.multiply(this.transform);\n // it is important to multiply alphas so graphics respect the current context\n ex.opacity = ex.opacity * this.opacity;\n if (this.tint) ex.tint = this.tint;\n }\n _rotate(ex) {\n var _a;\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : vec(this.width / 2, this.height / 2);\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\n ex.scale(scaleDirX, scaleDirY);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, this.height / this.scale.y);\n ex.scale(1, -1);\n }\n }\n /**\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\n * @param ex\n */ _postDraw(ex) {\n if (this.showDebug) ex.debug.drawRect(0, 0, this.width, this.height);\n ex.restore();\n }\n }\n Graphic._ID = 0;\n class Sprite extends Graphic {\n static from(image) {\n return new Sprite({\n image: image\n });\n }\n constructor(options){\n var _a, _b;\n super(options);\n this._logger = Logger.getInstance();\n this._dirty = true;\n this.image = options.image;\n const { width: width, height: height } = options;\n this.sourceView = (_a = options.sourceView) !== null && _a !== void 0 ? _a : {\n x: 0,\n y: 0,\n width: width !== null && width !== void 0 ? width : 0,\n height: height !== null && height !== void 0 ? height : 0\n };\n this.destSize = (_b = options.destSize) !== null && _b !== void 0 ? _b : {\n width: width !== null && width !== void 0 ? width : 0,\n height: height !== null && height !== void 0 ? height : 0\n };\n this._updateSpriteDimensions();\n // Fire when loaded\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.image.ready.then(()=>{\n this._updateSpriteDimensions();\n });\n }\n get width() {\n return Math.abs(this.destSize.width * this.scale.x);\n }\n get height() {\n return Math.abs(this.destSize.height * this.scale.y);\n }\n set width(newWidth) {\n newWidth /= Math.abs(this.scale.x);\n this.destSize.width = newWidth;\n super.width = Math.ceil(this.destSize.width);\n }\n set height(newHeight) {\n newHeight /= Math.abs(this.scale.y);\n this.destSize.height = newHeight;\n super.height = Math.ceil(this.destSize.height);\n }\n _updateSpriteDimensions() {\n var _a, _b, _c, _d, _e, _f;\n const { width: nativeWidth, height: nativeHeight } = this.image;\n // This code uses || to avoid 0's\n // If the source is not specified, use the native dimension\n this.sourceView.width = ((_a = this.sourceView) === null || _a === void 0 ? void 0 : _a.width) || nativeWidth;\n this.sourceView.height = ((_b = this.sourceView) === null || _b === void 0 ? void 0 : _b.height) || nativeHeight;\n // If the destination is not specified, use the source if specified, then native\n this.destSize.width = ((_c = this.destSize) === null || _c === void 0 ? void 0 : _c.width) || ((_d = this.sourceView) === null || _d === void 0 ? void 0 : _d.width) || nativeWidth;\n this.destSize.height = ((_e = this.destSize) === null || _e === void 0 ? void 0 : _e.height) || ((_f = this.sourceView) === null || _f === void 0 ? void 0 : _f.height) || nativeHeight;\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\n }\n _preDraw(ex, x, y) {\n if (this.image.isLoaded() && this._dirty) {\n this._dirty = false;\n this._updateSpriteDimensions();\n }\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n if (this.image.isLoaded()) ex.drawImage(this.image.image, this.sourceView.x, this.sourceView.y, this.sourceView.width, this.sourceView.height, x, y, this.destSize.width, this.destSize.height);\n else this._logger.warnOnce(`ImageSource ${this.image.path}` + ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` + `Read https://excaliburjs.com/docs/imagesource for more information.`);\n }\n clone() {\n return new Sprite({\n image: this.image,\n sourceView: {\n ...this.sourceView\n },\n destSize: {\n ...this.destSize\n },\n ...this.cloneGraphicOptions()\n });\n }\n }\n /**\n * Describes the different image filtering modes\n */ var ImageFiltering;\n (function(ImageFiltering) {\n /**\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\n *\n * Useful for Pixel art aesthetics.\n */ ImageFiltering[\"Pixel\"] = \"Pixel\";\n /**\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\n */ ImageFiltering[\"Blended\"] = \"Blended\";\n })(ImageFiltering || (ImageFiltering = {}));\n /**\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\n */ class TextureLoader {\n constructor(gl){\n this._textureMap = new Map();\n this._gl = gl;\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n dispose() {\n for (const [image] of this._textureMap)this.delete(image);\n this._textureMap.clear();\n this._gl = null;\n }\n /**\n * Get the WebGL Texture from a source image\n * @param image\n */ get(image) {\n return this._textureMap.get(image);\n }\n /**\n * Returns whether a source image has been loaded as a texture\n * @param image\n */ has(image) {\n return this._textureMap.has(image);\n }\n /**\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\n * @param image Source graphic\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\n */ load(image, filtering, forceUpdate = false) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) return null;\n let tex = null;\n // If reuse the texture if it's from the same source\n if (this.has(image)) tex = this.get(image);\n // Update existing webgl texture and return early\n if (tex) {\n if (forceUpdate) {\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n }\n return tex;\n }\n // No texture exists create a new one\n tex = gl.createTexture();\n // TODO implement texture gc with weakmap and timer\n TextureLoader.checkImageSizeSupportedAndLog(image);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n // TODO make configurable\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // NEAREST for pixel art, LINEAR for hi-res\n const filterMode = filtering !== null && filtering !== void 0 ? filtering : TextureLoader.filtering;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n this._textureMap.set(image, tex);\n return tex;\n }\n delete(image) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) return null;\n let tex = null;\n if (this.has(image)) {\n tex = this.get(image);\n gl.deleteTexture(tex);\n }\n }\n /**\n * Takes an image and returns if it meets size criteria for hardware\n * @param image\n * @returns if the image will be supported at runtime\n */ static checkImageSizeSupportedAndLog(image) {\n var _a;\n const originalSrc = (_a = image.dataset.originalSrc) !== null && _a !== void 0 ? _a : \"internal canvas bitmap\";\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\n TextureLoader._LOGGER.error(`The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of ` + `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image ` + `for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n` + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n return false;\n } else if (image.width > 4096 || image.height > 4096) // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\n TextureLoader._LOGGER.warn(`The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, ` + `it is recommended you resize images to a maximum (4096x4096).\\n\\n` + `Images will likely render as black rectangles on some mobile platforms.\\n\\n` + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n return true;\n }\n }\n TextureLoader._LOGGER = Logger.getInstance();\n /**\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\n */ TextureLoader.filtering = ImageFiltering.Blended;\n TextureLoader._MAX_TEXTURE_SIZE = 4096;\n class ImageSource {\n /**\n * The original size of the source image in pixels\n */ get width() {\n return this.image.naturalWidth;\n }\n /**\n * The original height of the source image in pixels\n */ get height() {\n return this.image.naturalHeight;\n }\n /**\n * Returns true if the Texture is completely loaded and is ready\n * to be drawn.\n */ isLoaded() {\n if (!this._src) // this boosts speed of access\n this._src = this.data.src;\n return !!this._src;\n }\n get image() {\n return this.data;\n }\n /**\n * The path to the image, can also be a data url like 'data:image/'\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\n */ constructor(path, bustCache = false, filtering){\n this.path = path;\n this._logger = Logger.getInstance();\n /**\n * Access to the underlying html image element\n */ this.data = new Image();\n this._readyFuture = new Future();\n /**\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\n */ this.ready = this._readyFuture.promise;\n this._resource = new Resource(path, \"blob\", bustCache);\n this.filtering = filtering;\n if (path.endsWith(\".svg\") || path.endsWith(\".gif\")) this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\n }\n /**\n * Create an ImageSource from and HTML tag element\n * @param image\n */ static fromHtmlImageElement(image, options) {\n const imageSource = new ImageSource(\"\");\n imageSource._src = \"image-element\";\n imageSource.data = image;\n imageSource.data.setAttribute(\"data-original-src\", \"image-element\");\n if (options === null || options === void 0 ? void 0 : options.filtering) imageSource.data.setAttribute(\"filtering\", options === null || options === void 0 ? void 0 : options.filtering);\n else imageSource.data.setAttribute(\"filtering\", ImageFiltering.Blended);\n TextureLoader.checkImageSizeSupportedAndLog(image);\n imageSource._readyFuture.resolve(image);\n return imageSource;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * Begins loading the image and returns a promise that resolves when the image is loaded\n */ async load() {\n if (this.isLoaded()) return this.data;\n try {\n // Load base64 or blob if needed\n let url;\n if (!this.path.includes(\"data:image/\")) {\n const blob = await this._resource.load();\n url = URL.createObjectURL(blob);\n } else url = this.path;\n // Decode the image\n const image = new Image();\n // Use Image.onload over Image.decode()\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\n // Otherwise chrome will throw still Image.decode() failures for large textures\n const loadedFuture = new Future();\n image.onload = ()=>loadedFuture.resolve();\n image.src = url;\n image.setAttribute(\"data-original-src\", this.path);\n await loadedFuture.promise;\n // Set results\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\n // See image-renderer.ts draw()\n this.data = image;\n // emit warning if potentially too big\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\n } catch (error) {\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\n }\n // Do a bad thing to pass the filtering as an attribute\n this.data.setAttribute(\"filtering\", this.filtering);\n // todo emit complete\n this._readyFuture.resolve(this.data);\n return this.data;\n }\n /**\n * Build a sprite from this ImageSource\n */ toSprite() {\n return Sprite.from(this);\n }\n /**\n * Unload images from memory\n */ unload() {\n this.data = new Image();\n }\n }\n class SpriteFont extends Graphic {\n constructor(options){\n super(options);\n this._text = \"\";\n this.alphabet = \"\";\n this.shadow = null;\n this.caseInsensitive = false;\n this.spacing = 0;\n this.lineHeight = undefined;\n this._logger = Logger.getInstance();\n const { alphabet: alphabet, spriteSheet: spriteSheet, caseInsensitive: caseInsensitive, spacing: spacing, shadow: shadow, lineHeight: lineHeight } = options;\n this.alphabet = alphabet;\n this.spriteSheet = spriteSheet;\n this.caseInsensitive = caseInsensitive !== null && caseInsensitive !== void 0 ? caseInsensitive : this.caseInsensitive;\n this.spacing = spacing !== null && spacing !== void 0 ? spacing : this.spacing;\n this.shadow = shadow !== null && shadow !== void 0 ? shadow : this.shadow;\n this.lineHeight = lineHeight !== null && lineHeight !== void 0 ? lineHeight : this.lineHeight;\n }\n _getCharacterSprites(text) {\n const results = [];\n // handle case insensitive\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\n // for each letter in text\n for(let letterIndex = 0; letterIndex < textToRender.length; letterIndex++){\n // find the sprite index in alphabet , if there is an error pick the first\n const letter = textToRender[letterIndex];\n let spriteIndex = alphabet.indexOf(letter);\n if (spriteIndex === -1) {\n spriteIndex = 0;\n this._logger.warnOnce(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\n this._logger.warnOnce(\"There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.\");\n }\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\n if (letterSprite) results.push(letterSprite);\n else {\n this._logger.warnOnce(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\n this._logger.warnOnce(\"There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.\");\n }\n }\n return results;\n }\n measureText(text, maxWidth) {\n const lines = this._getLinesFromText(text, maxWidth);\n const maxWidthLine = lines.reduce((a, b)=>{\n return a.length > b.length ? a : b;\n });\n const sprites = this._getCharacterSprites(maxWidthLine);\n let width = 0;\n let height = 0;\n for (const sprite of sprites){\n width += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\n }\n _drawImage(ex, x, y, maxWidth) {\n var _a;\n let xCursor = 0;\n let yCursor = 0;\n let height = 0;\n const lines = this._getLinesFromText(this._text, maxWidth);\n for (const line of lines){\n for (const sprite of this._getCharacterSprites(line)){\n // draw it in the right spot and increase the cursor by sprite width\n sprite.draw(ex, x + xCursor, y + yCursor);\n xCursor += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n xCursor = 0;\n yCursor += (_a = this.lineHeight) !== null && _a !== void 0 ? _a : height;\n }\n }\n render(ex, text, _color, x, y, maxWidth) {\n // SpriteFont doesn't support _color, yet...\n this._text = text;\n const bounds = this.measureText(text, maxWidth);\n this.width = bounds.width;\n this.height = bounds.height;\n if (this.shadow) {\n ex.save();\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n ex.restore();\n }\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n }\n clone() {\n return new SpriteFont({\n alphabet: this.alphabet,\n spriteSheet: this.spriteSheet,\n spacing: this.spacing\n });\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) return this._cachedLines;\n const lines = text.split(\"\\n\");\n if (maxWidth == null) return lines;\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for(let i = 0; i < lines.length; i++){\n let line = lines[i];\n let newLine = \"\";\n // Note: we subtract the spacing to counter the initial padding on the left side.\n if (this.measureText(line).width > maxWidth) {\n while(this.measureText(line).width > maxWidth){\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n }\n /**\n * Represents a collection of sprites from a source image with some organization in a grid\n */ class SpriteSheet {\n /**\n * Build a new sprite sheet from a list of sprites\n *\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\n * @param options\n */ constructor(options){\n this.sprites = [];\n const { sprites: sprites, rows: rows, columns: columns } = options;\n this.sprites = sprites;\n this.rows = rows !== null && rows !== void 0 ? rows : 1;\n this.columns = columns !== null && columns !== void 0 ? columns : this.sprites.length;\n }\n /**\n * Find a sprite by their x/y integer coordinates in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\n * and `getSprite(1, 0)` is the sprite one to the right.\n * @param x\n * @param y\n */ getSprite(x, y, options) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n if (x >= this.columns || x < 0) throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\n if (y >= this.rows || y < 0) throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\n const spriteIndex = x + y * this.columns;\n const sprite = this.sprites[spriteIndex];\n if (sprite) {\n if (options) {\n const spriteWithOptions = sprite.clone();\n spriteWithOptions.flipHorizontal = (_a = options.flipHorizontal) !== null && _a !== void 0 ? _a : spriteWithOptions.flipHorizontal;\n spriteWithOptions.flipVertical = (_b = options.flipVertical) !== null && _b !== void 0 ? _b : spriteWithOptions.flipVertical;\n spriteWithOptions.width = (_c = options.width) !== null && _c !== void 0 ? _c : spriteWithOptions.width;\n spriteWithOptions.height = (_d = options.height) !== null && _d !== void 0 ? _d : spriteWithOptions.height;\n spriteWithOptions.rotation = (_e = options.rotation) !== null && _e !== void 0 ? _e : spriteWithOptions.rotation;\n spriteWithOptions.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : spriteWithOptions.scale;\n spriteWithOptions.opacity = (_g = options.opacity) !== null && _g !== void 0 ? _g : spriteWithOptions.opacity;\n spriteWithOptions.tint = (_h = options.tint) !== null && _h !== void 0 ? _h : spriteWithOptions.tint;\n spriteWithOptions.origin = (_j = options.origin) !== null && _j !== void 0 ? _j : spriteWithOptions.origin;\n return spriteWithOptions;\n }\n return sprite;\n }\n throw Error(`Invalid sprite coordinates (${x}, ${y}`);\n }\n /**\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\n * @param options\n */ static fromImageSourceWithSourceViews(options) {\n const sprites = options.sourceViews.map((sourceView)=>{\n return new Sprite({\n image: options.image,\n sourceView: sourceView\n });\n });\n return new SpriteSheet({\n sprites: sprites\n });\n }\n /**\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\n *\n * Example:\n * ```\n * const spriteSheet = SpriteSheet.fromImageSource({\n * image: imageSource,\n * grid: {\n * rows: 5,\n * columns: 2,\n * spriteWidth: 32, // pixels\n * spriteHeight: 32 // pixels\n * },\n * // Optionally specify spacing\n * spacing: {\n * // pixels from the top left to start the sprite parsing\n * originOffset: {\n * x: 5,\n * y: 5\n * },\n * // pixels between each sprite while parsing\n * margin: {\n * x: 1,\n * y: 1\n * }\n * }\n * })\n * ```\n * @param options\n */ static fromImageSource(options) {\n var _a;\n const sprites = [];\n options.spacing = (_a = options.spacing) !== null && _a !== void 0 ? _a : {};\n const { image: image, grid: { rows: rows, columns: cols, spriteWidth: spriteWidth, spriteHeight: spriteHeight }, spacing: { originOffset: originOffset, margin: margin } } = options;\n const offsetDefaults = {\n x: 0,\n y: 0,\n ...originOffset\n };\n const marginDefaults = {\n x: 0,\n y: 0,\n ...margin\n };\n for(let x = 0; x < cols; x++)for(let y = 0; y < rows; y++)sprites[x + y * cols] = new Sprite({\n image: image,\n sourceView: {\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\n width: spriteWidth,\n height: spriteHeight\n },\n destSize: {\n height: spriteHeight,\n width: spriteWidth\n }\n });\n return new SpriteSheet({\n sprites: sprites,\n rows: rows,\n columns: cols\n });\n }\n clone() {\n return new SpriteSheet({\n sprites: this.sprites.map((sprite)=>sprite.clone()),\n rows: this.rows,\n columns: this.columns\n });\n }\n }\n /* harmony default export */ const debug_font = \"data:image/png;base64,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\";\n /**\n * Internal debugtext helper\n */ class DebugText {\n constructor(){\n /**\n * base64 font\n */ this.fontSheet = debug_font;\n this.size = 16;\n // We fire and forget, we don't care if it's loaded or not\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.load();\n }\n load() {\n this._imageSource = new ImageSource(this.fontSheet);\n return this._imageSource.load().then(()=>{\n this._spriteSheet = SpriteSheet.fromImageSource({\n image: this._imageSource,\n grid: {\n rows: 4,\n columns: 16,\n spriteWidth: 16,\n spriteHeight: 16\n }\n });\n this._spriteFont = new SpriteFont({\n alphabet: \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!'&.\\\"?-()+# \",\n caseInsensitive: true,\n spriteSheet: this._spriteSheet,\n spacing: -6\n });\n });\n }\n /**\n * Writes debug text using the built in sprint font\n * @param ctx\n * @param text\n * @param pos\n */ write(ctx, text, pos) {\n if (this._imageSource.isLoaded()) this._spriteFont.render(ctx, text, null, pos.x, pos.y);\n }\n }\n class RenderSource {\n constructor(_gl, _texture){\n this._gl = _gl;\n this._texture = _texture;\n }\n use() {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\n }\n disable() {\n const gl = this._gl;\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n }\n class RenderTarget {\n constructor(options){\n var _a, _b;\n this.antialias = false;\n this.samples = 1;\n this._gl = options.gl;\n this.width = options.width;\n this.height = options.height;\n this.transparency = options.transparency;\n this.antialias = (_a = options.antialias) !== null && _a !== void 0 ? _a : this.antialias;\n this.samples = (_b = options.samples) !== null && _b !== void 0 ? _b : this._gl.getParameter(this._gl.MAX_SAMPLES);\n const gl = this._gl;\n // Determine current context format for blitting later needs to match\n if (gl.drawingBufferFormat) this.bufferFormat = gl.drawingBufferFormat;\n else // Documented in webgl spec\n // https://registry.khronos.org/webgl/specs/latest/1.0/\n if (this.transparency) this.bufferFormat = gl.RGBA8;\n else this.bufferFormat = gl.RGB8;\n this._setupRenderBuffer();\n this._setupFramebuffer();\n }\n setResolution(width, height) {\n const gl = this._gl;\n this.width = width;\n this.height = height;\n // update backing texture size\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // update render buffer size\n if (this._renderBuffer) {\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\n gl.renderbufferStorageMultisample(gl.RENDERBUFFER, Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, this.height);\n }\n }\n get renderBuffer() {\n return this._renderBuffer;\n }\n get renderFrameBuffer() {\n return this._renderFrameBuffer;\n }\n get frameBuffer() {\n return this._frameBuffer;\n }\n get frameTexture() {\n return this._frameTexture;\n }\n _setupRenderBuffer() {\n if (this.antialias) {\n const gl = this._gl;\n // Render buffers can be used as an input to a shader\n this._renderBuffer = gl.createRenderbuffer();\n this._renderFrameBuffer = gl.createFramebuffer();\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\n gl.renderbufferStorageMultisample(gl.RENDERBUFFER, Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, this.height);\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\n gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._renderBuffer);\n }\n }\n _setupFramebuffer() {\n // Allocates frame buffer\n const gl = this._gl;\n this._frameTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // set the filtering so we don't need mips\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // attach the texture as the first color attachment\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\n // After this bind all draw calls will draw to this framebuffer texture\n this._frameBuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\n // Reset after initialized\n this.disable();\n }\n toRenderSource() {\n if (this.renderBuffer) this.blitRenderBufferToFrameBuffer();\n const source = new RenderSource(this._gl, this._frameTexture);\n return source;\n }\n blitToScreen() {\n const gl = this._gl;\n // set to size of canvas's drawingBuffer\n if (this._renderBuffer) {\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.clearBufferfv(gl.COLOR, 0, [\n 0.0,\n 0.0,\n 1.0,\n 1.0\n ]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n } else {\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.frameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.clearBufferfv(gl.COLOR, 0, [\n 0.0,\n 0.0,\n 1.0,\n 1.0\n ]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n }\n blitRenderBufferToFrameBuffer() {\n if (this._renderBuffer) {\n const gl = this._gl;\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.frameBuffer);\n gl.clearBufferfv(gl.COLOR, 0, [\n 0.0,\n 0.0,\n 1.0,\n 1.0\n ]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n }\n copyToTexture(texture) {\n const gl = this._gl;\n if (this._renderBuffer) this.blitRenderBufferToFrameBuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, this.width, this.height, 0);\n }\n /**\n * When called, all drawing gets redirected to this render target\n */ use() {\n const gl = this._gl;\n if (this.antialias) gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\n else gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n // very important to set the viewport to the size of the framebuffer texture\n gl.viewport(0, 0, this.width, this.height);\n }\n /**\n * When called, all drawing is sent back to the canvas\n */ disable() {\n const gl = this._gl;\n // passing null switches rendering back to the canvas\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n }\n /* harmony default export */ const line_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\";\n /* harmony default export */ const line_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\";\n /**\n * Return the size of the GlType in bytes\n * @param gl\n * @param type\n */ function getGlTypeSizeBytes(gl, type) {\n switch(type){\n case gl.FLOAT:\n return 4;\n case gl.SHORT:\n return 2;\n case gl.UNSIGNED_SHORT:\n return 2;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n default:\n return 1;\n }\n }\n /**\n * Based on the type return the number of attribute components\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\n * @param gl\n * @param type\n */ function getAttributeComponentSize(gl, type) {\n switch(type){\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n return 1;\n case gl.FLOAT_VEC2:\n return 2;\n case gl.FLOAT_VEC3:\n return 3;\n case gl.FLOAT_VEC4:\n return 4;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n case gl.UNSIGNED_SHORT:\n case gl.SHORT:\n return 1;\n default:\n return 1;\n }\n }\n /**\n * Based on the attribute return the corresponding supported attrib pointer type\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\n * @param gl\n * @param type\n */ function getAttributePointerType(gl, type) {\n switch(type){\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n case gl.FLOAT_VEC2:\n case gl.FLOAT_VEC3:\n case gl.FLOAT_VEC4:\n return gl.FLOAT;\n case gl.BYTE:\n return gl.BYTE;\n case gl.UNSIGNED_BYTE:\n return gl.UNSIGNED_BYTE;\n case gl.SHORT:\n return gl.SHORT;\n case gl.UNSIGNED_SHORT:\n return gl.UNSIGNED_SHORT;\n default:\n return gl.FLOAT;\n }\n }\n class Shader {\n get compiled() {\n return this._compiled;\n }\n /**\n * Create a shader program in excalibur\n * @param options specify shader vertex and fragment source\n */ constructor(options){\n this._logger = Logger.getInstance();\n this.uniforms = {};\n this.attributes = {};\n this._compiled = false;\n const { gl: gl, vertexSource: vertexSource, fragmentSource: fragmentSource } = options;\n this._gl = gl;\n this.vertexSource = vertexSource;\n this.fragmentSource = fragmentSource;\n }\n dispose() {\n const gl = this._gl;\n gl.deleteProgram(this.program);\n this._gl = null;\n }\n /**\n * Binds the shader program\n */ use() {\n const gl = this._gl;\n gl.useProgram(this.program);\n Shader._ACTIVE_SHADER_INSTANCE = this;\n }\n isCurrentlyBound() {\n return Shader._ACTIVE_SHADER_INSTANCE === this;\n }\n /**\n * Compile the current shader against a webgl context\n */ compile() {\n const gl = this._gl;\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\n const attributes = this.getAttributes();\n for (const attribute of attributes)this.attributes[attribute.name] = attribute;\n const uniforms = this.getUniforms();\n for (const uniform of uniforms)this.uniforms[uniform.name] = uniform;\n this._compiled = true;\n return this.program;\n }\n getUniforms() {\n const gl = this._gl;\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\n const uniforms = [];\n for(let i = 0; i < uniformCount; i++){\n const uniform = gl.getActiveUniform(this.program, i);\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\n uniforms.push({\n name: uniform.name,\n glType: uniform.type,\n location: uniformLocation\n });\n }\n return uniforms;\n }\n getAttributes() {\n const gl = this._gl;\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\n const attributes = [];\n for(let i = 0; i < attributeCount; i++){\n const attribute = gl.getActiveAttrib(this.program, i);\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\n attributes.push({\n name: attribute.name,\n glType: getAttributePointerType(gl, attribute.type),\n size: getAttributeComponentSize(gl, attribute.type),\n location: attributeLocation,\n normalized: false\n });\n }\n return attributes;\n }\n /**\n * Set a texture in a gpu texture slot\n * @param slotNumber\n * @param texture\n */ setTexture(slotNumber, texture) {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n }\n /**\n * Set an integer uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformInt(name, value) {\n this.setUniform(\"uniform1i\", name, ~~value);\n }\n /**\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformInt(name, value) {\n return this.trySetUniform(\"uniform1i\", name, ~~value);\n }\n /**\n * Set an integer array uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformIntArray(name, value) {\n this.setUniform(\"uniform1iv\", name, value);\n }\n /**\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformIntArray(name, value) {\n return this.trySetUniform(\"uniform1iv\", name, value);\n }\n /**\n * Set a boolean uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformBoolean(name, value) {\n this.setUniform(\"uniform1i\", name, value ? 1 : 0);\n }\n /**\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformBoolean(name, value) {\n return this.trySetUniform(\"uniform1i\", name, value ? 1 : 0);\n }\n /**\n * Set a float uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformFloat(name, value) {\n this.setUniform(\"uniform1f\", name, value);\n }\n /**\n * Set a float uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformFloat(name, value) {\n return this.trySetUniform(\"uniform1f\", name, value);\n }\n /**\n * Set a float array uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformFloatArray(name, value) {\n this.setUniform(\"uniform1fv\", name, value);\n }\n /**\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformFloatArray(name, value) {\n return this.trySetUniform(\"uniform1fv\", name, value);\n }\n /**\n * Set a [[Vector]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformFloatVector(name, value) {\n this.setUniform(\"uniform2f\", name, value.x, value.y);\n }\n /**\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformFloatVector(name, value) {\n return this.trySetUniform(\"uniform2f\", name, value.x, value.y);\n }\n /**\n * Set a [[Color]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformFloatColor(name, value) {\n this.setUniform(\"uniform4f\", name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformFloatColor(name, value) {\n return this.trySetUniform(\"uniform4f\", name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\n * Set an [[Matrix]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformMatrix(name, value) {\n this.setUniform(\"uniformMatrix4fv\", name, false, value.data);\n }\n /**\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformMatrix(name, value) {\n return this.trySetUniform(\"uniformMatrix4fv\", name, false, value.data);\n }\n /**\n * Set any available uniform type in webgl\n *\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\n */ setUniform(uniformType, name, ...value) {\n if (!this._compiled) throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n if (!this.isCurrentlyBound()) throw Error(\"Currently accessed shader instance is not the current active shader in WebGL, must call `shader.use()` before setting uniforms\");\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [\n location,\n ...value\n ];\n this._gl[uniformType].apply(this._gl, args);\n } else throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,` + \" unused uniforms are optimized away by most browsers\");\n }\n /**\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\n * true if it was set.\n *\n * WILL NOT THROW on error\n *\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\n *\n */ trySetUniform(uniformType, name, ...value) {\n if (!this._compiled) {\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n return false;\n }\n if (!this.isCurrentlyBound()) {\n this._logger.warn(\"Currently accessed shader instance is not the current active shader in WebGL, must call `shader.use()` before setting uniforms\");\n return false;\n }\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [\n location,\n ...value\n ];\n this._gl[uniformType].apply(this._gl, args);\n } else return false;\n return true;\n }\n _createProgram(gl, vertexShader, fragmentShader) {\n const program = gl.createProgram();\n if (program === null) throw Error(\"Could not create graphics shader program\");\n // attach the shaders.\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n // link the program.\n gl.linkProgram(program);\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n if (!success) throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\n return program;\n }\n _compileShader(gl, source, type) {\n const typeName = gl.VERTEX_SHADER === type ? \"vertex\" : \"fragment\";\n const shader = gl.createShader(type);\n if (shader === null) throw Error(`Could not build shader: [${source}]`);\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (!success) {\n const errorInfo = gl.getShaderInfoLog(shader);\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\n }\n return shader;\n }\n _processSourceForError(source, errorInfo) {\n if (!source) return errorInfo;\n const lines = source.split(\"\\n\");\n const errorLineStart = errorInfo.search(/\\d:\\d/);\n const errorLineEnd = errorInfo.indexOf(\" \", errorLineStart);\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(\":\").map((v)=>Number(v));\n for(let i = 0; i < lines.length; i++)lines[i] = `${i + 1}: ${lines[i]}${error2 === i + 1 ? \" <----- ERROR!\" : \"\"}`;\n return \"\\n\\nSource:\\n\" + lines.join(\"\\n\");\n }\n }\n Shader._ACTIVE_SHADER_INSTANCE = null;\n /**\n * Helper around vertex buffer to simplify creating and uploading geometry\n *\n * Under the hood uses Float32Array\n */ class VertexBuffer {\n constructor(options){\n /**\n * If the vertices never change switching 'static' can be more efficient on the gpu\n *\n * Default is 'dynamic'\n */ this.type = \"dynamic\";\n const { gl: gl, size: size, type: type, data: data } = options;\n this._gl = gl;\n this.buffer = this._gl.createBuffer();\n if (!data && !size) throw Error(\"Must either provide data or a size to the VertexBuffer\");\n if (!data) this.bufferData = new Float32Array(size);\n else this.bufferData = data;\n this.type = type !== null && type !== void 0 ? type : this.type;\n // Allocate buffer\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === \"static\" ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n /**\n * Bind this vertex buffer\n */ bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n }\n /**\n * Upload vertex buffer geometry to the GPU\n */ upload(count) {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n if (count) gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\n else // TODO always use bufferSubData? need to perf test it\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === \"static\" ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n dispose() {\n const gl = this._gl;\n gl.deleteBuffer(this.buffer);\n this._gl = null;\n }\n }\n /**\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\n * the memory layout for your vertices inside a particular buffer\n *\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\n *\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\n */ class VertexLayout {\n get vertexBuffer() {\n return this._vertexBuffer;\n }\n get attributes() {\n return this._attributes;\n }\n constructor(options){\n this._logger = Logger.getInstance();\n this._layout = [];\n this._attributes = [];\n this._vertexTotalSizeBytes = 0;\n const { gl: gl, shader: shader, vertexBuffer: vertexBuffer, attributes: attributes } = options;\n this._gl = gl;\n this._vertexBuffer = vertexBuffer;\n this._attributes = attributes;\n this._shader = shader;\n if (shader) this.initialize();\n }\n /**\n * Total number of bytes that the vertex will take up\n */ get totalVertexSizeBytes() {\n return this._vertexTotalSizeBytes;\n }\n set shader(shader) {\n if (shader && this._shader !== shader) {\n this._shader = shader;\n this.initialize();\n }\n }\n get shader() {\n return this._shader;\n }\n /**\n * Layouts need shader locations and must be bound to a shader\n */ initialize() {\n if (!this._shader) return;\n if (!this._shader.compiled) throw Error(\"Shader not compiled, shader must be compiled before defining a vertex layout\");\n this._vertexTotalSizeBytes = 0;\n this._layout.length = 0;\n const shaderAttributes = this._shader.attributes;\n for (const attribute of this._attributes){\n const attrib = shaderAttributes[attribute[0]];\n if (!attrib) throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}` + ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\n if (attrib.size !== attribute[1]) throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],` + ` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\n this._layout.push(attrib);\n }\n // calc size\n let componentsPerVertex = 0;\n for (const vertAttribute of this._layout){\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\n componentsPerVertex += vertAttribute.size;\n }\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) this._logger.warn(`The vertex component size (${componentsPerVertex}) does NOT divide evenly into the specified vertex buffer` + ` (${this._vertexBuffer.bufferData.length})`);\n }\n /**\n * Bind this layout with it's associated vertex buffer\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\n */ use(uploadBuffer = false, count) {\n if (!this._shader) throw Error(\"No shader is associated with this vertex layout, a shader must be set\");\n const gl = this._gl;\n if (!this._shader.isCurrentlyBound()) throw Error(\"Shader associated with this vertex layout is not active! Call shader.use() before layout.use()\");\n this._vertexBuffer.bind();\n if (uploadBuffer) this._vertexBuffer.upload(count);\n let offset = 0;\n // TODO switch to VAOs if the extension is\n for (const vert of this._layout){\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\n gl.enableVertexAttribArray(vert.location);\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\n }\n }\n }\n class GraphicsDiagnostics {\n static clear() {\n GraphicsDiagnostics.DrawCallCount = 0;\n GraphicsDiagnostics.DrawnImagesCount = 0;\n }\n }\n GraphicsDiagnostics.DrawCallCount = 0;\n GraphicsDiagnostics.DrawnImagesCount = 0;\n class LineRenderer {\n constructor(){\n this.type = \"ex.line\";\n this.priority = 0;\n this._maxLines = 10922;\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n vertexSource: line_vertex,\n fragmentSource: line_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n this._vertexBuffer = new VertexBuffer({\n gl: gl,\n size: 12 * this._maxLines,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n vertexBuffer: this._vertexBuffer,\n shader: this._shader,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_color\",\n 4\n ]\n ]\n });\n }\n dispose() {\n this._vertexBuffer.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n draw(start, end, color) {\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._lineCount++;\n const transform = this._context.getTransform();\n const finalStart = transform.multiply(start);\n const finalEnd = transform.multiply(end);\n const vertexBuffer = this._vertexBuffer.bufferData;\n // Start\n vertexBuffer[this._vertexIndex++] = finalStart.x;\n vertexBuffer[this._vertexIndex++] = finalStart.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n // End\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n }\n _isFull() {\n if (this._lineCount >= this._maxLines) return true;\n return false;\n }\n hasPendingDraws() {\n return this._lineCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._lineCount === 0) return;\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\n GraphicsDiagnostics.DrawCallCount++;\n // reset\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n }\n /* harmony default export */ const point_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\";\n /* harmony default export */ const point_fragment = '#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \"premultiply\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}';\n class PointRenderer {\n constructor(){\n this.type = \"ex.point\";\n this.priority = 0;\n this._maxPoints = 10922;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n vertexSource: point_vertex,\n fragmentSource: point_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 7 * this._maxPoints,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_size\",\n 1\n ]\n ]\n });\n }\n dispose() {\n this._buffer.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n draw(point, color, size) {\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._pointCount++;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const finalPoint = transform.multiply(point);\n if (snapToPixel) {\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\n }\n const vertexBuffer = this._buffer.bufferData;\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\n }\n _isFull() {\n if (this._pointCount >= this._maxPoints) return true;\n return false;\n }\n hasPendingDraws() {\n return this._pointCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._pointCount === 0) return;\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\n GraphicsDiagnostics.DrawCallCount++;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n }\n /* harmony default export */ const screen_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\";\n /* harmony default export */ const screen_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\";\n /**\n * This is responsible for painting the entire screen during the render passes\n */ class ScreenPassPainter {\n constructor(gl){\n this._gl = gl;\n this._shader = new Shader({\n gl: gl,\n vertexSource: screen_vertex,\n fragmentSource: screen_fragment\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n type: \"static\",\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1,\n -1,\n 0,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n -1,\n 1,\n 0,\n 1,\n -1,\n 1,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n 1,\n 1,\n 1\n ])\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_texcoord\",\n 2\n ]\n ]\n });\n this._buffer.upload();\n }\n renderWithPostProcessor(postprocessor) {\n const gl = this._gl;\n postprocessor.getShader().use();\n postprocessor.getLayout().use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n renderToScreen() {\n const gl = this._gl;\n this._shader.use();\n this._layout.use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n }\n /**\n * Helper that defines and index buffer for quad geometry\n *\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\n * it is almost always worth it in terms of performance to use an index buffer.\n */ class QuadIndexBuffer {\n /**\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\n * @param numberOfQuads Specify the max number of quads you want to draw\n * @param useUint16 Optionally force a uint16 buffer\n */ constructor(gl, numberOfQuads, useUint16){\n this._logger = Logger.getInstance();\n this._gl = gl;\n this.buffer = gl.createBuffer();\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n const totalVertices = numberOfQuads * 6;\n if (!useUint16) this.bufferData = new Uint32Array(totalVertices);\n else {\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\n const maxUint16 = 65535;\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\n this.bufferGlType = gl.UNSIGNED_SHORT;\n this.bufferData = new Uint16Array(totalVertices);\n // TODO Should we error if this happens?? maybe not might crash mid game\n if (numberOfQuads > maxUint16Index) this._logger.warn(`Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\n }\n let currentQuad = 0;\n for(let i = 0; i < totalVertices; i += 6){\n // first triangle\n this.bufferData[i + 0] = currentQuad + 0;\n this.bufferData[i + 1] = currentQuad + 1;\n this.bufferData[i + 2] = currentQuad + 2;\n // second triangle\n this.bufferData[i + 3] = currentQuad + 2;\n this.bufferData[i + 4] = currentQuad + 1;\n this.bufferData[i + 5] = currentQuad + 3;\n currentQuad += 4;\n }\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n get size() {\n return this.bufferData.length;\n }\n /**\n * Upload data to the GPU\n */ upload() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n /**\n * Bind this index buffer\n */ bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n }\n dispose() {\n const gl = this._gl;\n gl.deleteBuffer(this.buffer);\n this._gl = null;\n }\n }\n /* harmony default export */ const image_renderer_frag = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\nuniform bool u_pixelart;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nin vec2 v_res;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\n// Inigo Quilez pixel art filter https://jorenjoestar.github.io/post/pixel_art_filtering/\\r\\nvec2 uv_iq(in vec2 uv, in vec2 texture_size) {\\r\\n vec2 pixel = uv * texture_size;\\r\\n \\r\\n vec2 seam=floor(pixel+.5);\\r\\n vec2 dudv=fwidth(pixel);\\r\\n pixel=seam+clamp((pixel-seam)/dudv,-.5,.5);\\r\\n \\r\\n return pixel/texture_size;\\r\\n}\\r\\n\\r\\nvoid main(){\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n \\r\\n vec4 color=vec4(1.,0,0,1.);\\r\\n \\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n \\r\\n color.rgb=color.rgb*v_opacity;\\r\\n color.a=color.a*v_opacity;\\r\\n fragColor=color*v_tint;\\r\\n}\";\n /* harmony default export */ const image_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity\\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture res\\r\\nin vec2 a_res;\\r\\nout vec2 v_res;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main(){\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position=u_matrix*vec4(a_position,0.,1.);\\r\\n \\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity=a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord=a_texcoord;\\r\\n\\r\\n v_res = a_res;\\r\\n\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex=a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint=a_tint;\\r\\n}\";\n class ImageRenderer {\n constructor(options){\n this.type = \"ex.image\";\n this.priority = 0;\n this._maxImages = 10922; // max(uint16) / 6 verts\n this._maxTextures = 0;\n // Per flush vars\n this._imageCount = 0;\n this._textures = [];\n this._vertexIndex = 0;\n this.pixelArtSampler = options.pixelArtSampler;\n this.uvPadding = options.uvPadding;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Transform shader source\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\n const transformedFrag = this._transformFragmentSource(image_renderer_frag, this._maxTextures);\n // Compile shader\n this._shader = new Shader({\n gl: gl,\n fragmentSource: transformedFrag,\n vertexSource: image_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\n this._shader.setUniformIntArray(\"u_textures\", [\n ...Array(this._maxTextures)\n ].map((_, i)=>i));\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 48 * this._maxImages,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_res\",\n 2\n ],\n [\n \"a_texcoord\",\n 2\n ],\n [\n \"a_textureIndex\",\n 1\n ],\n [\n \"a_tint\",\n 4\n ]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._textures.length = 0;\n this._context = null;\n this._gl = null;\n }\n _transformFragmentSource(source, maxTextures) {\n let newSource = source.replace(\"%%count%%\", maxTextures.toString());\n let texturePickerBuilder = \"\";\n for(let i = 0; i < maxTextures; i++){\n if (i === 0) texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\n else texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\n texturePickerBuilder += ` vec2 uv = u_pixelart ? uv_iq(v_texcoord, v_res) : v_texcoord;\\n`;\n texturePickerBuilder += ` color = texture(u_textures[${i}], uv);\\n`;\n texturePickerBuilder += ` }\\n`;\n }\n newSource = newSource.replace(\"%%texture_picker%%\", texturePickerBuilder);\n return newSource;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute(\"filtering\");\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended || maybeFiltering === ImageFiltering.Pixel) filtering = maybeFiltering;\n const force = image.getAttribute(\"forceUpload\") === \"true\" ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute(\"forceUpload\");\n if (this._textures.indexOf(texture) === -1) this._textures.push(texture);\n }\n _bindTextures(gl) {\n // Bind textures in the correct order\n for(let i = 0; i < this._maxTextures; i++){\n gl.activeTexture(gl.TEXTURE0 + i);\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\n }\n }\n _getTextureIdForImage(image) {\n if (image) {\n const maybeTexture = this._context.textureLoader.get(image);\n return this._textures.indexOf(maybeTexture);\n }\n return -1;\n }\n _isFull() {\n if (this._imageCount >= this._maxImages) return true;\n if (this._textures.length >= this._maxTextures) return true;\n return false;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._imageCount++;\n // This creates and uploads the texture if not already done\n this._addImageAsTexture(image);\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [\n 0,\n 0,\n (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0,\n (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0\n ];\n let dest = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1\n ];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1,\n (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0,\n (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0\n ];\n dest = [\n dx,\n dy\n ];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n let topLeft = vec(dest[0], dest[1]);\n let topRight = vec(dest[0] + width, dest[1]);\n let bottomLeft = vec(dest[0], dest[1] + height);\n let bottomRight = vec(dest[0] + width, dest[1] + height);\n topLeft = transform.multiply(topLeft);\n topRight = transform.multiply(topRight);\n bottomLeft = transform.multiply(bottomLeft);\n bottomRight = transform.multiply(bottomRight);\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + sign(topLeft.x) * pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + sign(topLeft.y) * pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + sign(topRight.x) * pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + sign(topRight.y) * pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + sign(bottomLeft.x) * pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + sign(bottomLeft.y) * pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + sign(bottomRight.x) * pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + sign(bottomRight.y) * pixelSnapEpsilon);\n }\n const tint = this._context.tint;\n const textureId = this._getTextureIdForImage(image);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = (sx + this.uvPadding) / imageWidth;\n const uvy0 = (sy + this.uvPadding) / imageHeight;\n const uvx1 = (sx + sw - this.uvPadding) / imageWidth;\n const uvy1 = (sy + sh - this.uvPadding) / imageHeight;\n const txWidth = image.width;\n const txHeight = image.height;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n }\n hasPendingDraws() {\n return this._imageCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._imageCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true, 48 * this._imageCount); // 4 verts * 12 components\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Turn on pixel art aa sampler\n this._shader.setUniformBoolean(\"u_pixelart\", this.pixelArtSampler);\n // Bind textures to\n this._bindTextures(gl);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._imageCount = 0;\n this._vertexIndex = 0;\n this._textures.length = 0;\n }\n }\n /* harmony default export */ const rectangle_renderer_frag = \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\";\n /* harmony default export */ const rectangle_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";\n class RectangleRenderer {\n constructor(){\n this.type = \"ex.rectangle\";\n this.priority = 0;\n this._maxRectangles = 10922; // max(uint16) / 6 verts\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\n this._shader = new Shader({\n gl: gl,\n fragmentSource: rectangle_renderer_frag,\n vertexSource: rectangle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 64 * this._maxRectangles,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ],\n [\n \"a_size\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_strokeColor\",\n 4\n ],\n [\n \"a_strokeThickness\",\n 1\n ]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n _isFull() {\n if (this._rectangleCount >= this._maxRectangles) return true;\n return false;\n }\n draw(...args) {\n if (args[0] instanceof Vector && args[1] instanceof Vector) this.drawLine.apply(this, args);\n else this.drawRectangle.apply(this, args);\n }\n drawLine(start, end, color, thickness = 1) {\n if (this._isFull()) this.flush();\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const dir = end.sub(start);\n const length = dir.size;\n const normal = dir.normalize().perpendicular();\n const halfThick = thickness / 2;\n /**\n * +---------------------^----------------------+\n * | | (normal) |\n * (startx, starty)------------------>(endx, endy)\n * | |\n * + -------------------------------------------+\n */ const startTop = transform.multiply(normal.scale(halfThick).add(start));\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\n if (snapToPixel) {\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n const stroke = Color.Transparent;\n const strokeThickness = 0;\n const width = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = startTop.x;\n vertexBuffer[this._vertexIndex++] = startTop.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = startBottom.x;\n vertexBuffer[this._vertexIndex++] = startBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = endTop.x;\n vertexBuffer[this._vertexIndex++] = endTop.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = endBottom.x;\n vertexBuffer[this._vertexIndex++] = endBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n }\n drawRectangle(pos, width, height, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) this.flush();\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\n const topRight = transform.multiply(pos.add(vec(width, 0)));\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n }\n hasPendingDraws() {\n return this._rectangleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._rectangleCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n }\n /* harmony default export */ const circle_renderer_frag = \"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\";\n /* harmony default export */ const circle_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";\n class CircleRenderer {\n constructor(){\n this.type = \"ex.circle\";\n this.priority = 0;\n this._maxCircles = 10922; // max(uint16) / 6 verts\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n fragmentSource: circle_renderer_frag,\n vertexSource: circle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 56 * this._maxCircles,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_strokeColor\",\n 4\n ],\n [\n \"a_strokeThickness\",\n 1\n ]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n _isFull() {\n if (this._circleCount >= this._maxCircles) return true;\n return false;\n }\n draw(pos, radius, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) this.flush();\n this._circleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO UV could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n }\n hasPendingDraws() {\n return this._circleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._circleCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n }\n class Pool {\n constructor(builder, recycler, maxObjects = 100){\n this.builder = builder;\n this.recycler = recycler;\n this.maxObjects = maxObjects;\n this.totalAllocations = 0;\n this.index = 0;\n this.objects = [];\n this.disableWarnings = false;\n this._logger = Logger.getInstance();\n }\n dispose() {\n this.objects.length = 0;\n }\n preallocate() {\n for(let i = 0; i < this.maxObjects; i++)this.objects[i] = this.builder();\n }\n /**\n * Use many instances out of the in the context and return all to the pool.\n *\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\n * @param context\n */ using(context) {\n const result = context(this);\n if (result) return this.done(...result);\n return this.done();\n }\n /**\n * Use a single instance out of th pool and immediately return it to the pool\n * @param context\n */ borrow(context) {\n const object = this.get();\n context(object);\n this.index--;\n }\n /**\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\n * @param args\n */ get(...args) {\n if (this.index === this.maxObjects) {\n if (!this.disableWarnings) this._logger.warn(\"Max pooled objects reached, possible memory leak? Doubling\");\n this.maxObjects = this.maxObjects * 2;\n }\n if (this.objects[this.index]) // Pool has an available object already constructed\n return this.recycler(this.objects[this.index++], ...args);\n else {\n // New allocation\n this.totalAllocations++;\n const object = this.objects[this.index++] = this.builder(...args);\n return object;\n }\n }\n done(...objects) {\n // All objects in pool now considered \"free\"\n this.index = 0;\n for (const object of objects){\n const poolIndex = this.objects.indexOf(object);\n // Build a new object to take the pool place\n this.objects[poolIndex] = this.builder(); // TODO problematic 0-arg only support\n this.totalAllocations++;\n }\n return objects;\n }\n }\n class DrawCall {\n constructor(){\n this.z = 0;\n this.priority = 0;\n this.transform = AffineMatrix.identity();\n this.state = {\n z: 0,\n opacity: 1,\n tint: Color.White,\n material: null\n };\n }\n }\n const defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nin vec2 a_screenuv;\r\nout vec2 v_screenuv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n v_screenuv = a_screenuv;\r\n}\r\n`;\n class Material {\n constructor(options){\n this._logger = Logger.getInstance();\n this._color = Color.Transparent;\n this._initialized = false;\n this._images = new Map();\n this._textures = new Map();\n const { color: color, name: name, vertexSource: vertexSource, fragmentSource: fragmentSource, graphicsContext: graphicsContext, images: images } = options;\n this._name = name !== null && name !== void 0 ? name : \"anonymous material\";\n this._vertexSource = vertexSource !== null && vertexSource !== void 0 ? vertexSource : defaultVertexSource;\n this._fragmentSource = fragmentSource;\n this._color = color !== null && color !== void 0 ? color : this._color;\n if (!graphicsContext) throw Error(`Material ${name} must be provided an excalibur webgl graphics context`);\n if (graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this._graphicsContext = graphicsContext;\n this._initialize(graphicsContext);\n } else this._logger.warn(`Material ${name} was created in 2D Canvas mode, currently only WebGL is supported`);\n if (images) for(const key in images)this.addImageSource(key, images[key]);\n }\n _initialize(graphicsContextWebGL) {\n if (this._initialized) return;\n const gl = graphicsContextWebGL.__gl;\n // max texture slots - 2 for the graphic texture and screen texture\n this._maxTextureSlots = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) - 2;\n this._shader = graphicsContextWebGL.createShader({\n vertexSource: this._vertexSource,\n fragmentSource: this._fragmentSource\n });\n this._shader.compile();\n this._initialized = true;\n }\n get name() {\n var _a;\n return (_a = this._name) !== null && _a !== void 0 ? _a : \"anonymous material\";\n }\n get isUsingScreenTexture() {\n return this._fragmentSource.includes(\"u_screen_texture\");\n }\n update(callback) {\n if (this._shader) {\n this._shader.use();\n callback(this._shader);\n }\n }\n getShader() {\n return this._shader;\n }\n addImageSource(textureUniformName, image) {\n if (this._images.size < this._maxTextureSlots) this._images.set(textureUniformName, image);\n else this._logger.warn(`Max number texture slots ${this._maxTextureSlots} have been reached for material \"${this.name}\", ` + `no more textures will be uploaded due to hardware constraints.`);\n }\n removeImageSource(textureName) {\n const image = this._images.get(textureName);\n this._graphicsContext.textureLoader.delete(image.image);\n this._images.delete(textureName);\n }\n _loadImageSource(image) {\n const imageElement = image.image;\n const maybeFiltering = imageElement.getAttribute(\"filtering\");\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended || maybeFiltering === ImageFiltering.Pixel) filtering = maybeFiltering;\n const force = imageElement.getAttribute(\"forceUpload\") === \"true\" ? true : false;\n const texture = this._graphicsContext.textureLoader.load(imageElement, filtering, force);\n // remove force attribute after upload\n imageElement.removeAttribute(\"forceUpload\");\n if (!this._textures.has(image)) this._textures.set(image, texture);\n return texture;\n }\n uploadAndBind(gl, startingTextureSlot = 2) {\n let textureSlot = startingTextureSlot;\n for (const [textureName, image] of this._images.entries()){\n if (!image.isLoaded()) {\n this._logger.warnOnce(`Image named ${textureName} in material ${this.name} not loaded, nothing will be uploaded to the shader.` + ` Did you forget to add this to a loader? https://excaliburjs.com/docs/loaders/`);\n continue;\n } // skip unloaded images, maybe warn\n const texture = this._loadImageSource(image);\n gl.activeTexture(gl.TEXTURE0 + textureSlot);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n this._shader.trySetUniformInt(textureName, textureSlot);\n textureSlot++;\n }\n }\n use() {\n if (this._initialized) {\n // bind the shader\n this._shader.use();\n // Apply standard uniforms\n this._shader.trySetUniformFloatColor(\"u_color\", this._color);\n } else throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\n }\n }\n class MaterialRenderer {\n constructor(){\n this.type = \"ex.material\";\n this.priority = 0;\n this._textures = [];\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 24,\n type: \"dynamic\"\n });\n // Setup a vertex layout/buffer to the material\n this._layout = new VertexLayout({\n gl: gl,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ],\n [\n \"a_screenuv\",\n 2\n ]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, 1, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._textures.length = 0;\n this._context = null;\n this._gl = null;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n const gl = this._gl;\n // Extract context info\n const material = this._context.material;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n // material shader\n const shader = material.getShader();\n // construct geometry, or hold on to it in the material?\n // geometry primitive for drawing rectangles?\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n let vertexIndex = 0;\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [\n 0,\n 0,\n (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0,\n (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0\n ];\n let dest = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1\n ];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1,\n (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0,\n (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0\n ];\n dest = [\n dx,\n dy\n ];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n const topLeft = vec(dest[0], dest[1]);\n const topRight = vec(dest[0] + width, dest[1]);\n const bottomLeft = vec(dest[0], dest[1] + height);\n const bottomRight = vec(dest[0] + width, dest[1] + height);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = sx / imageWidth;\n const uvy0 = sy / imageHeight;\n const uvx1 = (sx + sw - 0.01) / imageWidth;\n const uvy1 = (sy + sh - 0.01) / imageHeight;\n const topLeftScreen = transform.getPosition();\n const bottomRightScreen = topLeftScreen.add(bottomRight);\n const screenUVX0 = topLeftScreen.x / this._context.width;\n const screenUVY0 = topLeftScreen.y / this._context.height;\n const screenUVX1 = bottomRightScreen.x / this._context.width;\n const screenUVY1 = bottomRightScreen.y / this._context.height;\n // (0, 0) - 0\n vertexBuffer[vertexIndex++] = topLeft.x;\n vertexBuffer[vertexIndex++] = topLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy0;\n vertexBuffer[vertexIndex++] = screenUVX0;\n vertexBuffer[vertexIndex++] = screenUVY0;\n // (0, 1) - 1\n vertexBuffer[vertexIndex++] = bottomLeft.x;\n vertexBuffer[vertexIndex++] = bottomLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy1;\n vertexBuffer[vertexIndex++] = screenUVX0;\n vertexBuffer[vertexIndex++] = screenUVY1;\n // (1, 0) - 2\n vertexBuffer[vertexIndex++] = topRight.x;\n vertexBuffer[vertexIndex++] = topRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy0;\n vertexBuffer[vertexIndex++] = screenUVX1;\n vertexBuffer[vertexIndex++] = screenUVY0;\n // (1, 1) - 3\n vertexBuffer[vertexIndex++] = bottomRight.x;\n vertexBuffer[vertexIndex++] = bottomRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy1;\n vertexBuffer[vertexIndex++] = screenUVX1;\n vertexBuffer[vertexIndex++] = screenUVY1;\n // This creates and uploads the texture if not already done\n const texture = this._addImageAsTexture(image);\n // apply material\n material.use();\n this._layout.shader = shader;\n // apply layout and geometry\n this._layout.use(true);\n // apply time in ms since the page (performance.now())\n shader.trySetUniformFloat(\"u_time_ms\", performance.now());\n // apply opacity\n shader.trySetUniformFloat(\"u_opacity\", opacity);\n // apply resolution\n shader.trySetUniformFloatVector(\"u_resolution\", vec(this._context.width, this._context.height));\n // apply graphic resolution\n shader.trySetUniformFloatVector(\"u_graphic_resolution\", vec(imageWidth, imageHeight));\n // apply size\n shader.trySetUniformFloatVector(\"u_size\", vec(sw, sh));\n // apply orthographic projection\n shader.trySetUniformMatrix(\"u_matrix\", this._context.ortho);\n // apply geometry transform\n shader.trySetUniformMatrix(\"u_transform\", transform.to4x4());\n // bind graphic image texture 'uniform sampler2D u_graphic;'\n gl.activeTexture(gl.TEXTURE0 + 0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n shader.trySetUniformInt(\"u_graphic\", 0);\n // bind the screen texture\n gl.activeTexture(gl.TEXTURE0 + 1);\n gl.bindTexture(gl.TEXTURE_2D, this._context.materialScreenTexture);\n shader.trySetUniformInt(\"u_screen_texture\", 1);\n // bind any additional textures in the material\n material.uploadAndBind(gl);\n // bind quad index buffer\n this._quads.bind();\n // Draw a single quad\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount++;\n GraphicsDiagnostics.DrawCallCount++;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute(\"filtering\");\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended || maybeFiltering === ImageFiltering.Pixel) filtering = maybeFiltering;\n const force = image.getAttribute(\"forceUpload\") === \"true\" ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute(\"forceUpload\");\n if (this._textures.indexOf(texture) === -1) this._textures.push(texture);\n return texture;\n }\n hasPendingDraws() {\n return false;\n }\n flush() {\n // flush does not do anything, material renderer renders immediately per draw\n }\n }\n // renderers\n const pixelSnapEpsilon = 0.0001;\n class ExcaliburGraphicsContextWebGLDebug {\n constructor(_webglCtx){\n this._webglCtx = _webglCtx;\n this._debugText = new DebugText();\n }\n /**\n * Draw a debugging rectangle to the context\n * @param x\n * @param y\n * @param width\n * @param height\n */ drawRect(x, y, width, height, rectOptions = {\n color: Color.Black\n }) {\n this.drawLine(vec(x, y), vec(x + width, y), {\n ...rectOptions\n });\n this.drawLine(vec(x + width, y), vec(x + width, y + height), {\n ...rectOptions\n });\n this.drawLine(vec(x + width, y + height), vec(x, y + height), {\n ...rectOptions\n });\n this.drawLine(vec(x, y + height), vec(x, y), {\n ...rectOptions\n });\n }\n /**\n * Draw a debugging line to the context\n * @param start\n * @param end\n * @param lineOptions\n */ drawLine(start, end, lineOptions = {\n color: Color.Black\n }) {\n this._webglCtx.draw(\"ex.line\", start, end, lineOptions.color);\n }\n /**\n * Draw a debugging point to the context\n * @param point\n * @param pointOptions\n */ drawPoint(point, pointOptions = {\n color: Color.Black,\n size: 5\n }) {\n this._webglCtx.draw(\"ex.point\", point, pointOptions.color, pointOptions.size);\n }\n drawText(text, pos) {\n this._debugText.write(this._webglCtx, text, pos);\n }\n }\n class ExcaliburGraphicsContextWebGL {\n get z() {\n return this._state.current.z;\n }\n set z(value) {\n this._state.current.z = value;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get width() {\n return this.__gl.canvas.width;\n }\n get height() {\n return this.__gl.canvas.height;\n }\n get ortho() {\n return this._ortho;\n }\n /**\n * Checks the underlying webgl implementation if the requested internal resolution is supported\n * @param dim\n */ checkIfResolutionSupported(dim) {\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\n let supported = true;\n if (dim.width > 4096 || dim.height > 4096) supported = false;\n return supported;\n }\n constructor(options){\n this._logger = Logger.getInstance();\n this._renderers = new Map();\n this._isDrawLifecycle = false;\n this.useDrawSorting = true;\n this._drawCallPool = new Pool(()=>new DrawCall(), (instance)=>{\n instance.priority = 0;\n instance.z = 0;\n instance.renderer = undefined;\n instance.args = undefined;\n return instance;\n }, 4000);\n this._drawCalls = [];\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\n this._postProcessTargets = [];\n this._postprocessors = [];\n this._transform = new TransformStack();\n this._state = new StateStack();\n /**\n * Snaps the drawing x/y coordinate to the nearest whole pixel\n */ this.snapToPixel = false;\n /**\n * Native context smoothing\n */ this.smoothing = false;\n /**\n * Whether the pixel art sampler is enabled for smooth sub pixel anti-aliasing\n */ this.pixelArtSampler = false;\n /**\n * UV padding in pixels to use in internal image rendering to prevent texture bleed\n *\n */ this.uvPadding = .01;\n this.backgroundColor = Color.ExcaliburBlue;\n this.multiSampleAntialiasing = true;\n this.transparency = true;\n this._disposed = false;\n this.debug = new ExcaliburGraphicsContextWebGLDebug(this);\n this._totalPostProcessorTime = 0;\n const { canvasElement: canvasElement, context: context, enableTransparency: enableTransparency, antialiasing: antialiasing, uvPadding: uvPadding, multiSampleAntialiasing: multiSampleAntialiasing, pixelArtSampler: pixelArtSampler, powerPreference: powerPreference, snapToPixel: snapToPixel, backgroundColor: backgroundColor, useDrawSorting: useDrawSorting } = options;\n this.__gl = context !== null && context !== void 0 ? context : canvasElement.getContext(\"webgl2\", {\n antialias: antialiasing !== null && antialiasing !== void 0 ? antialiasing : this.smoothing,\n premultipliedAlpha: false,\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : this.transparency,\n depth: false,\n powerPreference: powerPreference !== null && powerPreference !== void 0 ? powerPreference : \"high-performance\"\n });\n if (!this.__gl) throw Error(\"Failed to retrieve webgl context from browser\");\n this.textureLoader = new TextureLoader(this.__gl);\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = antialiasing !== null && antialiasing !== void 0 ? antialiasing : this.smoothing;\n this.transparency = enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : this.transparency;\n this.pixelArtSampler = pixelArtSampler !== null && pixelArtSampler !== void 0 ? pixelArtSampler : this.pixelArtSampler;\n this.uvPadding = uvPadding !== null && uvPadding !== void 0 ? uvPadding : this.uvPadding;\n this.multiSampleAntialiasing = typeof multiSampleAntialiasing === \"boolean\" ? multiSampleAntialiasing : this.multiSampleAntialiasing;\n this.samples = typeof multiSampleAntialiasing === \"object\" ? multiSampleAntialiasing.samples : undefined;\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.useDrawSorting = useDrawSorting !== null && useDrawSorting !== void 0 ? useDrawSorting : this.useDrawSorting;\n this._drawCallPool.disableWarnings = true;\n this._drawCallPool.preallocate();\n this._init();\n }\n dispose() {\n if (!this._disposed) {\n this._disposed = true;\n this.textureLoader.dispose();\n for (const renderer of this._renderers.values())renderer.dispose();\n this._renderers.clear();\n this._drawCallPool.dispose();\n this._drawCalls.length = 0;\n this.__gl = null;\n }\n }\n _init() {\n const gl = this.__gl;\n // Setup viewport and view matrix\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\n // Clear background\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n // Enable alpha blending\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n // Setup builtin renderers\n this.register(new ImageRenderer({\n uvPadding: this.uvPadding,\n pixelArtSampler: this.pixelArtSampler\n }));\n this.register(new MaterialRenderer());\n this.register(new RectangleRenderer());\n this.register(new CircleRenderer());\n this.register(new PointRenderer());\n this.register(new LineRenderer());\n this.materialScreenTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this.materialScreenTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n gl.bindTexture(gl.TEXTURE_2D, null);\n this._screenRenderer = new ScreenPassPainter(gl);\n this._renderTarget = new RenderTarget({\n gl: gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n });\n this._postProcessTargets = [\n new RenderTarget({\n gl: gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n }),\n new RenderTarget({\n gl: gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n })\n ];\n this._msaaTarget = new RenderTarget({\n gl: gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height,\n antialias: this.multiSampleAntialiasing,\n samples: this.samples\n });\n }\n register(renderer) {\n this._renderers.set(renderer.type, renderer);\n renderer.initialize(this.__gl, this);\n }\n get(rendererName) {\n return this._renderers.get(rendererName);\n }\n _isCurrentRenderer(renderer) {\n if (!this._currentRenderer || this._currentRenderer === renderer) return true;\n return false;\n }\n beginDrawLifecycle() {\n this._isDrawLifecycle = true;\n }\n endDrawLifecycle() {\n this._isDrawLifecycle = false;\n }\n draw(rendererName, ...args) {\n if (!this._isDrawLifecycle) this._logger.warnOnce(`Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` + `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\n const renderer = this._renderers.get(rendererName);\n if (renderer) {\n if (this.useDrawSorting) {\n const drawCall = this._drawCallPool.get();\n drawCall.z = this._state.current.z;\n drawCall.priority = renderer.priority;\n drawCall.renderer = rendererName;\n this.getTransform().clone(drawCall.transform);\n drawCall.state.z = this._state.current.z;\n drawCall.state.opacity = this._state.current.opacity;\n drawCall.state.tint = this._state.current.tint;\n drawCall.state.material = this._state.current.material;\n drawCall.args = args;\n this._drawCalls.push(drawCall);\n } else {\n // Set the current renderer if not defined\n if (!this._currentRenderer) this._currentRenderer = renderer;\n if (!this._isCurrentRenderer(renderer)) // switching graphics means we must flush the previous\n this._currentRenderer.flush();\n // If we are still using the same renderer we can add to the current batch\n renderer.draw(...args);\n this._currentRenderer = renderer;\n }\n } else throw Error(`No renderer with name ${rendererName} has been registered`);\n }\n resetTransform() {\n this._transform.current = AffineMatrix.identity();\n }\n updateViewport(resolution) {\n const gl = this.__gl;\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._msaaTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) return; // zero dimension dest exit early\n else if (dwidth === 0 || dheight === 0) return; // zero dimension dest exit early\n else if (image.width === 0 || image.height === 0) return; // zero dimension source exit early\n if (!image) {\n Logger.getInstance().warn(\"Cannot draw a null or undefined image\");\n // tslint:disable-next-line: no-console\n if (console.trace) // tslint:disable-next-line: no-console\n console.trace();\n return;\n }\n if (this._state.current.material) this.draw(\"ex.material\", image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n else this.draw(\"ex.image\", image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n }\n drawLine(start, end, color, thickness = 1) {\n this.draw(\"ex.rectangle\", start, end, color, thickness);\n }\n drawRectangle(pos, width, height, color, stroke, strokeThickness) {\n this.draw(\"ex.rectangle\", pos, width, height, color, stroke, strokeThickness);\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.draw(\"ex.circle\", pos, radius, color, stroke, thickness);\n }\n save() {\n this._transform.save();\n this._state.save();\n }\n restore() {\n this._transform.restore();\n this._state.restore();\n }\n translate(x, y) {\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\n }\n rotate(angle) {\n this._transform.rotate(angle);\n }\n scale(x, y) {\n this._transform.scale(x, y);\n }\n transform(matrix) {\n this._transform.current = matrix;\n }\n getTransform() {\n return this._transform.current;\n }\n multiply(m) {\n this._transform.current.multiply(m, this._transform.current);\n }\n addPostProcessor(postprocessor) {\n this._postprocessors.push(postprocessor);\n postprocessor.initialize(this.__gl);\n }\n removePostProcessor(postprocessor) {\n const index = this._postprocessors.indexOf(postprocessor);\n if (index !== -1) this._postprocessors.splice(index, 1);\n }\n clearPostProcessors() {\n this._postprocessors.length = 0;\n }\n updatePostProcessors(delta) {\n for (const postprocessor of this._postprocessors){\n const shader = postprocessor.getShader();\n shader.use();\n const uniforms = shader.getUniforms();\n this._totalPostProcessorTime += delta;\n if (uniforms.find((u)=>u.name === \"u_time_ms\")) shader.setUniformFloat(\"u_time_ms\", this._totalPostProcessorTime);\n if (uniforms.find((u)=>u.name === \"u_elapsed_ms\")) shader.setUniformFloat(\"u_elapsed_ms\", delta);\n if (uniforms.find((u)=>u.name === \"u_resolution\")) shader.setUniformFloatVector(\"u_resolution\", vec(this.width, this.height));\n if (postprocessor.onUpdate) postprocessor.onUpdate(delta);\n }\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n /**\n * Creates and initializes the material which compiles the internal shader\n * @param options\n * @returns Material\n */ createMaterial(options) {\n const material = new Material({\n ...options,\n graphicsContext: this\n });\n return material;\n }\n createShader(options) {\n const gl = this.__gl;\n const { vertexSource: vertexSource, fragmentSource: fragmentSource } = options;\n const shader = new Shader({\n gl: gl,\n vertexSource: vertexSource,\n fragmentSource: fragmentSource\n });\n shader.compile();\n return shader;\n }\n clear() {\n const gl = this.__gl;\n const currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\n currentTarget.use();\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n // Clear the context with the newly set color. This is\n // the function call that actually does the drawing.\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n /**\n * Flushes all batched rendering to the screen\n */ flush() {\n // render target captures all draws and redirects to the render target\n let currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\n currentTarget.use();\n if (this.useDrawSorting) {\n // sort draw calls\n // Find the original order of the first instance of the draw call\n const originalSort = new Map();\n for (const [name] of this._renderers){\n const firstIndex = this._drawCalls.findIndex((dc)=>dc.renderer === name);\n originalSort.set(name, firstIndex);\n }\n this._drawCalls.sort((a, b)=>{\n const zIndex = a.z - b.z;\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\n const priority = a.priority - b.priority;\n if (zIndex === 0) {\n if (priority === 0) return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\n return priority;\n }\n return zIndex;\n });\n const oldTransform = this._transform.current;\n const oldState = this._state.current;\n if (this._drawCalls.length) {\n let currentRendererName = this._drawCalls[0].renderer;\n let currentRenderer = this._renderers.get(currentRendererName);\n for(let i = 0; i < this._drawCalls.length; i++){\n // hydrate the state for renderers\n this._transform.current = this._drawCalls[i].transform;\n this._state.current = this._drawCalls[i].state;\n if (this._drawCalls[i].renderer !== currentRendererName) {\n // switching graphics renderer means we must flush the previous\n currentRenderer.flush();\n currentRendererName = this._drawCalls[i].renderer;\n currentRenderer = this._renderers.get(currentRendererName);\n }\n // ! hack to grab screen texture before materials run because they might want it\n if (currentRenderer instanceof MaterialRenderer && this.material.isUsingScreenTexture) {\n currentTarget.copyToTexture(this.materialScreenTexture);\n currentTarget.use();\n }\n // If we are still using the same renderer we can add to the current batch\n currentRenderer.draw(...this._drawCalls[i].args);\n }\n if (currentRenderer.hasPendingDraws()) currentRenderer.flush();\n }\n // reset state\n this._transform.current = oldTransform;\n this._state.current = oldState;\n // reclaim draw calls\n this._drawCallPool.done();\n this._drawCalls.length = 0;\n } else {\n // This is the final flush at the moment to draw any leftover pending draw\n for (const renderer of this._renderers.values())if (renderer.hasPendingDraws()) renderer.flush();\n }\n currentTarget.disable();\n // post process step\n if (this._postprocessors.length > 0) {\n const source = currentTarget.toRenderSource();\n source.use();\n }\n // flip flop render targets for post processing\n for(let i = 0; i < this._postprocessors.length; i++){\n currentTarget = this._postProcessTargets[i % 2];\n this._postProcessTargets[i % 2].use();\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\n this._postProcessTargets[i % 2].toRenderSource().use();\n }\n // Final blit to the screen\n currentTarget.blitToScreen();\n }\n }\n const ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon = 0.0001;\n class ExcaliburGraphicsContext2DCanvasDebug {\n constructor(_ex){\n this._ex = _ex;\n this._debugText = new DebugText();\n }\n /**\n * Draw a debug rectangle to the context\n * @param x\n * @param y\n * @param width\n * @param height\n */ drawRect(x, y, width, height) {\n this._ex.__ctx.save();\n this._ex.__ctx.strokeStyle = \"red\";\n this._ex.__ctx.strokeRect(this._ex.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this._ex.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y, this._ex.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this._ex.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this._ex.__ctx.restore();\n }\n drawLine(start, end, lineOptions = {\n color: Color.Black\n }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\n this._ex.__ctx.moveTo(this._ex.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this._ex.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this._ex.__ctx.lineTo(this._ex.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this._ex.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this._ex.__ctx.lineWidth = 2;\n this._ex.__ctx.stroke();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawPoint(point, pointOptions = {\n color: Color.Black,\n size: 5\n }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\n this._ex.__ctx.arc(this._ex.snapToPixel ? ~~(point.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.x, this._ex.snapToPixel ? ~~(point.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.y, pointOptions.size, 0, Math.PI * 2);\n this._ex.__ctx.fill();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawText(text, pos) {\n this._debugText.write(this._ex, text, pos);\n }\n }\n class ExcaliburGraphicsContext2DCanvas {\n get width() {\n return this.__ctx.canvas.width;\n }\n get height() {\n return this.__ctx.canvas.height;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get smoothing() {\n return this.__ctx.imageSmoothingEnabled;\n }\n set smoothing(value) {\n this.__ctx.imageSmoothingEnabled = value;\n }\n constructor(options){\n /**\n * Unused in Canvas implementation\n */ this.useDrawSorting = false;\n /**\n * Unused in Canvas implementation\n */ this.z = 0;\n this.backgroundColor = Color.ExcaliburBlue;\n this._state = new StateStack();\n this.snapToPixel = false;\n this.debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\n const { canvasElement: canvasElement, context: context, enableTransparency: enableTransparency, snapToPixel: snapToPixel, antialiasing: smoothing, backgroundColor: backgroundColor } = options;\n this.__ctx = context !== null && context !== void 0 ? context : canvasElement.getContext(\"2d\", {\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : true\n });\n if (!this.__ctx) throw new Error(\"Cannot build new ExcaliburGraphicsContext2D for some reason!\");\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing;\n }\n resetTransform() {\n this.__ctx.resetTransform();\n }\n updateViewport(_resolution) {\n // pass\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) return; // zero dimension dest exit early\n else if (dwidth === 0 || dheight === 0) return; // zero dimension dest exit early\n else if (image.width === 0 || image.height === 0) return; // zero dimension source exit early\n this.__ctx.globalAlpha = this.opacity;\n const args = [\n image,\n sx,\n sy,\n swidth,\n sheight,\n dx,\n dy,\n dwidth,\n dheight\n ].filter((a)=>a !== undefined).map((a)=>typeof a === \"number\" && this.snapToPixel ? ~~a : a);\n this.__ctx.drawImage.apply(this.__ctx, args);\n GraphicsDiagnostics.DrawCallCount++;\n GraphicsDiagnostics.DrawnImagesCount = 1;\n }\n drawLine(start, end, color, thickness = 1) {\n this.__ctx.save();\n this.__ctx.beginPath();\n this.__ctx.strokeStyle = color.toString();\n this.__ctx.moveTo(this.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this.__ctx.lineTo(this.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this.__ctx.lineWidth = thickness;\n this.__ctx.stroke();\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n drawRectangle(pos, width, height, color) {\n this.__ctx.save();\n this.__ctx.fillStyle = color.toString();\n this.__ctx.fillRect(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, this.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this.__ctx.restore();\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.__ctx.save();\n this.__ctx.beginPath();\n if (stroke) this.__ctx.strokeStyle = stroke.toString();\n if (thickness) this.__ctx.lineWidth = thickness;\n this.__ctx.fillStyle = color.toString();\n this.__ctx.arc(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2);\n this.__ctx.fill();\n if (stroke) this.__ctx.stroke();\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n /**\n * Save the current state of the canvas to the stack (transforms and opacity)\n */ save() {\n this.__ctx.save();\n this._state.save();\n }\n /**\n * Restore the state of the canvas from the stack\n */ restore() {\n this.__ctx.restore();\n this._state.restore();\n }\n /**\n * Translate the origin of the context by an x and y\n * @param x\n * @param y\n */ translate(x, y) {\n this.__ctx.translate(this.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y);\n }\n /**\n * Rotate the context about the current origin\n */ rotate(angle) {\n this.__ctx.rotate(angle);\n }\n /**\n * Scale the context by an x and y factor\n * @param x\n * @param y\n */ scale(x, y) {\n this.__ctx.scale(x, y);\n }\n getTransform() {\n throw new Error(\"Not implemented\");\n }\n multiply(_m) {\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\n }\n addPostProcessor(_postprocessor) {\n // pass\n }\n removePostProcessor(_postprocessor) {\n // pass\n }\n clearPostProcessors() {\n // pass\n }\n updatePostProcessors(delta) {\n // pass\n }\n beginDrawLifecycle() {\n // pass\n }\n endDrawLifecycle() {\n // pass\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n createMaterial(options) {\n // pass\n return null;\n }\n clear() {\n // Clear frame\n this.__ctx.clearRect(0, 0, this.width, this.height);\n this.__ctx.fillStyle = this.backgroundColor.toString();\n this.__ctx.fillRect(0, 0, this.width, this.height);\n GraphicsDiagnostics.clear();\n }\n /**\n * Flushes the batched draw calls to the screen\n */ flush() {\n // pass\n }\n dispose() {\n this.__ctx = null;\n }\n }\n /**\n * Enum representing the different display modes available to Excalibur.\n */ var DisplayMode;\n (function(DisplayMode) {\n /**\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\n */ DisplayMode[\"Fixed\"] = \"Fixed\";\n /**\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\n * is guaranteed to be on screen.\n */ DisplayMode[\"FitContainerAndFill\"] = \"FitContainerAndFill\";\n /**\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\n * is guaranteed to be on screen.\n */ DisplayMode[\"FitScreenAndFill\"] = \"FitScreenAndFill\";\n /**\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\n * (letterbox) that would otherwise be present in [[FitContainer]].\n *\n * **warning** This will clip some drawable area from the user because of the zoom,\n * use [[Screen.contentArea]] to know the safe to draw area.\n */ DisplayMode[\"FitContainerAndZoom\"] = \"FitContainerAndZoom\";\n /**\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\n * (letterbox) that would otherwise be present in [[FitScreen]].\n *\n * **warning** This will clip some drawable area from the user because of the zoom,\n * use [[Screen.contentArea]] to know the safe to draw area.\n */ DisplayMode[\"FitScreenAndZoom\"] = \"FitScreenAndZoom\";\n /**\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\n *\n * You may want to center your game here is an example\n * ```html\n * \n * \n *
\n * \n *
\n * \n * ```\n *\n * ```css\n * // css\n * main {\n * display: flex;\n * align-items: center;\n * justify-content: center;\n * height: 100%;\n * width: 100%;\n * }\n * ```\n */ DisplayMode[\"FitScreen\"] = \"FitScreen\";\n /**\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\n */ DisplayMode[\"FillScreen\"] = \"FillScreen\";\n /**\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\n */ DisplayMode[\"FitContainer\"] = \"FitContainer\";\n /**\n * Use the parent DOM container's css width/height for the game resolution dynamically\n */ DisplayMode[\"FillContainer\"] = \"FillContainer\";\n })(DisplayMode || (DisplayMode = {}));\n /**\n * Convenience class for quick resolutions\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\n */ class Resolution {\n /* istanbul ignore next */ static get SVGA() {\n return {\n width: 800,\n height: 600\n };\n }\n /* istanbul ignore next */ static get Standard() {\n return {\n width: 1920,\n height: 1080\n };\n }\n /* istanbul ignore next */ static get Atari2600() {\n return {\n width: 160,\n height: 192\n };\n }\n /* istanbul ignore next */ static get GameBoy() {\n return {\n width: 160,\n height: 144\n };\n }\n /* istanbul ignore next */ static get GameBoyAdvance() {\n return {\n width: 240,\n height: 160\n };\n }\n /* istanbul ignore next */ static get NintendoDS() {\n return {\n width: 256,\n height: 192\n };\n }\n /* istanbul ignore next */ static get NES() {\n return {\n width: 256,\n height: 224\n };\n }\n /* istanbul ignore next */ static get SNES() {\n return {\n width: 256,\n height: 244\n };\n }\n }\n const ScreenEvents = {\n ScreenResize: \"resize\",\n PixelRatioChange: \"pixelratio\",\n FullScreenChange: \"fullscreen\"\n };\n /**\n * The Screen handles all aspects of interacting with the screen for Excalibur.\n */ class Screen {\n constructor(options){\n var _a, _b, _c, _d;\n /**\n * Listen to screen events [[ScreenEvents]]\n */ this.events = new EventEmitter();\n this._antialiasing = true;\n this._canvasImageRendering = \"auto\";\n this._resolutionStack = [];\n this._viewportStack = [];\n this._pixelRatioOverride = null;\n this._isFullScreen = false;\n this._isDisposed = false;\n this._logger = Logger.getInstance();\n this._fullscreenChangeHandler = ()=>{\n if (this._isDisposed) return;\n this._isFullScreen = !this._isFullScreen;\n this._logger.debug(\"Fullscreen Change\", this._isFullScreen);\n this.events.emit(\"fullscreen\", {\n fullscreen: this.isFullScreen\n });\n };\n this._pixelRatioChangeHandler = ()=>{\n if (this._isDisposed) return;\n this._logger.debug(\"Pixel Ratio Change\", window.devicePixelRatio);\n this._listenForPixelRatio();\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this.applyResolutionAndViewport();\n this.events.emit(\"pixelratio\", {\n pixelRatio: this.pixelRatio\n });\n };\n this._resizeHandler = ()=>{\n if (this._isDisposed) return;\n const parent = this.parent;\n this._logger.debug(\"View port resized\");\n this._setResolutionAndViewportByDisplayMode(parent);\n this.applyResolutionAndViewport();\n // Emit resize event\n this.events.emit(\"resize\", {\n resolution: this.resolution,\n viewport: this.viewport\n });\n };\n // Asking the window.devicePixelRatio is expensive we do it once\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this._contentArea = new BoundingBox();\n this._unsafeArea = new BoundingBox();\n this.viewport = options.viewport;\n this.resolution = (_a = options.resolution) !== null && _a !== void 0 ? _a : {\n ...this.viewport\n };\n this._contentResolution = this.resolution;\n this._displayMode = (_b = options.displayMode) !== null && _b !== void 0 ? _b : DisplayMode.Fixed;\n this._canvas = options.canvas;\n this.graphicsContext = options.context;\n this._antialiasing = (_c = options.antialiasing) !== null && _c !== void 0 ? _c : this._antialiasing;\n this._canvasImageRendering = (_d = options.canvasImageRendering) !== null && _d !== void 0 ? _d : this._canvasImageRendering;\n this._browser = options.browser;\n this._pixelRatioOverride = options.pixelRatio;\n this._applyDisplayMode();\n this._listenForPixelRatio();\n this._canvas.addEventListener(\"fullscreenchange\", this._fullscreenChangeHandler);\n this.applyResolutionAndViewport();\n }\n _listenForPixelRatio() {\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) // Safari <=13.1 workaround, remove any existing handlers\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.addEventListener) this._mediaQueryList.addEventListener(\"change\", this._pixelRatioChangeHandler, {\n once: true\n });\n else this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\n }\n dispose() {\n if (!this._isDisposed) {\n // Clean up handlers\n this._isDisposed = true;\n this.events.clear();\n this._browser.window.off(\"resize\", this._resizeHandler);\n this._browser.window.clear();\n if (this._resizeObserver) this._resizeObserver.disconnect();\n this.parent.removeEventListener(\"resize\", this._resizeHandler);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.removeEventListener) this._mediaQueryList.removeEventListener(\"change\", this._pixelRatioChangeHandler);\n else this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n this._canvas.removeEventListener(\"fullscreenchange\", this._fullscreenChangeHandler);\n this._canvas = null;\n }\n }\n _calculateDevicePixelRatio() {\n if (window.devicePixelRatio < 1) return 1;\n const devicePixelRatio = window.devicePixelRatio || 1;\n return devicePixelRatio;\n }\n /**\n * Returns the computed pixel ratio, first using any override, then the device pixel ratio\n */ get pixelRatio() {\n if (this._pixelRatioOverride) return this._pixelRatioOverride;\n return this._devicePixelRatio;\n }\n /**\n * Get or set the pixel ratio override\n *\n * You will need to call applyResolutionAndViewport() affect change on the screen\n */ get pixelRatioOverride() {\n return this._pixelRatioOverride;\n }\n set pixelRatioOverride(value) {\n this._pixelRatioOverride = value;\n }\n get isHiDpi() {\n return this.pixelRatio !== 1;\n }\n get displayMode() {\n return this._displayMode;\n }\n get canvas() {\n return this._canvas;\n }\n get parent() {\n switch(this.displayMode){\n case DisplayMode.FillContainer:\n case DisplayMode.FitContainer:\n case DisplayMode.FitContainerAndFill:\n case DisplayMode.FitContainerAndZoom:\n return this.canvas.parentElement || document.body;\n default:\n return window;\n }\n }\n get resolution() {\n return this._resolution;\n }\n set resolution(resolution) {\n this._resolution = resolution;\n }\n get viewport() {\n if (this._viewport) return this._viewport;\n return this._resolution;\n }\n set viewport(viewport) {\n this._viewport = viewport;\n }\n get aspectRatio() {\n return this._resolution.width / this._resolution.height;\n }\n get scaledWidth() {\n return this._resolution.width * this.pixelRatio;\n }\n get scaledHeight() {\n return this._resolution.height * this.pixelRatio;\n }\n setCurrentCamera(camera) {\n this._camera = camera;\n }\n pushResolutionAndViewport() {\n this._resolutionStack.push(this.resolution);\n this._viewportStack.push(this.viewport);\n this.resolution = {\n ...this.resolution\n };\n this.viewport = {\n ...this.viewport\n };\n }\n peekViewport() {\n return this._viewportStack[this._viewportStack.length - 1];\n }\n peekResolution() {\n return this._resolutionStack[this._resolutionStack.length - 1];\n }\n popResolutionAndViewport() {\n if (this._resolutionStack.length && this._viewportStack.length) {\n this.resolution = this._resolutionStack.pop();\n this.viewport = this._viewportStack.pop();\n }\n }\n applyResolutionAndViewport() {\n this._canvas.width = this.scaledWidth;\n this._canvas.height = this.scaledHeight;\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n const supported = this.graphicsContext.checkIfResolutionSupported({\n width: this.scaledWidth,\n height: this.scaledHeight\n });\n if (!supported) this._logger.warnOnce(`The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` + \" are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.\" + \" Try reducing the resolution or disabling Hi DPI scaling to avoid this\" + \" (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).\");\n }\n if (this._canvasImageRendering === \"auto\") this._canvas.style.imageRendering = \"auto\";\n else {\n this._canvas.style.imageRendering = \"pixelated\";\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\n if (this._canvas.style.imageRendering === \"\") this._canvas.style.imageRendering = \"crisp-edges\";\n }\n this._canvas.style.width = this.viewport.width + \"px\";\n this._canvas.style.height = this.viewport.height + \"px\";\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\n this.graphicsContext.updateViewport(this.resolution);\n this.graphicsContext.resetTransform();\n this.graphicsContext.smoothing = this._antialiasing;\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\n }\n get antialiasing() {\n return this._antialiasing;\n }\n set antialiasing(isSmooth) {\n this._antialiasing = isSmooth;\n this.graphicsContext.smoothing = this._antialiasing;\n }\n /**\n * Returns true if excalibur is fullscreen using the browser fullscreen api\n */ get isFullScreen() {\n return this._isFullScreen;\n }\n /**\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\n * For example, wire this to a user click handler.\n *\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\n * @param elementId\n */ goFullScreen(elementId) {\n if (elementId) {\n const maybeElement = document.getElementById(elementId);\n if (maybeElement) {\n if (!maybeElement.getAttribute(\"ex-fullscreen-listener\")) {\n maybeElement.setAttribute(\"ex-fullscreen-listener\", \"true\");\n maybeElement.addEventListener(\"fullscreenchange\", this._fullscreenChangeHandler);\n }\n const fullscreenPromise = maybeElement.requestFullscreen();\n return fullscreenPromise;\n }\n }\n return this._canvas.requestFullscreen();\n }\n /**\n * Requests to exit fullscreen using the browser fullscreen api\n */ exitFullScreen() {\n return document.exitFullscreen();\n }\n /**\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\n * Excalibur screen space.\n *\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\n * bottom right corner (resolutionX, resolutionY). When using *AndFill suffixed display modes screen space\n * (0, 0) is the top left of the safe content area bounding box not the viewport.\n * @param point\n */ pageToScreenCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n if (!this._isFullScreen) {\n newX -= getPosition(this._canvas).x;\n newY -= getPosition(this._canvas).y;\n }\n // if fullscreen api on it centers with black bars\n // we need to adjust the screen to world coordinates in this case\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = (newY - screenMarginY) / screenHeight * this.viewport.height;\n newX = newX / window.innerWidth * this.viewport.width;\n } else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = (newX - screenMarginX) / screenWidth * this.viewport.width;\n newY = newY / window.innerHeight * this.viewport.height;\n }\n }\n newX = newX / this.viewport.width * this.resolution.width;\n newY = newY / this.viewport.height * this.resolution.height;\n // offset by content area\n newX = newX - this.contentArea.left;\n newY = newY - this.contentArea.top;\n return new Vector(newX, newY);\n }\n /**\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\n * this is where html elements might live if you want to position them relative to Excalibur.\n *\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\n * bottom right corner (resolutionX, resolutionY)\n * @param point\n */ screenToPageCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n // no need to offset by content area, drawing is already offset by this\n newX = newX / this.resolution.width * this.viewport.width;\n newY = newY / this.resolution.height * this.viewport.height;\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = newY / this.viewport.height * screenHeight + screenMarginY;\n newX = newX / this.viewport.width * window.innerWidth;\n } else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = newX / this.viewport.width * screenWidth + screenMarginX;\n newY = newY / this.viewport.height * window.innerHeight;\n }\n }\n if (!this._isFullScreen) {\n newX += getPosition(this._canvas).x;\n newY += getPosition(this._canvas).y;\n }\n return new Vector(newX, newY);\n }\n /**\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\n *\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\n * and extends infinitely out relative from the [[Camera]].\n * @param point Screen coordinate to convert\n */ screenToWorldCoordinates(point) {\n // offset by content area\n point = point.add(vec(this.contentArea.left, this.contentArea.top));\n // the only difference between screen & world is the camera transform\n if (this._camera) return this._camera.inverse.multiply(point);\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n /**\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\n *\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\n * @param point World coordinate to convert\n */ worldToScreenCoordinates(point) {\n if (this._camera) return this._camera.transform.multiply(point);\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n pageToWorldCoordinates(point) {\n const screen = this.pageToScreenCoordinates(point);\n return this.screenToWorldCoordinates(screen);\n }\n worldToPageCoordinates(point) {\n const screen = this.worldToScreenCoordinates(point);\n return this.screenToPageCoordinates(screen);\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen\n * and the bottom right corner of the screen.\n *\n * World bounds are in world coordinates, useful for culling objects offscreen that are in world space\n */ getWorldBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Half).scale(vec(1 / this._camera.zoom, 1 / this._camera.zoom)).rotate(this._camera.rotation).translate(this._camera.pos);\n return bounds;\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen and the bottom right corner of the screen.\n *\n * Screen bounds are in screen coordinates, useful for culling objects offscreen that are in screen space\n */ getScreenBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero, Vector.Zero);\n return bounds;\n }\n /**\n * The width of the game canvas in pixels (physical width component of the\n * resolution of the canvas element)\n */ get canvasWidth() {\n return this.canvas.width;\n }\n /**\n * Returns half width of the game canvas in pixels (half physical width component)\n */ get halfCanvasWidth() {\n return this.canvas.width / 2;\n }\n /**\n * The height of the game canvas in pixels, (physical height component of\n * the resolution of the canvas element)\n */ get canvasHeight() {\n return this.canvas.height;\n }\n /**\n * Returns half height of the game canvas in pixels (half physical height component)\n */ get halfCanvasHeight() {\n return this.canvas.height / 2;\n }\n /**\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get drawWidth() {\n if (this._camera) return this.resolution.width / this._camera.zoom;\n return this.resolution.width;\n }\n /**\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get halfDrawWidth() {\n return this.drawWidth / 2;\n }\n /**\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get drawHeight() {\n if (this._camera) return this.resolution.height / this._camera.zoom;\n return this.resolution.height;\n }\n /**\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get halfDrawHeight() {\n return this.drawHeight / 2;\n }\n /**\n * Returns screen center coordinates including zoom and device pixel ratio.\n */ get center() {\n return vec(this.halfDrawWidth, this.halfDrawHeight);\n }\n /**\n * Returns the content area in screen space where it is safe to place content\n */ get contentArea() {\n return this._contentArea;\n }\n /**\n * Returns the unsafe area in screen space, this is the full screen and some space may not be onscreen.\n */ get unsafeArea() {\n return this._unsafeArea;\n }\n _computeFit() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (window.innerWidth / aspect < window.innerHeight) {\n adjustedWidth = window.innerWidth;\n adjustedHeight = window.innerWidth / aspect;\n } else {\n adjustedWidth = window.innerHeight * aspect;\n adjustedHeight = window.innerHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n this._unsafeArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _computeFitScreenAndFill() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitContainerAndFill() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const parent = this.canvas.parentElement;\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitAndFill(vw, vh) {\n this.viewport = {\n width: vw,\n height: vh\n };\n // if the current screen aspectRatio is less than the original aspectRatio\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\n // compute new resolution to match the original aspect ratio\n this.resolution = {\n width: vw * this._contentResolution.width / vw,\n height: vw * this._contentResolution.width / vw * vh / vw\n };\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\n this._contentArea = new BoundingBox({\n top: clip,\n left: 0,\n right: this._contentResolution.width,\n bottom: this.resolution.height - clip\n });\n this._unsafeArea = new BoundingBox({\n top: -clip,\n left: 0,\n right: this._contentResolution.width,\n bottom: this.resolution.height + clip\n });\n } else {\n this.resolution = {\n width: vh * this._contentResolution.height / vh * vw / vh,\n height: vh * this._contentResolution.height / vh\n };\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\n this._contentArea = new BoundingBox({\n top: 0,\n left: clip,\n right: this.resolution.width - clip,\n bottom: this._contentResolution.height\n });\n this._unsafeArea = new BoundingBox({\n top: 0,\n left: -clip,\n right: this.resolution.width + clip,\n bottom: this._contentResolution.height\n });\n }\n }\n _computeFitScreenAndZoom() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.canvas.style.position = \"absolute\";\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitContainerAndZoom() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.canvas.style.position = \"absolute\";\n const parent = this.canvas.parentElement;\n parent.style.position = \"relative\";\n parent.style.overflow = \"hidden\";\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitAndZoom(vw, vh) {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (vw / aspect < vh) {\n adjustedWidth = vw;\n adjustedHeight = vw / aspect;\n } else {\n adjustedWidth = vh * aspect;\n adjustedHeight = vh;\n }\n const scaleX = vw / adjustedWidth;\n const scaleY = vh / adjustedHeight;\n const maxScaleFactor = Math.max(scaleX, scaleY);\n const zoomedWidth = adjustedWidth * maxScaleFactor;\n const zoomedHeight = adjustedHeight * maxScaleFactor;\n // Center zoomed dimension if bigger than the screen\n if (zoomedWidth > vw) this.canvas.style.left = -(zoomedWidth - vw) / 2 + \"px\";\n else this.canvas.style.left = \"\";\n if (zoomedHeight > vh) this.canvas.style.top = -(zoomedHeight - vh) / 2 + \"px\";\n else this.canvas.style.top = \"\";\n this.viewport = {\n width: zoomedWidth,\n height: zoomedHeight\n };\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\n // return safe area\n if (this.viewport.width > vw) {\n const clip = (this.viewport.width - vw) / this.viewport.width * this.resolution.width;\n bounds.top = 0;\n bounds.left = clip / 2;\n bounds.right = this.resolution.width - clip / 2;\n bounds.bottom = this.resolution.height;\n }\n if (this.viewport.height > vh) {\n const clip = (this.viewport.height - vh) / this.viewport.height * this.resolution.height;\n bounds.top = clip / 2;\n bounds.left = 0;\n bounds.bottom = this.resolution.height - clip / 2;\n bounds.right = this.resolution.width;\n }\n this._contentArea = bounds;\n }\n _computeFitContainer() {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n const parent = this.canvas.parentElement;\n if (parent.clientWidth / aspect < parent.clientHeight) {\n adjustedWidth = parent.clientWidth;\n adjustedHeight = parent.clientWidth / aspect;\n } else {\n adjustedWidth = parent.clientHeight * aspect;\n adjustedHeight = parent.clientHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _applyDisplayMode() {\n this._setResolutionAndViewportByDisplayMode(this.parent);\n // watch resizing\n if (this.parent instanceof Window) this._browser.window.on(\"resize\", this._resizeHandler);\n else {\n this._resizeObserver = new ResizeObserver(()=>{\n this._resizeHandler();\n });\n this._resizeObserver.observe(this.parent);\n }\n this.parent.addEventListener(\"resize\", this._resizeHandler);\n }\n /**\n * Sets the resolution and viewport based on the selected display mode.\n */ _setResolutionAndViewportByDisplayMode(parent) {\n if (this.displayMode === DisplayMode.FillContainer) {\n this.resolution = {\n width: parent.clientWidth,\n height: parent.clientHeight\n };\n this.viewport = this.resolution;\n }\n if (this.displayMode === DisplayMode.FillScreen) {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.resolution = {\n width: parent.innerWidth,\n height: parent.innerHeight\n };\n this.viewport = this.resolution;\n }\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n if (this.displayMode === DisplayMode.FitScreen) this._computeFit();\n if (this.displayMode === DisplayMode.FitContainer) this._computeFitContainer();\n if (this.displayMode === DisplayMode.FitScreenAndFill) this._computeFitScreenAndFill();\n if (this.displayMode === DisplayMode.FitContainerAndFill) this._computeFitContainerAndFill();\n if (this.displayMode === DisplayMode.FitScreenAndZoom) this._computeFitScreenAndZoom();\n if (this.displayMode === DisplayMode.FitContainerAndZoom) this._computeFitContainerAndZoom();\n }\n }\n /**\n * Internal class used to build instances of AudioContext\n */ /* istanbul ignore next */ class AudioContextFactory {\n static create() {\n if (!this._INSTANCE) {\n if (window.AudioContext || window.webkitAudioContext) this._INSTANCE = new AudioContext();\n }\n return this._INSTANCE;\n }\n }\n AudioContextFactory._INSTANCE = null;\n /**\n * Patch for detecting legacy web audio in browsers\n * @internal\n * @param source\n */ function isLegacyWebAudioSource(source) {\n return !!source.playbackState;\n }\n class WebAudio {\n /**\n * Play an empty sound to unlock Safari WebAudio context. Call this function\n * right after a user interaction event.\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\n */ static unlock() {\n const promise = new Promise((resolve, reject)=>{\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) return resolve(true);\n const unlockTimeoutTimer = setTimeout(()=>{\n Logger.getInstance().warn(\"Excalibur was unable to unlock the audio context, audio probably will not play in this browser.\");\n resolve(false);\n }, 200);\n const audioContext = AudioContextFactory.create();\n audioContext.resume().then(()=>{\n // create empty buffer and play it\n const buffer = audioContext.createBuffer(1, 1, 22050);\n const source = audioContext.createBufferSource();\n let ended = false;\n source.buffer = buffer;\n source.connect(audioContext.destination);\n source.onended = ()=>ended = true;\n source.start(0);\n // by checking the play state after some time, we know if we're really unlocked\n setTimeout(()=>{\n if (isLegacyWebAudioSource(source)) {\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) WebAudio._UNLOCKED = true;\n } else if (audioContext.currentTime > 0 || ended) WebAudio._UNLOCKED = true;\n }, 0);\n clearTimeout(unlockTimeoutTimer);\n resolve(true);\n }, ()=>{\n reject();\n });\n });\n return promise;\n }\n static isUnlocked() {\n return this._UNLOCKED;\n }\n }\n WebAudio._UNLOCKED = false;\n /**\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\n *\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\n */ class Raster extends Graphic {\n constructor(options){\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;\n super(omit(options, [\n \"width\",\n \"height\"\n ])); // rasters do some special sauce with width/height\n this.filtering = null;\n this.lineCap = \"butt\";\n this.quality = 1;\n this._dirty = true;\n this._smoothing = false;\n this._color = watch(Color.Black, ()=>this.flagDirty());\n this._lineWidth = 1;\n this._lineDash = [];\n this._padding = 0;\n if (options) {\n this.quality = (_a = options.quality) !== null && _a !== void 0 ? _a : this.quality;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n this.strokeColor = options === null || options === void 0 ? void 0 : options.strokeColor;\n this.smoothing = (_c = options.smoothing) !== null && _c !== void 0 ? _c : this.smoothing;\n this.lineWidth = (_d = options.lineWidth) !== null && _d !== void 0 ? _d : this.lineWidth;\n this.lineDash = (_e = options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineCap = (_f = options.lineCap) !== null && _f !== void 0 ? _f : this.lineCap;\n this.padding = (_g = options.padding) !== null && _g !== void 0 ? _g : this.padding;\n this.filtering = (_h = options.filtering) !== null && _h !== void 0 ? _h : this.filtering;\n }\n this._bitmap = document.createElement(\"canvas\");\n // get the default canvas width/height as a fallback\n const bitmapWidth = (_j = options === null || options === void 0 ? void 0 : options.width) !== null && _j !== void 0 ? _j : this._bitmap.width;\n const bitmapHeight = (_k = options === null || options === void 0 ? void 0 : options.height) !== null && _k !== void 0 ? _k : this._bitmap.height;\n this.width = bitmapWidth;\n this.height = bitmapHeight;\n const maybeCtx = this._bitmap.getContext(\"2d\");\n if (!maybeCtx) /* istanbul ignore next */ throw new Error(\"Browser does not support 2d canvas drawing, cannot create Raster graphic\");\n else this._ctx = maybeCtx;\n }\n cloneRasterOptions() {\n return {\n color: this.color ? this.color.clone() : null,\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\n smoothing: this.smoothing,\n lineWidth: this.lineWidth,\n lineDash: this.lineDash,\n lineCap: this.lineCap,\n quality: this.quality,\n padding: this.padding\n };\n }\n /**\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\n */ get dirty() {\n return this._dirty;\n }\n /**\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\n * This should be called any time the graphics state changes such that it affects the outputted drawing\n */ flagDirty() {\n this._dirty = true;\n }\n /**\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n *\n * Any `padding`s or `quality` set will be factored into the width\n */ get width() {\n return Math.abs(this._getTotalWidth() * this.scale.x);\n }\n set width(value) {\n value /= Math.abs(this.scale.x);\n this._bitmap.width = value;\n this._originalWidth = value;\n this.flagDirty();\n }\n /**\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n *\n * Any `padding` or `quality` set will be factored into the height\n */ get height() {\n return Math.abs(this._getTotalHeight() * this.scale.y);\n }\n set height(value) {\n value /= Math.abs(this.scale.y);\n this._bitmap.height = value;\n this._originalHeight = value;\n this.flagDirty();\n }\n _getTotalWidth() {\n var _a;\n return (((_a = this._originalWidth) !== null && _a !== void 0 ? _a : this._bitmap.width) + this.padding * 2) * 1;\n }\n _getTotalHeight() {\n var _a;\n return (((_a = this._originalHeight) !== null && _a !== void 0 ? _a : this._bitmap.height) + this.padding * 2) * 1;\n }\n /**\n * Returns the local bounds of the Raster including the padding\n */ get localBounds() {\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\n }\n /**\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n */ get smoothing() {\n return this._smoothing;\n }\n set smoothing(value) {\n this._smoothing = value;\n this.flagDirty();\n }\n /**\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */ get color() {\n return this._color;\n }\n set color(value) {\n this.flagDirty();\n this._color = watch(value, ()=>this.flagDirty());\n }\n /**\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */ get strokeColor() {\n return this._strokeColor;\n }\n set strokeColor(value) {\n this.flagDirty();\n this._strokeColor = watch(value, ()=>this.flagDirty());\n }\n /**\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */ get lineWidth() {\n return this._lineWidth;\n }\n set lineWidth(value) {\n this._lineWidth = value;\n this.flagDirty();\n }\n get lineDash() {\n return this._lineDash;\n }\n set lineDash(value) {\n this._lineDash = value;\n this.flagDirty();\n }\n get padding() {\n return this._padding;\n }\n set padding(value) {\n this._padding = value;\n this.flagDirty();\n }\n /**\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\n */ rasterize() {\n this._dirty = false;\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\n this._ctx.save();\n this._applyRasterProperties(this._ctx);\n this.execute(this._ctx);\n this._ctx.restore();\n }\n _applyRasterProperties(ctx) {\n var _a, _b, _c;\n this._bitmap.width = this._getTotalWidth() * this.quality;\n this._bitmap.height = this._getTotalHeight() * this.quality;\n // Do a bad thing to pass the filtering as an attribute\n this._bitmap.setAttribute(\"filtering\", this.filtering);\n this._bitmap.setAttribute(\"forceUpload\", \"true\");\n ctx.scale(this.quality, this.quality);\n ctx.translate(this.padding, this.padding);\n ctx.imageSmoothingEnabled = this.smoothing;\n ctx.lineWidth = this.lineWidth;\n ctx.setLineDash((_a = this.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.lineCap = this.lineCap;\n ctx.strokeStyle = (_b = this.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = (_c = this.color) === null || _c === void 0 ? void 0 : _c.toString();\n }\n _drawImage(ex, x, y) {\n if (this._dirty) this.rasterize();\n ex.scale(1 / this.quality, 1 / this.quality);\n ex.drawImage(this._bitmap, x, y);\n }\n }\n /**\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\n *\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\n *\n * **Low performance API**\n */ class Canvas extends Raster {\n /**\n * Return the 2D graphics context of this canvas\n */ get ctx() {\n return this._ctx;\n }\n constructor(_options){\n super(_options);\n this._options = _options;\n }\n clone() {\n return new Canvas({\n ...this._options,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n var _a, _b;\n if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.draw) (_b = this._options) === null || _b === void 0 || _b.draw(ctx);\n if (!this._options.cache) this.flagDirty();\n }\n }\n class ExResponse {\n }\n ExResponse.type = {\n any: \"\",\n blob: \"blob\",\n json: \"json\",\n text: \"text\",\n document: \"document\",\n arraybuffer: \"arraybuffer\"\n };\n class StateMachine {\n constructor(){\n this.states = new Map();\n }\n get currentState() {\n return this._currentState;\n }\n set currentState(state) {\n this._currentState = state;\n }\n static create(machineDescription, data) {\n const machine = new StateMachine();\n machine.data = data;\n for(const stateName in machineDescription.states)machine.states.set(stateName, {\n name: stateName,\n ...machineDescription.states[stateName]\n });\n // validate transitions are states\n for (const state of machine.states.values())for (const transitionState of state.transitions){\n if (transitionState === \"*\") continue;\n if (!machine.states.has(transitionState)) throw Error(`Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`);\n }\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\n return machine;\n }\n in(state) {\n return this.currentState.name === state;\n }\n go(stateName, eventData) {\n var _a, _b;\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes(\"*\")) {\n const potentialNewState = this.states.get(stateName);\n if (this.currentState.onExit) {\n const canExit = (_a = this.currentState) === null || _a === void 0 ? void 0 : _a.onExit({\n to: potentialNewState.name,\n data: this.data\n });\n if (canExit === false) return false;\n }\n if (potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter) {\n const canEnter = potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter({\n from: this.currentState.name,\n eventData: eventData,\n data: this.data\n });\n if (canEnter === false) return false;\n }\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\n this.currentState = potentialNewState;\n if ((_b = this.currentState) === null || _b === void 0 ? void 0 : _b.onState) this.currentState.onState();\n return true;\n }\n return false;\n }\n update(elapsedMs) {\n if (this.currentState.onUpdate) this.currentState.onUpdate(this.data, elapsedMs);\n }\n save(saveKey) {\n localStorage.setItem(saveKey, JSON.stringify({\n currentState: this.currentState.name,\n data: this.data\n }));\n }\n restore(saveKey) {\n const state = JSON.parse(localStorage.getItem(saveKey));\n this.currentState = this.states.get(state.currentState);\n this.data = state.data;\n }\n }\n /**\n * Internal class representing a Web Audio AudioBufferSourceNode instance\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\n */ class WebAudioInstance {\n _createNewBufferSource() {\n this._instance = this._audioContext.createBufferSource();\n this._instance.buffer = this._src;\n this._instance.loop = this.loop;\n this._instance.playbackRate.value = this._playbackRate;\n this._instance.connect(this._volumeNode);\n this._volumeNode.connect(this._audioContext.destination);\n }\n _handleEnd() {\n if (!this.loop) this._instance.onended = ()=>{\n this._playingFuture.resolve(true);\n };\n }\n set loop(value) {\n this._loop = value;\n if (this._instance) {\n this._instance.loop = value;\n if (!this.loop) this._instance.onended = ()=>{\n this._playingFuture.resolve(true);\n };\n }\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n value = clamp(value, 0, 1.0);\n this._volume = value;\n if (this._stateMachine.in(\"PLAYING\") && this._volumeNode.gain.setTargetAtTime) // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\n // This exponential ramp provides a more pleasant transition in gain\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\n else this._volumeNode.gain.value = value;\n }\n get volume() {\n return this._volume;\n }\n /**\n * Returns the set duration to play, otherwise returns the total duration if unset\n */ get duration() {\n var _a;\n return (_a = this._duration) !== null && _a !== void 0 ? _a : this.getTotalPlaybackDuration();\n }\n /**\n * Set the duration that this audio should play.\n *\n * Note: if you seek to a specific point the duration will start from that point, for example\n *\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\n */ set duration(duration) {\n this._duration = duration;\n }\n constructor(_src){\n this._src = _src;\n this._audioContext = AudioContextFactory.create();\n this._volumeNode = this._audioContext.createGain();\n this._playingFuture = new Future();\n this._stateMachine = StateMachine.create({\n start: \"STOPPED\",\n states: {\n PLAYING: {\n onEnter: ({ data: data })=>{\n // Buffer nodes are single use\n this._createNewBufferSource();\n this._handleEnd();\n if (this.loop) // when looping don't set a duration\n this._instance.start(0, data.pausedAt * this._playbackRate);\n else this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\n data.startedAt = this._audioContext.currentTime - data.pausedAt;\n data.pausedAt = 0;\n },\n onState: ()=>this._playStarted(),\n onExit: ({ to: to })=>{\n // If you've exited early only resolve if explicitly STOPPED\n if (to === \"STOPPED\") this._playingFuture.resolve(true);\n // Whenever you're not playing... you stop!\n this._instance.onended = null; // disconnect the wired on-end handler\n this._instance.disconnect();\n this._instance.stop(0);\n this._instance = null;\n },\n transitions: [\n \"STOPPED\",\n \"PAUSED\",\n \"SEEK\"\n ]\n },\n SEEK: {\n onEnter: ({ eventData: position, data: data })=>{\n data.pausedAt = (position !== null && position !== void 0 ? position : 0) / this._playbackRate;\n data.startedAt = 0;\n },\n transitions: [\n \"*\"\n ]\n },\n STOPPED: {\n onEnter: ({ data: data })=>{\n data.pausedAt = 0;\n data.startedAt = 0;\n this._playingFuture.resolve(true);\n },\n transitions: [\n \"PLAYING\",\n \"PAUSED\",\n \"SEEK\"\n ]\n },\n PAUSED: {\n onEnter: ({ data: data })=>{\n // Playback rate will be a scale factor of how fast/slow the audio is being played\n // default is 1.0\n // we need to invert it to get the time scale\n data.pausedAt = this._audioContext.currentTime - data.startedAt;\n },\n transitions: [\n \"PLAYING\",\n \"STOPPED\",\n \"SEEK\"\n ]\n }\n }\n }, {\n startedAt: 0,\n pausedAt: 0\n });\n this._volume = 1;\n this._loop = false;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n this._playStarted = ()=>{};\n this._playbackRate = 1.0;\n this._createNewBufferSource();\n }\n isPlaying() {\n return this._stateMachine.in(\"PLAYING\");\n }\n isPaused() {\n return this._stateMachine.in(\"PAUSED\") || this._stateMachine.in(\"SEEK\");\n }\n isStopped() {\n return this._stateMachine.in(\"STOPPED\");\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n play(playStarted = ()=>{}) {\n this._playStarted = playStarted;\n this._stateMachine.go(\"PLAYING\");\n return this._playingFuture.promise;\n }\n pause() {\n this._stateMachine.go(\"PAUSED\");\n }\n stop() {\n this._stateMachine.go(\"STOPPED\");\n }\n seek(position) {\n this._stateMachine.go(\"PAUSED\");\n this._stateMachine.go(\"SEEK\", position);\n }\n getTotalPlaybackDuration() {\n return this._src.duration;\n }\n getPlaybackPosition() {\n const { pausedAt: pausedAt, startedAt: startedAt } = this._stateMachine.data;\n if (pausedAt) return pausedAt * this._playbackRate;\n if (startedAt) return (this._audioContext.currentTime - startedAt) * this._playbackRate;\n return 0;\n }\n set playbackRate(playbackRate) {\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\n }\n get playbackRate() {\n return this._instance.playbackRate.value;\n }\n }\n var EventTypes;\n (function(EventTypes) {\n EventTypes[\"Kill\"] = \"kill\";\n EventTypes[\"PreKill\"] = \"prekill\";\n EventTypes[\"PostKill\"] = \"postkill\";\n EventTypes[\"PreDraw\"] = \"predraw\";\n EventTypes[\"PostDraw\"] = \"postdraw\";\n EventTypes[\"PreDebugDraw\"] = \"predebugdraw\";\n EventTypes[\"PostDebugDraw\"] = \"postdebugdraw\";\n EventTypes[\"PreUpdate\"] = \"preupdate\";\n EventTypes[\"PostUpdate\"] = \"postupdate\";\n EventTypes[\"PreFrame\"] = \"preframe\";\n EventTypes[\"PostFrame\"] = \"postframe\";\n EventTypes[\"PreCollision\"] = \"precollision\";\n EventTypes[\"CollisionStart\"] = \"collisionstart\";\n EventTypes[\"CollisionEnd\"] = \"collisionend\";\n EventTypes[\"PostCollision\"] = \"postcollision\";\n EventTypes[\"Initialize\"] = \"initialize\";\n EventTypes[\"Activate\"] = \"activate\";\n EventTypes[\"Deactivate\"] = \"deactivate\";\n EventTypes[\"ExitViewport\"] = \"exitviewport\";\n EventTypes[\"EnterViewport\"] = \"enterviewport\";\n EventTypes[\"ExitTrigger\"] = \"exit\";\n EventTypes[\"EnterTrigger\"] = \"enter\";\n EventTypes[\"Connect\"] = \"connect\";\n EventTypes[\"Disconnect\"] = \"disconnect\";\n EventTypes[\"Button\"] = \"button\";\n EventTypes[\"Axis\"] = \"axis\";\n EventTypes[\"Visible\"] = \"visible\";\n EventTypes[\"Hidden\"] = \"hidden\";\n EventTypes[\"Start\"] = \"start\";\n EventTypes[\"Stop\"] = \"stop\";\n EventTypes[\"PointerUp\"] = \"pointerup\";\n EventTypes[\"PointerDown\"] = \"pointerdown\";\n EventTypes[\"PointerMove\"] = \"pointermove\";\n EventTypes[\"PointerEnter\"] = \"pointerenter\";\n EventTypes[\"PointerLeave\"] = \"pointerleave\";\n EventTypes[\"PointerCancel\"] = \"pointercancel\";\n EventTypes[\"PointerWheel\"] = \"pointerwheel\";\n EventTypes[\"Up\"] = \"up\";\n EventTypes[\"Down\"] = \"down\";\n EventTypes[\"Move\"] = \"move\";\n EventTypes[\"Enter\"] = \"enter\";\n EventTypes[\"Leave\"] = \"leave\";\n EventTypes[\"Cancel\"] = \"cancel\";\n EventTypes[\"Wheel\"] = \"wheel\";\n EventTypes[\"Press\"] = \"press\";\n EventTypes[\"Release\"] = \"release\";\n EventTypes[\"Hold\"] = \"hold\";\n EventTypes[\"PointerDragStart\"] = \"pointerdragstart\";\n EventTypes[\"PointerDragEnd\"] = \"pointerdragend\";\n EventTypes[\"PointerDragEnter\"] = \"pointerdragenter\";\n EventTypes[\"PointerDragLeave\"] = \"pointerdragleave\";\n EventTypes[\"PointerDragMove\"] = \"pointerdragmove\";\n EventTypes[\"ActionStart\"] = \"actionstart\";\n EventTypes[\"ActionComplete\"] = \"actioncomplete\";\n })(EventTypes || (EventTypes = {}));\n /**\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\n * some events are unique to a type, others are not.\n *\n */ class GameEvent {\n constructor(){\n this._bubbles = true;\n }\n /**\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\n * to all actors that apply.\n */ get bubbles() {\n return this._bubbles;\n }\n set bubbles(value) {\n this._bubbles = value;\n }\n /**\n * Prevents event from bubbling\n */ stopPropagation() {\n this.bubbles = false;\n }\n }\n /**\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\n */ class KillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'prekill' event is emitted directly before an actor is killed.\n */ class PreKillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'postkill' event is emitted directly after the actor is killed.\n */ class PostKillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'start' event is emitted on engine when has started and is ready for interaction.\n */ class GameStartEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\n */ class GameStopEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\n * transform so that all drawing takes place with the actor as the origin.\n *\n */ class PreDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\n * transform so that all drawing takes place with the actor as the origin.\n *\n */ class PostDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'pretransformdraw' event is emitted on actors/entities before any graphics transforms have taken place.\n * Useful if you need to completely customize the draw or modify the transform before drawing in the draw step (for example needing\n * latest camera positions)\n *\n */ class PreTransformDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'posttransformdraw' event is emitted on actors/entities after all graphics have been draw and transforms reset.\n * Useful if you need to completely custom the draw after everything is done.\n *\n */ class PostTransformDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\n */ class PreDebugDrawEvent extends GameEvent {\n constructor(ctx, target){\n super();\n this.ctx = ctx;\n this.target = target;\n }\n }\n /**\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\n */ class PostDebugDrawEvent extends GameEvent {\n constructor(ctx, target){\n super();\n this.ctx = ctx;\n this.target = target;\n }\n }\n /**\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\n */ class PreUpdateEvent extends GameEvent {\n constructor(engine, delta, target){\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\n */ class PostUpdateEvent extends GameEvent {\n constructor(engine, delta, target){\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'preframe' event is emitted on the engine, before the frame begins.\n */ class PreFrameEvent extends GameEvent {\n constructor(engine, prevStats){\n super();\n this.engine = engine;\n this.prevStats = prevStats;\n this.target = engine;\n }\n }\n /**\n * The 'postframe' event is emitted on the engine, after a frame ends.\n */ class PostFrameEvent extends GameEvent {\n constructor(engine, stats){\n super();\n this.engine = engine;\n this.stats = stats;\n this.target = engine;\n }\n }\n /**\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\n */ class GamepadConnectEvent extends GameEvent {\n constructor(index, gamepad){\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n }\n /**\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\n */ class GamepadDisconnectEvent extends GameEvent {\n constructor(index, gamepad){\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n }\n /**\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\n */ class GamepadButtonEvent extends GameEvent {\n /**\n * @param button The Gamepad button\n * @param value A numeric value between 0 and 1\n */ constructor(button, value, target){\n super();\n this.button = button;\n this.value = value;\n this.target = target;\n }\n }\n /**\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\n */ class GamepadAxisEvent extends GameEvent {\n /**\n * @param axis The Gamepad axis\n * @param value A numeric value between -1 and 1\n */ constructor(axis, value, target){\n super();\n this.axis = axis;\n this.value = value;\n this.target = target;\n }\n }\n /**\n * Event received by the [[Engine]] when the browser window is visible on a screen.\n */ class VisibleEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\n */ class HiddenEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\n */ class PreCollisionEvent extends GameEvent {\n /**\n * @param actor The actor the event was thrown on\n * @param other The actor that will collided with the current actor\n * @param side The side that will be collided with the current actor\n * @param intersection Intersection vector\n */ constructor(actor, other, side, intersection, contact){\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n this.target = actor;\n }\n }\n /**\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\n */ class PostCollisionEvent extends GameEvent {\n /**\n * @param actor The actor the event was thrown on\n * @param other The actor that did collide with the current actor\n * @param side The side that did collide with the current actor\n * @param intersection Intersection vector\n */ constructor(actor, other, side, intersection, contact){\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n class ContactStartEvent {\n constructor(target, other, side, contact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.contact = contact;\n }\n }\n class ContactEndEvent {\n constructor(target, other, side, lastContact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.lastContact = lastContact;\n }\n }\n class CollisionPreSolveEvent {\n constructor(target, other, side, intersection, contact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n }\n class CollisionPostSolveEvent {\n constructor(target, other, side, intersection, contact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n }\n /**\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\n */ class CollisionStartEvent extends GameEvent {\n /**\n *\n * @param actor\n * @param other\n * @param side\n * @param contact\n */ constructor(actor, other, side, contact){\n super();\n this.other = other;\n this.side = side;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n /**\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\n */ class CollisionEndEvent extends GameEvent {\n /**\n *\n */ constructor(actor, other, side, lastContact){\n super();\n this.other = other;\n this.side = side;\n this.lastContact = lastContact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n /**\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\n */ class InitializeEvent extends GameEvent {\n /**\n * @param engine The reference to the current engine\n */ constructor(engine, target){\n super();\n this.engine = engine;\n this.target = target;\n }\n }\n /**\n * Event thrown on a [[Scene]] on activation\n */ class ActivateEvent extends GameEvent {\n /**\n * @param context The context for the scene activation\n */ constructor(context, target){\n super();\n this.context = context;\n this.target = target;\n }\n }\n /**\n * Event thrown on a [[Scene]] on deactivation\n */ class DeactivateEvent extends GameEvent {\n /**\n * @param context The context for the scene deactivation\n */ constructor(context, target){\n super();\n this.context = context;\n this.target = target;\n }\n }\n /**\n * Event thrown on an [[Actor]] when the graphics bounds completely leaves the screen.\n */ class ExitViewPortEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * Event thrown on an [[Actor]] when any part of the graphics bounds are on screen.\n */ class EnterViewPortEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n class EnterTriggerEvent extends GameEvent {\n constructor(target, actor){\n super();\n this.target = target;\n this.actor = actor;\n }\n }\n class ExitTriggerEvent extends GameEvent {\n constructor(target, actor){\n super();\n this.target = target;\n this.actor = actor;\n }\n }\n /**\n * Event thrown on an [[Actor]] when an action starts.\n */ class ActionStartEvent extends GameEvent {\n constructor(action, target){\n super();\n this.action = action;\n this.target = target;\n }\n }\n /**\n * Event thrown on an [[Actor]] when an action completes.\n */ class ActionCompleteEvent extends GameEvent {\n constructor(action, target){\n super();\n this.action = action;\n this.target = target;\n }\n }\n class MediaEvent extends GameEvent {\n /**\n * Media event cannot bubble\n */ set bubbles(_value) {\n // stubbed\n }\n /**\n * Media event cannot bubble\n */ get bubbles() {\n return false;\n }\n /**\n * Media event cannot bubble, so they have no path\n */ get _path() {\n return null;\n }\n /**\n * Media event cannot bubble, so they have no path\n */ set _path(_val) {\n // stubbed\n }\n constructor(target, _name = \"MediaEvent\"){\n super();\n this.target = target;\n this._name = _name;\n }\n /**\n * Prevents event from bubbling\n */ stopPropagation() {\n /**\n * Stub\n */ }\n /**\n * Action, that calls when event happens\n */ action() {\n /**\n * Stub\n */ }\n /**\n * Propagate event further through event path\n */ propagate() {\n /**\n * Stub\n */ }\n layPath(_actor) {\n /**\n * Stub\n */ }\n }\n class NativeSoundEvent extends MediaEvent {\n constructor(target, track){\n super(target, \"NativeSoundEvent\");\n this.track = track;\n }\n }\n class NativeSoundProcessedEvent extends MediaEvent {\n constructor(target, _processedData){\n super(target, \"NativeSoundProcessedEvent\");\n this._processedData = _processedData;\n this.data = this._processedData;\n }\n }\n /**\n * Whether or not the browser can play this file as HTML5 Audio\n */ function canPlayFile(file) {\n try {\n const a = new Audio();\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\n const type = file.match(filetype)[1];\n if (a.canPlayType(\"audio/\" + type)) return true;\n else return false;\n } catch (e) {\n Logger.getInstance().warn(\"Cannot determine audio support, assuming no support for the Audio Tag\", e);\n return false;\n }\n }\n const SoundEvents = {\n VolumeChange: \"volumechange\",\n Processed: \"processed\",\n Pause: \"pause\",\n Stop: \"stop\",\n PlaybackEnd: \"playbackend\",\n Resume: \"resume\",\n PlaybackStart: \"playbackstart\"\n };\n /**\n * The [[Sound]] object allows games built in Excalibur to load audio\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\n */ class Sound {\n /**\n * Indicates whether the clip should loop when complete\n * @param value Set the looping flag\n */ set loop(value) {\n this._loop = value;\n for (const track of this._tracks)track.loop = this._loop;\n this.logger.debug(\"Set loop for all instances of sound\", this.path, \"to\", this._loop);\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n this._volume = value;\n for (const track of this._tracks)track.volume = this._volume;\n this.events.emit(\"volumechange\", new NativeSoundEvent(this));\n this.logger.debug(\"Set loop for all instances of sound\", this.path, \"to\", this._volume);\n }\n get volume() {\n return this._volume;\n }\n /**\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\n */ get duration() {\n return this._duration;\n }\n /**\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\n *\n * Note: if you seek to a specific point the duration will start from that point, for example\n *\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\n */ set duration(duration) {\n this._duration = duration;\n }\n /**\n * Return array of Current AudioInstances playing or being paused\n */ get instances() {\n return this._tracks;\n }\n get path() {\n return this._resource.path;\n }\n set path(val) {\n this._resource.path = val;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\n */ constructor(...paths){\n this.events = new EventEmitter();\n this.logger = Logger.getInstance();\n this._loop = false;\n this._volume = 1;\n this._isStopped = false;\n // private _isPaused = false;\n this._tracks = [];\n this._wasPlayingOnHidden = false;\n this._playbackRate = 1.0;\n this._audioContext = AudioContextFactory.create();\n this._resource = new Resource(\"\", ExResponse.type.arraybuffer);\n /**\n * Chrome : MP3, WAV, Ogg\n * Firefox : WAV, Ogg,\n * IE : MP3, WAV coming soon\n * Safari MP3, WAV, Ogg\n */ for (const path of paths)if (canPlayFile(path)) {\n this.path = path;\n break;\n }\n if (!this.path) {\n this.logger.warn(\"This browser does not support any of the audio files specified:\", paths.join(\", \"));\n this.logger.warn(\"Attempting to use\", paths[0]);\n this.path = paths[0]; // select the first specified\n }\n }\n isLoaded() {\n return !!this.data;\n }\n async load() {\n var _a, _b;\n if (this.data) return this.data;\n const arraybuffer = await this._resource.load();\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\n this._duration = (_b = (_a = this._duration) !== null && _a !== void 0 ? _a : audiobuffer === null || audiobuffer === void 0 ? void 0 : audiobuffer.duration) !== null && _b !== void 0 ? _b : undefined;\n this.events.emit(\"processed\", new NativeSoundProcessedEvent(this, audiobuffer));\n return this.data = audiobuffer;\n }\n async decodeAudio(data) {\n try {\n return await this._audioContext.decodeAudioData(data.slice(0));\n } catch (e) {\n this.logger.error(\"Unable to decode this browser may not fully support this format, or the file may be corrupt, if this is an mp3 try removing id3 tags and album art from the file.\");\n return await Promise.reject();\n }\n }\n wireEngine(engine) {\n if (engine) {\n this._engine = engine;\n this._engine.on(\"hidden\", ()=>{\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\n this._wasPlayingOnHidden = true;\n this.pause();\n }\n });\n this._engine.on(\"visible\", ()=>{\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.play();\n this._wasPlayingOnHidden = false;\n }\n });\n this._engine.on(\"start\", ()=>{\n this._isStopped = false;\n });\n this._engine.on(\"stop\", ()=>{\n this.stop();\n this._isStopped = true;\n });\n }\n }\n /**\n * Returns how many instances of the sound are currently playing\n */ instanceCount() {\n return this._tracks.length;\n }\n /**\n * Whether or not the sound is playing right now\n */ isPlaying() {\n return this._tracks.some((t)=>t.isPlaying());\n }\n isPaused() {\n return this._tracks.some((t)=>t.isPaused());\n }\n isStopped() {\n return this._tracks.some((t)=>t.isStopped());\n }\n /**\n * Play the sound, returns a promise that resolves when the sound is done playing\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\n */ play(volume) {\n if (!this.isLoaded()) {\n this.logger.warn(\"Cannot start playing. Resource\", this.path, \"is not loaded yet\");\n return Promise.resolve(true);\n }\n if (this._isStopped) {\n this.logger.warn(\"Cannot start playing. Engine is in a stopped state.\");\n return Promise.resolve(false);\n }\n this.volume = volume || this.volume;\n if (this.isPaused()) return this._resumePlayback();\n else return this._startPlayback();\n }\n /**\n * Stop the sound, and do not rewind\n */ pause() {\n if (!this.isPlaying()) return;\n for (const track of this._tracks)track.pause();\n this.events.emit(\"pause\", new NativeSoundEvent(this));\n this.logger.debug(\"Paused all instances of sound\", this.path);\n }\n /**\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\n */ stop() {\n for (const track of this._tracks)track.stop();\n this.events.emit(\"stop\", new NativeSoundEvent(this));\n this._tracks.length = 0;\n this.logger.debug(\"Stopped all instances of sound\", this.path);\n }\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(playbackRate) {\n this._playbackRate = playbackRate;\n this._tracks.forEach((t)=>{\n t.playbackRate = this._playbackRate;\n });\n }\n seek(position, trackId = 0) {\n if (this._tracks.length === 0) this._getTrackInstance(this.data);\n this._tracks[trackId].seek(position);\n }\n getTotalPlaybackDuration() {\n if (!this.isLoaded()) {\n this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.` + `Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`);\n return 0;\n }\n return this.data.duration;\n }\n /**\n * Return the current playback time of the playing track in seconds from the start.\n *\n * Optionally specify the track to query if multiple are playing at once.\n * @param trackId\n */ getPlaybackPosition(trackId = 0) {\n if (this._tracks.length) return this._tracks[trackId].getPlaybackPosition();\n return 0;\n }\n /**\n * Get Id of provided AudioInstance in current trackList\n * @param track [[Audio]] which Id is to be given\n */ getTrackId(track) {\n return this._tracks.indexOf(track);\n }\n async _resumePlayback() {\n if (this.isPaused) {\n const resumed = [];\n // ensure we resume *current* tracks (if paused)\n for (const track of this._tracks)resumed.push(track.play().then(()=>{\n this._tracks.splice(this.getTrackId(track), 1);\n return true;\n }));\n this.events.emit(\"resume\", new NativeSoundEvent(this));\n this.logger.debug(\"Resuming paused instances for sound\", this.path, this._tracks);\n // resolve when resumed tracks are done\n await Promise.all(resumed);\n }\n return true;\n }\n /**\n * Starts playback, returns a promise that resolves when playback is complete\n */ async _startPlayback() {\n const track = this._getTrackInstance(this.data);\n const complete = await track.play(()=>{\n this.events.emit(\"playbackstart\", new NativeSoundEvent(this, track));\n this.logger.debug(\"Playing new instance for sound\", this.path);\n });\n this.events.emit(\"playbackend\", new NativeSoundEvent(this, track));\n // cleanup any done tracks\n const trackId = this.getTrackId(track);\n if (trackId !== -1) this._tracks.splice(trackId, 1);\n return complete;\n }\n _getTrackInstance(data) {\n const newTrack = new WebAudioInstance(data);\n newTrack.loop = this.loop;\n newTrack.volume = this.volume;\n newTrack.duration = this.duration;\n newTrack.playbackRate = this._playbackRate;\n this._tracks.push(newTrack);\n return newTrack;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n const LoaderEvents = {\n // Add event types here\n BeforeLoad: \"beforeload\",\n AfterLoad: \"afterload\",\n UserAction: \"useraction\",\n LoadResourceStart: \"loadresourcestart\",\n LoadResourceEnd: \"loadresourceend\"\n };\n /**\n * Returns true if the constructor is for an Excalibur Loader\n */ function isLoaderConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n }\n class DefaultLoader {\n get resources() {\n return this._resources;\n }\n /**\n * @param options Optionally provide the list of resources you want to load at constructor time\n */ constructor(options){\n var _a;\n this.events = new EventEmitter();\n this.canvas = new Canvas({\n filtering: ImageFiltering.Blended,\n smoothing: true,\n cache: false,\n draw: this.onDraw.bind(this)\n });\n this._resources = [];\n this._numLoaded = 0;\n this._totalTimeMs = 0;\n this._loadingFuture = new Future();\n if (options && ((_a = options.loadables) === null || _a === void 0 ? void 0 : _a.length)) this.addResources(options.loadables);\n }\n /**\n * Called by the engine before loading\n * @param engine\n */ onInitialize(engine) {\n this.engine = engine;\n this.canvas.width = this.engine.screen.resolution.width;\n this.canvas.height = this.engine.screen.resolution.height;\n }\n /**\n * Return a promise that resolves when the user interacts with the loading screen in some way, usually a click.\n *\n * It's important to implement this in order to unlock the audio context in the browser. Browsers automatically prevent\n * audio from playing until the user performs an action.\n *\n */ async onUserAction() {\n return await Promise.resolve();\n }\n /**\n * Overridable lifecycle method, called directly before loading starts\n */ async onBeforeLoad() {\n // override me\n }\n /**\n * Overridable lifecycle method, called after loading has completed\n */ async onAfterLoad() {\n // override me\n await delay(500, this.engine.clock); // avoid a flicker\n }\n /**\n * Add a resource to the loader to load\n * @param loadable Resource to add\n */ addResource(loadable) {\n this._resources.push(loadable);\n }\n /**\n * Add a list of resources to the loader to load\n * @param loadables The list of resources to load\n */ addResources(loadables) {\n let i = 0;\n const len = loadables.length;\n for(i; i < len; i++)this.addResource(loadables[i]);\n }\n markResourceComplete() {\n this._numLoaded++;\n }\n /**\n * Returns the progress of the loader as a number between [0, 1] inclusive.\n */ get progress() {\n const total = this._resources.length;\n return total > 0 ? clamp(this._numLoaded, 0, total) / total : 1;\n }\n /**\n * Returns true if the loader has completely loaded all resources\n */ isLoaded() {\n return this._numLoaded === this._resources.length;\n }\n /**\n * Optionally override the onUpdate\n * @param engine\n * @param elapsedMilliseconds\n */ onUpdate(engine, elapsedMilliseconds) {\n this._totalTimeMs += elapsedMilliseconds;\n // override me\n }\n /**\n * Optionally override the onDraw\n */ onDraw(ctx) {\n const seconds = this._totalTimeMs / 1000;\n ctx.fillStyle = Color.Black.toRGBA();\n ctx.fillRect(0, 0, this.engine.screen.resolution.width, this.engine.screen.resolution.height);\n ctx.save();\n ctx.translate(this.engine.screen.resolution.width / 2, this.engine.screen.resolution.height / 2);\n const speed = seconds * 10;\n ctx.strokeStyle = \"white\";\n ctx.lineWidth = 10;\n ctx.lineCap = \"round\";\n ctx.arc(0, 0, 40, speed, speed + Math.PI * 3 / 2);\n ctx.stroke();\n ctx.fillStyle = \"white\";\n ctx.font = \"16px sans-serif\";\n const text = (this.progress * 100).toFixed(0) + \"%\";\n const textbox = ctx.measureText(text);\n const width = Math.abs(textbox.actualBoundingBoxLeft) + Math.abs(textbox.actualBoundingBoxRight);\n const height = Math.abs(textbox.actualBoundingBoxAscent) + Math.abs(textbox.actualBoundingBoxDescent);\n ctx.fillText(text, -width / 2, height / 2); // center\n ctx.restore();\n }\n areResourcesLoaded() {\n return this._loadingFuture.promise;\n }\n /**\n * Not meant to be overridden\n *\n * Begin loading all of the supplied resources, returning a promise\n * that resolves when loading of all is complete AND the user has interacted with the loading screen\n */ async load() {\n await this.onBeforeLoad();\n this.events.emit(\"beforeload\");\n this.canvas.flagDirty();\n await Promise.all(this._resources.map(async (r)=>{\n this.events.emit(\"loadresourcestart\", r);\n await r.load().finally(()=>{\n // capture progress\n this._numLoaded++;\n this.canvas.flagDirty();\n this.events.emit(\"loadresourceend\", r);\n });\n }));\n // Wire all sound to the engine\n for (const resource of this._resources)if (resource instanceof Sound) resource.wireEngine(this.engine);\n this._loadingFuture.resolve();\n this.canvas.flagDirty();\n // Unlock browser AudioContext in after user gesture\n // See: https://github.com/excaliburjs/Excalibur/issues/262\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\n await this.onUserAction();\n this.events.emit(\"useraction\");\n await WebAudio.unlock();\n await this.onAfterLoad();\n this.events.emit(\"afterload\");\n return this.data = this._resources;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n /* istanbul ignore next */ /**\n * Draw a line on canvas context\n * @param ctx The canvas context\n * @param color The color of the line\n * @param x1 The start x coordinate\n * @param y1 The start y coordinate\n * @param x2 The ending x coordinate\n * @param y2 The ending y coordinate\n * @param thickness The line thickness\n * @param cap The [[LineCapStyle]] (butt, round, or square)\n */ function line(ctx, color = Color.Red, x1, y1, x2, y2, thickness = 1, cap = \"butt\") {\n ctx.save();\n ctx.beginPath();\n ctx.lineWidth = thickness;\n ctx.lineCap = cap;\n ctx.strokeStyle = color.toString();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.closePath();\n ctx.stroke();\n ctx.restore();\n }\n /* istanbul ignore next */ /**\n * Draw the vector as a point onto the canvas.\n */ function point(ctx, color = Color.Red, point) {\n ctx.beginPath();\n ctx.strokeStyle = color.toString();\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\n ctx.closePath();\n ctx.stroke();\n }\n /**\n * Draw the vector as a line onto the canvas starting a origin point.\n */ /* istanbul ignore next */ /**\n *\n */ function vector(ctx, color, origin, vector, scale = 1.0) {\n const c = color ? color.toString() : \"blue\";\n const v = vector.scale(scale);\n ctx.beginPath();\n ctx.strokeStyle = c;\n ctx.moveTo(origin.x, origin.y);\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\n ctx.closePath();\n ctx.stroke();\n }\n /**\n * Draw a round rectangle on a canvas context\n * @param ctx The canvas context\n * @param x The top-left x coordinate\n * @param y The top-left y coordinate\n * @param width The width of the rectangle\n * @param height The height of the rectangle\n * @param radius The border radius of the rectangle\n * @param stroke The [[Color]] to stroke rectangle with\n * @param fill The [[Color]] to fill rectangle with\n */ function roundRect(ctx, x, y, width, height, radius = 5, stroke = Color.White, fill = null) {\n let br;\n if (typeof radius === \"number\") br = {\n tl: radius,\n tr: radius,\n br: radius,\n bl: radius\n };\n else {\n const defaultRadius = {\n tl: 0,\n tr: 0,\n br: 0,\n bl: 0\n };\n for(const prop in defaultRadius)if (defaultRadius.hasOwnProperty(prop)) {\n const side = prop;\n br[side] = radius[side] || defaultRadius[side];\n }\n }\n ctx.beginPath();\n ctx.moveTo(x + br.tl, y);\n ctx.lineTo(x + width - br.tr, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\n ctx.lineTo(x + width, y + height - br.br);\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\n ctx.lineTo(x + br.bl, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\n ctx.lineTo(x, y + br.tl);\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n }\n /**\n *\n */ function circle(ctx, x, y, radius, stroke = Color.White, fill = null) {\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, Math.PI * 2);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n }\n /* harmony default export */ const Loader_logo = \"data:image/png;base64,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\";\n // EXTERNAL MODULE: ./Director/Loader.css\n var Director_Loader = $2c23f148d58cd887$var$__webpack_require__(7835);\n /**\n * Pre-loading assets\n *\n * The loader provides a mechanism to preload multiple resources at\n * one time. The loader must be passed to the engine in order to\n * trigger the loading progress bar.\n *\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\n *\n * ## Example: Pre-loading resources for a game\n *\n * ```js\n * // create a loader\n * var loader = new ex.Loader();\n *\n * // create a resource dictionary (best practice is to keep a separate file)\n * var resources = {\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\n * };\n *\n * // loop through dictionary and add to loader\n * for (var loadable in resources) {\n * if (resources.hasOwnProperty(loadable)) {\n * loader.addResource(resources[loadable]);\n * }\n * }\n *\n * // start game\n * game.start(loader).then(function () {\n * console.log(\"Game started!\");\n * });\n * ```\n *\n * ## Customize the Loader\n *\n * The loader can be customized to show different, text, logo, background color, and button.\n *\n * ```typescript\n * const loader = new ex.Loader([playerTexture]);\n *\n * // The loaders button text can simply modified using this\n * loader.playButtonText = 'Start the best game ever';\n *\n * // The logo can be changed by inserting a base64 image string here\n *\n * loader.logo = 'data:image/png;base64,iVBORw...';\n * loader.logoWidth = 15;\n * loader.logoHeight = 14;\n *\n * // The background color can be changed like so by supplying a valid CSS color string\n *\n * loader.backgroundColor = 'red'\n * loader.backgroundColor = '#176BAA'\n *\n * // To build a completely new button\n * loader.startButtonFactory = () => {\n * let myButton = document.createElement('button');\n * myButton.textContent = 'The best button';\n * return myButton;\n * };\n *\n * engine.start(loader).then(() => {});\n * ```\n */ class Loader extends DefaultLoader {\n get _image() {\n if (!this._imageElement) {\n this._imageElement = new Image();\n this._imageElement.src = this.logo;\n }\n return this._imageElement;\n }\n get playButtonRootElement() {\n return this._playButtonRootElement;\n }\n get playButtonElement() {\n return this._playButtonElement;\n }\n get _playButton() {\n const existingRoot = document.getElementById(\"excalibur-play-root\");\n if (existingRoot) this._playButtonRootElement = existingRoot;\n if (!this._playButtonRootElement) {\n this._playButtonRootElement = document.createElement(\"div\");\n this._playButtonRootElement.id = \"excalibur-play-root\";\n this._playButtonRootElement.style.position = \"absolute\";\n document.body.appendChild(this._playButtonRootElement);\n }\n if (!this._styleBlock) {\n this._styleBlock = document.createElement(\"style\");\n this._styleBlock.textContent = this._playButtonStyles;\n document.head.appendChild(this._styleBlock);\n }\n if (!this._playButtonElement) {\n this._playButtonElement = this.startButtonFactory();\n this._playButtonRootElement.appendChild(this._playButtonElement);\n }\n return this._playButtonElement;\n }\n constructor(loadablesOrOptions){\n const options = Array.isArray(loadablesOrOptions) ? {\n loadables: loadablesOrOptions\n } : loadablesOrOptions;\n super(options);\n this._logger = Logger.getInstance();\n this._originalOptions = {\n loadables: []\n };\n this.events = new EventEmitter();\n this._playButtonShown = false;\n // logo drawing stuff\n // base64 string encoding of the excalibur logo (logo-white.png)\n this.logo = Loader_logo;\n this.logoWidth = 468;\n this.logoHeight = 118;\n /**\n * Gets or sets the color of the loading bar, default is [[Color.White]]\n */ this.loadingBarColor = Color.White;\n /**\n * Gets or sets the background color of the loader as a hex string\n */ this.backgroundColor = \"#176BAA\";\n this.suppressPlayButton = false;\n /** Loads the css from Loader.css */ this._playButtonStyles = Director_Loader /* default */ .Z.toString();\n /**\n * Get/set play button text\n */ this.playButtonText = \"Play game\";\n /**\n * Return a html button element for excalibur to use as a play button\n */ this.startButtonFactory = ()=>{\n let buttonElement = document.getElementById(\"excalibur-play\");\n if (!buttonElement) buttonElement = document.createElement(\"button\");\n buttonElement.id = \"excalibur-play\";\n buttonElement.textContent = this.playButtonText;\n buttonElement.style.display = \"none\";\n return buttonElement;\n };\n this._configuredPixelRatio = null;\n this._originalOptions = {\n ...Loader._DEFAULT_LOADER_OPTIONS,\n ...options\n };\n }\n onInitialize(engine) {\n this.engine = engine;\n this.screen = engine.screen;\n this.canvas.width = this.engine.canvas.width;\n this.canvas.height = this.engine.canvas.height;\n }\n /**\n * Shows the play button and returns a promise that resolves when clicked\n */ async showPlayButton() {\n var _a, _b;\n if (this.suppressPlayButton) {\n this.hidePlayButton();\n // Delay is to give the logo a chance to show, otherwise don't delay\n await delay(500, (_a = this.engine) === null || _a === void 0 ? void 0 : _a.clock);\n } else {\n const resizeHandler = ()=>{\n try {\n this._positionPlayButton();\n } catch (_a) {\n // swallow if can't position\n }\n };\n if ((_b = this.engine) === null || _b === void 0 ? void 0 : _b.browser) this.engine.browser.window.on(\"resize\", resizeHandler);\n this._playButtonShown = true;\n this._playButton.style.display = \"block\";\n document.body.addEventListener(\"keyup\", (evt)=>{\n if (evt.key === \"Enter\") this._playButton.click();\n });\n this._positionPlayButton();\n const playButtonClicked = new Promise((resolve)=>{\n const startButtonHandler = (e)=>{\n var _a;\n // We want to stop propagation to keep bubbling to the engine pointer handlers\n e.stopPropagation();\n // Hide Button after click\n this.hidePlayButton();\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.browser) this.engine.browser.window.off(\"resize\", resizeHandler);\n if (this._originalOptions.fullscreenAfterLoad) try {\n this._logger.info(\"requesting fullscreen\");\n if (this._originalOptions.fullscreenContainer instanceof HTMLElement) this._originalOptions.fullscreenContainer.requestFullscreen();\n else this.engine.screen.goFullScreen(this._originalOptions.fullscreenContainer);\n } catch (error) {\n this._logger.error(\"could not go fullscreen\", error);\n }\n resolve();\n };\n this._playButton.addEventListener(\"click\", startButtonHandler);\n this._playButton.addEventListener(\"touchend\", startButtonHandler);\n this._playButton.addEventListener(\"pointerup\", startButtonHandler);\n });\n return await playButtonClicked;\n }\n }\n hidePlayButton() {\n this._playButtonShown = false;\n this._playButton.style.display = \"none\";\n }\n /**\n * Clean up generated elements for the loader\n */ dispose() {\n if (this._playButtonRootElement.parentElement) {\n this._playButtonRootElement.removeChild(this._playButtonElement);\n document.body.removeChild(this._playButtonRootElement);\n document.head.removeChild(this._styleBlock);\n this._playButtonRootElement = null;\n this._playButtonElement = null;\n this._styleBlock = null;\n }\n }\n async onUserAction() {\n var _a;\n // short delay in showing the button for aesthetics\n await delay(200, (_a = this.engine) === null || _a === void 0 ? void 0 : _a.clock);\n this.canvas.flagDirty();\n // show play button\n await this.showPlayButton();\n }\n async onBeforeLoad() {\n var _a;\n this._configuredPixelRatio = this.screen.pixelRatioOverride;\n // Push the current user entered resolution/viewport\n this.screen.pushResolutionAndViewport();\n // Configure resolution for loader, it expects resolution === viewport\n this.screen.resolution = this.screen.viewport;\n this.screen.pixelRatioOverride = 1;\n this.screen.applyResolutionAndViewport();\n this.canvas.width = this.engine.canvas.width;\n this.canvas.height = this.engine.canvas.height;\n await ((_a = this._image) === null || _a === void 0 ? void 0 : _a.decode()); // decode logo if it exists\n }\n // eslint-disable-next-line require-await\n async onAfterLoad() {\n this.screen.pixelRatioOverride = this._configuredPixelRatio;\n this.screen.popResolutionAndViewport();\n this.screen.applyResolutionAndViewport();\n this.dispose();\n }\n _positionPlayButton() {\n if (this.engine) {\n const screenHeight = this.engine.screen.viewport.height;\n const screenWidth = this.engine.screen.viewport.width;\n if (this._playButtonRootElement) {\n const left = this.engine.canvas.offsetLeft;\n const top = this.engine.canvas.offsetTop;\n const buttonWidth = this._playButton.clientWidth;\n const buttonHeight = this._playButton.clientHeight;\n if (this.playButtonPosition) {\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\n } else {\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\n }\n }\n }\n }\n /**\n * Loader draw function. Draws the default Excalibur loading screen.\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\n * to customize the drawing, or just override entire method.\n */ onDraw(ctx) {\n const canvasHeight = this.engine.canvasHeight / this.engine.pixelRatio;\n const canvasWidth = this.engine.canvasWidth / this.engine.pixelRatio;\n this._positionPlayButton();\n ctx.fillStyle = this.backgroundColor;\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\n let logoY = canvasHeight / 2;\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\n let logoX = canvasWidth / 2 - width / 2;\n if (this.logoPosition) {\n logoX = this.logoPosition.x;\n logoY = this.logoPosition.y;\n }\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\n const oldAntialias = this.engine.getAntialiasing();\n this.engine.setAntialiasing(true);\n if (!this.logoPosition) ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\n else ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\n // loading box\n if (!this.suppressPlayButton && this._playButtonShown) {\n this.engine.setAntialiasing(oldAntialias);\n return;\n }\n let loadingX = logoX;\n let loadingY = logoY;\n if (this.loadingBarPosition) {\n loadingX = this.loadingBarPosition.x;\n loadingY = this.loadingBarPosition.y;\n }\n ctx.lineWidth = 2;\n roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\n const progress = width * this.progress;\n const margin = 5;\n const progressWidth = progress - margin * 2;\n const height = 20 - margin * 2;\n roundRect(ctx, loadingX + margin, loadingY + margin, progressWidth > 10 ? progressWidth : 10, height, 5, null, this.loadingBarColor);\n this.engine.setAntialiasing(oldAntialias);\n }\n }\n Loader._DEFAULT_LOADER_OPTIONS = {\n loadables: [],\n fullscreenAfterLoad: false,\n fullscreenContainer: undefined\n };\n /**\n * This is the list of features that will be used to log the supported\n * features to the console when Detector.logBrowserFeatures() is called.\n */ const REPORTED_FEATURES = {\n webgl: \"WebGL\",\n webaudio: \"WebAudio\",\n gamepadapi: \"Gamepad API\"\n };\n /**\n * Excalibur internal feature detection helper class\n */ class Detector {\n constructor(){\n this._features = null;\n this.failedTests = [];\n // critical browser features required for ex to run\n this._criticalTests = {\n // Test canvas/2d context support\n canvasSupport: function() {\n const elem = document.createElement(\"canvas\");\n return !!(elem.getContext && elem.getContext(\"2d\"));\n },\n // Test array buffer support ex uses for downloading binary data\n arrayBufferSupport: function() {\n const xhr = new XMLHttpRequest();\n xhr.open(\"GET\", \"/\");\n try {\n xhr.responseType = \"arraybuffer\";\n } catch (e) {\n return false;\n }\n return xhr.responseType === \"arraybuffer\";\n },\n // Test data urls ex uses for sprites\n dataUrlSupport: function() {\n const canvas = document.createElement(\"canvas\");\n return canvas.toDataURL(\"image/png\").indexOf(\"data:image/png\") === 0;\n },\n // Test object url support for loading\n objectUrlSupport: function() {\n return \"URL\" in window && \"revokeObjectURL\" in URL && \"createObjectURL\" in URL;\n },\n // RGBA support for colors\n rgbaSupport: function() {\n const style = document.createElement(\"a\").style;\n style.cssText = \"background-color:rgba(150,255,150,.5)\";\n return (\"\" + style.backgroundColor).indexOf(\"rgba\") > -1;\n }\n };\n // warnings excalibur performance will be degraded\n this._warningTest = {\n webAudioSupport: function() {\n return !!(window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext || window.oAudioContext);\n },\n webglSupport: function() {\n const elem = document.createElement(\"canvas\");\n return !!(elem.getContext && elem.getContext(\"webgl\"));\n }\n };\n this._features = this._loadBrowserFeatures();\n }\n /**\n * Returns a map of currently supported browser features. This method\n * treats the features as a singleton and will only calculate feature\n * support if it has not previously been done.\n */ getBrowserFeatures() {\n if (this._features === null) this._features = this._loadBrowserFeatures();\n return this._features;\n }\n /**\n * Report on non-critical browser support for debugging purposes.\n * Use native browser console colors for visibility.\n */ logBrowserFeatures() {\n let msg = \"%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n\";\n const args = [\n \"font-weight: bold; color: navy\",\n \"font-weight: normal; color: inherit\"\n ];\n const supported = this.getBrowserFeatures();\n for (const feature of Object.keys(REPORTED_FEATURES)){\n if (supported[feature]) {\n msg += \"(%c\\u2713%c)\"; // (✓)\n args.push(\"font-weight: bold; color: green\");\n args.push(\"font-weight: normal; color: inherit\");\n } else {\n msg += \"(%c\\u2717%c)\"; // (✗)\n args.push(\"font-weight: bold; color: red\");\n args.push(\"font-weight: normal; color: inherit\");\n }\n msg += \" \" + REPORTED_FEATURES[feature] + \"\\n\";\n }\n args.unshift(msg);\n // eslint-disable-next-line no-console\n console.log.apply(console, args);\n }\n /**\n * Executes several IIFE's to get a constant reference to supported\n * features within the current execution context.\n */ _loadBrowserFeatures() {\n return {\n // IIFE to check canvas support\n canvas: (()=>{\n return this._criticalTests.canvasSupport();\n })(),\n // IIFE to check arraybuffer support\n arraybuffer: (()=>{\n return this._criticalTests.arrayBufferSupport();\n })(),\n // IIFE to check dataurl support\n dataurl: (()=>{\n return this._criticalTests.dataUrlSupport();\n })(),\n // IIFE to check objecturl support\n objecturl: (()=>{\n return this._criticalTests.objectUrlSupport();\n })(),\n // IIFE to check rgba support\n rgba: (()=>{\n return this._criticalTests.rgbaSupport();\n })(),\n // IIFE to check webaudio support\n webaudio: (()=>{\n return this._warningTest.webAudioSupport();\n })(),\n // IIFE to check webgl support\n webgl: (()=>{\n return this._warningTest.webglSupport();\n })(),\n // IIFE to check gamepadapi support\n gamepadapi: (()=>{\n return !!navigator.getGamepads;\n })()\n };\n }\n test() {\n // Critical test will for ex not to run\n let failedCritical = false;\n for(const test in this._criticalTests)if (!this._criticalTests[test].call(this)) {\n this.failedTests.push(test);\n Logger.getInstance().error(\"Critical browser feature missing, Excalibur requires:\", test);\n failedCritical = true;\n }\n if (failedCritical) return false;\n // Warning tests do not for ex to return false to compatibility\n for(const warning in this._warningTest)if (!this._warningTest[warning]()) Logger.getInstance().warn(\"Warning browser feature missing, Excalibur will have reduced performance:\", warning);\n return true;\n }\n }\n /**\n * An enum that describes the types of collisions bodies can participate in\n */ var CollisionType;\n (function(CollisionType) {\n /**\n * Bodies with the `PreventCollision` setting do not participate in any\n * collisions and do not raise collision events.\n */ CollisionType[\"PreventCollision\"] = \"PreventCollision\";\n /**\n * Bodies with the `Passive` setting only raise collision events, but are not\n * influenced or moved by other bodies and do not influence or move other bodies.\n * This is useful for use in trigger type behavior.\n */ CollisionType[\"Passive\"] = \"Passive\";\n /**\n * Bodies with the `Active` setting raise collision events and participate\n * in collisions with other bodies and will be push or moved by bodies sharing\n * the `Active` or `Fixed` setting.\n */ CollisionType[\"Active\"] = \"Active\";\n /**\n * Bodies with the `Fixed` setting raise collision events and participate in\n * collisions with other bodies. Actors with the `Fixed` setting will not be\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\n * not be pushed or moved by each other, they will not interact except to throw\n * collision events.\n */ CollisionType[\"Fixed\"] = \"Fixed\";\n })(CollisionType || (CollisionType = {}));\n /**\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\n */ var CoordPlane;\n (function(CoordPlane) {\n /**\n * The world coordinate plane (default) represents world space, any entities drawn with world\n * space move when the camera moves.\n */ CoordPlane[\"World\"] = \"world\";\n /**\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\n * to screen coordinates ignoring the camera.\n */ CoordPlane[\"Screen\"] = \"screen\";\n })(CoordPlane || (CoordPlane = {}));\n class VectorView extends Vector {\n constructor(options){\n super(0, 0);\n this._getX = options.getX;\n this._getY = options.getY;\n this._setX = options.setX;\n this._setY = options.setY;\n }\n get x() {\n return this._x = this._getX();\n }\n set x(val) {\n this._setX(val);\n this._x = val;\n }\n get y() {\n return this._y = this._getY();\n }\n set y(val) {\n this._setY(val);\n this._y = val;\n }\n }\n /**\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\n */ class WatchVector extends Vector {\n constructor(original, change){\n super(original.x, original.y);\n this.original = original;\n this.change = change;\n }\n get x() {\n return this._x = this.original.x;\n }\n set x(newX) {\n this.change(newX, this._y);\n this._x = this.original.x = newX;\n }\n get y() {\n return this._y = this.original.y;\n }\n set y(newY) {\n this.change(this._x, newY);\n this._y = this.original.y = newY;\n }\n }\n class transform_Transform {\n constructor(){\n this._parent = null;\n this._children = [];\n this._pos = vec(0, 0);\n this._rotation = 0;\n this._scale = vec(1, 1);\n this._isDirty = false;\n this._isInverseDirty = false;\n this._matrix = AffineMatrix.identity();\n this._inverse = AffineMatrix.identity();\n }\n get parent() {\n return this._parent;\n }\n set parent(transform) {\n if (this._parent) {\n const index = this._parent._children.indexOf(this);\n if (index > -1) this._parent._children.splice(index, 1);\n }\n this._parent = transform;\n if (this._parent) this._parent._children.push(this);\n this.flagDirty();\n }\n get children() {\n return this._children;\n }\n set pos(v) {\n if (!v.equals(this._pos)) {\n this._pos.x = v.x;\n this._pos.y = v.y;\n this.flagDirty();\n }\n }\n get pos() {\n return new WatchVector(this._pos, (x, y)=>{\n if (x !== this._pos.x || y !== this._pos.y) this.flagDirty();\n });\n }\n set globalPos(v) {\n let localPos = v.clone();\n if (this.parent) localPos = this.parent.inverse.multiply(v);\n if (!localPos.equals(this._pos)) {\n this._pos = localPos;\n this.flagDirty();\n }\n }\n get globalPos() {\n return new VectorView({\n getX: ()=>this.matrix.data[4],\n getY: ()=>this.matrix.data[5],\n setX: (x)=>{\n if (this.parent) {\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\n this.pos.x = newX;\n } else this.pos.x = x;\n if (x !== this.matrix.data[4]) this.flagDirty();\n },\n setY: (y)=>{\n if (this.parent) {\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\n this.pos.y = newY;\n } else this.pos.y = y;\n if (y !== this.matrix.data[5]) this.flagDirty();\n }\n });\n }\n set rotation(rotation) {\n const canonRotation = canonicalizeAngle(rotation);\n if (canonRotation !== this._rotation) this.flagDirty();\n this._rotation = canonRotation;\n }\n get rotation() {\n return this._rotation;\n }\n set globalRotation(rotation) {\n let inverseRotation = 0;\n if (this.parent) inverseRotation = this.parent.globalRotation;\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\n if (canonRotation !== this._rotation) this.flagDirty();\n this._rotation = canonRotation;\n }\n get globalRotation() {\n if (this.parent) return this.matrix.getRotation();\n return this.rotation;\n }\n set scale(v) {\n if (!v.equals(this._scale)) {\n this._scale.x = v.x;\n this._scale.y = v.y;\n this.flagDirty();\n }\n }\n get scale() {\n return new WatchVector(this._scale, (x, y)=>{\n if (x !== this._scale.x || y !== this._scale.y) this.flagDirty();\n });\n }\n set globalScale(v) {\n let inverseScale = vec(1, 1);\n if (this.parent) inverseScale = this.parent.globalScale;\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\n }\n get globalScale() {\n return new VectorView({\n getX: ()=>this.parent ? this.matrix.getScaleX() : this.scale.x,\n getY: ()=>this.parent ? this.matrix.getScaleY() : this.scale.y,\n setX: (x)=>{\n if (this.parent) {\n const globalScaleX = this.parent.globalScale.x;\n this.scale.x = x / globalScaleX;\n } else this.scale.x = x;\n },\n setY: (y)=>{\n if (this.parent) {\n const globalScaleY = this.parent.globalScale.y;\n this.scale.y = y / globalScaleY;\n } else this.scale.y = y;\n }\n });\n }\n get matrix() {\n if (this._isDirty) {\n if (this.parent === null) this._matrix = this._calculateMatrix();\n else this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\n this._isDirty = false;\n }\n return this._matrix;\n }\n get inverse() {\n if (this._isInverseDirty) {\n this._inverse = this.matrix.inverse();\n this._isInverseDirty = false;\n }\n return this._inverse;\n }\n _calculateMatrix() {\n const matrix = AffineMatrix.identity().translate(this.pos.x, this.pos.y).rotate(this.rotation).scale(this.scale.x, this.scale.y);\n return matrix;\n }\n flagDirty() {\n this._isDirty = true;\n this._isInverseDirty = true;\n for(let i = 0; i < this._children.length; i++)this._children[i].flagDirty();\n }\n apply(point) {\n return this.matrix.multiply(point);\n }\n applyInverse(point) {\n return this.inverse.multiply(point);\n }\n setTransform(pos, rotation, scale) {\n this._pos.x = pos.x;\n this._pos.y = pos.y;\n this._rotation = canonicalizeAngle(rotation);\n this._scale.x = scale.x;\n this._scale.y = scale.y;\n this.flagDirty();\n }\n /**\n * Clones the current transform\n * **Warning does not clone the parent**\n * @param dest\n */ clone(dest) {\n const target = dest !== null && dest !== void 0 ? dest : new transform_Transform();\n this._pos.clone(target._pos);\n target._rotation = this._rotation;\n this._scale.clone(target._scale);\n target.flagDirty();\n return target;\n }\n }\n /**\n *\n */ function isComponentCtor(value) {\n return !!value && !!value.prototype && !!value.prototype.constructor;\n }\n /**\n * Type guard to check if a component implements clone\n * @param x\n */ function hasClone(x) {\n return !!(x === null || x === void 0 ? void 0 : x.clone);\n }\n /**\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\n *\n * Implementations of Component must have a zero-arg constructor to support dependencies\n *\n * ```typescript\n * class MyComponent extends ex.Component {\n * // zero arg support required if you want to use component dependencies\n * constructor(public optionalPos?: ex.Vector) {}\n * }\n * ```\n */ class Component {\n constructor(){\n // TODO maybe generate a unique id?\n /**\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\n */ this.owner = undefined;\n }\n /**\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\n */ clone() {\n const newComponent = new this.constructor();\n for(const prop in this)if (this.hasOwnProperty(prop)) {\n const val = this[prop];\n if (hasClone(val) && prop !== \"owner\" && prop !== \"clone\") newComponent[prop] = val.clone();\n else newComponent[prop] = val;\n }\n return newComponent;\n }\n }\n /**\n * Simple Observable implementation\n * @template T is the typescript Type that defines the data being observed\n */ class Observable {\n constructor(){\n this.observers = [];\n this.subscriptions = [];\n }\n /**\n * Register an observer to listen to this observable\n * @param observer\n */ register(observer) {\n this.observers.push(observer);\n }\n /**\n * Register a callback to listen to this observable\n * @param func\n */ subscribe(func) {\n this.subscriptions.push(func);\n }\n /**\n * Remove an observer from the observable\n * @param observer\n */ unregister(observer) {\n const i = this.observers.indexOf(observer);\n if (i !== -1) this.observers.splice(i, 1);\n }\n /**\n * Remove a callback that is listening to this observable\n * @param func\n */ unsubscribe(func) {\n const i = this.subscriptions.indexOf(func);\n if (i !== -1) this.subscriptions.splice(i, 1);\n }\n /**\n * Broadcasts a message to all observers and callbacks\n * @param message\n */ notifyAll(message) {\n const observersLength = this.observers.length;\n for(let i = 0; i < observersLength; i++)this.observers[i].notify(message);\n const subscriptionsLength = this.subscriptions.length;\n for(let i = 0; i < subscriptionsLength; i++)this.subscriptions[i](message);\n }\n /**\n * Removes all observers and callbacks\n */ clear() {\n this.observers.length = 0;\n this.subscriptions.length = 0;\n }\n }\n class TransformComponent extends Component {\n constructor(){\n super(...arguments);\n this._logger = Logger.getInstance();\n this._parentComponent = null;\n this._transform = new transform_Transform();\n this._addChildTransform = (child)=>{\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) {\n childTxComponent._transform.parent = this._transform;\n childTxComponent._parentComponent = this;\n }\n };\n /**\n * Observable that emits when the z index changes on this component\n */ this.zIndexChanged$ = new Observable();\n this._z = 0;\n this._coordPlane = CoordPlane.World;\n }\n get() {\n return this._transform;\n }\n onAdd(owner) {\n for (const child of owner.children)this._addChildTransform(child);\n owner.childrenAdded$.subscribe((child)=>this._addChildTransform(child));\n owner.childrenRemoved$.subscribe((child)=>{\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) {\n childTxComponent._transform.parent = null;\n childTxComponent._parentComponent = null;\n }\n });\n }\n onRemove(_previousOwner) {\n this._transform.parent = null;\n this._parentComponent = null;\n }\n /**\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\n * For example z=99 would be drawn on top of z=0.\n */ get z() {\n return this._z;\n }\n set z(val) {\n const oldz = this._z;\n this._z = val;\n if (oldz !== val) this.zIndexChanged$.notifyAll(val);\n }\n /**\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\n */ get coordPlane() {\n if (this._parentComponent) return this._parentComponent.coordPlane;\n return this._coordPlane;\n }\n set coordPlane(value) {\n var _a;\n if (!this._parentComponent) this._coordPlane = value;\n else this._logger.warn(`Cannot set coordinate plane on child entity ${(_a = this.owner) === null || _a === void 0 ? void 0 : _a.name}, children inherit their coordinate plane from their parents.`);\n }\n get pos() {\n return this._transform.pos;\n }\n set pos(v) {\n this._transform.pos = v;\n }\n get globalPos() {\n return this._transform.globalPos;\n }\n set globalPos(v) {\n this._transform.globalPos = v;\n }\n get rotation() {\n return this._transform.rotation;\n }\n set rotation(rotation) {\n this._transform.rotation = rotation;\n }\n get globalRotation() {\n return this._transform.globalRotation;\n }\n set globalRotation(rotation) {\n this._transform.globalRotation = rotation;\n }\n get scale() {\n return this._transform.scale;\n }\n set scale(v) {\n this._transform.scale = v;\n }\n get globalScale() {\n return this._transform.globalScale;\n }\n set globalScale(v) {\n this._transform.globalScale = v;\n }\n applyInverse(v) {\n return this._transform.applyInverse(v);\n }\n apply(v) {\n return this._transform.apply(v);\n }\n clone() {\n const component = new TransformComponent();\n component._transform = this._transform.clone();\n component._z = this._z;\n return component;\n }\n }\n class MotionComponent extends Component {\n constructor(){\n super(...arguments);\n /**\n * The velocity of an entity in pixels per second\n */ this.vel = Vector.Zero;\n /**\n * The acceleration of entity in pixels per second^2\n */ this.acc = Vector.Zero;\n /**\n * The scale rate of change in scale units per second\n */ this.scaleFactor = Vector.Zero;\n /**\n * The angular velocity which is how quickly the entity is rotating in radians per second\n */ this.angularVelocity = 0;\n /**\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\n */ this.torque = 0;\n /**\n * Inertia can be thought of as the resistance to motion\n */ this.inertia = 1;\n }\n }\n /**\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\n */ class CollisionGroupManager {\n /**\n * Create a new named collision group up to a max of 32.\n * @param name Name for the collision group\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\n */ static create(name, mask) {\n if (this._CURRENT_GROUP > this._MAX_GROUPS) throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\n if (this._GROUPS.get(name)) {\n const existingGroup = this._GROUPS.get(name);\n if (existingGroup.mask === mask) return existingGroup;\n throw new Error(`Collision group ${name} already exists with a different mask!`);\n }\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\n this._CURRENT_BIT = this._CURRENT_BIT << 1 | 0;\n this._CURRENT_GROUP++;\n this._GROUPS.set(name, group);\n return group;\n }\n /**\n * Get all collision groups currently tracked by excalibur\n */ static get groups() {\n return Array.from(this._GROUPS.values());\n }\n /**\n * Get a collision group by it's name\n * @param name\n */ static groupByName(name) {\n return this._GROUPS.get(name);\n }\n /**\n * Resets the managers internal group management state\n */ static reset() {\n this._GROUPS = new Map();\n this._CURRENT_BIT = this._STARTING_BIT;\n this._CURRENT_GROUP = 1;\n }\n }\n // using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\n CollisionGroupManager._STARTING_BIT = 1;\n CollisionGroupManager._MAX_GROUPS = 32;\n CollisionGroupManager._CURRENT_GROUP = 1;\n CollisionGroupManager._CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\n CollisionGroupManager._GROUPS = new Map();\n /**\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\n *\n * For example:\n *\n * Players have collision group \"player\"\n *\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\n *\n * Enemies have collision group \"enemy\"\n *\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\n *\n * Blocks have collision group \"ground\"\n *\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\n *\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\n * with players and blocks.\n *\n * This is done with bitmasking, see the following pseudo-code\n *\n * PlayerGroup = `0b001`\n * PlayerGroupMask = `0b110`\n *\n * EnemyGroup = `0b010`\n * EnemyGroupMask = `0b101`\n *\n * BlockGroup = `0b100`\n * BlockGroupMask = `0b011`\n *\n * Should Players collide? No because the bitwise mask evaluates to 0\n * `(player1.group & player2.mask) === 0`\n * `(0b001 & 0b110) === 0`\n *\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\n * `(player1.group & enemy1.mask) === 1`\n * `(0b001 & 0b101) === 1`\n *\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\n * `(player1.group & blocks1.mask) === 1`\n * `(0b001 & 0b011) === 1`\n */ class CollisionGroup {\n /**\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\n * @param name Name of the collision group\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\n */ constructor(name, category, mask){\n this._name = name;\n this._category = category;\n this._mask = mask;\n }\n /**\n * Get the name of the collision group\n */ get name() {\n return this._name;\n }\n /**\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\n */ get category() {\n return this._category;\n }\n /**\n * Get the mask for this collision group\n */ get mask() {\n return this._mask;\n }\n /**\n * Evaluates whether 2 collision groups can collide\n *\n * This means the mask has the same bit set the other category and vice versa\n * @param other CollisionGroup\n */ canCollide(other) {\n const overlap1 = this.category & other.mask;\n const overlap2 = this.mask & other.category;\n return overlap1 !== 0 && overlap2 !== 0;\n }\n /**\n * Inverts the collision group. For example, if before the group specified \"players\",\n * inverting would specify all groups except players\n * @returns CollisionGroup\n */ invert() {\n const group = CollisionGroupManager.create(\"~(\" + this.name + \")\", ~this.mask | 0);\n group._category = ~this.category;\n return group;\n }\n /**\n * Combine collision groups with each other. The new group includes all of the previous groups.\n * @param collisionGroups\n */ static combine(collisionGroups) {\n const combinedName = collisionGroups.map((c)=>c.name).join(\"+\");\n const combinedCategory = collisionGroups.reduce((current, g)=>g.category | current, 0);\n const combinedMask = ~combinedCategory;\n return CollisionGroupManager.create(combinedName, combinedMask);\n }\n /**\n * Creates a collision group that collides with the listed groups\n * @param collisionGroups\n */ static collidesWith(collisionGroups) {\n const combinedName = `collidesWith(${collisionGroups.map((c)=>c.name).join(\"+\")})`;\n const combinedMask = collisionGroups.reduce((current, g)=>g.category | current, 0);\n return CollisionGroupManager.create(combinedName, combinedMask);\n }\n toString() {\n return `\r\ncategory: ${this.category.toString(2).padStart(32, \"0\")}\r\nmask: ${(this.mask >>> 0).toString(2).padStart(32, \"0\")}\r\n `;\n }\n }\n /**\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\n * it is the default collision group on colliders.\n */ CollisionGroup.All = new CollisionGroup(\"Collide with all groups\", -1, -1);\n /**\n * Models a potential collision between 2 colliders\n */ class Pair {\n constructor(colliderA, colliderB){\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.id = null;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n }\n /**\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\n * @param colliderA\n * @param colliderB\n */ static canCollide(colliderA, colliderB) {\n var _a, _b;\n const bodyA = (_a = colliderA === null || colliderA === void 0 ? void 0 : colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB === null || colliderB === void 0 ? void 0 : colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n // Prevent self collision\n if (colliderA.id === colliderB.id) return false;\n // Colliders with the same owner do not collide (composite colliders)\n if (colliderA.owner && colliderB.owner && colliderA.owner.id === colliderB.owner.id) return false;\n // if the pair has a member with zero dimension don't collide\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) return false;\n // Body's needed for collision in the current state\n // TODO can we collide without a body?\n if (!bodyA || !bodyB) return false;\n // If both are in the same collision group short circuit\n if (!bodyA.group.canCollide(bodyB.group)) return false;\n // if both are fixed short circuit\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) return false;\n // if the either is prevent collision short circuit\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) return false;\n // if either is dead short circuit\n if (!bodyA.active || !bodyB.active) return false;\n return true;\n }\n /**\n * Returns whether or not it is possible for the pairs to collide\n */ get canCollide() {\n const colliderA = this.colliderA;\n const colliderB = this.colliderB;\n return Pair.canCollide(colliderA, colliderB);\n }\n /**\n * Runs the collision intersection logic on the members of this pair\n */ collide() {\n return this.colliderA.collide(this.colliderB);\n }\n /**\n * Check if the collider is part of the pair\n * @param collider\n */ hasCollider(collider) {\n return collider === this.colliderA || collider === this.colliderB;\n }\n /**\n * Calculates the unique pair hash id for this collision pair (owning id)\n */ static calculatePairHash(idA, idB) {\n if (idA.value < idB.value) return `#${idA.value}+${idB.value}`;\n else return `#${idB.value}+${idA.value}`;\n }\n }\n /**\n * A 1 dimensional projection on an axis, used to test overlaps\n */ class Projection {\n constructor(min, max){\n this.min = min;\n this.max = max;\n }\n overlaps(projection) {\n return this.max > projection.min && projection.max > this.min;\n }\n getOverlap(projection) {\n if (this.overlaps(projection)) {\n if (this.max > projection.max) return projection.max - this.min;\n else return this.max - projection.min;\n }\n return 0;\n }\n }\n /**\n * Dynamic Tree Node used for tracking bounds within the tree\n */ class TreeNode {\n constructor(parent){\n this.parent = parent;\n this.parent = parent || null;\n this.data = null;\n this.bounds = new BoundingBox();\n this.left = null;\n this.right = null;\n this.height = 0;\n }\n isLeaf() {\n return !this.left && !this.right;\n }\n }\n /**\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\n *\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\n * Every non-leaf node is a bounding box that contains child bounding boxes.\n */ class DynamicTree {\n constructor(_config, worldBounds = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)){\n this._config = _config;\n this.worldBounds = worldBounds;\n this.root = null;\n this.nodes = {};\n }\n /**\n * Inserts a node into the dynamic tree\n */ _insert(leaf) {\n // If there are no nodes in the tree, make this the root leaf\n if (this.root === null) {\n this.root = leaf;\n this.root.parent = null;\n return;\n }\n // Search the tree for a node that is not a leaf and find the best place to insert\n const leafAABB = leaf.bounds;\n let currentRoot = this.root;\n while(!currentRoot.isLeaf()){\n const left = currentRoot.left;\n const right = currentRoot.right;\n const area = currentRoot.bounds.getPerimeter();\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\n const combinedArea = combinedAABB.getPerimeter();\n // Calculate cost heuristic for creating a new parent and leaf\n const cost = 2 * combinedArea;\n // Minimum cost of pushing the leaf down the tree\n const inheritanceCost = 2 * (combinedArea - area);\n // Cost of descending\n let leftCost = 0;\n const leftCombined = leafAABB.combine(left.bounds);\n let newArea;\n let oldArea;\n if (left.isLeaf()) leftCost = leftCombined.getPerimeter() + inheritanceCost;\n else {\n oldArea = left.bounds.getPerimeter();\n newArea = leftCombined.getPerimeter();\n leftCost = newArea - oldArea + inheritanceCost;\n }\n let rightCost = 0;\n const rightCombined = leafAABB.combine(right.bounds);\n if (right.isLeaf()) rightCost = rightCombined.getPerimeter() + inheritanceCost;\n else {\n oldArea = right.bounds.getPerimeter();\n newArea = rightCombined.getPerimeter();\n rightCost = newArea - oldArea + inheritanceCost;\n }\n // cost is acceptable\n if (cost < leftCost && cost < rightCost) break;\n // Descend to the depths\n if (leftCost < rightCost) currentRoot = left;\n else currentRoot = right;\n }\n // Create the new parent node and insert into the tree\n const oldParent = currentRoot.parent;\n const newParent = new TreeNode(oldParent);\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\n newParent.height = currentRoot.height + 1;\n if (oldParent !== null) {\n // The sibling node was not the root\n if (oldParent.left === currentRoot) oldParent.left = newParent;\n else oldParent.right = newParent;\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n } else {\n // The sibling node was the root\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n this.root = newParent;\n }\n // Walk up the tree fixing heights and AABBs\n let currentNode = leaf.parent;\n while(currentNode){\n currentNode = this._balance(currentNode);\n if (!currentNode.left) throw new Error(\"Parent of current leaf cannot have a null left child\" + currentNode);\n if (!currentNode.right) throw new Error(\"Parent of current leaf cannot have a null right child\" + currentNode);\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode = currentNode.parent;\n }\n }\n /**\n * Removes a node from the dynamic tree\n */ _remove(leaf) {\n if (leaf === this.root) {\n this.root = null;\n return;\n }\n const parent = leaf.parent;\n const grandParent = parent.parent;\n let sibling;\n if (parent.left === leaf) sibling = parent.right;\n else sibling = parent.left;\n if (grandParent) {\n if (grandParent.left === parent) grandParent.left = sibling;\n else grandParent.right = sibling;\n sibling.parent = grandParent;\n let currentNode = grandParent;\n while(currentNode){\n currentNode = this._balance(currentNode);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode = currentNode.parent;\n }\n } else {\n this.root = sibling;\n sibling.parent = null;\n }\n }\n /**\n * Tracks a body in the dynamic tree\n */ trackCollider(collider) {\n const node = new TreeNode();\n node.data = collider;\n node.bounds = collider.bounds;\n node.bounds.left -= 2;\n node.bounds.top -= 2;\n node.bounds.right += 2;\n node.bounds.bottom += 2;\n this.nodes[collider.id.value] = node;\n this._insert(node);\n }\n /**\n * Updates the dynamic tree given the current bounds of each body being tracked\n */ updateCollider(collider) {\n var _a;\n const node = this.nodes[collider.id.value];\n if (!node) return false;\n const b = collider.bounds;\n // if the body is outside the world no longer update it\n if (!this.worldBounds.contains(b)) {\n Logger.getInstance().warn(\"Collider with id \" + collider.id.value + \" is outside the world bounds and will no longer be tracked for physics\");\n this.untrackCollider(collider);\n return false;\n }\n if (node.bounds.contains(b)) return false;\n this._remove(node);\n b.left -= this._config.boundsPadding;\n b.top -= this._config.boundsPadding;\n b.right += this._config.boundsPadding;\n b.bottom += this._config.boundsPadding;\n // THIS IS CAUSING UNNECESSARY CHECKS\n if (collider.owner) {\n const body = (_a = collider.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n if (body) {\n const multdx = body.vel.x * 32 / 1000 * this._config.velocityMultiplier;\n const multdy = body.vel.y * 32 / 1000 * this._config.velocityMultiplier;\n if (multdx < 0) b.left += multdx;\n else b.right += multdx;\n if (multdy < 0) b.top += multdy;\n else b.bottom += multdy;\n }\n }\n node.bounds = b;\n this._insert(node);\n return true;\n }\n /**\n * Untracks a body from the dynamic tree\n */ untrackCollider(collider) {\n const node = this.nodes[collider.id.value];\n if (!node) return;\n this._remove(node);\n this.nodes[collider.id.value] = null;\n delete this.nodes[collider.id.value];\n }\n /**\n * Balances the tree about a node\n */ _balance(node) {\n if (node === null) throw new Error(\"Cannot balance at null node\");\n if (node.isLeaf() || node.height < 2) return node;\n const left = node.left;\n const right = node.right;\n const a = node;\n const b = left;\n const c = right;\n const d = left.left;\n const e = left.right;\n const f = right.left;\n const g = right.right;\n const balance = c.height - b.height;\n // Rotate c node up\n if (balance > 1) {\n // Swap the right node with it's parent\n c.left = a;\n c.parent = a.parent;\n a.parent = c;\n // The original node's old parent should point to the right node\n // this is mega confusing\n if (c.parent) {\n if (c.parent.left === a) c.parent.left = c;\n else c.parent.right = c;\n } else this.root = c;\n // Rotate\n if (f.height > g.height) {\n c.right = f;\n a.right = g;\n g.parent = a;\n a.bounds = b.bounds.combine(g.bounds);\n c.bounds = a.bounds.combine(f.bounds);\n a.height = 1 + Math.max(b.height, g.height);\n c.height = 1 + Math.max(a.height, f.height);\n } else {\n c.right = g;\n a.right = f;\n f.parent = a;\n a.bounds = b.bounds.combine(f.bounds);\n c.bounds = a.bounds.combine(g.bounds);\n a.height = 1 + Math.max(b.height, f.height);\n c.height = 1 + Math.max(a.height, g.height);\n }\n return c;\n }\n // Rotate left node up\n if (balance < -1) {\n // swap\n b.left = a;\n b.parent = a.parent;\n a.parent = b;\n // node's old parent should point to b\n if (b.parent) {\n if (b.parent.left === a) b.parent.left = b;\n else {\n if (b.parent.right !== a) throw \"Error rotating Dynamic Tree\";\n b.parent.right = b;\n }\n } else this.root = b;\n // rotate\n if (d.height > e.height) {\n b.right = d;\n a.left = e;\n e.parent = a;\n a.bounds = c.bounds.combine(e.bounds);\n b.bounds = a.bounds.combine(d.bounds);\n a.height = 1 + Math.max(c.height, e.height);\n b.height = 1 + Math.max(a.height, d.height);\n } else {\n b.right = e;\n a.left = d;\n d.parent = a;\n a.bounds = c.bounds.combine(d.bounds);\n b.bounds = a.bounds.combine(e.bounds);\n a.height = 1 + Math.max(c.height, d.height);\n b.height = 1 + Math.max(a.height, e.height);\n }\n return b;\n }\n return node;\n }\n /**\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\n */ getHeight() {\n if (this.root === null) return 0;\n return this.root.height;\n }\n /**\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\n *\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\n * the tree until all possible colliders have been returned.\n */ query(collider, callback) {\n const bounds = collider.bounds;\n const helper = (currentNode)=>{\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\n if (currentNode.isLeaf() && currentNode.data !== collider) {\n if (callback.call(collider, currentNode.data)) return true;\n } else return helper(currentNode.left) || helper(currentNode.right);\n }\n return false;\n };\n helper(this.root);\n }\n /**\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\n * long ray to test the tree specified by `max`.\n *\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\n * the tree until all possible bodies that would intersect with the ray have been returned.\n */ rayCastQuery(ray, max = Infinity, callback) {\n const helper = (currentNode)=>{\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\n if (currentNode.isLeaf()) {\n if (callback.call(ray, currentNode.data)) // ray hit a leaf! return the body\n return true;\n } else // ray hit but not at a leaf, recurse deeper\n return helper(currentNode.left) || helper(currentNode.right);\n }\n return false; // ray missed\n };\n helper(this.root);\n }\n getNodes() {\n const helper = (currentNode)=>{\n if (currentNode) return [\n currentNode\n ].concat(helper(currentNode.left), helper(currentNode.right));\n else return [];\n };\n return helper(this.root);\n }\n debug(ex) {\n // draw all the nodes in the Dynamic Tree\n const helper = (currentNode)=>{\n if (currentNode) {\n if (currentNode.isLeaf()) currentNode.bounds.draw(ex, Color.Green);\n else currentNode.bounds.draw(ex, Color.White);\n if (currentNode.left) helper(currentNode.left);\n if (currentNode.right) helper(currentNode.right);\n }\n };\n helper(this.root);\n }\n }\n /**\n * A 2D ray that can be cast into the scene to do collision detection\n */ class Ray {\n /**\n * @param pos The starting position for the ray\n * @param dir The vector indicating the direction of the ray\n */ constructor(pos, dir){\n this.pos = pos;\n this.dir = dir.normalize();\n }\n /**\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\n * This number indicates the mathematical intersection time.\n * @param line The line to test\n */ intersect(line) {\n const numerator = line.begin.sub(this.pos);\n // Test is line and ray are parallel and non intersecting\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) return -1;\n // Lines are parallel\n const divisor = this.dir.cross(line.getSlope());\n if (divisor === 0) return -1;\n const t = numerator.cross(line.getSlope()) / divisor;\n if (t >= 0) {\n const u = numerator.cross(this.dir) / divisor / line.getLength();\n if (u >= 0 && u <= 1) return t;\n }\n return -1;\n }\n intersectPoint(line) {\n const time = this.intersect(line);\n if (time < 0) return null;\n return this.getPoint(time);\n }\n /**\n * Returns the point of intersection given the intersection time\n */ getPoint(time) {\n return this.pos.add(this.dir.scale(time));\n }\n }\n /**\n * Responsible for performing the collision broadphase (locating potential collisions) and\n * the narrowphase (actual collision contacts)\n */ class DynamicTreeCollisionProcessor {\n constructor(_config){\n this._config = _config;\n this._pairs = new Set();\n this._collisionPairCache = [];\n this._colliders = [];\n this._dynamicCollisionTree = new DynamicTree(_config.dynamicTree);\n }\n getColliders() {\n return this._colliders;\n }\n rayCast(ray, options) {\n var _a, _b, _c;\n const results = [];\n const maxDistance = (_a = options === null || options === void 0 ? void 0 : options.maxDistance) !== null && _a !== void 0 ? _a : Infinity;\n const collisionGroup = options === null || options === void 0 ? void 0 : options.collisionGroup;\n const collisionMask = !collisionGroup ? (_b = options === null || options === void 0 ? void 0 : options.collisionMask) !== null && _b !== void 0 ? _b : CollisionGroup.All.category : collisionGroup.category;\n const searchAllColliders = (_c = options === null || options === void 0 ? void 0 : options.searchAllColliders) !== null && _c !== void 0 ? _c : false;\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider)=>{\n const owner = collider.owner;\n const maybeBody = owner.get(BodyComponent);\n if ((options === null || options === void 0 ? void 0 : options.ignoreCollisionGroupAll) && maybeBody.group === CollisionGroup.All) return false;\n const canCollide = (collisionMask & maybeBody.group.category) !== 0;\n // Early exit if not the right group\n if ((maybeBody === null || maybeBody === void 0 ? void 0 : maybeBody.group) && !canCollide) return false;\n const hit = collider.rayCast(ray, maxDistance);\n if (hit) {\n if (options === null || options === void 0 ? void 0 : options.filter) {\n if (options.filter(hit)) {\n results.push(hit);\n if (!searchAllColliders) // returning true exits the search\n return true;\n }\n } else {\n results.push(hit);\n if (!searchAllColliders) // returning true exits the search\n return true;\n }\n }\n return false;\n });\n return results;\n }\n /**\n * Tracks a physics body for collisions\n */ track(target) {\n if (!target) {\n Logger.getInstance().warn(\"Cannot track null collider\");\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders){\n c.owner = target.owner;\n this._colliders.push(c);\n this._dynamicCollisionTree.trackCollider(c);\n }\n } else {\n this._colliders.push(target);\n this._dynamicCollisionTree.trackCollider(target);\n }\n }\n /**\n * Untracks a physics body\n */ untrack(target) {\n if (!target) {\n Logger.getInstance().warn(\"Cannot untrack a null collider\");\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders){\n const index = this._colliders.indexOf(c);\n if (index !== -1) this._colliders.splice(index, 1);\n this._dynamicCollisionTree.untrackCollider(c);\n }\n } else {\n const index = this._colliders.indexOf(target);\n if (index !== -1) this._colliders.splice(index, 1);\n this._dynamicCollisionTree.untrackCollider(target);\n }\n }\n _pairExists(colliderA, colliderB) {\n // if the collision pair has been calculated already short circuit\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\n return this._pairs.has(hash);\n }\n /**\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\n */ broadphase(targets, delta, stats) {\n const seconds = delta / 1000;\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\n const potentialColliders = targets.filter((other)=>{\n var _a, _b;\n const body = (_a = other.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n return ((_b = other.owner) === null || _b === void 0 ? void 0 : _b.active) && body.collisionType !== CollisionType.PreventCollision;\n });\n // clear old list of collision pairs\n this._collisionPairCache = [];\n this._pairs.clear();\n // check for normal collision pairs\n let collider;\n for(let j = 0, l = potentialColliders.length; j < l; j++){\n collider = potentialColliders[j];\n // Query the collision tree for potential colliders\n this._dynamicCollisionTree.query(collider, (other)=>{\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const pair = new Pair(collider, other);\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // Always return false, to query whole tree. Returning true in the query method stops searching\n return false;\n });\n }\n if (stats) stats.physics.pairs = this._collisionPairCache.length;\n // Check dynamic tree for fast moving objects\n // Fast moving objects are those moving at least there smallest bound per frame\n if (this._config.continuous.checkForFastBodies) for (const collider of potentialColliders){\n const body = collider.owner.get(BodyComponent);\n // Skip non-active objects. Does not make sense on other collision types\n if (body.collisionType !== CollisionType.Active) continue;\n // Maximum travel distance next frame\n const updateDistance = body.vel.size * seconds + // velocity term\n body.acc.size * 0.5 * seconds * seconds; // acc term\n // Find the minimum dimension\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\n if (this._config.continuous.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\n if (stats) stats.physics.fastBodies++;\n // start with the oldPos because the integration for actors has already happened\n // objects resting on a surface may be slightly penetrating in the current position\n const updateVec = body.globalPos.sub(body.oldPos);\n const centerPoint = collider.center;\n const furthestPoint = collider.getFurthestPoint(body.vel);\n const origin = furthestPoint.sub(updateVec);\n const ray = new Ray(origin, body.vel);\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\n ray.pos = ray.pos.add(ray.dir.scale(-2 * this._config.continuous.surfaceEpsilon));\n let minCollider;\n let minTranslate = new Vector(Infinity, Infinity);\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + this._config.continuous.surfaceEpsilon * 2, (other)=>{\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const hit = other.rayCast(ray, updateDistance + this._config.continuous.surfaceEpsilon * 10);\n if (hit) {\n const translate = hit.point.sub(origin);\n if (translate.size < minTranslate.size) {\n minTranslate = translate;\n minCollider = other;\n }\n }\n }\n return false;\n });\n if (minCollider && Vector.isValid(minTranslate)) {\n const pair = new Pair(collider, minCollider);\n if (!this._pairs.has(pair.id)) {\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // move the fast moving object to the other body\n // need to push into the surface by ex.Physics.surfaceEpsilon\n const shift = centerPoint.sub(furthestPoint);\n body.globalPos = origin.add(shift).add(minTranslate).add(ray.dir.scale(10 * this._config.continuous.surfaceEpsilon)); // needed to push the shape slightly into contact\n collider.update(body.transform.get());\n if (stats) stats.physics.fastBodyCollisions++;\n }\n }\n }\n // return cache\n return this._collisionPairCache;\n }\n /**\n * Applies narrow phase on collision pairs to find actual area intersections\n * Adds actual colliding pairs to stats' Frame data\n */ narrowphase(pairs, stats) {\n let contacts = [];\n for(let i = 0; i < pairs.length; i++){\n const newContacts = pairs[i].collide();\n contacts = contacts.concat(newContacts);\n if (stats && newContacts.length > 0) for (const c of newContacts)stats.physics.contacts.set(c.id, c);\n }\n if (stats) stats.physics.collisions += contacts.length;\n return contacts;\n }\n /**\n * Update the dynamic tree positions\n */ update(targets) {\n let updated = 0;\n const len = targets.length;\n for(let i = 0; i < len; i++)if (this._dynamicCollisionTree.updateCollider(targets[i])) updated++;\n return updated;\n }\n debug(ex) {\n this._dynamicCollisionTree.debug(ex);\n }\n }\n /**\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\n * for the purposes of colliding 2 objects in excalibur.\n */ class Collider {\n constructor(){\n this.id = createId(\"collider\", Collider._ID++);\n /**\n * Composite collider if any this collider is attached to\n *\n * **WARNING** do not tamper with this property\n */ this.composite = null;\n this.events = new EventEmitter();\n /**\n * Pixel offset of the collision collider relative to the collider, by default (0, 0) meaning the collider is positioned\n * on top of the collider.\n */ this.offset = Vector.Zero;\n }\n /**\n * Returns a boolean indicating whether this body collided with\n * or was in stationary contact with\n * the body of the other [[Collider]]\n */ touching(other) {\n const contact = this.collide(other);\n if (contact) return true;\n return false;\n }\n }\n Collider._ID = 0;\n /**\n * Possible collision resolution strategies\n *\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\n * like platformers or top down games.\n *\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\n * simulated physical interactions.\n */ var SolverStrategy;\n (function(SolverStrategy) {\n SolverStrategy[\"Arcade\"] = \"arcade\";\n SolverStrategy[\"Realistic\"] = \"realistic\";\n })(SolverStrategy || (SolverStrategy = {}));\n /**\n * Possible broadphase collision pair identification strategies\n *\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\n * potential collision pairs which is O(nlog(n)) faster.\n * @deprecated Unused in Excalibur, will be removed in v0.30\n */ var BroadphaseStrategy;\n (function(BroadphaseStrategy) {\n BroadphaseStrategy[BroadphaseStrategy[\"DynamicAABBTree\"] = 0] = \"DynamicAABBTree\";\n })(BroadphaseStrategy || (BroadphaseStrategy = {}));\n /**\n * Possible numerical integrators for position and velocity\n * @deprecated Unused in Excalibur, will be removed in v0.30\n */ var Integrator;\n (function(Integrator) {\n Integrator[Integrator[\"Euler\"] = 0] = \"Euler\";\n })(Integrator || (Integrator = {}));\n /**\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ /* istanbul ignore next */ class Physics {\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ static get gravity() {\n return Physics.acc;\n }\n static set gravity(v) {\n Physics.acc = v;\n }\n /**\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ static useArcadePhysics() {\n Physics.collisionResolutionStrategy = SolverStrategy.Arcade;\n }\n /**\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\n * simulated physical interactions.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ static useRealisticPhysics() {\n Physics.collisionResolutionStrategy = SolverStrategy.Realistic;\n }\n }\n /**\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\n *\n * This is a great way to globally simulate effects like gravity.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.acc = new Vector(0, 0);\n /**\n * Globally switches all Excalibur physics behavior on or off.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.enabled = true;\n /**\n * Gets or sets the broadphase pair identification strategy.\n *\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\n * potential collision pairs which is O(nlog(n)) faster.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.broadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\n /**\n * Gets or sets the global collision resolution strategy (narrowphase).\n *\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics.\n *\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\n * simulated physical interactions.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.collisionResolutionStrategy = SolverStrategy.Arcade;\n /**\n * The default mass to use if none is specified\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.defaultMass = 10;\n /**\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.integrator = Integrator.Euler;\n /**\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.dynamicTreeVelocityMultiplier = 2;\n /**\n * Pad RigidBody BoundingBox by a constant amount\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.boundsPadding = 5;\n /**\n * Number of position iterations (overlap) to run in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.positionIterations = 3;\n /**\n * Number of velocity iteration (response) to run in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.velocityIterations = 8;\n /**\n * Amount of overlap to tolerate in pixels\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.slop = 1;\n /**\n * Amount of positional overlap correction to apply each position iteration of the solver\n * O - meaning no correction, 1 - meaning correct all overlap\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.steeringFactor = 0.2;\n /**\n * Warm start set to true re-uses impulses from previous frames back in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.warmStart = true;\n /**\n * By default bodies do not sleep\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.bodiesCanSleepByDefault = false;\n /**\n * Surface epsilon is used to help deal with surface penetration\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.surfaceEpsilon = 0.1;\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.sleepEpsilon = 0.07;\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.wakeThreshold = Physics.sleepEpsilon * 3;\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.sleepBias = 0.9;\n /**\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\n * bodies from tunneling through one another.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.checkForFastBodies = true;\n /**\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\n * Excalibur will always perform the fast body raycast regardless of speed.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.disableMinimumSpeedForFastBody = false;\n /**\n * Tells the Arcade collision solver to prefer certain contacts over others\n */ var ContactSolveBias;\n (function(ContactSolveBias) {\n ContactSolveBias[\"None\"] = \"none\";\n ContactSolveBias[\"VerticalFirst\"] = \"vertical-first\";\n ContactSolveBias[\"HorizontalFirst\"] = \"horizontal-first\";\n })(ContactSolveBias || (ContactSolveBias = {}));\n /**\n * Vertical First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\n */ const VerticalFirst = {\n \"vertical\": 1,\n \"horizontal\": 2\n };\n /**\n * Horizontal First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\n */ const HorizontalFirst = {\n \"horizontal\": 1,\n \"vertical\": 2\n };\n /**\n * None value, [[ArcadeSolver]] sorts contacts using distance by default\n */ const None = {\n \"horizontal\": 0,\n \"vertical\": 0\n };\n const DefaultPhysicsConfig = {\n enabled: true,\n gravity: vec(0, 0),\n solver: SolverStrategy.Arcade,\n colliders: {\n compositeStrategy: \"together\"\n },\n continuous: {\n checkForFastBodies: true,\n disableMinimumSpeedForFastBody: false,\n surfaceEpsilon: 0.1\n },\n bodies: {\n canSleepByDefault: false,\n sleepEpsilon: 0.07,\n wakeThreshold: 0.07 * 3,\n sleepBias: 0.9,\n defaultMass: 10\n },\n dynamicTree: {\n boundsPadding: 5,\n velocityMultiplier: 2\n },\n arcade: {\n contactSolveBias: ContactSolveBias.None\n },\n realistic: {\n positionIterations: 3,\n velocityIterations: 8,\n slop: 1,\n steeringFactor: 0.2,\n warmStart: true\n }\n };\n /**\n * @deprecated will be removed in v0.30\n */ function DeprecatedStaticToConfig() {\n return {\n enabled: Physics.enabled,\n gravity: Physics.gravity,\n solver: Physics.collisionResolutionStrategy,\n continuous: {\n checkForFastBodies: Physics.checkForFastBodies,\n disableMinimumSpeedForFastBody: Physics.disableMinimumSpeedForFastBody,\n surfaceEpsilon: Physics.surfaceEpsilon\n },\n colliders: {\n compositeStrategy: \"together\"\n },\n bodies: {\n canSleepByDefault: Physics.bodiesCanSleepByDefault,\n sleepEpsilon: Physics.sleepEpsilon,\n wakeThreshold: Physics.wakeThreshold,\n sleepBias: Physics.sleepBias,\n defaultMass: Physics.defaultMass\n },\n dynamicTree: {\n boundsPadding: Physics.boundsPadding,\n velocityMultiplier: Physics.dynamicTreeVelocityMultiplier\n },\n arcade: {\n contactSolveBias: ContactSolveBias.None\n },\n realistic: {\n positionIterations: Physics.positionIterations,\n velocityIterations: Physics.velocityIterations,\n slop: Physics.slop,\n steeringFactor: Physics.steeringFactor,\n warmStart: Physics.warmStart\n }\n };\n }\n class CompositeCollider extends Collider {\n /**\n * Treat composite collider's member colliders as either separate colliders for the purposes of onCollisionStart/onCollision\n * or as a single collider together.\n *\n * This property can be overridden on individual [[CompositeColliders]].\n *\n * For composites without gaps or small groups of colliders, you probably want 'together'\n *\n * For composites with deliberate gaps, like a platforming level layout, you probably want 'separate'\n *\n * Default is 'together' if unset\n */ set compositeStrategy(value) {\n this._compositeStrategy = value;\n }\n get compositeStrategy() {\n return this._compositeStrategy;\n }\n constructor(colliders){\n super();\n this._collisionProcessor = new DynamicTreeCollisionProcessor(DefaultPhysicsConfig);\n this._dynamicAABBTree = new DynamicTree(DefaultPhysicsConfig.dynamicTree);\n this._colliders = [];\n for (const c of colliders)this.addCollider(c);\n }\n clearColliders() {\n this._colliders = [];\n }\n addCollider(collider) {\n let colliders;\n if (collider instanceof CompositeCollider) {\n colliders = collider.getColliders();\n colliders.forEach((c)=>c.offset.addEqual(collider.offset));\n } else colliders = [\n collider\n ];\n // Flatten composites\n for (const c of colliders){\n c.events.pipe(this.events);\n c.composite = this;\n this._colliders.push(c);\n this._collisionProcessor.track(c);\n this._dynamicAABBTree.trackCollider(c);\n }\n }\n removeCollider(collider) {\n collider.events.pipe(this.events);\n collider.composite = null;\n removeItemFromArray(collider, this._colliders);\n this._collisionProcessor.untrack(collider);\n this._dynamicAABBTree.untrackCollider(collider);\n }\n getColliders() {\n return this._colliders;\n }\n get worldPos() {\n var _a, _b;\n return ((_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero).add(this.offset);\n }\n get center() {\n var _a, _b;\n return ((_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero).add(this.offset);\n }\n get bounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider)=>acc.combine(collider.bounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox().translate(this.worldPos));\n return results.translate(this.offset);\n }\n get localBounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider)=>acc.combine(collider.localBounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox());\n return results;\n }\n get axes() {\n // TODO cache this\n const colliders = this.getColliders();\n let axes = [];\n for (const collider of colliders)axes = axes.concat(collider.axes);\n return axes;\n }\n getFurthestPoint(direction) {\n const colliders = this.getColliders();\n const furthestPoints = [];\n for (const collider of colliders)furthestPoints.push(collider.getFurthestPoint(direction));\n // Pick best point from all colliders\n let bestPoint = furthestPoints[0];\n let maxDistance = -Number.MAX_VALUE;\n for (const point of furthestPoints){\n const distance = point.dot(direction);\n if (distance > maxDistance) {\n bestPoint = point;\n maxDistance = distance;\n }\n }\n return bestPoint;\n }\n getInertia(mass) {\n const colliders = this.getColliders();\n let totalInertia = 0;\n for (const collider of colliders)totalInertia += collider.getInertia(mass);\n return totalInertia;\n }\n collide(other) {\n let otherColliders = [\n other\n ];\n if (other instanceof CompositeCollider) otherColliders = other.getColliders();\n const pairs = [];\n for (const c of otherColliders)this._dynamicAABBTree.query(c, (potentialCollider)=>{\n pairs.push(new Pair(c, potentialCollider));\n return false;\n });\n let contacts = [];\n for (const p of pairs)contacts = contacts.concat(p.collide());\n return contacts;\n }\n getClosestLineBetween(other) {\n const colliders = this.getColliders();\n const lines = [];\n if (other instanceof CompositeCollider) {\n const otherColliders = other.getColliders();\n for (const colliderA of colliders)for (const colliderB of otherColliders){\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\n if (maybeLine) lines.push(maybeLine);\n }\n } else for (const collider of colliders){\n const maybeLine = other.getClosestLineBetween(collider);\n if (maybeLine) lines.push(maybeLine);\n }\n if (lines.length) {\n let minLength = lines[0].getLength();\n let minLine = lines[0];\n for (const line of lines){\n const length = line.getLength();\n if (length < minLength) {\n minLength = length;\n minLine = line;\n }\n }\n return minLine;\n }\n return null;\n }\n contains(point) {\n const colliders = this.getColliders();\n for (const collider of colliders){\n if (collider.contains(point)) return true;\n }\n return false;\n }\n rayCast(ray, max) {\n const colliders = this.getColliders();\n const hits = [];\n for (const collider of colliders){\n const hit = collider.rayCast(ray, max);\n if (hit) hits.push(hit);\n }\n if (hits.length) {\n let minHit = hits[0];\n let minDistance = minHit.point.dot(ray.dir);\n for (const hit of hits){\n const distance = ray.dir.dot(hit.point);\n if (distance < minDistance) {\n minHit = hit;\n minDistance = distance;\n }\n }\n return minHit;\n }\n return null;\n }\n project(axis) {\n const colliders = this.getColliders();\n const projections = [];\n for (const collider of colliders){\n const proj = collider.project(axis);\n if (proj) projections.push(proj);\n }\n // Merge all proj's on the same axis\n if (projections.length) {\n const newProjection = new Projection(projections[0].min, projections[0].max);\n for (const proj of projections){\n newProjection.min = Math.min(proj.min, newProjection.min);\n newProjection.max = Math.max(proj.max, newProjection.max);\n }\n return newProjection;\n }\n return null;\n }\n update(transform) {\n if (transform) {\n const colliders = this.getColliders();\n for (const collider of colliders){\n collider.owner = this.owner;\n collider.update(transform);\n }\n }\n }\n debug(ex, color, options) {\n const colliders = this.getColliders();\n ex.save();\n ex.translate(this.offset.x, this.offset.y);\n for (const collider of colliders)collider.debug(ex, color, options);\n ex.restore();\n }\n clone() {\n const result = new CompositeCollider(this._colliders.map((c)=>c.clone()));\n result.offset = this.offset.clone();\n return result;\n }\n }\n /**\n * A 2D line segment\n */ class LineSegment {\n /**\n * @param begin The starting point of the line segment\n * @param end The ending point of the line segment\n */ constructor(begin, end){\n this.begin = begin;\n this.end = end;\n }\n /**\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\n */ get slope() {\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\n }\n /**\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\n */ get intercept() {\n return this.begin.y - this.slope * this.begin.x;\n }\n /**\n * Gets the normal of the line\n */ normal() {\n if (this._normal) return this._normal;\n return this._normal = this.end.sub(this.begin).normal();\n }\n dir() {\n if (this._dir) return this._dir;\n return this._dir = this.end.sub(this.begin);\n }\n getPoints() {\n return [\n this.begin,\n this.end\n ];\n }\n /**\n * Returns the slope of the line in the form of a vector of length 1\n */ getSlope() {\n if (this._slope) return this._slope;\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._slope = end.sub(begin).scale(1 / distance);\n }\n /**\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\n */ getEdge() {\n const begin = this.begin;\n const end = this.end;\n return end.sub(begin);\n }\n /**\n * Returns the length of the line segment in pixels\n */ getLength() {\n if (this._length) return this._length;\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._length = distance;\n }\n /**\n * Returns the midpoint of the edge\n */ get midpoint() {\n return this.begin.add(this.end).scale(0.5);\n }\n /**\n * Flips the direction of the line segment\n */ flip() {\n return new LineSegment(this.end, this.begin);\n }\n /**\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\n * @param point\n */ below(point) {\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\n return above2 >= 0;\n }\n /**\n * Returns the clip point\n * @param sideVector Vector that traces the line\n * @param length Length to clip along side\n */ clip(sideVector, length) {\n let dir = sideVector;\n dir = dir.normalize();\n const near = dir.dot(this.begin) - length;\n const far = dir.dot(this.end) - length;\n const results = [];\n if (near <= 0) results.push(this.begin);\n if (far <= 0) results.push(this.end);\n if (near * far < 0) {\n const clipTime = near / (near - far);\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\n }\n if (results.length !== 2) return null;\n return new LineSegment(results[0], results[1]);\n }\n /**\n * Find the perpendicular distance from the line to a point\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\n * @param point\n */ distanceToPoint(point, signed = false) {\n const x0 = point.x;\n const y0 = point.y;\n const l = this.getLength();\n const dy = this.end.y - this.begin.y;\n const dx = this.end.x - this.begin.x;\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\n return signed ? distance : Math.abs(distance);\n }\n /**\n * Find the perpendicular line from the line to a point\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\n * (a - p) - ((a - p) * n)n\n * a is a point on the line\n * p is the arbitrary point above the line\n * n is a unit vector in direction of the line\n * @param point\n */ findVectorToPoint(point) {\n const aMinusP = this.begin.sub(point);\n const n = this.getSlope();\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\n }\n /**\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\n * a new point with the calculated Y value and vice-versa.\n * @param x The known X value of the target point\n * @param y The known Y value of the target point\n * @returns A new point with the other calculated axis value\n */ findPoint(x = null, y = null) {\n const m = this.slope;\n const b = this.intercept;\n if (x !== null) return new Vector(x, m * x + b);\n else if (y !== null) return new Vector((y - b) / m, y);\n else throw new Error(\"You must provide an X or a Y value\");\n }\n /**\n * @see http://stackoverflow.com/a/11908158/109458\n */ hasPoint() {\n let currPoint;\n let threshold = 0;\n if (typeof arguments[0] === \"number\" && typeof arguments[1] === \"number\") {\n currPoint = new Vector(arguments[0], arguments[1]);\n threshold = arguments[2] || 0;\n } else if (arguments[0] instanceof Vector) {\n currPoint = arguments[0];\n threshold = arguments[1] || 0;\n } else throw \"Could not determine the arguments for Vector.hasPoint\";\n const dxc = currPoint.x - this.begin.x;\n const dyc = currPoint.y - this.begin.y;\n const dx1 = this.end.x - this.begin.x;\n const dy1 = this.end.y - this.begin.y;\n const cross = dxc * dy1 - dyc * dx1;\n // check whether point lines on the line\n if (Math.abs(cross) > threshold) return false;\n // check whether point lies in-between start and end\n if (Math.abs(dx1) >= Math.abs(dy1)) return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\n else return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\n }\n }\n /**\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n * @param p0 Point where L1 begins\n * @param u Direction and length of L1\n * @param q0 Point were L2 begins\n * @param v Direction and length of L2\n */ function ClosestLine(p0, u, q0, v) {\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\n // w(s, t) = P(s) - Q(t)\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\n //\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\n //\n // The closest point between 2 lines then satisfies this pair of equations\n // 1: u * wClosest = 0\n // 2: v * wClosest = 0\n //\n // Substituting wClosest into the equations we get\n //\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\n // simplify w0\n const w0 = p0.sub(q0);\n // simplify (u * u);\n const a = u.dot(u);\n // simplify (u * v);\n const b = u.dot(v);\n // simplify (v * v)\n const c = v.dot(v);\n // simplify (u * w0)\n const d = u.dot(w0);\n // simplify (v * w0)\n const e = v.dot(w0);\n // denominator ac - b^2\n const denom = a * c - b * b;\n let sDenom = denom;\n let tDenom = denom;\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\n if (denom === 0 || denom <= 0.01) {\n const tClosestParallel = d / b;\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\n }\n // Solve for sClosest for infinite line\n let sClosest = b * e - c * d; // / denom;\n // Solve for tClosest for infinite line\n let tClosest = a * e - b * d; // / denom;\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\n if (sClosest < 0) {\n sClosest = 0;\n tClosest = e;\n tDenom = c;\n } else if (sClosest > sDenom) {\n sClosest = sDenom;\n tClosest = e + b;\n tDenom = c;\n }\n if (tClosest < 0) {\n tClosest = 0;\n if (-d < 0) sClosest = 0;\n else if (-d > a) sClosest = sDenom;\n else {\n sClosest = -d;\n sDenom = a;\n }\n } else if (tClosest > tDenom) {\n tClosest = tDenom;\n if (-d + b < 0) sClosest = 0;\n else if (-d + b > a) sClosest = sDenom;\n else {\n sClosest = -d + b;\n sDenom = a;\n }\n }\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\n }\n const ClosestLineJumpTable = {\n PolygonPolygonClosestLine (polygonA, polygonB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = polygonB.worldPos;\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\n const thisDirection = otherDirection.negate();\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\n const thisPoint = polygonA.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const otherPoint = polygonB.rayCast(rayTowardsThis).point.add(rayTowardsThis.dir.scale(0.1));\n const thisFace = polygonA.getClosestFace(thisPoint);\n const otherFace = polygonB.getClosestFace(otherPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const q0 = otherFace.face.begin;\n const v = otherFace.face.getEdge();\n return ClosestLine(p0, u, q0, v);\n },\n PolygonEdgeClosestLine (polygon, edge) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = edge.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const q0 = edgeStart;\n const v = edgeVector;\n return ClosestLine(p0, u, q0, v);\n },\n PolygonCircleClosestLine (polygon, circle) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circle.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // Time of minimum distance\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp\n if (t > 1) t = 1;\n else if (t < 0) t = 0;\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\n const circlex = (p0.x + u.x * t - otherWorldPos.x) * circle.radius / (circle.radius + d);\n const circley = (p0.y + u.y * t - otherWorldPos.y) * circle.radius / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\n },\n CircleCircleClosestLine (circleA, circleB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circleB.worldPos;\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\n const thisWorldPos = circleA.worldPos;\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\n const thisPoint = circleA.rayCast(rayTowardsOther);\n const otherPoint = circleB.rayCast(rayTowardsThis);\n return new LineSegment(thisPoint.point, otherPoint.point);\n },\n CircleEdgeClosestLine (circle, edge) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n const circleWorldPos = circle.worldPos;\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const p0 = edgeStart;\n const u = edgeVector;\n // Time of minimum distance\n let t = (u.x * (circleWorldPos.x - p0.x) + u.y * (circleWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp to edge\n if (t > 1) t = 1;\n else if (t < 0) t = 0;\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorldPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorldPos.y, 2)) - circle.radius;\n const circlex = (p0.x + u.x * t - circleWorldPos.x) * circle.radius / (circle.radius + d);\n const circley = (p0.y + u.y * t - circleWorldPos.y) * circle.radius / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorldPos.x + circlex, circleWorldPos.y + circley));\n },\n EdgeEdgeClosestLine (edgeA, edgeB) {\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLineA = edgeA.asLine();\n const edgeStartA = edgeLineA.begin;\n const edgeVectorA = edgeLineA.getEdge();\n const p0 = edgeStartA;\n const u = edgeVectorA;\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLineB = edgeB.asLine();\n const edgeStartB = edgeLineB.begin;\n const edgeVectorB = edgeLineB.getEdge();\n const q0 = edgeStartB;\n const v = edgeVectorB;\n return ClosestLine(p0, u, q0, v);\n }\n };\n /**\n * This is a circle collider for the excalibur rigid body physics simulation\n */ class CircleCollider extends Collider {\n get worldPos() {\n return this._globalMatrix.getPosition();\n }\n /**\n * Get the radius of the circle\n */ get radius() {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n return this._naturalRadius * Math.min(scale.x, scale.y);\n }\n /**\n * Set the radius of the circle\n */ set radius(val) {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n this._naturalRadius = val / Math.min(scale.x, scale.y);\n }\n constructor(options){\n super();\n /**\n * Position of the circle relative to the collider, by default (0, 0).\n */ this.offset = Vector.Zero;\n this._globalMatrix = AffineMatrix.identity();\n this.offset = options.offset || Vector.Zero;\n this.radius = options.radius || 0;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Returns a clone of this shape, not associated with any collider\n */ clone() {\n return new CircleCollider({\n offset: this.offset.clone(),\n radius: this.radius\n });\n }\n /**\n * Get the center of the collider in world coordinates\n */ get center() {\n return this._globalMatrix.getPosition();\n }\n /**\n * Tests if a point is contained in this collider\n */ contains(point) {\n var _a, _b;\n const pos = (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : this.offset;\n const distance = pos.distance(point);\n if (distance <= this.radius) return true;\n return false;\n }\n /**\n * Casts a ray at the Circle collider and returns the nearest point of collision\n * @param ray\n */ rayCast(ray, max = Infinity) {\n var _a, _b;\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\n const c = this.center;\n const dir = ray.dir;\n const orig = ray.pos;\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\n if (discriminant < 0) // no intersection\n return null;\n else {\n let toi = 0;\n // tangent case\n if (discriminant === 0) {\n toi = -dir.dot(orig.sub(c));\n if (toi > 0 && toi < max) {\n const point = ray.getPoint(toi);\n return {\n point: point,\n normal: point.sub(c).normalize(),\n collider: this,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n distance: toi\n };\n }\n return null;\n } else {\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\n const positiveToi = [];\n if (toi1 >= 0) positiveToi.push(toi1);\n if (toi2 >= 0) positiveToi.push(toi2);\n const minToi = Math.min(...positiveToi);\n if (minToi <= max) {\n const point = ray.getPoint(minToi);\n return {\n point: point,\n normal: point.sub(c).normalize(),\n collider: this,\n body: (_b = this.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent),\n distance: minToi\n };\n }\n return null;\n }\n }\n }\n getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\n else if (shape instanceof PolygonCollider) return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\n else if (shape instanceof EdgeCollider) return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\n * @inheritdoc\n */ collide(collider) {\n if (collider instanceof CircleCollider) return CollisionJumpTable.CollideCircleCircle(this, collider);\n else if (collider instanceof PolygonCollider) return CollisionJumpTable.CollideCirclePolygon(this, collider);\n else if (collider instanceof EdgeCollider) return CollisionJumpTable.CollideCircleEdge(this, collider);\n else throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */ getFurthestPoint(direction) {\n return this.center.add(direction.normalize().scale(this.radius));\n }\n /**\n * Find the local point on the shape in the direction specified\n * @param direction\n */ getFurthestLocalPoint(direction) {\n const dir = direction.normalize();\n return dir.scale(this.radius);\n }\n /**\n * Get the axis aligned bounding box for the circle collider in world coordinates\n */ get bounds() {\n var _a, _b, _c;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = (_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero;\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius).rotate(rotation).scale(scale).translate(pos);\n }\n /**\n * Get the axis aligned bounding box for the circle collider in local coordinates\n */ get localBounds() {\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius);\n }\n /**\n * Get axis not implemented on circles, since there are infinite axis in a circle\n */ get axes() {\n return [];\n }\n /**\n * Returns the moment of inertia of a circle given it's mass\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */ getInertia(mass) {\n return mass * this.radius * this.radius / 2;\n }\n /* istanbul ignore next */ update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Project the circle along a specified axis\n */ project(axis) {\n const scalars = [];\n const point = this.center;\n const dotProduct = point.dot(axis);\n scalars.push(dotProduct);\n scalars.push(dotProduct + this.radius);\n scalars.push(dotProduct - this.radius);\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color, options) {\n var _a, _b, _c, _d;\n const { lineWidth: lineWidth } = {\n lineWidth: 1,\n ...options\n };\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = (_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero;\n ex.save();\n ex.translate(pos.x, pos.y);\n ex.rotate(rotation);\n ex.scale(scale.x, scale.y);\n ex.drawCircle((_d = this.offset) !== null && _d !== void 0 ? _d : Vector.Zero, this._naturalRadius, Color.Transparent, color, lineWidth);\n ex.restore();\n }\n }\n /**\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\n * Pair prevents collisions from being evaluated more than one time\n */ class CollisionContact {\n constructor(colliderA, colliderB, mtv, normal, tangent, points, localPoints, info){\n var _a, _b, _c, _d, _e, _f;\n this._canceled = false;\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.mtv = mtv;\n this.normal = normal;\n this.tangent = tangent;\n this.points = points;\n this.localPoints = localPoints;\n this.info = info;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n if (colliderA.composite || colliderB.composite) {\n // Add on the parent composite pair for start/end contact if 'together\n const colliderAId = ((_a = colliderA.composite) === null || _a === void 0 ? void 0 : _a.compositeStrategy) === \"separate\" ? colliderA.id : (_c = (_b = colliderA.composite) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : colliderA.id;\n const colliderBId = ((_d = colliderB.composite) === null || _d === void 0 ? void 0 : _d.compositeStrategy) === \"separate\" ? colliderB.id : (_f = (_e = colliderB.composite) === null || _e === void 0 ? void 0 : _e.id) !== null && _f !== void 0 ? _f : colliderB.id;\n this.id += \"|\" + Pair.calculatePairHash(colliderAId, colliderBId);\n }\n }\n /**\n * Match contact awake state, except if body's are Fixed\n */ matchAwake() {\n const bodyA = this.colliderA.owner.get(BodyComponent);\n const bodyB = this.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.sleeping !== bodyB.sleeping) {\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= bodyA.wakeThreshold) bodyA.setSleeping(false);\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= bodyB.wakeThreshold) bodyB.setSleeping(false);\n }\n }\n }\n isCanceled() {\n return this._canceled;\n }\n cancel() {\n this._canceled = true;\n }\n }\n class SeparatingAxis {\n static findPolygonPolygonSeparation(polyA, polyB) {\n let bestSeparation = -Number.MAX_VALUE;\n let bestSide = null;\n let bestAxis = null;\n let bestSideIndex = -1;\n let bestOtherPoint = null;\n const sides = polyA.getSides();\n const localSides = polyA.getLocalSides();\n for(let i = 0; i < sides.length; i++){\n const side = sides[i];\n const axis = side.normal();\n const vertB = polyB.getFurthestPoint(axis.negate());\n // Separation on side i's axis\n // We are looking for the largest separation between poly A's sides\n const vertSeparation = side.distanceToPoint(vertB, true);\n if (vertSeparation > bestSeparation) {\n bestSeparation = vertSeparation;\n bestSide = side;\n bestAxis = axis;\n bestSideIndex = i;\n bestOtherPoint = vertB;\n }\n }\n return {\n collider: polyA,\n separation: bestAxis ? bestSeparation : 99,\n axis: bestAxis,\n side: bestSide,\n localSide: localSides[bestSideIndex],\n sideId: bestSideIndex,\n point: bestOtherPoint,\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis.negate()) : null\n };\n }\n static findCirclePolygonSeparation(circle, polygon) {\n const axes = polygon.axes;\n const pc = polygon.center;\n // Special SAT with circles\n const polyDir = pc.sub(circle.worldPos);\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\n let minOverlap = Number.MAX_VALUE;\n let minAxis = null;\n let minIndex = -1;\n for(let i = 0; i < axes.length; i++){\n const proj1 = polygon.project(axes[i]);\n const proj2 = circle.project(axes[i]);\n const overlap = proj1.getOverlap(proj2);\n if (overlap <= 0) return null;\n else if (overlap < minOverlap) {\n minOverlap = overlap;\n minAxis = axes[i];\n minIndex = i;\n }\n }\n if (minIndex < 0) return null;\n return minAxis.normalize().scale(minOverlap);\n }\n }\n const CollisionJumpTable = {\n CollideCircleCircle (circleA, circleB) {\n const circleAPos = circleA.worldPos;\n const circleBPos = circleB.worldPos;\n const combinedRadius = circleA.radius + circleB.radius;\n const distance = circleAPos.distance(circleBPos);\n if (distance > combinedRadius) return [];\n // negative means overlap\n const separation = combinedRadius - distance;\n // Normal points from A -> B\n const normal = circleBPos.sub(circleAPos).normalize();\n const tangent = normal.perpendicular();\n const mvt = normal.scale(separation);\n const point = circleA.getFurthestPoint(normal);\n const local = circleA.getFurthestLocalPoint(normal);\n const info = {\n collider: circleA,\n separation: separation,\n axis: normal,\n point: point\n };\n return [\n new CollisionContact(circleA, circleB, mvt, normal, tangent, [\n point\n ], [\n local\n ], info)\n ];\n },\n CollideCirclePolygon (circle, polygon) {\n var _a, _b;\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\n if (!minAxis) return [];\n // make sure that the minAxis is pointing away from circle\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\n const point = circle.getFurthestPoint(minAxis);\n const xf = (_b = (_a = circle.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const local = xf.applyInverse(point);\n const normal = minAxis.normalize();\n const info = {\n collider: circle,\n separation: -minAxis.size,\n axis: normal,\n point: point,\n localPoint: local,\n side: polygon.findSide(normal.negate()),\n localSide: polygon.findLocalSide(normal.negate())\n };\n return [\n new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [\n point\n ], [\n local\n ], info)\n ];\n },\n CollideCircleEdge (circle, edge) {\n // TODO not sure this actually abides by local/world collisions\n // Are edge.begin and edge.end local space or world space? I think they should be local\n // center of the circle in world pos\n const cc = circle.center;\n // vector in the direction of the edge\n const edgeWorld = edge.asLine();\n const e = edgeWorld.end.sub(edgeWorld.begin);\n // amount of overlap with the circle's center along the edge direction\n const u = e.dot(edgeWorld.end.sub(cc));\n const v = e.dot(cc.sub(edgeWorld.begin));\n const side = edge.asLine();\n const localSide = edge.asLocalLine();\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\n if (v <= 0) {\n const da = edgeWorld.begin.sub(cc);\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\n // save some sqrts\n if (dda > circle.radius * circle.radius) return []; // no collision\n const normal = da.normalize();\n const separation = circle.radius - Math.sqrt(dda);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.begin,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [\n side.begin\n ], [\n localSide.begin\n ], info)\n ];\n }\n // Potential region B collision (circle is on the right side of the edge, after the end)\n if (u <= 0) {\n const db = edgeWorld.end.sub(cc);\n const ddb = db.dot(db);\n if (ddb > circle.radius * circle.radius) return [];\n const normal = db.normalize();\n const separation = circle.radius - Math.sqrt(ddb);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.end,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [\n side.end\n ], [\n localSide.end\n ], info)\n ];\n }\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\n const den = e.dot(e);\n const pointOnEdge = edgeWorld.begin.scale(u).add(edgeWorld.end.scale(v)).scale(1 / den);\n const d = cc.sub(pointOnEdge);\n const dd = d.dot(d);\n if (dd > circle.radius * circle.radius) return []; // no collision\n let normal = e.perpendicular();\n // flip correct direction\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\n normal.x = -normal.x;\n normal.y = -normal.y;\n }\n normal = normal.normalize();\n const separation = circle.radius - Math.sqrt(dd);\n const mvt = normal.scale(separation);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: pointOnEdge,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, mvt, normal.negate(), normal.negate().perpendicular(), [\n pointOnEdge\n ], [\n pointOnEdge.sub(edge.worldPos)\n ], info)\n ];\n },\n CollideEdgeEdge () {\n // Edge-edge collision doesn't make sense\n return [];\n },\n CollidePolygonEdge (polygon, edge) {\n var _a;\n const pc = polygon.center;\n const ec = edge.center;\n const dir = ec.sub(pc).normalize();\n // build a temporary polygon from the edge to use SAT\n const linePoly = new PolygonCollider({\n points: [\n edge.begin,\n edge.end,\n edge.end.add(dir.scale(100)),\n edge.begin.add(dir.scale(100))\n ],\n offset: edge.offset\n });\n linePoly.owner = edge.owner;\n const tx = (_a = edge.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (tx) linePoly.update(edge.owner.get(TransformComponent).get());\n // Gross hack but poly-poly works well\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\n if (contact.length) {\n // Fudge the contact back to edge\n contact[0].colliderB = edge;\n contact[0].id = Pair.calculatePairHash(polygon.id, edge.id);\n }\n return contact;\n },\n CollidePolygonPolygon (polyA, polyB) {\n var _a, _b, _c, _d;\n // Multi contact from SAT\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\n // do a SAT test to find a min axis if it exists\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\n // If there is no overlap from boxA's perspective we can end early\n if (separationA.separation > 0) return [];\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\n // If there is no overlap from boxB's perspective exit now\n if (separationB.separation > 0) return [];\n // Separations are both negative, we want to pick the least negative (minimal movement)\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\n // The incident side is the most opposite from the axes of collision on the other collider\n const other = separation.collider === polyA ? polyB : polyA;\n const incident = other.findSide(separation.axis.negate());\n // Clip incident side by the perpendicular lines at each end of the reference side\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\n const reference = separation.side;\n const refDir = reference.dir().normalize();\n // Find our contact points by clipping the incident by the collision side\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\n let clipLeft = null;\n if (clipRight) clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\n // If there is no left there is no collision\n if (clipLeft) {\n // We only want clip points below the reference edge, discard the others\n const points = clipLeft.getPoints().filter((p)=>{\n return reference.below(p);\n });\n let normal = separation.axis;\n let tangent = normal.perpendicular();\n // Point Contact A -> B\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\n normal = normal.negate();\n tangent = normal.perpendicular();\n }\n // Points are clipped from incident which is the other collider\n // Store those as locals\n let localPoints = [];\n if (separation.collider === polyA) {\n const xf = (_b = (_a = polyB.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n localPoints = points.map((p)=>xf.applyInverse(p));\n } else {\n const xf = (_d = (_c = polyA.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n localPoints = points.map((p)=>xf.applyInverse(p));\n }\n return [\n new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)\n ];\n }\n return [];\n },\n FindContactSeparation (contact, localPoint) {\n var _a, _b, _c, _d;\n const shapeA = contact.colliderA;\n const txA = (_b = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const shapeB = contact.colliderB;\n const txB = (_d = (_c = contact.colliderB.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n // both are circles\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\n const combinedRadius = shapeA.radius + shapeB.radius;\n const distance = txA.pos.distance(txB.pos);\n const separation = combinedRadius - distance;\n return -separation;\n }\n // both are polygons\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\n if (contact.info.localSide) {\n let side;\n let worldPoint;\n if (contact.info.collider === shapeA) {\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\n worldPoint = txB.apply(localPoint);\n } else {\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\n worldPoint = txA.apply(localPoint);\n }\n return side.distanceToPoint(worldPoint, true);\n }\n }\n // polygon v circle\n if (shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider || shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider) {\n const worldPoint = txA.apply(localPoint);\n if (contact.info.side) return contact.info.side.distanceToPoint(worldPoint, true);\n }\n // polygon v edge\n if (shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider || shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider) {\n let worldPoint;\n if (contact.info.collider === shapeA) worldPoint = txB.apply(localPoint);\n else worldPoint = txA.apply(localPoint);\n if (contact.info.side) return contact.info.side.distanceToPoint(worldPoint, true);\n }\n // circle v edge\n if (shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider || shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider) {\n // Local point is always on the edge which is always shapeB\n const worldPoint = txB.apply(localPoint);\n let circlePoint;\n if (shapeA instanceof CircleCollider) circlePoint = shapeA.getFurthestPoint(contact.normal);\n const dist = worldPoint.distance(circlePoint);\n if (contact.info.side) return dist > 0 ? -dist : 0;\n }\n return 0;\n }\n };\n /**\n * Edge is a single line collider to create collisions with a single line.\n */ class EdgeCollider extends Collider {\n constructor(options){\n var _a;\n super();\n this._globalMatrix = AffineMatrix.identity();\n this.begin = options.begin || Vector.Zero;\n this.end = options.end || Vector.Zero;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n }\n /**\n * Returns a clone of this Edge, not associated with any collider\n */ clone() {\n return new EdgeCollider({\n begin: this.begin.clone(),\n end: this.end.clone()\n });\n }\n get worldPos() {\n var _a;\n const tx = this._transform;\n return (_a = tx === null || tx === void 0 ? void 0 : tx.globalPos.add(this.offset)) !== null && _a !== void 0 ? _a : this.offset;\n }\n /**\n * Get the center of the collision area in world coordinates\n */ get center() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const pos = begin.average(end);\n return pos;\n }\n _getTransformedBegin() {\n return this._globalMatrix.multiply(this.begin);\n }\n _getTransformedEnd() {\n return this._globalMatrix.multiply(this.end);\n }\n /**\n * Returns the slope of the line in the form of a vector\n */ getSlope() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return end.sub(begin).scale(1 / distance);\n }\n /**\n * Returns the length of the line segment in pixels\n */ getLength() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return distance;\n }\n /**\n * Tests if a point is contained in this collision area\n */ contains() {\n return false;\n }\n /**\n * @inheritdoc\n */ rayCast(ray, max = Infinity) {\n var _a;\n const numerator = this._getTransformedBegin().sub(ray.pos);\n // Test is line and ray are parallel and non intersecting\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) return null;\n // Lines are parallel\n const divisor = ray.dir.cross(this.getSlope());\n if (divisor === 0) return null;\n const t = numerator.cross(this.getSlope()) / divisor;\n if (t >= 0 && t <= max) {\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\n if (u >= 0 && u <= 1) return {\n distance: t,\n normal: this.asLine().normal(),\n collider: this,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n point: ray.getPoint(t)\n };\n }\n return null;\n }\n /**\n * Returns the closes line between this and another collider, from this -> collider\n * @param shape\n */ getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\n else if (shape instanceof PolygonCollider) return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\n else if (shape instanceof EdgeCollider) return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\n * @inheritdoc\n */ collide(shape) {\n if (shape instanceof CircleCollider) return CollisionJumpTable.CollideCircleEdge(shape, this);\n else if (shape instanceof PolygonCollider) return CollisionJumpTable.CollidePolygonEdge(shape, this);\n else if (shape instanceof EdgeCollider) return CollisionJumpTable.CollideEdgeEdge();\n else throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */ getFurthestPoint(direction) {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n if (direction.dot(transformedBegin) > 0) return transformedBegin;\n else return transformedEnd;\n }\n _boundsFromBeginEnd(begin, end, padding = 10) {\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\n // this causes problems for the collision system so we give them some padding\n return new BoundingBox(Math.min(begin.x, end.x) - padding, Math.min(begin.y, end.y) - padding, Math.max(begin.x, end.x) + padding, Math.max(begin.y, end.y) + padding);\n }\n /**\n * Get the axis aligned bounding box for the edge collider in world space\n */ get bounds() {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\n }\n /**\n * Get the axis aligned bounding box for the edge collider in local space\n */ get localBounds() {\n return this._boundsFromBeginEnd(this.begin, this.end);\n }\n /**\n * Returns this edge represented as a line in world coordinates\n */ asLine() {\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\n }\n /**\n * Return this edge as a line in local line coordinates (relative to the position)\n */ asLocalLine() {\n return new LineSegment(this.begin, this.end);\n }\n /**\n * Get the axis associated with the edge\n */ get axes() {\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\n const edgeNormal = e.normal();\n const axes = [];\n axes.push(edgeNormal);\n axes.push(edgeNormal.negate());\n axes.push(edgeNormal.normal());\n axes.push(edgeNormal.normal().negate());\n return axes;\n }\n /**\n * Get the moment of inertia for an edge\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */ getInertia(mass) {\n const length = this.end.sub(this.begin).distance() / 2;\n return mass * length * length;\n }\n /**\n * @inheritdoc\n */ update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Project the edge along a specified axis\n */ project(axis) {\n const scalars = [];\n const points = [\n this._getTransformedBegin(),\n this._getTransformedEnd()\n ];\n const len = points.length;\n for(let i = 0; i < len; i++)scalars.push(points[i].dot(axis));\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color) {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n ex.drawLine(begin, end, color, 2);\n ex.drawCircle(begin, 2, color);\n ex.drawCircle(end, 2, color);\n }\n }\n class Debug {\n static registerGraphicsContext(ctx) {\n Debug._ctx = ctx;\n }\n static draw(debugDrawCall) {\n this._drawCalls.push(debugDrawCall);\n }\n static drawPoint(point, options) {\n Debug.draw((ctx)=>{\n ctx.debug.drawPoint(point, options);\n });\n }\n static drawLine(start, end, options) {\n Debug.draw((ctx)=>{\n ctx.debug.drawLine(start, end, options);\n });\n }\n static drawLines(points, options) {\n if (points.length > 1) Debug.draw((ctx)=>{\n for(let i = 0; i < points.length - 1; i++)ctx.debug.drawLine(points[i], points[i + 1], options);\n });\n }\n static drawText(text, pos) {\n Debug.draw((ctx)=>{\n ctx.debug.drawText(text, pos);\n });\n }\n static drawPolygon(points, options) {\n if (points.length > 1) Debug.draw((ctx)=>{\n const firstPoint = points[0];\n const polygon = [\n ...points,\n firstPoint\n ];\n for(let i = 0; i < polygon.length - 1; i++)ctx.debug.drawLine(polygon[i], polygon[i + 1], options);\n });\n }\n static drawCircle(center, radius, options) {\n const { color: color, strokeColor: strokeColor, width: width } = {\n color: Color.Black,\n strokeColor: undefined,\n width: undefined,\n ...options\n };\n Debug.draw((ctx)=>{\n ctx.drawCircle(center, radius, color, strokeColor, width);\n });\n }\n static drawBounds(boundingBox, options) {\n Debug.draw((ctx)=>{\n ctx.debug.drawRect(boundingBox.left, boundingBox.top, boundingBox.width, boundingBox.height, options);\n });\n }\n static drawRay(ray, options) {\n const { distance: distance, color: color } = {\n color: Color.Blue,\n distance: 10,\n ...options\n };\n Debug.draw((ctx)=>{\n const start = ray.pos;\n const end = ray.pos.add(ray.dir.scale(distance));\n ctx.debug.drawLine(start, end, {\n color: color\n });\n });\n }\n static flush(ctx) {\n ctx.save();\n ctx.z = Debug.z;\n for (const drawCall of Debug._drawCalls)drawCall(ctx);\n ctx.restore();\n Debug.clear();\n }\n static clear() {\n Debug._drawCalls.length = 0;\n }\n }\n Debug._drawCalls = [];\n Debug.z = Infinity;\n /**\n * Polygon collider for detecting collisions\n */ class PolygonCollider extends Collider {\n flagDirty() {\n this._localBoundsDirty = true;\n this._localSidesDirty = true;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n }\n /**\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\n * Excalibur stores these in counter-clockwise order\n */ set points(points) {\n this._points = points;\n this.flagDirty();\n }\n /**\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\n * Excalibur stores these in counter-clockwise order\n */ get points() {\n return this._points;\n }\n constructor(options){\n var _a, _b;\n super();\n this._logger = Logger.getInstance();\n this._transformedPoints = [];\n this._sides = [];\n this._localSides = [];\n this._globalMatrix = AffineMatrix.identity();\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n this._localSidesDirty = true;\n this._localBoundsDirty = true;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n this.points = (_b = options.points) !== null && _b !== void 0 ? _b : [];\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\n if (!counterClockwise) this.points.reverse();\n if (!this.isConvex()) {\n if (!options.suppressConvexWarning) this._logger.warn(\"Excalibur only supports convex polygon colliders and will not behave properly.Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles\");\n }\n // calculate initial transformation\n this._calculateTransformation();\n }\n _isCounterClockwiseWinding(points) {\n // https://stackoverflow.com/a/1165943\n let sum = 0;\n for(let i = 0; i < points.length; i++)sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\n return sum < 0;\n }\n /**\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\n */ isConvex() {\n // From SO: https://stackoverflow.com/a/45372025\n if (this.points.length < 3) return false;\n let oldPoint = this.points[this.points.length - 2];\n let newPoint = this.points[this.points.length - 1];\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n let oldDirection = 0;\n let orientation = 0;\n let angleSum = 0;\n for (const [i, point] of this.points.entries()){\n oldPoint = newPoint;\n oldDirection = direction;\n newPoint = point;\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n if (oldPoint.equals(newPoint)) return false; // repeat point\n let angle = direction - oldDirection;\n if (angle <= -Math.PI) angle += Math.PI * 2;\n else if (angle > Math.PI) angle -= Math.PI * 2;\n if (i === 0) {\n if (angle === 0.0) return false;\n orientation = angle > 0 ? 1 : -1;\n } else {\n if (orientation * angle <= 0) return false;\n }\n angleSum += angle;\n }\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\n }\n /**\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\n */ tessellate() {\n const polygons = [];\n for(let i = 1; i < this.points.length - 2; i++)polygons.push([\n this.points[0],\n this.points[i + 1],\n this.points[i + 2]\n ]);\n polygons.push([\n this.points[0],\n this.points[1],\n this.points[2]\n ]);\n return new CompositeCollider(polygons.map((points)=>Shape.Polygon(points)));\n }\n /**\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\n */ triangulate() {\n // https://www.youtube.com/watch?v=hTJFcHutls8\n if (this.points.length < 3) throw Error(\"Invalid polygon\");\n const triangles = [];\n // algorithm likes clockwise\n const vertices = [\n ...this.points\n ].reverse();\n let vertexCount = vertices.length;\n /**\n * Returns the previous index based on the current vertex\n */ function getPrevIndex(index) {\n return index === 0 ? vertexCount - 1 : index - 1;\n }\n /**\n * Retrieves the next index based on the current vertex\n */ function getNextIndex(index) {\n return index === vertexCount - 1 ? 0 : index + 1;\n }\n /**\n * Whether or not the angle at this vertex index is convex\n */ function isConvex(index) {\n const prev = getPrevIndex(index);\n const next = getNextIndex(index);\n const va = vertices[prev];\n const vb = vertices[index];\n const vc = vertices[next];\n // Check convexity\n const leftArm = va.sub(vb);\n const rightArm = vc.sub(vb);\n // Positive cross product is convex\n if (leftArm.cross(rightArm) < 0) return false;\n return true;\n }\n const convexVertices = vertices.map((_, i)=>isConvex(i));\n /**\n * Quick test for point in triangle\n */ function isPointInTriangle(point, a, b, c) {\n const ab = b.sub(a);\n const bc = c.sub(b);\n const ca = a.sub(c);\n const ap = point.sub(a);\n const bp = point.sub(b);\n const cp = point.sub(c);\n const cross1 = ab.cross(ap);\n const cross2 = bc.cross(bp);\n const cross3 = ca.cross(cp);\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) return false;\n return true;\n }\n /**\n * Calculate the area of the triangle\n */ // function triangleArea(a: Vector, b: Vector, c: Vector) {\n // return Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - c.y))/2;\n // }\n /**\n * Find the next suitable ear tip\n */ function findEarTip() {\n for(let i = 0; i < vertexCount; i++)if (convexVertices[i]) {\n const prev = getPrevIndex(i);\n const next = getNextIndex(i);\n const va = vertices[prev];\n const vb = vertices[i];\n const vc = vertices[next];\n let isEar = true;\n // Check that if any vertices are in the triangle a, b, c\n for(let j = 0; j < vertexCount; j++){\n // We can skip these verts because they are the triangle we are testing\n if (j === i || j === prev || j === next) continue;\n const point = vertices[j];\n if (isPointInTriangle(point, va, vb, vc)) {\n isEar = false;\n break;\n }\n }\n // Add ear to polygon list and remove from list\n if (isEar) return i;\n }\n // Fall back to any convex vertex\n for(let i = 0; i < vertexCount; i++){\n if (convexVertices[i]) return i;\n }\n // bail and return the first one?\n return 0;\n }\n /**\n * Cut the ear and produce a triangle, update internal state\n */ function cutEarTip(index) {\n const prev = getPrevIndex(index);\n const next = getNextIndex(index);\n const va = vertices[prev];\n const vb = vertices[index];\n const vc = vertices[next];\n // Clockwise winding\n // if (triangleArea(va, vb, vc) > 0) {\n triangles.push([\n va,\n vb,\n vc\n ]);\n // }\n vertices.splice(index, 1);\n convexVertices.splice(index, 1);\n vertexCount--;\n }\n // Loop over all the vertices finding ears\n while(vertexCount > 3){\n const earIndex = findEarTip();\n cutEarTip(earIndex);\n // reclassify vertices\n for(let i = 0; i < vertexCount; i++)convexVertices[i] = isConvex(i);\n }\n // Last triangle after the loop\n triangles.push([\n vertices[0],\n vertices[1],\n vertices[2]\n ]);\n // FIXME: there is a colinear triangle that sneaks in here sometimes\n return new CompositeCollider(triangles.map((points)=>Shape.Polygon(points, Vector.Zero, true)));\n }\n /**\n * Returns a clone of this ConvexPolygon, not associated with any collider\n */ clone() {\n return new PolygonCollider({\n offset: this.offset.clone(),\n points: this.points.map((p)=>p.clone())\n });\n }\n /**\n * Returns the world position of the collider, which is the current body transform plus any defined offset\n */ get worldPos() {\n if (this._transform) return this._transform.pos.add(this.offset);\n return this.offset;\n }\n /**\n * Get the center of the collider in world coordinates\n */ get center() {\n return this.bounds.center;\n }\n /**\n * Calculates the underlying transformation from the body relative space to world space\n */ _calculateTransformation() {\n const points = this.points;\n const len = points.length;\n this._transformedPoints.length = 0; // clear out old transform\n for(let i = 0; i < len; i++)this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\n }\n /**\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\n */ getTransformedPoints() {\n if (this._transformedPointsDirty) {\n this._calculateTransformation();\n this._transformedPointsDirty = false;\n }\n return this._transformedPoints;\n }\n /**\n * Gets the sides of the polygon in world space\n */ getSides() {\n if (this._sidesDirty) {\n const lines = [];\n const points = this.getTransformedPoints();\n const len = points.length;\n for(let i = 0; i < len; i++)// This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n this._sides = lines;\n this._sidesDirty = false;\n }\n return this._sides;\n }\n /**\n * Returns the local coordinate space sides\n */ getLocalSides() {\n if (this._localSidesDirty) {\n const lines = [];\n const points = this.points;\n const len = points.length;\n for(let i = 0; i < len; i++)// This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n this._localSides = lines;\n this._localSidesDirty = false;\n }\n return this._localSides;\n }\n /**\n * Given a direction vector find the world space side that is most in that direction\n * @param direction\n */ findSide(direction) {\n const sides = this.getSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let side = 0; side < sides.length; side++){\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\n * Given a direction vector find the local space side that is most in that direction\n * @param direction\n */ findLocalSide(direction) {\n const sides = this.getLocalSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let side = 0; side < sides.length; side++){\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\n * Get the axis associated with the convex polygon\n */ get axes() {\n const axes = [];\n const sides = this.getSides();\n for(let i = 0; i < sides.length; i++)axes.push(sides[i].normal());\n return axes;\n }\n /**\n * Updates the transform for the collision geometry\n *\n * Collision geometry (points/bounds) will not change until this is called.\n * @param transform\n */ update(transform) {\n var _a;\n if (transform) {\n this._transform = transform;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n // This change means an update must be performed in order for geometry to update\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n }\n /**\n * Tests if a point is contained in this collider in world space\n */ contains(point) {\n // Always cast to the right, as long as we cast in a consistent fixed direction we\n // will be fine\n const testRay = new Ray(point, new Vector(1, 0));\n const intersectCount = this.getSides().reduce(function(accum, side) {\n if (testRay.intersect(side) >= 0) return accum + 1;\n return accum;\n }, 0);\n if (intersectCount % 2 === 0) return false;\n return true;\n }\n getClosestLineBetween(collider) {\n if (collider instanceof CircleCollider) return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\n else if (collider instanceof PolygonCollider) return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\n else if (collider instanceof EdgeCollider) return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\n * return null.\n * @param collider\n */ collide(collider) {\n if (collider instanceof CircleCollider) return CollisionJumpTable.CollideCirclePolygon(collider, this);\n else if (collider instanceof PolygonCollider) return CollisionJumpTable.CollidePolygonPolygon(this, collider);\n else if (collider instanceof EdgeCollider) return CollisionJumpTable.CollidePolygonEdge(this, collider);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */ getFurthestPoint(direction) {\n const pts = this.getTransformedPoints();\n let furthestPoint = null;\n let maxDistance = -Number.MAX_VALUE;\n for(let i = 0; i < pts.length; i++){\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\n * Find the local point on the collider furthest in the direction specified\n * @param direction\n */ getFurthestLocalPoint(direction) {\n const pts = this.points;\n let furthestPoint = pts[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let i = 0; i < pts.length; i++){\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\n * Finds the closes face to the point using perpendicular distance\n * @param point point to test against polygon\n */ getClosestFace(point) {\n const sides = this.getSides();\n let min = Number.POSITIVE_INFINITY;\n let faceIndex = -1;\n let distance = -1;\n for(let i = 0; i < sides.length; i++){\n const dist = sides[i].distanceToPoint(point);\n if (dist < min) {\n min = dist;\n faceIndex = i;\n distance = dist;\n }\n }\n if (faceIndex !== -1) return {\n distance: sides[faceIndex].normal().scale(distance),\n face: sides[faceIndex]\n };\n return null;\n }\n /**\n * Get the axis aligned bounding box for the polygon collider in world coordinates\n */ get bounds() {\n return this.localBounds.transform(this._globalMatrix);\n }\n /**\n * Get the axis aligned bounding box for the polygon collider in local coordinates\n */ get localBounds() {\n if (this._localBoundsDirty) {\n this._localBounds = BoundingBox.fromPoints(this.points);\n this._localBoundsDirty = false;\n }\n return this._localBounds;\n }\n /**\n * Get the moment of inertia for an arbitrary polygon\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */ getInertia(mass) {\n if (this._cachedMass === mass && this._cachedInertia) return this._cachedInertia;\n let numerator = 0;\n let denominator = 0;\n const points = this.points;\n for(let i = 0; i < points.length; i++){\n const iplusone = (i + 1) % points.length;\n const crossTerm = points[iplusone].cross(points[i]);\n numerator += crossTerm * (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\n denominator += crossTerm;\n }\n this._cachedMass = mass;\n return this._cachedInertia = mass / 6 * (numerator / denominator);\n }\n /**\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\n */ rayCast(ray, max = Infinity) {\n var _a;\n // find the minimum contact time greater than 0\n // contact times less than 0 are behind the ray and we don't want those\n const sides = this.getSides();\n const len = sides.length;\n let minContactTime = Number.MAX_VALUE;\n let contactSide;\n let contactIndex = -1;\n for(let i = 0; i < len; i++){\n const contactTime = ray.intersect(sides[i]);\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\n minContactTime = contactTime;\n contactSide = sides[i];\n contactIndex = i;\n }\n }\n // contact was found\n if (contactIndex >= 0) return {\n collider: this,\n distance: minContactTime,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n point: ray.getPoint(minContactTime),\n normal: contactSide.normal()\n };\n // no contact found\n return null;\n }\n /**\n * Project the edges of the polygon along a specified axis\n */ project(axis) {\n const points = this.getTransformedPoints();\n const len = points.length;\n let min = Number.MAX_VALUE;\n let max = -Number.MAX_VALUE;\n for(let i = 0; i < len; i++){\n const scalar = points[i].dot(axis);\n min = Math.min(min, scalar);\n max = Math.max(max, scalar);\n }\n return new Projection(min, max);\n }\n debug(ex, color, options) {\n const points = this.getTransformedPoints();\n Debug.drawPolygon(points, {\n color: color\n });\n }\n }\n /**\n * Excalibur helper for defining colliders quickly\n */ class Shape {\n /**\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\n * @param width Width of the box\n * @param height Height of the box\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\n * @param offset Optional offset relative to the collider in local coordinates\n */ static Box(width, height, anchor = Vector.Half, offset = Vector.Zero) {\n return new PolygonCollider({\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\n offset: offset\n });\n }\n /**\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\n *\n * PolygonColliders are useful for creating convex polygon shapes\n * @param points Points specified in counter clockwise\n * @param offset Optional offset relative to the collider in local coordinates\n */ static Polygon(points, offset = Vector.Zero, suppressConvexWarning = false) {\n return new PolygonCollider({\n points: points,\n offset: offset,\n suppressConvexWarning: suppressConvexWarning\n });\n }\n /**\n * Creates a new [[CircleCollider|circle]] collider\n *\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\n * @param radius Radius of the circle collider\n * @param offset Optional offset relative to the collider in local coordinates\n */ static Circle(radius, offset = Vector.Zero) {\n return new CircleCollider({\n radius: radius,\n offset: offset\n });\n }\n /**\n * Creates a new [[EdgeCollider|edge]] collider\n *\n * Edge colliders are useful for floors, walls, and other barriers\n * @param begin Beginning of the edge in local coordinates to the collider\n * @param end Ending of the edge in local coordinates to the collider\n */ static Edge(begin, end) {\n return new EdgeCollider({\n begin: begin,\n end: end\n });\n }\n /**\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\n *\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\n * player experience.\n * @param width\n * @param height\n * @param offset Optional offset\n */ static Capsule(width, height, offset = Vector.Zero) {\n const logger = Logger.getInstance();\n if (width === height) logger.warn(\"A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider\");\n const vertical = height >= width;\n if (vertical) {\n // height > width, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\n Shape.Box(width, height - width, Vector.Half, offset),\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\n ]);\n return capsule;\n } else {\n // width > height, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\n Shape.Box(width - height, height, Vector.Half, offset),\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\n ]);\n return capsule;\n }\n }\n }\n class ColliderComponent extends Component {\n constructor(collider){\n super();\n this.events = new EventEmitter();\n /**\n * Observable that notifies when a collider is added to the body\n */ this.$colliderAdded = new Observable();\n /**\n * Observable that notifies when a collider is removed from the body\n */ this.$colliderRemoved = new Observable();\n this._collidersToRemove = [];\n this.set(collider);\n }\n /**\n * Get the current collider geometry\n */ get() {\n return this._collider;\n }\n /**\n * Set the collider geometry\n * @param collider\n * @returns the collider you set\n */ set(collider) {\n this.clear();\n if (collider) {\n this._collider = collider;\n this._collider.owner = this.owner;\n collider.events.pipe(this.events);\n this.$colliderAdded.notifyAll(collider);\n this.update();\n }\n return collider;\n }\n /**\n * Remove collider geometry from collider component\n */ clear() {\n if (this._collider) {\n this._collidersToRemove.push(this._collider);\n this._collider = null;\n }\n }\n processColliderRemoval() {\n for (const collider of this._collidersToRemove){\n collider.events.unpipe(this.events);\n this.$colliderRemoved.notifyAll(collider);\n collider.owner = null;\n }\n }\n clone() {\n const clone = new ColliderComponent(this._collider.clone());\n return clone;\n }\n /**\n * Return world space bounds\n */ get bounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\n * Return local space bounds\n */ get localBounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\n * Update the collider's transformed geometry\n */ update() {\n var _a;\n const tx = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (this._collider) {\n this._collider.owner = this.owner;\n if (tx) this._collider.update(tx.get());\n }\n }\n /**\n * Collide component with another\n * @param other\n */ collide(other) {\n let colliderA = this._collider;\n let colliderB = other._collider;\n if (!colliderA || !colliderB) return [];\n // If we have a composite left hand side :(\n // Might bite us, but to avoid updating all the handlers make composite always left side\n let flipped = false;\n if (colliderB instanceof CompositeCollider) {\n colliderA = colliderB;\n colliderB = this._collider;\n flipped = true;\n }\n if (this._collider) {\n const contacts = colliderA.collide(colliderB);\n if (contacts) {\n if (flipped) contacts.forEach((contact)=>{\n contact.mtv = contact.mtv.negate();\n contact.normal = contact.normal.negate();\n contact.tangent = contact.normal.perpendicular();\n contact.colliderA = this._collider;\n contact.colliderB = other._collider;\n });\n return contacts;\n }\n return [];\n }\n return [];\n }\n onAdd(entity) {\n if (this._collider) this.update();\n // Wire up the collider events to the owning entity\n this.events.on(\"precollision\", (evt)=>{\n const precollision = evt;\n entity.events.emit(\"precollision\", new PreCollisionEvent(precollision.target.owner, precollision.other.owner, precollision.side, precollision.intersection, precollision.contact));\n if (entity instanceof Actor) entity.onPreCollisionResolve(precollision.target, precollision.other, precollision.side, precollision.contact);\n });\n this.events.on(\"postcollision\", (evt)=>{\n const postcollision = evt;\n entity.events.emit(\"postcollision\", new PostCollisionEvent(postcollision.target.owner, postcollision.other.owner, postcollision.side, postcollision.intersection, postcollision.contact));\n if (entity instanceof Actor) entity.onPostCollisionResolve(postcollision.target, postcollision.other, postcollision.side, postcollision.contact);\n });\n this.events.on(\"collisionstart\", (evt)=>{\n const start = evt;\n entity.events.emit(\"collisionstart\", new CollisionStartEvent(start.target.owner, start.other.owner, start.side, start.contact));\n if (entity instanceof Actor) entity.onCollisionStart(start.target, start.other, start.side, start.contact);\n });\n this.events.on(\"collisionend\", (evt)=>{\n const end = evt;\n entity.events.emit(\"collisionend\", new CollisionEndEvent(end.target.owner, end.other.owner, end.side, end.lastContact));\n if (entity instanceof Actor) entity.onCollisionEnd(end.target, end.other, end.side, end.lastContact);\n });\n }\n onRemove() {\n this.events.clear();\n this.$colliderRemoved.notifyAll(this._collider);\n }\n /**\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\n *\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */ useBoxCollider(width, height, anchor = Vector.Half, center = Vector.Zero) {\n const collider = Shape.Box(width, height, anchor, center);\n return this.set(collider);\n }\n /**\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\n * to the anchor of the associated actor\n * of this physics body.\n *\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */ usePolygonCollider(points, center = Vector.Zero) {\n const poly = Shape.Polygon(points, center);\n return this.set(poly);\n }\n /**\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */ useCircleCollider(radius, center = Vector.Zero) {\n const collider = Shape.Circle(radius, center);\n return this.set(collider);\n }\n /**\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\n * of this physics body.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */ useEdgeCollider(begin, end) {\n const collider = Shape.Edge(begin, end);\n return this.set(collider);\n }\n /**\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\n * @param colliders\n */ useCompositeCollider(colliders) {\n return this.set(new CompositeCollider(colliders));\n }\n }\n var DegreeOfFreedom;\n (function(DegreeOfFreedom) {\n DegreeOfFreedom[\"Rotation\"] = \"rotation\";\n DegreeOfFreedom[\"X\"] = \"x\";\n DegreeOfFreedom[\"Y\"] = \"y\";\n })(DegreeOfFreedom || (DegreeOfFreedom = {}));\n /**\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\n * of physics simulation.\n */ class BodyComponent extends Component {\n constructor(options){\n var _a, _b, _c;\n super();\n this.dependencies = [\n TransformComponent,\n MotionComponent\n ];\n this.id = createId(\"body\", BodyComponent._ID++);\n this.events = new EventEmitter();\n this.oldTransform = new transform_Transform();\n /**\n * Indicates whether the old transform has been captured at least once for interpolation\n * @internal\n */ this.__oldTransformCaptured = false;\n /**\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\n */ this.enableFixedUpdateInterpolate = true;\n /**\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\n */ this.collisionType = CollisionType.PreventCollision;\n /**\n * The collision group for the body's colliders, by default body colliders collide with everything\n */ this.group = CollisionGroup.All;\n this._sleeping = false;\n /**\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\n */ this.bounciness = 0.2;\n /**\n * The coefficient of friction on this actor\n */ this.friction = 0.99;\n /**\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\n */ this.useGravity = true;\n /**\n * Degrees of freedom to limit\n *\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\n */ this.limitDegreeOfFreedom = [];\n /**\n * The velocity of the actor last frame (vx, vy) in pixels/second\n */ this.oldVel = new Vector(0, 0);\n /**\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */ this.oldAcc = Vector.Zero;\n if (options) {\n this.collisionType = (_a = options.type) !== null && _a !== void 0 ? _a : this.collisionType;\n this.group = (_b = options.group) !== null && _b !== void 0 ? _b : this.group;\n this.useGravity = (_c = options.useGravity) !== null && _c !== void 0 ? _c : this.useGravity;\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies,\n ...options.config\n };\n } else this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies\n };\n this.updatePhysicsConfig(this._bodyConfig);\n this._mass = BodyComponent._DEFAULT_CONFIG.defaultMass;\n }\n get matrix() {\n return this.transform.get().matrix;\n }\n /**\n * Called by excalibur to update physics config defaults if they change\n * @param config\n */ updatePhysicsConfig(config) {\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies,\n ...config\n };\n this.canSleep = this._bodyConfig.canSleepByDefault;\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\n this.wakeThreshold = this._bodyConfig.wakeThreshold;\n }\n /**\n * Called by excalibur to update defaults\n * @param config\n */ static updateDefaultPhysicsConfig(config) {\n BodyComponent._DEFAULT_CONFIG = config;\n }\n get mass() {\n return this._mass;\n }\n set mass(newMass) {\n this._mass = newMass;\n this._cachedInertia = undefined;\n this._cachedInverseInertia = undefined;\n }\n /**\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\n */ get inverseMass() {\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\n }\n /**\n * Whether this body is sleeping or not\n */ get sleeping() {\n return this._sleeping;\n }\n /**\n * Set the sleep state of the body\n * @param sleeping\n */ setSleeping(sleeping) {\n this._sleeping = sleeping;\n if (!sleeping) // Give it a kick to keep it from falling asleep immediately\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\n else {\n this.vel = Vector.Zero;\n this.acc = Vector.Zero;\n this.angularVelocity = 0;\n this.sleepMotion = 0;\n }\n }\n /**\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\n */ updateMotion() {\n if (this._sleeping) this.setSleeping(true);\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\n const bias = this._bodyConfig.sleepBias;\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * this._bodyConfig.sleepEpsilon);\n if (this.canSleep && this.sleepMotion < this._bodyConfig.sleepEpsilon) this.setSleeping(true);\n }\n /**\n * Get the moment of inertia from the [[ColliderComponent]]\n */ get inertia() {\n if (this._cachedInertia) return this._cachedInertia;\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\n const collider = this.owner.get(ColliderComponent);\n if (collider) {\n collider.$colliderAdded.subscribe(()=>{\n this._cachedInertia = null;\n });\n collider.$colliderRemoved.subscribe(()=>{\n this._cachedInertia = null;\n });\n const maybeCollider = collider.get();\n if (maybeCollider) return this._cachedInertia = maybeCollider.getInertia(this.mass);\n }\n return 0;\n }\n /**\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\n */ get inverseInertia() {\n if (this._cachedInverseInertia) return this._cachedInverseInertia;\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\n }\n /**\n * Returns if the owner is active\n */ get active() {\n var _a;\n return !!((_a = this.owner) === null || _a === void 0 ? void 0 : _a.active);\n }\n /**\n * @deprecated Use globalP0s\n */ get center() {\n return this.globalPos;\n }\n get transform() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n }\n get motion() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(MotionComponent);\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n /**\n * The (x, y) position of the actor this will be in the middle of the actor if the\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\n */ get globalPos() {\n return this.transform.globalPos;\n }\n set globalPos(val) {\n this.transform.globalPos = val;\n }\n /**\n * The position of the actor last frame (x, y) in pixels\n */ get oldPos() {\n return this.oldTransform.pos;\n }\n /**\n * The current velocity vector (vx, vy) of the actor in pixels/second\n */ get vel() {\n return this.motion.vel;\n }\n set vel(val) {\n this.motion.vel = val;\n }\n /**\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\n * be useful to simulate a gravitational effect.\n */ get acc() {\n return this.motion.acc;\n }\n set acc(val) {\n this.motion.acc = val;\n }\n /**\n * The current torque applied to the actor\n */ get torque() {\n return this.motion.torque;\n }\n set torque(val) {\n this.motion.torque = val;\n }\n /**\n * Gets/sets the rotation of the body from the last frame.\n */ get oldRotation() {\n return this.oldTransform.rotation;\n }\n /**\n * The rotation of the body in radians\n */ get rotation() {\n return this.transform.globalRotation;\n }\n set rotation(val) {\n this.transform.globalRotation = val;\n }\n /**\n * The scale vector of the actor\n */ get scale() {\n return this.transform.globalScale;\n }\n set scale(val) {\n this.transform.globalScale = val;\n }\n /**\n * The scale of the actor last frame\n */ get oldScale() {\n return this.oldTransform.scale;\n }\n /**\n * The scale rate of change of the actor in scale/second\n */ get scaleFactor() {\n return this.motion.scaleFactor;\n }\n set scaleFactor(scaleFactor) {\n this.motion.scaleFactor = scaleFactor;\n }\n /**\n * Get the angular velocity in radians/second\n */ get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\n * Set the angular velocity in radians/second\n */ set angularVelocity(value) {\n this.motion.angularVelocity = value;\n }\n /**\n * Apply a specific impulse to the body\n * @param point\n * @param impulse\n */ applyImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) finalImpulse.x = 0;\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) finalImpulse.y = 0;\n this.vel.addEqual(finalImpulse);\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\n * Apply only linear impulse to the body\n * @param impulse\n */ applyLinearImpulse(impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) finalImpulse.x = 0;\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) finalImpulse.y = 0;\n this.vel = this.vel.add(finalImpulse);\n }\n /**\n * Apply only angular impulse to the body\n * @param point\n * @param impulse\n */ applyAngularImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\n * Sets the old versions of pos, vel, acc, and scale.\n */ captureOldTransform() {\n // Capture old values before integration step updates them\n this.__oldTransformCaptured = true;\n const tx = this.transform.get();\n tx.clone(this.oldTransform);\n this.oldTransform.parent = tx.parent; // also grab parent\n this.oldVel.setTo(this.vel.x, this.vel.y);\n this.oldAcc.setTo(this.acc.x, this.acc.y);\n }\n clone() {\n const component = super.clone();\n return component;\n }\n }\n BodyComponent._ID = 0;\n BodyComponent._DEFAULT_CONFIG = {\n ...DefaultPhysicsConfig.bodies\n };\n /**\n * AddedComponent message\n */ class AddedComponent {\n constructor(data){\n this.data = data;\n this.type = \"Component Added\";\n }\n }\n /**\n * Type guard to know if message is f an Added Component\n */ function isAddedComponent(x) {\n return !!x && x.type === \"Component Added\";\n }\n /**\n * RemovedComponent message\n */ class RemovedComponent {\n constructor(data){\n this.data = data;\n this.type = \"Component Removed\";\n }\n }\n /**\n * Type guard to know if message is for a Removed Component\n */ function isRemovedComponent(x) {\n return !!x && x.type === \"Component Removed\";\n }\n const EntityEvents = {\n Initialize: \"initialize\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n Kill: \"kill\"\n };\n /**\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\n *\n * Entities can be strongly typed with the components they contain\n *\n * ```typescript\n * const entity = new Entity();\n * entity.components.a; // Type ComponentA\n * entity.components.b; // Type ComponentB\n * ```\n */ class Entity {\n constructor(componentsOrOptions, name){\n /**\n * The unique identifier for the entity\n */ this.id = Entity._ID++;\n this.name = `Entity#${this.id}`;\n /**\n * Listen to or emit events for an entity\n */ this.events = new EventEmitter();\n this._tags = new Set();\n this.componentAdded$ = new Observable;\n this.componentRemoved$ = new Observable;\n this.tagAdded$ = new Observable;\n this.tagRemoved$ = new Observable;\n /**\n * Current components on the entity\n *\n * **Do not modify**\n *\n * Use addComponent/removeComponent otherwise the ECS will not be notified of changes.\n */ this.components = new Map();\n this._componentsToRemove = [];\n this._instanceOfComponentCacheDirty = true;\n this._instanceOfComponentCache = new Map();\n /**\n * The current scene that the entity is in, if any\n */ this.scene = null;\n /**\n * Whether this entity is active, if set to false it will be reclaimed\n */ this.active = true;\n this._parent = null;\n this.childrenAdded$ = new Observable();\n this.childrenRemoved$ = new Observable();\n this._children = [];\n this._isInitialized = false;\n let componentsToAdd;\n let nameToAdd;\n if (Array.isArray(componentsOrOptions)) {\n componentsToAdd = componentsOrOptions;\n nameToAdd = name;\n } else if (componentsOrOptions && typeof componentsOrOptions === \"object\") {\n const { components: components, name: name } = componentsOrOptions;\n componentsToAdd = components;\n nameToAdd = name;\n }\n if (nameToAdd) this.name = nameToAdd;\n if (componentsToAdd) for (const component of componentsToAdd)this.addComponent(component);\n // this.addComponent(this.tagsComponent);\n }\n /**\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\n * If parented it will be removed from the parent when killed.\n */ kill() {\n if (this.active) {\n this.active = false;\n this.unparent();\n }\n this.emit(\"kill\", new KillEvent(this));\n }\n isKilled() {\n return !this.active;\n }\n /**\n * Specifically get the tags on the entity from [[TagsComponent]]\n */ get tags() {\n return this._tags;\n }\n /**\n * Check if a tag exists on the entity\n * @param tag name to check for\n */ hasTag(tag) {\n return this._tags.has(tag);\n }\n /**\n * Adds a tag to an entity\n * @param tag\n */ addTag(tag) {\n this._tags.add(tag);\n this.tagAdded$.notifyAll(tag);\n }\n /**\n * Removes a tag on the entity\n *\n * Removals are deferred until the end of update\n * @param tag\n */ removeTag(tag) {\n this._tags.delete(tag);\n this.tagRemoved$.notifyAll(tag);\n }\n /**\n * The types of the components on the Entity\n */ get types() {\n return Array.from(this.components.keys());\n }\n /**\n * Returns all component instances on entity\n */ getComponents() {\n return Array.from(this.components.values());\n }\n /**\n * Verifies that an entity has all the required types\n * @param requiredTypes\n */ hasAll(requiredTypes) {\n for(let i = 0; i < requiredTypes.length; i++){\n if (!this.components.has(requiredTypes[i])) return false;\n }\n return true;\n }\n /**\n * Verifies that an entity has all the required tags\n * @param requiredTags\n */ hasAllTags(requiredTags) {\n for(let i = 0; i < requiredTags.length; i++){\n if (!this.tags.has(requiredTags[i])) return false;\n }\n return true;\n }\n _getCachedInstanceOfType(type) {\n if (this._instanceOfComponentCacheDirty) {\n this._instanceOfComponentCacheDirty = false;\n this._instanceOfComponentCache.clear();\n }\n if (this._instanceOfComponentCache.has(type)) return this._instanceOfComponentCache.get(type);\n for (const instance of this.components.values())if (instance instanceof type) {\n this._instanceOfComponentCache.set(type, instance);\n return instance;\n }\n return undefined;\n }\n get(type) {\n const maybeComponent = this._getCachedInstanceOfType(type);\n return maybeComponent !== null && maybeComponent !== void 0 ? maybeComponent : this.components.get(type);\n }\n get parent() {\n return this._parent;\n }\n /**\n * Get the direct children of this entity\n */ get children() {\n return this._children;\n }\n /**\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\n */ unparent() {\n if (this._parent) {\n this._parent.removeChild(this);\n this._parent = null;\n }\n }\n /**\n * Adds an entity to be a child of this entity\n * @param entity\n */ addChild(entity) {\n if (entity.parent === null) {\n if (this.getAncestors().includes(entity)) throw new Error(\"Cycle detected, cannot add entity\");\n this._children.push(entity);\n entity._parent = this;\n this.childrenAdded$.notifyAll(entity);\n } else throw new Error(\"Entity already has a parent, cannot add without unparenting\");\n return this;\n }\n /**\n * Remove an entity from children if it exists\n * @param entity\n */ removeChild(entity) {\n if (entity.parent === this) {\n removeItemFromArray(entity, this._children);\n entity._parent = null;\n this.childrenRemoved$.notifyAll(entity);\n }\n return this;\n }\n /**\n * Removes all children from this entity\n */ removeAllChildren() {\n // Avoid modifying the array issue by walking backwards\n for(let i = this.children.length - 1; i >= 0; i--)this.removeChild(this.children[i]);\n return this;\n }\n /**\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\n */ getAncestors() {\n const result = [\n this\n ];\n let current = this.parent;\n while(current){\n result.push(current);\n current = current.parent;\n }\n return result.reverse();\n }\n /**\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\n */ getDescendants() {\n let result = [\n this\n ];\n let queue = [\n this\n ];\n while(queue.length > 0){\n const curr = queue.pop();\n if (curr) {\n queue = queue.concat(curr.children);\n result = result.concat(curr.children);\n }\n }\n return result;\n }\n /**\n * Creates a deep copy of the entity and a copy of all its components\n */ clone() {\n const newEntity = new Entity();\n for (const c of this.types){\n const componentInstance = this.get(c);\n if (componentInstance) newEntity.addComponent(componentInstance.clone());\n }\n for (const child of this.children)newEntity.addChild(child.clone());\n return newEntity;\n }\n /**\n * Adds a copy of all the components from another template entity as a \"prefab\"\n * @param templateEntity Entity to use as a template\n * @param force Force component replacement if it already exists on the target entity\n */ addTemplate(templateEntity, force = false) {\n for (const c of templateEntity.getComponents())this.addComponent(c.clone(), force);\n for (const child of templateEntity.children)this.addChild(child.clone().addTemplate(child));\n return this;\n }\n /**\n * Adds a component to the entity\n * @param component Component or Entity to add copy of components from\n * @param force Optionally overwrite any existing components of the same type\n */ addComponent(component, force = false) {\n this._instanceOfComponentCacheDirty = true;\n // if component already exists, skip if not forced\n if (this.has(component.constructor)) {\n if (force) // Remove existing component type if exists when forced\n this.removeComponent(component.constructor, true);\n else // early exit component exits\n return this;\n }\n // TODO circular dependencies will be a problem\n if (component.dependencies && component.dependencies.length) for (const ctor of component.dependencies)this.addComponent(new ctor());\n component.owner = this;\n this.components.set(component.constructor, component);\n if (component.onAdd) component.onAdd(this);\n this.componentAdded$.notifyAll(component);\n return this;\n }\n /**\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\n *\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\n * @param typeOrInstance\n * @param force\n */ removeComponent(typeOrInstance, force = false) {\n let type;\n if (isComponentCtor(typeOrInstance)) type = typeOrInstance;\n else type = typeOrInstance.constructor;\n if (force) {\n const componentToRemove = this.components.get(type);\n if (componentToRemove) {\n this.componentRemoved$.notifyAll(componentToRemove);\n componentToRemove.owner = undefined;\n if (componentToRemove.onRemove) componentToRemove.onRemove(this);\n }\n this.components.delete(type); // remove after the notify to preserve typing\n this._instanceOfComponentCacheDirty = true;\n } else this._componentsToRemove.push(type);\n return this;\n }\n clearComponents() {\n const components = this.types;\n for (const c of components)this.removeComponent(c);\n }\n /**\n * @hidden\n * @internal\n */ processComponentRemoval() {\n for (const type of this._componentsToRemove)this.removeComponent(type, true);\n this._componentsToRemove.length = 0;\n }\n /**\n * Check if a component type exists\n * @param type\n */ has(type) {\n return this.components.has(type);\n }\n /**\n * Gets whether the actor is Initialized\n */ get isInitialized() {\n return this._isInitialized;\n }\n /**\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\n *\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n * @internal\n */ _initialize(engine) {\n if (!this.isInitialized) {\n this.onInitialize(engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * `onInitialize` is called before the first update of the entity. This method is meant to be\n * overridden.\n *\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\n */ onInitialize(engine) {\n // Override me\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before an entity is updated.\n */ onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after an entity is updated.\n */ onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n *\n * Entity update lifecycle, called internally\n * @internal\n * @param engine\n * @param delta\n */ update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n for (const child of this.children)child.update(engine, delta);\n this._postupdate(engine, delta);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n if (handler) this.events.off(eventName, handler);\n else this.events.off(eventName);\n }\n }\n Entity._ID = 0;\n /**\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\n * @param graphic\n */ function hasGraphicsTick(graphic) {\n return !!graphic.tick;\n }\n /**\n * Component to manage drawings, using with the position component\n */ class GraphicsComponent extends Component {\n /**\n * Offset to apply to graphics by default\n */ get offset() {\n return new WatchVector(this._offset, ()=>{\n this.recalculateBounds();\n });\n }\n set offset(value) {\n this._offset = value;\n this.recalculateBounds();\n }\n /**\n * Anchor to apply to graphics by default\n */ get anchor() {\n return new WatchVector(this._anchor, ()=>{\n this.recalculateBounds();\n });\n }\n set anchor(value) {\n this._anchor = value;\n this.recalculateBounds();\n }\n constructor(options){\n super();\n this._logger = Logger.getInstance();\n this._current = \"default\";\n this._graphics = {};\n this._options = {};\n this.material = null;\n /**\n * Sets or gets wether any drawing should be visible in this component\n */ this.visible = true;\n /**\n * Sets or gets wither all drawings should have an opacity applied\n */ this.opacity = 1;\n this._offset = Vector.Zero;\n this._anchor = Vector.Half;\n /**\n * Flip all graphics horizontally along the y-axis\n */ this.flipHorizontal = false;\n /**\n * Flip all graphics vertically along the x-axis\n */ this.flipVertical = false;\n /**\n * If set to true graphics added to the component will be copied. This can effect performance, but is useful if you don't want\n * changes to a graphic to effect all the places it is used.\n */ this.copyGraphics = false;\n this._localBounds = null;\n // Defaults\n options = {\n visible: this.visible,\n graphics: {},\n ...options\n };\n const { current: current, anchor: anchor, opacity: opacity, visible: visible, graphics: graphics, offset: offset, copyGraphics: copyGraphics, onPreDraw: onPreDraw, onPostDraw: onPostDraw, onPreTransformDraw: onPreTransformDraw, onPostTransformDraw: onPostTransformDraw } = options;\n for (const [key, graphicOrOptions] of Object.entries(graphics))if (graphicOrOptions instanceof Graphic) this._graphics[key] = graphicOrOptions;\n else {\n this._graphics[key] = graphicOrOptions.graphic;\n this._options[key] = graphicOrOptions.options;\n }\n this.offset = offset !== null && offset !== void 0 ? offset : this.offset;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : this.anchor;\n this.copyGraphics = copyGraphics !== null && copyGraphics !== void 0 ? copyGraphics : this.copyGraphics;\n this.onPreDraw = onPreDraw !== null && onPreDraw !== void 0 ? onPreDraw : this.onPreDraw;\n this.onPostDraw = onPostDraw !== null && onPostDraw !== void 0 ? onPostDraw : this.onPostDraw;\n this.onPreDraw = onPreTransformDraw !== null && onPreTransformDraw !== void 0 ? onPreTransformDraw : this.onPreTransformDraw;\n this.onPostTransformDraw = onPostTransformDraw !== null && onPostTransformDraw !== void 0 ? onPostTransformDraw : this.onPostTransformDraw;\n this.visible = !!visible;\n this._current = current !== null && current !== void 0 ? current : this._current;\n if (current && this._graphics[current]) this.use(current);\n }\n getGraphic(name) {\n return this._graphics[name];\n }\n getOptions(name) {\n return this._options[name];\n }\n /**\n * Get registered graphics names\n */ getNames() {\n return Object.keys(this._graphics);\n }\n /**\n * Returns the currently displayed graphic\n */ get current() {\n return this._graphics[this._current];\n }\n /**\n * Returns the currently displayed graphic offsets\n */ get currentOptions() {\n return this._options[this._current];\n }\n /**\n * Returns all graphics associated with this component\n */ get graphics() {\n return this._graphics;\n }\n /**\n * Returns all graphics options associated with this component\n */ get options() {\n return this._options;\n }\n add(nameOrGraphic, graphicOrOptions, options) {\n let name = \"default\";\n let graphicToSet = null;\n let optionsToSet = undefined;\n if (typeof nameOrGraphic === \"string\" && graphicOrOptions instanceof Graphic) {\n name = nameOrGraphic;\n graphicToSet = graphicOrOptions;\n optionsToSet = options;\n }\n if (nameOrGraphic instanceof Graphic && !(graphicOrOptions instanceof Graphic)) {\n graphicToSet = nameOrGraphic;\n optionsToSet = graphicOrOptions;\n }\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\n this._options[name] = this.copyGraphics ? {\n ...optionsToSet\n } : optionsToSet;\n if (name === \"default\") this.use(\"default\");\n return graphicToSet;\n }\n /**\n * Removes a registered graphic, if the removed graphic is the current it will switch to the default\n * @param name\n */ remove(name) {\n delete this._graphics[name];\n delete this._options[name];\n if (this._current === name) {\n this._current = \"default\";\n this.recalculateBounds();\n }\n }\n /**\n * Shows a graphic, will be removed\n * @param nameOrGraphic\n * @param options\n * @deprecated will be removed in v0.30.0, use `graphics.use(...)`\n */ show(nameOrGraphic, options) {\n return this.use(nameOrGraphic, options);\n }\n /**\n * Use a graphic only, will set the default graphic. Returns the new [[Graphic]]\n *\n * Optionally override the stored options\n * @param nameOrGraphic\n * @param options\n */ use(nameOrGraphic, options) {\n var _a;\n if (nameOrGraphic instanceof Graphic) {\n let graphic = nameOrGraphic;\n if (this.copyGraphics) graphic = nameOrGraphic.clone();\n this._current = \"default\";\n this._graphics[this._current] = graphic;\n this._options[this._current] = options;\n } else {\n this._current = nameOrGraphic;\n this._options[this._current] = options;\n if (!(this._current in this._graphics)) this._logger.warn(`Graphic ${this._current} is not registered with the graphics component owned by ${(_a = this.owner) === null || _a === void 0 ? void 0 : _a.name}. Nothing will be drawn.`);\n }\n this.recalculateBounds();\n return this.current;\n }\n /**\n * Hide currently shown graphic\n */ hide() {\n this._current = \"ex.none\";\n }\n set localBounds(bounds) {\n this._localBounds = bounds;\n }\n recalculateBounds() {\n let bb = new BoundingBox();\n const graphic = this._graphics[this._current];\n const options = this._options[this._current];\n if (!graphic) {\n this._localBounds = bb;\n return;\n }\n let anchor = this.anchor;\n let offset = this.offset;\n if (options === null || options === void 0 ? void 0 : options.anchor) anchor = options.anchor;\n if (options === null || options === void 0 ? void 0 : options.offset) offset = options.offset;\n const bounds = graphic.localBounds;\n const offsetX = -bounds.width * anchor.x + offset.x;\n const offsetY = -bounds.height * anchor.y + offset.y;\n bb = graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(vec(offsetX, offsetY)).combine(bb);\n this._localBounds = bb;\n }\n get localBounds() {\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) this.recalculateBounds();\n return this._localBounds;\n }\n /**\n * Update underlying graphics if necessary, called internally\n * @param elapsed\n * @internal\n */ update(elapsed, idempotencyToken = 0) {\n const graphic = this.current;\n if (graphic && hasGraphicsTick(graphic)) graphic.tick(elapsed, idempotencyToken);\n }\n clone() {\n const graphics = new GraphicsComponent();\n graphics._graphics = {\n ...this._graphics\n };\n graphics._options = {\n ...this._options\n };\n graphics.offset = this.offset.clone();\n graphics.opacity = this.opacity;\n graphics.anchor = this.anchor.clone();\n graphics.copyGraphics = this.copyGraphics;\n graphics.onPreDraw = this.onPreDraw;\n graphics.onPostDraw = this.onPostDraw;\n graphics.visible = this.visible;\n return graphics;\n }\n }\n /**\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\n */ class Rectangle extends Raster {\n constructor(options){\n super(options);\n this.width = options.width;\n this.height = options.height;\n this.rasterize();\n }\n clone() {\n return new Rectangle({\n width: this.width,\n height: this.height,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.color) ctx.fillRect(0, 0, this.width, this.height);\n if (this.strokeColor) ctx.strokeRect(0, 0, this.width, this.height);\n }\n }\n /**\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\n *\n * Circles default to [[ImageFiltering.Blended]]\n */ class Circle extends Raster {\n get radius() {\n return this._radius;\n }\n set radius(value) {\n this._radius = value;\n this.width = this._radius * 2;\n this.height = this._radius * 2;\n this.flagDirty();\n }\n constructor(options){\n var _a, _b, _c;\n super(options);\n this._radius = 0;\n const lineWidth = (_a = options.lineWidth) !== null && _a !== void 0 ? _a : options.strokeColor ? 1 : 0; // default lineWidth in canvas is 1px\n this.padding = (_b = options.padding) !== null && _b !== void 0 ? _b : 2 + lineWidth / 2; // default 2 padding for circles looks nice\n this.radius = options.radius;\n this.filtering = (_c = options.filtering) !== null && _c !== void 0 ? _c : ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Circle({\n radius: this.radius,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.radius > 0) {\n ctx.beginPath();\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\n if (this.color) ctx.fill();\n if (this.strokeColor) ctx.stroke();\n }\n }\n }\n /**\n * Add this component to optionally configure how the pointer\n * system detects pointer events.\n *\n * By default the collider shape is used and graphics bounds is not.\n *\n * If both collider shape and graphics bounds are enabled it will fire events if either or\n * are intersecting the pointer.\n */ class PointerComponent extends Component {\n constructor(){\n super(...arguments);\n /**\n * Use any existing Collider component geometry for pointer events. This is useful if you want\n * user pointer events only to trigger on the same collision geometry used in the collider component\n * for collision resolution. Default is `true`.\n */ this.useColliderShape = true;\n /**\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\n * bounds around the graphic to trigger pointer events. Default is `true`.\n */ this.useGraphicsBounds = true;\n }\n }\n /**\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\n * Given a time, the function will return a value from positive startValue to positive endValue.\n *\n * ```js\n * function Linear (t) {\n * return t * t;\n * }\n *\n * // accelerating from zero velocity\n * function EaseInQuad (t) {\n * return t * t;\n * }\n *\n * // decelerating to zero velocity\n * function EaseOutQuad (t) {\n * return t * (2 - t);\n * }\n *\n * // acceleration until halfway, then deceleration\n * function EaseInOutQuad (t) {\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n * }\n *\n * // accelerating from zero velocity\n * function EaseInCubic (t) {\n * return t * t * t;\n * }\n *\n * // decelerating to zero velocity\n * function EaseOutCubic (t) {\n * return (--t) * t * t + 1;\n * }\n *\n * // acceleration until halfway, then deceleration\n * function EaseInOutCubic (t) {\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n * }\n * ```\n */ class EasingFunctions {\n static CreateReversibleEasingFunction(easing) {\n return (time, start, end, duration)=>{\n if (end < start) return start - (easing(time, end, start, duration) - end);\n else return easing(time, start, end, duration);\n };\n }\n static CreateVectorEasingFunction(easing) {\n return (time, start, end, duration)=>{\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\n };\n }\n }\n EasingFunctions.Linear = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n return endValue * currentTime / duration + startValue;\n });\n EasingFunctions.EaseInQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime + startValue;\n });\n EasingFunctions.EaseOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return -endValue * currentTime * (currentTime - 2) + startValue;\n });\n EasingFunctions.EaseInOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) return endValue / 2 * currentTime * currentTime + startValue;\n currentTime--;\n return -endValue / 2 * (currentTime * (currentTime - 2) - 1) + startValue;\n });\n EasingFunctions.EaseInCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime * currentTime + startValue;\n });\n EasingFunctions.EaseOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n currentTime--;\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\n });\n EasingFunctions.EaseInOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) return endValue / 2 * currentTime * currentTime * currentTime + startValue;\n currentTime -= 2;\n return endValue / 2 * (currentTime * currentTime * currentTime + 2) + startValue;\n });\n /**\n * Action Queues represent an ordered sequence of actions\n *\n * Action queues are part of the [[ActionContext|Action API]] and\n * store the list of actions to be executed for an [[Actor]].\n *\n * Actors implement [[Actor.actions]] which can be manipulated by\n * advanced users to adjust the actions currently being executed in the\n * queue.\n */ class ActionQueue {\n constructor(entity){\n this._actions = [];\n this._currentAction = null;\n this._completedActions = [];\n this._entity = entity;\n }\n /**\n * Add an action to the sequence\n * @param action\n */ add(action) {\n this._actions.push(action);\n }\n /**\n * Remove an action by reference from the sequence\n * @param action\n */ remove(action) {\n const index = this._actions.indexOf(action);\n this._actions.splice(index, 1);\n }\n /**\n * Removes all actions from this sequence\n */ clearActions() {\n this._actions.length = 0;\n this._completedActions.length = 0;\n if (this._currentAction) this._currentAction.stop();\n }\n /**\n *\n * @returns The total list of actions in this sequence complete or not\n */ getActions() {\n return this._actions.concat(this._completedActions);\n }\n /**\n *\n * @returns `true` if there are more actions to process in the sequence\n */ hasNext() {\n return this._actions.length > 0;\n }\n /**\n * @returns `true` if the current sequence of actions is done\n */ isComplete() {\n return this._actions.length === 0;\n }\n /**\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\n */ reset() {\n this._actions = this.getActions();\n const len = this._actions.length;\n for(let i = 0; i < len; i++)this._actions[i].reset();\n this._completedActions = [];\n }\n /**\n * Update the queue which updates actions and handles completing actions\n * @param elapsedMs\n */ update(elapsedMs) {\n if (this._actions.length > 0) {\n if (this._currentAction !== this._actions[0]) {\n this._currentAction = this._actions[0];\n this._entity.emit(\"actionstart\", new ActionStartEvent(this._currentAction, this._entity));\n }\n this._currentAction.update(elapsedMs);\n if (this._currentAction.isComplete(this._entity)) {\n this._entity.emit(\"actioncomplete\", new ActionCompleteEvent(this._currentAction, this._entity));\n const complete = this._actions.shift();\n if (complete) this._completedActions.push(complete);\n }\n }\n }\n }\n class Repeat {\n constructor(entity, repeatBuilder, repeat){\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeat = repeat;\n this._originalRepeat = repeat;\n this._repeatBuilder(this._repeatContext);\n this._repeat--; // current execution is the first repeat\n }\n update(delta) {\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n this._repeat--;\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || this._repeat <= 0 && this._actionQueue.isComplete();\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._repeat = this._originalRepeat;\n }\n }\n /**\n * RepeatForever Action implementation, it is recommended you use the fluent action\n * context API.\n *\n *\n */ class RepeatForever {\n constructor(entity, repeatBuilder){\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeatBuilder(this._repeatContext);\n }\n update(delta) {\n if (this._stopped) return;\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n this._stopped = true;\n this._actionQueue.clearActions();\n }\n reset() {\n return;\n }\n }\n class MoveBy {\n constructor(entity, offsetX, offsetY, speed){\n this._started = false;\n this._stopped = false;\n this._entity = entity;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = new Vector(offsetX, offsetY);\n if (speed <= 0) {\n Logger.getInstance().error(\"Attempted to moveBy with speed less than or equal to zero : \" + speed);\n throw new Error(\"Speed must be greater than 0 pixels per second\");\n }\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = this._start.add(this._offset);\n this._distance = this._offset.size;\n this._dir = this._end.sub(this._start).normalize();\n }\n if (this.isComplete(this._entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n } else this._motion.vel = this._dir.scale(this._speed);\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class MoveTo {\n constructor(entity, destx, desty, speed){\n this.entity = entity;\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = new Vector(destx, desty);\n this._speed = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._distance = this._start.distance(this._end);\n this._dir = this._end.sub(this._start).normalize();\n }\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete(this.entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n /**\n * An enum that describes the strategies that rotation actions can use\n */ var RotationType;\n (function(RotationType) {\n /**\n * Rotation via `ShortestPath` will use the smallest angle\n * between the starting and ending points. This strategy is the default behavior.\n */ RotationType[RotationType[\"ShortestPath\"] = 0] = \"ShortestPath\";\n /**\n * Rotation via `LongestPath` will use the largest angle\n * between the starting and ending points.\n */ RotationType[RotationType[\"LongestPath\"] = 1] = \"LongestPath\";\n /**\n * Rotation via `Clockwise` will travel in a clockwise direction,\n * regardless of the starting and ending points.\n */ RotationType[RotationType[\"Clockwise\"] = 2] = \"Clockwise\";\n /**\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\n * regardless of the starting and ending points.\n */ RotationType[RotationType[\"CounterClockwise\"] = 3] = \"CounterClockwise\";\n })(RotationType || (RotationType = {}));\n class RotateTo {\n constructor(entity, angleRadians, speed, rotationType){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = angleRadians;\n this._speed = speed;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n } else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch(this._rotationType){\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) this._direction = 1;\n else this._direction = -1;\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) this._direction = -1;\n else this._direction = 1;\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortestPathIsPositive) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (!this._shortestPathIsPositive) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class RotateBy {\n constructor(entity, angleRadiansOffset, speed, rotationType){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = angleRadiansOffset;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n this._end = this._start + this._offset;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n } else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch(this._rotationType){\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) this._direction = 1;\n else this._direction = -1;\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) this._direction = -1;\n else this._direction = 1;\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortDistance >= 0) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (this._shortDistance <= 0) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._start = undefined;\n this._currentNonCannonAngle = undefined;\n this._distance = undefined;\n }\n }\n class ScaleTo {\n constructor(entity, scaleX, scaleY, speedX, speedY){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._endX = scaleX;\n this._endY = scaleY;\n this._speedX = speedX;\n this._speedY = speedY;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startX = this._tx.scale.x;\n this._startY = this._tx.scale.y;\n this._distanceX = Math.abs(this._endX - this._startX);\n this._distanceY = Math.abs(this._endY - this._startY);\n }\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\n const directionX = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.x = this._speedX * directionX;\n } else this._motion.scaleFactor.x = 0;\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\n const directionY = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.y = this._speedY * directionY;\n } else this._motion.scaleFactor.y = 0;\n if (this.isComplete()) {\n this._tx.scale = vec(this._endX, this._endY);\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return this._stopped || Math.abs(this._tx.scale.x - this._startX) >= this._distanceX - 0.01 && Math.abs(this._tx.scale.y - this._startY) >= this._distanceY - 0.01;\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class ScaleBy {\n constructor(entity, scaleOffsetX, scaleOffsetY, speed){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\n this._speedX = this._speedY = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startScale = this._tx.scale.clone();\n this._endScale = this._startScale.add(this._offset);\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\n }\n this._motion.scaleFactor.x = this._speedX * this._directionX;\n this._motion.scaleFactor.y = this._speedY * this._directionY;\n if (this.isComplete()) {\n this._tx.scale = this._endScale;\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return this._stopped || Math.abs(this._tx.scale.x - this._startScale.x) >= this._distanceX - 0.01 && Math.abs(this._tx.scale.y - this._startScale.y) >= this._distanceY - 0.01;\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class CallMethod {\n constructor(method){\n this._method = null;\n this._hasBeenCalled = false;\n this._method = method;\n }\n update(_delta) {\n this._method();\n this._hasBeenCalled = true;\n }\n isComplete() {\n return this._hasBeenCalled;\n }\n reset() {\n this._hasBeenCalled = false;\n }\n stop() {\n this._hasBeenCalled = true;\n }\n }\n class EaseTo {\n constructor(entity, x, y, duration, easingFcn){\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._lerpEnd = new Vector(x, y);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) newX = this._lerpStart.x - (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n else newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n if (this._lerpEnd.y < this._lerpStart.y) newY = this._lerpStart.y - (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n else newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n } else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n }\n class EaseBy {\n constructor(entity, offsetX, offsetY, duration, easingFcn){\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._offset = new Vector(offsetX, offsetY);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n this._lerpEnd = this._lerpStart.add(this._offset);\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) newX = this._lerpStart.x - (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n else newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n if (this._lerpEnd.y < this._lerpStart.y) newY = this._lerpStart.y - (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n else newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n } else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n }\n class Blink {\n constructor(entity, timeVisible, timeNotVisible, numBlinks = 1){\n this._timeVisible = 0;\n this._timeNotVisible = 0;\n this._elapsedTime = 0;\n this._totalTime = 0;\n this._stopped = false;\n this._started = false;\n this._graphics = entity.get(GraphicsComponent);\n this._timeVisible = timeVisible;\n this._timeNotVisible = timeNotVisible;\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\n }\n update(delta) {\n if (!this._started) {\n this._started = true;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n if (!this._graphics) return;\n this._elapsedTime += delta;\n this._totalTime += delta;\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\n this._graphics.visible = false;\n this._elapsedTime = 0;\n }\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\n this._graphics.visible = true;\n this._elapsedTime = 0;\n }\n if (this.isComplete()) this._graphics.visible = true;\n }\n isComplete() {\n return this._stopped || this._totalTime >= this._duration;\n }\n stop() {\n if (this._graphics) this._graphics.visible = true;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n }\n class Fade {\n constructor(entity, endOpacity, speed){\n this._multiplier = 1;\n this._started = false;\n this._stopped = false;\n this._graphics = entity.get(GraphicsComponent);\n this._endOpacity = endOpacity;\n this._speed = this._ogspeed = speed;\n }\n update(delta) {\n if (!this._graphics) return;\n if (!this._started) {\n this._started = true;\n this._speed = this._ogspeed;\n // determine direction when we start\n if (this._endOpacity < this._graphics.opacity) this._multiplier = -1;\n else this._multiplier = 1;\n }\n if (this._speed > 0) this._graphics.opacity += this._multiplier * (Math.abs(this._graphics.opacity - this._endOpacity) * delta) / this._speed;\n this._speed -= delta;\n if (this.isComplete()) this._graphics.opacity = this._endOpacity;\n Logger.getInstance().debug(\"[Action fade] Actor opacity:\", this._graphics.opacity);\n }\n isComplete() {\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class Delay {\n constructor(delay){\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n this._delay = delay;\n }\n update(delta) {\n if (!this._started) this._started = true;\n this._elapsedTime += delta;\n }\n isComplete() {\n return this._stopped || this._elapsedTime >= this._delay;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n }\n }\n class Die {\n constructor(entity){\n this._stopped = false;\n this._entity = entity;\n }\n update(_delta) {\n this._entity.get(ActionsComponent).clearActions();\n this._entity.kill();\n this._stopped = true;\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n return;\n }\n reset() {\n return;\n }\n }\n class Follow {\n constructor(entity, entityToFollow, followDistance){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._followTx = entityToFollow.get(TransformComponent);\n this._followMotion = entityToFollow.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\n this._speed = 0;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\n if (actorToFollowSpeed !== 0) this._speed = actorToFollowSpeed;\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n if (this._distanceBetween >= this._maximumDistance) {\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n } else this._motion.vel = vec(0, 0);\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n isComplete() {\n // the actor following should never stop unless specified to do so\n return this._stopped;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class Meet {\n constructor(actor, actorToMeet, speed){\n this._started = false;\n this._stopped = false;\n this._speedWasSpecified = false;\n this._tx = actor.get(TransformComponent);\n this._motion = actor.get(MotionComponent);\n this._meetTx = actorToMeet.get(TransformComponent);\n this._meetMotion = actorToMeet.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\n this._speed = speed || 0;\n if (speed !== undefined) this._speedWasSpecified = true;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) this._speed = actorToMeetSpeed;\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete() {\n return this._stopped || this._distanceBetween <= 1;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._distanceBetween = undefined;\n }\n }\n /**\n * The fluent Action API allows you to perform \"actions\" on\n * [[Actor|Actors]] such as following, moving, rotating, and\n * more. You can implement your own actions by implementing\n * the [[Action]] interface.\n */ class ActionContext {\n constructor(entity){\n this._entity = entity;\n this._queue = new ActionQueue(entity);\n }\n getQueue() {\n return this._queue;\n }\n update(elapsedMs) {\n this._queue.update(elapsedMs);\n }\n /**\n * Clears all queued actions from the Actor\n */ clearActions() {\n this._queue.clearActions();\n }\n runAction(action) {\n action.reset();\n this._queue.add(action);\n return this;\n }\n easeTo(...args) {\n var _a, _b;\n let x = 0;\n let y = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n x = args[0].x;\n y = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n } else {\n x = args[0];\n y = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\n return this;\n }\n easeBy(...args) {\n var _a, _b;\n let offsetX = 0;\n let offsetY = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n offsetX = args[0].x;\n offsetY = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n } else {\n offsetX = args[0];\n offsetY = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\n return this;\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n let x = 0;\n let y = 0;\n let speed = 0;\n if (xOrPos instanceof Vector) {\n x = xOrPos.x;\n y = xOrPos.y;\n speed = yOrSpeed;\n } else {\n x = xOrPos;\n y = yOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveTo(this._entity, x, y, speed));\n return this;\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n let xOffset = 0;\n let yOffset = 0;\n let speed = 0;\n if (xOffsetOrVector instanceof Vector) {\n xOffset = xOffsetOrVector.x;\n yOffset = xOffsetOrVector.y;\n speed = yOffsetOrSpeed;\n } else {\n xOffset = xOffsetOrVector;\n yOffset = yOffsetOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\n return this;\n }\n /**\n * This method will rotate an actor to the specified angle at the speed\n * specified (in radians per second) and return back the actor. This\n * method is part of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadians The angle to rotate to in radians\n * @param speed The angular velocity of the rotation specified in radians per second\n * @param rotationType The [[RotationType]] to use for this rotation\n */ rotateTo(angleRadians, speed, rotationType) {\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\n return this;\n }\n /**\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\n * in radians/sec and return back the actor. This method is part\n * of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\n * @param speed The speed in radians/sec the actor should rotate at\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\n */ rotateBy(angleRadiansOffset, speed, rotationType) {\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\n return this;\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n let sizeX = 1;\n let sizeY = 1;\n let speedX = 0;\n let speedY = 0;\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\n sizeX = sizeXOrVector.x;\n sizeY = sizeXOrVector.y;\n speedX = sizeYOrSpeed.x;\n speedY = sizeYOrSpeed.y;\n }\n if (typeof sizeXOrVector === \"number\" && typeof sizeYOrSpeed === \"number\") {\n sizeX = sizeXOrVector;\n sizeY = sizeYOrSpeed;\n speedX = speedXOrUndefined;\n speedY = speedYOrUndefined;\n }\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\n return this;\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n let sizeOffsetX = 1;\n let sizeOffsetY = 1;\n if (sizeOffsetXOrVector instanceof Vector) {\n sizeOffsetX = sizeOffsetXOrVector.x;\n sizeOffsetY = sizeOffsetXOrVector.y;\n speed = sizeOffsetYOrSpeed;\n }\n if (typeof sizeOffsetXOrVector === \"number\" && typeof sizeOffsetYOrSpeed === \"number\") {\n sizeOffsetX = sizeOffsetXOrVector;\n sizeOffsetY = sizeOffsetYOrSpeed;\n }\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\n return this;\n }\n /**\n * This method will cause an actor to blink (become visible and not\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\n * the actor should be visible per blink, and the amount of time not visible.\n * This method is part of the actor 'Action' fluent API allowing action chaining.\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\n * @param numBlinks The number of times to blink\n */ blink(timeVisible, timeNotVisible, numBlinks = 1) {\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\n return this;\n }\n /**\n * This method will cause an actor's opacity to change from its current value\n * to the provided value by a specified time (in milliseconds). This method is\n * part of the actor 'Action' fluent API allowing action chaining.\n * @param opacity The ending opacity\n * @param time The time it should take to fade the actor (in milliseconds)\n */ fade(opacity, time) {\n this._queue.add(new Fade(this._entity, opacity, time));\n return this;\n }\n /**\n * This method will delay the next action from executing for a certain\n * amount of time (in milliseconds). This method is part of the actor\n * 'Action' fluent API allowing action chaining.\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\n */ delay(time) {\n this._queue.add(new Delay(time));\n return this;\n }\n /**\n * This method will add an action to the queue that will remove the actor from the\n * scene once it has completed its previous Any actions on the\n * action queue after this action will not be executed.\n */ die() {\n this._queue.add(new Die(this._entity));\n return this;\n }\n /**\n * This method allows you to call an arbitrary method as the next action in the\n * action queue. This is useful if you want to execute code in after a specific\n * action, i.e An actor arrives at a destination after traversing a path\n */ callMethod(method) {\n this._queue.add(new CallMethod(method));\n return this;\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\n * will repeat forever\n */ repeat(repeatBuilder, times) {\n if (!times) {\n this.repeatForever(repeatBuilder);\n return this;\n }\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\n return this;\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n */ repeatForever(repeatBuilder) {\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\n return this;\n }\n /**\n * This method will cause the entity to follow another at a specified distance\n * @param entity The entity to follow\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\n */ follow(entity, followDistance) {\n if (followDistance === undefined) this._queue.add(new Follow(this._entity, entity));\n else this._queue.add(new Follow(this._entity, entity, followDistance));\n return this;\n }\n /**\n * This method will cause the entity to move towards another until they\n * collide \"meet\" at a specified speed.\n * @param entity The entity to meet\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\n */ meet(entity, speed) {\n if (speed === undefined) this._queue.add(new Meet(this._entity, entity));\n else this._queue.add(new Meet(this._entity, entity, speed));\n return this;\n }\n /**\n * Returns a promise that resolves when the current action queue up to now\n * is finished.\n */ toPromise() {\n const temp = new Promise((resolve)=>{\n this._queue.add(new CallMethod(()=>{\n resolve();\n }));\n });\n return temp;\n }\n }\n class ActionsComponent extends Component {\n constructor(){\n super(...arguments);\n this.dependencies = [\n TransformComponent,\n MotionComponent\n ];\n this._ctx = null;\n }\n onAdd(entity) {\n this._ctx = new ActionContext(entity);\n }\n onRemove() {\n this._ctx = null;\n }\n _getCtx() {\n if (!this._ctx) throw new Error(\"Actions component not attached to an entity, no context available\");\n return this._ctx;\n }\n /**\n * Returns the internal action queue\n * @returns action queue\n */ getQueue() {\n if (!this._ctx) throw new Error(\"Actions component not attached to an entity, no queue available\");\n return this._ctx.getQueue();\n }\n runAction(action) {\n if (!this._ctx) throw new Error(\"Actions component not attached to an entity, cannot run action\");\n return this._ctx.runAction(action);\n }\n /**\n * Updates the internal action context, performing action and moving through the internal queue\n * @param elapsedMs\n */ update(elapsedMs) {\n var _a;\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.update(elapsedMs);\n }\n /**\n * Clears all queued actions from the Actor\n */ clearActions() {\n var _a;\n (_a = this._ctx) === null || _a === void 0 || _a.clearActions();\n }\n easeTo(...args) {\n return this._getCtx().easeTo.apply(this._ctx, args);\n }\n easeBy(...args) {\n return this._getCtx().easeBy.apply(this._ctx, args);\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n return this._getCtx().moveTo.apply(this._ctx, [\n xOrPos,\n yOrSpeed,\n speedOrUndefined\n ]);\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n return this._getCtx().moveBy.apply(this._ctx, [\n xOffsetOrVector,\n yOffsetOrSpeed,\n speedOrUndefined\n ]);\n }\n /**\n * This method will rotate an actor to the specified angle at the speed\n * specified (in radians per second) and return back the actor. This\n * method is part of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadians The angle to rotate to in radians\n * @param speed The angular velocity of the rotation specified in radians per second\n * @param rotationType The [[RotationType]] to use for this rotation\n */ rotateTo(angleRadians, speed, rotationType) {\n return this._getCtx().rotateTo(angleRadians, speed, rotationType);\n }\n /**\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\n * in radians/sec and return back the actor. This method is part\n * of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\n * @param speed The speed in radians/sec the actor should rotate at\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\n */ rotateBy(angleRadiansOffset, speed, rotationType) {\n return this._getCtx().rotateBy(angleRadiansOffset, speed, rotationType);\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n return this._getCtx().scaleTo.apply(this._ctx, [\n sizeXOrVector,\n sizeYOrSpeed,\n speedXOrUndefined,\n speedYOrUndefined\n ]);\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n return this._getCtx().scaleBy.apply(this._ctx, [\n sizeOffsetXOrVector,\n sizeOffsetYOrSpeed,\n speed\n ]);\n }\n /**\n * This method will cause an actor to blink (become visible and not\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\n * the actor should be visible per blink, and the amount of time not visible.\n * This method is part of the actor 'Action' fluent API allowing action chaining.\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\n * @param numBlinks The number of times to blink\n */ blink(timeVisible, timeNotVisible, numBlinks) {\n return this._getCtx().blink(timeVisible, timeNotVisible, numBlinks);\n }\n /**\n * This method will cause an actor's opacity to change from its current value\n * to the provided value by a specified time (in milliseconds). This method is\n * part of the actor 'Action' fluent API allowing action chaining.\n * @param opacity The ending opacity\n * @param time The time it should take to fade the actor (in milliseconds)\n */ fade(opacity, time) {\n return this._getCtx().fade(opacity, time);\n }\n /**\n * This method will delay the next action from executing for a certain\n * amount of time (in milliseconds). This method is part of the actor\n * 'Action' fluent API allowing action chaining.\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\n */ delay(time) {\n return this._getCtx().delay(time);\n }\n /**\n * This method will add an action to the queue that will remove the actor from the\n * scene once it has completed its previous Any actions on the\n * action queue after this action will not be executed.\n */ die() {\n return this._getCtx().die();\n }\n /**\n * This method allows you to call an arbitrary method as the next action in the\n * action queue. This is useful if you want to execute code in after a specific\n * action, i.e An actor arrives at a destination after traversing a path\n */ callMethod(method) {\n return this._getCtx().callMethod(method);\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\n * will repeat forever\n */ repeat(repeatBuilder, times) {\n return this._getCtx().repeat(repeatBuilder, times);\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n */ repeatForever(repeatBuilder) {\n return this._getCtx().repeatForever(repeatBuilder);\n }\n /**\n * This method will cause the entity to follow another at a specified distance\n * @param entity The entity to follow\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\n */ follow(entity, followDistance) {\n return this._getCtx().follow(entity, followDistance);\n }\n /**\n * This method will cause the entity to move towards another until they\n * collide \"meet\" at a specified speed.\n * @param entity The entity to meet\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\n */ meet(entity, speed) {\n return this._getCtx().meet(entity, speed);\n }\n /**\n * Returns a promise that resolves when the current action queue up to now\n * is finished.\n */ toPromise() {\n return this._getCtx().toPromise();\n }\n }\n /**\n * Enum representing the different font size units\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\n */ var FontUnit;\n (function(FontUnit) {\n /**\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\n */ FontUnit[\"Em\"] = \"em\";\n /**\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\n */ FontUnit[\"Rem\"] = \"rem\";\n /**\n * Pixel is a unit of length in screen pixels\n */ FontUnit[\"Px\"] = \"px\";\n /**\n * Point is a physical unit length (1/72 of an inch)\n */ FontUnit[\"Pt\"] = \"pt\";\n /**\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\n */ FontUnit[\"Percent\"] = \"%\";\n })(FontUnit || (FontUnit = {}));\n /**\n * Enum representing the different horizontal text alignments\n */ var TextAlign;\n (function(TextAlign) {\n /**\n * The text is left-aligned.\n */ TextAlign[\"Left\"] = \"left\";\n /**\n * The text is right-aligned.\n */ TextAlign[\"Right\"] = \"right\";\n /**\n * The text is centered.\n */ TextAlign[\"Center\"] = \"center\";\n /**\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\n * right-aligned for right-to-left locales).\n */ TextAlign[\"Start\"] = \"start\";\n /**\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\n * left-aligned for right-to-left locales).\n */ TextAlign[\"End\"] = \"end\";\n })(TextAlign || (TextAlign = {}));\n /**\n * Enum representing the different baseline text alignments\n */ var BaseAlign;\n (function(BaseAlign) {\n /**\n * The text baseline is the top of the em square.\n */ BaseAlign[\"Top\"] = \"top\";\n /**\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\n * alphabetic.\n */ BaseAlign[\"Hanging\"] = \"hanging\";\n /**\n * The text baseline is the middle of the em square.\n */ BaseAlign[\"Middle\"] = \"middle\";\n /**\n * The text baseline is the normal alphabetic baseline.\n */ BaseAlign[\"Alphabetic\"] = \"alphabetic\";\n /**\n * The text baseline is the ideographic baseline; this is the bottom of\n * the body of the characters, if the main body of characters protrudes\n * beneath the alphabetic baseline. Currently unsupported; this will\n * act like alphabetic.\n */ BaseAlign[\"Ideographic\"] = \"ideographic\";\n /**\n * The text baseline is the bottom of the bounding box. This differs\n * from the ideographic baseline in that the ideographic baseline\n * doesn't consider descenders.\n */ BaseAlign[\"Bottom\"] = \"bottom\";\n })(BaseAlign || (BaseAlign = {}));\n /**\n * Enum representing the different possible font styles\n */ var FontStyle;\n (function(FontStyle) {\n FontStyle[\"Normal\"] = \"normal\";\n FontStyle[\"Italic\"] = \"italic\";\n FontStyle[\"Oblique\"] = \"oblique\";\n })(FontStyle || (FontStyle = {}));\n /**\n * Enum representing the text direction, useful for other languages, or writing text in reverse\n */ var Direction;\n (function(Direction) {\n Direction[\"LeftToRight\"] = \"ltr\";\n Direction[\"RightToLeft\"] = \"rtl\";\n })(Direction || (Direction = {}));\n class FontTextInstance {\n constructor(font, text, color, maxWidth){\n this.font = font;\n this.text = text;\n this.color = color;\n this.maxWidth = maxWidth;\n this._textFragments = [];\n this.disposed = false;\n this._dirty = true;\n this.canvas = document.createElement(\"canvas\");\n this.ctx = this.canvas.getContext(\"2d\");\n this.dimensions = this.measureText(text);\n this._setDimension(this.dimensions, this.ctx);\n this._lastHashCode = this.getHashCode();\n }\n measureText(text, maxWidth) {\n if (this.disposed) throw Error(\"Accessing disposed text instance! \" + this.text);\n let lines = null;\n if (maxWidth != null) lines = this._getLinesFromText(text, maxWidth);\n else lines = text.split(\"\\n\");\n const maxWidthLine = lines.reduce((a, b)=>{\n return a.length > b.length ? a : b;\n });\n this._applyFont(this.ctx); // font must be applied to the context to measure it\n const metrics = this.ctx.measureText(maxWidthLine);\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\n // TODO lineheight makes the text bounds wonky\n const lineAdjustedHeight = textHeight * lines.length;\n textHeight = lineAdjustedHeight;\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\n const x = 0;\n const y = 0;\n const measurement = new BoundingBox({\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\n bottom: y + bottomBounds + this.font.padding,\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\n });\n return measurement;\n }\n _setDimension(textBounds, bitmap) {\n let lineHeightRatio = 1;\n if (this.font.lineHeight) lineHeightRatio = this.font.lineHeight / this.font.size;\n // Changing the width and height clears the context properties\n // We double the bitmap width to account for all possible alignment\n // We scale by \"quality\" so we render text without jaggies\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality * lineHeightRatio;\n }\n static getHashCode(font, text, color) {\n var _a;\n const hash = text + \"__hashcode__\" + font.fontString + font.showDebug + font.textAlign + font.baseAlign + font.direction + font.lineHeight + JSON.stringify(font.shadow) + (font.padding.toString() + font.smoothing.toString() + font.lineWidth.toString() + font.lineDash.toString() + ((_a = font.strokeColor) === null || _a === void 0 ? void 0 : _a.toString()) + (color ? color.toString() : font.color.toString()));\n return hash;\n }\n getHashCode(includeColor = true) {\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\n }\n _applyRasterProperties(ctx) {\n var _a, _b;\n ctx.translate(this.font.padding, this.font.padding);\n ctx.imageSmoothingEnabled = this.font.smoothing;\n ctx.lineWidth = this.font.lineWidth;\n ctx.setLineDash((_a = this.font.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.strokeStyle = (_b = this.font.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = this.color.toString();\n }\n _applyFont(ctx) {\n ctx.resetTransform();\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\n ctx.scale(this.font.quality, this.font.quality);\n ctx.textAlign = this.font.textAlign;\n ctx.textBaseline = this.font.baseAlign;\n ctx.font = this.font.fontString;\n ctx.direction = this.font.direction;\n if (this.font.shadow) {\n ctx.shadowColor = this.font.shadow.color.toString();\n ctx.shadowBlur = this.font.shadow.blur;\n ctx.shadowOffsetX = this.font.shadow.offset.x;\n ctx.shadowOffsetY = this.font.shadow.offset.y;\n }\n }\n _drawText(ctx, lines, lineHeight) {\n this._applyRasterProperties(ctx);\n this._applyFont(ctx);\n for(let i = 0; i < lines.length; i++){\n const line = lines[i];\n if (this.color) ctx.fillText(line, 0, i * lineHeight);\n if (this.font.strokeColor) ctx.strokeText(line, 0, i * lineHeight);\n }\n if (this.font.showDebug) {\n // Horizontal line\n /* istanbul ignore next */ line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\n // Vertical line\n /* istanbul ignore next */ line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\n }\n }\n _splitTextBitmap(bitmap) {\n const textImages = [];\n let currentX = 0;\n let currentY = 0;\n // 4k is the max for mobile devices\n const width = Math.min(4096, bitmap.canvas.width);\n const height = Math.min(4096, bitmap.canvas.height);\n // Splits the original bitmap into 4k max chunks\n while(currentX < bitmap.canvas.width){\n while(currentY < bitmap.canvas.height){\n // create new bitmap\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n // draw current slice to new bitmap in < 4k chunks\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\n textImages.push({\n x: currentX,\n y: currentY,\n canvas: canvas\n });\n currentY += height;\n }\n currentX += width;\n currentY = 0;\n }\n return textImages;\n }\n flagDirty() {\n this._dirty = true;\n }\n render(ex, x, y, maxWidth) {\n var _a;\n if (this.disposed) throw Error(\"Accessing disposed text instance! \" + this.text);\n this._ex = ex;\n const hashCode = this.getHashCode();\n if (this._lastHashCode !== hashCode) this._dirty = true;\n // Calculate image chunks\n if (this._dirty) {\n this.dimensions = this.measureText(this.text, maxWidth);\n this._setDimension(this.dimensions, this.ctx);\n const lines = this._getLinesFromText(this.text, maxWidth);\n const lineHeight = (_a = this.font.lineHeight) !== null && _a !== void 0 ? _a : this.dimensions.height / lines.length;\n // draws the text to the main bitmap\n this._drawText(this.ctx, lines, lineHeight);\n // clear any out old fragments\n if (ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)ex.textureLoader.delete(frag.canvas);\n // splits to < 4k fragments for large text\n this._textFragments = this._splitTextBitmap(this.ctx);\n if (ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)ex.textureLoader.load(frag.canvas, this.font.filtering, true);\n this._lastHashCode = hashCode;\n this._dirty = false;\n }\n // draws the bitmap fragments to excalibur graphics context\n for (const frag of this._textFragments)ex.drawImage(frag.canvas, 0, 0, frag.canvas.width, frag.canvas.height, frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2, frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2, frag.canvas.width / this.font.quality, frag.canvas.height / this.font.quality);\n }\n dispose() {\n this.disposed = true;\n this.dimensions = undefined;\n this.canvas = undefined;\n this.ctx = undefined;\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)this._ex.textureLoader.delete(frag.canvas);\n this._textFragments.length = 0;\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) return this._cachedLines;\n const lines = text.split(\"\\n\");\n if (maxWidth == null) return lines;\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for(let i = 0; i < lines.length; i++){\n let line = lines[i];\n let newLine = \"\";\n if (this.measureText(line).width > maxWidth) {\n while(this.measureText(line).width > maxWidth){\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n }\n class FontCache {\n static measureText(text, font, maxWidth) {\n const hash = FontTextInstance.getHashCode(font, text);\n if (FontCache._MEASURE_CACHE.has(hash)) return FontCache._MEASURE_CACHE.get(hash);\n FontCache._LOGGER.debug(\"Font text measurement cache miss\");\n const measurement = font.measureTextWithoutCache(text, maxWidth);\n FontCache._MEASURE_CACHE.set(hash, measurement);\n return measurement;\n }\n static getTextInstance(text, font, color) {\n const hash = FontTextInstance.getHashCode(font, text, color);\n let textInstance = FontCache._TEXT_CACHE.get(hash);\n if (!textInstance) {\n textInstance = new FontTextInstance(font, text, color);\n FontCache._TEXT_CACHE.set(hash, textInstance);\n FontCache._LOGGER.debug(\"Font text instance cache miss\");\n }\n // Cache the bitmap for certain amount of time\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\n return textInstance;\n }\n static checkAndClearCache() {\n const deferred = [];\n const currentHashCodes = new Set();\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries())// if bitmap hasn't been used in 100 ms clear it\n if (time + FontCache.FONT_TIMEOUT < performance.now()) {\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\n deferred.push(textInstance);\n textInstance.dispose();\n } else {\n const hash = textInstance.getHashCode(false);\n currentHashCodes.add(hash);\n }\n // Deferred removal of text instances\n deferred.forEach((t)=>{\n FontCache._TEXT_USAGE.delete(t);\n });\n // Regenerate text instance cache\n this._TEXT_CACHE.clear();\n for (const [textInstance] of this._TEXT_USAGE.entries())this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\n // Regenerated measurement cache\n const newTextMeasurementCache = new Map();\n for (const current of currentHashCodes)if (FontCache._MEASURE_CACHE.has(current)) newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\n this._MEASURE_CACHE.clear();\n this._MEASURE_CACHE = newTextMeasurementCache;\n }\n static get cacheSize() {\n return FontCache._TEXT_USAGE.size;\n }\n /**\n * Force clear all cached text bitmaps\n */ static clearCache() {\n for (const [textInstance] of FontCache._TEXT_USAGE.entries())textInstance.dispose();\n FontCache._TEXT_USAGE.clear();\n FontCache._TEXT_CACHE.clear();\n FontCache._MEASURE_CACHE.clear();\n }\n }\n FontCache.FONT_TIMEOUT = 500;\n FontCache._LOGGER = Logger.getInstance();\n FontCache._TEXT_USAGE = new Map();\n FontCache._TEXT_CACHE = new Map();\n FontCache._MEASURE_CACHE = new Map();\n /**\n * Represents a system or web font in Excalibur\n *\n * If no options specified, the system sans-serif 10 pixel is used\n *\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\n */ class Font extends Graphic {\n constructor(options = {}){\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;\n super(options); // <- Graphics properties\n /**\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\n *\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\n */ this.filtering = ImageFiltering.Blended;\n /**\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\n *\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\n *\n * (Default 2)\n */ this.quality = 2;\n // Raster properties for fonts\n this.padding = 2;\n this.smoothing = false;\n this.lineWidth = 1;\n this.lineDash = [];\n this.color = Color.Black;\n this.family = \"sans-serif\";\n this.style = FontStyle.Normal;\n this.bold = false;\n this.unit = FontUnit.Px;\n this.textAlign = TextAlign.Left;\n this.baseAlign = BaseAlign.Top;\n this.direction = Direction.LeftToRight;\n /**\n * Font line height in pixels, default line height if unset\n */ this.lineHeight = undefined;\n this.size = 10;\n this.shadow = null;\n this._textBounds = new BoundingBox();\n this._textMeasurement = new FontTextInstance(this, \"\", Color.Black);\n // Raster properties\n this.smoothing = (_a = options === null || options === void 0 ? void 0 : options.smoothing) !== null && _a !== void 0 ? _a : this.smoothing;\n this.padding = (_b = options === null || options === void 0 ? void 0 : options.padding) !== null && _b !== void 0 ? _b : this.padding;\n this.color = (_c = options === null || options === void 0 ? void 0 : options.color) !== null && _c !== void 0 ? _c : this.color;\n this.strokeColor = (_d = options === null || options === void 0 ? void 0 : options.strokeColor) !== null && _d !== void 0 ? _d : this.strokeColor;\n this.lineDash = (_e = options === null || options === void 0 ? void 0 : options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineWidth = (_f = options === null || options === void 0 ? void 0 : options.lineWidth) !== null && _f !== void 0 ? _f : this.lineWidth;\n this.filtering = (_g = options === null || options === void 0 ? void 0 : options.filtering) !== null && _g !== void 0 ? _g : this.filtering;\n // Font specific properties\n this.family = (_h = options === null || options === void 0 ? void 0 : options.family) !== null && _h !== void 0 ? _h : this.family;\n this.style = (_j = options === null || options === void 0 ? void 0 : options.style) !== null && _j !== void 0 ? _j : this.style;\n this.bold = (_k = options === null || options === void 0 ? void 0 : options.bold) !== null && _k !== void 0 ? _k : this.bold;\n this.size = (_l = options === null || options === void 0 ? void 0 : options.size) !== null && _l !== void 0 ? _l : this.size;\n this.unit = (_m = options === null || options === void 0 ? void 0 : options.unit) !== null && _m !== void 0 ? _m : this.unit;\n this.textAlign = (_o = options === null || options === void 0 ? void 0 : options.textAlign) !== null && _o !== void 0 ? _o : this.textAlign;\n this.baseAlign = (_p = options === null || options === void 0 ? void 0 : options.baseAlign) !== null && _p !== void 0 ? _p : this.baseAlign;\n this.direction = (_q = options === null || options === void 0 ? void 0 : options.direction) !== null && _q !== void 0 ? _q : this.direction;\n this.lineHeight = (_r = options === null || options === void 0 ? void 0 : options.lineHeight) !== null && _r !== void 0 ? _r : this.lineHeight;\n this.quality = (_s = options === null || options === void 0 ? void 0 : options.quality) !== null && _s !== void 0 ? _s : this.quality;\n if (options === null || options === void 0 ? void 0 : options.shadow) {\n this.shadow = {};\n this.shadow.blur = (_t = options.shadow.blur) !== null && _t !== void 0 ? _t : this.shadow.blur;\n this.shadow.offset = (_u = options.shadow.offset) !== null && _u !== void 0 ? _u : this.shadow.offset;\n this.shadow.color = (_v = options.shadow.color) !== null && _v !== void 0 ? _v : this.shadow.color;\n }\n }\n clone() {\n return new Font({\n ...this.cloneGraphicOptions(),\n size: this.size,\n unit: this.unit,\n family: this.family,\n style: this.style,\n bold: this.bold,\n textAlign: this.textAlign,\n baseAlign: this.baseAlign,\n direction: this.direction,\n shadow: this.shadow ? {\n blur: this.shadow.blur,\n offset: this.shadow.offset,\n color: this.shadow.color\n } : null\n });\n }\n get fontString() {\n return `${this.style} ${this.bold ? \"bold\" : \"\"} ${this.size}${this.unit} ${this.family}`;\n }\n get localBounds() {\n return this._textBounds;\n }\n _drawImage(_ex, _x, _y) {\n // TODO weird vestigial drawimage\n }\n _rotate(ex) {\n var _a;\n // TODO this needs to change depending on the bounding box...\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : this._textBounds.center;\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this._textBounds.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\n ex.scale(1, -1);\n }\n }\n measureTextWithoutCache(text, maxWidth) {\n return this._textMeasurement.measureText(text, maxWidth);\n }\n /**\n * Returns a BoundingBox that is the total size of the text including multiple lines\n *\n * Does not include any padding or adjustment\n * @param text\n * @returns BoundingBox\n */ measureText(text, maxWidth) {\n return FontCache.measureText(text, this, maxWidth);\n }\n _postDraw(ex) {\n ex.restore();\n }\n render(ex, text, colorOverride, x, y, maxWidth) {\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\n // Apply affine transformations\n this._textBounds = textInstance.dimensions;\n this._preDraw(ex, x, y);\n textInstance.render(ex, x, y, maxWidth);\n this._postDraw(ex);\n }\n }\n /**\n * Represent Text graphics in excalibur\n *\n * Useful for in game labels, ui, or overlays\n */ class Text extends Graphic {\n constructor(options){\n var _a, _b;\n super(options);\n this._text = \"\";\n this._textWidth = 0;\n this._textHeight = 0;\n // This order is important font, color, then text\n this.font = (_a = options.font) !== null && _a !== void 0 ? _a : new Font();\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : this.color;\n this.text = options.text;\n this.maxWidth = options.maxWidth;\n }\n clone() {\n var _a, _b;\n return new Text({\n text: this.text.slice(),\n color: (_b = (_a = this.color) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : Color.Black,\n font: this.font.clone(),\n maxWidth: this.maxWidth\n });\n }\n get text() {\n return this._text;\n }\n set text(value) {\n this._text = value;\n this._calculateDimension();\n }\n get font() {\n return this._font;\n }\n set font(font) {\n this._font = font;\n }\n get width() {\n if (this._textWidth === 0) this._calculateDimension();\n return this._textWidth * this.scale.x;\n }\n get height() {\n if (this._textHeight === 0) this._calculateDimension();\n return this._textHeight * this.scale.y;\n }\n _calculateDimension() {\n const { width: width, height: height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n }\n get localBounds() {\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\n }\n _rotate(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _flip(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _preDraw(ex, x, y) {\n if (this.isStale() || this.font.isStale()) {\n this.font.flipHorizontal = this.flipHorizontal;\n this.font.flipVertical = this.flipVertical;\n this.font.rotation = this.rotation;\n this.font.origin = this.origin;\n this.font.opacity = this.opacity;\n }\n this.font.tint = this.tint;\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n var _a;\n let color = Color.Black;\n if (this.font instanceof Font) color = (_a = this.color) !== null && _a !== void 0 ? _a : this.font.color;\n const { width: width, height: height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\n if (this.font.showDebug) {\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\n if (this.maxWidth != null) ex.debug.drawRect(x, y, this.maxWidth, this.height, {\n color: Color.Yellow\n });\n }\n }\n }\n /**\n * Type guard for checking if something is an Actor\n * @param x\n */ function isActor(x) {\n return x instanceof Actor;\n }\n const ActorEvents = {\n CollisionStart: \"collisionstart\",\n CollisionEnd: \"collisionend\",\n PreCollision: \"precollision\",\n PostCollision: \"postcollision\",\n Kill: \"kill\",\n PreKill: \"prekill\",\n PostKill: \"postkill\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\",\n PreTransformDraw: \"pretransformdraw\",\n PostTransformDraw: \"posttransformdraw\",\n PreDebugDraw: \"predebugdraw\",\n PostDebugDraw: \"postdebugdraw\",\n PointerUp: \"pointerup\",\n PointerDown: \"pointerdown\",\n PointerEnter: \"pointerenter\",\n PointerLeave: \"pointerleave\",\n PointerMove: \"pointermove\",\n PointerCancel: \"pointercancel\",\n Wheel: \"pointerwheel\",\n PointerDrag: \"pointerdragstart\",\n PointerDragEnd: \"pointerdragend\",\n PointerDragEnter: \"pointerdragenter\",\n PointerDragLeave: \"pointerdragleave\",\n PointerDragMove: \"pointerdragmove\",\n EnterViewPort: \"enterviewport\",\n ExitViewPort: \"exitviewport\",\n ActionStart: \"actionstart\",\n ActionComplete: \"actioncomplete\"\n };\n /**\n * The most important primitive in Excalibur is an `Actor`. Anything that\n * can move on the screen, collide with another `Actor`, respond to events,\n * or interact with the current scene, must be an actor. An `Actor` **must**\n * be part of a [[Scene]] for it to be drawn to the screen.\n */ class Actor extends Entity {\n /**\n * Gets the position vector of the actor in pixels\n */ get pos() {\n return this.transform.pos;\n }\n /**\n * Sets the position vector of the actor in pixels\n */ set pos(thePos) {\n this.transform.pos = thePos.clone();\n }\n /**\n * Gets the position vector of the actor from the last frame\n */ get oldPos() {\n return this.body.oldPos;\n }\n /**\n * Sets the position vector of the actor in the last frame\n */ set oldPos(thePos) {\n this.body.oldPos.setTo(thePos.x, thePos.y);\n }\n /**\n * Gets the velocity vector of the actor in pixels/sec\n */ get vel() {\n return this.motion.vel;\n }\n /**\n * Sets the velocity vector of the actor in pixels/sec\n */ set vel(theVel) {\n this.motion.vel = theVel.clone();\n }\n /**\n * Gets the velocity vector of the actor from the last frame\n */ get oldVel() {\n return this.body.oldVel;\n }\n /**\n * Sets the velocity vector of the actor from the last frame\n */ set oldVel(theVel) {\n this.body.oldVel.setTo(theVel.x, theVel.y);\n }\n /**\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\n * useful to simulate a gravitational effect.\n */ get acc() {\n return this.motion.acc;\n }\n /**\n * Sets the acceleration vector of teh actor in pixels/second/second\n */ set acc(theAcc) {\n this.motion.acc = theAcc.clone();\n }\n /**\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */ set oldAcc(theAcc) {\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\n }\n /**\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */ get oldAcc() {\n return this.body.oldAcc;\n }\n /**\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\n */ get rotation() {\n return this.transform.rotation;\n }\n /**\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\n */ set rotation(theAngle) {\n this.transform.rotation = theAngle;\n }\n /**\n * Gets the rotational velocity of the actor in radians/second\n */ get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\n * Sets the rotational velocity of the actor in radians/sec\n */ set angularVelocity(angularVelocity) {\n this.motion.angularVelocity = angularVelocity;\n }\n get scale() {\n return this.get(TransformComponent).scale;\n }\n set scale(scale) {\n this.get(TransformComponent).scale = scale;\n }\n /**\n * The anchor to apply all actor related transformations like rotation,\n * translation, and scaling. By default the anchor is in the center of\n * the actor. By default it is set to the center of the actor (.5, .5)\n *\n * An anchor of (.5, .5) will ensure that drawings are centered.\n *\n * Use `anchor.setTo` to set the anchor to a different point using\n * values between 0 and 1. For example, anchoring to the top-left would be\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\n */ get anchor() {\n return this._anchor;\n }\n set anchor(vec) {\n this._anchor = watch(vec, (v)=>this._handleAnchorChange(v));\n this._handleAnchorChange(vec);\n }\n _handleAnchorChange(v) {\n if (this.graphics) this.graphics.anchor = v;\n }\n /**\n * The offset in pixels to apply to all actor graphics\n *\n * Default offset of (0, 0)\n */ get offset() {\n return this._offset;\n }\n set offset(vec) {\n this._offset = watch(vec, (v)=>this._handleOffsetChange(v));\n this._handleOffsetChange(vec);\n }\n _handleOffsetChange(v) {\n if (this.graphics) this.graphics.offset = v;\n }\n /**\n * Indicates whether the actor is physically in the viewport\n */ get isOffScreen() {\n return this.hasTag(\"ex.offscreen\");\n }\n get draggable() {\n return this._draggable;\n }\n set draggable(isDraggable) {\n if (isDraggable) {\n if (isDraggable && !this._draggable) {\n this.events.on(\"pointerdragstart\", this._pointerDragStartHandler);\n this.events.on(\"pointerdragend\", this._pointerDragEndHandler);\n this.events.on(\"pointerdragmove\", this._pointerDragMoveHandler);\n this.events.on(\"pointerdragleave\", this._pointerDragLeaveHandler);\n } else if (!isDraggable && this._draggable) {\n this.events.off(\"pointerdragstart\", this._pointerDragStartHandler);\n this.events.off(\"pointerdragend\", this._pointerDragEndHandler);\n this.events.off(\"pointerdragmove\", this._pointerDragMoveHandler);\n this.events.off(\"pointerdragleave\", this._pointerDragLeaveHandler);\n }\n this._draggable = isDraggable;\n }\n }\n /**\n * Sets the color of the actor's current graphic\n */ get color() {\n return this._color;\n }\n set color(v) {\n this._color = v.clone();\n const currentGraphic = this.graphics.current;\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) currentGraphic.color = this._color;\n }\n // #endregion\n /**\n *\n * @param config\n */ constructor(config){\n super();\n this.events = new EventEmitter();\n this._anchor = watch(Vector.Half, (v)=>this._handleAnchorChange(v));\n this._offset = watch(Vector.Zero, (v)=>this._handleOffsetChange(v));\n /**\n * Convenience reference to the global logger\n */ this.logger = Logger.getInstance();\n /**\n * Draggable helper\n */ this._draggable = false;\n this._dragging = false;\n this._pointerDragStartHandler = ()=>{\n this._dragging = true;\n };\n this._pointerDragEndHandler = ()=>{\n this._dragging = false;\n };\n this._pointerDragMoveHandler = (pe)=>{\n if (this._dragging) this.pos = pe.worldPos;\n };\n this._pointerDragLeaveHandler = (pe)=>{\n if (this._dragging) this.pos = pe.worldPos;\n };\n const { name: name, x: x, y: y, pos: pos, coordPlane: coordPlane, scale: scale, width: width, height: height, radius: radius, collider: collider, vel: vel, acc: acc, rotation: rotation, angularVelocity: angularVelocity, z: z, color: color, visible: visible, opacity: opacity, anchor: anchor, offset: offset, collisionType: collisionType, collisionGroup: collisionGroup } = {\n ...config\n };\n this.name = name !== null && name !== void 0 ? name : this.name;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : Actor.defaults.anchor.clone();\n this.offset = offset !== null && offset !== void 0 ? offset : Vector.Zero;\n this.transform = new TransformComponent();\n this.addComponent(this.transform);\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.rotation = rotation !== null && rotation !== void 0 ? rotation : 0;\n this.scale = scale !== null && scale !== void 0 ? scale : vec(1, 1);\n this.z = z !== null && z !== void 0 ? z : 0;\n this.transform.coordPlane = coordPlane !== null && coordPlane !== void 0 ? coordPlane : CoordPlane.World;\n this.pointer = new PointerComponent;\n this.addComponent(this.pointer);\n this.graphics = new GraphicsComponent({\n anchor: this.anchor,\n offset: this.offset,\n opacity: opacity\n });\n this.addComponent(this.graphics);\n this.motion = new MotionComponent;\n this.addComponent(this.motion);\n this.vel = vel !== null && vel !== void 0 ? vel : Vector.Zero;\n this.acc = acc !== null && acc !== void 0 ? acc : Vector.Zero;\n this.angularVelocity = angularVelocity !== null && angularVelocity !== void 0 ? angularVelocity : 0;\n this.actions = new ActionsComponent;\n this.addComponent(this.actions);\n this.body = new BodyComponent;\n this.addComponent(this.body);\n this.body.collisionType = collisionType !== null && collisionType !== void 0 ? collisionType : CollisionType.Passive;\n if (collisionGroup) this.body.group = collisionGroup;\n if (collider) {\n this.collider = new ColliderComponent(collider);\n this.addComponent(this.collider);\n } else if (radius) {\n this.collider = new ColliderComponent(Shape.Circle(radius));\n this.addComponent(this.collider);\n } else if (width > 0 && height > 0) {\n this.collider = new ColliderComponent(Shape.Box(width, height, this.anchor));\n this.addComponent(this.collider);\n } else {\n this.collider = new ColliderComponent();\n this.addComponent(this.collider); // no collider\n }\n this.graphics.visible = visible !== null && visible !== void 0 ? visible : true;\n if (color) {\n this.color = color;\n if (width && height) this.graphics.add(new Rectangle({\n color: color,\n width: width,\n height: height\n }));\n else if (radius) this.graphics.add(new Circle({\n color: color,\n radius: radius\n }));\n }\n }\n clone() {\n const clone = new Actor({\n color: this.color.clone(),\n anchor: this.anchor.clone(),\n offset: this.offset.clone()\n });\n clone.clearComponents();\n clone.processComponentRemoval();\n // Clone builtins, order is important, same as ctor\n clone.addComponent(clone.transform = this.transform.clone(), true);\n clone.addComponent(clone.pointer = this.pointer.clone(), true);\n clone.addComponent(clone.graphics = this.graphics.clone(), true);\n clone.addComponent(clone.motion = this.motion.clone(), true);\n clone.addComponent(clone.actions = this.actions.clone(), true);\n clone.addComponent(clone.body = this.body.clone(), true);\n clone.addComponent(clone.collider = this.collider.clone(), true);\n const builtInComponents = [\n this.transform,\n this.pointer,\n this.graphics,\n this.motion,\n this.actions,\n this.body,\n this.collider\n ];\n // Clone non-builtin the current actors components\n const components = this.getComponents();\n for (const c of components)if (!builtInComponents.includes(c)) clone.addComponent(c.clone(), true);\n return clone;\n }\n /**\n * `onInitialize` is called before the first update of the actor. This method is meant to be\n * overridden. This is where initialization of child actors should take place.\n *\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\n */ onInitialize(engine) {\n // Override me\n }\n /**\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\n *\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n * @internal\n */ _initialize(engine) {\n super._initialize(engine);\n for (const child of this.children)child._initialize(engine);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n // #endregion\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _prekill handler for [[onPreKill]] lifecycle event\n * @internal\n */ _prekill(scene) {\n this.events.emit(\"prekill\", new PreKillEvent(this));\n this.onPreKill(scene);\n }\n /**\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\n *\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\n */ onPreKill(scene) {\n // Override me\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _prekill handler for [[onPostKill]] lifecycle event\n * @internal\n */ _postkill(scene) {\n this.events.emit(\"postkill\", new PostKillEvent(this));\n this.onPostKill(scene);\n }\n /**\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\n *\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\n */ onPostKill(scene) {\n // Override me\n }\n /**\n * If the current actor is a member of the scene, this will remove\n * it from the scene graph. It will no longer be drawn or updated.\n */ kill() {\n if (this.scene) {\n this._prekill(this.scene);\n this.events.emit(\"kill\", new KillEvent(this));\n super.kill();\n this._postkill(this.scene);\n } else this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\n }\n /**\n * If the current actor is killed, it will now not be killed.\n */ unkill() {\n this.active = true;\n }\n /**\n * Indicates wether the actor has been killed.\n */ isKilled() {\n return !this.active;\n }\n /**\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\n */ get z() {\n return this.get(TransformComponent).z;\n }\n /**\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\n * The z-index determines the relative order an actor is drawn in.\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\n * @param newZ new z-index to assign\n */ set z(newZ) {\n this.get(TransformComponent).z = newZ;\n }\n /**\n * Get the center point of an actor (global position)\n */ get center() {\n const globalPos = this.getGlobalPos();\n return new Vector(globalPos.x + this.width / 2 - this.anchor.x * this.width, globalPos.y + this.height / 2 - this.anchor.y * this.height);\n }\n /**\n * Get the local center point of an actor\n */ get localCenter() {\n return new Vector(this.pos.x + this.width / 2 - this.anchor.x * this.width, this.pos.y + this.height / 2 - this.anchor.y * this.height);\n }\n get width() {\n return this.collider.localBounds.width * this.getGlobalScale().x;\n }\n get height() {\n return this.collider.localBounds.height * this.getGlobalScale().y;\n }\n /**\n * Gets this actor's rotation taking into account any parent relationships\n * @returns Rotation angle in radians\n */ getGlobalRotation() {\n return this.get(TransformComponent).globalRotation;\n }\n /**\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\n * @returns Position in world coordinates\n */ getGlobalPos() {\n return this.get(TransformComponent).globalPos;\n }\n /**\n * Gets the global scale of the Actor\n */ getGlobalScale() {\n return this.get(TransformComponent).globalScale;\n }\n // #region Collision\n /**\n * Tests whether the x/y specified are contained in the actor\n * @param x X coordinate to test (in world coordinates)\n * @param y Y coordinate to test (in world coordinates)\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\n */ contains(x, y, recurse = false) {\n const point = vec(x, y);\n const collider = this.get(ColliderComponent);\n collider.update();\n const geom = collider.get();\n if (!geom) return false;\n const containment = geom.contains(point);\n if (recurse) return containment || this.children.some((child)=>{\n return child.contains(x, y, true);\n });\n return containment;\n }\n /**\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\n * @param actor Actor to test\n * @param distance Distance in pixels to test\n */ within(actor, distance) {\n const collider = this.get(ColliderComponent);\n const otherCollider = actor.get(ColliderComponent);\n const me = collider.get();\n const other = otherCollider.get();\n if (me && other) return me.getClosestLineBetween(other).getLength() <= distance;\n return false;\n }\n // #endregion\n // #region Update\n /**\n * Called by the Engine, updates the state of the actor\n * @internal\n * @param engine The reference to the current game engine\n * @param delta The time elapsed since the last update in milliseconds\n */ update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this._postupdate(engine, delta);\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before an actor is updated.\n */ onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after an actor is updated.\n */ onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n * Fires before every collision resolution for a confirmed contact\n * @param self\n * @param other\n * @param side\n * @param contact\n */ onPreCollisionResolve(self1, other, side, contact) {\n // Override me\n }\n /**\n * Fires after every resolution for a confirmed contact.\n * @param self\n * @param other\n * @param side\n * @param contact\n */ onPostCollisionResolve(self1, other, side, contact) {\n // Override me\n }\n /**\n * Fires once when 2 entities with a ColliderComponent first start colliding or touching, if the Colliders stay in contact this\n * does not continue firing until they separate and re-collide.\n * @param self\n * @param other\n * @param side\n * @param contact\n */ onCollisionStart(self1, other, side, contact) {\n // Override me\n }\n /**\n * Fires once when 2 entities with a ColliderComponent separate after having been in contact.\n * @param self\n * @param other\n * @param side\n * @param lastContact\n */ onCollisionEnd(self1, other, side, lastContact) {\n // Override me\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n }\n // #region Properties\n /**\n * Set defaults for all Actors\n */ Actor.defaults = {\n anchor: Vector.Half\n };\n /**\n * Type guard to detect a screen element\n */ function isScreenElement(actor) {\n return actor instanceof ScreenElement;\n }\n /**\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\n * not participate in collisions. Drawn on top of all other actors.\n */ class ScreenElement extends Actor {\n constructor(config){\n var _a, _b;\n super({\n ...config\n });\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\n this.anchor = (_a = config === null || config === void 0 ? void 0 : config.anchor) !== null && _a !== void 0 ? _a : vec(0, 0);\n this.body.collisionType = (_b = config === null || config === void 0 ? void 0 : config.collisionType) !== null && _b !== void 0 ? _b : CollisionType.PreventCollision;\n this.pointer.useGraphicsBounds = true;\n this.pointer.useColliderShape = false;\n if (!(config === null || config === void 0 ? void 0 : config.collider) && (config === null || config === void 0 ? void 0 : config.width) > 0 && (config === null || config === void 0 ? void 0 : config.height) > 0) this.collider.useBoxCollider(this.width, this.height, this.anchor);\n }\n _initialize(engine) {\n this._engine = engine;\n super._initialize(engine);\n }\n contains(x, y, useWorld = true) {\n if (useWorld) return super.contains(x, y);\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\n return super.contains(coords.x, coords.y);\n }\n }\n /**\n * The Excalibur timer hooks into the internal timer and fires callbacks,\n * after a certain interval, optionally repeating.\n */ class Timer {\n get complete() {\n return this._complete;\n }\n constructor(fcn, interval, repeats, numberOfRepeats, randomRange, random){\n this._logger = Logger.getInstance();\n this.id = 0;\n this._elapsedTime = 0;\n this._totalTimeAlive = 0;\n this._running = false;\n this._numberOfTicks = 0;\n this.interval = 10;\n this.repeats = false;\n this.maxNumberOfRepeats = -1;\n this.randomRange = [\n 0,\n 0\n ];\n this._baseInterval = 10;\n this._generateRandomInterval = ()=>{\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\n };\n this._complete = false;\n this.scene = null;\n if (typeof fcn !== \"function\") {\n const options = fcn;\n fcn = options.fcn;\n interval = options.interval;\n repeats = options.repeats;\n numberOfRepeats = options.numberOfRepeats;\n randomRange = options.randomRange;\n random = options.random;\n }\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\n this.maxNumberOfRepeats = numberOfRepeats;\n if (!repeats) throw new Error(\"repeats must be set to true if numberOfRepeats is set\");\n }\n this.id = Timer._MAX_ID++;\n this._callbacks = [];\n this._baseInterval = this.interval = interval;\n if (!!randomRange) {\n if (randomRange[0] > randomRange[1]) throw new Error(\"min value must be lower than max value for range\");\n //We use the instance of ex.Random to generate the range\n this.random = random !== null && random !== void 0 ? random : new Random();\n this.randomRange = randomRange;\n this.interval = this._generateRandomInterval();\n this.on(()=>{\n this.interval = this._generateRandomInterval();\n });\n }\n this.repeats = repeats || this.repeats;\n if (fcn) this.on(fcn);\n }\n /**\n * Adds a new callback to be fired after the interval is complete\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\n */ on(fcn) {\n this._callbacks.push(fcn);\n }\n /**\n * Removes a callback from the callback list to be fired after the interval is complete.\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\n */ off(fcn) {\n const index = this._callbacks.indexOf(fcn);\n this._callbacks.splice(index, 1);\n }\n /**\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\n * @param delta Number of elapsed milliseconds since the last update.\n */ update(delta) {\n if (this._running) {\n this._totalTimeAlive += delta;\n this._elapsedTime += delta;\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n if (!this.complete && this._elapsedTime >= this.interval) {\n this._callbacks.forEach((c)=>{\n c.call(this);\n });\n this._numberOfTicks++;\n if (this.repeats) this._elapsedTime = 0;\n else {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n }\n }\n }\n /**\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\n *\n * Warning** you may need to call `timer.start()` again if the timer had completed\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\n */ reset(newInterval, newNumberOfRepeats) {\n if (!!newInterval && newInterval >= 0) this._baseInterval = this.interval = newInterval;\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\n this.maxNumberOfRepeats = newNumberOfRepeats;\n if (!this.repeats) throw new Error(\"repeats must be set to true if numberOfRepeats is set\");\n }\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n get timesRepeated() {\n return this._numberOfTicks;\n }\n getTimeRunning() {\n return this._totalTimeAlive;\n }\n /**\n * @returns milliseconds until the next action callback, if complete will return 0\n */ get timeToNextAction() {\n if (this.complete) return 0;\n return this.interval - this._elapsedTime;\n }\n /**\n * @returns milliseconds elapsed toward the next action\n */ get timeElapsedTowardNextAction() {\n return this._elapsedTime;\n }\n get isRunning() {\n return this._running;\n }\n /**\n * Pauses the timer, time will no longer increment towards the next call\n */ pause() {\n this._running = false;\n return this;\n }\n /**\n * Resumes the timer, time will now increment towards the next call.\n */ resume() {\n this._running = true;\n return this;\n }\n /**\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\n */ start() {\n if (!this.scene) this._logger.warn(\"Cannot start a timer not part of a scene, timer wont start until added\");\n this._running = true;\n if (this.complete) {\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n return this;\n }\n /**\n * Stops the timer and resets the elapsed time counter towards the next action invocation\n */ stop() {\n this._running = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n return this;\n }\n /**\n * Cancels the timer, preventing any further executions.\n */ cancel() {\n this.pause();\n if (this.scene) this.scene.cancelTimer(this);\n }\n }\n Timer._MAX_ID = 0;\n class ParallaxComponent extends Component {\n constructor(parallaxFactor){\n super();\n this.parallaxFactor = vec(1.0, 1.0);\n this.parallaxFactor = parallaxFactor !== null && parallaxFactor !== void 0 ? parallaxFactor : this.parallaxFactor;\n }\n }\n /**\n * Provide arbitrary drawing for the purposes of debugging your game\n *\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\n *\n */ class DebugGraphicsComponent extends Component {\n constructor(draw, useTransform = true){\n super();\n this.draw = draw;\n this.useTransform = useTransform;\n }\n }\n const TileMapEvents = {\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\"\n };\n /**\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\n *\n * TileMaps are useful for top down or side scrolling grid oriented games.\n */ class TileMap extends Entity {\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n flagTilesDirty() {\n for(let i = 0; i < this.tiles.length; i++)if (this.tiles[i]) this.tiles[i].flagDirty();\n }\n get x() {\n var _a;\n return (_a = this.transform.pos.x) !== null && _a !== void 0 ? _a : 0;\n }\n set x(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos) this.get(TransformComponent).pos = vec(val, this.y);\n }\n get y() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos.y) !== null && _b !== void 0 ? _b : 0;\n }\n set y(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos) this.transform.pos = vec(this.x, val);\n }\n get z() {\n var _a;\n return (_a = this.transform.z) !== null && _a !== void 0 ? _a : 0;\n }\n set z(val) {\n if (this.transform) this.transform.z = val;\n }\n get rotation() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.rotation) !== null && _b !== void 0 ? _b : 0;\n }\n set rotation(val) {\n if (this.transform) this.transform.rotation = val;\n }\n get scale() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : Vector.One;\n }\n set scale(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.scale) this.transform.scale = val;\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n get vel() {\n return this._motion.vel;\n }\n set vel(val) {\n this._motion.vel = val;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * @param options\n */ constructor(options){\n var _a, _b, _c;\n super([], options.name);\n this.events = new EventEmitter();\n this._token = 0;\n this.logger = Logger.getInstance();\n this.tiles = [];\n this._rows = [];\n this._cols = [];\n this.renderFromTopOfGraphic = false;\n this.meshingLookBehind = 10;\n this._collidersDirty = true;\n this._originalOffsets = new WeakMap();\n this.meshingLookBehind = (_a = options.meshingLookBehind) !== null && _a !== void 0 ? _a : this.meshingLookBehind;\n this.addComponent(new TransformComponent());\n this.addComponent(new MotionComponent());\n this.addComponent(new BodyComponent({\n type: CollisionType.Fixed\n }));\n this.addComponent(new GraphicsComponent({\n onPostDraw: (ctx, delta)=>this.draw(ctx, delta)\n }));\n this.addComponent(new DebugGraphicsComponent((ctx, debugFlags)=>this.debug(ctx, debugFlags), false));\n this.addComponent(new ColliderComponent());\n this._graphics = this.get(GraphicsComponent);\n this.transform = this.get(TransformComponent);\n this._motion = this.get(MotionComponent);\n this.collider = this.get(ColliderComponent);\n this._composite = this.collider.useCompositeCollider([]);\n this.transform.pos = (_b = options.pos) !== null && _b !== void 0 ? _b : Vector.Zero;\n this._oldPos = this.transform.pos.clone();\n this._oldScale = this.transform.scale.clone();\n this.renderFromTopOfGraphic = (_c = options.renderFromTopOfGraphic) !== null && _c !== void 0 ? _c : this.renderFromTopOfGraphic;\n this.tileWidth = options.tileWidth;\n this.tileHeight = options.tileHeight;\n this.rows = options.rows;\n this.columns = options.columns;\n this.tiles = new Array(this.rows * this.columns);\n this._rows = new Array(this.rows);\n this._cols = new Array(this.columns);\n let currentCol = [];\n for(let i = 0; i < this.columns; i++){\n for(let j = 0; j < this.rows; j++){\n const tile = new Tile({\n x: i,\n y: j,\n map: this\n });\n tile.map = this;\n this.tiles[i + j * this.columns] = tile;\n currentCol.push(tile);\n if (!this._rows[j]) this._rows[j] = [];\n this._rows[j].push(tile);\n }\n this._cols[i] = currentCol;\n currentCol = [];\n }\n this._graphics.localBounds = new BoundingBox({\n left: 0,\n top: 0,\n right: this.columns * this.tileWidth * this.scale.x,\n bottom: this.rows * this.tileHeight * this.scale.y\n });\n }\n _initialize(engine) {\n super._initialize(engine);\n this._engine = engine;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n } else return this._originalOffsets.get(collider);\n }\n /**\n * Tiles colliders based on the solid tiles in the tilemap.\n */ _updateColliders() {\n this.collider.$colliderRemoved.notifyAll(this._composite);\n this._composite.clearColliders();\n const colliders = [];\n this._composite = this.collider.useCompositeCollider([]);\n let current;\n /**\n * Returns wether or not the 2 boxes share an edge and are the same height\n * @param prev\n * @param next\n * @returns true if they share and edge, false if not\n */ const shareEdges = (prev, next)=>{\n if (prev && next) // same top/bottom\n return prev.top === next.top && prev.bottom === next.bottom && // Shared right/left edge\n prev.right === next.left;\n return false;\n };\n /**\n * Potentially merges the current collider into a list of previous ones, mutating the list\n * If checkAndCombine returns true, the collider was successfully merged and should be thrown away\n * @param current current collider to test\n * @param colliders List of colliders to consider merging with\n * @param maxLookBack The amount of colliders to look back for combination\n * @returns false when no combination found, true when successfully combined\n */ const checkAndCombine = (current, colliders, maxLookBack = this.meshingLookBehind)=>{\n if (!current) return false;\n // walk backwards through the list of colliders and combine with the first that shares an edge\n for(let i = colliders.length - 1; i >= 0; i--){\n if (maxLookBack-- < 0) // blunt the O(n^2) algorithm a bit\n return false;\n const prev = colliders[i];\n if (shareEdges(prev, current)) {\n colliders[i] = prev.combine(current);\n return true;\n }\n }\n return false;\n };\n // ? configurable bias perhaps, horizontal strips vs. vertical ones\n // Bad tile collider packing algorithm\n for(let i = 0; i < this.columns; i++){\n // Scan column for colliders\n for(let j = 0; j < this.rows; j++){\n const tile = this.tiles[i + j * this.columns];\n // Current tile in column is solid build up current collider\n if (tile.solid) {\n // Use custom collider otherwise bounding box\n if (tile.getColliders().length > 0) {\n // tile with custom collider interrupting the current run\n for (const collider of tile.getColliders()){\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n //we push any current collider before nulling the current run\n if (current && !checkAndCombine(current, colliders)) colliders.push(current);\n current = null;\n // Use the bounding box\n } else if (!current) // no current run, start one\n current = tile.defaultGeometry;\n else // combine with current run\n current = current.combine(tile.defaultGeometry);\n } else {\n // Not solid skip and cut off the current collider\n // End of run check and combine\n if (current && !checkAndCombine(current, colliders)) colliders.push(current);\n current = null;\n }\n }\n // After a column is complete check to see if it can be merged into the last one\n // Eno of run check and combine\n if (current && !checkAndCombine(current, colliders)) // else new collider if no combination\n colliders.push(current);\n current = null;\n }\n for (const c of colliders){\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n this.collider.update();\n // Notify that colliders have been updated\n this.collider.$colliderAdded.notifyAll(this._composite);\n }\n /**\n * Returns the [[Tile]] by index (row major order)\n */ getTileByIndex(index) {\n return this.tiles[index];\n }\n /**\n * Returns the [[Tile]] by its x and y integer coordinates\n *\n * For example, if I want the tile in fifth column (x), and second row (y):\n * `getTile(4, 1)` 0 based, so 0 is the first in row/column\n */ getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) return null;\n return this.tiles[x + y * this.columns];\n }\n /**\n * Returns the [[Tile]] by testing a point in world coordinates,\n * returns `null` if no Tile was found.\n */ getTileByPoint(point) {\n const { x: x, y: y } = this._getTileCoordinates(point);\n const tile = this.getTile(x, y);\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) return tile;\n return null;\n }\n _getTileCoordinates(point) {\n // Convert to Tile Space point\n point = this.transform.applyInverse(point);\n const x = Math.floor(point.x / this.tileWidth);\n const y = Math.floor(point.y / this.tileHeight);\n return {\n x: x,\n y: y\n };\n }\n getRows() {\n return this._rows;\n }\n getColumns() {\n return this._cols;\n }\n /**\n * Returns the on screen tiles for a tilemap, this will overshoot by a small amount because of the internal quad tree data structure.\n *\n * Useful if you need to perform specific logic on onscreen tiles\n */ getOnScreenTiles() {\n let worldBounds = this._engine.screen.getWorldBounds();\n const maybeParallax = this.get(ParallaxComponent);\n if (maybeParallax && this.isInitialized) {\n let pos = this.pos;\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\n pos = pos.sub(parallaxOffset);\n // adjust world bounds by parallax factor\n worldBounds = worldBounds.translate(pos);\n }\n const bounds = this.transform.coordPlane === CoordPlane.Screen ? this._engine.screen.getScreenBounds() : worldBounds;\n const topLeft = this._getTileCoordinates(bounds.topLeft);\n const topRight = this._getTileCoordinates(bounds.topRight);\n const bottomRight = this._getTileCoordinates(bounds.bottomRight);\n const bottomLeft = this._getTileCoordinates(bounds.bottomLeft);\n const tileStartX = Math.min(clamp(topLeft.x, 0, this.columns - 1), clamp(topRight.x, 0, this.columns - 1));\n const tileStartY = Math.min(clamp(topLeft.y, 0, this.rows - 1), clamp(topRight.y, 0, this.rows - 1));\n const tileEndX = Math.max(clamp(bottomRight.x, 0, this.columns - 1), clamp(bottomLeft.x, 0, this.columns - 1));\n const tileEndY = Math.max(clamp(bottomRight.y, 0, this.rows - 1), clamp(bottomLeft.y, 0, this.rows - 1));\n const tiles = [];\n for(let x = tileStartX; x <= tileEndX; x++)for(let y = tileStartY; y <= tileEndY; y++)tiles.push(this.getTile(x, y));\n return tiles;\n }\n update(engine, delta) {\n this._initialize(engine);\n this.onPreUpdate(engine, delta);\n this.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n if (!this._oldPos.equals(this.pos) || this._oldRotation !== this.rotation || !this._oldScale.equals(this.scale)) {\n this.flagCollidersDirty();\n this.flagTilesDirty();\n }\n if (this._collidersDirty) {\n this._collidersDirty = false;\n this._updateColliders();\n }\n this._token++;\n this.pos.clone(this._oldPos);\n this._oldRotation = this.rotation;\n this.scale.clone(this._oldScale);\n this.transform.pos = this.pos;\n this.onPostUpdate(engine, delta);\n this.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n }\n /**\n * Draws the tile map to the screen. Called by the [[Scene]].\n * @param ctx ExcaliburGraphicsContext\n * @param delta The number of milliseconds since the last draw\n */ draw(ctx, delta) {\n if (!this.isInitialized) return;\n this.emit(\"predraw\", new PreDrawEvent(ctx, delta, this)); // TODO fix event\n let graphics, graphicsIndex, graphicsLen;\n const tiles = this.getOnScreenTiles();\n for(let i = 0; i < tiles.length; i++){\n const tile = tiles[i];\n // get non-negative tile sprites\n const offsets = tile.getGraphicsOffsets();\n graphics = tile.getGraphics();\n for(graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++){\n // draw sprite, warning if sprite doesn't exist\n const graphic = graphics[graphicsIndex];\n const offset = offsets[graphicsIndex];\n if (graphic) {\n if (hasGraphicsTick(graphic)) graphic === null || graphic === void 0 || graphic.tick(delta, this._token);\n const offsetY = this.renderFromTopOfGraphic ? 0 : graphic.height - this.tileHeight;\n graphic.draw(ctx, tile.x * this.tileWidth + offset.x, tile.y * this.tileHeight - offsetY + offset.y);\n }\n }\n }\n this.emit(\"postdraw\", new PostDrawEvent(ctx, delta, this));\n }\n debug(gfx, debugFlags) {\n const { showAll: showAll, showGrid: showGrid, gridColor: gridColor, gridWidth: gridWidth, showSolidBounds: showColliderBounds, solidBoundsColor: colliderBoundsColor, showColliderGeometry: showColliderGeometry } = debugFlags.tilemap;\n const { geometryColor: geometryColor, geometryLineWidth: geometryLineWidth, geometryPointSize: geometryPointSize } = debugFlags.collider;\n const width = this.tileWidth * this.columns * this.scale.x;\n const height = this.tileHeight * this.rows * this.scale.y;\n const pos = this.pos;\n if (showGrid || showAll) {\n for(let r = 0; r < this.rows + 1; r++){\n const yOffset = vec(0, r * this.tileHeight * this.scale.y);\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), gridColor, gridWidth);\n }\n for(let c = 0; c < this.columns + 1; c++){\n const xOffset = vec(c * this.tileWidth * this.scale.x, 0);\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), gridColor, gridWidth);\n }\n }\n if (showAll || showColliderBounds || showColliderGeometry) {\n const colliders = this._composite.getColliders();\n gfx.save();\n gfx.translate(this.pos.x, this.pos.y);\n gfx.scale(this.scale.x, this.scale.y);\n for (const collider of colliders){\n const bounds = collider.localBounds;\n const pos = collider.worldPos.sub(this.pos);\n if (showColliderBounds) gfx.drawRectangle(pos, bounds.width, bounds.height, colliderBoundsColor);\n }\n gfx.restore();\n if (showColliderGeometry) for (const collider of colliders)collider.debug(gfx, geometryColor, {\n lineWidth: geometryLineWidth,\n pointSize: geometryPointSize\n });\n }\n if (showAll || showColliderBounds) {\n gfx.save();\n gfx.z = 999;\n if (showColliderBounds) for(let i = 0; i < this.tiles.length; i++)this.tiles[i].bounds.draw(gfx);\n gfx.restore();\n }\n }\n }\n /**\n * TileMap Tile\n *\n * A light-weight object that occupies a space in a collision map. Generally\n * created by a [[TileMap]].\n *\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\n * of the sprites in the array so the last one will be drawn on top. You can\n * use transparency to create layers this way.\n */ class Tile extends Entity {\n /**\n * Return the world position of the top left corner of the tile\n */ get pos() {\n if (this._posDirty) {\n this._recalculate();\n this._posDirty = false;\n }\n return this._pos;\n }\n /**\n * Width of the tile in pixels\n */ get width() {\n return this._width;\n }\n /**\n * Height of the tile in pixels\n */ get height() {\n return this._height;\n }\n /**\n * Wether this tile should be treated as solid by the tilemap\n */ get solid() {\n return this._solid;\n }\n /**\n * Wether this tile should be treated as solid by the tilemap\n */ set solid(val) {\n var _a;\n (_a = this.map) === null || _a === void 0 || _a.flagCollidersDirty();\n this._solid = val;\n }\n /**\n * Current list of graphics for this tile\n */ getGraphics() {\n return this._graphics;\n }\n /**\n * Current list of offsets for this tile's graphics\n */ getGraphicsOffsets() {\n return this._offsets;\n }\n /**\n * Add another [[Graphic]] to this TileMap tile\n * @param graphic\n */ addGraphic(graphic, options) {\n this._graphics.push(graphic);\n if (options === null || options === void 0 ? void 0 : options.offset) this._offsets.push(options.offset);\n else this._offsets.push(Vector.Zero);\n }\n /**\n * Remove an instance of a [[Graphic]] from this tile\n */ removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) {\n this._graphics.splice(index, 1);\n this._offsets.splice(index, 1);\n }\n }\n /**\n * Clear all graphics from this tile\n */ clearGraphics() {\n this._graphics.length = 0;\n this._offsets.length = 0;\n }\n /**\n * Returns the list of colliders\n */ getColliders() {\n return this._colliders;\n }\n /**\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\n *\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\n *\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\n * @param collider\n */ addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\n * Removes a collider from the [[Tile]]\n * @param collider\n */ removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) this._colliders.splice(index, 1);\n this.map.flagCollidersDirty();\n }\n /**\n * Clears all colliders from the [[Tile]]\n */ clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n constructor(options){\n var _a, _b;\n super();\n this._posDirty = false;\n this._solid = false;\n this._graphics = [];\n this._offsets = [];\n /**\n * Current list of colliders for this tile\n */ this._colliders = [];\n /**\n * Arbitrary data storage per tile, useful for any game specific data\n */ this.data = new Map();\n this.x = options.x;\n this.y = options.y;\n this.map = options.map;\n this._width = options.map.tileWidth * this.map.scale.x;\n this._height = options.map.tileHeight * this.map.scale.y;\n this.solid = (_a = options.solid) !== null && _a !== void 0 ? _a : this.solid;\n this._graphics = (_b = options.graphics) !== null && _b !== void 0 ? _b : [];\n this._recalculate();\n }\n flagDirty() {\n return this._posDirty = true;\n }\n _recalculate() {\n const geometryPos = this.map.pos.add(vec(this.x * this.map.tileWidth, this.y * this.map.tileHeight));\n this._geometry = new BoundingBox(geometryPos.x, geometryPos.y, geometryPos.x + this.map.tileWidth, geometryPos.y + this.map.tileHeight);\n this._width = this.map.tileWidth * this.map.scale.x;\n this._height = this.map.tileHeight * this.map.scale.y;\n this._pos = this.map.pos.add(vec(this.x * this._width, this.y * this._height));\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\n if (this.map.rotation) this._bounds = this._bounds.rotate(this.map.rotation, this.map.pos);\n this._posDirty = false;\n }\n /**\n * Tile bounds in world space\n */ get bounds() {\n if (this._posDirty) this._recalculate();\n return this._bounds;\n }\n get defaultGeometry() {\n return this._geometry;\n }\n /**\n * Tile position in world space\n */ get center() {\n if (this._posDirty) this._recalculate();\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\n }\n }\n /**\n * Container to house convenience strategy methods\n * @internal\n */ class StrategyContainer {\n constructor(camera){\n this.camera = camera;\n }\n /**\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\n * @param actor The actor to lock the camera to\n */ lockToActor(actor) {\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\n }\n /**\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\n * @param actor The actor to lock the camera to\n * @param axis The axis to follow the actor on\n */ lockToActorAxis(actor, axis) {\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\n }\n /**\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\n * correct and bounce around the target\n * @param actor Target actor to elastically follow\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\n */ elasticToActor(actor, cameraElasticity, cameraFriction) {\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\n }\n /**\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\n * @param actor Target actor to follow when it is \"radius\" pixels away\n * @param radius Number of pixels away before the camera will follow\n */ radiusAroundActor(actor, radius) {\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\n }\n /**\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\n * @param box The bounding box to limit the camera to.\n */ limitCameraBounds(box) {\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\n }\n }\n /**\n * Camera axis enum\n */ var Axis;\n (function(Axis) {\n Axis[Axis[\"X\"] = 0] = \"X\";\n Axis[Axis[\"Y\"] = 1] = \"Y\";\n })(Axis || (Axis = {}));\n /**\n * Lock a camera to the exact x/y position of an actor.\n */ class LockCameraToActorStrategy {\n constructor(target){\n this.target = target;\n this.action = (target, camera, engine, delta)=>{\n const center = target.center;\n return center;\n };\n }\n }\n /**\n * Lock a camera to a specific axis around an actor.\n */ class LockCameraToActorAxisStrategy {\n constructor(target, axis){\n this.target = target;\n this.axis = axis;\n this.action = (target, cam, _eng, _delta)=>{\n const center = target.center;\n const currentFocus = cam.getFocus();\n if (this.axis === Axis.X) return new Vector(center.x, currentFocus.y);\n else return new Vector(currentFocus.x, center.y);\n };\n }\n }\n /**\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\n */ class ElasticToActorStrategy {\n /**\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\n * correct and bounce around the target\n * @param target Target actor to elastically follow\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\n */ constructor(target, cameraElasticity, cameraFriction){\n this.target = target;\n this.cameraElasticity = cameraElasticity;\n this.cameraFriction = cameraFriction;\n this.action = (target, cam, _eng, _delta)=>{\n const position = target.center;\n let focus = cam.getFocus();\n let cameraVel = cam.vel.clone();\n // Calculate the stretch vector, using the spring equation\n // F = kX\n // https://en.wikipedia.org/wiki/Hooke's_law\n // Apply to the current camera velocity\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\n cameraVel = cameraVel.add(stretch);\n // Calculate the friction (-1 to apply a force in the opposition of motion)\n // Apply to the current camera velocity\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\n cameraVel = cameraVel.add(friction);\n // Update position by velocity deltas\n focus = focus.add(cameraVel);\n return focus;\n };\n }\n }\n class RadiusAroundActorStrategy {\n /**\n *\n * @param target Target actor to follow when it is \"radius\" pixels away\n * @param radius Number of pixels away before the camera will follow\n */ constructor(target, radius){\n this.target = target;\n this.radius = radius;\n this.action = (target, cam, _eng, _delta)=>{\n const position = target.center;\n const focus = cam.getFocus();\n const direction = position.sub(focus);\n const distance = direction.size;\n if (distance >= this.radius) {\n const offset = distance - this.radius;\n return focus.add(direction.normalize().scale(offset));\n }\n return focus;\n };\n }\n }\n /**\n * Prevent a camera from going beyond the given camera dimensions.\n */ class LimitCameraBoundsStrategy {\n constructor(target){\n this.target = target;\n /**\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\n *\n * Note that this strategy does not perform any movement by itself.\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\n *\n * Make sure that the camera bounds are at least as large as the viewport size.\n * @param target The bounding box to limit the camera to\n */ this.boundSizeChecked = false; // Check and warn only once\n this.action = (target, cam, _eng, _delta)=>{\n const focus = cam.getFocus();\n if (!this.boundSizeChecked) {\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) Logger.getInstance().warn(\"Camera bounds should not be smaller than the engine viewport\");\n this.boundSizeChecked = true;\n }\n let focusX = focus.x;\n let focusY = focus.y;\n if (focus.x < target.left + _eng.halfDrawWidth) focusX = target.left + _eng.halfDrawWidth;\n else if (focus.x > target.right - _eng.halfDrawWidth) focusX = target.right - _eng.halfDrawWidth;\n if (focus.y < target.top + _eng.halfDrawHeight) focusY = target.top + _eng.halfDrawHeight;\n else if (focus.y > target.bottom - _eng.halfDrawHeight) focusY = target.bottom - _eng.halfDrawHeight;\n return vec(focusX, focusY);\n };\n }\n }\n const CameraEvents = {\n Initialize: \"initialize\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\"\n };\n /**\n * Cameras\n *\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\n * to move around your game and set focus. They are used to determine\n * what is \"off screen\" and can be used to scale the game.\n *\n */ class Camera {\n constructor(){\n this.events = new EventEmitter();\n this.transform = AffineMatrix.identity();\n this.inverse = AffineMatrix.identity();\n this._cameraStrategies = [];\n this.strategy = new StrategyContainer(this);\n /**\n * Get or set current zoom of the camera, defaults to 1\n */ this._z = 1;\n /**\n * Get or set rate of change in zoom, defaults to 0\n */ this.dz = 0;\n /**\n * Get or set zoom acceleration\n */ this.az = 0;\n /**\n * Current rotation of the camera\n */ this.rotation = 0;\n this._angularVelocity = 0;\n /**\n * Get or set the camera's position\n */ this._posChanged = false;\n this._pos = watchAny(Vector.Zero, ()=>this._posChanged = true);\n /**\n * Interpolated camera position if more draws are running than updates\n *\n * Enabled when `Engine.fixedUpdateFps` is enabled, in all other cases this will be the same as pos\n */ this.drawPos = this.pos.clone();\n this._oldPos = this.pos.clone();\n /**\n * Get or set the camera's velocity\n */ this.vel = Vector.Zero;\n /**\n * Get or set the camera's acceleration\n */ this.acc = Vector.Zero;\n this._cameraMoving = false;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = null;\n this._lerpEnd = null;\n //camera effects\n this._isShaking = false;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._elapsedShakeTime = 0;\n this._xShake = 0;\n this._yShake = 0;\n this._isZooming = false;\n this._zoomStart = 1;\n this._zoomEnd = 1;\n this._currentZoomTime = 0;\n this._zoomDuration = 0;\n this._zoomEasing = EasingFunctions.EaseInOutCubic;\n this._easing = EasingFunctions.EaseInOutCubic;\n this._halfWidth = 0;\n this._halfHeight = 0;\n this._viewport = null;\n this._isInitialized = false;\n this._snapPos = vec(0, 0);\n }\n get zoom() {\n return this._z;\n }\n set zoom(val) {\n this._z = val;\n if (this._engine) {\n this._halfWidth = this._engine.halfDrawWidth;\n this._halfHeight = this._engine.halfDrawHeight;\n }\n }\n /**\n * Get or set the camera's angular velocity\n */ get angularVelocity() {\n return this._angularVelocity;\n }\n set angularVelocity(value) {\n this._angularVelocity = value;\n }\n get pos() {\n return this._pos;\n }\n set pos(vec) {\n this._pos = watchAny(vec, ()=>this._posChanged = true);\n this._posChanged = true;\n }\n /**\n * Get the camera's x position\n */ get x() {\n return this.pos.x;\n }\n /**\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\n */ set x(value) {\n if (!this._follow && !this._cameraMoving) this.pos = vec(value, this.pos.y);\n }\n /**\n * Get the camera's y position\n */ get y() {\n return this.pos.y;\n }\n /**\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\n */ set y(value) {\n if (!this._follow && !this._cameraMoving) this.pos = vec(this.pos.x, value);\n }\n /**\n * Get or set the camera's x velocity\n */ get dx() {\n return this.vel.x;\n }\n set dx(value) {\n this.vel = vec(value, this.vel.y);\n }\n /**\n * Get or set the camera's y velocity\n */ get dy() {\n return this.vel.y;\n }\n set dy(value) {\n this.vel = vec(this.vel.x, value);\n }\n /**\n * Get or set the camera's x acceleration\n */ get ax() {\n return this.acc.x;\n }\n set ax(value) {\n this.acc = vec(value, this.acc.y);\n }\n /**\n * Get or set the camera's y acceleration\n */ get ay() {\n return this.acc.y;\n }\n set ay(value) {\n this.acc = vec(this.acc.x, value);\n }\n /**\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\n */ getFocus() {\n return this.pos;\n }\n /**\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\n * @param pos The target position to move to\n * @param duration The duration in milliseconds the move should last\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\n */ move(pos, duration, easingFn = EasingFunctions.EaseInOutCubic) {\n if (typeof easingFn !== \"function\") throw \"Please specify an EasingFunction\";\n // cannot move when following an actor\n if (this._follow) return Promise.reject(pos);\n // resolve existing promise, if any\n if (this._lerpPromise && this._lerpResolve) this._lerpResolve(pos);\n this._lerpPromise = new Promise((resolve)=>{\n this._lerpResolve = resolve;\n });\n this._lerpStart = this.getFocus().clone();\n this._lerpDuration = duration;\n this._lerpEnd = pos;\n this._currentLerpTime = 0;\n this._cameraMoving = true;\n this._easing = easingFn;\n return this._lerpPromise;\n }\n /**\n * Sets the camera to shake at the specified magnitudes for the specified duration\n * @param magnitudeX The x magnitude of the shake\n * @param magnitudeY The y magnitude of the shake\n * @param duration The duration of the shake in milliseconds\n */ shake(magnitudeX, magnitudeY, duration) {\n this._isShaking = true;\n this._shakeMagnitudeX = magnitudeX;\n this._shakeMagnitudeY = magnitudeY;\n this._shakeDuration = duration;\n }\n /**\n * Zooms the camera in or out by the specified scale over the specified duration.\n * If no duration is specified, it take effect immediately.\n * @param scale The scale of the zoom\n * @param duration The duration of the zoom in milliseconds\n */ zoomOverTime(scale, duration = 0, easingFn = EasingFunctions.EaseInOutCubic) {\n this._zoomPromise = new Promise((resolve)=>{\n this._zoomResolve = resolve;\n });\n if (duration) {\n this._isZooming = true;\n this._zoomEasing = easingFn;\n this._currentZoomTime = 0;\n this._zoomDuration = duration;\n this._zoomStart = this.zoom;\n this._zoomEnd = scale;\n } else {\n this._isZooming = false;\n this.zoom = scale;\n return Promise.resolve(true);\n }\n return this._zoomPromise;\n }\n /**\n * Gets the bounding box of the viewport of this camera in world coordinates\n */ get viewport() {\n if (this._viewport) return this._viewport;\n return new BoundingBox(0, 0, 0, 0);\n }\n /**\n * Adds a new camera strategy to this camera\n * @param cameraStrategy Instance of an [[CameraStrategy]]\n */ addStrategy(cameraStrategy) {\n this._cameraStrategies.push(cameraStrategy);\n }\n /**\n * Removes a camera strategy by reference\n * @param cameraStrategy Instance of an [[CameraStrategy]]\n */ removeStrategy(cameraStrategy) {\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\n }\n /**\n * Clears all camera strategies from the camera\n */ clearAllStrategies() {\n this._cameraStrategies.length = 0;\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before a scene is updated.\n */ onPreUpdate(engine, delta) {\n // Overridable\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */ onPostUpdate(engine, delta) {\n // Overridable\n }\n get isInitialized() {\n return this._isInitialized;\n }\n _initialize(engine) {\n if (!this.isInitialized) {\n this._engine = engine;\n this._screen = engine.screen;\n const currentRes = this._screen.contentArea;\n let center = vec(currentRes.width / 2, currentRes.height / 2);\n if (!this._engine.loadingComplete) {\n // If there was a loading screen, we peek the configured resolution\n const res = this._screen.peekResolution();\n if (res) center = vec(res.width / 2, res.height / 2);\n }\n this._halfWidth = center.x;\n this._halfHeight = center.y;\n // If the user has not set the camera pos, apply default center screen position\n if (!this._posChanged) this.pos = center;\n this.pos.clone(this.drawPos);\n // First frame bootstrap\n // Ensure camera tx is correct\n // Run update twice to ensure properties are init'd\n this.updateTransform(this.pos);\n // Run strategies for first frame\n this.runStrategies(engine, engine.clock.elapsed());\n // Setup the first frame viewport\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform(this.pos);\n this.pos.clone(this._oldPos);\n this.onInitialize(engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */ onInitialize(engine) {\n // Overridable\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n runStrategies(engine, delta) {\n for (const s of this._cameraStrategies)this.pos = s.action.call(s, s.target, this, engine, delta);\n }\n updateViewport() {\n // recalculate viewport\n this._viewport = new BoundingBox(this.x - this._halfWidth, this.y - this._halfHeight, this.x + this._halfWidth, this.y + this._halfHeight);\n }\n update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this.pos.clone(this._oldPos);\n // Update placements based on linear algebra\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\n this.zoom += this.dz * delta / 1000;\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\n this.dz += this.az * delta / 1000;\n this.rotation += this.angularVelocity * delta / 1000;\n if (this._isZooming) {\n if (this._currentZoomTime < this._zoomDuration) {\n const zoomEasing = this._zoomEasing;\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\n this.zoom = newZoom;\n this._currentZoomTime += delta;\n } else {\n this._isZooming = false;\n this.zoom = this._zoomEnd;\n this._currentZoomTime = 0;\n this._zoomResolve(true);\n }\n }\n if (this._cameraMoving) {\n if (this._currentLerpTime < this._lerpDuration) {\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\n this.pos = lerpPoint;\n this._currentLerpTime += delta;\n } else {\n this.pos = this._lerpEnd;\n const end = this._lerpEnd.clone();\n this._lerpStart = null;\n this._lerpEnd = null;\n this._currentLerpTime = 0;\n this._cameraMoving = false;\n // Order matters here, resolve should be last so any chain promises have a clean slate\n this._lerpResolve(end);\n }\n }\n if (this._isDoneShaking()) {\n this._isShaking = false;\n this._elapsedShakeTime = 0;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._xShake = 0;\n this._yShake = 0;\n } else {\n this._elapsedShakeTime += delta;\n this._xShake = (Math.random() * this._shakeMagnitudeX | 0) + 1;\n this._yShake = (Math.random() * this._shakeMagnitudeY | 0) + 1;\n }\n this.runStrategies(engine, delta);\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform(this.pos);\n this._postupdate(engine, delta);\n }\n /**\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\n * @param ctx Canvas context to apply transformations\n */ draw(ctx) {\n // default to the current position\n this.pos.clone(this.drawPos);\n // interpolation if fixed update is on\n // must happen on the draw, because more draws are potentially happening than updates\n if (this._engine.fixedUpdateFps) {\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n const interpolatedPos = this.pos.scale(blend).add(this._oldPos.scale(1.0 - blend));\n interpolatedPos.clone(this.drawPos);\n this.updateTransform(interpolatedPos);\n }\n // Snap camera to pixel\n if (ctx.snapToPixel) {\n const snapPos = this.drawPos.clone(this._snapPos);\n snapPos.x = ~~(snapPos.x + pixelSnapEpsilon * sign(snapPos.x));\n snapPos.y = ~~(snapPos.y + pixelSnapEpsilon * sign(snapPos.y));\n snapPos.clone(this.drawPos);\n this.updateTransform(snapPos);\n }\n ctx.multiply(this.transform);\n }\n updateTransform(pos) {\n // center the camera\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\n const cameraPos = vec(-pos.x + newCanvasWidth / 2 + this._xShake, -pos.y + newCanvasHeight / 2 + this._yShake);\n // Calculate camera transform\n this.transform.reset();\n this.transform.scale(this.zoom, this.zoom);\n // rotate about the focus\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\n this.transform.rotate(this.rotation);\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\n this.transform.translate(cameraPos.x, cameraPos.y);\n this.transform.inverse(this.inverse);\n }\n _isDoneShaking() {\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\n }\n }\n const TriggerEvents = {\n ExitTrigger: \"exit\",\n EnterTrigger: \"enter\"\n };\n const triggerDefaults = {\n pos: Vector.Zero,\n width: 10,\n height: 10,\n visible: false,\n action: ()=>{\n return;\n },\n filter: ()=>true,\n repeat: -1\n };\n /**\n * Triggers are a method of firing arbitrary code on collision. These are useful\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\n */ class Trigger extends Actor {\n /**\n *\n * @param opts Trigger options\n */ constructor(opts){\n super({\n x: opts.pos.x,\n y: opts.pos.y,\n width: opts.width,\n height: opts.height\n });\n this.events = new EventEmitter();\n /**\n * Action to fire when triggered by collision\n */ this.action = ()=>{\n return;\n };\n /**\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\n * filter return true for the collided actor.\n */ this.filter = ()=>true;\n /**\n * Number of times to repeat before killing the trigger,\n */ this.repeat = -1;\n opts = {\n ...triggerDefaults,\n ...opts\n };\n this.filter = opts.filter || this.filter;\n this.repeat = opts.repeat || this.repeat;\n this.action = opts.action || this.action;\n if (opts.target) this.target = opts.target;\n this.graphics.visible = opts.visible;\n this.body.collisionType = CollisionType.Passive;\n this.events.on(\"collisionstart\", (evt)=>{\n if (this.filter(evt.other)) {\n this.events.emit(\"enter\", new EnterTriggerEvent(this, evt.other));\n this._dispatchAction();\n // remove trigger if its done, -1 repeat forever\n if (this.repeat === 0) this.kill();\n }\n });\n this.events.on(\"collisionend\", (evt)=>{\n if (this.filter(evt.other)) this.events.emit(\"exit\", new ExitTriggerEvent(this, evt.other));\n });\n }\n set target(target) {\n this._target = target;\n this.filter = (actor)=>actor === target;\n }\n get target() {\n return this._target;\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n _dispatchAction() {\n if (this.repeat !== 0) {\n this.action.call(this);\n this.repeat--;\n }\n }\n }\n /**\n * Higher priorities run earlier than others in the system update\n */ const SystemPriority = {\n Highest: -Infinity,\n Higher: -5,\n Average: 0,\n Lower: 5,\n Lowest: Infinity\n };\n /**\n * Enum that determines whether to run the system in the update or draw phase\n */ var SystemType;\n (function(SystemType) {\n SystemType[\"Update\"] = \"update\";\n SystemType[\"Draw\"] = \"draw\";\n })(SystemType || (SystemType = {}));\n /**\n * An Excalibur [[System]] that updates entities of certain types.\n * Systems are scene specific\n *\n *\n *\n * Excalibur Systems currently require at least 1 Component type to operated\n *\n * Multiple types are declared as a type union\n * For example:\n *\n * ```typescript\n * class MySystem extends System {\n * public readonly types = ['a', 'b'] as const;\n * public readonly systemType = SystemType.Update;\n * public update(entities: Entity) {\n * ...\n * }\n * }\n * ```\n */ class System {\n constructor(){\n /**\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\n * For a system to execute after all other a higher priority value (10 for example) must be set.\n */ this.priority = SystemPriority.Average;\n }\n }\n // Add/Remove entities and components\n class EntityManager {\n constructor(_world){\n this._world = _world;\n this.entities = [];\n this._entityIndex = {};\n this._entitiesToRemove = [];\n }\n /**\n * Runs the entity lifecycle\n * @param scene\n * @param elapsed\n */ updateEntities(scene, elapsed) {\n for (const entity of this.entities){\n entity.update(scene.engine, elapsed);\n if (!entity.active) this.removeEntity(entity);\n }\n }\n findEntitiesForRemoval() {\n for (const entity of this.entities)if (!entity.active) this.removeEntity(entity);\n }\n /**\n * Adds an entity to be tracked by the EntityManager\n * @param entity\n */ addEntity(entity) {\n entity.active = true;\n entity.scene = this._world.scene;\n if (entity && !this._entityIndex[entity.id]) {\n this._entityIndex[entity.id] = entity;\n this.entities.push(entity);\n this._world.queryManager.addEntity(entity);\n // if entity has children\n entity.children.forEach((c)=>{\n c.scene = entity.scene;\n this.addEntity(c);\n });\n entity.childrenAdded$.register({\n notify: (e)=>{\n this.addEntity(e);\n }\n });\n entity.childrenRemoved$.register({\n notify: (e)=>{\n this.removeEntity(e, false);\n }\n });\n }\n }\n removeEntity(idOrEntity, deferred = true) {\n var _a, _b;\n let id = 0;\n if (idOrEntity instanceof Entity) id = idOrEntity.id;\n else id = idOrEntity;\n const entity = this._entityIndex[id];\n if (entity && entity.active) entity.active = false;\n if (entity && deferred) {\n this._entitiesToRemove.push(entity);\n return;\n }\n delete this._entityIndex[id];\n if (entity) {\n entity.scene = null;\n removeItemFromArray(entity, this.entities);\n this._world.queryManager.removeEntity(entity);\n // if entity has children\n entity.children.forEach((c)=>{\n c.scene = null;\n this.removeEntity(c, deferred);\n });\n entity.childrenAdded$.clear();\n entity.childrenRemoved$.clear();\n // stats\n if ((_b = (_a = this._world) === null || _a === void 0 ? void 0 : _a.scene) === null || _b === void 0 ? void 0 : _b.engine) this._world.scene.engine.stats.currFrame.actors.killed++;\n }\n }\n processEntityRemovals() {\n for (const entity of this._entitiesToRemove){\n if (entity.active) continue;\n this.removeEntity(entity, false);\n }\n this._entitiesToRemove.length = 0;\n }\n processComponentRemovals() {\n for (const entity of this.entities)entity.processComponentRemoval();\n }\n getById(id) {\n return this._entityIndex[id];\n }\n getByName(name) {\n return this.entities.filter((e)=>e.name === name);\n }\n clear() {\n for(let i = this.entities.length - 1; i >= 0; i--)this.removeEntity(this.entities[i]);\n }\n }\n /**\n * Represents query for entities that match a list of types that is cached and observable\n *\n * Queries can be strongly typed by supplying a type union in the optional type parameter\n * ```typescript\n * const queryAB = new ex.Query(['A', 'B']);\n * ```\n */ class Query {\n constructor(requiredComponents){\n this.requiredComponents = requiredComponents;\n this.components = new Set();\n this.entities = [];\n /**\n * This fires right after the component is added\n */ this.entityAdded$ = new Observable();\n /**\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\n */ this.entityRemoved$ = new Observable();\n if (requiredComponents.length === 0) throw new Error(\"Cannot create query without components\");\n for (const type of requiredComponents)this.components.add(type);\n this.id = Query.createId(requiredComponents);\n }\n static createId(requiredComponents) {\n // TODO what happens if a user defines the same type name as a built in type\n // ! TODO this could be dangerous depending on the bundler's settings for names\n // Maybe some kind of hash function is better here?\n return requiredComponents.slice().map((c)=>c.name).sort().join(\"-\");\n }\n /**\n * Potentially adds an entity to a query index, returns true if added, false if not\n * @param entity\n */ checkAndAdd(entity) {\n if (!this.entities.includes(entity) && entity.hasAll(Array.from(this.components))) {\n this.entities.push(entity);\n this.entityAdded$.notifyAll(entity);\n return true;\n }\n return false;\n }\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index > -1) {\n this.entities.splice(index, 1);\n this.entityRemoved$.notifyAll(entity);\n }\n }\n /**\n * Returns a list of entities that match the query\n * @param sort Optional sorting function to sort entities returned from the query\n */ getEntities(sort) {\n if (sort) this.entities.sort(sort);\n return this.entities;\n }\n }\n class TagQuery {\n constructor(requiredTags){\n this.requiredTags = requiredTags;\n this.tags = new Set();\n this.entities = [];\n /**\n * This fires right after the component is added\n */ this.entityAdded$ = new Observable();\n /**\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\n */ this.entityRemoved$ = new Observable();\n if (requiredTags.length === 0) throw new Error(\"Cannot create tag query without tags\");\n for (const tag of requiredTags)this.tags.add(tag);\n this.id = TagQuery.createId(requiredTags);\n }\n static createId(requiredComponents) {\n return requiredComponents.slice().sort().join(\"-\");\n }\n checkAndAdd(entity) {\n if (!this.entities.includes(entity) && entity.hasAllTags(Array.from(this.tags))) {\n this.entities.push(entity);\n this.entityAdded$.notifyAll(entity);\n return true;\n }\n return false;\n }\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index > -1) {\n this.entities.splice(index, 1);\n this.entityRemoved$.notifyAll(entity);\n }\n }\n /**\n * Returns a list of entities that match the query\n * @param sort Optional sorting function to sort entities returned from the query\n */ getEntities(sort) {\n if (sort) this.entities.sort(sort);\n return this.entities;\n }\n }\n /**\n * The query manager is responsible for updating all queries when entities/components change\n */ class QueryManager {\n constructor(_world){\n this._world = _world;\n this._queries = new Map();\n this._addComponentHandlers = new Map();\n this._removeComponentHandlers = new Map();\n this._componentToQueriesIndex = new Map();\n this._tagQueries = new Map();\n this._addTagHandlers = new Map();\n this._removeTagHandlers = new Map();\n this._tagToQueriesIndex = new Map();\n this._createAddComponentHandler = (entity)=>(c)=>{\n this.addComponent(entity, c);\n };\n this._createRemoveComponentHandler = (entity)=>(c)=>{\n this.removeComponent(entity, c);\n };\n this._createAddTagHandler = (entity)=>(tag)=>{\n this.addTag(entity, tag);\n };\n this._createRemoveTagHandler = (entity)=>(tag)=>{\n this.removeTag(entity, tag);\n };\n }\n createQuery(requiredComponents) {\n const id = Query.createId(requiredComponents);\n if (this._queries.has(id)) // short circuit if query is already created\n return this._queries.get(id);\n const query = new Query(requiredComponents);\n this._queries.set(query.id, query);\n // index maintenance\n for (const component of requiredComponents){\n const queries = this._componentToQueriesIndex.get(component);\n if (!queries) this._componentToQueriesIndex.set(component, [\n query\n ]);\n else queries.push(query);\n }\n for (const entity of this._world.entities)this.addEntity(entity);\n return query;\n }\n createTagQuery(requiredTags) {\n const id = TagQuery.createId(requiredTags);\n if (this._tagQueries.has(id)) // short circuit if query is already created\n return this._tagQueries.get(id);\n const query = new TagQuery(requiredTags);\n this._tagQueries.set(query.id, query);\n // index maintenance\n for (const tag of requiredTags){\n const queries = this._tagToQueriesIndex.get(tag);\n if (!queries) this._tagToQueriesIndex.set(tag, [\n query\n ]);\n else queries.push(query);\n }\n for (const entity of this._world.entities)this.addEntity(entity);\n return query;\n }\n /**\n * Scans queries and locates any that need this entity added\n * @param entity\n */ addEntity(entity) {\n const maybeAddComponent = this._addComponentHandlers.get(entity);\n const maybeRemoveComponent = this._removeComponentHandlers.get(entity);\n const addComponent = maybeAddComponent !== null && maybeAddComponent !== void 0 ? maybeAddComponent : this._createAddComponentHandler(entity);\n const removeComponent = maybeRemoveComponent !== null && maybeRemoveComponent !== void 0 ? maybeRemoveComponent : this._createRemoveComponentHandler(entity);\n this._addComponentHandlers.set(entity, addComponent);\n this._removeComponentHandlers.set(entity, removeComponent);\n const maybeAddTag = this._addTagHandlers.get(entity);\n const maybeRemoveTag = this._removeTagHandlers.get(entity);\n const addTag = maybeAddTag !== null && maybeAddTag !== void 0 ? maybeAddTag : this._createAddTagHandler(entity);\n const removeTag = maybeRemoveTag !== null && maybeRemoveTag !== void 0 ? maybeRemoveTag : this._createRemoveTagHandler(entity);\n this._addTagHandlers.set(entity, addTag);\n this._removeTagHandlers.set(entity, removeTag);\n for (const query of this._queries.values())query.checkAndAdd(entity);\n for (const tagQuery of this._tagQueries.values())tagQuery.checkAndAdd(entity);\n entity.componentAdded$.subscribe(addComponent);\n entity.componentRemoved$.subscribe(removeComponent);\n entity.tagAdded$.subscribe(addTag);\n entity.tagRemoved$.subscribe(removeTag);\n }\n /**\n * Scans queries and locates any that need this entity removed\n * @param entity\n */ removeEntity(entity) {\n // Handle components\n const addComponent = this._addComponentHandlers.get(entity);\n const removeComponent = this._removeComponentHandlers.get(entity);\n for (const query of this._queries.values())query.removeEntity(entity);\n if (addComponent) entity.componentAdded$.unsubscribe(addComponent);\n if (removeComponent) entity.componentRemoved$.unsubscribe(removeComponent);\n // Handle tags\n const addTag = this._addTagHandlers.get(entity);\n const removeTag = this._removeTagHandlers.get(entity);\n for (const tagQuery of this._tagQueries.values())tagQuery.removeEntity(entity);\n if (addTag) entity.tagAdded$.unsubscribe(addTag);\n if (removeTag) entity.tagRemoved$.unsubscribe(removeTag);\n }\n /**\n * Updates any queries when a component is added to an entity\n * @param entity\n * @param component\n */ addComponent(entity, component) {\n var _a;\n const queries = (_a = this._componentToQueriesIndex.get(component.constructor)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries)query.checkAndAdd(entity);\n }\n /**\n * Updates any queries when a component is removed from an entity\n * @param entity\n * @param component\n */ removeComponent(entity, component) {\n var _a;\n const queries = (_a = this._componentToQueriesIndex.get(component.constructor)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries)query.removeEntity(entity);\n }\n /**\n * Updates any queries when a tag is added to an entity\n * @param entity\n * @param tag\n */ addTag(entity, tag) {\n var _a;\n const queries = (_a = this._tagToQueriesIndex.get(tag)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries)query.checkAndAdd(entity);\n }\n /**\n * Updates any queries when a component is removed from an entity\n * @param entity\n * @param tag\n */ removeTag(entity, tag) {\n var _a;\n const queries = (_a = this._tagToQueriesIndex.get(tag)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries)query.removeEntity(entity);\n }\n }\n /**\n *\n */ function isSystemConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n }\n /**\n * The SystemManager is responsible for keeping track of all systems in a scene.\n * Systems are scene specific\n */ class SystemManager {\n constructor(_world){\n this._world = _world;\n /**\n * List of systems, to add a new system call [[SystemManager.addSystem]]\n */ this.systems = [];\n this.initialized = false;\n }\n /**\n * Get a system registered in the manager by type\n * @param systemType\n */ get(systemType) {\n return this.systems.find((s)=>s instanceof systemType);\n }\n /**\n * Adds a system to the manager, it will now be updated every frame\n * @param systemOrCtor\n */ addSystem(systemOrCtor) {\n let system;\n if (systemOrCtor instanceof System) system = systemOrCtor;\n else system = new systemOrCtor(this._world);\n this.systems.push(system);\n this.systems.sort((a, b)=>a.priority - b.priority);\n // If systems are added and the manager has already been init'd\n // then immediately init the system\n if (this.initialized && system.initialize) system.initialize(this._world, this._world.scene);\n }\n /**\n * Removes a system from the manager, it will no longer be updated\n * @param system\n */ removeSystem(system) {\n removeItemFromArray(system, this.systems);\n }\n /**\n * Initialize all systems in the manager\n *\n * Systems added after initialize() will be initialized on add\n */ initialize() {\n if (!this.initialized) {\n this.initialized = true;\n for (const s of this.systems)if (s.initialize) s.initialize(this._world, this._world.scene);\n }\n }\n /**\n * Updates all systems\n * @param type whether this is an update or draw system\n * @param scene context reference\n * @param delta time in milliseconds\n */ updateSystems(type, scene, delta) {\n const systems = this.systems.filter((s)=>s.systemType === type);\n for (const s of systems)if (s.preupdate) s.preupdate(scene, delta);\n for (const s of systems)s.update(delta);\n for (const s of systems)if (s.postupdate) s.postupdate(scene, delta);\n }\n clear() {\n for(let i = this.systems.length - 1; i >= 0; i--)this.removeSystem(this.systems[i]);\n }\n }\n /**\n * The World is a self-contained entity component system for a particular context.\n */ class World {\n /**\n * The context type is passed to the system updates\n * @param scene\n */ constructor(scene){\n this.scene = scene;\n this.queryManager = new QueryManager(this);\n this.entityManager = new EntityManager(this);\n this.systemManager = new SystemManager(this);\n }\n /**\n * Query the ECS world for entities that match your components\n * @param requiredTypes\n */ query(requiredTypes) {\n return this.queryManager.createQuery(requiredTypes);\n }\n queryTags(requiredTags) {\n return this.queryManager.createTagQuery(requiredTags);\n }\n /**\n * Update systems by type and time elapsed in milliseconds\n */ update(type, delta) {\n if (type === SystemType.Update) this.entityManager.updateEntities(this.scene, delta);\n this.systemManager.updateSystems(type, this.scene, delta);\n this.entityManager.findEntitiesForRemoval();\n this.entityManager.processComponentRemovals();\n this.entityManager.processEntityRemovals();\n }\n add(entityOrSystem) {\n if (entityOrSystem instanceof Entity) this.entityManager.addEntity(entityOrSystem);\n if (entityOrSystem instanceof System || isSystemConstructor(entityOrSystem)) this.systemManager.addSystem(entityOrSystem);\n }\n /**\n * Get a system out of the ECS world\n */ get(system) {\n return this.systemManager.get(system);\n }\n remove(entityOrSystem, deferred = true) {\n if (entityOrSystem instanceof Entity) this.entityManager.removeEntity(entityOrSystem, deferred);\n if (entityOrSystem instanceof System) this.systemManager.removeSystem(entityOrSystem);\n }\n get entities() {\n return this.entityManager.entities;\n }\n clearEntities() {\n this.entityManager.clear();\n }\n clearSystems() {\n this.systemManager.clear();\n }\n }\n class EulerIntegrator {\n static integrate(transform, motion, totalAcc, elapsedMs) {\n const seconds = elapsedMs / 1000;\n // This code looks a little wild, but it's to avoid creating any new Vector instances\n // integration is done in a tight loop so this is key to avoid GC'ing\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\n transform.pos.add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS).addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\n const rotation = transform.rotation + motion.angularVelocity * seconds;\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\n const tx = transform.get();\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\n }\n }\n // Scratch vectors to avoid allocation\n EulerIntegrator._POS = new Vector(0, 0);\n EulerIntegrator._SCALE = new Vector(1, 1);\n EulerIntegrator._ACC = new Vector(0, 0);\n EulerIntegrator._VEL = new Vector(0, 0);\n EulerIntegrator._VEL_ACC = new Vector(0, 0);\n EulerIntegrator._SCALE_FACTOR = new Vector(0, 0);\n class MotionSystem extends System {\n constructor(world, physics){\n super();\n this.world = world;\n this.physics = physics;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._physicsConfigDirty = false;\n physics.$configUpdate.subscribe(()=>this._physicsConfigDirty = true);\n this.query = this.world.query([\n TransformComponent,\n MotionComponent\n ]);\n }\n update(elapsedMs) {\n let transform;\n let motion;\n const entities = this.query.entities;\n for(let i = 0; i < entities.length; i++){\n transform = entities[i].get(TransformComponent);\n motion = entities[i].get(MotionComponent);\n const optionalBody = entities[i].get(BodyComponent);\n if (this._physicsConfigDirty && optionalBody) optionalBody.updatePhysicsConfig(this.physics.config.bodies);\n if (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.sleeping) continue;\n const totalAcc = motion.acc.clone();\n if ((optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.collisionType) === CollisionType.Active && (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.useGravity)) totalAcc.addEqual(this.physics.config.gravity);\n optionalBody === null || optionalBody === void 0 || optionalBody.captureOldTransform();\n // Update transform and motion based on Euler linear algebra\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\n }\n }\n }\n /**\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\n * and negates velocity along the collision normal.\n *\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\n *\n */ class ArcadeSolver {\n constructor(config){\n this.config = config;\n this.directionMap = new Map();\n this.distanceMap = new Map();\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter((c)=>!c.isCanceled());\n // Locate collision bias order\n let bias;\n switch(this.config.contactSolveBias){\n case ContactSolveBias.HorizontalFirst:\n bias = HorizontalFirst;\n break;\n case ContactSolveBias.VerticalFirst:\n bias = VerticalFirst;\n break;\n default:\n bias = None;\n }\n // Sort by bias (None, VerticalFirst, HorizontalFirst) to avoid artifacts with seams\n // Sort contacts by distance to avoid artifacts with seams\n // It's important to solve in a specific order\n contacts.sort((a, b)=>{\n const aDir = this.directionMap.get(a.id);\n const bDir = this.directionMap.get(b.id);\n const aDist = this.distanceMap.get(a.id);\n const bDist = this.distanceMap.get(b.id);\n return bias[aDir] - bias[bDir] || aDist - bDist;\n });\n for (const contact of contacts){\n // Solve position first in arcade\n this.solvePosition(contact);\n // Solve velocity second in arcade\n this.solveVelocity(contact);\n }\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n const epsilon = .0001;\n for (const contact of contacts){\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\n this.distanceMap.set(contact.id, distance);\n this.directionMap.set(contact.id, side === Side.Left || side === Side.Right ? \"horizontal\" : \"vertical\");\n // Publish collision events on both participants\n contact.colliderA.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\n contact.colliderB.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact));\n }\n }\n postSolve(contacts) {\n var _a, _b;\n for (const contact of contacts){\n if (contact.isCanceled()) continue;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n // Publish collision events on both participants\n contact.colliderA.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\n contact.colliderB.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact));\n }\n }\n solvePosition(contact) {\n var _a, _b;\n const epsilon = .0001;\n // if bounds no longer intersect skip to the next\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\n // Cancel the contact to prevent and solving\n contact.cancel();\n return;\n }\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n return;\n }\n let mtv = contact.mtv;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) return;\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) // split overlaps if both are Active\n mtv = mtv.scale(0.5);\n // Resolve overlaps\n if (bodyA.collisionType === CollisionType.Active) {\n bodyA.globalPos.x -= mtv.x;\n bodyA.globalPos.y -= mtv.y;\n colliderA.update(bodyA.transform.get());\n }\n if (bodyB.collisionType === CollisionType.Active) {\n bodyB.globalPos.x += mtv.x;\n bodyB.globalPos.y += mtv.y;\n colliderB.update(bodyB.transform.get());\n }\n }\n }\n solveVelocity(contact) {\n var _a, _b;\n if (contact.isCanceled()) return;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) return;\n const normal = contact.normal;\n const opposite = normal.negate();\n if (bodyA.collisionType === CollisionType.Active) // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform when sliding off\n {\n if (bodyA.vel.normalize().dot(opposite) < 0) {\n // Cancel out velocity opposite direction of collision normal\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\n bodyA.vel = bodyA.vel.add(velAdj);\n }\n }\n if (bodyB.collisionType === CollisionType.Active) // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform\n {\n if (bodyB.vel.normalize().dot(normal) < 0) {\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\n bodyB.vel = bodyB.vel.add(velAdj);\n }\n }\n }\n }\n }\n /**\n * Holds information about contact points, meant to be reused over multiple frames of contact\n */ class ContactConstraintPoint {\n constructor(point, local, contact){\n this.point = point;\n this.local = local;\n this.contact = contact;\n /**\n * Impulse accumulated over time in normal direction\n */ this.normalImpulse = 0;\n /**\n * Impulse accumulated over time in the tangent direction\n */ this.tangentImpulse = 0;\n /**\n * Effective mass seen in the normal direction\n */ this.normalMass = 0;\n /**\n * Effective mass seen in the tangent direction\n */ this.tangentMass = 0;\n /**\n * Direction from center of mass of bodyA to contact point\n */ this.aToContact = new Vector(0, 0);\n /**\n * Direction from center of mass of bodyB to contact point\n */ this.bToContact = new Vector(0, 0);\n /**\n * Original contact velocity combined with bounciness\n */ this.originalVelocityAndRestitution = 0;\n this.update();\n }\n /**\n * Updates the contact information\n */ update() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const normal = this.contact.normal;\n const tangent = this.contact.tangent;\n this.aToContact = this.point.sub(bodyA.globalPos);\n this.bToContact = this.point.sub(bodyB.globalPos);\n const aToContactNormal = this.aToContact.cross(normal);\n const bToContactNormal = this.bToContact.cross(normal);\n this.normalMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactNormal * aToContactNormal + bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = this.aToContact.cross(tangent);\n const bToContactTangent = this.bToContact.cross(tangent);\n this.tangentMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactTangent * aToContactTangent + bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n }\n return this;\n }\n /**\n * Returns the relative velocity between bodyA and bodyB\n */ getRelativeVelocity() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Relative velocity in linear terms\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\n return velB.sub(velA);\n }\n return Vector.Zero;\n }\n }\n class RealisticSolver {\n constructor(config){\n this.config = config;\n this.lastFrameContacts = new Map();\n // map contact id to contact points\n this.idToContactConstraint = new Map();\n }\n getContactConstraints(id) {\n var _a;\n return (_a = this.idToContactConstraint.get(id)) !== null && _a !== void 0 ? _a : [];\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter((c)=>!c.isCanceled());\n // Solve velocity first\n this.solveVelocity(contacts);\n // Solve position last because non-overlap is the most important\n this.solvePosition(contacts);\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n var _a, _b, _c;\n const epsilon = .0001;\n for (const contact of contacts){\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderA.events.emit(\"beforecollisionresolve\", new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n contact.colliderB.events.emit(\"beforecollisionresolve\", new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n // Match awake state for sleeping\n contact.matchAwake();\n }\n // Keep track of contacts that done\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\n for (const contact of contacts){\n // Remove all current contacts that are not done\n const index = finishedContactIds.indexOf(contact.id);\n if (index > -1) finishedContactIds.splice(index, 1);\n const contactPoints = (_a = this.idToContactConstraint.get(contact.id)) !== null && _a !== void 0 ? _a : [];\n let pointIndex = 0;\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) for (const point of contact.points){\n const normal = contact.normal;\n const tangent = contact.tangent;\n const aToContact = point.sub(bodyA.globalPos);\n const bToContact = point.sub(bodyB.globalPos);\n const aToContactNormal = aToContact.cross(normal);\n const bToContactNormal = bToContact.cross(normal);\n const normalMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactNormal * aToContactNormal + bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = aToContact.cross(tangent);\n const bToContactTangent = bToContact.cross(tangent);\n const tangentMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactTangent * aToContactTangent + bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n // Preserve normal/tangent impulse by re-using the contact point if it's close\n if (contactPoints[pointIndex] && ((_c = (_b = contactPoints[pointIndex]) === null || _b === void 0 ? void 0 : _b.point) === null || _c === void 0 ? void 0 : _c.squareDistance(point)) < 4) {\n contactPoints[pointIndex].point = point;\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\n } else // new contact if it's not close or doesn't exist\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\n // Update contact point calculations\n contactPoints[pointIndex].aToContact = aToContact;\n contactPoints[pointIndex].bToContact = bToContact;\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\n // Calculate relative velocity before solving to accurately do restitution\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\n if (relativeVelocity < -0.1) contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\n pointIndex++;\n }\n this.idToContactConstraint.set(contact.id, contactPoints);\n }\n // Clean up any contacts that did not occur last frame\n for (const id of finishedContactIds)this.idToContactConstraint.delete(id);\n // Warm contacts with accumulated impulse\n // Useful for tall stacks\n if (this.config.warmStart) this.warmStart(contacts);\n else for (const contact of contacts){\n const contactPoints = this.getContactConstraints(contact.id);\n for (const point of contactPoints){\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n postSolve(contacts) {\n for (const contact of contacts){\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip post solve for active+passive collisions\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n // Update motion values for sleeping\n bodyA.updateMotion();\n bodyB.updateMotion();\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderA.events.emit(\"aftercollisionresolve\", new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n contact.colliderB.events.emit(\"aftercollisionresolve\", new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n }\n // Store contacts\n this.lastFrameContacts.clear();\n for (const c of contacts)this.lastFrameContacts.set(c.id, c);\n }\n /**\n * Warm up body's based on previous frame contact points\n * @param contacts\n */ warmStart(contacts) {\n var _a, _b, _c;\n for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const contactPoints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of contactPoints)if (this.config.warmStart) {\n const normalImpulse = contact.normal.scale(point.normalImpulse);\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\n const impulse = normalImpulse.add(tangentImpulse);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n } else {\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n }\n /**\n * Iteratively solve the position overlap constraint\n * @param contacts\n */ solvePosition(contacts) {\n var _a, _b, _c;\n for(let i = 0; i < this.config.positionIterations; i++)for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of constraints){\n const normal = contact.normal;\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\n const steeringConstant = this.config.steeringFactor; //0.2;\n const maxCorrection = -5;\n const slop = this.config.slop; //1;\n // Clamp to avoid over-correction\n // Remember that we are shooting for 0 overlap in the end\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\n const impulse = normal.scale(-steeringForce * point.normalMass);\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\n // We adjust position and rotation instead of doing the velocity\n if (bodyA.collisionType === CollisionType.Active) {\n // TODO make applyPseudoImpulse function?\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) impulseForce.x = 0;\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) impulseForce.y = 0;\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\n }\n if (bodyB.collisionType === CollisionType.Active) {\n const impulseForce = impulse.scale(bodyB.inverseMass);\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) impulseForce.x = 0;\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) impulseForce.y = 0;\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\n }\n }\n }\n }\n }\n solveVelocity(contacts) {\n var _a, _b, _c;\n for(let i = 0; i < this.config.velocityIterations; i++)for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n const friction = Math.min(bodyA.friction, bodyB.friction);\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n // Friction constraint\n for (const point of constraints){\n const relativeVelocity = point.getRelativeVelocity();\n // Negate velocity in tangent direction to simulate friction\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\n let impulseDelta = tangentVelocity * point.tangentMass;\n // Clamping based in Erin Catto's GDC 2006 talk\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\n // But deltas can vary\n const maxFriction = friction * point.normalImpulse;\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\n impulseDelta = newImpulse - point.tangentImpulse;\n point.tangentImpulse = newImpulse;\n const impulse = contact.tangent.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n // Bounce constraint\n for (const point of constraints){\n // Need to recalc relative velocity because the previous step could have changed vel\n const relativeVelocity = point.getRelativeVelocity();\n // Compute impulse in normal direction\n const normalVelocity = relativeVelocity.dot(contact.normal);\n // Per Erin it is a mistake to apply the restitution inside the iteration\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\n // Clamping based in Erin Catto's GDC 2014 talk\n // Accumulated impulse stored in the contact is always positive (dV > 0)\n // But deltas can be negative\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\n impulseDelta = newImpulse - point.normalImpulse;\n point.normalImpulse = newImpulse;\n const impulse = contact.normal.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n }\n }\n }\n }\n class CollisionSystem extends System {\n get _processor() {\n return this._physics.collisionProcessor;\n }\n constructor(world, _physics){\n super();\n this._physics = _physics;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._configDirty = false;\n this._lastFrameContacts = new Map();\n this._currentFrameContacts = new Map();\n this._arcadeSolver = new ArcadeSolver(_physics.config.arcade);\n this._realisticSolver = new RealisticSolver(_physics.config.realistic);\n this._physics.$configUpdate.subscribe(()=>this._configDirty = true);\n this._trackCollider = (c)=>this._processor.track(c);\n this._untrackCollider = (c)=>this._processor.untrack(c);\n this.query = world.query([\n TransformComponent,\n MotionComponent,\n ColliderComponent\n ]);\n this.query.entityAdded$.subscribe((e)=>{\n const colliderComponent = e.get(ColliderComponent);\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\n const collider = colliderComponent.get();\n if (collider) this._processor.track(collider);\n });\n this.query.entityRemoved$.subscribe((e)=>{\n const colliderComponent = e.get(ColliderComponent);\n const collider = colliderComponent.get();\n if (colliderComponent && collider) this._processor.untrack(collider);\n });\n }\n initialize(world, scene) {\n this._engine = scene.engine;\n }\n update(elapsedMs) {\n var _a, _b, _c, _d;\n if (!this._physics.config.enabled) return;\n // Collect up all the colliders and update them\n let colliders = [];\n for (const entity of this.query.entities){\n const colliderComp = entity.get(ColliderComponent);\n const collider = colliderComp === null || colliderComp === void 0 ? void 0 : colliderComp.get();\n if (colliderComp && ((_a = colliderComp.owner) === null || _a === void 0 ? void 0 : _a.active) && collider) {\n colliderComp.update();\n if (collider instanceof CompositeCollider) {\n const compositeColliders = collider.getColliders();\n if (!collider.compositeStrategy) collider.compositeStrategy = this._physics.config.colliders.compositeStrategy;\n colliders = colliders.concat(compositeColliders);\n } else colliders.push(collider);\n }\n }\n // Update the spatial partitioning data structures\n // TODO if collider invalid it will break the processor\n // TODO rename \"update\" to something more specific\n this._processor.update(colliders);\n // Run broadphase on all colliders and locates potential collisions\n const pairs = this._processor.broadphase(colliders, elapsedMs);\n this._currentFrameContacts.clear();\n // Given possible pairs find actual contacts\n let contacts = this._processor.narrowphase(pairs, (_d = (_c = (_b = this._engine) === null || _b === void 0 ? void 0 : _b.debug) === null || _c === void 0 ? void 0 : _c.stats) === null || _d === void 0 ? void 0 : _d.currFrame);\n const solver = this.getSolver();\n // Solve, this resolves the position/velocity so entities aren't overlapping\n contacts = solver.solve(contacts);\n // Record contacts for start/end\n for (const contact of contacts){\n if (contact.isCanceled()) continue;\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\n const index = contact.id.indexOf(\"|\");\n if (index > 0) {\n const compositeId = contact.id.substring(index + 1);\n this._currentFrameContacts.set(compositeId, contact);\n } else this._currentFrameContacts.set(contact.id, contact);\n }\n // Emit contact start/end events\n this.runContactStartEnd();\n // reset the last frame cache\n this._lastFrameContacts.clear();\n // Keep track of collisions contacts that have started or ended\n this._lastFrameContacts = new Map(this._currentFrameContacts);\n // Process deferred collider removals\n for (const entity of this.query.entities){\n const collider = entity.get(ColliderComponent);\n if (collider) collider.processColliderRemoval();\n }\n }\n getSolver() {\n if (this._configDirty) {\n this._configDirty = false;\n this._arcadeSolver = new ArcadeSolver(this._physics.config.arcade);\n this._realisticSolver = new RealisticSolver(this._physics.config.realistic);\n }\n return this._physics.config.solver === SolverStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\n }\n debug(ex) {\n this._processor.debug(ex);\n }\n runContactStartEnd() {\n // If composite colliders are 'together' collisions may have a duplicate id because we want to treat those as a singular start/end\n for (const [id, c] of this._currentFrameContacts)// find all new contacts\n if (!this._lastFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n const side = Side.fromDirection(c.mtv);\n const opposite = Side.getOpposite(side);\n colliderA.events.emit(\"collisionstart\", new CollisionStartEvent(colliderA, colliderB, side, c));\n colliderA.events.emit(\"contactstart\", new ContactStartEvent(colliderA, colliderB, side, c));\n colliderB.events.emit(\"collisionstart\", new CollisionStartEvent(colliderB, colliderA, opposite, c));\n colliderB.events.emit(\"contactstart\", new ContactStartEvent(colliderB, colliderA, opposite, c));\n }\n // find all contacts that have ceased\n for (const [id, c] of this._lastFrameContacts)if (!this._currentFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n const side = Side.fromDirection(c.mtv);\n const opposite = Side.getOpposite(side);\n colliderA.events.emit(\"collisionend\", new CollisionEndEvent(colliderA, colliderB, side, c));\n colliderA.events.emit(\"contactend\", new ContactEndEvent(colliderA, colliderB, side, c));\n colliderB.events.emit(\"collisionend\", new CollisionEndEvent(colliderB, colliderA, opposite, c));\n colliderB.events.emit(\"contactend\", new ContactEndEvent(colliderB, colliderA, opposite, c));\n }\n }\n }\n var AnimationDirection;\n (function(AnimationDirection) {\n /**\n * Animation is playing forwards\n */ AnimationDirection[\"Forward\"] = \"forward\";\n /**\n * Animation is playing backwards\n */ AnimationDirection[\"Backward\"] = \"backward\";\n })(AnimationDirection || (AnimationDirection = {}));\n var AnimationStrategy;\n (function(AnimationStrategy) {\n /**\n * Animation ends without displaying anything\n */ AnimationStrategy[\"End\"] = \"end\";\n /**\n * Animation loops to the first frame after the last frame\n */ AnimationStrategy[\"Loop\"] = \"loop\";\n /**\n * Animation plays to the last frame, then backwards to the first frame, then repeats\n */ AnimationStrategy[\"PingPong\"] = \"pingpong\";\n /**\n * Animation ends stopping on the last frame\n */ AnimationStrategy[\"Freeze\"] = \"freeze\";\n })(AnimationStrategy || (AnimationStrategy = {}));\n const AnimationEvents = {\n Frame: \"frame\",\n Loop: \"loop\",\n End: \"end\"\n };\n /**\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\n *\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\n */ class Animation extends Graphic {\n constructor(options){\n var _a, _b, _c;\n super(options);\n this.events = new EventEmitter();\n this.frames = [];\n this.strategy = AnimationStrategy.Loop;\n this.frameDuration = 100;\n this._idempotencyToken = -1;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = 0;\n this._pingPongDirection = 1;\n this._done = false;\n this._playing = true;\n this._speed = 1;\n this._reversed = false;\n this.frames = options.frames;\n this.speed = (_a = options.speed) !== null && _a !== void 0 ? _a : this.speed;\n this.strategy = (_b = options.strategy) !== null && _b !== void 0 ? _b : this.strategy;\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : (_c = options.frameDuration) !== null && _c !== void 0 ? _c : this.frameDuration;\n if (options.reverse) this.reverse();\n this.goToFrame(0);\n }\n clone() {\n return new Animation({\n frames: this.frames.map((f)=>({\n ...f\n })),\n frameDuration: this.frameDuration,\n speed: this.speed,\n reverse: this._reversed,\n strategy: this.strategy,\n ...this.cloneGraphicOptions()\n });\n }\n get width() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) return Math.abs(maybeFrame.graphic.width * this.scale.x);\n return 0;\n }\n get height() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) return Math.abs(maybeFrame.graphic.height * this.scale.y);\n return 0;\n }\n /**\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\n * and optional [[AnimationStrategy]]\n *\n * Example:\n * ```typescript\n * const spriteSheet = SpriteSheet.fromImageSource({...});\n *\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\n * ```\n * @param spriteSheet\n * @param frameIndices\n * @param durationPerFrameMs\n * @param strategy\n */ static fromSpriteSheet(spriteSheet, frameIndices, durationPerFrameMs, strategy = AnimationStrategy.Loop) {\n const maxIndex = spriteSheet.sprites.length - 1;\n const invalidIndices = frameIndices.filter((index)=>index < 0 || index > maxIndex);\n if (invalidIndices.length) Animation._LOGGER.warn(`Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(\",\")} no frame will be shown`);\n return new Animation({\n frames: spriteSheet.sprites.filter((_, index)=>frameIndices.indexOf(index) > -1).map((f)=>({\n graphic: f,\n duration: durationPerFrameMs\n })),\n strategy: strategy\n });\n }\n /**\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\n *\n * Example:\n * ```typescript\n * const spriteSheet = SpriteSheet.fromImageSource({...});\n *\n * const anim = Animation.fromSpriteSheetCoordinates({\n * spriteSheet,\n * frameCoordinates: [\n * {x: 0, y: 5, duration: 100, options { flipHorizontal: true }},\n * {x: 1, y: 5, duration: 200},\n * {x: 2, y: 5, duration: 100},\n * {x: 3, y: 5, duration: 500}\n * ],\n * strategy: AnimationStrategy.PingPong\n * });\n * ```\n * @param options\n * @returns Animation\n */ static fromSpriteSheetCoordinates(options) {\n const { spriteSheet: spriteSheet, frameCoordinates: frameCoordinates, durationPerFrameMs: durationPerFrameMs, speed: speed, strategy: strategy, reverse: reverse } = options;\n const defaultDuration = durationPerFrameMs !== null && durationPerFrameMs !== void 0 ? durationPerFrameMs : 100;\n const frames = [];\n for (const coord of frameCoordinates){\n const { x: x, y: y, duration: duration, options: options } = coord;\n const sprite = spriteSheet.getSprite(x, y, options);\n if (sprite) frames.push({\n graphic: sprite,\n duration: duration !== null && duration !== void 0 ? duration : defaultDuration\n });\n else Animation._LOGGER.warn(`Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`);\n }\n return new Animation({\n frames: frames,\n strategy: strategy,\n speed: speed,\n reverse: reverse\n });\n }\n /**\n * Current animation speed\n *\n * 1 meaning normal 1x speed.\n * 2 meaning 2x speed and so on.\n */ get speed() {\n return this._speed;\n }\n /**\n * Current animation speed\n *\n * 1 meaning normal 1x speed.\n * 2 meaning 2x speed and so on.\n */ set speed(val) {\n this._speed = clamp(Math.abs(val), 0, Infinity);\n }\n /**\n * Returns the current Frame of the animation\n *\n * Use [[Animation.currentFrameIndex]] to get the frame number and\n * [[Animation.goToFrame]] to set the current frame index\n */ get currentFrame() {\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) return this.frames[this._currentFrame];\n return null;\n }\n /**\n * Returns the current frame index of the animation\n *\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\n */ get currentFrameIndex() {\n return this._currentFrame;\n }\n /**\n * Returns the amount of time in milliseconds left in the current frame\n */ get currentFrameTimeLeft() {\n return this._timeLeftInFrame;\n }\n /**\n * Returns `true` if the animation is playing\n */ get isPlaying() {\n return this._playing;\n }\n /**\n * Reverses the play direction of the Animation, this preserves the current frame\n */ reverse() {\n // Don't mutate with the original frame list, create a copy\n this.frames = this.frames.slice().reverse();\n this._reversed = !this._reversed;\n }\n /**\n * Returns the current play direction of the animation\n */ get direction() {\n // Keep logically consistent with ping-pong direction\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\n const reversed = this._reversed && this._pingPongDirection === 1 ? true : false;\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\n }\n /**\n * Plays or resumes the animation from the current frame\n */ play() {\n this._playing = true;\n }\n /**\n * Pauses the animation on the current frame\n */ pause() {\n this._playing = false;\n this._firstTick = true; // firstTick must be set to emit the proper frame event\n }\n /**\n * Reset the animation back to the beginning, including if the animation were done\n */ reset() {\n this._done = false;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame) this._timeLeftInFrame = (maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration;\n }\n /**\n * Returns `true` if the animation can end\n */ get canFinish() {\n switch(this.strategy){\n case AnimationStrategy.End:\n case AnimationStrategy.Freeze:\n return true;\n default:\n return false;\n }\n }\n /**\n * Returns `true` if the animation is done, for looping type animations\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\n *\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\n */ get done() {\n return this._done;\n }\n /**\n * Jump the animation immediately to a specific frame if it exists\n *\n * Optionally specify an override for the duration of the frame, useful for\n * keeping multiple animations in sync with one another.\n * @param frameNumber\n * @param duration\n */ goToFrame(frameNumber, duration) {\n this._currentFrame = frameNumber;\n this._timeLeftInFrame = duration !== null && duration !== void 0 ? duration : this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame && !this._done) {\n this._timeLeftInFrame = duration !== null && duration !== void 0 ? duration : (maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration;\n this.events.emit(\"frame\", {\n ...maybeFrame,\n frameIndex: this.currentFrameIndex\n });\n }\n }\n _nextFrame() {\n const currentFrame = this._currentFrame;\n if (this._done) return currentFrame;\n let next = -1;\n switch(this.strategy){\n case AnimationStrategy.Loop:\n next = (currentFrame + 1) % this.frames.length;\n if (next === 0) this.events.emit(\"loop\", this);\n break;\n case AnimationStrategy.End:\n next = currentFrame + 1;\n if (next >= this.frames.length) {\n this._done = true;\n this._currentFrame = this.frames.length;\n this.events.emit(\"end\", this);\n }\n break;\n case AnimationStrategy.Freeze:\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\n if (next >= this.frames.length - 1) {\n this._done = true;\n this.events.emit(\"end\", this);\n }\n break;\n case AnimationStrategy.PingPong:\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\n this._pingPongDirection = -1;\n this.events.emit(\"loop\", this);\n }\n if (currentFrame + this._pingPongDirection < 0) {\n this._pingPongDirection = 1;\n this.events.emit(\"loop\", this);\n }\n next = currentFrame + this._pingPongDirection % this.frames.length;\n break;\n }\n return next;\n }\n /**\n * Called internally by Excalibur to update the state of the animation potential update the current frame\n * @param elapsedMilliseconds Milliseconds elapsed\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\n */ tick(elapsedMilliseconds, idempotencyToken = 0) {\n if (this._idempotencyToken === idempotencyToken) return;\n this._idempotencyToken = idempotencyToken;\n if (!this._playing) return;\n // if it's the first frame emit frame event\n if (this._firstTick) {\n this._firstTick = false;\n this.events.emit(\"frame\", {\n ...this.currentFrame,\n frameIndex: this.currentFrameIndex\n });\n }\n this._timeLeftInFrame -= elapsedMilliseconds * this._speed;\n if (this._timeLeftInFrame <= 0) this.goToFrame(this._nextFrame());\n }\n _drawImage(ctx, x, y) {\n if (this.currentFrame) this.currentFrame.graphic.draw(ctx, x, y);\n }\n }\n Animation._LOGGER = Logger.getInstance();\n class GraphicsGroup extends Graphic {\n constructor(options){\n super(options);\n this._logger = Logger.getInstance();\n this.members = [];\n this.members = options.members;\n this._updateDimensions();\n }\n clone() {\n return new GraphicsGroup({\n members: [\n ...this.members\n ],\n ...this.cloneGraphicOptions()\n });\n }\n _updateDimensions() {\n const bb = this.localBounds;\n this.width = bb.width;\n this.height = bb.height;\n return bb;\n }\n get localBounds() {\n let bb = new BoundingBox();\n for (const member of this.members)if (member instanceof Graphic) bb = member.localBounds.combine(bb);\n else {\n const { graphic: graphic, offset: pos, useBounds: useBounds } = member;\n const shouldUseBounds = useBounds === undefined ? true : useBounds;\n if (graphic) {\n if (shouldUseBounds) bb = graphic.localBounds.translate(pos).combine(bb);\n } else this._logger.warnOnce(`Graphics group member has an null or undefined graphic, member definition: ${JSON.stringify(member)}.`);\n }\n return bb;\n }\n _isAnimationOrGroup(graphic) {\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\n }\n tick(elapsedMilliseconds, idempotencyToken) {\n for (const member of this.members){\n let graphic;\n if (member instanceof Graphic) graphic = member;\n else graphic = member.graphic;\n if (this._isAnimationOrGroup(graphic)) graphic.tick(elapsedMilliseconds, idempotencyToken);\n }\n }\n reset() {\n for (const member of this.members){\n let graphic;\n if (member instanceof Graphic) graphic = member;\n else graphic = member.graphic;\n if (this._isAnimationOrGroup(graphic)) graphic.reset();\n }\n }\n _preDraw(ex, x, y) {\n this._updateDimensions();\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n const pos = Vector.Zero;\n for (const member of this.members){\n let graphic;\n if (member instanceof Graphic) graphic = member;\n else {\n graphic = member.graphic;\n member.offset.clone(pos);\n }\n if (!graphic) continue;\n ex.save();\n ex.translate(x, y);\n graphic.draw(ex, pos.x, pos.y);\n if (this.showDebug) /* istanbul ignore next */ ex.debug.drawRect(0, 0, this.width, this.height);\n ex.restore();\n }\n }\n }\n /**\n * Configurable helper extends base type and makes all properties available as option bag arguments\n * @internal\n * @param base\n */ function Configurable(base) {\n return class extends base {\n assign(props) {\n //set the value of every property that was passed in,\n //if the constructor previously set this value, it will be overridden here\n for(const k in props)// eslint-disable-next-line\n if (typeof this[k] !== \"function\") // eslint-disable-next-line\n this[k] = props[k];\n }\n constructor(...args){\n super(...args);\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\n //of whatever ctor is the implementation, so args.length doesn't work here.\n const size = args.filter(function(value) {\n return value !== undefined;\n }).length;\n if (size === 1 && args[0] && typeof args[0] === \"object\" && !(args[0] instanceof Array)) this.assign(args[0]);\n }\n };\n }\n /**\n * An enum that represents the types of emitter nozzles\n */ var EmitterType;\n (function(EmitterType) {\n /**\n * Constant for the circular emitter type\n */ EmitterType[EmitterType[\"Circle\"] = 0] = \"Circle\";\n /**\n * Constant for the rectangular emitter type\n */ EmitterType[EmitterType[\"Rectangle\"] = 1] = \"Rectangle\";\n })(EmitterType || (EmitterType = {}));\n /**\n * @hidden\n */ class ParticleImpl extends Entity {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite){\n super();\n this.position = new Vector(0, 0);\n this.velocity = new Vector(0, 0);\n this.acceleration = new Vector(0, 0);\n this.particleRotationalVelocity = 0;\n this.currentRotation = 0;\n this.focus = null;\n this.focusAccel = 0;\n this.opacity = 1;\n this.beginColor = Color.White;\n this.endColor = Color.White;\n // Life is counted in ms\n this.life = 300;\n this.fadeFlag = false;\n // Color transitions\n this._rRate = 1;\n this._gRate = 1;\n this._bRate = 1;\n this._aRate = 0;\n this._currentColor = Color.White;\n this.emitter = null;\n this.particleSize = 5;\n this.particleSprite = null;\n this.sizeRate = 0;\n this.elapsedMultiplier = 0;\n this.visible = true;\n this.isOffscreen = false;\n let emitter = emitterOrConfig;\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\n const config = emitterOrConfig;\n emitter = config.emitter;\n life = config.life;\n opacity = config.opacity;\n endColor = config.endColor;\n beginColor = config.beginColor;\n position = config.position;\n velocity = config.velocity;\n acceleration = config.acceleration;\n startSize = config.startSize;\n endSize = config.endSize;\n particleSprite = config.particleSprite;\n }\n this.emitter = emitter;\n this.life = life || this.life;\n this.opacity = opacity || this.opacity;\n this.endColor = endColor || this.endColor.clone();\n this.beginColor = beginColor || this.beginColor.clone();\n this._currentColor = this.beginColor.clone();\n this.particleSprite = particleSprite;\n if (this.emitter.particleTransform === ParticleTransform.Global) {\n const globalPos = this.emitter.transform.globalPos;\n this.position = (position || this.position).add(globalPos);\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\n } else {\n this.velocity = velocity || this.velocity;\n this.position = position || this.position;\n }\n this.acceleration = acceleration || this.acceleration;\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\n this._aRate = this.opacity / this.life;\n this.startSize = startSize || 0;\n this.endSize = endSize || 0;\n if (this.endSize > 0 && this.startSize > 0) {\n this.sizeRate = (this.endSize - this.startSize) / this.life;\n this.particleSize = this.startSize;\n }\n this.addComponent(this.transform = new TransformComponent());\n this.addComponent(this.graphics = new GraphicsComponent());\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // TODO wut\n if (this.particleSprite) {\n this.graphics.opacity = this.opacity;\n this.graphics.use(this.particleSprite);\n } else {\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\n this.graphics.onPostDraw = (ctx)=>{\n ctx.save();\n this.graphics.opacity = this.opacity;\n const tmpColor = this._currentColor.clone();\n tmpColor.a = 1;\n ctx.debug.drawPoint(vec(0, 0), {\n color: tmpColor,\n size: this.particleSize\n });\n ctx.restore();\n };\n }\n }\n kill() {\n this.emitter.removeParticle(this);\n }\n update(engine, delta) {\n this.life = this.life - delta;\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\n if (this.life < 0) this.kill();\n if (this.fadeFlag) this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\n if (this.startSize > 0 && this.endSize > 0) this.particleSize = clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize));\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\n if (this.focus) {\n const accel = this.focus.sub(this.position).normalize().scale(this.focusAccel).scale(delta / 1000);\n this.velocity = this.velocity.add(accel);\n } else this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\n this.position = this.position.add(this.velocity.scale(delta / 1000));\n if (this.particleRotationalVelocity) this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI);\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // todo wut\n this.graphics.opacity = this.opacity;\n }\n }\n /**\n * Particle is used in a [[ParticleEmitter]]\n */ class Particle extends Configurable(ParticleImpl) {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite){\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite);\n }\n }\n var ParticleTransform;\n (function(ParticleTransform) {\n /**\n * [[ParticleTransform.Global]] is the default and emits particles as if\n * they were world space objects, useful for most effects.\n */ ParticleTransform[\"Global\"] = \"global\";\n /**\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\n * as they would in a parent/child actor relationship.\n */ ParticleTransform[\"Local\"] = \"local\";\n })(ParticleTransform || (ParticleTransform = {}));\n /**\n * Using a particle emitter is a great way to create interesting effects\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\n * extend [[Actor]] allowing you to use all of the features that come with.\n */ class ParticleEmitter extends Actor {\n /**\n * Gets the opacity of each particle from 0 to 1.0\n */ get opacity() {\n return this.graphics.opacity;\n }\n /**\n * Gets the opacity of each particle from 0 to 1.0\n */ set opacity(opacity) {\n this.graphics.opacity = opacity;\n }\n /**\n * Gets or sets the sprite that a particle should use\n */ get particleSprite() {\n return this._sprite;\n }\n set particleSprite(val) {\n if (val) this._sprite = val;\n }\n /**\n * @param config particle emitter options bag\n */ constructor(config){\n var _a, _b;\n super({\n width: (_a = config.width) !== null && _a !== void 0 ? _a : 0,\n height: (_b = config.height) !== null && _b !== void 0 ? _b : 0\n });\n this._particlesToEmit = 0;\n this.numParticles = 0;\n /**\n * Gets or sets the isEmitting flag\n */ this.isEmitting = true;\n /**\n * Gets or sets the backing particle collection\n */ this.particles = [];\n /**\n * Gets or sets the backing deadParticle collection\n */ this.deadParticles = [];\n /**\n * Gets or sets the minimum particle velocity\n */ this.minVel = 0;\n /**\n * Gets or sets the maximum particle velocity\n */ this.maxVel = 0;\n /**\n * Gets or sets the acceleration vector for all particles\n */ this.acceleration = new Vector(0, 0);\n /**\n * Gets or sets the minimum angle in radians\n */ this.minAngle = 0;\n /**\n * Gets or sets the maximum angle in radians\n */ this.maxAngle = 0;\n /**\n * Gets or sets the emission rate for particles (particles/sec)\n */ this.emitRate = 1; //particles/sec\n /**\n * Gets or sets the life of each particle in milliseconds\n */ this.particleLife = 2000;\n /**\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\n */ this.fadeFlag = false;\n /**\n * Gets or sets the optional focus where all particles should accelerate towards\n */ this.focus = null;\n /**\n * Gets or sets the acceleration for focusing particles if a focus has been specified\n */ this.focusAccel = null;\n /**\n * Gets or sets the optional starting size for the particles\n */ this.startSize = null;\n /**\n * Gets or sets the optional ending size for the particles\n */ this.endSize = null;\n /**\n * Gets or sets the minimum size of all particles\n */ this.minSize = 5;\n /**\n * Gets or sets the maximum size of all particles\n */ this.maxSize = 5;\n /**\n * Gets or sets the beginning color of all particles\n */ this.beginColor = Color.White;\n /**\n * Gets or sets the ending color of all particles\n */ this.endColor = Color.White;\n this._sprite = null;\n /**\n * Gets or sets the emitter type for the particle emitter\n */ this.emitterType = EmitterType.Rectangle;\n /**\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\n */ this.radius = 0;\n /**\n * Gets or sets the particle rotational speed velocity\n */ this.particleRotationalVelocity = 0;\n /**\n * Indicates whether particles should start with a random rotation\n */ this.randomRotation = false;\n /**\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\n * they were world space objects, useful for most effects.\n *\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\n * as they would in a parent/child actor relationship.\n */ this.particleTransform = ParticleTransform.Global;\n const { x: x, y: y, pos: pos, isEmitting: isEmitting, minVel: minVel, maxVel: maxVel, acceleration: acceleration, minAngle: minAngle, maxAngle: maxAngle, emitRate: emitRate, particleLife: particleLife, opacity: opacity, fadeFlag: fadeFlag, focus: focus, focusAccel: focusAccel, startSize: startSize, endSize: endSize, minSize: minSize, maxSize: maxSize, beginColor: beginColor, endColor: endColor, particleSprite: particleSprite, emitterType: emitterType, radius: radius, particleRotationalVelocity: particleRotationalVelocity, particleTransform: particleTransform, randomRotation: randomRotation, random: random } = {\n ...config\n };\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.isEmitting = isEmitting !== null && isEmitting !== void 0 ? isEmitting : this.isEmitting;\n this.minVel = minVel !== null && minVel !== void 0 ? minVel : this.minVel;\n this.maxVel = maxVel !== null && maxVel !== void 0 ? maxVel : this.maxVel;\n this.acceleration = acceleration !== null && acceleration !== void 0 ? acceleration : this.acceleration;\n this.minAngle = minAngle !== null && minAngle !== void 0 ? minAngle : this.minAngle;\n this.maxAngle = maxAngle !== null && maxAngle !== void 0 ? maxAngle : this.maxAngle;\n this.emitRate = emitRate !== null && emitRate !== void 0 ? emitRate : this.emitRate;\n this.particleLife = particleLife !== null && particleLife !== void 0 ? particleLife : this.particleLife;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.fadeFlag = fadeFlag !== null && fadeFlag !== void 0 ? fadeFlag : this.fadeFlag;\n this.focus = focus !== null && focus !== void 0 ? focus : this.focus;\n this.focusAccel = focusAccel !== null && focusAccel !== void 0 ? focusAccel : this.focusAccel;\n this.startSize = startSize !== null && startSize !== void 0 ? startSize : this.startSize;\n this.endSize = endSize !== null && endSize !== void 0 ? endSize : this.endSize;\n this.minSize = minSize !== null && minSize !== void 0 ? minSize : this.minSize;\n this.maxSize = maxSize !== null && maxSize !== void 0 ? maxSize : this.maxSize;\n this.beginColor = beginColor !== null && beginColor !== void 0 ? beginColor : this.beginColor;\n this.endColor = endColor !== null && endColor !== void 0 ? endColor : this.endColor;\n this.particleSprite = particleSprite !== null && particleSprite !== void 0 ? particleSprite : this.particleSprite;\n this.emitterType = emitterType !== null && emitterType !== void 0 ? emitterType : this.emitterType;\n this.radius = radius !== null && radius !== void 0 ? radius : this.radius;\n this.particleRotationalVelocity = particleRotationalVelocity !== null && particleRotationalVelocity !== void 0 ? particleRotationalVelocity : this.particleRotationalVelocity;\n this.randomRotation = randomRotation !== null && randomRotation !== void 0 ? randomRotation : this.randomRotation;\n this.particleTransform = particleTransform !== null && particleTransform !== void 0 ? particleTransform : this.particleTransform;\n this.body.collisionType = CollisionType.PreventCollision;\n this.random = random !== null && random !== void 0 ? random : new Random();\n }\n removeParticle(particle) {\n this.deadParticles.push(particle);\n }\n /**\n * Causes the emitter to emit particles\n * @param particleCount Number of particles to emit right now\n */ emitParticles(particleCount) {\n var _a;\n for(let i = 0; i < particleCount; i++){\n const p = this._createParticle();\n this.particles.push(p);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\n if (this.particleTransform === ParticleTransform.Global) this.scene.world.add(p);\n else this.addChild(p);\n }\n }\n }\n clearParticles() {\n this.particles.length = 0;\n }\n // Creates a new particle given the constraints of the emitter\n _createParticle() {\n // todo implement emitter constraints;\n let ranX = 0;\n let ranY = 0;\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\n const dx = vel * Math.cos(angle);\n const dy = vel * Math.sin(angle);\n if (this.emitterType === EmitterType.Rectangle) {\n ranX = randomInRange(0, this.width, this.random);\n ranY = randomInRange(0, this.height, this.random);\n } else if (this.emitterType === EmitterType.Circle) {\n const radius = randomInRange(0, this.radius, this.random);\n ranX = radius * Math.cos(angle);\n ranY = radius * Math.sin(angle);\n }\n const p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new Vector(ranX, ranY), new Vector(dx, dy), this.acceleration, this.startSize, this.endSize, this.particleSprite);\n p.fadeFlag = this.fadeFlag;\n p.particleSize = size;\n p.particleRotationalVelocity = this.particleRotationalVelocity;\n if (this.randomRotation) p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\n if (this.focus) {\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\n p.focusAccel = this.focusAccel;\n }\n return p;\n }\n update(engine, delta) {\n var _a;\n super.update(engine, delta);\n if (this.isEmitting) {\n this._particlesToEmit += this.emitRate * (delta / 1000);\n if (this._particlesToEmit > 1.0) {\n this.emitParticles(Math.floor(this._particlesToEmit));\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\n }\n }\n // deferred removal\n for(let i = 0; i < this.deadParticles.length; i++){\n removeItemFromArray(this.deadParticles[i], this.particles);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) this.scene.world.remove(this.deadParticles[i], false);\n }\n this.deadParticles.length = 0;\n }\n }\n /**\n * Blend 2 transforms for interpolation, will interpolate from the context of newTx's parent if it exists\n */ function blendTransform(oldTx, newTx, blend, target) {\n if (oldTx.parent !== newTx.parent) {\n // Caller expects a local transform\n // Adjust old tx to be local to the new parent whatever that is\n const oldTxWithNewParent = oldTx.clone();\n const oldGlobalPos = oldTx.globalPos.clone();\n const oldGlobalScale = oldTx.globalScale.clone();\n const oldGlobalRotation = oldTx.globalRotation;\n oldTxWithNewParent.parent = newTx.parent;\n oldTxWithNewParent.globalPos = oldGlobalPos;\n oldTxWithNewParent.globalScale = oldGlobalScale;\n oldTxWithNewParent.globalRotation = oldGlobalRotation;\n oldTx = oldTxWithNewParent;\n }\n let interpolatedPos = newTx.pos;\n let interpolatedScale = newTx.scale;\n let interpolatedRotation = newTx.rotation;\n interpolatedPos = newTx.pos.scale(blend).add(oldTx.pos.scale(1.0 - blend));\n interpolatedScale = newTx.scale.scale(blend).add(oldTx.scale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(oldTx.rotation) + blend * Math.cos(newTx.rotation);\n const sine = (1.0 - blend) * Math.sin(oldTx.rotation) + blend * Math.sin(newTx.rotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n const tx = target !== null && target !== void 0 ? target : new transform_Transform();\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\n return tx;\n }\n /**\n *\n */ function blendGlobalTransform(oldTx, newTx, blend, target) {\n let interpolatedPos = newTx.globalPos;\n let interpolatedScale = newTx.globalScale;\n let interpolatedRotation = newTx.globalRotation;\n interpolatedPos = newTx.globalPos.scale(blend).add(oldTx.globalPos.scale(1.0 - blend));\n interpolatedScale = newTx.globalScale.scale(blend).add(oldTx.globalScale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(oldTx.globalRotation) + blend * Math.cos(newTx.globalRotation);\n const sine = (1.0 - blend) * Math.sin(oldTx.globalRotation) + blend * Math.sin(newTx.globalRotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n const tx = target !== null && target !== void 0 ? target : new Transform();\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\n return tx;\n }\n // this import seems to bomb wallaby\n class GraphicsSystem extends System {\n get sortedTransforms() {\n return this._sortedTransforms;\n }\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Average;\n this._token = 0;\n this._sortedTransforms = [];\n this._zHasChanged = false;\n this._zIndexUpdate = ()=>{\n this._zHasChanged = true;\n };\n this._targetInterpolationTransform = new transform_Transform();\n this.query = this.world.query([\n TransformComponent,\n GraphicsComponent\n ]);\n this.query.entityAdded$.subscribe((e)=>{\n const tx = e.get(TransformComponent);\n this._sortedTransforms.push(tx);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n });\n this.query.entityRemoved$.subscribe((e)=>{\n const tx = e.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) this._sortedTransforms.splice(index, 1);\n });\n }\n initialize(world, scene) {\n this._camera = scene.camera;\n this._engine = scene.engine;\n }\n preupdate() {\n // Graphics context could be switched to fallback in a new frame\n this._graphicsContext = this._engine.graphicsContext;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b)=>{\n return a.z - b.z;\n });\n this._zHasChanged = false;\n }\n }\n update(delta) {\n this._token++;\n let graphics;\n FontCache.checkAndClearCache();\n // This is a performance enhancement, most things are in world space\n // so if we can only do this once saves a ton of transform updates\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n for (const transform of this._sortedTransforms){\n const entity = transform.owner;\n // If the entity is offscreen skip\n if (entity.hasTag(\"ex.offscreen\")) continue;\n graphics = entity.get(GraphicsComponent);\n // Exit if graphics set to not visible\n if (!graphics.visible) continue;\n // Optionally run the onPreTransformDraw graphics lifecycle draw\n if (graphics.onPreTransformDraw) graphics.onPreTransformDraw(this._graphicsContext, delta);\n entity.events.emit(\"pretransformdraw\", new PreTransformDrawEvent(this._graphicsContext, delta, entity));\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n if (transform.coordPlane === CoordPlane.Screen) this._graphicsContext.restore();\n this._graphicsContext.save();\n if (transform.coordPlane === CoordPlane.Screen) this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n // Tick any graphics state (but only once) for animations and graphics groups\n graphics.update(delta, this._token);\n // Apply parallax\n const parallax = entity.get(ParallaxComponent);\n if (parallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\n const parallaxOffset = this._camera.drawPos.scale(oneMinusFactor);\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\n }\n // Position the entity + estimate lag\n this._applyTransform(entity);\n // If there is a material enable it on the context\n if (graphics.material) this._graphicsContext.material = graphics.material;\n // Optionally run the onPreDraw graphics lifecycle draw\n if (graphics.onPreDraw) graphics.onPreDraw(this._graphicsContext, delta);\n entity.events.emit(\"predraw\", new PreDrawEvent(this._graphicsContext, delta, entity));\n // TODO remove this hack on the particle redo\n // Remove this line after removing the wallaby import\n const particleOpacity = entity instanceof Particle ? entity.opacity : 1;\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\n // Draw the graphics component\n this._drawGraphicsComponent(graphics, transform);\n // Optionally run the onPostDraw graphics lifecycle draw\n if (graphics.onPostDraw) graphics.onPostDraw(this._graphicsContext, delta);\n entity.events.emit(\"postdraw\", new PostDrawEvent(this._graphicsContext, delta, entity));\n this._graphicsContext.restore();\n // Reset the transform back to the original world space\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n }\n // Optionally run the onPreTransformDraw graphics lifecycle draw\n if (graphics.onPostTransformDraw) graphics.onPostTransformDraw(this._graphicsContext, delta);\n entity.events.emit(\"posttransformdraw\", new PostTransformDrawEvent(this._graphicsContext, delta, entity));\n }\n this._graphicsContext.restore();\n }\n _drawGraphicsComponent(graphicsComponent, transformComponent) {\n var _a, _b;\n if (graphicsComponent.visible) {\n const flipHorizontal = graphicsComponent.flipHorizontal;\n const flipVertical = graphicsComponent.flipVertical;\n const graphic = graphicsComponent.current;\n const options = (_a = graphicsComponent.currentOptions) !== null && _a !== void 0 ? _a : {};\n if (graphic) {\n let anchor = graphicsComponent.anchor;\n let offset = graphicsComponent.offset;\n let scaleX = 1;\n let scaleY = 1;\n // handle specific overrides\n if (options === null || options === void 0 ? void 0 : options.anchor) anchor = options.anchor;\n if (options === null || options === void 0 ? void 0 : options.offset) offset = options.offset;\n const globalScale = transformComponent.globalScale;\n scaleX *= graphic.scale.x * globalScale.x;\n scaleY *= graphic.scale.y * globalScale.y;\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\n const offsetX = -graphic.width * anchor.x + offset.x * scaleX;\n const offsetY = -graphic.height * anchor.y + offset.y * scaleY;\n const oldFlipHorizontal = graphic.flipHorizontal;\n const oldFlipVertical = graphic.flipVertical;\n if (flipHorizontal || flipVertical) {\n // flip any currently flipped graphics\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\n }\n graphic === null || graphic === void 0 || graphic.draw(this._graphicsContext, offsetX, offsetY);\n if (flipHorizontal || flipVertical) {\n graphic.flipHorizontal = oldFlipHorizontal;\n graphic.flipVertical = oldFlipVertical;\n }\n // TODO move debug code out?\n if (((_b = this._engine) === null || _b === void 0 ? void 0 : _b.isDebug) && this._engine.debug.graphics.showBounds) {\n const offset = vec(offsetX, offsetY);\n if (graphic instanceof GraphicsGroup) for (const member of graphic.members){\n let g;\n let pos = Vector.Zero;\n if (member instanceof Graphic) g = member;\n else {\n g = member.graphic;\n pos = member.offset;\n }\n g === null || g === void 0 || g.localBounds.translate(offset.add(pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n else /* istanbul ignore next */ graphic === null || graphic === void 0 || graphic.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n }\n }\n }\n /**\n * This applies the current entity transform to the graphics context\n * @param entity\n */ _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors){\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n const optionalBody = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(BodyComponent);\n let tx = transform.get();\n if (optionalBody) {\n if (this._engine.fixedUpdateFps && optionalBody.__oldTransformCaptured && optionalBody.enableFixedUpdateInterpolate) {\n // Interpolate graphics if needed\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n tx = blendTransform(optionalBody.oldTransform, transform.get(), blend, this._targetInterpolationTransform);\n }\n }\n if (transform) {\n this._graphicsContext.z = transform.z;\n this._graphicsContext.translate(tx.pos.x, tx.pos.y);\n this._graphicsContext.scale(tx.scale.x, tx.scale.y);\n this._graphicsContext.rotate(tx.rotation);\n }\n }\n }\n }\n class DebugSystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Lowest;\n this.query = this.world.query([\n TransformComponent\n ]);\n }\n initialize(world, scene) {\n this._graphicsContext = scene.engine.graphicsContext;\n this._camera = scene.camera;\n this._engine = scene.engine;\n this._collisionSystem = world.systemManager.get(CollisionSystem);\n }\n update() {\n var _a;\n if (!this._engine.isDebug) return;\n const filterSettings = this._engine.debug.filter;\n let id;\n let name;\n const entitySettings = this._engine.debug.entity;\n let tx;\n const txSettings = this._engine.debug.transform;\n let motion;\n const motionSettings = this._engine.debug.motion;\n let colliderComp;\n const colliderSettings = this._engine.debug.collider;\n const physicsSettings = this._engine.debug.physics;\n let graphics;\n const graphicsSettings = this._engine.debug.graphics;\n let debugDraw;\n let body;\n const bodySettings = this._engine.debug.body;\n const cameraSettings = this._engine.debug.camera;\n for (const entity of this.query.entities){\n if (entity.hasTag(\"offscreen\")) continue;\n if (entity instanceof Particle) continue;\n if (filterSettings.useFilter) {\n const allIds = filterSettings.ids.length === 0;\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\n if (!idMatch) continue;\n const allNames = filterSettings.nameQuery === \"\";\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\n if (!nameMatch) continue;\n }\n let cursor = Vector.Zero;\n const lineHeight = vec(0, 16);\n id = entity.id;\n name = entity.name;\n tx = entity.get(TransformComponent);\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n this._pushCameraTransform(tx);\n this._graphicsContext.save();\n if (tx.coordPlane === CoordPlane.Screen) this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n this._graphicsContext.z = txSettings.debugZIndex;\n this._applyTransform(entity);\n if (tx) {\n if (txSettings.showAll || txSettings.showPosition) this._graphicsContext.debug.drawPoint(Vector.Zero, {\n size: 4,\n color: txSettings.positionColor\n });\n if (txSettings.showAll || txSettings.showPositionLabel) {\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showZIndex) {\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showId) {\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? \"child of id(\" + ((_a = entity.parent) === null || _a === void 0 ? void 0 : _a.id) + \")\" : \"\"}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showName) {\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showRotation) {\n this._graphicsContext.drawLine(Vector.Zero, Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero), txSettings.rotationColor, 2);\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showScale) this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\n }\n graphics = entity.get(GraphicsComponent);\n if (graphics) {\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\n const bounds = graphics.localBounds;\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\n }\n }\n debugDraw = entity.get(DebugGraphicsComponent);\n if (debugDraw) {\n if (!debugDraw.useTransform) this._graphicsContext.restore();\n debugDraw.draw(this._graphicsContext, this._engine.debug);\n if (!debugDraw.useTransform) {\n this._graphicsContext.save();\n this._applyTransform(entity);\n }\n }\n body = entity.get(BodyComponent);\n if (body) {\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showCollisionType) {\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMass) {\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMotion) {\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showSleeping) {\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping : \"cant sleep\"})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n }\n this._graphicsContext.restore();\n // World space\n this._graphicsContext.save();\n if (tx.coordPlane === CoordPlane.Screen) this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n this._graphicsContext.z = txSettings.debugZIndex;\n motion = entity.get(MotionComponent);\n if (motion) {\n if (motionSettings.showAll || motionSettings.showVelocity) {\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\n cursor = cursor.add(lineHeight);\n }\n if (motionSettings.showAll || motionSettings.showAcceleration) this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\n }\n // Colliders live in world space already so after the restore()\n colliderComp = entity.get(ColliderComponent);\n if (colliderComp) {\n const collider = colliderComp.get();\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) collider.debug(this._graphicsContext, colliderSettings.geometryColor, {\n lineWidth: colliderSettings.geometryLineWidth,\n pointSize: colliderSettings.geometryPointSize\n });\n if (colliderSettings.showAll || colliderSettings.showBounds) {\n if (collider instanceof CompositeCollider) {\n const colliders = collider.getColliders();\n for (const collider of colliders){\n const bounds = collider.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, {\n color: colliderSettings.boundsColor\n });\n if (colliderSettings.showAll || colliderSettings.showOwner) this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\n }\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\n } else if (collider) {\n const bounds = colliderComp.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, {\n color: colliderSettings.boundsColor\n });\n if (colliderSettings.showAll || colliderSettings.showOwner) this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\n }\n }\n }\n this._graphicsContext.restore();\n this._popCameraTransform(tx);\n }\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) this._collisionSystem.debug(this._graphicsContext);\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts){\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) for (const point of contact.points)this._graphicsContext.debug.drawPoint(point, {\n size: physicsSettings.contactSize,\n color: physicsSettings.collisionContactColor\n });\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) for (const point of contact.points)this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\n color: physicsSettings.collisionNormalColor\n });\n }\n this._graphicsContext.restore();\n if (cameraSettings) {\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (cameraSettings.showAll || cameraSettings.showFocus) this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\n if (cameraSettings.showAll || cameraSettings.showZoom) this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\n this._graphicsContext.restore();\n }\n this._graphicsContext.flush();\n }\n postupdate(engine, elapsedMs) {\n if (this._engine.isDebug) {\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n Debug.flush(this._graphicsContext);\n this._graphicsContext.restore();\n }\n }\n /**\n * This applies the current entity transform to the graphics context\n * @param entity\n */ _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors){\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n if (transform) {\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\n this._graphicsContext.rotate(transform.rotation);\n }\n }\n }\n /**\n * Applies the current camera transform if in world coordinates\n * @param transform\n */ _pushCameraTransform(transform) {\n // Establish camera offset per entity\n if (transform.coordPlane === CoordPlane.World) {\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n }\n }\n /**\n * Resets the current camera transform if in world coordinates\n * @param transform\n */ _popCameraTransform(transform) {\n if (transform.coordPlane === CoordPlane.World) // Apply camera world offset\n this._graphicsContext.restore();\n }\n }\n /**\n * The PointerSystem is responsible for dispatching pointer events to entities\n * that need them.\n *\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\n * the [[Collider]]'s shape for pointer events.\n */ class PointerSystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n /**\n * Optionally override component configuration for all entities\n */ this.overrideUseColliderShape = false;\n /**\n * Optionally override component configuration for all entities\n */ this.overrideUseGraphicsBounds = false;\n this.lastFrameEntityToPointers = new Map();\n this.currentFrameEntityToPointers = new Map();\n this._sortedTransforms = [];\n this._sortedEntities = [];\n this._zHasChanged = false;\n this._zIndexUpdate = ()=>{\n this._zHasChanged = true;\n };\n this.query = this.world.query([\n TransformComponent,\n PointerComponent\n ]);\n this.query.entityAdded$.subscribe((e)=>{\n const tx = e.get(TransformComponent);\n this._sortedTransforms.push(tx);\n this._sortedEntities.push(tx.owner);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n });\n this.query.entityRemoved$.subscribe((e)=>{\n const tx = e.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) {\n this._sortedTransforms.splice(index, 1);\n this._sortedEntities.splice(index, 1);\n }\n });\n }\n initialize(world, scene) {\n this._engine = scene.engine;\n this._scene = scene;\n }\n preupdate() {\n // event receiver might change per frame\n this._receivers = [\n this._engine.input.pointers,\n this._scene.input.pointers\n ];\n this._engineReceiver = this._engine.input.pointers;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b)=>{\n return b.z - a.z;\n });\n this._sortedEntities = this._sortedTransforms.map((t)=>t.owner);\n this._zHasChanged = false;\n }\n }\n entityCurrentlyUnderPointer(entity, pointerId) {\n return this.currentFrameEntityToPointers.has(entity.id) && this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entityWasUnderPointer(entity, pointerId) {\n return this.lastFrameEntityToPointers.has(entity.id) && this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entered(entity, pointerId) {\n return this.entityCurrentlyUnderPointer(entity, pointerId) && !this.lastFrameEntityToPointers.has(entity.id);\n }\n left(entity, pointerId) {\n return !this.currentFrameEntityToPointers.has(entity.id) && this.entityWasUnderPointer(entity, pointerId);\n }\n addPointerToEntity(entity, pointerId) {\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\n this.currentFrameEntityToPointers.set(entity.id, [\n pointerId\n ]);\n return;\n }\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\n }\n update() {\n // Locate all the pointer/entity mappings\n this._processPointerToEntity(this._sortedEntities);\n // Dispatch pointer events on entities\n this._dispatchEvents(this._sortedEntities);\n // Clear last frame's events\n this._receivers.forEach((r)=>r.update());\n this.lastFrameEntityToPointers.clear();\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\n this.currentFrameEntityToPointers.clear();\n this._receivers.forEach((r)=>r.clear());\n }\n _processPointerToEntity(entities) {\n var _a;\n let transform;\n let collider;\n let graphics;\n let pointer;\n const receiver = this._engineReceiver;\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\n // doesn't seem to cause issues tho for perf\n // Pre-process find entities under pointers\n for (const entity of entities){\n transform = entity.get(TransformComponent);\n pointer = (_a = entity.get(PointerComponent)) !== null && _a !== void 0 ? _a : new PointerComponent;\n // Check collider contains pointer\n collider = entity.get(ColliderComponent);\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\n collider.update();\n const geom = collider.get();\n if (geom) {\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries())if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) this.addPointerToEntity(entity, pointerId);\n }\n }\n // Check graphics contains pointer\n graphics = entity.get(GraphicsComponent);\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries())if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) this.addPointerToEntity(entity, pointerId);\n }\n }\n }\n _processDownAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastDownPerPointer = new Map(); // TODO will this get confused between receivers?\n // Loop through down and dispatch to entities\n for (const event of receiver.currentFrameDown){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit(\"pointerdown\", event);\n if (receiver.isDragStart(event.pointerId)) entity.events.emit(\"pointerdragstart\", event);\n }\n lastDownPerPointer.set(event.pointerId, event);\n }\n return lastDownPerPointer;\n }\n _processUpAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastUpPerPointer = new Map();\n // Loop through up and dispatch to entities\n for (const event of receiver.currentFrameUp){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit(\"pointerup\", event);\n if (receiver.isDragEnd(event.pointerId)) entity.events.emit(\"pointerdragend\", event);\n }\n lastUpPerPointer.set(event.pointerId, event);\n }\n return lastUpPerPointer;\n }\n _processMoveAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastMovePerPointer = new Map();\n // Loop through move and dispatch to entities\n for (const event of receiver.currentFrameMove){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n // move\n entity.events.emit(\"pointermove\", event);\n if (receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragmove\", event);\n }\n lastMovePerPointer.set(event.pointerId, event);\n }\n return lastMovePerPointer;\n }\n _processEnterLeaveAndEmit(entity, lastUpDownMoveEvents) {\n const receiver = this._engineReceiver;\n // up, down, and move are considered for enter and leave\n for (const event of lastUpDownMoveEvents){\n // enter\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\n entity.events.emit(\"pointerenter\", event);\n if (receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragenter\", event);\n break;\n }\n if (event.active && entity.active && // leave can happen on move\n (this.left(entity, event.pointerId) || // or leave can happen on pointer up\n this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === \"up\")) {\n entity.events.emit(\"pointerleave\", event);\n if (receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragleave\", event);\n break;\n }\n }\n }\n _processCancelAndEmit(entity) {\n const receiver = this._engineReceiver;\n // cancel\n for (const event of receiver.currentFrameCancel)if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) entity.events.emit(\"pointercancel\", event);\n }\n _processWheelAndEmit(entity) {\n const receiver = this._engineReceiver;\n // wheel\n for (const event of receiver.currentFrameWheel)// Currently the wheel only fires under the primary pointer '0'\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) entity.events.emit(\"pointerwheel\", event);\n }\n _dispatchEvents(entities) {\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\n // Filter preserves z order\n const entitiesWithEvents = entities.filter((e)=>lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\n let lastMovePerPointer;\n let lastUpPerPointer;\n let lastDownPerPointer;\n // Dispatch events in entity z order\n for (const entity of entitiesWithEvents){\n lastDownPerPointer = this._processDownAndEmit(entity);\n lastUpPerPointer = this._processUpAndEmit(entity);\n lastMovePerPointer = this._processMoveAndEmit(entity);\n const lastUpDownMoveEvents = [\n ...lastMovePerPointer.values(),\n ...lastDownPerPointer.values(),\n ...lastUpPerPointer.values()\n ];\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\n this._processCancelAndEmit(entity);\n this._processWheelAndEmit(entity);\n }\n }\n }\n class ActionsSystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._actions = [];\n this.query = this.world.query([\n ActionsComponent\n ]);\n this.query.entityAdded$.subscribe((e)=>this._actions.push(e.get(ActionsComponent)));\n this.query.entityRemoved$.subscribe((e)=>{\n const action = e.get(ActionsComponent);\n const index = this._actions.indexOf(action);\n if (index > -1) this._actions.splice(index, 1);\n });\n }\n update(delta) {\n for (const actions of this._actions)actions.update(delta);\n }\n }\n class IsometricEntityComponent extends Component {\n /**\n * Specify the isometric map to use to position this entity's z-index\n * @param mapOrOptions\n */ constructor(mapOrOptions){\n super();\n /**\n * Vertical \"height\" in the isometric world\n */ this.elevation = 0;\n this.columns = mapOrOptions.columns;\n this.rows = mapOrOptions.rows;\n this.tileWidth = mapOrOptions.tileWidth;\n this.tileHeight = mapOrOptions.tileHeight;\n }\n }\n class IsometricEntitySystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Lower;\n this.query = this.world.query([\n TransformComponent,\n IsometricEntityComponent\n ]);\n }\n update() {\n let transform;\n let iso;\n for (const entity of this.query.entities){\n transform = entity.get(TransformComponent);\n iso = entity.get(IsometricEntityComponent);\n const maxZindexPerElevation = Math.max(iso.columns * iso.tileWidth, iso.rows * iso.tileHeight);\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\n transform.z = newZ;\n }\n }\n }\n class OffscreenSystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Higher;\n this.query = this.world.query([\n TransformComponent,\n GraphicsComponent\n ]);\n }\n initialize(world, scene) {\n this._camera = scene.camera;\n this._screen = scene.engine.screen;\n }\n update() {\n this._worldBounds = this._screen.getWorldBounds();\n let transform;\n let graphics;\n let maybeParallax;\n for (const entity of this.query.entities){\n graphics = entity.get(GraphicsComponent);\n transform = entity.get(TransformComponent);\n maybeParallax = entity.get(ParallaxComponent);\n let parallaxOffset;\n if (maybeParallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\n }\n // Figure out if entities are offscreen\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\n if (entityOffscreen && !entity.hasTag(\"ex.offscreen\")) {\n entity.events.emit(\"exitviewport\", new ExitViewPortEvent(entity));\n entity.addTag(\"ex.offscreen\");\n }\n if (!entityOffscreen && entity.hasTag(\"ex.offscreen\")) {\n entity.events.emit(\"enterviewport\", new EnterViewPortEvent(entity));\n entity.removeTag(\"ex.offscreen\");\n }\n }\n }\n _isOffscreen(transform, graphics, parallaxOffset) {\n if (transform.coordPlane === CoordPlane.World) {\n let bounds = graphics.localBounds;\n if (parallaxOffset) bounds = bounds.translate(parallaxOffset);\n const transformedBounds = bounds.transform(transform.get().matrix);\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\n return graphicsOffscreen;\n } else // TODO screen coordinates\n return false;\n }\n }\n class PhysicsWorld {\n get config() {\n return watchDeep(this._config, (change)=>{\n this.$configUpdate.notifyAll(change);\n });\n }\n set config(newConfig) {\n this._config = newConfig;\n this.$configUpdate.notifyAll(newConfig);\n }\n /**\n * Spatial data structure for locating potential collision pairs and ray casts\n */ get collisionProcessor() {\n if (this._configDirty) {\n this._configDirty = false;\n // preserve tracked colliders if config updates\n const colliders = this._collisionProcessor.getColliders();\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this._config);\n for (const collider of colliders)this._collisionProcessor.track(collider);\n }\n return this._collisionProcessor;\n }\n constructor(config){\n this.$configUpdate = new Observable;\n this._configDirty = false;\n this.config = config;\n this.$configUpdate.subscribe((config)=>{\n this._configDirty = true;\n BodyComponent.updateDefaultPhysicsConfig(config.bodies);\n });\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this.config);\n }\n /**\n * Raycast into the scene's physics world\n * @param ray\n * @param options\n */ rayCast(ray, options) {\n return this.collisionProcessor.rayCast(ray, options);\n }\n }\n const GamepadEvents = {\n GamepadConnect: \"connect\",\n GamepadDisconnect: \"disconnect\",\n GamepadButton: \"button\",\n GamepadAxis: \"axis\"\n };\n /**\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\n * to provide controller support for your games.\n */ class Gamepads {\n constructor(){\n this.events = new EventEmitter();\n /**\n * Whether or not to poll for Gamepad input (default: `false`)\n */ this.enabled = false;\n /**\n * Whether or not Gamepad API is supported\n */ this.supported = !!navigator.getGamepads;\n this._gamePadTimeStamps = [\n 0,\n 0,\n 0,\n 0\n ];\n this._oldPads = [];\n this._pads = [];\n this._initSuccess = false;\n this._navigator = navigator;\n this._minimumConfiguration = null;\n this._enabled = true;\n }\n init() {\n if (!this.supported) return;\n if (this._initSuccess) return;\n // In Chrome, this will return 4 undefined items until a button is pressed\n // In FF, this will not return any items until a button is pressed\n this._oldPads = this._clonePads(this._navigator.getGamepads());\n if (this._oldPads.length && this._oldPads[0]) this._initSuccess = true;\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n /**\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\n * all other controllers with more axis or buttons are valid as well. If no minimum\n * configuration is set all pads are valid.\n */ setMinimumGamepadConfiguration(config) {\n this._enableAndUpdate(); // if config is used, implicitly enable\n this._minimumConfiguration = config;\n }\n /**\n * When implicitly enabled, set the enabled flag and run an update so information is updated\n */ _enableAndUpdate() {\n if (!this.enabled) {\n this.enabled = true;\n this.update();\n }\n }\n /**\n * Checks a navigator gamepad against the minimum configuration if present.\n */ _isGamepadValid(pad) {\n if (!this._minimumConfiguration) return true;\n if (!pad) return false;\n const axesLength = pad.axes.filter((value)=>{\n return true;\n }).length;\n const buttonLength = pad.buttons.filter((value)=>{\n return true;\n }).length;\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n this.events.off(eventName, handler);\n }\n /**\n * Updates Gamepad state and publishes Gamepad events\n */ update() {\n if (!this.enabled || !this.supported) return;\n if (!this._enabled) return;\n this.init();\n const gamepads = this._navigator.getGamepads();\n for(let i = 0; i < gamepads.length; i++){\n if (!gamepads[i]) {\n const gamepad = this.at(i);\n // If was connected, but now isn't emit the disconnect event\n if (gamepad.connected) this.events.emit(\"disconnect\", new GamepadDisconnectEvent(i, gamepad));\n // Reset connection status\n gamepad.connected = false;\n continue;\n } else {\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) this.events.emit(\"connect\", new GamepadConnectEvent(i, this.at(i)));\n // Set connection status\n this.at(i).connected = true;\n }\n this.at(i).update();\n // Only supported in Chrome\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) continue;\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\n // Add reference to navigator gamepad\n this.at(i).navigatorGamepad = gamepads[i];\n // Buttons\n let b, bi, a, ai, value;\n for(b in Buttons){\n bi = Buttons[b];\n if (typeof bi === \"number\") {\n if (gamepads[i].buttons[bi]) {\n value = gamepads[i].buttons[bi].value;\n if (value !== this._oldPads[i].getButton(bi)) {\n if (gamepads[i].buttons[bi].pressed) {\n this.at(i).updateButton(bi, value);\n this.at(i).events.emit(\"button\", new GamepadButtonEvent(bi, value, this.at(i)));\n } else this.at(i).updateButton(bi, 0);\n }\n }\n }\n }\n // Axes\n for(a in Axes){\n ai = Axes[a];\n if (typeof ai === \"number\") {\n value = gamepads[i].axes[ai];\n if (value !== this._oldPads[i].getAxes(ai)) {\n this.at(i).updateAxes(ai, value);\n this.at(i).events.emit(\"axis\", new GamepadAxisEvent(ai, value, this.at(i)));\n }\n }\n }\n this._oldPads[i] = this._clonePad(gamepads[i]);\n }\n }\n /**\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\n */ at(index) {\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\n if (index >= this._pads.length) // Ensure there is a pad to retrieve\n for(let i = this._pads.length - 1, max = index; i < max; i++){\n this._pads.push(new Gamepad());\n this._oldPads.push(new Gamepad());\n }\n return this._pads[index];\n }\n /**\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\n */ getValidGamepads() {\n this._enableAndUpdate();\n const result = [];\n for(let i = 0; i < this._pads.length; i++)if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) result.push(this.at(i));\n return result;\n }\n /**\n * Gets the number of connected gamepads\n */ count() {\n return this._pads.filter((p)=>p.connected).length;\n }\n _clonePads(pads) {\n const arr = [];\n for(let i = 0, len = pads.length; i < len; i++)arr.push(this._clonePad(pads[i]));\n return arr;\n }\n /**\n * Fastest way to clone a known object is to do it yourself\n */ _clonePad(pad) {\n let i, len;\n const clonedPad = new Gamepad();\n if (!pad) return clonedPad;\n for(i = 0, len = pad.buttons.length; i < len; i++)if (pad.buttons[i]) clonedPad.updateButton(i, pad.buttons[i].value);\n for(i = 0, len = pad.axes.length; i < len; i++)clonedPad.updateAxes(i, pad.axes[i]);\n return clonedPad;\n }\n }\n /**\n * The minimum value an axis has to move before considering it a change\n */ Gamepads.MinAxisMoveThreshold = 0.05;\n /**\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\n * for more information on handling controller input.\n */ class Gamepad {\n constructor(){\n this.events = new EventEmitter();\n this.connected = false;\n this._axes = new Array(4);\n this._buttons = new Array(16);\n this._buttonsUp = new Array(16);\n this._buttonsDown = new Array(16);\n for(let i = 0; i < this._buttons.length; i++)this._buttons[i] = 0;\n for(let i = 0; i < this._axes.length; i++)this._axes[i] = 0;\n }\n update() {\n // Reset buttonsDown and buttonsUp after update is complete\n this._buttonsDown = new Array(16);\n this._buttonsUp = new Array(16);\n }\n /**\n * Whether or not the given button is pressed\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\n * @param button The button to query\n * @param threshold The threshold over which the button is considered to be pressed\n */ isButtonPressed(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\n * Tests if a certain button is held down. This is persisted between frames.\n * @param button The button to query\n * @param threshold The threshold over which the button is considered to be pressed\n */ isButtonHeld(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\n * @param button Test whether a button was just pressed\n * @param threshold The threshold over which the button is considered to be pressed\n */ wasButtonPressed(button, threshold = 1) {\n return this._buttonsDown[button] >= threshold;\n }\n /**\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\n * @param button Test whether a button was just released\n */ wasButtonReleased(button) {\n return Boolean(this._buttonsUp[button]);\n }\n /**\n * Gets the given button value between 0 and 1\n */ getButton(button) {\n return this._buttons[button];\n }\n /**\n * Gets the given axis value between -1 and 1. Values below\n * [[MinAxisMoveThreshold]] are considered 0.\n */ getAxes(axes) {\n const value = this._axes[axes];\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) return 0;\n else return value;\n }\n updateButton(buttonIndex, value) {\n // button was just released\n if (value === 0 && this._buttons[buttonIndex]) this._buttonsUp[buttonIndex] = 1;\n else this._buttonsDown[buttonIndex] = value;\n this._buttons[buttonIndex] = value;\n }\n updateAxes(axesIndex, value) {\n this._axes[axesIndex] = value;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n /**\n * Gamepad Buttons enumeration\n */ var Buttons;\n (function(Buttons) {\n /**\n * Face 1 button (e.g. A)\n */ Buttons[Buttons[\"Face1\"] = 0] = \"Face1\";\n /**\n * Face 2 button (e.g. B)\n */ Buttons[Buttons[\"Face2\"] = 1] = \"Face2\";\n /**\n * Face 3 button (e.g. X)\n */ Buttons[Buttons[\"Face3\"] = 2] = \"Face3\";\n /**\n * Face 4 button (e.g. Y)\n */ Buttons[Buttons[\"Face4\"] = 3] = \"Face4\";\n /**\n * Left bumper button\n */ Buttons[Buttons[\"LeftBumper\"] = 4] = \"LeftBumper\";\n /**\n * Right bumper button\n */ Buttons[Buttons[\"RightBumper\"] = 5] = \"RightBumper\";\n /**\n * Left trigger button\n */ Buttons[Buttons[\"LeftTrigger\"] = 6] = \"LeftTrigger\";\n /**\n * Right trigger button\n */ Buttons[Buttons[\"RightTrigger\"] = 7] = \"RightTrigger\";\n /**\n * Select button\n */ Buttons[Buttons[\"Select\"] = 8] = \"Select\";\n /**\n * Start button\n */ Buttons[Buttons[\"Start\"] = 9] = \"Start\";\n /**\n * Left analog stick press (e.g. L3)\n */ Buttons[Buttons[\"LeftStick\"] = 10] = \"LeftStick\";\n /**\n * Right analog stick press (e.g. R3)\n */ Buttons[Buttons[\"RightStick\"] = 11] = \"RightStick\";\n /**\n * D-pad up\n */ Buttons[Buttons[\"DpadUp\"] = 12] = \"DpadUp\";\n /**\n * D-pad down\n */ Buttons[Buttons[\"DpadDown\"] = 13] = \"DpadDown\";\n /**\n * D-pad left\n */ Buttons[Buttons[\"DpadLeft\"] = 14] = \"DpadLeft\";\n /**\n * D-pad right\n */ Buttons[Buttons[\"DpadRight\"] = 15] = \"DpadRight\";\n })(Buttons || (Buttons = {}));\n /**\n * Gamepad Axes enumeration\n */ var Axes;\n (function(Axes) {\n /**\n * Left analogue stick X direction\n */ Axes[Axes[\"LeftStickX\"] = 0] = \"LeftStickX\";\n /**\n * Left analogue stick Y direction\n */ Axes[Axes[\"LeftStickY\"] = 1] = \"LeftStickY\";\n /**\n * Right analogue stick X direction\n */ Axes[Axes[\"RightStickX\"] = 2] = \"RightStickX\";\n /**\n * Right analogue stick Y direction\n */ Axes[Axes[\"RightStickY\"] = 3] = \"RightStickY\";\n })(Axes || (Axes = {}));\n /**\n * This allows you to map multiple inputs to specific commands! This is especially useful when\n * you need to allow multiple input sources to control a specific action.\n */ class InputMapper {\n constructor(inputs){\n this.inputs = inputs;\n this._handlers = new Map();\n }\n /**\n * Executes the input map, called internally by Excalibur\n */ execute() {\n for (const [input, command] of this._handlers.entries()){\n const results = input(this.inputs);\n if (results) command(results);\n }\n }\n /**\n * This allows you to map multiple inputs to specific commands! This is useful\n *\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\n *\n * Example:\n * ```typescript\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\n *\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\n * ```\n * @param inputHandler\n * @param commandHandler\n */ on(inputHandler, commandHandler) {\n this._handlers.set(inputHandler, commandHandler);\n }\n }\n /**\n * Checks if excalibur is in a x-origin iframe\n */ function isCrossOriginIframe() {\n try {\n // Try and listen to events on top window frame if within an iframe.\n //\n // See https://github.com/excaliburjs/Excalibur/issues/1294\n //\n // Attempt to add an event listener, which triggers a DOMException on\n // cross-origin iframes\n const noop = ()=>{\n return;\n };\n window.top.addEventListener(\"blur\", noop);\n window.top.removeEventListener(\"blur\", noop);\n } catch (_a) {\n return true;\n }\n return false;\n }\n /**\n * Enum representing physical input key codes\n */ var Keys;\n (function(Keys) {\n // NUMPAD\n Keys[\"Num0\"] = \"Numpad0\";\n Keys[\"Num1\"] = \"Numpad1\";\n Keys[\"Num2\"] = \"Numpad2\";\n Keys[\"Num3\"] = \"Numpad3\";\n Keys[\"Num4\"] = \"Numpad4\";\n Keys[\"Num5\"] = \"Numpad5\";\n Keys[\"Num6\"] = \"Numpad6\";\n Keys[\"Num7\"] = \"Numpad7\";\n Keys[\"Num8\"] = \"Numpad8\";\n Keys[\"Num9\"] = \"Numpad9\";\n Keys[\"NumAdd\"] = \"NumpadAdd\";\n Keys[\"NumSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumDivide\"] = \"NumpadDivide\";\n // NumComma = 'NumpadComma', // not x-browser\n Keys[\"NumDecimal\"] = \"NumpadDecimal\";\n Keys[\"Numpad0\"] = \"Numpad0\";\n Keys[\"Numpad1\"] = \"Numpad1\";\n Keys[\"Numpad2\"] = \"Numpad2\";\n Keys[\"Numpad3\"] = \"Numpad3\";\n Keys[\"Numpad4\"] = \"Numpad4\";\n Keys[\"Numpad5\"] = \"Numpad5\";\n Keys[\"Numpad6\"] = \"Numpad6\";\n Keys[\"Numpad7\"] = \"Numpad7\";\n Keys[\"Numpad8\"] = \"Numpad8\";\n Keys[\"Numpad9\"] = \"Numpad9\";\n Keys[\"NumpadAdd\"] = \"NumpadAdd\";\n Keys[\"NumpadSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumpadMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumpadDivide\"] = \"NumpadDivide\";\n // NumpadComma = 'NumpadComma', // not x-browser\n Keys[\"NumpadDecimal\"] = \"NumpadDecimal\";\n // MODIFIERS\n Keys[\"NumLock\"] = \"NumLock\";\n Keys[\"ShiftLeft\"] = \"ShiftLeft\";\n Keys[\"ShiftRight\"] = \"ShiftRight\";\n Keys[\"AltLeft\"] = \"AltLeft\";\n Keys[\"AltRight\"] = \"AltRight\";\n Keys[\"ControlLeft\"] = \"ControlLeft\";\n Keys[\"ControlRight\"] = \"ControlRight\";\n Keys[\"MetaLeft\"] = \"MetaLeft\";\n Keys[\"MetaRight\"] = \"MetaRight\";\n // NUMBERS\n Keys[\"Key0\"] = \"Digit0\";\n Keys[\"Key1\"] = \"Digit1\";\n Keys[\"Key2\"] = \"Digit2\";\n Keys[\"Key3\"] = \"Digit3\";\n Keys[\"Key4\"] = \"Digit4\";\n Keys[\"Key5\"] = \"Digit5\";\n Keys[\"Key6\"] = \"Digit6\";\n Keys[\"Key7\"] = \"Digit7\";\n Keys[\"Key8\"] = \"Digit8\";\n Keys[\"Key9\"] = \"Digit9\";\n Keys[\"Digit0\"] = \"Digit0\";\n Keys[\"Digit1\"] = \"Digit1\";\n Keys[\"Digit2\"] = \"Digit2\";\n Keys[\"Digit3\"] = \"Digit3\";\n Keys[\"Digit4\"] = \"Digit4\";\n Keys[\"Digit5\"] = \"Digit5\";\n Keys[\"Digit6\"] = \"Digit6\";\n Keys[\"Digit7\"] = \"Digit7\";\n Keys[\"Digit8\"] = \"Digit8\";\n Keys[\"Digit9\"] = \"Digit9\";\n // FUNCTION KEYS\n Keys[\"F1\"] = \"F1\";\n Keys[\"F2\"] = \"F2\";\n Keys[\"F3\"] = \"F3\";\n Keys[\"F4\"] = \"F4\";\n Keys[\"F5\"] = \"F5\";\n Keys[\"F6\"] = \"F6\";\n Keys[\"F7\"] = \"F7\";\n Keys[\"F8\"] = \"F8\";\n Keys[\"F9\"] = \"F9\";\n Keys[\"F10\"] = \"F10\";\n Keys[\"F11\"] = \"F11\";\n Keys[\"F12\"] = \"F12\";\n // LETTERS\n Keys[\"A\"] = \"KeyA\";\n Keys[\"B\"] = \"KeyB\";\n Keys[\"C\"] = \"KeyC\";\n Keys[\"D\"] = \"KeyD\";\n Keys[\"E\"] = \"KeyE\";\n Keys[\"F\"] = \"KeyF\";\n Keys[\"G\"] = \"KeyG\";\n Keys[\"H\"] = \"KeyH\";\n Keys[\"I\"] = \"KeyI\";\n Keys[\"J\"] = \"KeyJ\";\n Keys[\"K\"] = \"KeyK\";\n Keys[\"L\"] = \"KeyL\";\n Keys[\"M\"] = \"KeyM\";\n Keys[\"N\"] = \"KeyN\";\n Keys[\"O\"] = \"KeyO\";\n Keys[\"P\"] = \"KeyP\";\n Keys[\"Q\"] = \"KeyQ\";\n Keys[\"R\"] = \"KeyR\";\n Keys[\"S\"] = \"KeyS\";\n Keys[\"T\"] = \"KeyT\";\n Keys[\"U\"] = \"KeyU\";\n Keys[\"V\"] = \"KeyV\";\n Keys[\"W\"] = \"KeyW\";\n Keys[\"X\"] = \"KeyX\";\n Keys[\"Y\"] = \"KeyY\";\n Keys[\"Z\"] = \"KeyZ\";\n Keys[\"KeyA\"] = \"KeyA\";\n Keys[\"KeyB\"] = \"KeyB\";\n Keys[\"KeyC\"] = \"KeyC\";\n Keys[\"KeyD\"] = \"KeyD\";\n Keys[\"KeyE\"] = \"KeyE\";\n Keys[\"KeyF\"] = \"KeyF\";\n Keys[\"KeyG\"] = \"KeyG\";\n Keys[\"KeyH\"] = \"KeyH\";\n Keys[\"KeyI\"] = \"KeyI\";\n Keys[\"KeyJ\"] = \"KeyJ\";\n Keys[\"KeyK\"] = \"KeyK\";\n Keys[\"KeyL\"] = \"KeyL\";\n Keys[\"KeyM\"] = \"KeyM\";\n Keys[\"KeyN\"] = \"KeyN\";\n Keys[\"KeyO\"] = \"KeyO\";\n Keys[\"KeyP\"] = \"KeyP\";\n Keys[\"KeyQ\"] = \"KeyQ\";\n Keys[\"KeyR\"] = \"KeyR\";\n Keys[\"KeyS\"] = \"KeyS\";\n Keys[\"KeyT\"] = \"KeyT\";\n Keys[\"KeyU\"] = \"KeyU\";\n Keys[\"KeyV\"] = \"KeyV\";\n Keys[\"KeyW\"] = \"KeyW\";\n Keys[\"KeyX\"] = \"KeyX\";\n Keys[\"KeyY\"] = \"KeyY\";\n Keys[\"KeyZ\"] = \"KeyZ\";\n // SYMBOLS\n Keys[\"Semicolon\"] = \"Semicolon\";\n Keys[\"Quote\"] = \"Quote\";\n Keys[\"Comma\"] = \"Comma\";\n Keys[\"Minus\"] = \"Minus\";\n Keys[\"Period\"] = \"Period\";\n Keys[\"Slash\"] = \"Slash\";\n Keys[\"Equal\"] = \"Equal\";\n Keys[\"BracketLeft\"] = \"BracketLeft\";\n Keys[\"Backslash\"] = \"Backslash\";\n Keys[\"BracketRight\"] = \"BracketRight\";\n Keys[\"Backquote\"] = \"Backquote\";\n // DIRECTIONS\n Keys[\"Up\"] = \"ArrowUp\";\n Keys[\"Down\"] = \"ArrowDown\";\n Keys[\"Left\"] = \"ArrowLeft\";\n Keys[\"Right\"] = \"ArrowRight\";\n Keys[\"ArrowUp\"] = \"ArrowUp\";\n Keys[\"ArrowDown\"] = \"ArrowDown\";\n Keys[\"ArrowLeft\"] = \"ArrowLeft\";\n Keys[\"ArrowRight\"] = \"ArrowRight\";\n // OTHER\n Keys[\"Space\"] = \"Space\";\n Keys[\"Backspace\"] = \"Backspace\";\n Keys[\"Delete\"] = \"Delete\";\n Keys[\"Esc\"] = \"Escape\";\n Keys[\"Escape\"] = \"Escape\";\n Keys[\"Enter\"] = \"Enter\";\n Keys[\"NumpadEnter\"] = \"NumpadEnter\";\n Keys[\"ContextMenu\"] = \"ContextMenu\";\n })(Keys || (Keys = {}));\n /**\n * Event thrown on a game object for a key event\n */ class KeyEvent extends GameEvent {\n /**\n * @param key The key responsible for throwing the event\n * @param value The key's typed value the browser detected\n * @param originalEvent The original keyboard event that Excalibur handled\n */ constructor(key, value, originalEvent){\n super();\n this.key = key;\n this.value = value;\n this.originalEvent = originalEvent;\n }\n }\n const KeyEvents = {\n Press: \"press\",\n Hold: \"hold\",\n Release: \"release\"\n };\n /**\n * Provides keyboard support for Excalibur.\n */ class Keyboard {\n constructor(){\n this.events = new EventEmitter();\n this._enabled = true;\n /**\n * Keys that are currently held down\n */ this._keys = [];\n /**\n * Keys up in the current frame\n */ this._keysUp = [];\n /**\n * Keys down in the current frame\n */ this._keysDown = [];\n this._releaseAllKeys = (ev)=>{\n for (const code of this._keys){\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit(\"up\", keyEvent);\n this.events.emit(\"release\", keyEvent);\n }\n this._keysUp = Array.from(new Set(this._keys.concat(this._keysUp)));\n this._keys.length = 0;\n };\n this._handleKeyDown = (ev)=>{\n if (!this._enabled) return;\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) this._releaseAllKeys(ev);\n const code = ev.code;\n if (this._keys.indexOf(code) === -1) {\n this._keys.push(code);\n this._keysDown.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit(\"down\", keyEvent);\n this.events.emit(\"press\", keyEvent);\n }\n };\n this._handleKeyUp = (ev)=>{\n if (!this._enabled) return;\n const code = ev.code;\n const key = this._keys.indexOf(code);\n this._keys.splice(key, 1);\n this._keysUp.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n // alias the old api, we may want to deprecate this in the future\n this.events.emit(\"up\", keyEvent);\n this.events.emit(\"release\", keyEvent);\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (ev.key === \"Meta\") this._releaseAllKeys(ev);\n };\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Initialize Keyboard event listeners\n */ init(keyboardOptions) {\n let { global: global } = keyboardOptions;\n const { grabWindowFocus: grabWindowFocus } = keyboardOptions;\n if (!global) {\n if (isCrossOriginIframe()) {\n global = window;\n // Workaround for iframes like for itch.io or codesandbox\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\n if (grabWindowFocus) window.focus();\n Logger.getInstance().warn(\"Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus\");\n } else global = window.top;\n }\n global.addEventListener(\"blur\", ()=>{\n this._keys.length = 0; // empties array efficiently\n });\n // key up is on window because canvas cannot have focus\n global.addEventListener(\"keyup\", this._handleKeyUp);\n // key down is on window because canvas cannot have focus\n global.addEventListener(\"keydown\", this._handleKeyDown);\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n update() {\n // Reset keysDown and keysUp after update is complete\n this._keysDown.length = 0;\n this._keysUp.length = 0;\n // Emit synthetic \"hold\" event\n for(let i = 0; i < this._keys.length; i++)this.events.emit(\"hold\", new KeyEvent(this._keys[i]));\n }\n /**\n * Gets list of keys being pressed down\n */ getKeys() {\n return this._keys;\n }\n /**\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\n * @param key Test whether a key was just pressed\n */ wasPressed(key) {\n return this._keysDown.indexOf(key) > -1;\n }\n /**\n * Tests if a certain key is held down. This is persisted between frames.\n * @param key Test whether a key is held down\n */ isHeld(key) {\n return this._keys.indexOf(key) > -1;\n }\n /**\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\n * @param key Test whether a key was just released\n */ wasReleased(key) {\n return this._keysUp.indexOf(key) > -1;\n }\n /**\n * Trigger a manual key event\n * @param type\n * @param key\n * @param character\n */ triggerEvent(type, key, character) {\n if (type === \"down\") this._handleKeyDown(new KeyboardEvent(\"keydown\", {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n if (type === \"up\") this._handleKeyUp(new KeyboardEvent(\"keyup\", {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n }\n }\n class GlobalCoordinates {\n static fromPagePosition(xOrPos, yOrEngine, engineOrUndefined) {\n let pageX;\n let pageY;\n let pagePos;\n let engine;\n if (arguments.length === 3) {\n pageX = xOrPos;\n pageY = yOrEngine;\n pagePos = new Vector(pageX, pageY);\n engine = engineOrUndefined;\n } else {\n pagePos = xOrPos;\n pageX = pagePos.x;\n pageY = pagePos.y;\n engine = yOrEngine;\n }\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\n }\n constructor(worldPos, pagePos, screenPos){\n this.worldPos = worldPos;\n this.pagePos = pagePos;\n this.screenPos = screenPos;\n }\n }\n class PointerEvent {\n cancel() {\n this.active = false;\n }\n get pagePos() {\n return this.coordinates.pagePos;\n }\n get screenPos() {\n return this.coordinates.screenPos;\n }\n get worldPos() {\n return this.coordinates.worldPos;\n }\n constructor(type, pointerId, button, pointerType, coordinates, nativeEvent){\n this.type = type;\n this.pointerId = pointerId;\n this.button = button;\n this.pointerType = pointerType;\n this.coordinates = coordinates;\n this.nativeEvent = nativeEvent;\n this.active = true;\n }\n }\n class WheelEvent {\n cancel() {\n this.active = false;\n }\n constructor(x, y, pageX, pageY, screenX, screenY, index, deltaX, deltaY, deltaZ, deltaMode, ev){\n this.x = x;\n this.y = y;\n this.pageX = pageX;\n this.pageY = pageY;\n this.screenX = screenX;\n this.screenY = screenY;\n this.index = index;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.deltaZ = deltaZ;\n this.deltaMode = deltaMode;\n this.ev = ev;\n this.active = true;\n }\n }\n class PointerAbstraction {\n constructor(){\n this.events = new EventEmitter();\n /**\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\n */ this.lastPagePos = Vector.Zero;\n /**\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\n */ this.lastScreenPos = Vector.Zero;\n /**\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\n */ this.lastWorldPos = Vector.Zero;\n this._onPointerMove = (ev)=>{\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this._onPointerDown = (ev)=>{\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this.on(\"move\", this._onPointerMove);\n this.on(\"down\", this._onPointerDown);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n var WheelDeltaMode;\n (function(WheelDeltaMode) {\n WheelDeltaMode[\"Pixel\"] = \"Pixel\";\n WheelDeltaMode[\"Line\"] = \"Line\";\n WheelDeltaMode[\"Page\"] = \"Page\";\n })(WheelDeltaMode || (WheelDeltaMode = {}));\n /**\n * Native browser button enumeration\n */ var NativePointerButton;\n (function(NativePointerButton) {\n NativePointerButton[NativePointerButton[\"NoButton\"] = -1] = \"NoButton\";\n NativePointerButton[NativePointerButton[\"Left\"] = 0] = \"Left\";\n NativePointerButton[NativePointerButton[\"Middle\"] = 1] = \"Middle\";\n NativePointerButton[NativePointerButton[\"Right\"] = 2] = \"Right\";\n NativePointerButton[NativePointerButton[\"Unknown\"] = 3] = \"Unknown\";\n })(NativePointerButton || (NativePointerButton = {}));\n /**\n * The mouse button being pressed.\n */ var PointerButton;\n (function(PointerButton) {\n PointerButton[\"Left\"] = \"Left\";\n PointerButton[\"Middle\"] = \"Middle\";\n PointerButton[\"Right\"] = \"Right\";\n PointerButton[\"Unknown\"] = \"Unknown\";\n PointerButton[\"NoButton\"] = \"NoButton\";\n })(PointerButton || (PointerButton = {}));\n /**\n * The type of pointer for a [[PointerEvent]].\n */ var PointerType;\n (function(PointerType) {\n PointerType[\"Touch\"] = \"Touch\";\n PointerType[\"Mouse\"] = \"Mouse\";\n PointerType[\"Pen\"] = \"Pen\";\n PointerType[\"Unknown\"] = \"Unknown\";\n })(PointerType || (PointerType = {}));\n const PointerEvents = {\n Move: \"move\",\n Down: \"down\",\n Up: \"up\",\n Wheel: \"wheel\"\n };\n /**\n * Is this event a native touch event?\n */ function isTouchEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\n }\n /**\n * Is this event a native pointer event\n */ function isPointerEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\n }\n /**\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\n */ class PointerEventReceiver {\n constructor(target, engine){\n this.target = target;\n this.engine = engine;\n this.events = new EventEmitter();\n this.primary = new PointerAbstraction();\n this._activeNativePointerIdsToNormalized = new Map();\n this.lastFramePointerCoords = new Map();\n this.currentFramePointerCoords = new Map();\n this.currentFramePointerDown = new Map();\n this.lastFramePointerDown = new Map();\n this.currentFrameDown = [];\n this.currentFrameUp = [];\n this.currentFrameMove = [];\n this.currentFrameCancel = [];\n this.currentFrameWheel = [];\n this._enabled = true;\n this._pointers = [\n this.primary\n ];\n this._boundHandle = this._handle.bind(this);\n this._boundWheel = this._handleWheel.bind(this);\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n /**\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\n * handlers.\n * @param target\n * @param engine\n */ recreate(target, engine) {\n const eventReceiver = new PointerEventReceiver(target, engine);\n eventReceiver.primary = this.primary;\n eventReceiver._pointers = this._pointers;\n return eventReceiver;\n }\n /**\n * Locates a specific pointer by id, creates it if it doesn't exist\n * @param index\n */ at(index) {\n if (index >= this._pointers.length) // Ensure there is a pointer to retrieve\n for(let i = this._pointers.length - 1, max = index; i < max; i++)this._pointers.push(new PointerAbstraction());\n return this._pointers[index];\n }\n /**\n * The number of pointers currently being tracked by excalibur\n */ count() {\n return this._pointers.length;\n }\n /**\n * Is the specified pointer id down this frame\n * @param pointerId\n */ isDown(pointerId) {\n var _a;\n return (_a = this.currentFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\n * Was the specified pointer id down last frame\n * @param pointerId\n */ wasDown(pointerId) {\n var _a;\n return (_a = this.lastFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\n * Whether the Pointer is currently dragging.\n */ isDragging(pointerId) {\n return this.isDown(pointerId);\n }\n /**\n * Whether the Pointer just started dragging.\n */ isDragStart(pointerId) {\n return this.isDown(pointerId) && !this.wasDown(pointerId);\n }\n /**\n * Whether the Pointer just ended dragging.\n */ isDragEnd(pointerId) {\n return !this.isDown(pointerId) && this.wasDown(pointerId);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Called internally by excalibur\n *\n * Updates the current frame pointer info and emits raw pointer events\n *\n * This does not emit events to entities, see PointerSystem\n */ update() {\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\n for (const event of this.currentFrameDown){\n this.emit(\"down\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"down\", event);\n this.primary.emit(\"pointerdown\", event);\n }\n for (const event of this.currentFrameUp){\n this.emit(\"up\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"up\", event);\n }\n for (const event of this.currentFrameMove){\n this.emit(\"move\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"move\", event);\n }\n for (const event of this.currentFrameCancel){\n this.emit(\"cancel\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"cancel\", event);\n }\n for (const event of this.currentFrameWheel){\n this.emit(\"wheel\", event);\n this.primary.emit(\"pointerwheel\", event);\n this.primary.emit(\"wheel\", event);\n }\n }\n /**\n * Clears the current frame event and pointer data\n */ clear() {\n for (const event of this.currentFrameUp){\n this.currentFramePointerCoords.delete(event.pointerId);\n const ids = this._activeNativePointerIdsToNormalized.entries();\n for (const [native, normalized] of ids)if (normalized === event.pointerId) this._activeNativePointerIdsToNormalized.delete(native);\n }\n this.currentFrameDown.length = 0;\n this.currentFrameUp.length = 0;\n this.currentFrameMove.length = 0;\n this.currentFrameCancel.length = 0;\n this.currentFrameWheel.length = 0;\n }\n /**\n * Initializes the pointer event receiver so that it can start listening to native\n * browser events.\n */ init(options) {\n var _a;\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\n // It is important on mobile to have touch action 'none'\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\n if (this.target === this.engine.canvas) this.engine.canvas.style.touchAction = \"none\";\n else document.body.style.touchAction = \"none\";\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.addEventListener(\"pointerdown\", this._boundHandle);\n this.target.addEventListener(\"pointerup\", this._boundHandle);\n this.target.addEventListener(\"pointermove\", this._boundHandle);\n this.target.addEventListener(\"pointercancel\", this._boundHandle);\n } else {\n // Touch Events\n this.target.addEventListener(\"touchstart\", this._boundHandle);\n this.target.addEventListener(\"touchend\", this._boundHandle);\n this.target.addEventListener(\"touchmove\", this._boundHandle);\n this.target.addEventListener(\"touchcancel\", this._boundHandle);\n // Mouse Events\n this.target.addEventListener(\"mousedown\", this._boundHandle);\n this.target.addEventListener(\"mouseup\", this._boundHandle);\n this.target.addEventListener(\"mousemove\", this._boundHandle);\n }\n // MDN MouseWheelEvent\n const wheelOptions = {\n passive: !(this.engine.pageScrollPreventionMode === ScrollPreventionMode.All || this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas)\n };\n if (\"onwheel\" in document.createElement(\"div\")) // Modern Browsers\n this.target.addEventListener(\"wheel\", this._boundWheel, wheelOptions);\n else if (document.onmousewheel !== undefined) // Webkit and IE\n this.target.addEventListener(\"mousewheel\", this._boundWheel, wheelOptions);\n else // Remaining browser and older Firefox\n this.target.addEventListener(\"MozMousePixelScroll\", this._boundWheel, wheelOptions);\n const grabWindowFocus = (_a = options === null || options === void 0 ? void 0 : options.grabWindowFocus) !== null && _a !== void 0 ? _a : true;\n // Handle cross origin iframe\n if (grabWindowFocus && isCrossOriginIframe()) {\n const grabFocus = ()=>{\n window.focus();\n };\n // Preferred pointer events\n if (window.PointerEvent) this.target.addEventListener(\"pointerdown\", grabFocus);\n else {\n // Touch Events\n this.target.addEventListener(\"touchstart\", grabFocus);\n // Mouse Events\n this.target.addEventListener(\"mousedown\", grabFocus);\n }\n }\n }\n detach() {\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.removeEventListener(\"pointerdown\", this._boundHandle);\n this.target.removeEventListener(\"pointerup\", this._boundHandle);\n this.target.removeEventListener(\"pointermove\", this._boundHandle);\n this.target.removeEventListener(\"pointercancel\", this._boundHandle);\n } else {\n // Touch Events\n this.target.removeEventListener(\"touchstart\", this._boundHandle);\n this.target.removeEventListener(\"touchend\", this._boundHandle);\n this.target.removeEventListener(\"touchmove\", this._boundHandle);\n this.target.removeEventListener(\"touchcancel\", this._boundHandle);\n // Mouse Events\n this.target.removeEventListener(\"mousedown\", this._boundHandle);\n this.target.removeEventListener(\"mouseup\", this._boundHandle);\n this.target.removeEventListener(\"mousemove\", this._boundHandle);\n }\n if (\"onwheel\" in document.createElement(\"div\")) // Modern Browsers\n this.target.removeEventListener(\"wheel\", this._boundWheel);\n else if (document.onmousewheel !== undefined) // Webkit and IE\n this.target.addEventListener(\"mousewheel\", this._boundWheel);\n else // Remaining browser and older Firefox\n this.target.addEventListener(\"MozMousePixelScroll\", this._boundWheel);\n }\n /**\n * Take native pointer id and map it to index in active pointers\n * @param nativePointerId\n */ _normalizePointerId(nativePointerId) {\n // Add to the the native pointer set id\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\n // Native pointer ids in ascending order\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b)=>a - b);\n // The index into sorted ids will be the new id, will always have an id\n const id = currentPointerIds.findIndex((p)=>p === nativePointerId);\n // Save the mapping so we can reverse it later\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\n // ignore pointer because game isn't watching\n return id;\n }\n /**\n * Responsible for handling and parsing pointer events\n */ _handle(ev) {\n if (!this._enabled) return;\n ev.preventDefault();\n const eventCoords = new Map();\n let button;\n let pointerType;\n if (isTouchEvent(ev)) {\n button = PointerButton.Unknown;\n pointerType = PointerType.Touch;\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\n for(let i = 0; i < ev.changedTouches.length; i++){\n const touch = ev.changedTouches[i];\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\n const nativePointerId = i + 1;\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n } else {\n button = this._nativeButtonToPointerButton(ev.button);\n pointerType = PointerType.Mouse;\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\n let nativePointerId = 1;\n if (isPointerEvent(ev)) {\n nativePointerId = ev.pointerId;\n pointerType = this._stringToPointerType(ev.pointerType);\n }\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n for (const [pointerId, coord] of eventCoords.entries())switch(ev.type){\n case \"mousedown\":\n case \"pointerdown\":\n case \"touchstart\":\n this.currentFrameDown.push(new PointerEvent(\"down\", pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, true);\n break;\n case \"mouseup\":\n case \"pointerup\":\n case \"touchend\":\n this.currentFrameUp.push(new PointerEvent(\"up\", pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, false);\n break;\n case \"mousemove\":\n case \"pointermove\":\n case \"touchmove\":\n this.currentFrameMove.push(new PointerEvent(\"move\", pointerId, button, pointerType, coord, ev));\n break;\n case \"touchcancel\":\n case \"pointercancel\":\n this.currentFrameCancel.push(new PointerEvent(\"cancel\", pointerId, button, pointerType, coord, ev));\n break;\n }\n }\n _handleWheel(ev) {\n if (!this._enabled) return;\n // Should we prevent page scroll because of this event\n if (this.engine.pageScrollPreventionMode === ScrollPreventionMode.All || this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas) ev.preventDefault();\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\n const world = this.engine.screen.screenToWorldCoordinates(screen);\n /**\n * A constant used to normalize wheel events across different browsers\n *\n * This normalization factor is pulled from\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\n */ const ScrollWheelNormalizationFactor = -1 / 40;\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\n const deltaY = ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\n const deltaZ = ev.deltaZ || 0;\n let deltaMode = WheelDeltaMode.Pixel;\n if (ev.deltaMode) {\n if (ev.deltaMode === 1) deltaMode = WheelDeltaMode.Line;\n else if (ev.deltaMode === 2) deltaMode = WheelDeltaMode.Page;\n }\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\n this.currentFrameWheel.push(we);\n }\n /**\n * Triggers an excalibur pointer event in a world space pos\n *\n * Useful for testing pointers in excalibur\n * @param type\n * @param pos\n */ triggerEvent(type, pos) {\n const page = this.engine.screen.worldToPageCoordinates(pos);\n // Send an event to the event receiver\n if (window.PointerEvent) this._handle(new window.PointerEvent(\"pointer\" + type, {\n pointerId: 0,\n clientX: page.x,\n clientY: page.y\n }));\n else // Safari hack\n this._handle(new window.MouseEvent(\"mouse\" + type, {\n clientX: page.x,\n clientY: page.y\n }));\n // Force update pointer system\n const pointerSystem = this.engine.currentScene.world.get(PointerSystem);\n pointerSystem.preupdate(this.engine.currentScene, 1);\n pointerSystem.update(1);\n }\n _nativeButtonToPointerButton(s) {\n switch(s){\n case NativePointerButton.NoButton:\n return PointerButton.NoButton;\n case NativePointerButton.Left:\n return PointerButton.Left;\n case NativePointerButton.Middle:\n return PointerButton.Middle;\n case NativePointerButton.Right:\n return PointerButton.Right;\n case NativePointerButton.Unknown:\n return PointerButton.Unknown;\n default:\n return fail(s);\n }\n }\n _stringToPointerType(s) {\n switch(s){\n case \"touch\":\n return PointerType.Touch;\n case \"mouse\":\n return PointerType.Mouse;\n case \"pen\":\n return PointerType.Pen;\n default:\n return PointerType.Unknown;\n }\n }\n }\n class InputHost {\n constructor(options){\n this._enabled = true;\n const { pointerTarget: pointerTarget, grabWindowFocus: grabWindowFocus, engine: engine } = options;\n this.keyboard = new Keyboard();\n this.pointers = new PointerEventReceiver(pointerTarget, engine);\n this.gamepads = new Gamepads();\n this.keyboard.init({\n grabWindowFocus: grabWindowFocus\n });\n this.pointers.init({\n grabWindowFocus: grabWindowFocus\n });\n this.gamepads.init();\n this.inputMapper = new InputMapper({\n keyboard: this.keyboard,\n pointers: this.pointers,\n gamepads: this.gamepads\n });\n }\n get enabled() {\n return this._enabled;\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n this.keyboard.toggleEnabled(this._enabled);\n this.pointers.toggleEnabled(this._enabled);\n this.gamepads.toggleEnabled(this._enabled);\n }\n update() {\n if (this._enabled) {\n this.inputMapper.execute();\n this.keyboard.update();\n this.gamepads.update();\n }\n }\n }\n class PreLoadEvent {\n }\n const SceneEvents = {\n Initialize: \"initialize\",\n Activate: \"activate\",\n Deactivate: \"deactivate\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\",\n PreDebugDraw: \"predebugdraw\",\n PostDebugDraw: \"postdebugdraw\",\n PreLoad: \"preload\"\n };\n /**\n *\n */ function isSceneConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n }\n /**\n * [[Actor|Actors]] are composed together into groupings called Scenes in\n * Excalibur. The metaphor models the same idea behind real world\n * actors in a scene. Only actors in scenes will be updated and drawn.\n *\n * Typical usages of a scene include: levels, menus, loading screens, etc.\n */ class Scene {\n /**\n * The actors in the current scene\n */ get actors() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof Actor;\n });\n }\n /**\n * The entities in the current scene\n */ get entities() {\n return this.world.entityManager.entities;\n }\n /**\n * The triggers in the current scene\n */ get triggers() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof Trigger;\n });\n }\n /**\n * The [[TileMap]]s in the scene, if any\n */ get tileMaps() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof TileMap;\n });\n }\n get timers() {\n return this._timers;\n }\n constructor(){\n // Initialize systems\n this._logger = Logger.getInstance();\n this.events = new EventEmitter();\n /**\n * Gets or sets the current camera for the scene\n */ this.camera = new Camera();\n /**\n * The ECS world for the scene\n */ this.world = new World(this);\n /**\n * The Excalibur physics world for the scene. Used to interact\n * with colliders included in the scene.\n *\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\n */ this.physics = new PhysicsWorld(DefaultPhysicsConfig);\n this._isInitialized = false;\n this._timers = [];\n this._cancelQueue = [];\n // Update\n this.world.add(ActionsSystem);\n this.world.add(new MotionSystem(this.world, this.physics));\n this.world.add(new CollisionSystem(this.world, this.physics));\n this.world.add(PointerSystem);\n this.world.add(IsometricEntitySystem);\n // Draw\n this.world.add(OffscreenSystem);\n this.world.add(GraphicsSystem);\n this.world.add(DebugSystem);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Event hook to provide Scenes a way of loading scene specific resources.\n *\n * This is called before the Scene.onInitialize during scene transition. It will only ever fire once for a scene.\n * @param loader\n */ onPreLoad(loader) {\n // will be overridden\n }\n /**\n * Event hook fired directly before transition, either \"in\" or \"out\" of the scene\n *\n * This overrides the Engine scene definition. However transitions specified in goToScene take highest precedence\n *\n * ```typescript\n * // Overrides all\n * Engine.goToScene('scene', { destinationIn: ..., sourceOut: ... });\n * ```\n *\n * This can be used to configure custom transitions for a scene dynamically\n */ onTransition(direction) {\n // will be overridden\n return undefined;\n }\n /**\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\n * overridden. This is where initialization of child actors should take place.\n */ onInitialize(engine) {\n // will be overridden\n }\n /**\n * This is called when the scene is made active and started. It is meant to be overridden,\n * this is where you should setup any DOM UI or event handlers needed for the scene.\n */ onActivate(context) {\n // will be overridden\n }\n /**\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\n */ onDeactivate(context) {\n // will be overridden\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before a scene is updated.\n */ onPreUpdate(engine, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */ onPostUpdate(engine, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreDraw` is called directly before a scene is drawn.\n *\n */ onPreDraw(ctx, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostDraw` is called directly after a scene is drawn.\n *\n */ onPostDraw(ctx, delta) {\n // will be overridden\n }\n /**\n * Initializes actors in the scene\n */ _initializeChildren() {\n for (const child of this.entities)child._initialize(this.engine);\n }\n /**\n * Gets whether or not the [[Scene]] has been initialized\n */ get isInitialized() {\n return this._isInitialized;\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Initializes the scene before the first update, meant to be called by engine not by users of\n * Excalibur\n * @internal\n */ async _initialize(engine) {\n var _a;\n if (!this.isInitialized) {\n try {\n this.engine = engine;\n // PhysicsWorld config is watched so things will automagically update\n this.physics.config = this.engine.physics;\n this.input = new InputHost({\n pointerTarget: engine.pointerScope === PointerScope.Canvas ? engine.canvas : document,\n grabWindowFocus: engine.grabWindowFocus,\n engine: engine\n });\n // Initialize camera first\n this.camera._initialize(engine);\n this.world.systemManager.initialize();\n // This order is important! we want to be sure any custom init that add actors\n // fire before the actor init\n await this.onInitialize(engine);\n this._initializeChildren();\n this._logger.debug(\"Scene.onInitialize\", this, engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n } catch (e) {\n this._logger.error(`Error during scene initialization for scene ${(_a = engine.director) === null || _a === void 0 ? void 0 : _a.getSceneName(this)}!`);\n throw e;\n }\n this._isInitialized = true;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\n * @internal\n */ async _activate(context) {\n var _a, _b;\n try {\n this._logger.debug(\"Scene.onActivate\", this);\n this.input.toggleEnabled(true);\n await this.onActivate(context);\n } catch (e) {\n this._logger.error(`Error during scene activation for scene ${(_b = (_a = this.engine) === null || _a === void 0 ? void 0 : _a.director) === null || _b === void 0 ? void 0 : _b.getSceneName(this)}!`);\n throw e;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\n * @internal\n */ async _deactivate(context) {\n this._logger.debug(\"Scene.onDeactivate\", this);\n this.input.toggleEnabled(false);\n await this.onDeactivate(context);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */ _preupdate(engine, delta) {\n this.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */ _postupdate(engine, delta) {\n this.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\n * @internal\n */ _predraw(ctx, delta) {\n this.emit(\"predraw\", new PreDrawEvent(ctx, delta, this));\n this.onPreDraw(ctx, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\n * @internal\n */ _postdraw(ctx, delta) {\n this.emit(\"postdraw\", new PostDrawEvent(ctx, delta, this));\n this.onPostDraw(ctx, delta);\n }\n /**\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\n * @param engine Reference to the current Engine\n * @param delta The number of milliseconds since the last update\n */ update(engine, delta) {\n var _a;\n if (!this.isInitialized) {\n this._logger.warnOnce(`Scene update called before initialize for scene ${(_a = engine.director) === null || _a === void 0 ? void 0 : _a.getSceneName(this)}!`);\n return;\n }\n this._preupdate(engine, delta);\n // TODO differed entity removal for timers\n let i, len;\n // Remove timers in the cancel queue before updating them\n for(i = 0, len = this._cancelQueue.length; i < len; i++)this.removeTimer(this._cancelQueue[i]);\n this._cancelQueue.length = 0;\n // Cycle through timers updating timers\n for (const timer of this._timers)timer.update(delta);\n this.world.update(SystemType.Update, delta);\n // Camera last keeps renders smooth that are based on entity/actor\n if (this.camera) this.camera.update(engine, delta);\n this._collectActorStats(engine);\n this._postupdate(engine, delta);\n this.input.update();\n }\n /**\n * Draws all the actors in the Scene. Called by the [[Engine]].\n * @param ctx The current rendering context\n * @param delta The number of milliseconds since the last draw\n */ draw(ctx, delta) {\n var _a;\n if (!this.isInitialized) {\n this._logger.warnOnce(`Scene draw called before initialize!`);\n return;\n }\n this._predraw(ctx, delta);\n this.world.update(SystemType.Draw, delta);\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.isDebug) this.debugDraw(ctx);\n this._postdraw(ctx, delta);\n }\n /**\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\n * @param ctx The current rendering context\n */ /* istanbul ignore next */ debugDraw(ctx) {\n this.emit(\"predebugdraw\", new PreDebugDrawEvent(ctx, this));\n // pass\n this.emit(\"postdebugdraw\", new PostDebugDrawEvent(ctx, this));\n }\n /**\n * Checks whether an actor is contained in this scene or not\n */ contains(actor) {\n return this.actors.indexOf(actor) > -1;\n }\n add(entity) {\n this.emit(\"entityadded\", {\n target: entity\n });\n this.world.add(entity);\n entity.scene = this;\n if (entity instanceof Timer) {\n if (!contains(this._timers, entity)) this.addTimer(entity);\n return;\n }\n }\n /**\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\n * and adds it to this scene.\n *\n * Useful if you want to have an object be present in only 1 scene at a time.\n * @param entity\n */ transfer(entity) {\n let scene;\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\n scene = entity.scene;\n entity.scene.world.remove(entity, false);\n }\n if (entity instanceof Timer && entity.scene) {\n scene = entity.scene;\n entity.scene.removeTimer(entity);\n }\n scene === null || scene === void 0 || scene.emit(\"entityremoved\", {\n target: entity\n });\n this.add(entity);\n }\n remove(entity) {\n if (entity instanceof Entity) {\n this.emit(\"entityremoved\", {\n target: entity\n });\n if (entity.active) entity.kill();\n this.world.remove(entity);\n }\n if (entity instanceof Timer) this.removeTimer(entity);\n }\n /**\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\n *\n * By default entities use deferred removal\n * @param deferred\n */ clear(deferred = true) {\n for(let i = this.entities.length - 1; i >= 0; i--)this.world.remove(this.entities[i], deferred);\n for(let i = this.timers.length - 1; i >= 0; i--)this.removeTimer(this.timers[i]);\n }\n /**\n * Adds a [[Timer]] to the scene\n * @param timer The timer to add\n */ addTimer(timer) {\n this._timers.push(timer);\n timer.scene = this;\n return timer;\n }\n /**\n * Removes a [[Timer]] from the scene.\n * @warning Can be dangerous, use [[cancelTimer]] instead\n * @param timer The timer to remove\n */ removeTimer(timer) {\n const i = this._timers.indexOf(timer);\n if (i !== -1) this._timers.splice(i, 1);\n return timer;\n }\n /**\n * Cancels a [[Timer]], removing it from the scene nicely\n * @param timer The timer to cancel\n */ cancelTimer(timer) {\n this._cancelQueue.push(timer);\n return timer;\n }\n /**\n * Tests whether a [[Timer]] is active in the scene\n */ isTimerActive(timer) {\n return this._timers.indexOf(timer) > -1 && !timer.complete;\n }\n isCurrentScene() {\n if (this.engine) return this.engine.currentScene === this;\n return false;\n }\n _collectActorStats(engine) {\n const screenElements = this.actors.filter((a)=>a instanceof ScreenElement);\n for (const _ui of screenElements)engine.stats.currFrame.actors.ui++;\n for (const actor of this.actors){\n engine.stats.currFrame.actors.alive++;\n for (const child of actor.children)if (isScreenElement(child)) // TODO not true\n engine.stats.currFrame.actors.ui++;\n else engine.stats.currFrame.actors.alive++;\n }\n }\n }\n var ColorBlindnessMode;\n (function(ColorBlindnessMode) {\n ColorBlindnessMode[\"Protanope\"] = \"Protanope\";\n ColorBlindnessMode[\"Deuteranope\"] = \"Deuteranope\";\n ColorBlindnessMode[\"Tritanope\"] = \"Tritanope\";\n })(ColorBlindnessMode || (ColorBlindnessMode = {}));\n /* harmony default export */ const color_blind_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\";\n /**\n * Helper that defines a whole screen renderer, just provide a fragment source!\n *\n * Currently supports 1 varying\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\n */ class ScreenShader {\n constructor(gl, fragmentSource){\n this._shader = new Shader({\n gl: gl,\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\n fragmentSource: fragmentSource\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n type: \"static\",\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1,\n -1,\n 0,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n -1,\n 1,\n 0,\n 1,\n -1,\n 1,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n 1,\n 1,\n 1\n ])\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_texcoord\",\n 2\n ]\n ]\n });\n this._buffer.upload();\n }\n getShader() {\n return this._shader;\n }\n getLayout() {\n return this._layout;\n }\n }\n class ColorBlindnessPostProcessor {\n constructor(_colorBlindnessMode, simulate = false){\n this._colorBlindnessMode = _colorBlindnessMode;\n this._simulate = false;\n this._simulate = simulate;\n }\n initialize(gl) {\n this._shader = new ScreenShader(gl, color_blind_fragment);\n this.simulate = this._simulate;\n this.colorBlindnessMode = this._colorBlindnessMode;\n }\n getShader() {\n return this._shader.getShader();\n }\n getLayout() {\n return this._shader.getLayout();\n }\n set colorBlindnessMode(colorBlindMode) {\n this._colorBlindnessMode = colorBlindMode;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) shader.setUniformInt(\"u_type\", 0);\n else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) shader.setUniformInt(\"u_type\", 1);\n else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) shader.setUniformInt(\"u_type\", 2);\n }\n }\n get colorBlindnessMode() {\n return this._colorBlindnessMode;\n }\n set simulate(value) {\n this._simulate = value;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n shader.setUniformBoolean(\"u_simulate\", value);\n }\n }\n get simulate() {\n return this._simulate;\n }\n }\n class ColorBlindFlags {\n constructor(engine){\n this._engine = engine;\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\n }\n /**\n * Correct colors for a specified color blindness\n * @param colorBlindness\n */ correct(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = false;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Simulate colors for a specified color blindness\n * @param colorBlindness\n */ simulate(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = true;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Remove color blindness post processor\n */ clear() {\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Debug statistics and flags for Excalibur. If polling these values, it would be\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\n * updated during a frame.\n */ class DebugConfig {\n constructor(engine){\n /**\n * Performance statistics\n */ this.stats = {\n /**\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\n * Best accessed on [[postframe]] event. See [[FrameStats]]\n */ currFrame: new FrameStats(),\n /**\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\n */ prevFrame: new FrameStats()\n };\n /**\n * Filter debug context to named entities or entity ids\n */ this.filter = {\n /**\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\n */ useFilter: false,\n /**\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\n */ nameQuery: \"\",\n /**\n * Query for Entity ids, if the id matches it will be included\n */ ids: []\n };\n /**\n * Entity debug settings\n */ this.entity = {\n showAll: false,\n showId: false,\n showName: false\n };\n /**\n * Transform component debug settings\n */ this.transform = {\n showAll: false,\n debugZIndex: 10000000,\n showPosition: false,\n showPositionLabel: false,\n positionColor: Color.Yellow,\n showZIndex: false,\n showScale: false,\n scaleColor: Color.Green,\n showRotation: false,\n rotationColor: Color.Blue\n };\n /**\n * Graphics component debug settings\n */ this.graphics = {\n showAll: false,\n showBounds: false,\n boundsColor: Color.Yellow\n };\n /**\n * Collider component debug settings\n */ this.collider = {\n showAll: false,\n showBounds: false,\n boundsColor: Color.Blue,\n showOwner: false,\n showGeometry: true,\n geometryColor: Color.Green,\n geometryLineWidth: 1,\n geometryPointSize: .5\n };\n /**\n * Physics simulation debug settings\n */ this.physics = {\n showAll: false,\n showBroadphaseSpacePartitionDebug: false,\n showCollisionNormals: false,\n collisionNormalColor: Color.Cyan,\n showCollisionContacts: true,\n contactSize: 2,\n collisionContactColor: Color.Red\n };\n /**\n * Motion component debug settings\n */ this.motion = {\n showAll: false,\n showVelocity: false,\n velocityColor: Color.Yellow,\n showAcceleration: false,\n accelerationColor: Color.Red\n };\n /**\n * Body component debug settings\n */ this.body = {\n showAll: false,\n showCollisionGroup: false,\n showCollisionType: false,\n showSleeping: false,\n showMotion: false,\n showMass: false\n };\n /**\n * Camera debug settings\n */ this.camera = {\n showAll: false,\n showFocus: false,\n focusColor: Color.Red,\n showZoom: false\n };\n this.tilemap = {\n showAll: false,\n showGrid: false,\n gridColor: Color.Red,\n gridWidth: .5,\n showSolidBounds: false,\n solidBoundsColor: Color.fromHex(\"#8080807F\"),\n showColliderGeometry: true\n };\n this.isometric = {\n showAll: false,\n showPosition: false,\n positionColor: Color.Yellow,\n positionSize: 1,\n showGrid: false,\n gridColor: Color.Red,\n gridWidth: 1,\n showColliderGeometry: true\n };\n this._engine = engine;\n this.colorBlindMode = new ColorBlindFlags(this._engine);\n }\n /**\n * Switch the current excalibur clock with the [[TestClock]] and return\n * it in the same running state.\n *\n * This is useful when you need to debug frame by frame.\n */ useTestClock() {\n const clock = this._engine.clock;\n const wasRunning = clock.isRunning();\n clock.stop();\n const testClock = clock.toTestClock();\n if (wasRunning) testClock.start();\n this._engine.clock = testClock;\n return testClock;\n }\n /**\n * Switch the current excalibur clock with the [[StandardClock]] and\n * return it in the same running state.\n *\n * This is useful when you need to switch back to normal mode after\n * debugging.\n */ useStandardClock() {\n const currentClock = this._engine.clock;\n const wasRunning = currentClock.isRunning();\n currentClock.stop();\n const standardClock = currentClock.toStandardClock();\n if (wasRunning) standardClock.start();\n this._engine.clock = standardClock;\n return standardClock;\n }\n }\n /**\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\n * creating instances of this every frame.\n */ class FrameStats {\n constructor(){\n this._id = 0;\n this._delta = 0;\n this._fps = 0;\n this._actorStats = {\n alive: 0,\n killed: 0,\n ui: 0,\n get remaining () {\n return this.alive - this.killed;\n },\n get total () {\n return this.remaining + this.ui;\n }\n };\n this._durationStats = {\n update: 0,\n draw: 0,\n get total () {\n return this.update + this.draw;\n }\n };\n this._physicsStats = new PhysicsStats();\n this._graphicsStats = {\n drawCalls: 0,\n drawnImages: 0\n };\n }\n /**\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\n * @param [otherStats] Optional stats to clone\n */ reset(otherStats) {\n if (otherStats) {\n this.id = otherStats.id;\n this.delta = otherStats.delta;\n this.fps = otherStats.fps;\n this.actors.alive = otherStats.actors.alive;\n this.actors.killed = otherStats.actors.killed;\n this.actors.ui = otherStats.actors.ui;\n this.duration.update = otherStats.duration.update;\n this.duration.draw = otherStats.duration.draw;\n this._physicsStats.reset(otherStats.physics);\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\n } else {\n this.id = this.delta = this.fps = 0;\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\n this.duration.update = this.duration.draw = 0;\n this._physicsStats.reset();\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\n }\n }\n /**\n * Provides a clone of this instance.\n */ clone() {\n const fs = new FrameStats();\n fs.reset(this);\n return fs;\n }\n /**\n * Gets the frame's id\n */ get id() {\n return this._id;\n }\n /**\n * Sets the frame's id\n */ set id(value) {\n this._id = value;\n }\n /**\n * Gets the frame's delta (time since last frame)\n */ get delta() {\n return this._delta;\n }\n /**\n * Sets the frame's delta (time since last frame). Internal use only.\n * @internal\n */ set delta(value) {\n this._delta = value;\n }\n /**\n * Gets the frame's frames-per-second (FPS)\n */ get fps() {\n return this._fps;\n }\n /**\n * Sets the frame's frames-per-second (FPS). Internal use only.\n * @internal\n */ set fps(value) {\n this._fps = value;\n }\n /**\n * Gets the frame's actor statistics\n */ get actors() {\n return this._actorStats;\n }\n /**\n * Gets the frame's duration statistics\n */ get duration() {\n return this._durationStats;\n }\n /**\n * Gets the frame's physics statistics\n */ get physics() {\n return this._physicsStats;\n }\n /**\n * Gets the frame's graphics statistics\n */ get graphics() {\n return this._graphicsStats;\n }\n }\n class PhysicsStats {\n constructor(){\n this._pairs = 0;\n this._collisions = 0;\n this._contacts = new Map();\n this._fastBodies = 0;\n this._fastBodyCollisions = 0;\n this._broadphase = 0;\n this._narrowphase = 0;\n }\n /**\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\n * @param [otherStats] Optional stats to clone\n */ reset(otherStats) {\n if (otherStats) {\n this.pairs = otherStats.pairs;\n this.collisions = otherStats.collisions;\n this.contacts = otherStats.contacts;\n this.fastBodies = otherStats.fastBodies;\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\n this.broadphase = otherStats.broadphase;\n this.narrowphase = otherStats.narrowphase;\n } else {\n this.pairs = this.collisions = this.fastBodies = 0;\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\n this.contacts.clear();\n }\n }\n /**\n * Provides a clone of this instance.\n */ clone() {\n const ps = new PhysicsStats();\n ps.reset(this);\n return ps;\n }\n get pairs() {\n return this._pairs;\n }\n set pairs(value) {\n this._pairs = value;\n }\n get collisions() {\n return this._collisions;\n }\n set collisions(value) {\n this._collisions = value;\n }\n get contacts() {\n return this._contacts;\n }\n set contacts(contacts) {\n this._contacts = contacts;\n }\n get fastBodies() {\n return this._fastBodies;\n }\n set fastBodies(value) {\n this._fastBodies = value;\n }\n get fastBodyCollisions() {\n return this._fastBodyCollisions;\n }\n set fastBodyCollisions(value) {\n this._fastBodyCollisions = value;\n }\n get broadphase() {\n return this._broadphase;\n }\n set broadphase(value) {\n this._broadphase = value;\n }\n get narrowphase() {\n return this._narrowphase;\n }\n set narrowphase(value) {\n this._narrowphase = value;\n }\n }\n class BrowserComponent {\n on(eventName, handler) {\n if (this._nativeHandlers[eventName]) this.off(eventName, this._nativeHandlers[eventName]);\n this._nativeHandlers[eventName] = this._decorate(handler);\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\n }\n off(eventName, handler) {\n if (!handler) handler = this._nativeHandlers[eventName];\n this.nativeComponent.removeEventListener(eventName, handler);\n this._nativeHandlers[eventName] = null;\n }\n _decorate(handler) {\n return (evt)=>{\n if (!this._paused) handler(evt);\n };\n }\n pause() {\n this._paused = true;\n }\n resume() {\n this._paused = false;\n }\n clear() {\n for(const event in this._nativeHandlers)this.off(event);\n }\n constructor(nativeComponent){\n this.nativeComponent = nativeComponent;\n this._paused = false;\n this._nativeHandlers = {};\n }\n }\n class BrowserEvents {\n constructor(_windowGlobal, _documentGlobal){\n this._windowGlobal = _windowGlobal;\n this._documentGlobal = _documentGlobal;\n this._windowComponent = new BrowserComponent(this._windowGlobal);\n this._documentComponent = new BrowserComponent(this._documentGlobal);\n }\n get window() {\n return this._windowComponent;\n }\n get document() {\n return this._documentComponent;\n }\n pause() {\n this.window.pause();\n this.document.pause();\n }\n resume() {\n this.window.resume();\n this.document.resume();\n }\n clear() {\n this.window.clear();\n this.document.clear();\n }\n }\n const DefaultAntialiasOptions = {\n pixelArtSampler: false,\n nativeContextAntialiasing: false,\n multiSampleAntialiasing: true,\n filtering: ImageFiltering.Blended,\n canvasImageRendering: \"auto\"\n };\n const DefaultPixelArtOptions = {\n pixelArtSampler: true,\n nativeContextAntialiasing: false,\n multiSampleAntialiasing: true,\n filtering: ImageFiltering.Blended,\n canvasImageRendering: \"auto\"\n };\n class FpsSampler {\n constructor(options){\n var _a;\n this._samplePeriod = 100;\n this._currentFrameTime = 0;\n this._frames = 0;\n this._previousSampleTime = 0;\n this._beginFrameTime = 0;\n this._fps = options.initialFps;\n this._samplePeriod = (_a = options.samplePeriod) !== null && _a !== void 0 ? _a : this._samplePeriod;\n this._currentFrameTime = 1000 / options.initialFps;\n this._nowFn = options.nowFn;\n this._previousSampleTime = this._nowFn();\n }\n /**\n * Start of code block to sample FPS for\n */ start() {\n this._beginFrameTime = this._nowFn();\n }\n /**\n * End of code block to sample FPS for\n */ end() {\n this._frames++;\n const time = this._nowFn();\n this._currentFrameTime = time - this._beginFrameTime;\n if (time >= this._previousSampleTime + this._samplePeriod) {\n this._fps = this._frames * 1000 / (time - this._previousSampleTime);\n this._previousSampleTime = time;\n this._frames = 0;\n }\n }\n /**\n * Return the currently sampled fps over the last sample period, by default every 100ms\n */ get fps() {\n return this._fps;\n }\n /**\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\n */ get instant() {\n return 1000 / this._currentFrameTime;\n }\n }\n /**\n * Abstract Clock is the base type of all Clocks\n *\n * It has a few opinions\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\n * 2. The default timing api is implemented in now()\n *\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\n * method is unique to your clock implementation.\n */ class Clock {\n constructor(options){\n var _a, _b, _c;\n this._onFatalException = ()=>{};\n this._maxFps = Infinity;\n this._lastTime = 0;\n this._elapsed = 1;\n this._scheduledCbs = [];\n this._totalElapsed = 0;\n this._options = options;\n this.tick = options.tick;\n this._lastTime = (_a = this.now()) !== null && _a !== void 0 ? _a : 0;\n this._maxFps = (_b = options.maxFps) !== null && _b !== void 0 ? _b : this._maxFps;\n this._onFatalException = (_c = options.onFatalException) !== null && _c !== void 0 ? _c : this._onFatalException;\n this.fpsSampler = new FpsSampler({\n initialFps: 60,\n nowFn: ()=>this.now()\n });\n }\n /**\n * Get the elapsed time for the last completed frame\n */ elapsed() {\n return this._elapsed;\n }\n /**\n * Get the current time in milliseconds\n */ now() {\n return performance.now();\n }\n toTestClock() {\n const testClock = new TestClock({\n ...this._options,\n defaultUpdateMs: 16.6\n });\n return testClock;\n }\n toStandardClock() {\n const clock = new StandardClock({\n ...this._options\n });\n return clock;\n }\n setFatalExceptionHandler(handler) {\n this._onFatalException = handler;\n }\n /**\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\n *\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\n * stopped or paused.\n * @param cb callback to fire\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\n */ schedule(cb, timeoutMs = 0) {\n // Scheduled based on internal elapsed time\n const scheduledTime = this._totalElapsed + timeoutMs;\n this._scheduledCbs.push([\n cb,\n scheduledTime\n ]);\n }\n _runScheduledCbs() {\n // walk backwards to delete items as we loop\n for(let i = this._scheduledCbs.length - 1; i > -1; i--)if (this._scheduledCbs[i][1] <= this._totalElapsed) {\n this._scheduledCbs[i][0](this._elapsed);\n this._scheduledCbs.splice(i, 1);\n }\n }\n update(overrideUpdateMs) {\n try {\n this.fpsSampler.start();\n // Get the time to calculate time-elapsed\n const now = this.now();\n let elapsed = now - this._lastTime || 1; // first frame\n // Constrain fps\n const fpsInterval = 1000 / this._maxFps;\n // only run frame if enough time has elapsed\n if (elapsed >= fpsInterval) {\n let leftover = 0;\n if (fpsInterval !== 0) {\n leftover = elapsed % fpsInterval;\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\n }\n // Resolves issue #138 if the game has been paused, or blurred for\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\n // and provides more expected behavior when the engine comes back\n // into focus\n if (elapsed > 200) elapsed = 1;\n // tick the mainloop and run scheduled callbacks\n this._elapsed = overrideUpdateMs || elapsed;\n this._totalElapsed += this._elapsed;\n this._runScheduledCbs();\n this.tick(overrideUpdateMs || elapsed);\n if (fpsInterval !== 0) this._lastTime = now - leftover;\n else this._lastTime = now;\n this.fpsSampler.end();\n }\n } catch (e) {\n this._onFatalException(e);\n this.stop();\n }\n }\n }\n /**\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\n */ class StandardClock extends Clock {\n constructor(options){\n super(options);\n this._running = false;\n }\n isRunning() {\n return this._running;\n }\n start() {\n if (this._running) return;\n this._running = true;\n const mainloop = ()=>{\n // stop the loop\n if (!this._running) return;\n try {\n // request next loop\n this._requestId = window.requestAnimationFrame(mainloop);\n this.update();\n } catch (e) {\n window.cancelAnimationFrame(this._requestId);\n throw e;\n }\n };\n // begin the first frame\n mainloop();\n }\n stop() {\n window.cancelAnimationFrame(this._requestId);\n this._running = false;\n }\n }\n /**\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\n */ class TestClock extends Clock {\n constructor(options){\n super({\n ...options\n });\n this._logger = Logger.getInstance();\n this._running = false;\n this._currentTime = 0;\n this._updateMs = options.defaultUpdateMs;\n }\n /**\n * Get the current time in milliseconds\n */ now() {\n var _a;\n return (_a = this._currentTime) !== null && _a !== void 0 ? _a : 0;\n }\n isRunning() {\n return this._running;\n }\n start() {\n this._running = true;\n }\n stop() {\n this._running = false;\n }\n /**\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\n * @param overrideUpdateMs\n */ step(overrideUpdateMs) {\n const time = overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs;\n if (this._running) {\n // to be comparable to RAF this needs to be a full blown Task\n // For example, images cannot decode synchronously in a single step\n this.update(time);\n this._currentTime += time;\n } else this._logger.warn(\"The clock is not running, no step will be performed\");\n }\n /**\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\n * @param numberOfSteps\n * @param overrideUpdateMs\n */ run(numberOfSteps, overrideUpdateMs) {\n for(let i = 0; i < numberOfSteps; i++)this.step(overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs);\n }\n }\n // EXTERNAL MODULE: ./Util/Toaster.css\n var Util_Toaster = $2c23f148d58cd887$var$__webpack_require__(7379);\n /**\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\n */ class Toaster {\n constructor(){\n this._toasterCss = Util_Toaster /* default */ .Z.toString();\n this._isInitialized = false;\n }\n _initialize() {\n if (!this._isInitialized) {\n this._container = document.createElement(\"div\");\n this._container.id = \"ex-toast-container\";\n document.body.appendChild(this._container);\n this._isInitialized = true;\n this._styleBlock = document.createElement(\"style\");\n this._styleBlock.textContent = this._toasterCss;\n document.head.appendChild(this._styleBlock);\n }\n }\n dispose() {\n this._container.parentElement.removeChild(this._container);\n this._styleBlock.parentElement.removeChild(this._styleBlock);\n this._isInitialized = false;\n }\n _createFragment(message) {\n const toastMessage = document.createElement(\"span\");\n toastMessage.innerText = message;\n return toastMessage;\n }\n /**\n * Display a toast message to a player\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\n * @param linkTarget Optionally specify a link location\n * @param linkName Optionally specify a name for that link location\n */ toast(message, linkTarget, linkName) {\n this._initialize();\n const toast = document.createElement(\"div\");\n toast.className = \"ex-toast-message\";\n const messageFragments = message.split(\"[LINK]\").map((message)=>this._createFragment(message));\n if (linkTarget) {\n const link = document.createElement(\"a\");\n link.href = linkTarget;\n if (linkName) link.innerText = linkName;\n else link.innerText = linkTarget;\n messageFragments.splice(1, 0, link);\n }\n // Assembly message\n const finalMessage = document.createElement(\"div\");\n messageFragments.forEach((message)=>{\n finalMessage.appendChild(message);\n });\n toast.appendChild(finalMessage);\n // Dismiss button\n const dismissBtn = document.createElement(\"button\");\n dismissBtn.innerText = \"x\";\n dismissBtn.addEventListener(\"click\", ()=>{\n this._container.removeChild(toast);\n });\n toast.appendChild(dismissBtn);\n // Escape to dismiss\n const keydownHandler = (evt)=>{\n if (evt.key === \"Escape\") try {\n this._container.removeChild(toast);\n } catch (_a) {\n // pass\n }\n document.removeEventListener(\"keydown\", keydownHandler);\n };\n document.addEventListener(\"keydown\", keydownHandler);\n // Insert into container\n const first = this._container.firstChild;\n this._container.insertBefore(toast, first);\n }\n }\n const DirectorEvents = {\n NavigationStart: \"navigationstart\",\n Navigation: \"navigation\",\n NavigationEnd: \"navigationend\"\n };\n /**\n * The Director is responsible for managing scenes and changing scenes in Excalibur.\n *\n * It deals with transitions, scene loaders, switching scenes\n *\n * This is used internally by Excalibur, generally not mean to\n * be instantiated end users directly.\n */ class Director {\n /**\n * Gets whether the director currently transitioning between scenes\n *\n * Useful if you need to block behavior during transition\n */ get isTransitioning() {\n return this._isTransitioning;\n }\n constructor(_engine, scenes){\n this._engine = _engine;\n this.events = new EventEmitter();\n this._logger = Logger.getInstance();\n this._initialized = false;\n /**\n * All registered scenes in Excalibur\n */ this.scenes = {};\n /**\n * Holds all instantiated scenes\n */ this._sceneToInstance = new Map();\n this._sceneToLoader = new Map();\n this._sceneToTransition = new Map();\n /**\n * Used to keep track of scenes that have already been loaded so we don't load multiple times\n */ this._loadedScenes = new Set();\n this._isTransitioning = false;\n this.rootScene = this.currentScene = new Scene();\n this.add(\"root\", this.rootScene);\n this.currentScene = this.rootScene;\n this.currentSceneName = \"root\";\n for(const sceneKey in scenes){\n const sceneOrOptions = scenes[sceneKey];\n this.add(sceneKey, sceneOrOptions);\n if (sceneKey === \"root\") {\n this.rootScene = this.getSceneInstance(\"root\");\n this.currentScene = this.rootScene;\n }\n }\n }\n /**\n * Initialize the director's internal state\n */ async onInitialize() {\n if (!this._initialized) {\n this._initialized = true;\n if (this._deferredGoto) {\n const deferredScene = this._deferredGoto;\n const deferredTransition = this._deferredTransition;\n this._deferredGoto = null;\n this._deferredTransition = null;\n await this.swapScene(deferredScene);\n if (deferredTransition) await this.playTransition(deferredTransition);\n } else await this.swapScene(\"root\");\n }\n }\n get isInitialized() {\n return this._initialized;\n }\n /**\n * Configures the start scene, and optionally the transition & loader for the director\n *\n * Typically this is called at the beginning of the game to the start scene and transition and never again.\n * @param startScene\n * @param options\n */ configureStart(startScene, options) {\n const maybeLoaderOrCtor = options === null || options === void 0 ? void 0 : options.loader;\n if (maybeLoaderOrCtor instanceof DefaultLoader) this.mainLoader = maybeLoaderOrCtor;\n else if (isLoaderConstructor(maybeLoaderOrCtor)) this.mainLoader = new maybeLoaderOrCtor();\n else this.mainLoader = new Loader();\n let maybeStartTransition;\n if (options) {\n const { inTransition: inTransition } = options;\n maybeStartTransition = inTransition;\n }\n this.startScene = startScene;\n // Fire and forget promise for the initial scene\n if (maybeStartTransition) // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.swapScene(this.startScene).then(()=>{\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.playTransition(maybeStartTransition);\n });\n else // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.swapScene(this.startScene);\n this.currentSceneName = this.startScene;\n }\n _getLoader(sceneName) {\n return this._sceneToLoader.get(sceneName);\n }\n _getInTransition(sceneName) {\n var _a;\n const sceneOrRoute = this.scenes[sceneName];\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) return null;\n return (_a = sceneOrRoute === null || sceneOrRoute === void 0 ? void 0 : sceneOrRoute.transitions) === null || _a === void 0 ? void 0 : _a.in;\n }\n _getOutTransition(sceneName) {\n var _a;\n const sceneOrRoute = this.scenes[sceneName];\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) return null;\n return (_a = sceneOrRoute === null || sceneOrRoute === void 0 ? void 0 : sceneOrRoute.transitions) === null || _a === void 0 ? void 0 : _a.out;\n }\n getDeferredScene() {\n const maybeDeferred = this.getSceneDefinition(this._deferredGoto);\n if (this._deferredGoto && maybeDeferred) return maybeDeferred;\n return null;\n }\n /**\n * Returns a scene by name if it exists, might be the constructor and not the instance of a scene\n * @param name\n */ getSceneDefinition(name) {\n const maybeScene = this.scenes[name];\n if (maybeScene instanceof Scene || isSceneConstructor(maybeScene)) return maybeScene;\n else if (maybeScene) return maybeScene.scene;\n return undefined;\n }\n getSceneName(scene) {\n for (const [name, sceneInstance] of this._sceneToInstance){\n if (scene === sceneInstance) return name;\n }\n return \"unknown scene name\";\n }\n /**\n * Returns the same Director, but asserts a scene DOES exist to the type system\n * @param name\n */ assertAdded(name) {\n return this;\n }\n /**\n * Returns the same Director, but asserts a scene DOES NOT exist to the type system\n * @param name\n */ assertRemoved(name) {\n return this;\n }\n /**\n * Adds additional Scenes to the game!\n * @param name\n * @param sceneOrRoute\n */ add(name, sceneOrRoute) {\n if (!(sceneOrRoute instanceof Scene) && !isSceneConstructor(sceneOrRoute)) {\n const { loader: loader, transitions: transitions } = sceneOrRoute;\n const { in: inTransition, out: outTransition } = transitions !== null && transitions !== void 0 ? transitions : {};\n this._sceneToTransition.set(name, {\n in: inTransition,\n out: outTransition\n });\n if (isLoaderConstructor(loader)) this._sceneToLoader.set(name, new loader());\n else this._sceneToLoader.set(name, loader);\n }\n if (this.scenes[name]) this._logger.warn(\"Scene\", name, \"already exists overwriting\");\n this.scenes[name] = sceneOrRoute;\n return this.assertAdded(name);\n }\n remove(nameOrScene) {\n if (nameOrScene instanceof Scene || isSceneConstructor(nameOrScene)) {\n const sceneOrCtor = nameOrScene;\n // remove scene\n for(const key in this.scenes)if (this.scenes.hasOwnProperty(key)) {\n const potentialSceneOrOptions = this.scenes[key];\n let scene;\n if (potentialSceneOrOptions instanceof Scene || isSceneConstructor(potentialSceneOrOptions)) scene = potentialSceneOrOptions;\n else scene = potentialSceneOrOptions.scene;\n if (scene === sceneOrCtor) {\n if (key === this.currentSceneName) throw new Error(`Cannot remove a currently active scene: ${key}`);\n this._sceneToTransition.delete(key);\n this._sceneToLoader.delete(key);\n delete this.scenes[key];\n }\n }\n }\n if (typeof nameOrScene === \"string\") {\n if (nameOrScene === this.currentSceneName) throw new Error(`Cannot remove a currently active scene: ${nameOrScene}`);\n // remove scene\n this._sceneToTransition.delete(nameOrScene);\n this._sceneToLoader.delete(nameOrScene);\n delete this.scenes[nameOrScene];\n }\n }\n /**\n * Go to a specific scene, and optionally override loaders and transitions\n * @param destinationScene\n * @param options\n */ async goto(destinationScene, options) {\n var _a, _b, _c, _d, _e, _f;\n const maybeDest = this.getSceneInstance(destinationScene);\n if (!maybeDest) {\n this._logger.warn(`Scene ${destinationScene} does not exist! Check the name, are you sure you added it?`);\n return;\n }\n const sourceScene = this.currentSceneName;\n const engineInputEnabled = (_b = (_a = this._engine.input) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;\n this._isTransitioning = true;\n const maybeSourceOut = (_c = this.getSceneInstance(sourceScene)) === null || _c === void 0 ? void 0 : _c.onTransition(\"out\");\n const maybeDestinationIn = maybeDest === null || maybeDest === void 0 ? void 0 : maybeDest.onTransition(\"in\");\n options = {\n sourceOut: (_d = this._getOutTransition(this.currentSceneName)) !== null && _d !== void 0 ? _d : maybeSourceOut,\n destinationIn: (_e = this._getInTransition(destinationScene)) !== null && _e !== void 0 ? _e : maybeDestinationIn,\n // Goto options\n ...options\n };\n const { sourceOut: sourceOut, destinationIn: destinationIn, sceneActivationData: sceneActivationData } = options;\n const outTransition = sourceOut !== null && sourceOut !== void 0 ? sourceOut : this._getOutTransition(this.currentSceneName);\n const inTransition = destinationIn !== null && destinationIn !== void 0 ? destinationIn : this._getInTransition(destinationScene);\n const hideLoader = (outTransition === null || outTransition === void 0 ? void 0 : outTransition.hideLoader) || (inTransition === null || inTransition === void 0 ? void 0 : inTransition.hideLoader);\n if (hideLoader) // Start hidden loader early and take advantage of the transition\n // Don't await and block on a hidden loader\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.maybeLoadScene(destinationScene, hideLoader);\n this._emitEvent(\"navigationstart\", sourceScene, destinationScene);\n // Run the out transition on the current scene if present\n await this.playTransition(outTransition);\n // Run the loader if present\n await this.maybeLoadScene(destinationScene, hideLoader);\n // Give incoming transition a chance to grab info from previous\n await (inTransition === null || inTransition === void 0 ? void 0 : inTransition.onPreviousSceneDeactivate(this.currentScene));\n // Swap to the new scene\n await this.swapScene(destinationScene, sceneActivationData);\n this._emitEvent(\"navigation\", sourceScene, destinationScene);\n // Run the in transition on the new scene if present\n await this.playTransition(inTransition);\n this._emitEvent(\"navigationend\", sourceScene, destinationScene);\n (_f = this._engine.input) === null || _f === void 0 || _f.toggleEnabled(engineInputEnabled);\n this._isTransitioning = false;\n }\n /**\n * Retrieves a scene instance by key if it's registered.\n *\n * This will call any constructors that were given as a definition\n * @param scene\n */ getSceneInstance(scene) {\n const sceneDefinition = this.getSceneDefinition(scene);\n if (!sceneDefinition) return undefined;\n if (this._sceneToInstance.has(scene)) return this._sceneToInstance.get(scene);\n if (sceneDefinition instanceof Scene) {\n this._sceneToInstance.set(scene, sceneDefinition);\n return sceneDefinition;\n }\n const newScene = new sceneDefinition();\n this._sceneToInstance.set(scene, newScene);\n return newScene;\n }\n /**\n * Triggers scene loading if has not already been loaded\n * @param scene\n * @param hideLoader\n */ async maybeLoadScene(scene, hideLoader = false) {\n var _a;\n const loader = (_a = this._getLoader(scene)) !== null && _a !== void 0 ? _a : new DefaultLoader();\n const sceneToLoad = this.getSceneDefinition(scene);\n const sceneToLoadInstance = this.getSceneInstance(scene);\n if (sceneToLoad && sceneToLoadInstance && !this._loadedScenes.has(sceneToLoadInstance)) {\n sceneToLoadInstance.onPreLoad(loader);\n sceneToLoadInstance.events.emit(\"preload\", {\n loader: loader\n });\n if (hideLoader) // Don't await a hidden loader\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this._engine.load(loader, hideLoader);\n else await this._engine.load(loader);\n this._loadedScenes.add(sceneToLoadInstance);\n }\n }\n /**\n * Plays a transition in the current scene\n * @param transition\n */ async playTransition(transition) {\n var _a, _b, _c, _d, _e, _f, _g;\n if (!this.isInitialized) {\n this._deferredTransition = transition;\n return;\n }\n if (transition) {\n this.currentTransition = transition;\n const currentScene = this._engine.currentScene;\n const sceneInputEnabled = (_b = (_a = currentScene.input) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;\n (_c = currentScene.input) === null || _c === void 0 || _c.toggleEnabled(!transition.blockInput);\n (_d = this._engine.input) === null || _d === void 0 || _d.toggleEnabled(!transition.blockInput);\n await this.currentTransition.play(this._engine);\n (_e = currentScene.input) === null || _e === void 0 || _e.toggleEnabled(sceneInputEnabled);\n }\n (_f = this.currentTransition) === null || _f === void 0 || _f.kill();\n (_g = this.currentTransition) === null || _g === void 0 || _g.reset();\n this.currentTransition = null;\n }\n /**\n * Swaps the current and destination scene after performing required lifecycle events\n * @param destinationScene\n * @param data\n */ async swapScene(destinationScene, data) {\n const engine = this._engine;\n // if not yet initialized defer goToScene\n if (!this.isInitialized) {\n this._deferredGoto = destinationScene;\n return;\n }\n const maybeDest = this.getSceneInstance(destinationScene);\n if (maybeDest) {\n const previousScene = this.currentScene;\n const nextScene = maybeDest;\n this._logger.debug(\"Going to scene:\", destinationScene);\n // only deactivate when initialized\n if (this.currentScene.isInitialized) {\n const context = {\n engine: engine,\n previousScene: previousScene,\n nextScene: nextScene\n };\n await this.currentScene._deactivate(context);\n this.currentScene.events.emit(\"deactivate\", new DeactivateEvent(context, this.currentScene));\n }\n // wait for the scene to be loaded if needed\n const destLoader = this._sceneToLoader.get(destinationScene);\n await (destLoader === null || destLoader === void 0 ? void 0 : destLoader.areResourcesLoaded());\n // set current scene to new one\n this.currentScene = nextScene;\n this.currentSceneName = destinationScene;\n engine.screen.setCurrentCamera(nextScene.camera);\n // initialize the current scene if has not been already\n await this.currentScene._initialize(engine);\n const context = {\n engine: engine,\n previousScene: previousScene,\n nextScene: nextScene,\n data: data\n };\n await this.currentScene._activate(context);\n this.currentScene.events.emit(\"activate\", new ActivateEvent(context, this.currentScene));\n } else this._logger.error(\"Scene\", destinationScene, \"does not exist!\");\n }\n _emitEvent(eventName, sourceScene, destinationScene) {\n const source = this.getSceneDefinition(sourceScene);\n const dest = this.getSceneDefinition(destinationScene);\n this.events.emit(eventName, {\n sourceScene: source,\n sourceName: sourceScene,\n destinationScene: dest,\n destinationName: destinationScene\n });\n }\n }\n polyfill();\n const EngineEvents = {\n FallbackGraphicsContext: \"fallbackgraphicscontext\",\n Initialize: \"initialize\",\n Visible: \"visible\",\n Hidden: \"hidden\",\n Start: \"start\",\n Stop: \"stop\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreFrame: \"preframe\",\n PostFrame: \"postframe\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\"\n };\n /**\n * Enum representing the different mousewheel event bubble prevention\n */ var ScrollPreventionMode;\n (function(ScrollPreventionMode) {\n /**\n * Do not prevent any page scrolling\n */ ScrollPreventionMode[ScrollPreventionMode[\"None\"] = 0] = \"None\";\n /**\n * Prevent page scroll if mouse is over the game canvas\n */ ScrollPreventionMode[ScrollPreventionMode[\"Canvas\"] = 1] = \"Canvas\";\n /**\n * Prevent all page scrolling via mouse wheel\n */ ScrollPreventionMode[ScrollPreventionMode[\"All\"] = 2] = \"All\";\n })(ScrollPreventionMode || (ScrollPreventionMode = {}));\n /**\n * The Excalibur Engine\n *\n * The [[Engine]] is the main driver for a game. It is responsible for\n * starting/stopping the game, maintaining state, transmitting events,\n * loading resources, and managing the scene.\n */ class Engine {\n /**\n * The width of the game canvas in pixels (physical width component of the\n * resolution of the canvas element)\n */ get canvasWidth() {\n return this.screen.canvasWidth;\n }\n /**\n * Returns half width of the game canvas in pixels (half physical width component)\n */ get halfCanvasWidth() {\n return this.screen.halfCanvasWidth;\n }\n /**\n * The height of the game canvas in pixels, (physical height component of\n * the resolution of the canvas element)\n */ get canvasHeight() {\n return this.screen.canvasHeight;\n }\n /**\n * Returns half height of the game canvas in pixels (half physical height component)\n */ get halfCanvasHeight() {\n return this.screen.halfCanvasHeight;\n }\n /**\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get drawWidth() {\n return this.screen.drawWidth;\n }\n /**\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get halfDrawWidth() {\n return this.screen.halfDrawWidth;\n }\n /**\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get drawHeight() {\n return this.screen.drawHeight;\n }\n /**\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get halfDrawHeight() {\n return this.screen.halfDrawHeight;\n }\n /**\n * Returns whether excalibur detects the current screen to be HiDPI\n */ get isHiDpi() {\n return this.screen.isHiDpi;\n }\n /**\n * Access [[stats]] that holds frame statistics.\n */ get stats() {\n return this.debug.stats;\n }\n /**\n * The current [[Scene]] being drawn and updated on screen\n */ get currentScene() {\n return this.director.currentScene;\n }\n /**\n * The current [[Scene]] being drawn and updated on screen\n */ get currentSceneName() {\n return this.director.currentSceneName;\n }\n /**\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\n */ get rootScene() {\n return this.director.rootScene;\n }\n /**\n * Contains all the scenes currently registered with Excalibur\n */ get scenes() {\n return this.director.scenes;\n }\n /**\n * Indicates whether the engine is set to fullscreen or not\n */ get isFullscreen() {\n return this.screen.isFullScreen;\n }\n /**\n * Indicates the current [[DisplayMode]] of the engine.\n */ get displayMode() {\n return this.screen.displayMode;\n }\n /**\n * Returns the calculated pixel ration for use in rendering\n */ get pixelRatio() {\n return this.screen.pixelRatio;\n }\n get isDebug() {\n return this._isDebug;\n }\n /**\n * Hints the graphics context to truncate fractional world space coordinates\n */ get snapToPixel() {\n return this.graphicsContext.snapToPixel;\n }\n set snapToPixel(shouldSnapToPixel) {\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\n * the game will be rendered full screen (taking up all available browser window space).\n * You can customize the game rendering through [[EngineOptions]].\n *\n * Example:\n *\n * ```js\n * var game = new ex.Engine({\n * width: 0, // the width of the canvas\n * height: 0, // the height of the canvas\n * enableCanvasTransparency: true, // the transparencySection of the canvas\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\n * });\n *\n * // call game.start, which is a Promise\n * game.start().then(function () {\n * // ready, set, go!\n * });\n * ```\n */ constructor(options){\n var _a, _b, _c, _d, _e, _f, _g;\n /**\n * Current Excalibur version string\n *\n * Useful for plugins or other tools that need to know what features are available\n */ this.version = EX_VERSION;\n /**\n * Listen to and emit events on the Engine\n */ this.events = new EventEmitter();\n /**\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\n *\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\n * one that bounces between 30fps and 60fps\n */ this.maxFps = Number.POSITIVE_INFINITY;\n this._inputEnabled = true;\n this._suppressPlayButton = false;\n /**\n * Indicates whether audio should be paused when the game is no longer visible.\n */ this.pauseAudioWhenHidden = true;\n /**\n * Indicates whether the engine should draw with debug information\n */ this._isDebug = false;\n /**\n * Sets the Transparency for the engine.\n */ this.enableCanvasTransparency = true;\n /**\n * The action to take when a fatal exception is thrown\n */ this.onFatalException = (e)=>{\n Logger.getInstance().fatal(e, e.stack);\n };\n this._toaster = new Toaster();\n this._timescale = 1.0;\n this._isInitialized = false;\n this._originalOptions = {};\n this._performanceThresholdTriggered = false;\n this._fpsSamples = [];\n this._disposed = false;\n this._isLoading = false;\n this._hideLoader = false;\n this._isReadyFuture = new Future();\n /**\n * Returns the current frames elapsed milliseconds\n */ this.currentFrameElapsedMs = 0;\n /**\n * Returns the current frame lag when in fixed update mode\n */ this.currentFrameLagMs = 0;\n this._lagMs = 0;\n this._screenShotRequests = [];\n options = {\n ...Engine._DEFAULT_ENGINE_OPTIONS,\n ...options\n };\n this._originalOptions = options;\n Flags.freeze();\n // Initialize browser events facade\n this.browser = new BrowserEvents(window, document);\n // Check compatibility\n const detector = new Detector();\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\n const message = document.createElement(\"div\");\n message.innerText = \"Sorry, your browser does not support all the features needed for Excalibur\";\n document.body.appendChild(message);\n detector.failedTests.forEach(function(test) {\n const testMessage = document.createElement(\"div\");\n testMessage.innerText = \"Browser feature missing \" + test;\n document.body.appendChild(testMessage);\n });\n if (options.canvasElementId) {\n const canvas = document.getElementById(options.canvasElementId);\n if (canvas) canvas.parentElement.removeChild(canvas);\n }\n return;\n } else this._compatible = true;\n // Use native console API for color fun\n // eslint-disable-next-line no-console\n if (console.log && !options.suppressConsoleBootMessage) {\n // eslint-disable-next-line no-console\n console.log(`%cPowered by Excalibur.js (v${EX_VERSION})`, \"background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;\");\n // eslint-disable-next-line no-console\n console.log(\"\\n /| ________________\\nO|===|* >________________>\\n \\\\|\");\n // eslint-disable-next-line no-console\n console.log(\"Visit\", \"http://excaliburjs.com\", \"for more information\");\n }\n // Suppress play button\n if (options.suppressPlayButton) this._suppressPlayButton = true;\n this._logger = Logger.getInstance();\n // If debug is enabled, let's log browser features to the console.\n if (this._logger.defaultLevel === LogLevel.Debug) detector.logBrowserFeatures();\n this._logger.debug(\"Building engine...\");\n this.canvasElementId = options.canvasElementId;\n if (options.canvasElementId) {\n this._logger.debug(\"Using Canvas element specified: \" + options.canvasElementId);\n //test for existence of element\n if (document.getElementById(options.canvasElementId) === null) throw new Error(\"Cannot find existing element in the DOM, please ensure element is created prior to engine creation.\");\n this.canvas = document.getElementById(options.canvasElementId);\n } else if (options.canvasElement) {\n this._logger.debug(\"Using Canvas element specified:\", options.canvasElement);\n this.canvas = options.canvasElement;\n } else {\n this._logger.debug(\"Using generated canvas element\");\n this.canvas = document.createElement(\"canvas\");\n }\n let displayMode = (_a = options.displayMode) !== null && _a !== void 0 ? _a : DisplayMode.Fixed;\n if (options.width && options.height || options.viewport) {\n if (options.displayMode === undefined) displayMode = DisplayMode.Fixed;\n this._logger.debug(\"Engine viewport is size \" + options.width + \" x \" + options.height);\n } else if (!options.displayMode) {\n this._logger.debug(\"Engine viewport is fit\");\n displayMode = DisplayMode.FitScreen;\n }\n this._originalDisplayMode = displayMode;\n let pixelArtSampler;\n let uvPadding;\n let nativeContextAntialiasing;\n let canvasImageRendering;\n let filtering;\n let multiSampleAntialiasing;\n if (typeof options.antialiasing === \"object\") ({ pixelArtSampler: pixelArtSampler, nativeContextAntialiasing: nativeContextAntialiasing, multiSampleAntialiasing: multiSampleAntialiasing, filtering: filtering, canvasImageRendering: canvasImageRendering } = {\n ...options.pixelArt ? DefaultPixelArtOptions : DefaultAntialiasOptions,\n ...options.antialiasing\n });\n else {\n pixelArtSampler = !!options.pixelArt;\n nativeContextAntialiasing = false;\n multiSampleAntialiasing = options.antialiasing;\n canvasImageRendering = options.antialiasing ? \"auto\" : \"pixelated\";\n filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\n }\n if (nativeContextAntialiasing && multiSampleAntialiasing) this._logger.warnOnce(`Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing` + ` at the same time, they are incompatible settings. If you aren\\'t sure use multiSampleAntialiasing`);\n if (options.pixelArt) uvPadding = .25;\n if (!options.antialiasing || filtering === ImageFiltering.Pixel) uvPadding = 0;\n // Override with any user option, if non default to .25 for pixel art, 0.01 for everything else\n uvPadding = (_c = (_b = options.uvPadding) !== null && _b !== void 0 ? _b : uvPadding) !== null && _c !== void 0 ? _c : 0.01;\n // Canvas 2D fallback can be flagged on\n let useCanvasGraphicsContext = Flags.isEnabled(\"use-canvas-context\");\n if (!useCanvasGraphicsContext) // Attempt webgl first\n try {\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n pixelArtSampler: pixelArtSampler,\n antialiasing: nativeContextAntialiasing,\n multiSampleAntialiasing: multiSampleAntialiasing,\n uvPadding: uvPadding,\n powerPreference: options.powerPreference,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n } catch (e) {\n this._logger.warn(`Excalibur could not load webgl for some reason (${e.message}) and loaded a Canvas 2D fallback. ` + `Some features of Excalibur will not work in this mode. \\n\\n` + \"Read more about this issue at https://excaliburjs.com/docs/webgl\");\n // fallback to canvas in case of failure\n useCanvasGraphicsContext = true;\n }\n if (useCanvasGraphicsContext) this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n antialiasing: nativeContextAntialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: nativeContextAntialiasing,\n canvasImageRendering: canvasImageRendering,\n browser: this.browser,\n viewport: (_d = options.viewport) !== null && _d !== void 0 ? _d : options.width && options.height ? {\n width: options.width,\n height: options.height\n } : Resolution.SVGA,\n resolution: options.resolution,\n displayMode: displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : (_e = options.pixelRatio) !== null && _e !== void 0 ? _e : null\n });\n // TODO REMOVE STATIC!!!\n // Set default filtering based on antialiasing\n TextureLoader.filtering = filtering;\n if (options.backgroundColor) this.backgroundColor = options.backgroundColor.clone();\n this.grabWindowFocus = options.grabWindowFocus;\n this.pointerScope = options.pointerScope;\n this.maxFps = (_f = options.maxFps) !== null && _f !== void 0 ? _f : this.maxFps;\n this.fixedUpdateFps = (_g = options.fixedUpdateFps) !== null && _g !== void 0 ? _g : this.fixedUpdateFps;\n this.clock = new StandardClock({\n maxFps: this.maxFps,\n tick: this._mainloop.bind(this),\n onFatalException: (e)=>this.onFatalException(e)\n });\n this.enableCanvasTransparency = options.enableCanvasTransparency;\n if (typeof options.physics === \"boolean\") this.physics = {\n ...DefaultPhysicsConfig,\n ...DeprecatedStaticToConfig(),\n enabled: options.physics\n };\n else this.physics = {\n ...DefaultPhysicsConfig,\n ...DeprecatedStaticToConfig(),\n ...options.physics\n };\n this.debug = new DebugConfig(this);\n this.director = new Director(this, options.scenes);\n this._initialize(options);\n window.___EXCALIBUR_DEVTOOL = this;\n }\n _monitorPerformanceThresholdAndTriggerFallback() {\n const { allow: allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\n let { threshold: threshold, showPlayerMessage: showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\n if (threshold === undefined) threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\n if (showPlayerMessage === undefined) showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\n if (!Flags.isEnabled(\"use-canvas-context\") && allow && this.ready && !this._performanceThresholdTriggered) {\n // Calculate Average fps for last X number of frames after start\n if (this._fpsSamples.length === threshold.numberOfFrames) this._fpsSamples.splice(0, 1);\n this._fpsSamples.push(this.clock.fpsSampler.fps);\n let total = 0;\n for(let i = 0; i < this._fpsSamples.length; i++)total += this._fpsSamples[i];\n const average = total / this._fpsSamples.length;\n if (this._fpsSamples.length === threshold.numberOfFrames) {\n if (average <= threshold.fps) {\n this._performanceThresholdTriggered = true;\n this._logger.warn(`Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` + \"this might mean your browser doesn't have webgl enabled or hardware acceleration is unavailable.\\n\\n\" + \"If in Chrome:\\n\" + ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n' + ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' + \"If in Firefox, visit about:config\\n\" + \" * Ensure webgl.disabled = false\\n\" + \" * Ensure webgl.force-enabled = true\\n\" + \" * Ensure layers.acceleration.force-enabled = true\\n\\n\" + \"Read more about this issue at https://excaliburjs.com/docs/performance\");\n if (showPlayerMessage) this._toaster.toast(\"Excalibur is encountering performance issues. It's possible that your browser doesn't have hardware acceleration enabled. Visit [LINK] for more information and potential solutions.\", \"https://excaliburjs.com/docs/performance\");\n this.useCanvas2DFallback();\n this.emit(\"fallbackgraphicscontext\", this.graphicsContext);\n }\n }\n }\n }\n /**\n * Switches the engine's graphics context to the 2D Canvas.\n * @warning Some features of Excalibur will not work in this mode.\n */ useCanvas2DFallback() {\n var _a, _b, _c;\n // Swap out the canvas\n const newCanvas = this.canvas.cloneNode(false);\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\n this.canvas = newCanvas;\n const options = {\n ...this._originalOptions,\n antialiasing: this.getAntialiasing()\n };\n const displayMode = this._originalDisplayMode;\n // New graphics context\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n antialiasing: options.antialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n // Reset screen\n if (this.screen) this.screen.dispose();\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: (_a = options.antialiasing) !== null && _a !== void 0 ? _a : true,\n browser: this.browser,\n viewport: (_b = options.viewport) !== null && _b !== void 0 ? _b : options.width && options.height ? {\n width: options.width,\n height: options.height\n } : Resolution.SVGA,\n resolution: options.resolution,\n displayMode: displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : (_c = options.pixelRatio) !== null && _c !== void 0 ? _c : null\n });\n this.screen.setCurrentCamera(this.currentScene.camera);\n // Reset pointers\n this.input.pointers.detach();\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\n this.input.pointers.init();\n }\n /**\n * Attempts to completely clean up excalibur resources, including removing the canvas from the dom.\n *\n * To start again you will need to new up an Engine.\n */ dispose() {\n if (!this._disposed) {\n this._disposed = true;\n this.stop();\n this.input.toggleEnabled(false);\n this.canvas.parentNode.removeChild(this.canvas);\n this.canvas = null;\n this.screen.dispose();\n this.graphicsContext.dispose();\n this.graphicsContext = null;\n }\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen\n * and the bottom right corner of the screen.\n */ getWorldBounds() {\n return this.screen.getWorldBounds();\n }\n /**\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\n */ get timescale() {\n return this._timescale;\n }\n /**\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\n * when using time-based movement.\n */ set timescale(value) {\n if (value <= 0) {\n Logger.getInstance().error(\"Cannot set engine.timescale to a value of 0 or less than 0.\");\n return;\n }\n this._timescale = value;\n }\n /**\n * Adds a [[Timer]] to the [[currentScene]].\n * @param timer The timer to add to the [[currentScene]].\n */ addTimer(timer) {\n return this.currentScene.addTimer(timer);\n }\n /**\n * Removes a [[Timer]] from the [[currentScene]].\n * @param timer The timer to remove to the [[currentScene]].\n */ removeTimer(timer) {\n return this.currentScene.removeTimer(timer);\n }\n /**\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\n * would levels or menus.\n * @param key The name of the scene, must be unique\n * @param scene The scene to add to the engine\n */ addScene(key, scene) {\n this.director.add(key, scene);\n return this;\n }\n /**\n * @internal\n */ removeScene(entity) {\n this.director.remove(entity);\n }\n add(entity) {\n if (arguments.length === 2) {\n this.director.add(arguments[0], arguments[1]);\n return;\n }\n const maybeDeferred = this.director.getDeferredScene();\n if (maybeDeferred instanceof Scene) maybeDeferred.add(entity);\n else this.currentScene.add(entity);\n }\n remove(entity) {\n if (entity instanceof Entity) this.currentScene.remove(entity);\n if (entity instanceof Scene || isSceneConstructor(entity)) this.removeScene(entity);\n if (typeof entity === \"string\") this.removeScene(entity);\n }\n /**\n * Changes the current scene with optionally supplied:\n * * Activation data\n * * Transitions\n * * Loaders\n *\n * Example:\n * ```typescript\n * game.goToScene('myScene', {\n * sceneActivationData: {any: 'thing at all'},\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\n * loader: MyLoader\n * });\n * ```\n *\n * Scenes are defined in the Engine constructor\n * ```typescript\n * const engine = new ex.Engine({\n scenes: {...}\n });\n * ```\n * Or by adding dynamically\n *\n * ```typescript\n * engine.addScene('myScene', new ex.Scene());\n * ```\n * @param destinationScene\n * @param options\n * @deprecated use goToScene, it now behaves the same as goto\n */ async goto(destinationScene, options) {\n await this.director.goto(destinationScene, options);\n }\n /**\n * Changes the current scene with optionally supplied:\n * * Activation data\n * * Transitions\n * * Loaders\n *\n * Example:\n * ```typescript\n * game.goToScene('myScene', {\n * sceneActivationData: {any: 'thing at all'},\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\n * loader: MyLoader\n * });\n * ```\n *\n * Scenes are defined in the Engine constructor\n * ```typescript\n * const engine = new ex.Engine({\n scenes: {...}\n });\n * ```\n * Or by adding dynamically\n *\n * ```typescript\n * engine.addScene('myScene', new ex.Scene());\n * ```\n * @param destinationScene\n * @param options\n */ async goToScene(destinationScene, options) {\n await this.director.goto(destinationScene, options);\n }\n /**\n * Transforms the current x, y from screen coordinates to world coordinates\n * @param point Screen coordinate to convert\n */ screenToWorldCoordinates(point) {\n return this.screen.screenToWorldCoordinates(point);\n }\n /**\n * Transforms a world coordinate, to a screen coordinate\n * @param point World coordinate to convert\n */ worldToScreenCoordinates(point) {\n return this.screen.worldToScreenCoordinates(point);\n }\n /**\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\n */ _initialize(options) {\n var _a, _b;\n this.pageScrollPreventionMode = options.scrollPreventionMode;\n // initialize inputs\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n const grabWindowFocus = (_b = (_a = this._originalOptions) === null || _a === void 0 ? void 0 : _a.grabWindowFocus) !== null && _b !== void 0 ? _b : true;\n this.input = new InputHost({\n pointerTarget: pointerTarget,\n grabWindowFocus: grabWindowFocus,\n engine: this\n });\n this.inputMapper = this.input.inputMapper;\n // Issue #385 make use of the visibility api\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\n this.browser.document.on(\"visibilitychange\", ()=>{\n if (document.visibilityState === \"hidden\") {\n this.events.emit(\"hidden\", new HiddenEvent(this));\n this._logger.debug(\"Window hidden\");\n } else if (document.visibilityState === \"visible\") {\n this.events.emit(\"visible\", new VisibleEvent(this));\n this._logger.debug(\"Window visible\");\n }\n });\n if (!this.canvasElementId && !options.canvasElement) document.body.appendChild(this.canvas);\n }\n toggleInputEnabled(enabled) {\n this._inputEnabled = enabled;\n this.input.toggleEnabled(this._inputEnabled);\n }\n onInitialize(engine) {\n // Override me\n }\n /**\n * If supported by the browser, this will set the antialiasing flag on the\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\n * image resources.\n * @param isSmooth Set smoothing to true or false\n * @deprecated Set in engine constructor, will be removed in v0.30\n */ setAntialiasing(isSmooth) {\n this.screen.antialiasing = isSmooth;\n }\n /**\n * Return the current smoothing status of the canvas\n * @deprecated Set in engine constructor, will be removed in v0.30\n */ getAntialiasing() {\n return this.screen.antialiasing;\n }\n /**\n * Gets whether the actor is Initialized\n */ get isInitialized() {\n return this._isInitialized;\n }\n async _overrideInitialize(engine) {\n if (!this.isInitialized) {\n await this.director.onInitialize();\n await this.onInitialize(engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * Updates the entire state of the game\n * @param delta Number of milliseconds elapsed since the last update.\n */ _update(delta) {\n var _a;\n if (this._isLoading) {\n // suspend updates until loading is finished\n (_a = this._loader) === null || _a === void 0 || _a.onUpdate(this, delta);\n // Update input listeners\n this.input.update();\n return;\n }\n // Publish preupdate events\n this._preupdate(delta);\n // process engine level events\n this.currentScene.update(this, delta);\n // Update graphics postprocessors\n this.graphicsContext.updatePostProcessors(delta);\n // Publish update event\n this._postupdate(delta);\n // Update input listeners\n this.input.update();\n }\n /**\n * @internal\n */ _preupdate(delta) {\n this.emit(\"preupdate\", new PreUpdateEvent(this, delta, this));\n this.onPreUpdate(this, delta);\n }\n onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * @internal\n */ _postupdate(delta) {\n this.emit(\"postupdate\", new PostUpdateEvent(this, delta, this));\n this.onPostUpdate(this, delta);\n }\n onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n * Draws the entire game\n * @param delta Number of milliseconds elapsed since the last draw.\n */ _draw(delta) {\n var _a, _b;\n this.graphicsContext.beginDrawLifecycle();\n this.graphicsContext.clear();\n this._predraw(this.graphicsContext, delta);\n // Drawing nothing else while loading\n if (this._isLoading) {\n if (!this._hideLoader) {\n (_a = this._loader) === null || _a === void 0 || _a.canvas.draw(this.graphicsContext, 0, 0);\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n }\n return;\n }\n // Use scene background color if present, fallback to engine\n this.graphicsContext.backgroundColor = (_b = this.currentScene.backgroundColor) !== null && _b !== void 0 ? _b : this.backgroundColor;\n this.currentScene.draw(this.graphicsContext, delta);\n this._postdraw(this.graphicsContext, delta);\n // Flush any pending drawings\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n this._checkForScreenShots();\n }\n /**\n * @internal\n */ _predraw(ctx, delta) {\n this.emit(\"predraw\", new PreDrawEvent(ctx, delta, this));\n this.onPreDraw(ctx, delta);\n }\n onPreDraw(ctx, delta) {\n // Override me\n }\n /**\n * @internal\n */ _postdraw(ctx, delta) {\n this.emit(\"postdraw\", new PostDrawEvent(ctx, delta, this));\n this.onPostDraw(ctx, delta);\n }\n onPostDraw(ctx, delta) {\n // Override me\n }\n /**\n * Enable or disable Excalibur debugging functionality.\n * @param toggle a value that debug drawing will be changed to\n */ showDebug(toggle) {\n this._isDebug = toggle;\n }\n /**\n * Toggle Excalibur debugging functionality.\n */ toggleDebug() {\n this._isDebug = !this._isDebug;\n return this._isDebug;\n }\n /**\n * Returns true when loading is totally complete and the player has clicked start\n */ get loadingComplete() {\n return !this._isLoading;\n }\n get ready() {\n return this._isReadyFuture.isCompleted;\n }\n isReady() {\n return this._isReadyFuture.promise;\n }\n async start(sceneNameOrLoader, options) {\n if (!this._compatible) throw new Error(\"Excalibur is incompatible with your browser\");\n this._isLoading = true;\n let loader;\n if (sceneNameOrLoader instanceof DefaultLoader) loader = sceneNameOrLoader;\n else if (typeof sceneNameOrLoader === \"string\") {\n this.director.configureStart(sceneNameOrLoader, options);\n loader = this.director.mainLoader;\n }\n // Start the excalibur clock which drives the mainloop\n this._logger.debug(\"Starting game clock...\");\n this.browser.resume();\n this.clock.start();\n this._logger.debug(\"Game clock started\");\n await this.load(loader !== null && loader !== void 0 ? loader : new Loader());\n // Initialize before ready\n await this._overrideInitialize(this);\n this._isReadyFuture.resolve();\n this.emit(\"start\", new GameStartEvent(this));\n return this._isReadyFuture.promise;\n }\n _mainloop(elapsed) {\n this.emit(\"preframe\", new PreFrameEvent(this, this.stats.prevFrame));\n const delta = elapsed * this.timescale;\n this.currentFrameElapsedMs = delta;\n // reset frame stats (reuse existing instances)\n const frameId = this.stats.prevFrame.id + 1;\n this.stats.currFrame.reset();\n this.stats.currFrame.id = frameId;\n this.stats.currFrame.delta = delta;\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\n GraphicsDiagnostics.clear();\n const beforeUpdate = this.clock.now();\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\n if (this.fixedUpdateFps) {\n this._lagMs += delta;\n while(this._lagMs >= fixedTimestepMs){\n this._update(fixedTimestepMs);\n this._lagMs -= fixedTimestepMs;\n }\n } else this._update(delta);\n const afterUpdate = this.clock.now();\n this.currentFrameLagMs = this._lagMs;\n this._draw(delta);\n const afterDraw = this.clock.now();\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\n this.emit(\"postframe\", new PostFrameEvent(this, this.stats.currFrame));\n this.stats.prevFrame.reset(this.stats.currFrame);\n this._monitorPerformanceThresholdAndTriggerFallback();\n }\n /**\n * Stops Excalibur's main loop, useful for pausing the game.\n */ stop() {\n if (this.clock.isRunning()) {\n this.emit(\"stop\", new GameStopEvent(this));\n this.browser.pause();\n this.clock.stop();\n this._logger.debug(\"Game stopped\");\n }\n }\n /**\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\n */ isRunning() {\n return this.clock.isRunning();\n }\n /**\n * Takes a screen shot of the current viewport and returns it as an\n * HTML Image Element.\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\n */ screenshot(preserveHiDPIResolution = false) {\n const screenShotPromise = new Promise((resolve)=>{\n this._screenShotRequests.push({\n preserveHiDPIResolution: preserveHiDPIResolution,\n resolve: resolve\n });\n });\n return screenShotPromise;\n }\n _checkForScreenShots() {\n // We must grab the draw buffer before we yield to the browser\n // the draw buffer is cleared after compositing\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\n // forces the browser to copy buffers which can have a mass perf impact on mobile\n for (const request of this._screenShotRequests){\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\n const screenshot = document.createElement(\"canvas\");\n screenshot.width = finalWidth;\n screenshot.height = finalHeight;\n const ctx = screenshot.getContext(\"2d\");\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\n const result = new Image();\n const raw = screenshot.toDataURL(\"image/png\");\n result.src = raw;\n request.resolve(result);\n }\n // Reset state\n this._screenShotRequests.length = 0;\n }\n /**\n * Another option available to you to load resources into the game.\n * Immediately after calling this the game will pause and the loading screen\n * will appear.\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\n */ async load(loader, hideLoader = false) {\n try {\n // early exit if loaded\n if (loader.isLoaded()) return;\n this._loader = loader;\n this._isLoading = true;\n this._hideLoader = hideLoader;\n if (loader instanceof Loader) loader.suppressPlayButton = this._suppressPlayButton;\n this._loader.onInitialize(this);\n await loader.load();\n } catch (e) {\n this._logger.error(\"Error loading resources, things may not behave properly\", e);\n await Promise.resolve();\n } finally{\n this._isLoading = false;\n this._hideLoader = false;\n this._loader = null;\n }\n }\n }\n /**\n * Default [[EngineOptions]]\n */ Engine._DEFAULT_ENGINE_OPTIONS = {\n width: 0,\n height: 0,\n enableCanvasTransparency: true,\n useDrawSorting: true,\n configurePerformanceCanvas2DFallback: {\n allow: false,\n showPlayerMessage: false,\n threshold: {\n fps: 20,\n numberOfFrames: 100\n }\n },\n canvasElementId: \"\",\n canvasElement: undefined,\n snapToPixel: false,\n antialiasing: true,\n pixelArt: false,\n powerPreference: \"high-performance\",\n pointerScope: PointerScope.Canvas,\n suppressConsoleBootMessage: null,\n suppressMinimumBrowserFeatureDetection: null,\n suppressHiDPIScaling: null,\n suppressPlayButton: null,\n grabWindowFocus: true,\n scrollPreventionMode: ScrollPreventionMode.Canvas,\n backgroundColor: Color.fromHex(\"#2185d0\") // Excalibur blue\n };\n /**\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\n */ class EventDispatcher {\n constructor(){\n this._handlers = {};\n this._wiredEventDispatchers = [];\n this._deferedHandlerRemovals = [];\n }\n /**\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\n */ clear() {\n this._handlers = {};\n this._wiredEventDispatchers = [];\n }\n _processDeferredHandlerRemovals() {\n for (const eventHandler of this._deferedHandlerRemovals)this._removeHandler(eventHandler.name, eventHandler.handler);\n this._deferedHandlerRemovals.length = 0;\n }\n /**\n * Emits an event for target\n * @param eventName The name of the event to publish\n * @param event Optionally pass an event data object to the handler\n */ emit(eventName, event) {\n this._processDeferredHandlerRemovals();\n if (!eventName) // key not mapped\n return;\n eventName = eventName.toLowerCase();\n if (typeof event === \"undefined\" || event === null) event = new GameEvent();\n let i, len;\n if (this._handlers[eventName]) {\n i = 0;\n len = this._handlers[eventName].length;\n for(i; i < len; i++)this._handlers[eventName][i](event);\n }\n i = 0;\n len = this._wiredEventDispatchers.length;\n for(i; i < len; i++)this._wiredEventDispatchers[i].emit(eventName, event);\n }\n /**\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\n * @param eventName The name of the event to subscribe to\n * @param handler The handler callback to fire on this event\n */ on(eventName, handler) {\n this._processDeferredHandlerRemovals();\n eventName = eventName.toLowerCase();\n if (!this._handlers[eventName]) this._handlers[eventName] = [];\n this._handlers[eventName].push(handler);\n }\n /**\n * Unsubscribe an event handler(s) from an event. If a specific handler\n * is specified for an event, only that handler will be unsubscribed.\n * Otherwise all handlers will be unsubscribed for that event.\n * @param eventName The name of the event to unsubscribe\n * @param handler Optionally the specific handler to unsubscribe\n */ off(eventName, handler) {\n this._deferedHandlerRemovals.push({\n name: eventName,\n handler: handler\n });\n }\n _removeHandler(eventName, handler) {\n eventName = eventName.toLowerCase();\n const eventHandlers = this._handlers[eventName];\n if (eventHandlers) {\n // if no explicit handler is give with the event name clear all handlers\n if (!handler) this._handlers[eventName].length = 0;\n else {\n const index = eventHandlers.indexOf(handler);\n if (index > -1) this._handlers[eventName].splice(index, 1);\n }\n }\n }\n /**\n * Once listens to an event one time, then unsubscribes from that event\n * @param eventName The name of the event to subscribe to once\n * @param handler The handler of the event that will be auto unsubscribed\n */ once(eventName, handler) {\n this._processDeferredHandlerRemovals();\n const metaHandler = (event)=>{\n const ev = event || new GameEvent();\n this.off(eventName, metaHandler);\n handler(ev);\n };\n this.on(eventName, metaHandler);\n }\n /**\n * Wires this event dispatcher to also receive events from another\n */ wire(eventDispatcher) {\n eventDispatcher._wiredEventDispatchers.push(this);\n }\n /**\n * Unwires this event dispatcher from another\n */ unwire(eventDispatcher) {\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\n if (index > -1) eventDispatcher._wiredEventDispatchers.splice(index, 1);\n }\n }\n /**\n * Labels are the way to draw small amounts of text to the screen. They are\n * actors and inherit all of the benefits and capabilities.\n */ class Label extends Actor {\n get font() {\n return this._font;\n }\n set font(newFont) {\n this._font = newFont;\n this._text.font = newFont;\n }\n /**\n * The text to draw.\n */ get text() {\n return this._text.text;\n }\n set text(text) {\n this._text.text = text;\n }\n get color() {\n return this._text.color;\n }\n set color(color) {\n if (this._text) this._text.color = color;\n }\n get opacity() {\n return this._text.opacity;\n }\n set opacity(opacity) {\n this._text.opacity = opacity;\n }\n /**\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\n */ get spriteFont() {\n return this._spriteFont;\n }\n set spriteFont(sf) {\n if (sf) {\n this._spriteFont = sf;\n this._text.font = this._spriteFont;\n }\n }\n /**\n * Build a new label\n * @param options\n */ constructor(options){\n super(options);\n this._font = new Font();\n this._text = new Text({\n text: \"\",\n font: this._font\n });\n const { text: text, pos: pos, x: x, y: y, spriteFont: spriteFont, font: font, color: color } = {\n text: \"\",\n ...options\n };\n this.pos = pos !== null && pos !== void 0 ? pos : x && y ? vec(x, y) : this.pos;\n this.text = text !== null && text !== void 0 ? text : this.text;\n this.font = font !== null && font !== void 0 ? font : this.font;\n this.spriteFont = spriteFont !== null && spriteFont !== void 0 ? spriteFont : this.spriteFont;\n this._text.color = color !== null && color !== void 0 ? color : this.color;\n const gfx = this.get(GraphicsComponent);\n gfx.anchor = Vector.Zero;\n gfx.use(this._text);\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n /**\n * Returns the width of the text in the label (in pixels);\n */ getTextWidth() {\n return this._text.width;\n }\n }\n class IsometricTile extends Entity {\n getGraphics() {\n return this._graphics;\n }\n /**\n * Tile graphics\n */ addGraphic(graphic, options) {\n this._graphics.push(graphic);\n this._gfx.visible = this.map.visible;\n this._gfx.opacity = this.map.opacity;\n if (options === null || options === void 0 ? void 0 : options.offset) this._gfx.offset = options.offset;\n // TODO detect when this changes on the map and apply to all tiles\n this._gfx.localBounds = this._recalculateBounds();\n }\n _recalculateBounds() {\n let bounds = this._tileBounds.clone();\n for (const graphic of this._graphics){\n const offset = vec(this.map.graphicsOffset.x - this.map.tileWidth / 2, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : graphic.height - this.map.tileHeight));\n bounds = bounds.combine(graphic.localBounds.translate(offset));\n }\n return bounds;\n }\n removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) this._graphics.splice(index, 1);\n this._gfx.localBounds = this._recalculateBounds();\n }\n clearGraphics() {\n this._graphics.length = 0;\n this._gfx.visible = false;\n this._gfx.localBounds = this._recalculateBounds();\n }\n getColliders() {\n return this._colliders;\n }\n /**\n * Adds a collider to the IsometricTile\n *\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\n * @param collider\n */ addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\n * Removes a collider from the IsometricTile\n * @param collider\n */ removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) this._colliders.splice(index, 1);\n this.map.flagCollidersDirty();\n }\n /**\n * Clears all colliders from the IsometricTile\n */ clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n /**\n * Returns the top left corner of the [[IsometricTile]] in world space\n */ get pos() {\n return this.map.tileToWorld(vec(this.x, this.y));\n }\n /**\n * Returns the center of the [[IsometricTile]]\n */ get center() {\n return this.pos.add(vec(0, this.map.tileHeight / 2));\n }\n /**\n * Construct a new IsometricTile\n * @param x tile coordinate in x (not world position)\n * @param y tile coordinate in y (not world position)\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\n * @param map reference to owning IsometricMap\n */ constructor(x, y, graphicsOffset, map){\n super([\n new TransformComponent(),\n new GraphicsComponent({\n offset: graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : Vector.Zero,\n onPostDraw: (gfx, elapsed)=>this.draw(gfx, elapsed)\n }),\n new IsometricEntityComponent(map)\n ]);\n /**\n * Indicates whether this tile is solid\n */ this.solid = false;\n this._tileBounds = new BoundingBox();\n this._graphics = [];\n /**\n * Tile colliders\n */ this._colliders = [];\n /**\n * Arbitrary data storage per tile, useful for any game specific data\n */ this.data = new Map();\n this.x = x;\n this.y = y;\n this.map = map;\n this._transform = this.get(TransformComponent);\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\n const halfTileWidth = this.map.tileWidth / 2;\n const halfTileHeight = this.map.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n // The x position shifts left with every y step\n const xPos = (this.x - this.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (this.x + this.y) * halfTileHeight;\n this._transform.pos = vec(xPos, yPos);\n this._isometricEntityComponent.elevation = map.elevation;\n this._gfx = this.get(GraphicsComponent);\n this._gfx.visible = false; // start not visible\n const totalWidth = this.map.tileWidth;\n const totalHeight = this.map.tileHeight;\n // initial guess at gfx bounds based on the tile\n const offset = vec(0, this.map.renderFromTopOfGraphic ? totalHeight : 0);\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\n left: -totalWidth / 2,\n top: -totalHeight,\n right: totalWidth / 2,\n bottom: totalHeight\n }).translate(offset);\n }\n draw(gfx, _elapsed) {\n const halfTileWidth = this.map.tileWidth / 2;\n gfx.save();\n // shift left origin to corner of map, not the left corner of the first sprite\n gfx.translate(-halfTileWidth, 0);\n for (const graphic of this._graphics)graphic.draw(gfx, this.map.graphicsOffset.x, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : graphic.height - this.map.tileHeight));\n gfx.restore();\n }\n }\n /**\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\n *\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\n *\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\n * your art assets.\n */ class IsometricMap extends Entity {\n constructor(options){\n super([\n new TransformComponent(),\n new BodyComponent({\n type: CollisionType.Fixed\n }),\n new ColliderComponent(),\n new DebugGraphicsComponent((ctx, debugFlags)=>this.debug(ctx, debugFlags), false)\n ], options.name);\n this.elevation = 0;\n /**\n * Whether tiles should be visible\n */ this.visible = true;\n /**\n * Opacity of tiles\n */ this.opacity = 1.0;\n /**\n * Render the tile graphic from the top instead of the bottom\n *\n * default is `false` meaning rendering from the bottom\n */ this.renderFromTopOfGraphic = false;\n this.graphicsOffset = vec(0, 0);\n this._collidersDirty = false;\n this._originalOffsets = new WeakMap();\n const { pos: pos, tileWidth: tileWidth, tileHeight: tileHeight, columns: width, rows: height, renderFromTopOfGraphic: renderFromTopOfGraphic, graphicsOffset: graphicsOffset, elevation: elevation } = options;\n this.transform = this.get(TransformComponent);\n if (pos) this.transform.pos = pos;\n this.collider = this.get(ColliderComponent);\n if (this.collider) this.collider.set(this._composite = new CompositeCollider([]));\n this.renderFromTopOfGraphic = renderFromTopOfGraphic !== null && renderFromTopOfGraphic !== void 0 ? renderFromTopOfGraphic : this.renderFromTopOfGraphic;\n this.graphicsOffset = graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : this.graphicsOffset;\n this.elevation = elevation !== null && elevation !== void 0 ? elevation : this.elevation;\n this.tileWidth = tileWidth;\n this.tileHeight = tileHeight;\n this.columns = width;\n this.rows = height;\n this.tiles = new Array(width * height);\n // build up tile representation\n for(let y = 0; y < height; y++)for(let x = 0; x < width; x++){\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\n this.tiles[x + y * width] = tile;\n this.addChild(tile);\n }\n }\n update() {\n if (this._collidersDirty) {\n this.updateColliders();\n this._collidersDirty = false;\n }\n }\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n } else return this._originalOffsets.get(collider);\n }\n updateColliders() {\n this._composite.clearColliders();\n const pos = this.get(TransformComponent).pos;\n for (const tile of this.tiles){\n if (tile.solid) for (const collider of tile.getColliders()){\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = this.tileToWorld(vec(tile.x, tile.y)).sub(pos).add(originalOffset).sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n }\n this.collider.update();\n }\n /**\n * Convert world space coordinates to the tile x, y coordinate\n * @param worldCoordinate\n */ worldToTile(worldCoordinate) {\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n return vec(~~((worldCoordinate.x / halfTileWidth + worldCoordinate.y / halfTileHeight) / 2), ~~((worldCoordinate.y / halfTileHeight - worldCoordinate.x / halfTileWidth) / 2));\n }\n /**\n * Given a tile coordinate, return the top left corner in world space\n * @param tileCoordinate\n */ tileToWorld(tileCoordinate) {\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // The x position shifts left with every y step\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\n return vec(xPos, yPos).add(this.transform.pos);\n }\n /**\n * Returns the [[IsometricTile]] by its x and y coordinates\n */ getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) return null;\n return this.tiles[x + y * this.columns];\n }\n /**\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\n * returns `null` if no Tile was found.\n */ getTileByPoint(point) {\n const tileCoord = this.worldToTile(point);\n const tile = this.getTile(tileCoord.x, tileCoord.y);\n return tile;\n }\n _getMaxZIndex() {\n let maxZ = Number.NEGATIVE_INFINITY;\n for (const tile of this.tiles){\n const currentZ = tile.get(TransformComponent).z;\n if (currentZ > maxZ) maxZ = currentZ;\n }\n return maxZ;\n }\n /**\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\n * @param gfx\n */ debug(gfx, debugFlags) {\n const { showAll: showAll, showPosition: showPosition, positionColor: positionColor, positionSize: positionSize, showGrid: showGrid, gridColor: gridColor, gridWidth: gridWidth, showColliderGeometry: showColliderGeometry } = debugFlags.isometric;\n const { geometryColor: geometryColor, geometryLineWidth: geometryLineWidth, geometryPointSize: geometryPointSize } = debugFlags.collider;\n gfx.save();\n gfx.z = this._getMaxZIndex() + 0.5;\n if (showAll || showGrid) {\n for(let y = 0; y < this.rows + 1; y++){\n const left = this.tileToWorld(vec(0, y));\n const right = this.tileToWorld(vec(this.columns, y));\n gfx.drawLine(left, right, gridColor, gridWidth);\n }\n for(let x = 0; x < this.columns + 1; x++){\n const top = this.tileToWorld(vec(x, 0));\n const bottom = this.tileToWorld(vec(x, this.rows));\n gfx.drawLine(top, bottom, gridColor, gridWidth);\n }\n }\n if (showAll || showPosition) for (const tile of this.tiles)gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), positionSize, positionColor);\n if (showAll || showColliderGeometry) for (const tile of this.tiles){\n if (tile.solid) for (const collider of tile.getColliders())collider.debug(gfx, geometryColor, {\n lineWidth: geometryLineWidth,\n pointSize: geometryPointSize\n });\n }\n gfx.restore();\n }\n }\n /**\n * Action that can represent a sequence of actions, this can be useful in conjunction with\n * [[ParallelActions]] to run multiple sequences in parallel.\n */ class ActionSequence {\n constructor(entity, actionBuilder){\n this._stopped = false;\n this._sequenceBuilder = actionBuilder;\n this._sequenceContext = new ActionContext(entity);\n this._actionQueue = this._sequenceContext.getQueue();\n this._sequenceBuilder(this._sequenceContext);\n }\n update(delta) {\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || this._actionQueue.isComplete();\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._stopped = false;\n this._actionQueue.reset();\n }\n clone(entity) {\n return new ActionSequence(entity, this._sequenceBuilder);\n }\n }\n /**\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\n */ class ParallelActions {\n constructor(parallelActions){\n this._actions = parallelActions;\n }\n update(delta) {\n for(let i = 0; i < this._actions.length; i++)this._actions[i].update(delta);\n }\n isComplete(entity) {\n return this._actions.every((a)=>a.isComplete(entity));\n }\n reset() {\n this._actions.forEach((a)=>a.reset());\n }\n stop() {\n this._actions.forEach((a)=>a.stop());\n }\n }\n /**\n * QuadTree spatial data structure. Useful for quickly retrieving all objects that might\n * be in a specific location.\n */ class QuadTree {\n constructor(bounds, options){\n this.bounds = bounds;\n this.options = options;\n this._defaultOptions = {\n maxDepth: 10,\n capacity: 10,\n level: 0\n };\n this.items = [];\n this._isDivided = false;\n this.topLeft = null;\n this.topRight = null;\n this.bottomLeft = null;\n this.bottomRight = null;\n this.options = {\n ...this._defaultOptions,\n ...options\n };\n this.halfWidth = bounds.width / 2;\n this.halfHeight = bounds.height / 2;\n }\n /**\n * Splits the quad tree one level deeper\n */ _split() {\n this._isDivided = true;\n const newLevelOptions = {\n maxDepth: this.options.maxDepth,\n capacity: this.options.capacity,\n level: this.options.level + 1\n };\n this.topLeft = new QuadTree(new BoundingBox({\n left: this.bounds.left,\n top: this.bounds.top,\n right: this.bounds.left + this.halfWidth,\n bottom: this.bounds.top + this.halfHeight\n }), newLevelOptions);\n this.topRight = new QuadTree(new BoundingBox({\n left: this.bounds.left + this.halfWidth,\n top: this.bounds.top,\n right: this.bounds.right,\n bottom: this.bounds.top + this.halfHeight\n }), newLevelOptions);\n this.bottomLeft = new QuadTree(new BoundingBox({\n left: this.bounds.left,\n top: this.bounds.top + this.halfHeight,\n right: this.bounds.left + this.halfWidth,\n bottom: this.bounds.bottom\n }), newLevelOptions);\n this.bottomRight = new QuadTree(new BoundingBox({\n left: this.bounds.left + this.halfWidth,\n top: this.bounds.top + this.halfHeight,\n right: this.bounds.right,\n bottom: this.bounds.bottom\n }), newLevelOptions);\n }\n _insertIntoSubNodes(item) {\n var _a, _b, _c, _d;\n if ((_a = this.topLeft) === null || _a === void 0 ? void 0 : _a.bounds.overlaps(item.bounds)) this.topLeft.insert(item);\n if ((_b = this.topRight) === null || _b === void 0 ? void 0 : _b.bounds.overlaps(item.bounds)) this.topRight.insert(item);\n if ((_c = this.bottomLeft) === null || _c === void 0 ? void 0 : _c.bounds.overlaps(item.bounds)) this.bottomLeft.insert(item);\n if ((_d = this.bottomRight) === null || _d === void 0 ? void 0 : _d.bounds.overlaps(item.bounds)) this.bottomRight.insert(item);\n }\n /**\n * Insert an item to be tracked in the QuadTree\n * @param item\n */ insert(item) {\n // add to subnodes if it matches\n if (this._isDivided) {\n this._insertIntoSubNodes(item);\n return;\n }\n // leaf case\n this.items.push(item);\n // capacity\n if (this.items.length > this.options.capacity && this.options.level < this.options.maxDepth) {\n if (!this._isDivided) this._split();\n // divide this level's items into it's subnodes\n for (const item of this.items)this._insertIntoSubNodes(item);\n // clear this level\n this.items.length = 0;\n }\n }\n /**\n * Remove a tracked item in the QuadTree\n * @param item\n */ remove(item) {\n var _a, _b, _c, _d;\n if (!this.bounds.overlaps(item.bounds)) return;\n if (!this._isDivided) {\n const index = this.items.indexOf(item);\n if (index > -1) this.items.splice(index, 1);\n return;\n }\n if ((_a = this.topLeft) === null || _a === void 0 ? void 0 : _a.bounds.overlaps(item.bounds)) this.topLeft.remove(item);\n if ((_b = this.topRight) === null || _b === void 0 ? void 0 : _b.bounds.overlaps(item.bounds)) this.topRight.remove(item);\n if ((_c = this.bottomLeft) === null || _c === void 0 ? void 0 : _c.bounds.overlaps(item.bounds)) this.bottomLeft.remove(item);\n if ((_d = this.bottomRight) === null || _d === void 0 ? void 0 : _d.bounds.overlaps(item.bounds)) this.bottomRight.remove(item);\n }\n /**\n * Query the structure for all objects that intersect the bounding box\n * @param boundingBox\n * @returns items\n */ query(boundingBox) {\n let results = this.items;\n if (this._isDivided) {\n if (this.topLeft.bounds.overlaps(boundingBox)) results = results.concat(this.topLeft.query(boundingBox));\n if (this.topRight.bounds.overlaps(boundingBox)) results = results.concat(this.topRight.query(boundingBox));\n if (this.bottomLeft.bounds.overlaps(boundingBox)) results = results.concat(this.bottomLeft.query(boundingBox));\n if (this.bottomRight.bounds.overlaps(boundingBox)) results = results.concat(this.bottomRight.query(boundingBox));\n }\n results = results.filter((item, index)=>{\n return results.indexOf(item) >= index;\n });\n return results;\n }\n clear() {\n this.items = [];\n this._isDivided = false;\n this.topLeft = null;\n this.topRight = null;\n this.bottomLeft = null;\n this.bottomRight = null;\n }\n getAllItems() {\n let results = this.items;\n if (this._isDivided) {\n results = results.concat(this.topLeft.getAllItems());\n results = results.concat(this.topRight.getAllItems());\n results = results.concat(this.bottomLeft.getAllItems());\n results = results.concat(this.bottomRight.getAllItems());\n }\n results = results.filter((item, index)=>{\n return results.indexOf(item) >= index;\n });\n return results;\n }\n getTreeDepth() {\n if (!this._isDivided) return 0;\n return 1 + Math.max(this.topLeft.getTreeDepth(), this.topRight.getTreeDepth(), this.bottomLeft.getTreeDepth(), this.bottomRight.getTreeDepth());\n }\n debug(ctx) {\n this.bounds.draw(ctx, Color.Yellow);\n if (this._isDivided) {\n this.topLeft.bounds.draw(ctx, Color.Yellow);\n this.topRight.bounds.draw(ctx, Color.Yellow);\n this.bottomLeft.bounds.draw(ctx, Color.Yellow);\n this.bottomRight.bounds.draw(ctx, Color.Yellow);\n }\n }\n }\n /**\n * Type guard checking for internal initialize method\n * @internal\n * @param a\n */ function has_initialize(a) {\n return !!a._initialize;\n }\n /**\n *\n */ function hasOnInitialize(a) {\n return !!a.onInitialize;\n }\n /**\n *\n */ function has_preupdate(a) {\n return !!a._preupdate;\n }\n /**\n *\n */ function hasOnPreUpdate(a) {\n return !!a.onPreUpdate;\n }\n /**\n *\n */ function has_postupdate(a) {\n return !!a.onPostUpdate;\n }\n /**\n *\n */ function hasOnPostUpdate(a) {\n return !!a.onPostUpdate;\n }\n /**\n *\n */ function hasPreDraw(a) {\n return !!a.onPreDraw;\n }\n /**\n *\n */ function hasPostDraw(a) {\n return !!a.onPostDraw;\n }\n /**\n * The [[Texture]] object allows games built in Excalibur to load image resources.\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\n * to pre-load before starting a level or game.\n */ class Gif {\n /**\n * @param path Path to the image resource\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\n * @param bustCache Optionally load texture with cache busting\n */ constructor(path, color = Color.Magenta, bustCache = false){\n this.path = path;\n this.color = color;\n this._stream = null;\n this._gif = null;\n this._textures = [];\n this._animation = null;\n this._transparentColor = null;\n this._resource = new Resource(path, \"arraybuffer\", bustCache);\n this._transparentColor = color;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * Begins loading the texture and returns a promise to be resolved on completion\n */ async load() {\n const arraybuffer = await this._resource.load();\n this._stream = new Stream(arraybuffer);\n this._gif = new ParseGif(this._stream, this._transparentColor);\n const images = this._gif.images.map((i)=>new ImageSource(i.src, false));\n // Load all textures\n await Promise.all(images.map((t)=>t.load()));\n return this.data = this._textures = images;\n }\n isLoaded() {\n return !!this.data;\n }\n /**\n * Return a frame of the gif as a sprite by id\n * @param id\n */ toSprite(id = 0) {\n const sprite = this._textures[id].toSprite();\n return sprite;\n }\n /**\n * Return the gif as a spritesheet\n */ toSpriteSheet() {\n const sprites = this._textures.map((image)=>{\n return image.toSprite();\n });\n return new SpriteSheet({\n sprites: sprites\n });\n }\n /**\n * Transform the GIF into an animation with duration per frame\n */ toAnimation(durationPerFrameMs) {\n const spriteSheet = this.toSpriteSheet();\n const length = spriteSheet.sprites.length;\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\n return this._animation;\n }\n get readCheckBytes() {\n return this._gif.checkBytes;\n }\n }\n const bitsToNum = (ba)=>{\n return ba.reduce(function(s, n) {\n return s * 2 + n;\n }, 0);\n };\n const byteToBitArr = (bite)=>{\n const a = [];\n for(let i = 7; i >= 0; i--)a.push(!!(bite & 1 << i));\n return a;\n };\n class Stream {\n constructor(dataArray){\n this.data = null;\n this.len = 0;\n this.position = 0;\n this.readByte = ()=>{\n if (this.position >= this.data.byteLength) throw new Error(\"Attempted to read past end of stream.\");\n return this.data[this.position++];\n };\n this.readBytes = (n)=>{\n const bytes = [];\n for(let i = 0; i < n; i++)bytes.push(this.readByte());\n return bytes;\n };\n this.read = (n)=>{\n let s = \"\";\n for(let i = 0; i < n; i++)s += String.fromCharCode(this.readByte());\n return s;\n };\n this.readUnsigned = ()=>{\n // Little-endian.\n const a = this.readBytes(2);\n return (a[1] << 8) + a[0];\n };\n this.data = new Uint8Array(dataArray);\n this.len = this.data.byteLength;\n if (this.len === 0) throw new Error(\"No data loaded from file\");\n }\n }\n const lzwDecode = function(minCodeSize, data) {\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\n const readCode = function(size) {\n let code = 0;\n for(let i = 0; i < size; i++){\n if (data.charCodeAt(pos >> 3) & 1 << (pos & 7)) code |= 1 << i;\n pos++;\n }\n return code;\n };\n const output = [];\n const clearCode = 1 << minCodeSize;\n const eoiCode = clearCode + 1;\n let codeSize = minCodeSize + 1;\n let dict = [];\n const clear = function() {\n dict = [];\n codeSize = minCodeSize + 1;\n for(let i = 0; i < clearCode; i++)dict[i] = [\n i\n ];\n dict[clearCode] = [];\n dict[eoiCode] = null;\n };\n let code;\n let last;\n while(true){\n last = code;\n code = readCode(codeSize);\n if (code === clearCode) {\n clear();\n continue;\n }\n if (code === eoiCode) break;\n if (code < dict.length) {\n if (last !== clearCode) dict.push(dict[last].concat(dict[code][0]));\n } else {\n if (code !== dict.length) throw new Error(\"Invalid LZW code.\");\n dict.push(dict[last].concat(dict[last][0]));\n }\n output.push.apply(output, dict[code]);\n if (dict.length === 1 << codeSize && codeSize < 12) // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\n codeSize++;\n }\n // I don't know if this is technically an error, but some GIFs do it.\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\n return output;\n };\n // The actual parsing; returns an object with properties.\n class ParseGif {\n constructor(stream, color = Color.Magenta){\n this._st = null;\n this._handler = {};\n this._transparentColor = null;\n this.frames = [];\n this.images = [];\n this.globalColorTable = [];\n this.checkBytes = [];\n // LZW (GIF-specific)\n this.parseColorTable = (entries)=>{\n // Each entry is 3 bytes, for RGB.\n const ct = [];\n for(let i = 0; i < entries; i++){\n const rgb = this._st.readBytes(3);\n const rgba = \"#\" + rgb.map((x)=>{\n const hex = x.toString(16);\n return hex.length === 1 ? \"0\" + hex : hex;\n }).join(\"\");\n ct.push(rgba);\n }\n return ct;\n };\n this.readSubBlocks = ()=>{\n let size, data;\n data = \"\";\n do {\n size = this._st.readByte();\n data += this._st.read(size);\n }while (size !== 0);\n return data;\n };\n this.parseHeader = ()=>{\n const hdr = {\n sig: null,\n ver: null,\n width: null,\n height: null,\n colorRes: null,\n globalColorTableSize: null,\n gctFlag: null,\n sorted: null,\n globalColorTable: [],\n bgColor: null,\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n };\n hdr.sig = this._st.read(3);\n hdr.ver = this._st.read(3);\n if (hdr.sig !== \"GIF\") throw new Error(\"Not a GIF file.\"); // XXX: This should probably be handled more nicely.\n hdr.width = this._st.readUnsigned();\n hdr.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n hdr.gctFlag = bits.shift();\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\n hdr.sorted = bits.shift();\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\n hdr.bgColor = this._st.readByte();\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n if (hdr.gctFlag) {\n hdr.globalColorTable = this.parseColorTable(1 << hdr.globalColorTableSize + 1);\n this.globalColorTable = hdr.globalColorTable;\n }\n if (this._handler.hdr && this._handler.hdr(hdr)) this.checkBytes.push(this._handler.hdr);\n };\n this.parseExt = (block)=>{\n const parseGCExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 4\n const bits = byteToBitArr(this._st.readByte());\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\n block.userInput = bits.shift();\n block.transparencyGiven = bits.shift();\n block.delayTime = this._st.readUnsigned();\n block.transparencyIndex = this._st.readByte();\n block.terminator = this._st.readByte();\n if (this._handler.gce && this._handler.gce(block)) this.checkBytes.push(this._handler.gce);\n };\n const parseComExt = (block)=>{\n block.comment = this.readSubBlocks();\n if (this._handler.com && this._handler.com(block)) this.checkBytes.push(this._handler.com);\n };\n const parsePTExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 12\n block.ptHeader = this._st.readBytes(12);\n block.ptData = this.readSubBlocks();\n if (this._handler.pte && this._handler.pte(block)) this.checkBytes.push(this._handler.pte);\n };\n const parseAppExt = (block)=>{\n const parseNetscapeExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 3\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\n block.iterations = this._st.readUnsigned();\n block.terminator = this._st.readByte();\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) this.checkBytes.push(this._handler.app);\n };\n const parseUnknownAppExt = (block)=>{\n block.appData = this.readSubBlocks();\n // FIXME: This won't work if a handler wants to match on any identifier.\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) this.checkBytes.push(this._handler.app[block.identifier]);\n };\n this.checkBytes.push(this._st.readByte()); // Always 11\n block.identifier = this._st.read(8);\n block.authCode = this._st.read(3);\n switch(block.identifier){\n case \"NETSCAPE\":\n parseNetscapeExt(block);\n break;\n default:\n parseUnknownAppExt(block);\n break;\n }\n };\n const parseUnknownExt = (block)=>{\n block.data = this.readSubBlocks();\n if (this._handler.unknown && this._handler.unknown(block)) this.checkBytes.push(this._handler.unknown);\n };\n block.label = this._st.readByte();\n switch(block.label){\n case 0xf9:\n block.extType = \"gce\";\n parseGCExt(block);\n break;\n case 0xfe:\n block.extType = \"com\";\n parseComExt(block);\n break;\n case 0x01:\n block.extType = \"pte\";\n parsePTExt(block);\n break;\n case 0xff:\n block.extType = \"app\";\n parseAppExt(block);\n break;\n default:\n block.extType = \"unknown\";\n parseUnknownExt(block);\n break;\n }\n };\n this.parseImg = (img)=>{\n const deinterlace = (pixels, width)=>{\n // Of course this defeats the purpose of interlacing. And it's *probably*\n // the least efficient way it's ever been implemented. But nevertheless...\n const newPixels = new Array(pixels.length);\n const rows = pixels.length / width;\n const cpRow = (toRow, fromRow)=>{\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\n newPixels.splice.apply(newPixels, [\n toRow * width,\n width\n ].concat(fromPixels));\n };\n const offsets = [\n 0,\n 4,\n 2,\n 1\n ];\n const steps = [\n 8,\n 8,\n 4,\n 2\n ];\n let fromRow = 0;\n for(let pass = 0; pass < 4; pass++)for(let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]){\n cpRow(toRow, fromRow);\n fromRow++;\n }\n return newPixels;\n };\n img.leftPos = this._st.readUnsigned();\n img.topPos = this._st.readUnsigned();\n img.width = this._st.readUnsigned();\n img.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n img.lctFlag = bits.shift();\n img.interlaced = bits.shift();\n img.sorted = bits.shift();\n img.reserved = bits.splice(0, 2);\n img.lctSize = bitsToNum(bits.splice(0, 3));\n if (img.lctFlag) img.lct = this.parseColorTable(1 << img.lctSize + 1);\n img.lzwMinCodeSize = this._st.readByte();\n const lzwData = this.readSubBlocks();\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\n if (img.interlaced) // Move\n img.pixels = deinterlace(img.pixels, img.width);\n this.frames.push(img);\n this.arrayToImage(img);\n if (this._handler.img && this._handler.img(img)) this.checkBytes.push(this._handler);\n };\n this.parseBlock = ()=>{\n const block = {\n sentinel: this._st.readByte(),\n type: \"\"\n };\n const blockChar = String.fromCharCode(block.sentinel);\n switch(blockChar){\n case \"!\":\n block.type = \"ext\";\n this.parseExt(block);\n break;\n case \",\":\n block.type = \"img\";\n this.parseImg(block);\n break;\n case \";\":\n block.type = \"eof\";\n if (this._handler.eof && this._handler.eof(block)) this.checkBytes.push(this._handler.eof);\n break;\n default:\n throw new Error(\"Unknown block: 0x\" + block.sentinel.toString(16));\n }\n if (block.type !== \"eof\") this.parseBlock();\n };\n this.arrayToImage = (frame)=>{\n let count = 0;\n const c = document.createElement(\"canvas\");\n c.id = count.toString();\n c.width = frame.width;\n c.height = frame.height;\n count++;\n const context = c.getContext(\"2d\");\n const pixSize = 1;\n let y = 0;\n let x = 0;\n for(let i = 0; i < frame.pixels.length; i++){\n if (x % frame.width === 0) {\n y++;\n x = 0;\n }\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) context.fillStyle = `rgba(0, 0, 0, 0)`;\n else context.fillStyle = this.globalColorTable[frame.pixels[i]];\n context.fillRect(x, y, pixSize, pixSize);\n x++;\n }\n const img = new Image();\n img.src = c.toDataURL();\n this.images.push(img);\n };\n this._st = stream;\n this._handler = {};\n this._transparentColor = color;\n this.parseHeader();\n this.parseBlock();\n }\n }\n class FontSource {\n constructor(/**\n * Path to the font resource relative from the HTML document hosting the game, or absolute\n */ path, /**\n * The font family name\n */ family, { bustCache: bustCache, ...options } = {}){\n this.path = path;\n this.family = family;\n this._isLoaded = false;\n this._resource = new Resource(path, \"blob\", bustCache);\n this._options = options;\n }\n async load() {\n if (this.isLoaded()) return this.data;\n try {\n const blob = await this._resource.load();\n const url = URL.createObjectURL(blob);\n if (!this.data) {\n this.data = new FontFace(this.family, `url(${url})`);\n document.fonts.add(this.data);\n }\n await this.data.load();\n this._isLoaded = true;\n } catch (error) {\n throw `Error loading FontSource from path '${this.path}' with error [${error.message}]`;\n }\n return this.data;\n }\n isLoaded() {\n return this._isLoaded;\n }\n /**\n * Build a font from this FontSource.\n * @param options {FontOptions} Override the font options\n */ toFont(options) {\n return new Font({\n family: this.family,\n ...this._options,\n ...options\n });\n }\n }\n /**\n * Excalibur coroutine helper, returns a promise when complete. Coroutines run before frame update.\n *\n * Each coroutine yield is 1 excalibur frame. Coroutines get passed the elapsed time our of yield. Coroutines\n * run internally on the excalibur clock.\n *\n * If you yield a promise it will be awaited before resumed\n * If you yield a number it will wait that many ms before resumed\n * @param engine\n * @param coroutineGenerator\n */ function coroutine(engine, coroutineGenerator) {\n return new Promise((resolve, reject)=>{\n const generator = coroutineGenerator();\n const loop = (elapsedMs)=>{\n try {\n const { done: done, value: value } = generator.next(elapsedMs);\n if (done) resolve();\n if (value instanceof Promise) value.then(()=>{\n // schedule next loop\n engine.clock.schedule(loop);\n });\n else if (value === undefined || value === void 0) // schedule next frame\n engine.clock.schedule(loop);\n else // schedule value milliseconds from now\n engine.clock.schedule(loop, value || 0);\n } catch (e) {\n reject(e);\n }\n };\n loop(engine.clock.elapsed()); // run first frame immediately\n });\n }\n /**\n * Base Transition that can be extended to provide custom scene transitions in Excalibur.\n */ class Transition extends Entity {\n /**\n * Returns a number between [0, 1] indicating what state the transition is in.\n *\n * * For 'out' direction transitions start at 0 and end at 1\n * * For 'in' direction transitions start at 1 and end at 0\n */ get progress() {\n return this._currentProgress;\n }\n get complete() {\n if (this.direction === \"out\") return this.progress >= 1;\n else return this.progress <= 0;\n }\n constructor(options){\n var _a, _b, _c, _d;\n super();\n this._logger = Logger.getInstance();\n this.transform = new TransformComponent();\n this.graphics = new GraphicsComponent();\n this._completeFuture = new Future();\n // State needs to be reset between uses\n this.started = false;\n this._currentDistance = 0;\n this._currentProgress = 0;\n this.done = this._completeFuture.promise;\n this.name = `Transition#${this.id}`;\n this.duration = options.duration;\n this.easing = (_a = options.easing) !== null && _a !== void 0 ? _a : EasingFunctions.Linear;\n this.direction = (_b = options.direction) !== null && _b !== void 0 ? _b : \"out\";\n this.hideLoader = (_c = options.hideLoader) !== null && _c !== void 0 ? _c : false;\n this.blockInput = (_d = options.blockInput) !== null && _d !== void 0 ? _d : false;\n this.transform.coordPlane = CoordPlane.Screen;\n this.transform.pos = Vector.Zero;\n this.transform.z = Infinity; // Transitions sit on top of everything\n this.graphics.anchor = Vector.Zero;\n this.addComponent(this.transform);\n this.addComponent(this.graphics);\n if (this.direction === \"out\") this._currentProgress = 0;\n else this._currentProgress = 1;\n }\n /**\n * Overridable lifecycle method, called before each update.\n *\n * **WARNING BE SURE** to call `super.updateTransition()` if overriding in your own custom implementation\n * @param engine\n * @param delta\n */ updateTransition(engine, delta) {\n if (this.complete) return;\n this._currentDistance += clamp(delta / this.duration, 0, 1);\n if (this._currentDistance >= 1) this._currentDistance = 1;\n if (this.direction === \"out\") this._currentProgress = clamp(this.easing(this._currentDistance, 0, 1, 1), 0, 1);\n else this._currentProgress = clamp(this.easing(this._currentDistance, 1, 0, 1), 0, 1);\n }\n /**\n * Overridable lifecycle method, called right before the previous scene has deactivated.\n *\n * This gives incoming transition a chance to grab info from previous scene if desired\n * @param scene\n */ async onPreviousSceneDeactivate(scene) {\n // override me\n }\n /**\n * Overridable lifecycle method, called once at the beginning of the transition\n *\n * `progress` is given between 0 and 1\n * @param progress\n */ onStart(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called every frame of the transition\n *\n * `progress` is given between 0 and 1\n * @param progress\n */ onUpdate(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called at the end of the transition,\n *\n * `progress` is given between 0 and 1\n * @param progress\n */ onEnd(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called when the transition is reset\n *\n * Use this to override and provide your own reset logic for internal state in custom transition implementations\n */ onReset() {\n // override me\n }\n /**\n * reset() is called by the engine to reset transitions\n */ reset() {\n this.started = false;\n this._completeFuture = new Future();\n this.done = this._completeFuture.promise;\n this._currentDistance = 0;\n if (this.direction === \"out\") this._currentProgress = 0;\n else this._currentProgress = 1;\n this.onReset();\n }\n play(engine, targetScene) {\n if (this.started) {\n this.reset();\n this._logger.warn(`Attempted to play a transition ${this.name} that is already playing, reset transition.`);\n }\n const currentScene = targetScene !== null && targetScene !== void 0 ? targetScene : engine.currentScene;\n currentScene.add(this);\n const self1 = this;\n return coroutine(engine, function*() {\n while(!self1.complete){\n const elapsed = yield; // per frame\n self1.updateTransition(engine, elapsed);\n self1.execute();\n }\n });\n }\n /**\n * execute() is called by the engine every frame to update the Transition lifecycle onStart/onUpdate/onEnd\n */ execute() {\n if (!this.isInitialized) return;\n if (!this.started) {\n this.started = true;\n this.onStart(this.progress);\n }\n this.onUpdate(this.progress);\n if (this.complete && !this._completeFuture.isCompleted) {\n this.onEnd(this.progress);\n this._completeFuture.resolve();\n }\n }\n }\n class FadeInOut extends Transition {\n constructor(options){\n var _a, _b;\n super({\n ...options,\n duration: (_a = options.duration) !== null && _a !== void 0 ? _a : 2000\n });\n this.name = `FadeInOut#${this.id}`;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n }\n onInitialize(engine) {\n this.transform.pos = engine.screen.unsafeArea.topLeft;\n this.screenCover = new Rectangle({\n width: engine.screen.resolution.width,\n height: engine.screen.resolution.height,\n color: this.color\n });\n this.graphics.add(this.screenCover);\n this.graphics.opacity = this.progress;\n }\n onReset() {\n this.graphics.opacity = this.progress;\n }\n onStart(progress) {\n this.graphics.opacity = progress;\n }\n onEnd(progress) {\n this.graphics.opacity = progress;\n }\n onUpdate(progress) {\n this.graphics.opacity = progress;\n }\n }\n /**\n * CrossFades between the previous scene and the destination scene\n *\n * Note: CrossFade only works as an \"in\" transition\n */ class CrossFade extends Transition {\n constructor(options){\n super({\n direction: \"in\",\n ...options\n }); // default the correct direction\n this.name = `CrossFade#${this.id}`;\n }\n async onPreviousSceneDeactivate(scene) {\n this.image = await scene.engine.screenshot(true);\n // Firefox is particularly slow\n // needed in case the image isn't ready yet\n await this.image.decode();\n }\n onInitialize(engine) {\n this.engine = engine;\n this.transform.pos = engine.screen.unsafeArea.topLeft;\n this.screenCover = ImageSource.fromHtmlImageElement(this.image).toSprite();\n this.graphics.add(this.screenCover);\n this.transform.scale = vec(1 / engine.screen.pixelRatio, 1 / engine.screen.pixelRatio);\n this.graphics.opacity = this.progress;\n }\n onStart(_progress) {\n this.graphics.opacity = this.progress;\n }\n onReset() {\n this.graphics.opacity = this.progress;\n }\n onEnd(progress) {\n this.graphics.opacity = progress;\n }\n onUpdate(progress) {\n this.graphics.opacity = progress;\n }\n }\n class Line extends Graphic {\n constructor(options){\n super();\n this.color = Color.Black;\n this.thickness = 1;\n const { start: start, end: end, color: color, thickness: thickness } = options;\n this.start = start;\n this.end = end;\n this.color = color !== null && color !== void 0 ? color : this.color;\n this.thickness = thickness !== null && thickness !== void 0 ? thickness : this.thickness;\n this._localBounds = this._calculateBounds();\n const { width: width, height: height } = this._localBounds;\n this.width = width;\n this.height = height;\n }\n get localBounds() {\n return this._localBounds;\n }\n _calculateBounds() {\n const lineNormal = this.end.sub(this.start).normal();\n const halfThickness = this.thickness / 2;\n const points = [\n this.start.add(lineNormal.scale(halfThickness)),\n this.end.add(lineNormal.scale(halfThickness)),\n this.end.add(lineNormal.scale(-halfThickness)),\n this.start.add(lineNormal.scale(-halfThickness))\n ];\n return BoundingBox.fromPoints(points);\n }\n _drawImage(ctx, _x, _y) {\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\n }\n clone() {\n return new Line({\n start: this.start,\n end: this.end,\n color: this.color,\n thickness: this.thickness\n });\n }\n }\n /**\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\n *\n * Polygons default to [[ImageFiltering.Blended]]\n */ class Polygon extends Raster {\n get points() {\n return this._points;\n }\n set points(points) {\n this._points = points;\n const min = this.minPoint;\n this.width = this._points.reduce((max, p)=>Math.max(p.x, max), 0) - min.x;\n this.height = this._points.reduce((max, p)=>Math.max(p.y, max), 0) - min.y;\n this.flagDirty();\n }\n get minPoint() {\n const minX = this._points.reduce((min, p)=>Math.min(p.x, min), Infinity);\n const minY = this._points.reduce((min, p)=>Math.min(p.y, min), Infinity);\n return vec(minX, minY);\n }\n constructor(options){\n super(options);\n this.points = options.points;\n this.filtering = ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Polygon({\n points: this.points.map((p)=>p.clone()),\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.points && this.points.length) {\n ctx.beginPath();\n // Iterate through the supplied points and construct a 'polygon'\n const min = this.minPoint.negate();\n const firstPoint = this.points[0].add(min);\n ctx.moveTo(firstPoint.x, firstPoint.y);\n this.points.forEach((point)=>{\n ctx.lineTo(point.x + min.x, point.y + min.y);\n });\n ctx.lineTo(firstPoint.x, firstPoint.y);\n ctx.closePath();\n if (this.color) ctx.fill();\n if (this.strokeColor) ctx.stroke();\n }\n }\n }\n const maxMessages = 5;\n const obsoleteMessage = {};\n const resetObsoleteCounter = ()=>{\n for(const message in obsoleteMessage)obsoleteMessage[message] = 0;\n };\n const logMessage = (message, options)=>{\n const suppressObsoleteMessages = Flags.isEnabled(\"suppress-obsolete-message\");\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\n Logger.getInstance().warn(message);\n // tslint:disable-next-line: no-console\n if (console.trace && options.showStackTrace) // tslint:disable-next-line: no-console\n console.trace();\n }\n obsoleteMessage[message]++;\n };\n /**\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\n */ function obsolete(options) {\n options = {\n message: \"This feature will be removed in future versions of Excalibur.\",\n alternateMethod: null,\n showStackTrace: false,\n ...options\n };\n return function(target, property, descriptor) {\n if (descriptor && !(typeof descriptor.value === \"function\" || typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\")) throw new SyntaxError(\"Only classes/functions/getters/setters can be marked as obsolete\");\n const methodSignature = `${target.name || \"\"}${target.name && property ? \".\" : \"\"}${property ? property : \"\"}`;\n const message = `${methodSignature} is marked obsolete: ${options.message}` + (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : \"\");\n if (!obsoleteMessage[message]) obsoleteMessage[message] = 0;\n // If descriptor is null it is a class\n const method = descriptor ? {\n ...descriptor\n } : target;\n if (!descriptor) {\n // with es2015 classes we need to change our decoration tactic\n class DecoratedClass extends method {\n constructor(...args){\n logMessage(message, options);\n super(...args);\n }\n }\n return DecoratedClass;\n }\n if (descriptor && descriptor.value) {\n method.value = function() {\n logMessage(message, options);\n return descriptor.value.apply(this, arguments);\n };\n return method;\n }\n if (descriptor && descriptor.get) method.get = function() {\n logMessage(message, options);\n return descriptor.get.apply(this, arguments);\n };\n if (descriptor && descriptor.set) method.set = function() {\n logMessage(message, options);\n return descriptor.set.apply(this, arguments);\n };\n return method;\n };\n }\n class AsyncWaitQueue {\n constructor(){\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\n this._queue = [];\n }\n get length() {\n return this._queue.length;\n }\n enqueue() {\n const future = new Future();\n this._queue.push(future);\n return future.promise;\n }\n dequeue(value) {\n const future = this._queue.shift();\n future.resolve(value);\n }\n }\n /**\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\n *\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\n * around browser limitations like max Image.decode() calls in chromium being 256.\n */ class Semaphore {\n constructor(_count){\n this._count = _count;\n this._waitQueue = new AsyncWaitQueue();\n }\n get count() {\n return this._count;\n }\n get waiting() {\n return this._waitQueue.length;\n }\n // eslint-disable-next-line require-await\n async enter() {\n if (this._count !== 0) {\n this._count--;\n return Promise.resolve();\n }\n return this._waitQueue.enqueue();\n }\n exit(count = 1) {\n if (count === 0) return;\n while(count !== 0 && this._waitQueue.length !== 0){\n this._waitQueue.dequeue(null);\n count--;\n }\n this._count += count;\n }\n }\n /**\n * The current Excalibur version string\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\n */ const EX_VERSION = \"0.29.1\";\n polyfill();\n// This file is used as the bundle entry point and exports everything\n// that will be exposed as the `ex` global variable.\n// ex.Events namespace\n// ex.Input namespace\n// TODO deprecated import site remove in v0.29.0\n// ex.Util namespaces\n// ex.Deprecated\n// import * as deprecated from './Deprecated';\n// export { deprecated as Deprecated };\n// export * from './Deprecated';\n})();\nvar $2c23f148d58cd887$export$f05c91211c084e80 = $2c23f148d58cd887$var$__webpack_exports__.y1j;\nvar $2c23f148d58cd887$export$e04e17a44f37debc = $2c23f148d58cd887$var$__webpack_exports__.fWn;\nvar $2c23f148d58cd887$export$dfcd1bb88f6d711b = $2c23f148d58cd887$var$__webpack_exports__.Ia8;\nvar $2c23f148d58cd887$export$89f31cec7c284d42 = $2c23f148d58cd887$var$__webpack_exports__.rqv;\nvar $2c23f148d58cd887$export$a3f070f3e473c3b = $2c23f148d58cd887$var$__webpack_exports__.zH6;\nvar $2c23f148d58cd887$export$856e7d6d9d698871 = $2c23f148d58cd887$var$__webpack_exports__.hLI;\nvar $2c23f148d58cd887$export$caffe607ed29fca1 = $2c23f148d58cd887$var$__webpack_exports__.yyv;\nvar $2c23f148d58cd887$export$adc62e83dbcda319 = $2c23f148d58cd887$var$__webpack_exports__.tX5;\nvar $2c23f148d58cd887$export$f73d3eb6fd876d80 = $2c23f148d58cd887$var$__webpack_exports__.vtX;\nvar $2c23f148d58cd887$export$da248c61eea53296 = $2c23f148d58cd887$var$__webpack_exports__.r7K;\nvar $2c23f148d58cd887$export$f0455ab08e3fbd0e = $2c23f148d58cd887$var$__webpack_exports__.cE4;\nvar $2c23f148d58cd887$export$c35d437ae5945fcd = $2c23f148d58cd887$var$__webpack_exports__.fwF;\nvar $2c23f148d58cd887$export$67ee29bab3792d4c = $2c23f148d58cd887$var$__webpack_exports__.sce;\nvar $2c23f148d58cd887$export$d230853e97069d46 = $2c23f148d58cd887$var$__webpack_exports__.AQ6;\nvar $2c23f148d58cd887$export$6cfd78ddb48c90c6 = $2c23f148d58cd887$var$__webpack_exports__._c7;\nvar $2c23f148d58cd887$export$3769e64eb87b5ecc = $2c23f148d58cd887$var$__webpack_exports__.KUs;\nvar $2c23f148d58cd887$export$54dc36bc2fac5425 = $2c23f148d58cd887$var$__webpack_exports__.Ajp;\nvar $2c23f148d58cd887$export$387a78ab20784494 = $2c23f148d58cd887$var$__webpack_exports__.dkO;\nvar $2c23f148d58cd887$export$d06866a9fb0606da = $2c23f148d58cd887$var$__webpack_exports__.RDh;\nvar $2c23f148d58cd887$export$83c931ba0d3bbaf5 = $2c23f148d58cd887$var$__webpack_exports__._H9;\nvar $2c23f148d58cd887$export$1a553341cd0b8415 = $2c23f148d58cd887$var$__webpack_exports__.mxs;\nvar $2c23f148d58cd887$export$43416332cf06b1f = $2c23f148d58cd887$var$__webpack_exports__.OmD;\nvar $2c23f148d58cd887$export$63080c4de6cfc362 = $2c23f148d58cd887$var$__webpack_exports__.kBf;\nvar $2c23f148d58cd887$export$fa45ecb18b97ae89 = $2c23f148d58cd887$var$__webpack_exports__.C4F;\nvar $2c23f148d58cd887$export$c24f8f35353a1e26 = $2c23f148d58cd887$var$__webpack_exports__.NQt;\nvar $2c23f148d58cd887$export$8688def55452cbca = $2c23f148d58cd887$var$__webpack_exports__.JjN;\nvar $2c23f148d58cd887$export$665d5a662b7213f3 = $2c23f148d58cd887$var$__webpack_exports__.EK_;\nvar $2c23f148d58cd887$export$79f141de891a5fed = $2c23f148d58cd887$var$__webpack_exports__.V1s;\nvar $2c23f148d58cd887$export$41606648ac8a293c = $2c23f148d58cd887$var$__webpack_exports__.xHm;\nvar $2c23f148d58cd887$export$8d01c972ee8b14a9 = $2c23f148d58cd887$var$__webpack_exports__.Xz7;\nvar $2c23f148d58cd887$export$c89a927ffc67e6fa = $2c23f148d58cd887$var$__webpack_exports__.Cdc;\nvar $2c23f148d58cd887$export$e2395b697f5a931f = $2c23f148d58cd887$var$__webpack_exports__.FKn;\nvar $2c23f148d58cd887$export$9735c82c4bae3302 = $2c23f148d58cd887$var$__webpack_exports__.SUY;\nvar $2c23f148d58cd887$export$44e6803d1d57f89a = $2c23f148d58cd887$var$__webpack_exports__.ab2;\nvar $2c23f148d58cd887$export$1ed419d47673a225 = $2c23f148d58cd887$var$__webpack_exports__.GfZ;\nvar $2c23f148d58cd887$export$b7c6eef0ebb06133 = $2c23f148d58cd887$var$__webpack_exports__.YMS;\nvar $2c23f148d58cd887$export$3c9e91dc1b611d2e = $2c23f148d58cd887$var$__webpack_exports__.oyv;\nvar $2c23f148d58cd887$export$ce0ca64520c7bfd2 = $2c23f148d58cd887$var$__webpack_exports__.aUb;\nvar $2c23f148d58cd887$export$83caf30c40e9d4b8 = $2c23f148d58cd887$var$__webpack_exports__.SdD;\nvar $2c23f148d58cd887$export$4df0464d8c812c98 = $2c23f148d58cd887$var$__webpack_exports__.JUv;\nvar $2c23f148d58cd887$export$55e924fc640a8405 = $2c23f148d58cd887$var$__webpack_exports__.jEj;\nvar $2c23f148d58cd887$export$fbd6eb86d6a3f08 = $2c23f148d58cd887$var$__webpack_exports__.TFq;\nvar $2c23f148d58cd887$export$7cd2649c3408da6c = $2c23f148d58cd887$var$__webpack_exports__.HDU;\nvar $2c23f148d58cd887$export$897cd666d936ac4c = $2c23f148d58cd887$var$__webpack_exports__.R_y;\nvar $2c23f148d58cd887$export$cf976780b3106589 = $2c23f148d58cd887$var$__webpack_exports__.t50;\nvar $2c23f148d58cd887$export$5dcfde0f6b96512b = $2c23f148d58cd887$var$__webpack_exports__.s$$;\nvar $2c23f148d58cd887$export$ddb2ed749236e720 = $2c23f148d58cd887$var$__webpack_exports__.v2G;\nvar $2c23f148d58cd887$export$892596cec99bc70e = $2c23f148d58cd887$var$__webpack_exports__.Ilk;\nvar $2c23f148d58cd887$export$8ed4b5bb5352fe14 = $2c23f148d58cd887$var$__webpack_exports__.s9i;\nvar $2c23f148d58cd887$export$c46090c9df657074 = $2c23f148d58cd887$var$__webpack_exports__.dxL;\nvar $2c23f148d58cd887$export$b3bf2ffaa538264b = $2c23f148d58cd887$var$__webpack_exports__.LLX;\nvar $2c23f148d58cd887$export$16fa2f45be04daa8 = $2c23f148d58cd887$var$__webpack_exports__.wA2;\nvar $2c23f148d58cd887$export$d16a7c95008e315d = $2c23f148d58cd887$var$__webpack_exports__.R_p;\nvar $2c23f148d58cd887$export$abda45806f5adbae = $2c23f148d58cd887$var$__webpack_exports__.IQ$;\nvar $2c23f148d58cd887$export$e5a30aa3d28b26e2 = $2c23f148d58cd887$var$__webpack_exports__.I5F;\nvar $2c23f148d58cd887$export$de7807bd8bd828df = $2c23f148d58cd887$var$__webpack_exports__.X8$;\nvar $2c23f148d58cd887$export$1bdfb0c7c42d632d = $2c23f148d58cd887$var$__webpack_exports__.FR6;\nvar $2c23f148d58cd887$export$bf92f329076cd7a3 = $2c23f148d58cd887$var$__webpack_exports__.pTZ;\nvar $2c23f148d58cd887$export$71de6146fb6d69d2 = $2c23f148d58cd887$var$__webpack_exports__.U8o;\nvar $2c23f148d58cd887$export$71efaa2be447940c = $2c23f148d58cd887$var$__webpack_exports__.kbG;\nvar $2c23f148d58cd887$export$d78c8c6074541cf2 = $2c23f148d58cd887$var$__webpack_exports__.FEv;\nvar $2c23f148d58cd887$export$7d34ad93c25aa8e7 = $2c23f148d58cd887$var$__webpack_exports__.iS_;\nvar $2c23f148d58cd887$export$153e5dc2c098b35c = $2c23f148d58cd887$var$__webpack_exports__.cGG;\nvar $2c23f148d58cd887$export$f7c1896972d6c454 = $2c23f148d58cd887$var$__webpack_exports__.ETM;\nvar $2c23f148d58cd887$export$c3e6e677dda8521a = $2c23f148d58cd887$var$__webpack_exports__.RPN;\nvar $2c23f148d58cd887$export$e52858e61b0ea117 = $2c23f148d58cd887$var$__webpack_exports__.skb;\nvar $2c23f148d58cd887$export$3d1f12550a40f54d = $2c23f148d58cd887$var$__webpack_exports__.SLU;\nvar $2c23f148d58cd887$export$4544b2d7eff33859 = $2c23f148d58cd887$var$__webpack_exports__.Q3w;\nvar $2c23f148d58cd887$export$dd6b48f99ee8a36 = $2c23f148d58cd887$var$__webpack_exports__.xK2;\nvar $2c23f148d58cd887$export$aafe01318a900193 = $2c23f148d58cd887$var$__webpack_exports__.vrO;\nvar $2c23f148d58cd887$export$fd69b6a3b7f47e29 = $2c23f148d58cd887$var$__webpack_exports__.EA2;\nvar $2c23f148d58cd887$export$e1545123b54f6785 = $2c23f148d58cd887$var$__webpack_exports__.RdJ;\nvar $2c23f148d58cd887$export$7419ff430885d61c = $2c23f148d58cd887$var$__webpack_exports__.cNu;\nvar $2c23f148d58cd887$export$a340d4e5571cbd07 = $2c23f148d58cd887$var$__webpack_exports__.wtG;\nvar $2c23f148d58cd887$export$e695250628cde35 = $2c23f148d58cd887$var$__webpack_exports__.gU7;\nvar $2c23f148d58cd887$export$c5e124f7bab3d492 = $2c23f148d58cd887$var$__webpack_exports__.LSk;\nvar $2c23f148d58cd887$export$cacd6541cfeeb6c1 = $2c23f148d58cd887$var$__webpack_exports__.Nmp;\nvar $2c23f148d58cd887$export$a74d557191881f82 = $2c23f148d58cd887$var$__webpack_exports__.twX;\nvar $2c23f148d58cd887$export$99bf88c530739783 = $2c23f148d58cd887$var$__webpack_exports__.UND;\nvar $2c23f148d58cd887$export$4b7264771109adb6 = $2c23f148d58cd887$var$__webpack_exports__.d1Y;\nvar $2c23f148d58cd887$export$62053d374d83dfb1 = $2c23f148d58cd887$var$__webpack_exports__.xrL;\nvar $2c23f148d58cd887$export$d7078bb1ea3ba3f2 = $2c23f148d58cd887$var$__webpack_exports__.sRW;\nvar $2c23f148d58cd887$export$86ae8da356d53161 = $2c23f148d58cd887$var$__webpack_exports__.cmV;\nvar $2c23f148d58cd887$export$62230588c4867d28 = $2c23f148d58cd887$var$__webpack_exports__.qWz;\nvar $2c23f148d58cd887$export$df007b1d5b86e25a = $2c23f148d58cd887$var$__webpack_exports__.N0Q;\nvar $2c23f148d58cd887$export$6ff391a2049fdf40 = $2c23f148d58cd887$var$__webpack_exports__.q8b;\nvar $2c23f148d58cd887$export$89e5ccdc4c19a8f6 = $2c23f148d58cd887$var$__webpack_exports__.ynB;\nvar $2c23f148d58cd887$export$2cbc8fe61dd10773 = $2c23f148d58cd887$var$__webpack_exports__.jT9;\nvar $2c23f148d58cd887$export$d45269226a4bbdc1 = $2c23f148d58cd887$var$__webpack_exports__.wAz;\nvar $2c23f148d58cd887$export$2c3b404bf3a77a1f = $2c23f148d58cd887$var$__webpack_exports__.D4V;\nvar $2c23f148d58cd887$export$20434e7e042d306a = $2c23f148d58cd887$var$__webpack_exports__.NLr;\nvar $2c23f148d58cd887$export$462adefbb095232e = $2c23f148d58cd887$var$__webpack_exports__.N6H;\nvar $2c23f148d58cd887$export$83f8212621739c1f = $2c23f148d58cd887$var$__webpack_exports__.W1A;\nvar $2c23f148d58cd887$export$bc644a473284d944 = $2c23f148d58cd887$var$__webpack_exports__.JHW;\nvar $2c23f148d58cd887$export$66b8a9cb33a156c = $2c23f148d58cd887$var$__webpack_exports__.ZZ$;\nvar $2c23f148d58cd887$export$c7b7134fd828a5 = $2c23f148d58cd887$var$__webpack_exports__.v2K;\nvar $2c23f148d58cd887$export$ec8b666c5fe2c75a = $2c23f148d58cd887$var$__webpack_exports__.pBf;\nvar $2c23f148d58cd887$export$4fae95256245c8c0 = $2c23f148d58cd887$var$__webpack_exports__.vpe;\nvar $2c23f148d58cd887$export$86d9a347f2bf71d6 = $2c23f148d58cd887$var$__webpack_exports__.GMl;\nvar $2c23f148d58cd887$export$ada873a34909da65 = $2c23f148d58cd887$var$__webpack_exports__.zW2;\nvar $2c23f148d58cd887$export$afee3afd6be961ec = $2c23f148d58cd887$var$__webpack_exports__.B0K;\nvar $2c23f148d58cd887$export$c03216fb3a7a2f87 = $2c23f148d58cd887$var$__webpack_exports__.Nv7;\nvar $2c23f148d58cd887$export$81940238f313e11f = $2c23f148d58cd887$var$__webpack_exports__.C_p;\nvar $2c23f148d58cd887$export$40f8f9a8f94db930 = $2c23f148d58cd887$var$__webpack_exports__.MUA;\nvar $2c23f148d58cd887$export$c579e21b95165414 = $2c23f148d58cd887$var$__webpack_exports__.xqU;\nvar $2c23f148d58cd887$export$c983850c6c9d8b0e = $2c23f148d58cd887$var$__webpack_exports__.pTp;\nvar $2c23f148d58cd887$export$be5b6c6ac24b4683 = $2c23f148d58cd887$var$__webpack_exports__.trb;\nvar $2c23f148d58cd887$export$434ba092ed0eee4e = $2c23f148d58cd887$var$__webpack_exports__.vUK;\nvar $2c23f148d58cd887$export$455f05776f1ba8ba = $2c23f148d58cd887$var$__webpack_exports__.j9l;\nvar $2c23f148d58cd887$export$89abf52a030e56ee = $2c23f148d58cd887$var$__webpack_exports__.Zxw;\nvar $2c23f148d58cd887$export$549c899505235621 = $2c23f148d58cd887$var$__webpack_exports__.v51;\nvar $2c23f148d58cd887$export$1f6d1255105a925c = $2c23f148d58cd887$var$__webpack_exports__.gYv;\nvar $2c23f148d58cd887$export$23b468d4ca3f8c96 = $2c23f148d58cd887$var$__webpack_exports__.Hdx;\nvar $2c23f148d58cd887$export$6976e674e6d5804c = $2c23f148d58cd887$var$__webpack_exports__.Z$d;\nvar $2c23f148d58cd887$export$420acfc1740638d3 = $2c23f148d58cd887$var$__webpack_exports__.iqV;\nvar $2c23f148d58cd887$export$e84927905accfe51 = $2c23f148d58cd887$var$__webpack_exports__.o$7;\nvar $2c23f148d58cd887$export$c9d7bf589772a8ce = $2c23f148d58cd887$var$__webpack_exports__.olM;\nvar $2c23f148d58cd887$export$d5011a4647754c9b = $2c23f148d58cd887$var$__webpack_exports__.Zm$;\nvar $2c23f148d58cd887$export$b8c6aa234afa01bc = $2c23f148d58cd887$var$__webpack_exports__.$QH;\nvar $2c23f148d58cd887$export$6c3776220abeb931 = $2c23f148d58cd887$var$__webpack_exports__.i78;\nvar $2c23f148d58cd887$export$27a9cd7ebdd38262 = $2c23f148d58cd887$var$__webpack_exports__.nJg;\nvar $2c23f148d58cd887$export$fb1b94e06ba8ebc8 = $2c23f148d58cd887$var$__webpack_exports__.h6u;\nvar $2c23f148d58cd887$export$3d953a2d86354b5f = $2c23f148d58cd887$var$__webpack_exports__.hts;\nvar $2c23f148d58cd887$export$88528019d270f582 = $2c23f148d58cd887$var$__webpack_exports__.j88;\nvar $2c23f148d58cd887$export$402da60b1c009e43 = $2c23f148d58cd887$var$__webpack_exports__.VME;\nvar $2c23f148d58cd887$export$757ccd1717b77f48 = $2c23f148d58cd887$var$__webpack_exports__.fy2;\nvar $2c23f148d58cd887$export$48ebf29bc7cb1dd7 = $2c23f148d58cd887$var$__webpack_exports__.nt;\nvar $2c23f148d58cd887$export$3c8c04bde7eed7cb = $2c23f148d58cd887$var$__webpack_exports__.Ukr;\nvar $2c23f148d58cd887$export$adfa9d260876eca5 = $2c23f148d58cd887$var$__webpack_exports__.zsu;\nvar $2c23f148d58cd887$export$6c043ed3a716859a = $2c23f148d58cd887$var$__webpack_exports__.oA6;\nvar $2c23f148d58cd887$export$9f9afb456a8bef30 = $2c23f148d58cd887$var$__webpack_exports__.TVh;\nvar $2c23f148d58cd887$export$1033a6fa0779f4f5 = $2c23f148d58cd887$var$__webpack_exports__.xxj;\nvar $2c23f148d58cd887$export$38f8109d2b8f43ef = $2c23f148d58cd887$var$__webpack_exports__.XdK;\nvar $2c23f148d58cd887$export$b5aa7fe3676b74a9 = $2c23f148d58cd887$var$__webpack_exports__.fBD;\nvar $2c23f148d58cd887$export$5213deb2877a09f2 = $2c23f148d58cd887$var$__webpack_exports__.Jmb;\nvar $2c23f148d58cd887$export$280e9a68c3ffd919 = $2c23f148d58cd887$var$__webpack_exports__.cXo;\nvar $2c23f148d58cd887$export$49a1ecce8d203 = $2c23f148d58cd887$var$__webpack_exports__.Dm5;\nvar $2c23f148d58cd887$export$f5b8910cec6cf069 = $2c23f148d58cd887$var$__webpack_exports__.IIB;\nvar $2c23f148d58cd887$export$99f13cbf742a0580 = $2c23f148d58cd887$var$__webpack_exports__.IX$;\nvar $2c23f148d58cd887$export$2ae6ec0f10d96242 = $2c23f148d58cd887$var$__webpack_exports__.ebW;\nvar $2c23f148d58cd887$export$d379657aa3df1705 = $2c23f148d58cd887$var$__webpack_exports__.zI0;\nvar $2c23f148d58cd887$export$ffed6a4cd9a88787 = $2c23f148d58cd887$var$__webpack_exports__.LYD;\nvar $2c23f148d58cd887$export$7705889256a9371a = $2c23f148d58cd887$var$__webpack_exports__.cEG;\nvar $2c23f148d58cd887$export$539f65e788a82c62 = $2c23f148d58cd887$var$__webpack_exports__.SEl;\nvar $2c23f148d58cd887$export$851e6d93385b6ad2 = $2c23f148d58cd887$var$__webpack_exports__.t9V;\nvar $2c23f148d58cd887$export$4b0c1c390bf9a356 = $2c23f148d58cd887$var$__webpack_exports__.ez5;\nvar $2c23f148d58cd887$export$16e4d70cc375e707 = $2c23f148d58cd887$var$__webpack_exports__.N1d;\nvar $2c23f148d58cd887$export$4b0075e5ea5e1f26 = $2c23f148d58cd887$var$__webpack_exports__.R8U;\nvar $2c23f148d58cd887$export$f3a6c1ca682fd40f = $2c23f148d58cd887$var$__webpack_exports__.SKZ;\nvar $2c23f148d58cd887$export$b04be29aa201d4f5 = $2c23f148d58cd887$var$__webpack_exports__.__J;\nvar $2c23f148d58cd887$export$b3509fba7d85d294 = $2c23f148d58cd887$var$__webpack_exports__.RI$;\nvar $2c23f148d58cd887$export$17d680238e50603e = $2c23f148d58cd887$var$__webpack_exports__.x12;\nvar $2c23f148d58cd887$export$8b98feb4a2766c75 = $2c23f148d58cd887$var$__webpack_exports__.ccz;\nvar $2c23f148d58cd887$export$3b0d6d7590275603 = $2c23f148d58cd887$var$__webpack_exports__.aNw;\nvar $2c23f148d58cd887$export$38d47553764a3d88 = $2c23f148d58cd887$var$__webpack_exports__.XrL;\nvar $2c23f148d58cd887$export$1c4c6d3f8d56581 = $2c23f148d58cd887$var$__webpack_exports__.xwn;\nvar $2c23f148d58cd887$export$fc869739b2177284 = $2c23f148d58cd887$var$__webpack_exports__.dNK;\nvar $2c23f148d58cd887$export$243e62d78d3b544d = $2c23f148d58cd887$var$__webpack_exports__.ini;\nvar $2c23f148d58cd887$export$efa9a398d6368992 = $2c23f148d58cd887$var$__webpack_exports__.YdH;\nvar $2c23f148d58cd887$export$a2d8b23205c25948 = $2c23f148d58cd887$var$__webpack_exports__.F5T;\nvar $2c23f148d58cd887$export$5b12bf1653c0dd85 = $2c23f148d58cd887$var$__webpack_exports__.y3G;\nvar $2c23f148d58cd887$export$9f9b2346169b00c0 = $2c23f148d58cd887$var$__webpack_exports__.l57;\nvar $2c23f148d58cd887$export$8c37b217b84d3f89 = $2c23f148d58cd887$var$__webpack_exports__.xn0;\nvar $2c23f148d58cd887$export$35624b13e79b24a9 = $2c23f148d58cd887$var$__webpack_exports__.t2V;\nvar $2c23f148d58cd887$export$f75e7304717c9cbc = $2c23f148d58cd887$var$__webpack_exports__.uxB;\nvar $2c23f148d58cd887$export$ec1251c88c8bd5c9 = $2c23f148d58cd887$var$__webpack_exports__.cpd;\nvar $2c23f148d58cd887$export$d17844835b0fe8a8 = $2c23f148d58cd887$var$__webpack_exports__.fiy;\nvar $2c23f148d58cd887$export$d1d8cb3d5c2a5671 = $2c23f148d58cd887$var$__webpack_exports__.$XZ;\nvar $2c23f148d58cd887$export$4d607ef791645d6 = $2c23f148d58cd887$var$__webpack_exports__.UG6;\nvar $2c23f148d58cd887$export$f0b55daf9f154b55 = $2c23f148d58cd887$var$__webpack_exports__.uqK;\nvar $2c23f148d58cd887$export$fa9699e41ba6faff = $2c23f148d58cd887$var$__webpack_exports__.STE;\nvar $2c23f148d58cd887$export$57ca7e07b341709d = $2c23f148d58cd887$var$__webpack_exports__.Hq9;\nvar $2c23f148d58cd887$export$77cea355fa80b5f4 = $2c23f148d58cd887$var$__webpack_exports__.y$z;\nvar $2c23f148d58cd887$export$8844adde4348f85c = $2c23f148d58cd887$var$__webpack_exports__.mAD;\nvar $2c23f148d58cd887$export$d63d7cff08fe4dc9 = $2c23f148d58cd887$var$__webpack_exports__.sOq;\nvar $2c23f148d58cd887$export$a960801e47624f4f = $2c23f148d58cd887$var$__webpack_exports__.hUw;\nvar $2c23f148d58cd887$export$ed6a63ee685a4d78 = $2c23f148d58cd887$var$__webpack_exports__._0G;\nvar $2c23f148d58cd887$export$4fe52ae24ae61d51 = $2c23f148d58cd887$var$__webpack_exports__.Sqs;\nvar $2c23f148d58cd887$export$c36c68baa13912a5 = $2c23f148d58cd887$var$__webpack_exports__.hpZ;\nvar $2c23f148d58cd887$export$616c632b282478dd = $2c23f148d58cd887$var$__webpack_exports__.Vol;\nvar $2c23f148d58cd887$export$459b1801e3134a24 = $2c23f148d58cd887$var$__webpack_exports__.vYX;\nvar $2c23f148d58cd887$export$2f09efa5b67124a7 = $2c23f148d58cd887$var$__webpack_exports__.wIZ;\nvar $2c23f148d58cd887$export$618424ba3f30cd41 = $2c23f148d58cd887$var$__webpack_exports__.cBi;\nvar $2c23f148d58cd887$export$4a963ea7a16edf21 = $2c23f148d58cd887$var$__webpack_exports__.c30;\nvar $2c23f148d58cd887$export$a4017560efebe97d = $2c23f148d58cd887$var$__webpack_exports__.PGK;\nvar $2c23f148d58cd887$export$982e5de016bedff1 = $2c23f148d58cd887$var$__webpack_exports__.MPV;\nvar $2c23f148d58cd887$export$6860c0696b73f79b = $2c23f148d58cd887$var$__webpack_exports__.RFv;\nvar $2c23f148d58cd887$export$94806efd9890932f = $2c23f148d58cd887$var$__webpack_exports__.Ux6;\nvar $2c23f148d58cd887$export$3bee0b2628b43478 = $2c23f148d58cd887$var$__webpack_exports__.rxy;\nvar $2c23f148d58cd887$export$caed39dbb767d548 = $2c23f148d58cd887$var$__webpack_exports__.I$c;\nvar $2c23f148d58cd887$export$7e5ab4f7f9fd407 = $2c23f148d58cd887$var$__webpack_exports__.kfC;\nvar $2c23f148d58cd887$export$330520496d871ecf = $2c23f148d58cd887$var$__webpack_exports__.VjY;\nvar $2c23f148d58cd887$export$7d31b617c820d435 = $2c23f148d58cd887$var$__webpack_exports__.mgq;\nvar $2c23f148d58cd887$export$f23a2a272a8df60 = $2c23f148d58cd887$var$__webpack_exports__.YVA;\nvar $2c23f148d58cd887$export$14963ee5c8637e11 = $2c23f148d58cd887$var$__webpack_exports__.Kgp;\nvar $2c23f148d58cd887$export$1d2c184034fc4cc2 = $2c23f148d58cd887$var$__webpack_exports__.HH$;\nvar $2c23f148d58cd887$export$fea21a521a6360c1 = $2c23f148d58cd887$var$__webpack_exports__.M_d;\nvar $2c23f148d58cd887$export$8c15bdf7e3727f73 = $2c23f148d58cd887$var$__webpack_exports__.rgh;\nvar $2c23f148d58cd887$export$6eb043bf81d89752 = $2c23f148d58cd887$var$__webpack_exports__.Ra6;\nvar $2c23f148d58cd887$export$e390b859365a3d5b = $2c23f148d58cd887$var$__webpack_exports__.KhR;\nvar $2c23f148d58cd887$export$82a33120f6a0d987 = $2c23f148d58cd887$var$__webpack_exports__.gvQ;\nvar $2c23f148d58cd887$export$1ec85152758537e0 = $2c23f148d58cd887$var$__webpack_exports__.BS5;\nvar $2c23f148d58cd887$export$a8584993858a18df = $2c23f148d58cd887$var$__webpack_exports__.xhz;\nvar $2c23f148d58cd887$export$906049a3747337a6 = $2c23f148d58cd887$var$__webpack_exports__.xOq;\nvar $2c23f148d58cd887$export$dbd8a6303ac26a42 = $2c23f148d58cd887$var$__webpack_exports__.a9j;\nvar $2c23f148d58cd887$export$9f68b6f37a444556 = $2c23f148d58cd887$var$__webpack_exports__.bHk;\nvar $2c23f148d58cd887$export$fe2b6ac465da985d = $2c23f148d58cd887$var$__webpack_exports__.CgK;\nvar $2c23f148d58cd887$export$4c3c82f4dcd79fcc = $2c23f148d58cd887$var$__webpack_exports__.A0M;\nvar $2c23f148d58cd887$export$e4ce43ec0499fb8f = $2c23f148d58cd887$var$__webpack_exports__.cEd;\nvar $2c23f148d58cd887$export$e44279b5c44add28 = $2c23f148d58cd887$var$__webpack_exports__.cuY;\nvar $2c23f148d58cd887$export$dfa3a012bb2ef2e1 = $2c23f148d58cd887$var$__webpack_exports__.kvE;\nvar $2c23f148d58cd887$export$8201b979875baf73 = $2c23f148d58cd887$var$__webpack_exports__.SBu;\nvar $2c23f148d58cd887$export$b82688eb02220411 = $2c23f148d58cd887$var$__webpack_exports__.PsT;\nvar $2c23f148d58cd887$export$62297b13309008b2 = $2c23f148d58cd887$var$__webpack_exports__.AE_;\nvar $2c23f148d58cd887$export$b986383a50b53ea4 = $2c23f148d58cd887$var$__webpack_exports__.ctO;\nvar $2c23f148d58cd887$export$ad5b3d166367714c = $2c23f148d58cd887$var$__webpack_exports__.OLH;\nvar $2c23f148d58cd887$export$a92776769f460054 = $2c23f148d58cd887$var$__webpack_exports__.kky;\nvar $2c23f148d58cd887$export$eeb71495ca594706 = $2c23f148d58cd887$var$__webpack_exports__.nSF;\nvar $2c23f148d58cd887$export$a186db52eed6d40e = $2c23f148d58cd887$var$__webpack_exports__.zHn;\nvar $2c23f148d58cd887$export$c07ce6d13c46df49 = $2c23f148d58cd887$var$__webpack_exports__.zwx;\nvar $2c23f148d58cd887$export$4617fb02663045ef = $2c23f148d58cd887$var$__webpack_exports__.AeJ;\nvar $2c23f148d58cd887$export$32437fc39ad02208 = $2c23f148d58cd887$var$__webpack_exports__.hLz;\nvar $2c23f148d58cd887$export$f9d61a2a6155ab51 = $2c23f148d58cd887$var$__webpack_exports__.wA;\nvar $2c23f148d58cd887$export$9bd81f7d9b69ccb3 = $2c23f148d58cd887$var$__webpack_exports__.jhr;\nvar $2c23f148d58cd887$export$3e4ff2216a90b8a4 = $2c23f148d58cd887$var$__webpack_exports__.GVs;\nvar $2c23f148d58cd887$export$39a853cfb5a94a63 = $2c23f148d58cd887$var$__webpack_exports__._zO;\nvar $2c23f148d58cd887$export$62833702c6700187 = $2c23f148d58cd887$var$__webpack_exports__.LXZ;\nvar $2c23f148d58cd887$export$a43177620e7a9310 = $2c23f148d58cd887$var$__webpack_exports__.w6$;\nvar $2c23f148d58cd887$export$a16b6ef1fd362a19 = $2c23f148d58cd887$var$__webpack_exports__.mhV;\nvar $2c23f148d58cd887$export$91397be43fc980cc = $2c23f148d58cd887$var$__webpack_exports__.MOD;\nvar $2c23f148d58cd887$export$23b9d128e61caefd = $2c23f148d58cd887$var$__webpack_exports__.kwd;\nvar $2c23f148d58cd887$export$ab681471d41eeddc = $2c23f148d58cd887$var$__webpack_exports__.Lmr;\nvar $2c23f148d58cd887$export$38af1803e3442a7f = $2c23f148d58cd887$var$__webpack_exports__.xsS;\nvar $2c23f148d58cd887$export$c1825d965cf69ea3 = $2c23f148d58cd887$var$__webpack_exports__.K5l;\nvar $2c23f148d58cd887$export$a98515d67472a41f = $2c23f148d58cd887$var$__webpack_exports__.lLr;\nvar $2c23f148d58cd887$export$57486627f01aaaf3 = $2c23f148d58cd887$var$__webpack_exports__.Z$r;\nvar $2c23f148d58cd887$export$77630fcd7c3f2eb6 = $2c23f148d58cd887$var$__webpack_exports__.IXb;\nvar $2c23f148d58cd887$export$3bf088dd0bb7575 = $2c23f148d58cd887$var$__webpack_exports__.Xsu;\nvar $2c23f148d58cd887$export$2f3ac66e390c188b = $2c23f148d58cd887$var$__webpack_exports__.SGH;\nvar $2c23f148d58cd887$export$d160a188872e1e4e = $2c23f148d58cd887$var$__webpack_exports__.SMj;\nvar $2c23f148d58cd887$export$5c7bd08c630c970c = $2c23f148d58cd887$var$__webpack_exports__.L34;\nvar $2c23f148d58cd887$export$462bb059fed9d9e5 = $2c23f148d58cd887$var$__webpack_exports__.exe;\nvar $2c23f148d58cd887$export$6428a7f2611ef1fa = $2c23f148d58cd887$var$__webpack_exports__.bnF;\nvar $2c23f148d58cd887$export$80a00690bda7f17e = $2c23f148d58cd887$var$__webpack_exports__.MFA;\nvar $2c23f148d58cd887$export$50994fad4c4676f4 = $2c23f148d58cd887$var$__webpack_exports__.kPj;\nvar $2c23f148d58cd887$export$85990f0f98a390bb = $2c23f148d58cd887$var$__webpack_exports__.$uU;\nvar $2c23f148d58cd887$export$5bff0d6cc6200d64 = $2c23f148d58cd887$var$__webpack_exports__.Sap;\nvar $2c23f148d58cd887$export$3075603db8e6204c = $2c23f148d58cd887$var$__webpack_exports__.jyi;\nvar $2c23f148d58cd887$export$e1896ac0c4970221 = $2c23f148d58cd887$var$__webpack_exports__.E03;\nvar $2c23f148d58cd887$export$bd73ddfe5f8475d8 = $2c23f148d58cd887$var$__webpack_exports__.V6q;\nvar $2c23f148d58cd887$export$f62bb2892382b3dd = $2c23f148d58cd887$var$__webpack_exports__.rg2;\nvar $2c23f148d58cd887$export$cbf2d83d1eab018a = $2c23f148d58cd887$var$__webpack_exports__.DVW;\nvar $2c23f148d58cd887$export$9ad53eded130cce4 = $2c23f148d58cd887$var$__webpack_exports__.nVo;\nvar $2c23f148d58cd887$export$6a4eb2e7fc9e8903 = $2c23f148d58cd887$var$__webpack_exports__.F6N;\nvar $2c23f148d58cd887$export$e1dae5660003ffa7 = $2c23f148d58cd887$var$__webpack_exports__.xP7;\nvar $2c23f148d58cd887$export$a12e67a4b4590901 = $2c23f148d58cd887$var$__webpack_exports__.Odq;\nvar $2c23f148d58cd887$export$7c88eb83095afadd = $2c23f148d58cd887$var$__webpack_exports__.uY9;\nvar $2c23f148d58cd887$export$c586aa7b67d94d19 = $2c23f148d58cd887$var$__webpack_exports__.Zif;\nvar $2c23f148d58cd887$export$47b45ce774071a36 = $2c23f148d58cd887$var$__webpack_exports__.c_d;\nvar $2c23f148d58cd887$export$9440a22058545f9a = $2c23f148d58cd887$var$__webpack_exports__.MJk;\nvar $2c23f148d58cd887$export$5f1af8db9871e1d6 = $2c23f148d58cd887$var$__webpack_exports__.xvT;\nvar $2c23f148d58cd887$export$3720eb13f948f394 = $2c23f148d58cd887$var$__webpack_exports__.PHM;\nvar $2c23f148d58cd887$export$fd1bfc71f64c538c = $2c23f148d58cd887$var$__webpack_exports__.dpR;\nvar $2c23f148d58cd887$export$235cb65c20ad2b7 = $2c23f148d58cd887$var$__webpack_exports__.n9L;\nvar $2c23f148d58cd887$export$16ec26812de3ce7a = $2c23f148d58cd887$var$__webpack_exports__.KwO;\nvar $2c23f148d58cd887$export$dac3abbdc575ce73 = $2c23f148d58cd887$var$__webpack_exports__.SxM;\nvar $2c23f148d58cd887$export$c57e9b2d8b9e4de = $2c23f148d58cd887$var$__webpack_exports__.B7y;\nvar $2c23f148d58cd887$export$fb98e3a2a4cd92d7 = $2c23f148d58cd887$var$__webpack_exports__.x7r;\nvar $2c23f148d58cd887$export$563a914cafbdc389 = $2c23f148d58cd887$var$__webpack_exports__.wx7;\nvar $2c23f148d58cd887$export$1def2aa75b7c7fe0 = $2c23f148d58cd887$var$__webpack_exports__.Uvn;\nvar $2c23f148d58cd887$export$be58926105124dd4 = $2c23f148d58cd887$var$__webpack_exports__.uTP;\nvar $2c23f148d58cd887$export$2eba8ec3a333fdbb = $2c23f148d58cd887$var$__webpack_exports__.OFT;\nvar $2c23f148d58cd887$export$41fb9f06171c75f4 = $2c23f148d58cd887$var$__webpack_exports__.xzN;\nvar $2c23f148d58cd887$export$14963f945d6d59f0 = $2c23f148d58cd887$var$__webpack_exports__.CcZ;\nvar $2c23f148d58cd887$export$ba8651401a8a2b84 = $2c23f148d58cd887$var$__webpack_exports__.M5Z;\nvar $2c23f148d58cd887$export$f8f26dd395d7e1bd = $2c23f148d58cd887$var$__webpack_exports__.ZrN;\nvar $2c23f148d58cd887$export$9b781de7bf37bf48 = $2c23f148d58cd887$var$__webpack_exports__.OWs;\nvar $2c23f148d58cd887$export$ab650c8e5b9b9f2c = $2c23f148d58cd887$var$__webpack_exports__.dF9;\nvar $2c23f148d58cd887$export$41825a1ed6473903 = $2c23f148d58cd887$var$__webpack_exports__.oZy;\nvar $2c23f148d58cd887$export$f5ae2f144b95ebf4 = $2c23f148d58cd887$var$__webpack_exports__.rD2;\nvar $2c23f148d58cd887$export$31ac8f65680039dd = $2c23f148d58cd887$var$__webpack_exports__.KmN;\nvar $2c23f148d58cd887$export$d5c6f73f7a77b9d = $2c23f148d58cd887$var$__webpack_exports__.VHo;\nvar $2c23f148d58cd887$export$8bfbf00b5dba81f6 = $2c23f148d58cd887$var$__webpack_exports__.ohE;\nvar $2c23f148d58cd887$export$2af5ef044257da25 = $2c23f148d58cd887$var$__webpack_exports__.R$E;\nvar $2c23f148d58cd887$export$8c3375c231593a9d = $2c23f148d58cd887$var$__webpack_exports__.xQN;\nvar $2c23f148d58cd887$export$9a4eae43f302c46e = $2c23f148d58cd887$var$__webpack_exports__.AdJ;\nvar $2c23f148d58cd887$export$812cd9544993280d = $2c23f148d58cd887$var$__webpack_exports__.q3I;\nvar $2c23f148d58cd887$export$a4913eafbb02ceb4 = $2c23f148d58cd887$var$__webpack_exports__.Pab;\nvar $2c23f148d58cd887$export$7d15b64cf5a3a4c4 = $2c23f148d58cd887$var$__webpack_exports__.uZ5;\nvar $2c23f148d58cd887$export$c372a5d5a3996cbf = $2c23f148d58cd887$var$__webpack_exports__.TAE;\nvar $2c23f148d58cd887$export$7149c6ffc9994c32 = $2c23f148d58cd887$var$__webpack_exports__.McK;\nvar $2c23f148d58cd887$export$d436988b04cb99a5 = $2c23f148d58cd887$var$__webpack_exports__.F9c;\nvar $2c23f148d58cd887$export$3ba9f2e94585ecc6 = $2c23f148d58cd887$var$__webpack_exports__.k0b;\nvar $2c23f148d58cd887$export$25dac40984956196 = $2c23f148d58cd887$var$__webpack_exports__.hnT;\nvar $2c23f148d58cd887$export$57932b71da6538b7 = $2c23f148d58cd887$var$__webpack_exports__.RSJ;\nvar $2c23f148d58cd887$export$a17402ef5f32064d = $2c23f148d58cd887$var$__webpack_exports__.Mku;\nvar $2c23f148d58cd887$export$d5dea09620a858fd = $2c23f148d58cd887$var$__webpack_exports__.h90;\nvar $2c23f148d58cd887$export$1377812d73ae3cab = $2c23f148d58cd887$var$__webpack_exports__.rms;\nvar $2c23f148d58cd887$export$331f4c7ef74a9752 = $2c23f148d58cd887$var$__webpack_exports__.ErP;\nvar $2c23f148d58cd887$export$5f4e18965661d41f = $2c23f148d58cd887$var$__webpack_exports__.aVg;\nvar $2c23f148d58cd887$export$817667946f51142b = $2c23f148d58cd887$var$__webpack_exports__.lPc;\nvar $2c23f148d58cd887$export$adc479603c39b28 = $2c23f148d58cd887$var$__webpack_exports__.Z8E;\nvar $2c23f148d58cd887$export$ba30ba18962891e7 = $2c23f148d58cd887$var$__webpack_exports__.k15;\nvar $2c23f148d58cd887$export$bcf8f1355133000b = $2c23f148d58cd887$var$__webpack_exports__.YsU;\nvar $2c23f148d58cd887$export$256576ea924e6c90 = $2c23f148d58cd887$var$__webpack_exports__.lNv;\nvar $2c23f148d58cd887$export$786d9ab531bddbaa = $2c23f148d58cd887$var$__webpack_exports__.Xyg;\nvar $2c23f148d58cd887$export$e87630d8ef35465d = $2c23f148d58cd887$var$__webpack_exports__.cu9;\nvar $2c23f148d58cd887$export$c3cedacda2d7ce48 = $2c23f148d58cd887$var$__webpack_exports__.p88;\nvar $2c23f148d58cd887$export$5a62d8eea226ddc = $2c23f148d58cd887$var$__webpack_exports__.MZQ;\nvar $2c23f148d58cd887$export$640d107500a3202a = $2c23f148d58cd887$var$__webpack_exports__.FUM;\nvar $2c23f148d58cd887$export$506bf22710a79182 = $2c23f148d58cd887$var$__webpack_exports__.BxR;\nvar $2c23f148d58cd887$export$8b958c8ecd94a804 = $2c23f148d58cd887$var$__webpack_exports__.vdf;\nvar $2c23f148d58cd887$export$816343276f749e02 = $2c23f148d58cd887$var$__webpack_exports__.iaL;\nvar $2c23f148d58cd887$export$d02631cccf789723 = $2c23f148d58cd887$var$__webpack_exports__.w6H;\nvar $2c23f148d58cd887$export$5dc5812d8b390c43 = $2c23f148d58cd887$var$__webpack_exports__.Q4c;\nvar $2c23f148d58cd887$export$c5552dfdbc7cec71 = $2c23f148d58cd887$var$__webpack_exports__.Xxe;\nvar $2c23f148d58cd887$export$56cb859c01fa134d = $2c23f148d58cd887$var$__webpack_exports__.Uxb;\nvar $2c23f148d58cd887$export$cba01ba138429a1d = $2c23f148d58cd887$var$__webpack_exports__.Yr5;\nvar $2c23f148d58cd887$export$202e0172ed3c7be0 = $2c23f148d58cd887$var$__webpack_exports__.Bhw;\nvar $2c23f148d58cd887$export$d55298c9efc5ed14 = $2c23f148d58cd887$var$__webpack_exports__.yOA;\n\n});\n\n\nvar $3MXpL = parcelRequire(\"3MXpL\");\n\nvar $3MXpL = parcelRequire(\"3MXpL\");\n\nvar $3MXpL = parcelRequire(\"3MXpL\");\nvar $f82d5511d53990a3$exports = {};\n\n!function(e, t) {\n $f82d5511d53990a3$exports = t((parcelRequire(\"3MXpL\")));\n}(self, (e)=>(()=>{\n \"use strict\";\n var t = {\n 445: (e, t, s)=>{\n s.r(t), s.d(t, {\n compare: ()=>u,\n compareVersions: ()=>l,\n satisfies: ()=>f,\n validate: ()=>m,\n validateStrict: ()=>y\n });\n const r = /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i, i = (e)=>{\n if (\"string\" != typeof e) throw new TypeError(\"Invalid argument expected string\");\n const t = e.match(r);\n if (!t) throw new Error(`Invalid argument not valid semver ('${e}' received)`);\n return t.shift(), t;\n }, a = (e)=>\"*\" === e || \"x\" === e || \"X\" === e, n = (e)=>{\n const t = parseInt(e, 10);\n return isNaN(t) ? e : t;\n }, o = (e, t)=>{\n if (a(e) || a(t)) return 0;\n const [s, r] = ((e, t)=>typeof e != typeof t ? [\n String(e),\n String(t)\n ] : [\n e,\n t\n ])(n(e), n(t));\n return s > r ? 1 : s < r ? -1 : 0;\n }, d = (e, t)=>{\n for(let s = 0; s < Math.max(e.length, t.length); s++){\n const r = o(e[s] || \"0\", t[s] || \"0\");\n if (0 !== r) return r;\n }\n return 0;\n }, l = (e, t)=>{\n const s = i(e), r = i(t), a = s.pop(), n = r.pop(), o = d(s, r);\n return 0 !== o ? o : a && n ? d(a.split(\".\"), n.split(\".\")) : a || n ? a ? -1 : 1 : 0;\n }, u = (e, t, s)=>{\n h(s);\n const r = l(e, t);\n return c[s].includes(r);\n }, c = {\n \">\": [\n 1\n ],\n \">=\": [\n 0,\n 1\n ],\n \"=\": [\n 0\n ],\n \"<=\": [\n -1,\n 0\n ],\n \"<\": [\n -1\n ],\n \"!=\": [\n -1,\n 1\n ]\n }, p = Object.keys(c), h = (e)=>{\n if (\"string\" != typeof e) throw new TypeError(\"Invalid operator type, expected string but got \" + typeof e);\n if (-1 === p.indexOf(e)) throw new Error(`Invalid operator, expected one of ${p.join(\"|\")}`);\n }, f = (e, t)=>{\n if ((t = t.replace(/([><=]+)\\s+/g, \"$1\")).includes(\"||\")) return t.split(\"||\").some((t)=>f(e, t));\n if (t.includes(\" - \")) {\n const [s, r] = t.split(\" - \", 2);\n return f(e, `>=${s} <=${r}`);\n }\n if (t.includes(\" \")) return t.trim().replace(/\\s{2,}/g, \" \").split(\" \").every((t)=>f(e, t));\n const s = t.match(/^([<>=~^]+)/), r = s ? s[1] : \"=\";\n if (\"^\" !== r && \"~\" !== r) return u(e, t, r);\n const [a, n, o, , l] = i(e), [c, p, h, , m] = i(t), y = [\n a,\n n,\n o\n ], _ = [\n c,\n null != p ? p : \"x\",\n null != h ? h : \"x\"\n ];\n if (m) {\n if (!l) return !1;\n if (0 !== d(y, _)) return !1;\n if (-1 === d(l.split(\".\"), m.split(\".\"))) return !1;\n }\n const v = _.findIndex((e)=>\"0\" !== e) + 1, g = \"~\" === r ? 2 : v > 1 ? v : 1;\n return 0 === d(y.slice(0, g), _.slice(0, g)) && -1 !== d(y.slice(g), _.slice(g));\n }, m = (e)=>\"string\" == typeof e && /^[v\\d]/.test(e) && r.test(e), y = (e)=>\"string\" == typeof e && /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/.test(e);\n },\n 961: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.EntityLayer = void 0;\n const r = s(205);\n t.EntityLayer = class {\n constructor(e, t, s, i){\n var a, n;\n if (this.ldtkLayer = t, this.resource = s, this.order = i, this.entities = [], this.ldtkToEntity = new Map, this.entityToLdtk = new Map, this.worldPos = (0, r.vec)(e.ldtkLevel.worldX, e.ldtkLevel.worldY), this.offset = (0, r.vec)(t.__pxTotalOffsetX, t.__pxTotalOffsetY), t.entityInstances) for (let e of t.entityInstances){\n const t = s.projectMetadata.defs.entities.find((t)=>t.identifier === e.__identifier);\n if (s.factories.has(e.__identifier)) {\n const i = s.factories.get(e.__identifier);\n if (i) {\n const s = i({\n type: e.__identifier,\n worldPos: (0, r.vec)(e.px[0], e.px[1]).add(this.worldPos.add(this.offset)),\n entity: e,\n definition: t,\n layer: this\n });\n s && (this.entities.push(s), this.ldtkToEntity.set(e, s), this.entityToLdtk.set(s, e));\n }\n } else {\n const o = new r.Actor({\n name: e.__identifier,\n pos: (0, r.vec)(e.px[0], e.px[1]).add(this.worldPos.add(this.offset)),\n width: e.width,\n height: e.height,\n anchor: (0, r.vec)(null !== (a = null == t ? void 0 : t.pivotX) && void 0 !== a ? a : 0, null !== (n = null == t ? void 0 : t.pivotY) && void 0 !== n ? n : 0),\n z: i\n });\n if (e.__tile) {\n const t = s.tilesets.get(e.__tile.tilesetUid);\n if (t) {\n const s = Math.floor(e.__tile.x / e.__tile.w), r = Math.floor(e.__tile.y / e.__tile.h), i = t.spritesheet.getSprite(s, r);\n i && o.graphics.use(i);\n }\n }\n this.entities.push(o), this.ldtkToEntity.set(e, o), this.entityToLdtk.set(o, e);\n }\n }\n }\n runFactory(e) {\n if (this.resource.factories.has(e) && this.ldtkLayer.entityInstances) for (let e of this.ldtkLayer.entityInstances){\n const t = this.resource.projectMetadata.defs.entities.find((t)=>t.identifier === e.__identifier), s = this.resource.factories.get(e.__identifier);\n if (s) {\n const i = s({\n type: e.__identifier,\n worldPos: (0, r.vec)(e.px[0], e.px[1]).add(this.worldPos.add(this.offset)),\n entity: e,\n definition: t,\n layer: this\n });\n if (i) {\n const t = this.ldtkToEntity.get(e);\n if (t) {\n const s = this.entities.indexOf(t);\n s > -1 && (this.entities.splice(s, 1), this.ldtkToEntity.delete(e), this.entityToLdtk.delete(t));\n }\n return this.entities.push(i), this.ldtkToEntity.set(e, i), this.entityToLdtk.set(i, e), i;\n }\n }\n }\n }\n getEntitiesByIdentifier(e) {\n const t = this.getLdtkEntitiesByIdentifier(e);\n let s = [];\n for (const e of t){\n const t = this.ldtkToEntity.get(e);\n t && s.push(t);\n }\n return s;\n }\n getEntitiesByField(e, t) {\n const s = this.getLdtkEntitiesByField(e, t);\n let r = [];\n for (const e of s){\n const t = this.ldtkToEntity.get(e);\n t && r.push(t);\n }\n return r;\n }\n getLdtkEntitiesByIdentifier(e) {\n return this.ldtkLayer.entityInstances.filter((t)=>t.__identifier.toLocaleLowerCase() === e.toLowerCase());\n }\n getLdtkEntitiesByField(e, t) {\n return this.ldtkLayer.entityInstances.filter((s)=>{\n if (void 0 !== t) {\n let r = t;\n \"string\" == typeof t && (r = t.toLocaleLowerCase());\n const i = s.fieldInstances.find((t)=>t.__identifier.toLocaleLowerCase() === e.toLocaleLowerCase());\n return !!i && i.__value === r;\n }\n return !!s.fieldInstances.find((t)=>t.__identifier.toLocaleLowerCase() === e.toLocaleLowerCase());\n });\n }\n };\n },\n 710: (e, t)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.FetchLoader = void 0, t.FetchLoader = async (e, t)=>{\n const s = await fetch(e);\n switch(t.toLowerCase()){\n case \"xml\":\n default:\n return await s.text();\n case \"json\":\n return await s.json();\n }\n };\n },\n 607: function(e, t, s) {\n var r = this && this.__createBinding || (Object.create ? function(e, t, s, r) {\n void 0 === r && (r = s);\n var i = Object.getOwnPropertyDescriptor(t, s);\n i && !(\"get\" in i ? !t.__esModule : i.writable || i.configurable) || (i = {\n enumerable: !0,\n get: function() {\n return t[s];\n }\n }), Object.defineProperty(e, r, i);\n } : function(e, t, s, r) {\n void 0 === r && (r = s), e[r] = t[s];\n }), i = this && this.__exportStar || function(e, t) {\n for(var s in e)\"default\" === s || Object.prototype.hasOwnProperty.call(t, s) || r(t, e, s);\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), i(s(398), t), i(s(961), t), i(s(710), t), i(s(920), t), i(s(515), t), i(s(512), t), i(s(289), t), i(s(32), t), i(s(692), t), i(s(245), t), i(s(699), t);\n },\n 920: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.IntGridLayer = void 0;\n const r = s(205);\n t.IntGridLayer = class {\n constructor(e, t, s, i){\n if (this.order = i, this.worldPos = (0, r.vec)(e.ldtkLevel.worldX, e.ldtkLevel.worldY), this.offset = (0, r.vec)(t.__pxTotalOffsetX, t.__pxTotalOffsetY), this.ldtkLayer = t, t.intGridCsv.length) {\n const e = t.__cHei, i = t.__cWid;\n this.tilemap = new r.TileMap({\n name: t.__identifier,\n pos: this.worldPos.add(this.offset),\n tileWidth: t.__gridSize,\n tileHeight: t.__gridSize,\n rows: e,\n columns: i\n });\n const a = s.projectMetadata.defs.layers.find((e)=>t.__identifier === e.identifier);\n if (a) {\n const e = a.intGridValues.find((e)=>{\n var t;\n return \"solid\" === (null === (t = null == e ? void 0 : e.identifier) || void 0 === t ? void 0 : t.toLocaleLowerCase());\n });\n for(let s = 0; s < t.intGridCsv.length; s++){\n const r = s % i, a = Math.floor(s / i), n = this.tilemap.getTile(r, a);\n e && t.intGridCsv[s] === e.value && (n.solid = !0), e || 1 !== t.intGridCsv[s] || (n.solid = !0);\n }\n }\n }\n }\n };\n },\n 398: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.LdtkResource = void 0;\n const r = s(692), i = s(32), a = s(710), n = s(699), o = s(445), d = s(289), l = s(205), u = s(515), c = s(245), p = s(512), h = s(961), f = s(920);\n class m {\n constructor(e, t){\n this.path = e, this.tilesets = new Map, this.levels = new Map, this.levelsByName = new Map, this.factories = new Map, this.fileLoader = a.FetchLoader, this._imageLoader = new d.LoaderCache(l.ImageSource), this._levelLoader = new d.LoaderCache(u.LevelResource), this.startZIndex = 0, this.textQuality = 4, this.useExcaliburWiring = !0, this.useMapBackgroundColor = !1, this.useTilemapCameraStrategy = !1, this.headless = !1, this.strict = !0;\n const { useExcaliburWiring: s, useTilemapCameraStrategy: r, entityIdentifierFactories: i, pathMap: n, useMapBackgroundColor: o, fileLoader: c, strict: p, headless: h, startZIndex: f } = {\n ...t\n };\n this.strict = null != p ? p : this.strict, this.headless = null != h ? h : this.headless, this.useExcaliburWiring = null != s ? s : this.useExcaliburWiring, this.useTilemapCameraStrategy = null != r ? r : this.useTilemapCameraStrategy, this.useMapBackgroundColor = null != o ? o : this.useMapBackgroundColor, this.startZIndex = null != f ? f : this.startZIndex, this.fileLoader = null != c ? c : this.fileLoader, this.pathMap = n;\n for(const e in i)this.registerEntityIdentifierFactory(e, i[e]);\n }\n async load() {\n var e;\n const t = await this.fileLoader(this.path, \"json\");\n if (this.strict) try {\n this.projectMetadata = n.LdtkProjectMetadata.parse(t);\n } catch (e) {\n throw console.error(`Could not parse LDtk map from location ${this.path}.\\nExcalibur only supports the latest version of LDtk formats as of the plugin's release.`), console.error(\"Is your map file corrupted or being interpreted as the wrong type?\"), e;\n }\n else this.projectMetadata = t;\n (0, o.compare)(m.supportedLdtkVersion, null !== (e = this.projectMetadata.jsonVersion) && void 0 !== e ? e : \"0.0.0\", \">\") && console.warn(`The excalibur ldtk plugin officially supports ${m.supportedLdtkVersion}+, the current map has LDtk version ${this.projectMetadata.jsonVersion}`);\n for (let e of this.projectMetadata.defs.tilesets)if (e.relPath) {\n const t = (0, i.pathRelativeToBase)(this.path, e.relPath, this.pathMap), s = this._imageLoader.getOrAdd(t), r = new c.Tileset({\n image: s,\n ldtkTileset: e\n });\n this.tilesets.set(e.uid, r);\n } else \"Internal_Icons\" !== e.identifier && console.warn(`No tileset image provided for ${e.identifier}`);\n for (let e of this.projectMetadata.levels)if (e.externalRelPath) {\n const t = (0, i.pathRelativeToBase)(this.path, e.externalRelPath, this.pathMap);\n this._levelLoader.getOrAdd(t, this, {\n headless: this.headless,\n strict: this.strict,\n fileLoader: this.fileLoader,\n imageLoader: this._imageLoader,\n pathMap: this.pathMap\n });\n } else {\n const t = new p.Level(e, this);\n this.levels.set(e.uid, t), this.levelsByName.set(e.identifier.toLowerCase(), t);\n }\n return await Promise.all([\n this._imageLoader.load(),\n this._levelLoader.load()\n ]), this._levelLoader.values().forEach((e)=>{\n this.levels.set(e.data.ldtkLevel.uid, e.data), this.levelsByName.set(e.data.ldtkLevel.identifier.toLowerCase(), e.data);\n }), this.data = this.projectMetadata;\n }\n isLoaded() {\n return !!this.data;\n }\n registerEntityIdentifierFactory(e, t) {\n if (this.factories.set(e, t), this.isLoaded()) for (let t of this.getEntityLayers())t.runFactory(e);\n }\n getLevel(e) {\n return this.levelsByName.get(e.toLowerCase());\n }\n getEntityLayers(e) {\n let t = [];\n if (e) {\n const s = this.getLevel(e);\n if (s) for (let e of s.layers)e instanceof h.EntityLayer && t.push(e);\n } else for (const e of this.levels.values())for (let s of e.layers)s instanceof h.EntityLayer && t.push(s);\n return t;\n }\n getTileLayers(e) {\n let t = [];\n if (e) {\n const s = this.getLevel(e);\n if (s) for (let e of s.layers)e instanceof r.TileLayer && t.push(e);\n } else for (const e of this.levels.values())for (let s of e.layers)s instanceof r.TileLayer && t.push(s);\n return t;\n }\n getIntGridLayers(e) {\n let t = [];\n if (e) {\n const s = this.getLevel(e);\n if (s) for (let e of s.layers)e instanceof f.IntGridLayer && t.push(e);\n } else for (const e of this.levels.values())for (let s of e.layers)s instanceof f.IntGridLayer && t.push(s);\n return t;\n }\n getLdtkEntitiesByIdentifier(e, t) {\n let s = [];\n const r = null != t ? t : Array.from(this.levels.values()).map((e)=>e.ldtkLevel.identifier);\n for (const t of r){\n const r = this.getEntityLayers(t);\n for (let t of r)s = s.concat(t.getLdtkEntitiesByIdentifier(e));\n }\n return s;\n }\n getLdtkEntitiesByField(e, t, s) {\n let r = [];\n const i = null != s ? s : Array.from(this.levels.values()).map((e)=>e.ldtkLevel.identifier);\n for (const s of i){\n const i = this.getEntityLayers(s);\n for (let s of i)r = r.concat(s.getLdtkEntitiesByField(e, t));\n }\n return r;\n }\n getEntitiesByIdentifier(e, t) {\n let s = [];\n const r = null != t ? t : Array.from(this.levels.values()).map((e)=>e.ldtkLevel.identifier);\n for (const t of r){\n const r = this.getEntityLayers(t);\n for (let t of r)s = s.concat(t.getEntitiesByIdentifier(e));\n }\n return s;\n }\n getEntitiesByField(e, t, s) {\n let r = [];\n const i = null != s ? s : Array.from(this.levels.values()).map((e)=>e.ldtkLevel.identifier);\n for (const s of i){\n const i = this.getEntityLayers(s);\n for (let s of i)r = r.concat(s.getEntitiesByField(e, t));\n }\n return r;\n }\n getLevelBounds(e) {\n e = null != e ? e : Array.from(this.levelsByName.keys());\n let t = new l.BoundingBox;\n for (const s of this.levels.values()){\n if (!e.includes(s.ldtkLevel.identifier)) continue;\n const r = this.getTileLayers(s.ldtkLevel.identifier)[0];\n r && (t = t.combine(l.BoundingBox.fromDimension(r.tilemap.tileWidth * r.tilemap.columns, r.tilemap.tileHeight * r.tilemap.rows, l.Vector.Zero, r.tilemap.pos)));\n }\n return t;\n }\n addToScene(e, t) {\n var s, i;\n const { pos: a, useLevelOffsets: n } = {\n pos: (0, l.vec)(0, 0),\n useLevelOffsets: !0,\n ...t\n };\n for (let [i, o] of this.levels.entries())if (!(null === (s = null == t ? void 0 : t.levelFilter) || void 0 === s ? void 0 : s.length) || t.levelFilter.includes(o.ldtkLevel.identifier)) for (let t of o.layers)if (t instanceof r.TileLayer || t instanceof f.IntGridLayer) t.tilemap.pos = t.tilemap.pos.add(a), n || (t.tilemap.pos = t.tilemap.pos.sub(t.worldPos)), e.add(t.tilemap);\n else for (let s of t.entities){\n const r = s.get(l.TransformComponent);\n r && (r.pos = r.pos.add(a), n || (r.pos = r.pos.sub(t.worldPos))), e.add(s);\n }\n if (this.useExcaliburWiring) {\n const t = this.getLdtkEntitiesByField(\"camera\", !0)[0];\n if (t) {\n e.camera.pos = (0, l.vec)(t.px[0], t.px[0]);\n const s = t.fieldInstances.find((e)=>\"zoom\" === e.__identifier.toLocaleLowerCase());\n s && (e.camera.zoom = +s.__value);\n }\n }\n if (this.useTilemapCameraStrategy) {\n let s = this.getLevelBounds(null == t ? void 0 : t.levelFilter);\n e.camera.strategy.limitCameraBounds(s);\n }\n if (this.useMapBackgroundColor) {\n for (let [s, r] of this.levels.entries())if (!(null === (i = null == t ? void 0 : t.levelFilter) || void 0 === i ? void 0 : i.length) || t.levelFilter.includes(r.ldtkLevel.identifier)) {\n e.backgroundColor = r.backgroundColor;\n break;\n }\n }\n }\n }\n t.LdtkResource = m, m.supportedLdtkVersion = \"1.5.3\";\n },\n 515: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.LevelResource = void 0;\n const r = s(205), i = s(289), a = s(710), n = s(512), o = s(699);\n t.LevelResource = class {\n constructor(e, t, s){\n this.path = e, this.resource = t, this.fileLoader = a.FetchLoader, this.strict = !0, this.headless = !1;\n const { headless: n, strict: o, fileLoader: d, imageLoader: l, pathMap: u } = {\n ...s\n };\n this.fileLoader = null != d ? d : this.fileLoader, this.strict = null != o ? o : this.strict, this.headless = null != n ? n : this.headless, this.imageLoader = null != l ? l : new i.LoaderCache(r.ImageSource), this.pathMap = null != u ? u : this.pathMap;\n }\n async load() {\n const e = await this.fileLoader(this.path, \"json\");\n let t;\n if (this.strict) try {\n t = o.LdtkLevel.parse(e);\n } catch (e) {\n throw console.error(`Could not parse LDtk level data at ${this.path} are you sure a level is there and not corrupt?`), e;\n }\n else t = e;\n return this.data = new n.Level(t, this.resource);\n }\n isLoaded() {\n return !!this.data;\n }\n };\n },\n 512: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.Level = void 0;\n const r = s(205), i = s(961), a = s(920), n = s(692);\n t.Level = class {\n constructor(e, t){\n var s, o, d;\n if (this.ldtkLevel = e, this.resource = t, this.layers = [], e.__bgColor && (this.backgroundColor = r.Color.fromHex(e.__bgColor)), e.layerInstances) {\n let r = t.startZIndex, l = e.layerInstances.slice().reverse();\n for (let e of l)0 !== (null === (s = e.entityInstances) || void 0 === s ? void 0 : s.length) && this.layers.push(new i.EntityLayer(this, e, t, r)), 0 !== (null === (o = e.gridTiles) || void 0 === o ? void 0 : o.length) && this.layers.push(new n.TileLayer(this, e, t, r)), 0 !== (null === (d = e.intGridCsv) || void 0 === d ? void 0 : d.length) && this.layers.push(new a.IntGridLayer(this, e, t, r)), r++;\n }\n }\n };\n },\n 289: (e, t)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.LoaderCache = void 0, t.LoaderCache = class {\n constructor(e){\n this.type = e, this._loaded = !1, this.cache = new Map;\n }\n getOrAdd(...e) {\n let t = this.cache.get(e.join(\"+\"));\n return t || (t = new this.type(...e), this.cache.set(e.join(\"+\"), t), t);\n }\n values() {\n if (this._loaded) return Array.from(this.cache.values());\n throw new Error(\"Read through cache not yet loaded! No values to return!\");\n }\n async load() {\n const e = Array.from(this.cache.entries()), t = await Promise.allSettled(e.map((e)=>e[1].load()));\n let s = 0;\n for(let r = 0; r < t.length; r++){\n const i = t[r];\n \"rejected\" === i.status && (console.error(`Error loading resource at ${e[r][0]}, is your pathMap correct? or your LDtk map corrupted?`, i.reason), s++);\n }\n if (s) throw new Error(`Error loading ${s} resources`);\n this._loaded = !0;\n }\n };\n },\n 32: (e, t)=>{\n function s(e, t) {\n for (const { path: s, output: r } of t)if (\"string\" == typeof s) {\n if (e.includes(s)) return r;\n } else {\n const t = e.match(s);\n if (t) return r.replace(\"[match]\", t[0]);\n }\n return e;\n }\n function r(e, t) {\n if (!t) return !1;\n for (const { path: s, output: r } of t)if (\"string\" == typeof s) {\n if (e.includes(s)) return !0;\n } else if (e.match(s)) return !0;\n return !1;\n }\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.pathRelativeToBase = t.pathInMap = t.mapPath = t.filenameFromPath = void 0, t.filenameFromPath = function(e) {\n const t = e.match(/[^/\\\\&\\?]+\\.\\w{2,4}(?=([\\#\\?&].*$|$))/gi);\n if (t) return t[0];\n throw new Error(`Could not locate filename from path: ${e}`);\n }, t.mapPath = s, t.pathInMap = r, t.pathRelativeToBase = function(e, t, i) {\n if (r(t, i) && i) return s(t, i);\n if (0 === t.indexOf(\"/\")) return t;\n const a = e.split(\"/\"), n = t.split(\"/\");\n return a[a.length - 1].includes(\".\") && a.pop(), a.concat(n).join(\"/\");\n };\n },\n 692: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.TileLayer = void 0;\n const r = s(205);\n t.TileLayer = class {\n constructor(e, t, s, i){\n this.order = i, this.worldPos = (0, r.vec)(e.ldtkLevel.worldX, e.ldtkLevel.worldY), this.offset = (0, r.vec)(t.__pxTotalOffsetX, t.__pxTotalOffsetY), this.ldtkLayer = t, this.tilemap = new r.TileMap({\n name: t.__identifier,\n pos: this.worldPos.add(this.offset),\n tileWidth: t.__gridSize,\n tileHeight: t.__gridSize,\n rows: t.__cHei,\n columns: t.__cWid\n }), this.tilemap.z = i;\n for (let e of t.gridTiles){\n const r = Math.floor(e.px[0] / t.__gridSize), i = Math.floor(e.px[1] / t.__gridSize), a = this.tilemap.getTile(r, i);\n if (t.__tilesetDefUid) {\n const r = s.tilesets.get(t.__tilesetDefUid);\n if (r) {\n const t = Math.floor(e.src[0] / r.ldtkTileset.tileGridSize), s = Math.floor(e.src[1] / r.ldtkTileset.tileGridSize), i = r.spritesheet.getSprite(t, s);\n i ? a.addGraphic(i) : console.error(\"Could not find sprite in LDtk spritesheet at\", t, s);\n }\n } else console.error(\"Could not tileset in LDtk\", t.__tilesetDefUid, t.__tilesetRelPath);\n }\n }\n };\n },\n 245: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.Tileset = void 0;\n const r = s(205);\n t.Tileset = class {\n constructor(e){\n const { image: t, ldtkTileset: s } = e;\n this.image = t, this.ldtkTileset = s, this.spritesheet = r.SpriteSheet.fromImageSource({\n image: t,\n grid: {\n rows: s.pxHei / s.tileGridSize,\n columns: s.pxWid / s.tileGridSize,\n spriteHeight: s.tileGridSize,\n spriteWidth: s.tileGridSize\n }\n });\n }\n };\n },\n 699: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.LdtkProjectMetadata = t.LdtkEntityDefinition = t.LdtkLayerDefinition = t.LdtkLevel = t.LdtkLayerInstance = t.LdtkEntityInstance = void 0;\n const r = s(754), i = r.z.object({\n h: r.z.number(),\n tilesetUid: r.z.number(),\n w: r.z.number(),\n x: r.z.number(),\n y: r.z.number()\n }), a = r.z.tuple([\n r.z.number(),\n r.z.number()\n ]), n = r.z.object({\n __identifier: r.z.string(),\n __tile: i.nullable(),\n __type: r.z.string(),\n __value: r.z.any(),\n defUid: r.z.number()\n }), o = r.z.object({\n a: r.z.number(),\n f: r.z.number(),\n px: a,\n src: a,\n t: r.z.number()\n });\n t.LdtkEntityInstance = r.z.object({\n __grid: a,\n __identifier: r.z.string(),\n __pivot: a,\n __smartColor: r.z.string(),\n __tags: r.z.array(r.z.string()),\n __tile: i.nullable(),\n __worldX: r.z.number().nullable(),\n __worldY: r.z.number().nullable(),\n defUid: r.z.number(),\n fieldInstances: r.z.array(n),\n height: r.z.number(),\n iid: r.z.string(),\n px: a,\n width: r.z.number()\n }), t.LdtkLayerInstance = r.z.object({\n __cHei: r.z.number(),\n __cWid: r.z.number(),\n __gridSize: r.z.number(),\n __identifier: r.z.string(),\n __opacity: r.z.number(),\n __pxTotalOffsetX: r.z.number(),\n __pxTotalOffsetY: r.z.number(),\n __tilesetDefUid: r.z.number().nullable(),\n __tilesetRelPath: r.z.string().nullable(),\n __type: r.z.union([\n r.z.literal(\"IntGrid\"),\n r.z.literal(\"Entities\"),\n r.z.literal(\"Tiles\"),\n r.z.literal(\"AutoLayer\")\n ]),\n autoLayerTiles: r.z.array(o),\n entityInstances: r.z.array(t.LdtkEntityInstance),\n gridTiles: r.z.array(o),\n iid: r.z.string(),\n intGridCsv: r.z.array(r.z.number()),\n layerDefUid: r.z.number(),\n levelId: r.z.number(),\n overrideTilesetUid: r.z.number().nullable(),\n pxOffsetX: r.z.number(),\n pxOffsetY: r.z.number(),\n visible: r.z.boolean()\n }), t.LdtkLevel = r.z.object({\n __bgColor: r.z.string().nullable(),\n bgColor: r.z.string().nullable(),\n __bgPos: r.z.object({\n cropRect: r.z.array(r.z.tuple([\n r.z.number(),\n r.z.number(),\n r.z.number(),\n r.z.number()\n ])),\n scale: r.z.tuple([\n r.z.number(),\n r.z.number()\n ]),\n topLeftPx: a\n }).nullable(),\n __neighbours: r.z.array(r.z.object({\n dir: r.z.union([\n r.z.literal(\"n\"),\n r.z.literal(\"s\"),\n r.z.literal(\"w\"),\n r.z.literal(\"e\"),\n r.z.literal(\"ne\"),\n r.z.literal(\"nw\"),\n r.z.literal(\"se\"),\n r.z.literal(\"sw\"),\n r.z.literal(\"o\"),\n r.z.literal(\"<\"),\n r.z.literal(\">\")\n ]),\n levelIid: r.z.string()\n })),\n bgRelPath: r.z.string().nullable(),\n externalRelPath: r.z.string().nullable(),\n fieldInstances: r.z.array(n),\n identifier: r.z.string(),\n iid: r.z.string(),\n layerInstances: r.z.array(t.LdtkLayerInstance).nullable(),\n pxHei: r.z.number(),\n pxWid: r.z.number(),\n uid: r.z.number(),\n worldDepth: r.z.number(),\n worldX: r.z.number(),\n worldY: r.z.number()\n });\n const d = r.z.object({\n identifier: r.z.string(),\n iid: r.z.string(),\n levels: r.z.array(t.LdtkLevel),\n worldGridHeight: r.z.number(),\n worldGridWidth: r.z.number(),\n worldLayout: r.z.union([\n r.z.literal(\"Free\"),\n r.z.literal(\"GridVania\"),\n r.z.literal(\"LinearHorizontal\"),\n r.z.literal(\"LinearVertical\")\n ])\n }), l = r.z.object({\n color: r.z.number(),\n id: r.z.string(),\n tileRect: i.nullable()\n }), u = r.z.object({\n externalRelPath: r.z.string().nullable(),\n iconTilesetUid: r.z.number().nullable(),\n identifier: r.z.string(),\n tags: r.z.array(r.z.string()),\n uid: r.z.number(),\n values: r.z.array(l)\n }), c = r.z.object({\n __cHei: r.z.number(),\n __cWid: r.z.number(),\n customData: r.z.array(r.z.object({\n data: r.z.string(),\n tileId: r.z.number()\n })),\n embedAtlas: r.z.string().nullable(),\n enumsTags: r.z.optional(r.z.array(r.z.object({\n enumValueId: r.z.string(),\n tileIds: r.z.array(r.z.number())\n }))),\n identifier: r.z.string(),\n padding: r.z.number(),\n pxHei: r.z.number(),\n pxWid: r.z.number(),\n relPath: r.z.string().nullable(),\n spacing: r.z.number(),\n tags: r.z.array(r.z.string()),\n tagsSourceEnumUid: r.z.number().nullable(),\n tileGridSize: r.z.number(),\n uid: r.z.number()\n });\n t.LdtkLayerDefinition = r.z.object({\n __type: r.z.union([\n r.z.literal(\"IntGrid\"),\n r.z.literal(\"Entities\"),\n r.z.literal(\"Tiles\"),\n r.z.literal(\"AutoLayer\")\n ]),\n autoSourceLayerDefUid: r.z.number().nullable(),\n displayOpacity: r.z.number(),\n gridSize: r.z.number(),\n identifier: r.z.string(),\n intGridValues: r.z.array(r.z.object({\n color: r.z.string(),\n groupUid: r.z.number(),\n identifier: r.z.string().nullable(),\n tile: i.nullable(),\n value: r.z.number()\n })),\n intGridValuesGroups: r.z.array(r.z.object({\n color: r.z.string().nullable(),\n identifier: r.z.string().nullable(),\n uid: r.z.number()\n })),\n parallaxFactorX: r.z.number(),\n parallaxFactorY: r.z.number(),\n parallaxScaling: r.z.boolean(),\n pxOffsetX: r.z.number(),\n pxOffsetY: r.z.number(),\n tilesetDefUid: r.z.number().nullable(),\n uid: r.z.number()\n }), t.LdtkEntityDefinition = r.z.object({\n color: r.z.string(),\n height: r.z.number(),\n identifier: r.z.string(),\n nineSliceBorders: r.z.array(r.z.number()),\n pivotX: r.z.number(),\n pivotY: r.z.number(),\n tileRect: i.nullable(),\n tileRenderMode: r.z.union([\n r.z.literal(\"Cover\"),\n r.z.literal(\"FitInside\"),\n r.z.literal(\"Repeat\"),\n r.z.literal(\"Stretch\"),\n r.z.literal(\"FullSizeCropped\"),\n r.z.literal(\"FullSizeUncropped\"),\n r.z.literal(\"NineSlice\")\n ]),\n tilesetId: r.z.number().nullable(),\n uiTileRect: i.nullable(),\n uid: r.z.number(),\n width: r.z.number()\n });\n const p = r.z.object({\n tilesets: r.z.array(c),\n enums: r.z.array(u),\n layers: r.z.array(t.LdtkLayerDefinition),\n entities: r.z.array(t.LdtkEntityDefinition)\n });\n t.LdtkProjectMetadata = r.z.object({\n iid: r.z.string(),\n bgColor: r.z.string().nullable(),\n defs: p,\n externalLevels: r.z.boolean(),\n jsonVersion: r.z.string(),\n levels: r.z.array(t.LdtkLevel),\n toc: r.z.array(r.z.object({\n identifier: r.z.string(),\n instancesData: r.z.array(r.z.object({\n fields: r.z.any(),\n heiPx: r.z.number(),\n iids: r.z.string(),\n widPix: r.z.number(),\n worldX: r.z.number(),\n worldY: r.z.number()\n }))\n })),\n worldGridHeight: r.z.number().nullable(),\n worldGridWidth: r.z.number().nullable(),\n worldLayout: r.z.union([\n r.z.literal(\"Free\"),\n r.z.literal(\"GridVania\"),\n r.z.literal(\"LinearHorizontal\"),\n r.z.literal(\"LinearVertical\")\n ]).nullable(),\n worlds: r.z.array(d)\n });\n },\n 280: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.ZodError = t.quotelessJson = t.ZodIssueCode = void 0;\n const r = s(110);\n t.ZodIssueCode = r.util.arrayToEnum([\n \"invalid_type\",\n \"invalid_literal\",\n \"custom\",\n \"invalid_union\",\n \"invalid_union_discriminator\",\n \"invalid_enum_value\",\n \"unrecognized_keys\",\n \"invalid_arguments\",\n \"invalid_return_type\",\n \"invalid_date\",\n \"invalid_string\",\n \"too_small\",\n \"too_big\",\n \"invalid_intersection_types\",\n \"not_multiple_of\",\n \"not_finite\"\n ]), t.quotelessJson = (e)=>JSON.stringify(e, null, 2).replace(/\"([^\"]+)\":/g, \"$1:\");\n class i extends Error {\n constructor(e){\n super(), this.issues = [], this.addIssue = (e)=>{\n this.issues = [\n ...this.issues,\n e\n ];\n }, this.addIssues = (e = [])=>{\n this.issues = [\n ...this.issues,\n ...e\n ];\n };\n const t = new.target.prototype;\n Object.setPrototypeOf ? Object.setPrototypeOf(this, t) : this.__proto__ = t, this.name = \"ZodError\", this.issues = e;\n }\n get errors() {\n return this.issues;\n }\n format(e) {\n const t = e || function(e) {\n return e.message;\n }, s = {\n _errors: []\n }, r = (e)=>{\n for (const i of e.issues)if (\"invalid_union\" === i.code) i.unionErrors.map(r);\n else if (\"invalid_return_type\" === i.code) r(i.returnTypeError);\n else if (\"invalid_arguments\" === i.code) r(i.argumentsError);\n else if (0 === i.path.length) s._errors.push(t(i));\n else {\n let e = s, r = 0;\n for(; r < i.path.length;){\n const s = i.path[r];\n r === i.path.length - 1 ? (e[s] = e[s] || {\n _errors: []\n }, e[s]._errors.push(t(i))) : e[s] = e[s] || {\n _errors: []\n }, e = e[s], r++;\n }\n }\n };\n return r(this), s;\n }\n toString() {\n return this.message;\n }\n get message() {\n return JSON.stringify(this.issues, r.util.jsonStringifyReplacer, 2);\n }\n get isEmpty() {\n return 0 === this.issues.length;\n }\n flatten(e = (e)=>e.message) {\n const t = {}, s = [];\n for (const r of this.issues)r.path.length > 0 ? (t[r.path[0]] = t[r.path[0]] || [], t[r.path[0]].push(e(r))) : s.push(e(r));\n return {\n formErrors: s,\n fieldErrors: t\n };\n }\n get formErrors() {\n return this.flatten();\n }\n }\n t.ZodError = i, i.create = (e)=>new i(e);\n },\n 996: function(e, t, s) {\n var r = this && this.__importDefault || function(e) {\n return e && e.__esModule ? e : {\n default: e\n };\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.getErrorMap = t.setErrorMap = t.defaultErrorMap = void 0;\n const i = r(s(325));\n t.defaultErrorMap = i.default;\n let a = i.default;\n t.setErrorMap = function(e) {\n a = e;\n }, t.getErrorMap = function() {\n return a;\n };\n },\n 349: function(e, t, s) {\n var r = this && this.__createBinding || (Object.create ? function(e, t, s, r) {\n void 0 === r && (r = s), Object.defineProperty(e, r, {\n enumerable: !0,\n get: function() {\n return t[s];\n }\n });\n } : function(e, t, s, r) {\n void 0 === r && (r = s), e[r] = t[s];\n }), i = this && this.__exportStar || function(e, t) {\n for(var s in e)\"default\" === s || Object.prototype.hasOwnProperty.call(t, s) || r(t, e, s);\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), i(s(996), t), i(s(187), t), i(s(116), t), i(s(110), t), i(s(433), t), i(s(280), t);\n },\n 762: (e, t)=>{\n var s;\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.errorUtil = void 0, (s = t.errorUtil || (t.errorUtil = {})).errToObj = (e)=>\"string\" == typeof e ? {\n message: e\n } : e || {}, s.toString = (e)=>\"string\" == typeof e ? e : null == e ? void 0 : e.message;\n },\n 187: function(e, t, s) {\n var r = this && this.__importDefault || function(e) {\n return e && e.__esModule ? e : {\n default: e\n };\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.isAsync = t.isValid = t.isDirty = t.isAborted = t.OK = t.DIRTY = t.INVALID = t.ParseStatus = t.addIssueToContext = t.EMPTY_PATH = t.makeIssue = void 0;\n const i = s(996), a = r(s(325));\n t.makeIssue = (e)=>{\n const { data: t, path: s, errorMaps: r, issueData: i } = e, a = [\n ...s,\n ...i.path || []\n ], n = {\n ...i,\n path: a\n };\n let o = \"\";\n const d = r.filter((e)=>!!e).slice().reverse();\n for (const e of d)o = e(n, {\n data: t,\n defaultError: o\n }).message;\n return {\n ...i,\n path: a,\n message: i.message || o\n };\n }, t.EMPTY_PATH = [], t.addIssueToContext = function(e, s) {\n const r = (0, t.makeIssue)({\n issueData: s,\n data: e.data,\n path: e.path,\n errorMaps: [\n e.common.contextualErrorMap,\n e.schemaErrorMap,\n (0, i.getErrorMap)(),\n a.default\n ].filter((e)=>!!e)\n });\n e.common.issues.push(r);\n };\n class n {\n constructor(){\n this.value = \"valid\";\n }\n dirty() {\n \"valid\" === this.value && (this.value = \"dirty\");\n }\n abort() {\n \"aborted\" !== this.value && (this.value = \"aborted\");\n }\n static mergeArray(e, s) {\n const r = [];\n for (const i of s){\n if (\"aborted\" === i.status) return t.INVALID;\n \"dirty\" === i.status && e.dirty(), r.push(i.value);\n }\n return {\n status: e.value,\n value: r\n };\n }\n static async mergeObjectAsync(e, t) {\n const s = [];\n for (const e of t)s.push({\n key: await e.key,\n value: await e.value\n });\n return n.mergeObjectSync(e, s);\n }\n static mergeObjectSync(e, s) {\n const r = {};\n for (const i of s){\n const { key: s, value: a } = i;\n if (\"aborted\" === s.status) return t.INVALID;\n if (\"aborted\" === a.status) return t.INVALID;\n \"dirty\" === s.status && e.dirty(), \"dirty\" === a.status && e.dirty(), \"__proto__\" === s.value || void 0 === a.value && !i.alwaysSet || (r[s.value] = a.value);\n }\n return {\n status: e.value,\n value: r\n };\n }\n }\n t.ParseStatus = n, t.INVALID = Object.freeze({\n status: \"aborted\"\n }), t.DIRTY = (e)=>({\n status: \"dirty\",\n value: e\n }), t.OK = (e)=>({\n status: \"valid\",\n value: e\n }), t.isAborted = (e)=>\"aborted\" === e.status, t.isDirty = (e)=>\"dirty\" === e.status, t.isValid = (e)=>\"valid\" === e.status, t.isAsync = (e)=>\"undefined\" != typeof Promise && e instanceof Promise;\n },\n 116: (e, t)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n });\n },\n 110: (e, t)=>{\n var s;\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.getParsedType = t.ZodParsedType = t.objectUtil = t.util = void 0, function(e) {\n e.assertEqual = (e)=>e, e.assertIs = function(e) {}, e.assertNever = function(e) {\n throw new Error;\n }, e.arrayToEnum = (e)=>{\n const t = {};\n for (const s of e)t[s] = s;\n return t;\n }, e.getValidEnumValues = (t)=>{\n const s = e.objectKeys(t).filter((e)=>\"number\" != typeof t[t[e]]), r = {};\n for (const e of s)r[e] = t[e];\n return e.objectValues(r);\n }, e.objectValues = (t)=>e.objectKeys(t).map(function(e) {\n return t[e];\n }), e.objectKeys = \"function\" == typeof Object.keys ? (e)=>Object.keys(e) : (e)=>{\n const t = [];\n for(const s in e)Object.prototype.hasOwnProperty.call(e, s) && t.push(s);\n return t;\n }, e.find = (e, t)=>{\n for (const s of e)if (t(s)) return s;\n }, e.isInteger = \"function\" == typeof Number.isInteger ? (e)=>Number.isInteger(e) : (e)=>\"number\" == typeof e && isFinite(e) && Math.floor(e) === e, e.joinValues = function(e, t = \" | \") {\n return e.map((e)=>\"string\" == typeof e ? `'${e}'` : e).join(t);\n }, e.jsonStringifyReplacer = (e, t)=>\"bigint\" == typeof t ? t.toString() : t;\n }(s = t.util || (t.util = {})), (t.objectUtil || (t.objectUtil = {})).mergeShapes = (e, t)=>({\n ...e,\n ...t\n }), t.ZodParsedType = s.arrayToEnum([\n \"string\",\n \"nan\",\n \"number\",\n \"integer\",\n \"float\",\n \"boolean\",\n \"date\",\n \"bigint\",\n \"symbol\",\n \"function\",\n \"undefined\",\n \"null\",\n \"array\",\n \"object\",\n \"unknown\",\n \"promise\",\n \"void\",\n \"never\",\n \"map\",\n \"set\"\n ]), t.getParsedType = (e)=>{\n switch(typeof e){\n case \"undefined\":\n return t.ZodParsedType.undefined;\n case \"string\":\n return t.ZodParsedType.string;\n case \"number\":\n return isNaN(e) ? t.ZodParsedType.nan : t.ZodParsedType.number;\n case \"boolean\":\n return t.ZodParsedType.boolean;\n case \"function\":\n return t.ZodParsedType.function;\n case \"bigint\":\n return t.ZodParsedType.bigint;\n case \"symbol\":\n return t.ZodParsedType.symbol;\n case \"object\":\n return Array.isArray(e) ? t.ZodParsedType.array : null === e ? t.ZodParsedType.null : e.then && \"function\" == typeof e.then && e.catch && \"function\" == typeof e.catch ? t.ZodParsedType.promise : \"undefined\" != typeof Map && e instanceof Map ? t.ZodParsedType.map : \"undefined\" != typeof Set && e instanceof Set ? t.ZodParsedType.set : \"undefined\" != typeof Date && e instanceof Date ? t.ZodParsedType.date : t.ZodParsedType.object;\n default:\n return t.ZodParsedType.unknown;\n }\n };\n },\n 754: function(e, t, s) {\n var r = this && this.__createBinding || (Object.create ? function(e, t, s, r) {\n void 0 === r && (r = s), Object.defineProperty(e, r, {\n enumerable: !0,\n get: function() {\n return t[s];\n }\n });\n } : function(e, t, s, r) {\n void 0 === r && (r = s), e[r] = t[s];\n }), i = this && this.__setModuleDefault || (Object.create ? function(e, t) {\n Object.defineProperty(e, \"default\", {\n enumerable: !0,\n value: t\n });\n } : function(e, t) {\n e.default = t;\n }), a = this && this.__importStar || function(e) {\n if (e && e.__esModule) return e;\n var t = {};\n if (null != e) for(var s in e)\"default\" !== s && Object.prototype.hasOwnProperty.call(e, s) && r(t, e, s);\n return i(t, e), t;\n }, n = this && this.__exportStar || function(e, t) {\n for(var s in e)\"default\" === s || Object.prototype.hasOwnProperty.call(t, s) || r(t, e, s);\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.z = void 0;\n const o = a(s(349));\n t.z = o, n(s(349), t), t.default = o;\n },\n 325: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n });\n const r = s(110), i = s(280);\n t.default = (e, t)=>{\n let s;\n switch(e.code){\n case i.ZodIssueCode.invalid_type:\n s = e.received === r.ZodParsedType.undefined ? \"Required\" : `Expected ${e.expected}, received ${e.received}`;\n break;\n case i.ZodIssueCode.invalid_literal:\n s = `Invalid literal value, expected ${JSON.stringify(e.expected, r.util.jsonStringifyReplacer)}`;\n break;\n case i.ZodIssueCode.unrecognized_keys:\n s = `Unrecognized key(s) in object: ${r.util.joinValues(e.keys, \", \")}`;\n break;\n case i.ZodIssueCode.invalid_union:\n s = \"Invalid input\";\n break;\n case i.ZodIssueCode.invalid_union_discriminator:\n s = `Invalid discriminator value. Expected ${r.util.joinValues(e.options)}`;\n break;\n case i.ZodIssueCode.invalid_enum_value:\n s = `Invalid enum value. Expected ${r.util.joinValues(e.options)}, received '${e.received}'`;\n break;\n case i.ZodIssueCode.invalid_arguments:\n s = \"Invalid function arguments\";\n break;\n case i.ZodIssueCode.invalid_return_type:\n s = \"Invalid function return type\";\n break;\n case i.ZodIssueCode.invalid_date:\n s = \"Invalid date\";\n break;\n case i.ZodIssueCode.invalid_string:\n \"object\" == typeof e.validation ? \"includes\" in e.validation ? (s = `Invalid input: must include \"${e.validation.includes}\"`, \"number\" == typeof e.validation.position && (s = `${s} at one or more positions greater than or equal to ${e.validation.position}`)) : \"startsWith\" in e.validation ? s = `Invalid input: must start with \"${e.validation.startsWith}\"` : \"endsWith\" in e.validation ? s = `Invalid input: must end with \"${e.validation.endsWith}\"` : r.util.assertNever(e.validation) : s = \"regex\" !== e.validation ? `Invalid ${e.validation}` : \"Invalid\";\n break;\n case i.ZodIssueCode.too_small:\n s = \"array\" === e.type ? `Array must contain ${e.exact ? \"exactly\" : e.inclusive ? \"at least\" : \"more than\"} ${e.minimum} element(s)` : \"string\" === e.type ? `String must contain ${e.exact ? \"exactly\" : e.inclusive ? \"at least\" : \"over\"} ${e.minimum} character(s)` : \"number\" === e.type ? `Number must be ${e.exact ? \"exactly equal to \" : e.inclusive ? \"greater than or equal to \" : \"greater than \"}${e.minimum}` : \"date\" === e.type ? `Date must be ${e.exact ? \"exactly equal to \" : e.inclusive ? \"greater than or equal to \" : \"greater than \"}${new Date(Number(e.minimum))}` : \"Invalid input\";\n break;\n case i.ZodIssueCode.too_big:\n s = \"array\" === e.type ? `Array must contain ${e.exact ? \"exactly\" : e.inclusive ? \"at most\" : \"less than\"} ${e.maximum} element(s)` : \"string\" === e.type ? `String must contain ${e.exact ? \"exactly\" : e.inclusive ? \"at most\" : \"under\"} ${e.maximum} character(s)` : \"number\" === e.type ? `Number must be ${e.exact ? \"exactly\" : e.inclusive ? \"less than or equal to\" : \"less than\"} ${e.maximum}` : \"bigint\" === e.type ? `BigInt must be ${e.exact ? \"exactly\" : e.inclusive ? \"less than or equal to\" : \"less than\"} ${e.maximum}` : \"date\" === e.type ? `Date must be ${e.exact ? \"exactly\" : e.inclusive ? \"smaller than or equal to\" : \"smaller than\"} ${new Date(Number(e.maximum))}` : \"Invalid input\";\n break;\n case i.ZodIssueCode.custom:\n s = \"Invalid input\";\n break;\n case i.ZodIssueCode.invalid_intersection_types:\n s = \"Intersection results could not be merged\";\n break;\n case i.ZodIssueCode.not_multiple_of:\n s = `Number must be a multiple of ${e.multipleOf}`;\n break;\n case i.ZodIssueCode.not_finite:\n s = \"Number must be finite\";\n break;\n default:\n s = t.defaultError, r.util.assertNever(e);\n }\n return {\n message: s\n };\n };\n },\n 433: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.date = t.boolean = t.bigint = t.array = t.any = t.coerce = t.ZodFirstPartyTypeKind = t.late = t.ZodSchema = t.Schema = t.custom = t.ZodReadonly = t.ZodPipeline = t.ZodBranded = t.BRAND = t.ZodNaN = t.ZodCatch = t.ZodDefault = t.ZodNullable = t.ZodOptional = t.ZodTransformer = t.ZodEffects = t.ZodPromise = t.ZodNativeEnum = t.ZodEnum = t.ZodLiteral = t.ZodLazy = t.ZodFunction = t.ZodSet = t.ZodMap = t.ZodRecord = t.ZodTuple = t.ZodIntersection = t.ZodDiscriminatedUnion = t.ZodUnion = t.ZodObject = t.ZodArray = t.ZodVoid = t.ZodNever = t.ZodUnknown = t.ZodAny = t.ZodNull = t.ZodUndefined = t.ZodSymbol = t.ZodDate = t.ZodBoolean = t.ZodBigInt = t.ZodNumber = t.ZodString = t.ZodType = void 0, t.NEVER = t.void = t.unknown = t.union = t.undefined = t.tuple = t.transformer = t.symbol = t.string = t.strictObject = t.set = t.record = t.promise = t.preprocess = t.pipeline = t.ostring = t.optional = t.onumber = t.oboolean = t.object = t.number = t.nullable = t.null = t.never = t.nativeEnum = t.nan = t.map = t.literal = t.lazy = t.intersection = t.instanceof = t.function = t.enum = t.effect = t.discriminatedUnion = void 0;\n const r = s(996), i = s(762), a = s(187), n = s(110), o = s(280);\n class d {\n constructor(e, t, s, r){\n this._cachedPath = [], this.parent = e, this.data = t, this._path = s, this._key = r;\n }\n get path() {\n return this._cachedPath.length || (this._key instanceof Array ? this._cachedPath.push(...this._path, ...this._key) : this._cachedPath.push(...this._path, this._key)), this._cachedPath;\n }\n }\n const l = (e, t)=>{\n if ((0, a.isValid)(t)) return {\n success: !0,\n data: t.value\n };\n if (!e.common.issues.length) throw new Error(\"Validation failed but no issues detected.\");\n return {\n success: !1,\n get error () {\n if (this._error) return this._error;\n const t = new o.ZodError(e.common.issues);\n return this._error = t, this._error;\n }\n };\n };\n function u(e) {\n if (!e) return {};\n const { errorMap: t, invalid_type_error: s, required_error: r, description: i } = e;\n if (t && (s || r)) throw new Error('Can\\'t use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.');\n return t ? {\n errorMap: t,\n description: i\n } : {\n errorMap: (e, t)=>\"invalid_type\" !== e.code ? {\n message: t.defaultError\n } : void 0 === t.data ? {\n message: null != r ? r : t.defaultError\n } : {\n message: null != s ? s : t.defaultError\n },\n description: i\n };\n }\n class c {\n constructor(e){\n this.spa = this.safeParseAsync, this._def = e, this.parse = this.parse.bind(this), this.safeParse = this.safeParse.bind(this), this.parseAsync = this.parseAsync.bind(this), this.safeParseAsync = this.safeParseAsync.bind(this), this.spa = this.spa.bind(this), this.refine = this.refine.bind(this), this.refinement = this.refinement.bind(this), this.superRefine = this.superRefine.bind(this), this.optional = this.optional.bind(this), this.nullable = this.nullable.bind(this), this.nullish = this.nullish.bind(this), this.array = this.array.bind(this), this.promise = this.promise.bind(this), this.or = this.or.bind(this), this.and = this.and.bind(this), this.transform = this.transform.bind(this), this.brand = this.brand.bind(this), this.default = this.default.bind(this), this.catch = this.catch.bind(this), this.describe = this.describe.bind(this), this.pipe = this.pipe.bind(this), this.readonly = this.readonly.bind(this), this.isNullable = this.isNullable.bind(this), this.isOptional = this.isOptional.bind(this);\n }\n get description() {\n return this._def.description;\n }\n _getType(e) {\n return (0, n.getParsedType)(e.data);\n }\n _getOrReturnCtx(e, t) {\n return t || {\n common: e.parent.common,\n data: e.data,\n parsedType: (0, n.getParsedType)(e.data),\n schemaErrorMap: this._def.errorMap,\n path: e.path,\n parent: e.parent\n };\n }\n _processInputParams(e) {\n return {\n status: new a.ParseStatus,\n ctx: {\n common: e.parent.common,\n data: e.data,\n parsedType: (0, n.getParsedType)(e.data),\n schemaErrorMap: this._def.errorMap,\n path: e.path,\n parent: e.parent\n }\n };\n }\n _parseSync(e) {\n const t = this._parse(e);\n if ((0, a.isAsync)(t)) throw new Error(\"Synchronous parse encountered promise.\");\n return t;\n }\n _parseAsync(e) {\n const t = this._parse(e);\n return Promise.resolve(t);\n }\n parse(e, t) {\n const s = this.safeParse(e, t);\n if (s.success) return s.data;\n throw s.error;\n }\n safeParse(e, t) {\n var s;\n const r = {\n common: {\n issues: [],\n async: null !== (s = null == t ? void 0 : t.async) && void 0 !== s && s,\n contextualErrorMap: null == t ? void 0 : t.errorMap\n },\n path: (null == t ? void 0 : t.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data: e,\n parsedType: (0, n.getParsedType)(e)\n }, i = this._parseSync({\n data: e,\n path: r.path,\n parent: r\n });\n return l(r, i);\n }\n async parseAsync(e, t) {\n const s = await this.safeParseAsync(e, t);\n if (s.success) return s.data;\n throw s.error;\n }\n async safeParseAsync(e, t) {\n const s = {\n common: {\n issues: [],\n contextualErrorMap: null == t ? void 0 : t.errorMap,\n async: !0\n },\n path: (null == t ? void 0 : t.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data: e,\n parsedType: (0, n.getParsedType)(e)\n }, r = this._parse({\n data: e,\n path: s.path,\n parent: s\n }), i = await ((0, a.isAsync)(r) ? r : Promise.resolve(r));\n return l(s, i);\n }\n refine(e, t) {\n const s = (e)=>\"string\" == typeof t || void 0 === t ? {\n message: t\n } : \"function\" == typeof t ? t(e) : t;\n return this._refinement((t, r)=>{\n const i = e(t), a = ()=>r.addIssue({\n code: o.ZodIssueCode.custom,\n ...s(t)\n });\n return \"undefined\" != typeof Promise && i instanceof Promise ? i.then((e)=>!!e || (a(), !1)) : !!i || (a(), !1);\n });\n }\n refinement(e, t) {\n return this._refinement((s, r)=>!!e(s) || (r.addIssue(\"function\" == typeof t ? t(s, r) : t), !1));\n }\n _refinement(e) {\n return new J({\n schema: this,\n typeName: oe.ZodEffects,\n effect: {\n type: \"refinement\",\n refinement: e\n }\n });\n }\n superRefine(e) {\n return this._refinement(e);\n }\n optional() {\n return Q.create(this, this._def);\n }\n nullable() {\n return ee.create(this, this._def);\n }\n nullish() {\n return this.nullable().optional();\n }\n array() {\n return E.create(this, this._def);\n }\n promise() {\n return X.create(this, this._def);\n }\n or(e) {\n return A.create([\n this,\n e\n ], this._def);\n }\n and(e) {\n return R.create(this, e, this._def);\n }\n transform(e) {\n return new J({\n ...u(this._def),\n schema: this,\n typeName: oe.ZodEffects,\n effect: {\n type: \"transform\",\n transform: e\n }\n });\n }\n default(e) {\n const t = \"function\" == typeof e ? e : ()=>e;\n return new te({\n ...u(this._def),\n innerType: this,\n defaultValue: t,\n typeName: oe.ZodDefault\n });\n }\n brand() {\n return new ie({\n typeName: oe.ZodBranded,\n type: this,\n ...u(this._def)\n });\n }\n catch(e) {\n const t = \"function\" == typeof e ? e : ()=>e;\n return new se({\n ...u(this._def),\n innerType: this,\n catchValue: t,\n typeName: oe.ZodCatch\n });\n }\n describe(e) {\n return new this.constructor({\n ...this._def,\n description: e\n });\n }\n pipe(e) {\n return ae.create(this, e);\n }\n readonly() {\n return ne.create(this);\n }\n isOptional() {\n return this.safeParse(void 0).success;\n }\n isNullable() {\n return this.safeParse(null).success;\n }\n }\n t.ZodType = c, t.Schema = c, t.ZodSchema = c;\n const p = /^c[^\\s-]{8,}$/i, h = /^[a-z][a-z0-9]*$/, f = /^[0-9A-HJKMNP-TV-Z]{26}$/, m = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i, y = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_+-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\n let _;\n const v = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/, g = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;\n class b extends c {\n _parse(e) {\n if (this._def.coerce && (e.data = String(e.data)), this._getType(e) !== n.ZodParsedType.string) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.string,\n received: t.parsedType\n }), a.INVALID;\n }\n const t = new a.ParseStatus;\n let s;\n for (const l of this._def.checks)if (\"min\" === l.kind) e.data.length < l.value && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n minimum: l.value,\n type: \"string\",\n inclusive: !0,\n exact: !1,\n message: l.message\n }), t.dirty());\n else if (\"max\" === l.kind) e.data.length > l.value && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n maximum: l.value,\n type: \"string\",\n inclusive: !0,\n exact: !1,\n message: l.message\n }), t.dirty());\n else if (\"length\" === l.kind) {\n const r = e.data.length > l.value, i = e.data.length < l.value;\n (r || i) && (s = this._getOrReturnCtx(e, s), r ? (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n maximum: l.value,\n type: \"string\",\n inclusive: !0,\n exact: !0,\n message: l.message\n }) : i && (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n minimum: l.value,\n type: \"string\",\n inclusive: !0,\n exact: !0,\n message: l.message\n }), t.dirty());\n } else if (\"email\" === l.kind) y.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"email\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"emoji\" === l.kind) _ || (_ = new RegExp(\"^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$\", \"u\")), _.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"emoji\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"uuid\" === l.kind) m.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"uuid\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"cuid\" === l.kind) p.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"cuid\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"cuid2\" === l.kind) h.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"cuid2\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"ulid\" === l.kind) f.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"ulid\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"url\" === l.kind) try {\n new URL(e.data);\n } catch (r) {\n s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"url\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty();\n }\n else \"regex\" === l.kind ? (l.regex.lastIndex = 0, l.regex.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"regex\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty())) : \"trim\" === l.kind ? e.data = e.data.trim() : \"includes\" === l.kind ? e.data.includes(l.value, l.position) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_string,\n validation: {\n includes: l.value,\n position: l.position\n },\n message: l.message\n }), t.dirty()) : \"toLowerCase\" === l.kind ? e.data = e.data.toLowerCase() : \"toUpperCase\" === l.kind ? e.data = e.data.toUpperCase() : \"startsWith\" === l.kind ? e.data.startsWith(l.value) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_string,\n validation: {\n startsWith: l.value\n },\n message: l.message\n }), t.dirty()) : \"endsWith\" === l.kind ? e.data.endsWith(l.value) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_string,\n validation: {\n endsWith: l.value\n },\n message: l.message\n }), t.dirty()) : \"datetime\" === l.kind ? ((d = l).precision ? d.offset ? new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{${d.precision}}(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$`) : new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{${d.precision}}Z$`) : 0 === d.precision ? d.offset ? new RegExp(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$\") : new RegExp(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}Z$\") : d.offset ? new RegExp(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$\") : new RegExp(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?Z$\")).test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_string,\n validation: \"datetime\",\n message: l.message\n }), t.dirty()) : \"ip\" === l.kind ? (r = e.data, (\"v4\" !== (i = l.version) && i || !v.test(r)) && (\"v6\" !== i && i || !g.test(r)) && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"ip\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty())) : n.util.assertNever(l);\n var r, i, d;\n return {\n status: t.value,\n value: e.data\n };\n }\n _regex(e, t, s) {\n return this.refinement((t)=>e.test(t), {\n validation: t,\n code: o.ZodIssueCode.invalid_string,\n ...i.errorUtil.errToObj(s)\n });\n }\n _addCheck(e) {\n return new b({\n ...this._def,\n checks: [\n ...this._def.checks,\n e\n ]\n });\n }\n email(e) {\n return this._addCheck({\n kind: \"email\",\n ...i.errorUtil.errToObj(e)\n });\n }\n url(e) {\n return this._addCheck({\n kind: \"url\",\n ...i.errorUtil.errToObj(e)\n });\n }\n emoji(e) {\n return this._addCheck({\n kind: \"emoji\",\n ...i.errorUtil.errToObj(e)\n });\n }\n uuid(e) {\n return this._addCheck({\n kind: \"uuid\",\n ...i.errorUtil.errToObj(e)\n });\n }\n cuid(e) {\n return this._addCheck({\n kind: \"cuid\",\n ...i.errorUtil.errToObj(e)\n });\n }\n cuid2(e) {\n return this._addCheck({\n kind: \"cuid2\",\n ...i.errorUtil.errToObj(e)\n });\n }\n ulid(e) {\n return this._addCheck({\n kind: \"ulid\",\n ...i.errorUtil.errToObj(e)\n });\n }\n ip(e) {\n return this._addCheck({\n kind: \"ip\",\n ...i.errorUtil.errToObj(e)\n });\n }\n datetime(e) {\n var t;\n return \"string\" == typeof e ? this._addCheck({\n kind: \"datetime\",\n precision: null,\n offset: !1,\n message: e\n }) : this._addCheck({\n kind: \"datetime\",\n precision: void 0 === (null == e ? void 0 : e.precision) ? null : null == e ? void 0 : e.precision,\n offset: null !== (t = null == e ? void 0 : e.offset) && void 0 !== t && t,\n ...i.errorUtil.errToObj(null == e ? void 0 : e.message)\n });\n }\n regex(e, t) {\n return this._addCheck({\n kind: \"regex\",\n regex: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n includes(e, t) {\n return this._addCheck({\n kind: \"includes\",\n value: e,\n position: null == t ? void 0 : t.position,\n ...i.errorUtil.errToObj(null == t ? void 0 : t.message)\n });\n }\n startsWith(e, t) {\n return this._addCheck({\n kind: \"startsWith\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n endsWith(e, t) {\n return this._addCheck({\n kind: \"endsWith\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n min(e, t) {\n return this._addCheck({\n kind: \"min\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n max(e, t) {\n return this._addCheck({\n kind: \"max\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n length(e, t) {\n return this._addCheck({\n kind: \"length\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n nonempty(e) {\n return this.min(1, i.errorUtil.errToObj(e));\n }\n trim() {\n return new b({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: \"trim\"\n }\n ]\n });\n }\n toLowerCase() {\n return new b({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: \"toLowerCase\"\n }\n ]\n });\n }\n toUpperCase() {\n return new b({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: \"toUpperCase\"\n }\n ]\n });\n }\n get isDatetime() {\n return !!this._def.checks.find((e)=>\"datetime\" === e.kind);\n }\n get isEmail() {\n return !!this._def.checks.find((e)=>\"email\" === e.kind);\n }\n get isURL() {\n return !!this._def.checks.find((e)=>\"url\" === e.kind);\n }\n get isEmoji() {\n return !!this._def.checks.find((e)=>\"emoji\" === e.kind);\n }\n get isUUID() {\n return !!this._def.checks.find((e)=>\"uuid\" === e.kind);\n }\n get isCUID() {\n return !!this._def.checks.find((e)=>\"cuid\" === e.kind);\n }\n get isCUID2() {\n return !!this._def.checks.find((e)=>\"cuid2\" === e.kind);\n }\n get isULID() {\n return !!this._def.checks.find((e)=>\"ulid\" === e.kind);\n }\n get isIP() {\n return !!this._def.checks.find((e)=>\"ip\" === e.kind);\n }\n get minLength() {\n let e = null;\n for (const t of this._def.checks)\"min\" === t.kind && (null === e || t.value > e) && (e = t.value);\n return e;\n }\n get maxLength() {\n let e = null;\n for (const t of this._def.checks)\"max\" === t.kind && (null === e || t.value < e) && (e = t.value);\n return e;\n }\n }\n function x(e, t) {\n const s = (e.toString().split(\".\")[1] || \"\").length, r = (t.toString().split(\".\")[1] || \"\").length, i = s > r ? s : r;\n return parseInt(e.toFixed(i).replace(\".\", \"\")) % parseInt(t.toFixed(i).replace(\".\", \"\")) / Math.pow(10, i);\n }\n t.ZodString = b, b.create = (e)=>{\n var t;\n return new b({\n checks: [],\n typeName: oe.ZodString,\n coerce: null !== (t = null == e ? void 0 : e.coerce) && void 0 !== t && t,\n ...u(e)\n });\n };\n class I extends c {\n constructor(){\n super(...arguments), this.min = this.gte, this.max = this.lte, this.step = this.multipleOf;\n }\n _parse(e) {\n if (this._def.coerce && (e.data = Number(e.data)), this._getType(e) !== n.ZodParsedType.number) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.number,\n received: t.parsedType\n }), a.INVALID;\n }\n let t;\n const s = new a.ParseStatus;\n for (const r of this._def.checks)\"int\" === r.kind ? n.util.isInteger(e.data) || (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: \"integer\",\n received: \"float\",\n message: r.message\n }), s.dirty()) : \"min\" === r.kind ? (r.inclusive ? e.data < r.value : e.data <= r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_small,\n minimum: r.value,\n type: \"number\",\n inclusive: r.inclusive,\n exact: !1,\n message: r.message\n }), s.dirty()) : \"max\" === r.kind ? (r.inclusive ? e.data > r.value : e.data >= r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_big,\n maximum: r.value,\n type: \"number\",\n inclusive: r.inclusive,\n exact: !1,\n message: r.message\n }), s.dirty()) : \"multipleOf\" === r.kind ? 0 !== x(e.data, r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.not_multiple_of,\n multipleOf: r.value,\n message: r.message\n }), s.dirty()) : \"finite\" === r.kind ? Number.isFinite(e.data) || (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.not_finite,\n message: r.message\n }), s.dirty()) : n.util.assertNever(r);\n return {\n status: s.value,\n value: e.data\n };\n }\n gte(e, t) {\n return this.setLimit(\"min\", e, !0, i.errorUtil.toString(t));\n }\n gt(e, t) {\n return this.setLimit(\"min\", e, !1, i.errorUtil.toString(t));\n }\n lte(e, t) {\n return this.setLimit(\"max\", e, !0, i.errorUtil.toString(t));\n }\n lt(e, t) {\n return this.setLimit(\"max\", e, !1, i.errorUtil.toString(t));\n }\n setLimit(e, t, s, r) {\n return new I({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: e,\n value: t,\n inclusive: s,\n message: i.errorUtil.toString(r)\n }\n ]\n });\n }\n _addCheck(e) {\n return new I({\n ...this._def,\n checks: [\n ...this._def.checks,\n e\n ]\n });\n }\n int(e) {\n return this._addCheck({\n kind: \"int\",\n message: i.errorUtil.toString(e)\n });\n }\n positive(e) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: !1,\n message: i.errorUtil.toString(e)\n });\n }\n negative(e) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: !1,\n message: i.errorUtil.toString(e)\n });\n }\n nonpositive(e) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: !0,\n message: i.errorUtil.toString(e)\n });\n }\n nonnegative(e) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: !0,\n message: i.errorUtil.toString(e)\n });\n }\n multipleOf(e, t) {\n return this._addCheck({\n kind: \"multipleOf\",\n value: e,\n message: i.errorUtil.toString(t)\n });\n }\n finite(e) {\n return this._addCheck({\n kind: \"finite\",\n message: i.errorUtil.toString(e)\n });\n }\n safe(e) {\n return this._addCheck({\n kind: \"min\",\n inclusive: !0,\n value: Number.MIN_SAFE_INTEGER,\n message: i.errorUtil.toString(e)\n })._addCheck({\n kind: \"max\",\n inclusive: !0,\n value: Number.MAX_SAFE_INTEGER,\n message: i.errorUtil.toString(e)\n });\n }\n get minValue() {\n let e = null;\n for (const t of this._def.checks)\"min\" === t.kind && (null === e || t.value > e) && (e = t.value);\n return e;\n }\n get maxValue() {\n let e = null;\n for (const t of this._def.checks)\"max\" === t.kind && (null === e || t.value < e) && (e = t.value);\n return e;\n }\n get isInt() {\n return !!this._def.checks.find((e)=>\"int\" === e.kind || \"multipleOf\" === e.kind && n.util.isInteger(e.value));\n }\n get isFinite() {\n let e = null, t = null;\n for (const s of this._def.checks){\n if (\"finite\" === s.kind || \"int\" === s.kind || \"multipleOf\" === s.kind) return !0;\n \"min\" === s.kind ? (null === t || s.value > t) && (t = s.value) : \"max\" === s.kind && (null === e || s.value < e) && (e = s.value);\n }\n return Number.isFinite(t) && Number.isFinite(e);\n }\n }\n t.ZodNumber = I, I.create = (e)=>new I({\n checks: [],\n typeName: oe.ZodNumber,\n coerce: (null == e ? void 0 : e.coerce) || !1,\n ...u(e)\n });\n class Z extends c {\n constructor(){\n super(...arguments), this.min = this.gte, this.max = this.lte;\n }\n _parse(e) {\n if (this._def.coerce && (e.data = BigInt(e.data)), this._getType(e) !== n.ZodParsedType.bigint) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.bigint,\n received: t.parsedType\n }), a.INVALID;\n }\n let t;\n const s = new a.ParseStatus;\n for (const r of this._def.checks)\"min\" === r.kind ? (r.inclusive ? e.data < r.value : e.data <= r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_small,\n type: \"bigint\",\n minimum: r.value,\n inclusive: r.inclusive,\n message: r.message\n }), s.dirty()) : \"max\" === r.kind ? (r.inclusive ? e.data > r.value : e.data >= r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_big,\n type: \"bigint\",\n maximum: r.value,\n inclusive: r.inclusive,\n message: r.message\n }), s.dirty()) : \"multipleOf\" === r.kind ? e.data % r.value !== BigInt(0) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.not_multiple_of,\n multipleOf: r.value,\n message: r.message\n }), s.dirty()) : n.util.assertNever(r);\n return {\n status: s.value,\n value: e.data\n };\n }\n gte(e, t) {\n return this.setLimit(\"min\", e, !0, i.errorUtil.toString(t));\n }\n gt(e, t) {\n return this.setLimit(\"min\", e, !1, i.errorUtil.toString(t));\n }\n lte(e, t) {\n return this.setLimit(\"max\", e, !0, i.errorUtil.toString(t));\n }\n lt(e, t) {\n return this.setLimit(\"max\", e, !1, i.errorUtil.toString(t));\n }\n setLimit(e, t, s, r) {\n return new Z({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: e,\n value: t,\n inclusive: s,\n message: i.errorUtil.toString(r)\n }\n ]\n });\n }\n _addCheck(e) {\n return new Z({\n ...this._def,\n checks: [\n ...this._def.checks,\n e\n ]\n });\n }\n positive(e) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: !1,\n message: i.errorUtil.toString(e)\n });\n }\n negative(e) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: !1,\n message: i.errorUtil.toString(e)\n });\n }\n nonpositive(e) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: !0,\n message: i.errorUtil.toString(e)\n });\n }\n nonnegative(e) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: !0,\n message: i.errorUtil.toString(e)\n });\n }\n multipleOf(e, t) {\n return this._addCheck({\n kind: \"multipleOf\",\n value: e,\n message: i.errorUtil.toString(t)\n });\n }\n get minValue() {\n let e = null;\n for (const t of this._def.checks)\"min\" === t.kind && (null === e || t.value > e) && (e = t.value);\n return e;\n }\n get maxValue() {\n let e = null;\n for (const t of this._def.checks)\"max\" === t.kind && (null === e || t.value < e) && (e = t.value);\n return e;\n }\n }\n t.ZodBigInt = Z, Z.create = (e)=>{\n var t;\n return new Z({\n checks: [],\n typeName: oe.ZodBigInt,\n coerce: null !== (t = null == e ? void 0 : e.coerce) && void 0 !== t && t,\n ...u(e)\n });\n };\n class T extends c {\n _parse(e) {\n if (this._def.coerce && (e.data = Boolean(e.data)), this._getType(e) !== n.ZodParsedType.boolean) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.boolean,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodBoolean = T, T.create = (e)=>new T({\n typeName: oe.ZodBoolean,\n coerce: (null == e ? void 0 : e.coerce) || !1,\n ...u(e)\n });\n class k extends c {\n _parse(e) {\n if (this._def.coerce && (e.data = new Date(e.data)), this._getType(e) !== n.ZodParsedType.date) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.date,\n received: t.parsedType\n }), a.INVALID;\n }\n if (isNaN(e.data.getTime())) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_date\n }), a.INVALID;\n }\n const t = new a.ParseStatus;\n let s;\n for (const r of this._def.checks)\"min\" === r.kind ? e.data.getTime() < r.value && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n message: r.message,\n inclusive: !0,\n exact: !1,\n minimum: r.value,\n type: \"date\"\n }), t.dirty()) : \"max\" === r.kind ? e.data.getTime() > r.value && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n message: r.message,\n inclusive: !0,\n exact: !1,\n maximum: r.value,\n type: \"date\"\n }), t.dirty()) : n.util.assertNever(r);\n return {\n status: t.value,\n value: new Date(e.data.getTime())\n };\n }\n _addCheck(e) {\n return new k({\n ...this._def,\n checks: [\n ...this._def.checks,\n e\n ]\n });\n }\n min(e, t) {\n return this._addCheck({\n kind: \"min\",\n value: e.getTime(),\n message: i.errorUtil.toString(t)\n });\n }\n max(e, t) {\n return this._addCheck({\n kind: \"max\",\n value: e.getTime(),\n message: i.errorUtil.toString(t)\n });\n }\n get minDate() {\n let e = null;\n for (const t of this._def.checks)\"min\" === t.kind && (null === e || t.value > e) && (e = t.value);\n return null != e ? new Date(e) : null;\n }\n get maxDate() {\n let e = null;\n for (const t of this._def.checks)\"max\" === t.kind && (null === e || t.value < e) && (e = t.value);\n return null != e ? new Date(e) : null;\n }\n }\n t.ZodDate = k, k.create = (e)=>new k({\n checks: [],\n coerce: (null == e ? void 0 : e.coerce) || !1,\n typeName: oe.ZodDate,\n ...u(e)\n });\n class w extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.symbol) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.symbol,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodSymbol = w, w.create = (e)=>new w({\n typeName: oe.ZodSymbol,\n ...u(e)\n });\n class C extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.undefined) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.undefined,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodUndefined = C, C.create = (e)=>new C({\n typeName: oe.ZodUndefined,\n ...u(e)\n });\n class z extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.null) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.null,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodNull = z, z.create = (e)=>new z({\n typeName: oe.ZodNull,\n ...u(e)\n });\n class L extends c {\n constructor(){\n super(...arguments), this._any = !0;\n }\n _parse(e) {\n return (0, a.OK)(e.data);\n }\n }\n t.ZodAny = L, L.create = (e)=>new L({\n typeName: oe.ZodAny,\n ...u(e)\n });\n class P extends c {\n constructor(){\n super(...arguments), this._unknown = !0;\n }\n _parse(e) {\n return (0, a.OK)(e.data);\n }\n }\n t.ZodUnknown = P, P.create = (e)=>new P({\n typeName: oe.ZodUnknown,\n ...u(e)\n });\n class O extends c {\n _parse(e) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.never,\n received: t.parsedType\n }), a.INVALID;\n }\n }\n t.ZodNever = O, O.create = (e)=>new O({\n typeName: oe.ZodNever,\n ...u(e)\n });\n class j extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.undefined) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.void,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodVoid = j, j.create = (e)=>new j({\n typeName: oe.ZodVoid,\n ...u(e)\n });\n class E extends c {\n _parse(e) {\n const { ctx: t, status: s } = this._processInputParams(e), r = this._def;\n if (t.parsedType !== n.ZodParsedType.array) return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.array,\n received: t.parsedType\n }), a.INVALID;\n if (null !== r.exactLength) {\n const e = t.data.length > r.exactLength.value, i = t.data.length < r.exactLength.value;\n (e || i) && ((0, a.addIssueToContext)(t, {\n code: e ? o.ZodIssueCode.too_big : o.ZodIssueCode.too_small,\n minimum: i ? r.exactLength.value : void 0,\n maximum: e ? r.exactLength.value : void 0,\n type: \"array\",\n inclusive: !0,\n exact: !0,\n message: r.exactLength.message\n }), s.dirty());\n }\n if (null !== r.minLength && t.data.length < r.minLength.value && ((0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_small,\n minimum: r.minLength.value,\n type: \"array\",\n inclusive: !0,\n exact: !1,\n message: r.minLength.message\n }), s.dirty()), null !== r.maxLength && t.data.length > r.maxLength.value && ((0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_big,\n maximum: r.maxLength.value,\n type: \"array\",\n inclusive: !0,\n exact: !1,\n message: r.maxLength.message\n }), s.dirty()), t.common.async) return Promise.all([\n ...t.data\n ].map((e, s)=>r.type._parseAsync(new d(t, e, t.path, s)))).then((e)=>a.ParseStatus.mergeArray(s, e));\n const i = [\n ...t.data\n ].map((e, s)=>r.type._parseSync(new d(t, e, t.path, s)));\n return a.ParseStatus.mergeArray(s, i);\n }\n get element() {\n return this._def.type;\n }\n min(e, t) {\n return new E({\n ...this._def,\n minLength: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n max(e, t) {\n return new E({\n ...this._def,\n maxLength: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n length(e, t) {\n return new E({\n ...this._def,\n exactLength: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n nonempty(e) {\n return this.min(1, e);\n }\n }\n function N(e) {\n if (e instanceof S) {\n const t = {};\n for(const s in e.shape){\n const r = e.shape[s];\n t[s] = Q.create(N(r));\n }\n return new S({\n ...e._def,\n shape: ()=>t\n });\n }\n return e instanceof E ? new E({\n ...e._def,\n type: N(e.element)\n }) : e instanceof Q ? Q.create(N(e.unwrap())) : e instanceof ee ? ee.create(N(e.unwrap())) : e instanceof V ? V.create(e.items.map((e)=>N(e))) : e;\n }\n t.ZodArray = E, E.create = (e, t)=>new E({\n type: e,\n minLength: null,\n maxLength: null,\n exactLength: null,\n typeName: oe.ZodArray,\n ...u(t)\n });\n class S extends c {\n constructor(){\n super(...arguments), this._cached = null, this.nonstrict = this.passthrough, this.augment = this.extend;\n }\n _getCached() {\n if (null !== this._cached) return this._cached;\n const e = this._def.shape(), t = n.util.objectKeys(e);\n return this._cached = {\n shape: e,\n keys: t\n };\n }\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.object) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.object,\n received: t.parsedType\n }), a.INVALID;\n }\n const { status: t, ctx: s } = this._processInputParams(e), { shape: r, keys: i } = this._getCached(), l = [];\n if (!(this._def.catchall instanceof O && \"strip\" === this._def.unknownKeys)) for(const e in s.data)i.includes(e) || l.push(e);\n const u = [];\n for (const e of i){\n const t = r[e], i = s.data[e];\n u.push({\n key: {\n status: \"valid\",\n value: e\n },\n value: t._parse(new d(s, i, s.path, e)),\n alwaysSet: e in s.data\n });\n }\n if (this._def.catchall instanceof O) {\n const e = this._def.unknownKeys;\n if (\"passthrough\" === e) for (const e of l)u.push({\n key: {\n status: \"valid\",\n value: e\n },\n value: {\n status: \"valid\",\n value: s.data[e]\n }\n });\n else if (\"strict\" === e) l.length > 0 && ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.unrecognized_keys,\n keys: l\n }), t.dirty());\n else if (\"strip\" !== e) throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\");\n } else {\n const e = this._def.catchall;\n for (const t of l){\n const r = s.data[t];\n u.push({\n key: {\n status: \"valid\",\n value: t\n },\n value: e._parse(new d(s, r, s.path, t)),\n alwaysSet: t in s.data\n });\n }\n }\n return s.common.async ? Promise.resolve().then(async ()=>{\n const e = [];\n for (const t of u){\n const s = await t.key;\n e.push({\n key: s,\n value: await t.value,\n alwaysSet: t.alwaysSet\n });\n }\n return e;\n }).then((e)=>a.ParseStatus.mergeObjectSync(t, e)) : a.ParseStatus.mergeObjectSync(t, u);\n }\n get shape() {\n return this._def.shape();\n }\n strict(e) {\n return i.errorUtil.errToObj, new S({\n ...this._def,\n unknownKeys: \"strict\",\n ...void 0 !== e ? {\n errorMap: (t, s)=>{\n var r, a, n, o;\n const d = null !== (n = null === (a = (r = this._def).errorMap) || void 0 === a ? void 0 : a.call(r, t, s).message) && void 0 !== n ? n : s.defaultError;\n return \"unrecognized_keys\" === t.code ? {\n message: null !== (o = i.errorUtil.errToObj(e).message) && void 0 !== o ? o : d\n } : {\n message: d\n };\n }\n } : {}\n });\n }\n strip() {\n return new S({\n ...this._def,\n unknownKeys: \"strip\"\n });\n }\n passthrough() {\n return new S({\n ...this._def,\n unknownKeys: \"passthrough\"\n });\n }\n extend(e) {\n return new S({\n ...this._def,\n shape: ()=>({\n ...this._def.shape(),\n ...e\n })\n });\n }\n merge(e) {\n return new S({\n unknownKeys: e._def.unknownKeys,\n catchall: e._def.catchall,\n shape: ()=>({\n ...this._def.shape(),\n ...e._def.shape()\n }),\n typeName: oe.ZodObject\n });\n }\n setKey(e, t) {\n return this.augment({\n [e]: t\n });\n }\n catchall(e) {\n return new S({\n ...this._def,\n catchall: e\n });\n }\n pick(e) {\n const t = {};\n return n.util.objectKeys(e).forEach((s)=>{\n e[s] && this.shape[s] && (t[s] = this.shape[s]);\n }), new S({\n ...this._def,\n shape: ()=>t\n });\n }\n omit(e) {\n const t = {};\n return n.util.objectKeys(this.shape).forEach((s)=>{\n e[s] || (t[s] = this.shape[s]);\n }), new S({\n ...this._def,\n shape: ()=>t\n });\n }\n deepPartial() {\n return N(this);\n }\n partial(e) {\n const t = {};\n return n.util.objectKeys(this.shape).forEach((s)=>{\n const r = this.shape[s];\n e && !e[s] ? t[s] = r : t[s] = r.optional();\n }), new S({\n ...this._def,\n shape: ()=>t\n });\n }\n required(e) {\n const t = {};\n return n.util.objectKeys(this.shape).forEach((s)=>{\n if (e && !e[s]) t[s] = this.shape[s];\n else {\n let e = this.shape[s];\n for(; e instanceof Q;)e = e._def.innerType;\n t[s] = e;\n }\n }), new S({\n ...this._def,\n shape: ()=>t\n });\n }\n keyof() {\n return Y(n.util.objectKeys(this.shape));\n }\n }\n t.ZodObject = S, S.create = (e, t)=>new S({\n shape: ()=>e,\n unknownKeys: \"strip\",\n catchall: O.create(),\n typeName: oe.ZodObject,\n ...u(t)\n }), S.strictCreate = (e, t)=>new S({\n shape: ()=>e,\n unknownKeys: \"strict\",\n catchall: O.create(),\n typeName: oe.ZodObject,\n ...u(t)\n }), S.lazycreate = (e, t)=>new S({\n shape: e,\n unknownKeys: \"strip\",\n catchall: O.create(),\n typeName: oe.ZodObject,\n ...u(t)\n });\n class A extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e), s = this._def.options;\n if (t.common.async) return Promise.all(s.map(async (e)=>{\n const s = {\n ...t,\n common: {\n ...t.common,\n issues: []\n },\n parent: null\n };\n return {\n result: await e._parseAsync({\n data: t.data,\n path: t.path,\n parent: s\n }),\n ctx: s\n };\n })).then(function(e) {\n for (const t of e)if (\"valid\" === t.result.status) return t.result;\n for (const s of e)if (\"dirty\" === s.result.status) return t.common.issues.push(...s.ctx.common.issues), s.result;\n const s = e.map((e)=>new o.ZodError(e.ctx.common.issues));\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_union,\n unionErrors: s\n }), a.INVALID;\n });\n {\n let e;\n const r = [];\n for (const i of s){\n const s = {\n ...t,\n common: {\n ...t.common,\n issues: []\n },\n parent: null\n }, a = i._parseSync({\n data: t.data,\n path: t.path,\n parent: s\n });\n if (\"valid\" === a.status) return a;\n \"dirty\" !== a.status || e || (e = {\n result: a,\n ctx: s\n }), s.common.issues.length && r.push(s.common.issues);\n }\n if (e) return t.common.issues.push(...e.ctx.common.issues), e.result;\n const i = r.map((e)=>new o.ZodError(e));\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_union,\n unionErrors: i\n }), a.INVALID;\n }\n }\n get options() {\n return this._def.options;\n }\n }\n t.ZodUnion = A, A.create = (e, t)=>new A({\n options: e,\n typeName: oe.ZodUnion,\n ...u(t)\n });\n const M = (e)=>e instanceof G ? M(e.schema) : e instanceof J ? M(e.innerType()) : e instanceof W ? [\n e.value\n ] : e instanceof H ? e.options : e instanceof q ? Object.keys(e.enum) : e instanceof te ? M(e._def.innerType) : e instanceof C ? [\n void 0\n ] : e instanceof z ? [\n null\n ] : null;\n class D extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n if (t.parsedType !== n.ZodParsedType.object) return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.object,\n received: t.parsedType\n }), a.INVALID;\n const s = this.discriminator, r = t.data[s], i = this.optionsMap.get(r);\n return i ? t.common.async ? i._parseAsync({\n data: t.data,\n path: t.path,\n parent: t\n }) : i._parseSync({\n data: t.data,\n path: t.path,\n parent: t\n }) : ((0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_union_discriminator,\n options: Array.from(this.optionsMap.keys()),\n path: [\n s\n ]\n }), a.INVALID);\n }\n get discriminator() {\n return this._def.discriminator;\n }\n get options() {\n return this._def.options;\n }\n get optionsMap() {\n return this._def.optionsMap;\n }\n static create(e, t, s) {\n const r = new Map;\n for (const s of t){\n const t = M(s.shape[e]);\n if (!t) throw new Error(`A discriminator value for key \\`${e}\\` could not be extracted from all schema options`);\n for (const i of t){\n if (r.has(i)) throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(i)}`);\n r.set(i, s);\n }\n }\n return new D({\n typeName: oe.ZodDiscriminatedUnion,\n discriminator: e,\n options: t,\n optionsMap: r,\n ...u(s)\n });\n }\n }\n function U(e, t) {\n const s = (0, n.getParsedType)(e), r = (0, n.getParsedType)(t);\n if (e === t) return {\n valid: !0,\n data: e\n };\n if (s === n.ZodParsedType.object && r === n.ZodParsedType.object) {\n const s = n.util.objectKeys(t), r = n.util.objectKeys(e).filter((e)=>-1 !== s.indexOf(e)), i = {\n ...e,\n ...t\n };\n for (const s of r){\n const r = U(e[s], t[s]);\n if (!r.valid) return {\n valid: !1\n };\n i[s] = r.data;\n }\n return {\n valid: !0,\n data: i\n };\n }\n if (s === n.ZodParsedType.array && r === n.ZodParsedType.array) {\n if (e.length !== t.length) return {\n valid: !1\n };\n const s = [];\n for(let r = 0; r < e.length; r++){\n const i = U(e[r], t[r]);\n if (!i.valid) return {\n valid: !1\n };\n s.push(i.data);\n }\n return {\n valid: !0,\n data: s\n };\n }\n return s === n.ZodParsedType.date && r === n.ZodParsedType.date && +e == +t ? {\n valid: !0,\n data: e\n } : {\n valid: !1\n };\n }\n t.ZodDiscriminatedUnion = D;\n class R extends c {\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e), r = (e, r)=>{\n if ((0, a.isAborted)(e) || (0, a.isAborted)(r)) return a.INVALID;\n const i = U(e.value, r.value);\n return i.valid ? (((0, a.isDirty)(e) || (0, a.isDirty)(r)) && t.dirty(), {\n status: t.value,\n value: i.data\n }) : ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_intersection_types\n }), a.INVALID);\n };\n return s.common.async ? Promise.all([\n this._def.left._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n }),\n this._def.right._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n })\n ]).then(([e, t])=>r(e, t)) : r(this._def.left._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n }), this._def.right._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n }));\n }\n }\n t.ZodIntersection = R, R.create = (e, t, s)=>new R({\n left: e,\n right: t,\n typeName: oe.ZodIntersection,\n ...u(s)\n });\n class V extends c {\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.parsedType !== n.ZodParsedType.array) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.array,\n received: s.parsedType\n }), a.INVALID;\n if (s.data.length < this._def.items.length) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n minimum: this._def.items.length,\n inclusive: !0,\n exact: !1,\n type: \"array\"\n }), a.INVALID;\n !this._def.rest && s.data.length > this._def.items.length && ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n maximum: this._def.items.length,\n inclusive: !0,\n exact: !1,\n type: \"array\"\n }), t.dirty());\n const r = [\n ...s.data\n ].map((e, t)=>{\n const r = this._def.items[t] || this._def.rest;\n return r ? r._parse(new d(s, e, s.path, t)) : null;\n }).filter((e)=>!!e);\n return s.common.async ? Promise.all(r).then((e)=>a.ParseStatus.mergeArray(t, e)) : a.ParseStatus.mergeArray(t, r);\n }\n get items() {\n return this._def.items;\n }\n rest(e) {\n return new V({\n ...this._def,\n rest: e\n });\n }\n }\n t.ZodTuple = V, V.create = (e, t)=>{\n if (!Array.isArray(e)) throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");\n return new V({\n items: e,\n typeName: oe.ZodTuple,\n rest: null,\n ...u(t)\n });\n };\n class $ extends c {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.parsedType !== n.ZodParsedType.object) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.object,\n received: s.parsedType\n }), a.INVALID;\n const r = [], i = this._def.keyType, l = this._def.valueType;\n for(const e in s.data)r.push({\n key: i._parse(new d(s, e, s.path, e)),\n value: l._parse(new d(s, s.data[e], s.path, e))\n });\n return s.common.async ? a.ParseStatus.mergeObjectAsync(t, r) : a.ParseStatus.mergeObjectSync(t, r);\n }\n get element() {\n return this._def.valueType;\n }\n static create(e, t, s) {\n return new $(t instanceof c ? {\n keyType: e,\n valueType: t,\n typeName: oe.ZodRecord,\n ...u(s)\n } : {\n keyType: b.create(),\n valueType: e,\n typeName: oe.ZodRecord,\n ...u(t)\n });\n }\n }\n t.ZodRecord = $;\n class B extends c {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.parsedType !== n.ZodParsedType.map) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.map,\n received: s.parsedType\n }), a.INVALID;\n const r = this._def.keyType, i = this._def.valueType, l = [\n ...s.data.entries()\n ].map(([e, t], a)=>({\n key: r._parse(new d(s, e, s.path, [\n a,\n \"key\"\n ])),\n value: i._parse(new d(s, t, s.path, [\n a,\n \"value\"\n ]))\n }));\n if (s.common.async) {\n const e = new Map;\n return Promise.resolve().then(async ()=>{\n for (const s of l){\n const r = await s.key, i = await s.value;\n if (\"aborted\" === r.status || \"aborted\" === i.status) return a.INVALID;\n \"dirty\" !== r.status && \"dirty\" !== i.status || t.dirty(), e.set(r.value, i.value);\n }\n return {\n status: t.value,\n value: e\n };\n });\n }\n {\n const e = new Map;\n for (const s of l){\n const r = s.key, i = s.value;\n if (\"aborted\" === r.status || \"aborted\" === i.status) return a.INVALID;\n \"dirty\" !== r.status && \"dirty\" !== i.status || t.dirty(), e.set(r.value, i.value);\n }\n return {\n status: t.value,\n value: e\n };\n }\n }\n }\n t.ZodMap = B, B.create = (e, t, s)=>new B({\n valueType: t,\n keyType: e,\n typeName: oe.ZodMap,\n ...u(s)\n });\n class F extends c {\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.parsedType !== n.ZodParsedType.set) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.set,\n received: s.parsedType\n }), a.INVALID;\n const r = this._def;\n null !== r.minSize && s.data.size < r.minSize.value && ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n minimum: r.minSize.value,\n type: \"set\",\n inclusive: !0,\n exact: !1,\n message: r.minSize.message\n }), t.dirty()), null !== r.maxSize && s.data.size > r.maxSize.value && ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n maximum: r.maxSize.value,\n type: \"set\",\n inclusive: !0,\n exact: !1,\n message: r.maxSize.message\n }), t.dirty());\n const i = this._def.valueType;\n function l(e) {\n const s = new Set;\n for (const r of e){\n if (\"aborted\" === r.status) return a.INVALID;\n \"dirty\" === r.status && t.dirty(), s.add(r.value);\n }\n return {\n status: t.value,\n value: s\n };\n }\n const u = [\n ...s.data.values()\n ].map((e, t)=>i._parse(new d(s, e, s.path, t)));\n return s.common.async ? Promise.all(u).then((e)=>l(e)) : l(u);\n }\n min(e, t) {\n return new F({\n ...this._def,\n minSize: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n max(e, t) {\n return new F({\n ...this._def,\n maxSize: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n size(e, t) {\n return this.min(e, t).max(e, t);\n }\n nonempty(e) {\n return this.min(1, e);\n }\n }\n t.ZodSet = F, F.create = (e, t)=>new F({\n valueType: e,\n minSize: null,\n maxSize: null,\n typeName: oe.ZodSet,\n ...u(t)\n });\n class K extends c {\n constructor(){\n super(...arguments), this.validate = this.implement;\n }\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n if (t.parsedType !== n.ZodParsedType.function) return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.function,\n received: t.parsedType\n }), a.INVALID;\n function s(e, s) {\n return (0, a.makeIssue)({\n data: e,\n path: t.path,\n errorMaps: [\n t.common.contextualErrorMap,\n t.schemaErrorMap,\n (0, r.getErrorMap)(),\n r.defaultErrorMap\n ].filter((e)=>!!e),\n issueData: {\n code: o.ZodIssueCode.invalid_arguments,\n argumentsError: s\n }\n });\n }\n function i(e, s) {\n return (0, a.makeIssue)({\n data: e,\n path: t.path,\n errorMaps: [\n t.common.contextualErrorMap,\n t.schemaErrorMap,\n (0, r.getErrorMap)(),\n r.defaultErrorMap\n ].filter((e)=>!!e),\n issueData: {\n code: o.ZodIssueCode.invalid_return_type,\n returnTypeError: s\n }\n });\n }\n const d = {\n errorMap: t.common.contextualErrorMap\n }, l = t.data;\n if (this._def.returns instanceof X) {\n const e = this;\n return (0, a.OK)(async function(...t) {\n const r = new o.ZodError([]), a = await e._def.args.parseAsync(t, d).catch((e)=>{\n throw r.addIssue(s(t, e)), r;\n }), n = await Reflect.apply(l, this, a);\n return await e._def.returns._def.type.parseAsync(n, d).catch((e)=>{\n throw r.addIssue(i(n, e)), r;\n });\n });\n }\n {\n const e = this;\n return (0, a.OK)(function(...t) {\n const r = e._def.args.safeParse(t, d);\n if (!r.success) throw new o.ZodError([\n s(t, r.error)\n ]);\n const a = Reflect.apply(l, this, r.data), n = e._def.returns.safeParse(a, d);\n if (!n.success) throw new o.ZodError([\n i(a, n.error)\n ]);\n return n.data;\n });\n }\n }\n parameters() {\n return this._def.args;\n }\n returnType() {\n return this._def.returns;\n }\n args(...e) {\n return new K({\n ...this._def,\n args: V.create(e).rest(P.create())\n });\n }\n returns(e) {\n return new K({\n ...this._def,\n returns: e\n });\n }\n implement(e) {\n return this.parse(e);\n }\n strictImplement(e) {\n return this.parse(e);\n }\n static create(e, t, s) {\n return new K({\n args: e || V.create([]).rest(P.create()),\n returns: t || P.create(),\n typeName: oe.ZodFunction,\n ...u(s)\n });\n }\n }\n t.ZodFunction = K;\n class G extends c {\n get schema() {\n return this._def.getter();\n }\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n return this._def.getter()._parse({\n data: t.data,\n path: t.path,\n parent: t\n });\n }\n }\n t.ZodLazy = G, G.create = (e, t)=>new G({\n getter: e,\n typeName: oe.ZodLazy,\n ...u(t)\n });\n class W extends c {\n _parse(e) {\n if (e.data !== this._def.value) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n received: t.data,\n code: o.ZodIssueCode.invalid_literal,\n expected: this._def.value\n }), a.INVALID;\n }\n return {\n status: \"valid\",\n value: e.data\n };\n }\n get value() {\n return this._def.value;\n }\n }\n function Y(e, t) {\n return new H({\n values: e,\n typeName: oe.ZodEnum,\n ...u(t)\n });\n }\n t.ZodLiteral = W, W.create = (e, t)=>new W({\n value: e,\n typeName: oe.ZodLiteral,\n ...u(t)\n });\n class H extends c {\n _parse(e) {\n if (\"string\" != typeof e.data) {\n const t = this._getOrReturnCtx(e), s = this._def.values;\n return (0, a.addIssueToContext)(t, {\n expected: n.util.joinValues(s),\n received: t.parsedType,\n code: o.ZodIssueCode.invalid_type\n }), a.INVALID;\n }\n if (-1 === this._def.values.indexOf(e.data)) {\n const t = this._getOrReturnCtx(e), s = this._def.values;\n return (0, a.addIssueToContext)(t, {\n received: t.data,\n code: o.ZodIssueCode.invalid_enum_value,\n options: s\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n get options() {\n return this._def.values;\n }\n get enum() {\n const e = {};\n for (const t of this._def.values)e[t] = t;\n return e;\n }\n get Values() {\n const e = {};\n for (const t of this._def.values)e[t] = t;\n return e;\n }\n get Enum() {\n const e = {};\n for (const t of this._def.values)e[t] = t;\n return e;\n }\n extract(e) {\n return H.create(e);\n }\n exclude(e) {\n return H.create(this.options.filter((t)=>!e.includes(t)));\n }\n }\n t.ZodEnum = H, H.create = Y;\n class q extends c {\n _parse(e) {\n const t = n.util.getValidEnumValues(this._def.values), s = this._getOrReturnCtx(e);\n if (s.parsedType !== n.ZodParsedType.string && s.parsedType !== n.ZodParsedType.number) {\n const e = n.util.objectValues(t);\n return (0, a.addIssueToContext)(s, {\n expected: n.util.joinValues(e),\n received: s.parsedType,\n code: o.ZodIssueCode.invalid_type\n }), a.INVALID;\n }\n if (-1 === t.indexOf(e.data)) {\n const e = n.util.objectValues(t);\n return (0, a.addIssueToContext)(s, {\n received: s.data,\n code: o.ZodIssueCode.invalid_enum_value,\n options: e\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n get enum() {\n return this._def.values;\n }\n }\n t.ZodNativeEnum = q, q.create = (e, t)=>new q({\n values: e,\n typeName: oe.ZodNativeEnum,\n ...u(t)\n });\n class X extends c {\n unwrap() {\n return this._def.type;\n }\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n if (t.parsedType !== n.ZodParsedType.promise && !1 === t.common.async) return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.promise,\n received: t.parsedType\n }), a.INVALID;\n const s = t.parsedType === n.ZodParsedType.promise ? t.data : Promise.resolve(t.data);\n return (0, a.OK)(s.then((e)=>this._def.type.parseAsync(e, {\n path: t.path,\n errorMap: t.common.contextualErrorMap\n })));\n }\n }\n t.ZodPromise = X, X.create = (e, t)=>new X({\n type: e,\n typeName: oe.ZodPromise,\n ...u(t)\n });\n class J extends c {\n innerType() {\n return this._def.schema;\n }\n sourceType() {\n return this._def.schema._def.typeName === oe.ZodEffects ? this._def.schema.sourceType() : this._def.schema;\n }\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e), r = this._def.effect || null, i = {\n addIssue: (e)=>{\n (0, a.addIssueToContext)(s, e), e.fatal ? t.abort() : t.dirty();\n },\n get path () {\n return s.path;\n }\n };\n if (i.addIssue = i.addIssue.bind(i), \"preprocess\" === r.type) {\n const e = r.transform(s.data, i);\n return s.common.issues.length ? {\n status: \"dirty\",\n value: s.data\n } : s.common.async ? Promise.resolve(e).then((e)=>this._def.schema._parseAsync({\n data: e,\n path: s.path,\n parent: s\n })) : this._def.schema._parseSync({\n data: e,\n path: s.path,\n parent: s\n });\n }\n if (\"refinement\" === r.type) {\n const e = (e)=>{\n const t = r.refinement(e, i);\n if (s.common.async) return Promise.resolve(t);\n if (t instanceof Promise) throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");\n return e;\n };\n if (!1 === s.common.async) {\n const r = this._def.schema._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n });\n return \"aborted\" === r.status ? a.INVALID : (\"dirty\" === r.status && t.dirty(), e(r.value), {\n status: t.value,\n value: r.value\n });\n }\n return this._def.schema._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n }).then((s)=>\"aborted\" === s.status ? a.INVALID : (\"dirty\" === s.status && t.dirty(), e(s.value).then(()=>({\n status: t.value,\n value: s.value\n }))));\n }\n if (\"transform\" === r.type) {\n if (!1 === s.common.async) {\n const e = this._def.schema._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n });\n if (!(0, a.isValid)(e)) return e;\n const n = r.transform(e.value, i);\n if (n instanceof Promise) throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");\n return {\n status: t.value,\n value: n\n };\n }\n return this._def.schema._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n }).then((e)=>(0, a.isValid)(e) ? Promise.resolve(r.transform(e.value, i)).then((e)=>({\n status: t.value,\n value: e\n })) : e);\n }\n n.util.assertNever(r);\n }\n }\n t.ZodEffects = J, t.ZodTransformer = J, J.create = (e, t, s)=>new J({\n schema: e,\n typeName: oe.ZodEffects,\n effect: t,\n ...u(s)\n }), J.createWithPreprocess = (e, t, s)=>new J({\n schema: t,\n effect: {\n type: \"preprocess\",\n transform: e\n },\n typeName: oe.ZodEffects,\n ...u(s)\n });\n class Q extends c {\n _parse(e) {\n return this._getType(e) === n.ZodParsedType.undefined ? (0, a.OK)(void 0) : this._def.innerType._parse(e);\n }\n unwrap() {\n return this._def.innerType;\n }\n }\n t.ZodOptional = Q, Q.create = (e, t)=>new Q({\n innerType: e,\n typeName: oe.ZodOptional,\n ...u(t)\n });\n class ee extends c {\n _parse(e) {\n return this._getType(e) === n.ZodParsedType.null ? (0, a.OK)(null) : this._def.innerType._parse(e);\n }\n unwrap() {\n return this._def.innerType;\n }\n }\n t.ZodNullable = ee, ee.create = (e, t)=>new ee({\n innerType: e,\n typeName: oe.ZodNullable,\n ...u(t)\n });\n class te extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n let s = t.data;\n return t.parsedType === n.ZodParsedType.undefined && (s = this._def.defaultValue()), this._def.innerType._parse({\n data: s,\n path: t.path,\n parent: t\n });\n }\n removeDefault() {\n return this._def.innerType;\n }\n }\n t.ZodDefault = te, te.create = (e, t)=>new te({\n innerType: e,\n typeName: oe.ZodDefault,\n defaultValue: \"function\" == typeof t.default ? t.default : ()=>t.default,\n ...u(t)\n });\n class se extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e), s = {\n ...t,\n common: {\n ...t.common,\n issues: []\n }\n }, r = this._def.innerType._parse({\n data: s.data,\n path: s.path,\n parent: {\n ...s\n }\n });\n return (0, a.isAsync)(r) ? r.then((e)=>({\n status: \"valid\",\n value: \"valid\" === e.status ? e.value : this._def.catchValue({\n get error () {\n return new o.ZodError(s.common.issues);\n },\n input: s.data\n })\n })) : {\n status: \"valid\",\n value: \"valid\" === r.status ? r.value : this._def.catchValue({\n get error () {\n return new o.ZodError(s.common.issues);\n },\n input: s.data\n })\n };\n }\n removeCatch() {\n return this._def.innerType;\n }\n }\n t.ZodCatch = se, se.create = (e, t)=>new se({\n innerType: e,\n typeName: oe.ZodCatch,\n catchValue: \"function\" == typeof t.catch ? t.catch : ()=>t.catch,\n ...u(t)\n });\n class re extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.nan) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.nan,\n received: t.parsedType\n }), a.INVALID;\n }\n return {\n status: \"valid\",\n value: e.data\n };\n }\n }\n t.ZodNaN = re, re.create = (e)=>new re({\n typeName: oe.ZodNaN,\n ...u(e)\n }), t.BRAND = Symbol(\"zod_brand\");\n class ie extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e), s = t.data;\n return this._def.type._parse({\n data: s,\n path: t.path,\n parent: t\n });\n }\n unwrap() {\n return this._def.type;\n }\n }\n t.ZodBranded = ie;\n class ae extends c {\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.common.async) return (async ()=>{\n const e = await this._def.in._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n });\n return \"aborted\" === e.status ? a.INVALID : \"dirty\" === e.status ? (t.dirty(), (0, a.DIRTY)(e.value)) : this._def.out._parseAsync({\n data: e.value,\n path: s.path,\n parent: s\n });\n })();\n {\n const e = this._def.in._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n });\n return \"aborted\" === e.status ? a.INVALID : \"dirty\" === e.status ? (t.dirty(), {\n status: \"dirty\",\n value: e.value\n }) : this._def.out._parseSync({\n data: e.value,\n path: s.path,\n parent: s\n });\n }\n }\n static create(e, t) {\n return new ae({\n in: e,\n out: t,\n typeName: oe.ZodPipeline\n });\n }\n }\n t.ZodPipeline = ae;\n class ne extends c {\n _parse(e) {\n const t = this._def.innerType._parse(e);\n return (0, a.isValid)(t) && (t.value = Object.freeze(t.value)), t;\n }\n }\n var oe;\n t.ZodReadonly = ne, ne.create = (e, t)=>new ne({\n innerType: e,\n typeName: oe.ZodReadonly,\n ...u(t)\n }), t.custom = (e, t = {}, s)=>e ? L.create().superRefine((r, i)=>{\n var a, n;\n if (!e(r)) {\n const e = \"function\" == typeof t ? t(r) : \"string\" == typeof t ? {\n message: t\n } : t, o = null === (n = null !== (a = e.fatal) && void 0 !== a ? a : s) || void 0 === n || n, d = \"string\" == typeof e ? {\n message: e\n } : e;\n i.addIssue({\n code: \"custom\",\n ...d,\n fatal: o\n });\n }\n }) : L.create(), t.late = {\n object: S.lazycreate\n }, function(e) {\n e.ZodString = \"ZodString\", e.ZodNumber = \"ZodNumber\", e.ZodNaN = \"ZodNaN\", e.ZodBigInt = \"ZodBigInt\", e.ZodBoolean = \"ZodBoolean\", e.ZodDate = \"ZodDate\", e.ZodSymbol = \"ZodSymbol\", e.ZodUndefined = \"ZodUndefined\", e.ZodNull = \"ZodNull\", e.ZodAny = \"ZodAny\", e.ZodUnknown = \"ZodUnknown\", e.ZodNever = \"ZodNever\", e.ZodVoid = \"ZodVoid\", e.ZodArray = \"ZodArray\", e.ZodObject = \"ZodObject\", e.ZodUnion = \"ZodUnion\", e.ZodDiscriminatedUnion = \"ZodDiscriminatedUnion\", e.ZodIntersection = \"ZodIntersection\", e.ZodTuple = \"ZodTuple\", e.ZodRecord = \"ZodRecord\", e.ZodMap = \"ZodMap\", e.ZodSet = \"ZodSet\", e.ZodFunction = \"ZodFunction\", e.ZodLazy = \"ZodLazy\", e.ZodLiteral = \"ZodLiteral\", e.ZodEnum = \"ZodEnum\", e.ZodEffects = \"ZodEffects\", e.ZodNativeEnum = \"ZodNativeEnum\", e.ZodOptional = \"ZodOptional\", e.ZodNullable = \"ZodNullable\", e.ZodDefault = \"ZodDefault\", e.ZodCatch = \"ZodCatch\", e.ZodPromise = \"ZodPromise\", e.ZodBranded = \"ZodBranded\", e.ZodPipeline = \"ZodPipeline\", e.ZodReadonly = \"ZodReadonly\";\n }(oe = t.ZodFirstPartyTypeKind || (t.ZodFirstPartyTypeKind = {})), t.instanceof = (e, s = {\n message: `Input not instance of ${e.name}`\n })=>(0, t.custom)((t)=>t instanceof e, s);\n const de = b.create;\n t.string = de;\n const le = I.create;\n t.number = le;\n const ue = re.create;\n t.nan = ue;\n const ce = Z.create;\n t.bigint = ce;\n const pe = T.create;\n t.boolean = pe;\n const he = k.create;\n t.date = he;\n const fe = w.create;\n t.symbol = fe;\n const me = C.create;\n t.undefined = me;\n const ye = z.create;\n t.null = ye;\n const _e = L.create;\n t.any = _e;\n const ve = P.create;\n t.unknown = ve;\n const ge = O.create;\n t.never = ge;\n const be = j.create;\n t.void = be;\n const xe = E.create;\n t.array = xe;\n const Ie = S.create;\n t.object = Ie;\n const Ze = S.strictCreate;\n t.strictObject = Ze;\n const Te = A.create;\n t.union = Te;\n const ke = D.create;\n t.discriminatedUnion = ke;\n const we = R.create;\n t.intersection = we;\n const Ce = V.create;\n t.tuple = Ce;\n const ze = $.create;\n t.record = ze;\n const Le = B.create;\n t.map = Le;\n const Pe = F.create;\n t.set = Pe;\n const Oe = K.create;\n t.function = Oe;\n const je = G.create;\n t.lazy = je;\n const Ee = W.create;\n t.literal = Ee;\n const Ne = H.create;\n t.enum = Ne;\n const Se = q.create;\n t.nativeEnum = Se;\n const Ae = X.create;\n t.promise = Ae;\n const Me = J.create;\n t.effect = Me, t.transformer = Me;\n const De = Q.create;\n t.optional = De;\n const Ue = ee.create;\n t.nullable = Ue;\n const Re = J.createWithPreprocess;\n t.preprocess = Re;\n const Ve = ae.create;\n t.pipeline = Ve, t.ostring = ()=>de().optional(), t.onumber = ()=>le().optional(), t.oboolean = ()=>pe().optional(), t.coerce = {\n string: (e)=>b.create({\n ...e,\n coerce: !0\n }),\n number: (e)=>I.create({\n ...e,\n coerce: !0\n }),\n boolean: (e)=>T.create({\n ...e,\n coerce: !0\n }),\n bigint: (e)=>Z.create({\n ...e,\n coerce: !0\n }),\n date: (e)=>k.create({\n ...e,\n coerce: !0\n })\n }, t.NEVER = a.INVALID;\n },\n 205: (t)=>{\n t.exports = e;\n }\n }, s = {};\n function r(e) {\n var i = s[e];\n if (void 0 !== i) return i.exports;\n var a = s[e] = {\n exports: {}\n };\n return t[e].call(a.exports, a, a.exports, r), a.exports;\n }\n return r.d = (e, t)=>{\n for(var s in t)r.o(t, s) && !r.o(e, s) && Object.defineProperty(e, s, {\n enumerable: !0,\n get: t[s]\n });\n }, r.o = (e, t)=>Object.prototype.hasOwnProperty.call(e, t), r.r = (e)=>{\n \"undefined\" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {\n value: \"Module\"\n }), Object.defineProperty(e, \"__esModule\", {\n value: !0\n });\n }, r(607);\n })());\n\n\nvar $53be842a0003f2fd$exports = {};\n$53be842a0003f2fd$exports = new URL(\"Hero 01.0a89e3b5.png\", import.meta.url).toString();\n\n\nvar $ee38e295ce16494f$exports = {};\n$ee38e295ce16494f$exports = new URL(\"Solaria Demo Update 01.c847244e.png\", import.meta.url).toString();\n\n\nvar $6e5a0b5cd91b5e01$exports = {};\n$6e5a0b5cd91b5e01$exports = new URL(\"Level_0.4121d29c.ldtkl\", import.meta.url).toString();\n\n\nvar $bbaeefda90929bac$exports = {};\n$bbaeefda90929bac$exports = new URL(\"Level_1.0859d067.ldtkl\", import.meta.url).toString();\n\n\nvar $63f629692c824b7c$exports = {};\n$63f629692c824b7c$exports = new URL(\"House.9ff42634.ldtkl\", import.meta.url).toString();\n\n\nvar $2b4fa2e46d897f1a$exports = {};\n$2b4fa2e46d897f1a$exports = new URL(\"top-down.3490dc55.ldtk\", import.meta.url).toString();\n\n\nconst $7c4c300842bd4cf2$export$e9a269813a6315a4 = {\n HeroSpriteSheetPng: new (0, $3MXpL.ImageSource)((0, (/*@__PURE__*/$parcel$interopDefault($53be842a0003f2fd$exports)))),\n LdtkResource: new (0, $f82d5511d53990a3$exports.LdtkResource)((0, (/*@__PURE__*/$parcel$interopDefault($2b4fa2e46d897f1a$exports))), {\n useTilemapCameraStrategy: true,\n useMapBackgroundColor: true,\n // Path map intercepts and redirects to work around parcel's static bundling\n pathMap: [\n {\n path: \"Hero 01.png\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($53be842a0003f2fd$exports)))\n },\n {\n path: \"Level_0.ldtkl\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($6e5a0b5cd91b5e01$exports)))\n },\n {\n path: \"Level_1.ldtkl\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($bbaeefda90929bac$exports)))\n },\n {\n path: \"House.ldtkl\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($63f629692c824b7c$exports)))\n },\n {\n path: \"Solaria Demo Update 01.png\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($ee38e295ce16494f$exports)))\n }\n ]\n })\n};\nconst $7c4c300842bd4cf2$export$f4c5de44377d2946 = new (0, $3MXpL.Loader)();\nfor (let resource of Object.values($7c4c300842bd4cf2$export$e9a269813a6315a4))$7c4c300842bd4cf2$export$f4c5de44377d2946.addResource(resource);\n\n\nconst $9d936a2aecb96285$export$29cd7b75162a9425 = {\n PlayerSpeed: 32,\n PlayerFrameSpeed: 200\n};\n\n\nclass $51d548b0596e1d08$export$2616165974278734 extends $3MXpL.Actor {\n constructor(args){\n super({\n ...args,\n collisionType: $3MXpL.CollisionType.Active\n });\n }\n onInitialize(engine) {\n const playerSpriteSheet = $3MXpL.SpriteSheet.fromImageSource({\n image: (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).HeroSpriteSheetPng,\n grid: {\n spriteWidth: 16,\n spriteHeight: 16,\n rows: 8,\n columns: 8\n }\n });\n const leftIdle = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 1),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 1),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 1),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 1),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"left-idle\", leftIdle);\n const rightIdle = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 2),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 2),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 2),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 2),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"right-idle\", rightIdle);\n const upIdle = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 3),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 3),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 3),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 3),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"up-idle\", upIdle);\n const downIdle = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 0),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 0),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 0),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 0),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"down-idle\", downIdle);\n const leftWalk = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 5),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 5),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 5),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 5),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"left-walk\", leftWalk);\n const rightWalk = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 6),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 6),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 6),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 6),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"right-walk\", rightWalk);\n const upWalk = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 7),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 7),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 7),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 7),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"up-walk\", upWalk);\n const downWalk = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 4),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 4),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 4),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 4),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"down-walk\", downWalk);\n }\n onPreUpdate(engine, elapsedMs) {\n this.vel = $3MXpL.Vector.Zero;\n this.graphics.use(\"down-idle\");\n if (engine.input.keyboard.isHeld($3MXpL.Input.Keys.ArrowRight)) {\n this.vel = $3MXpL.vec((0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerSpeed, 0);\n this.graphics.use(\"right-walk\");\n }\n if (engine.input.keyboard.isHeld($3MXpL.Input.Keys.ArrowLeft)) {\n this.vel = $3MXpL.vec(-(0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerSpeed, 0);\n this.graphics.use(\"left-walk\");\n }\n if (engine.input.keyboard.isHeld($3MXpL.Input.Keys.ArrowUp)) {\n this.vel = $3MXpL.vec(0, -(0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerSpeed);\n this.graphics.use(\"up-walk\");\n }\n if (engine.input.keyboard.isHeld($3MXpL.Input.Keys.ArrowDown)) {\n this.vel = $3MXpL.vec(0, (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerSpeed);\n this.graphics.use(\"down-walk\");\n }\n }\n}\n\n\n\n\nvar $3MXpL = parcelRequire(\"3MXpL\");\n\n\nclass $4c16b4f5569f0f92$export$1027d4534a5ce60b extends (0, $3MXpL.Scene) {\n onPreLoad(loader) {}\n onInitialize(engine) {\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.addToScene(this, {\n levelFilter: [\n \"House\"\n ]\n });\n const entities = (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.getEntityLayers(\"House\")[0];\n const playerStart = entities.getLdtkEntitiesByIdentifier(\"PlayerStart\")[0];\n this.playerSpawnLocation = (0, $3MXpL.vec)(playerStart.__worldX ?? 0, playerStart.__worldY ?? 0);\n }\n onActivate(context) {\n const player = this.world.entityManager.getByName(\"player\")[0];\n player.get((0, $3MXpL.TransformComponent)).pos = this.playerSpawnLocation;\n if (player instanceof (0, $51d548b0596e1d08$export$2616165974278734)) this.camera.strategy.lockToActor(player);\n const bounds = (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.getLevelBounds([\n \"House\"\n ]);\n this.camera.strategy.limitCameraBounds(bounds);\n }\n constructor(...args){\n super(...args);\n this.playerSpawnLocation = (0, $3MXpL.vec)(0, 0);\n }\n}\n\n\n\nvar $3MXpL = parcelRequire(\"3MXpL\");\n\n\nclass $7daec61009a51988$export$f38c40ba0ccca861 extends (0, $3MXpL.Scene) {\n onInitialize(engine) {\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.addToScene(this, {\n pos: (0, $3MXpL.vec)(0, 0),\n levelFilter: [\n \"Level_0\",\n \"Level_1\"\n ]\n });\n }\n onActivate(context) {\n const player = this.world.entityManager.getByName(\"player\")[0];\n if (player instanceof (0, $51d548b0596e1d08$export$2616165974278734)) this.camera.strategy.lockToActor(player);\n const bounds = (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.getLevelBounds([\n \"Level_0\",\n \"Level_1\"\n ]);\n this.camera.strategy.limitCameraBounds(bounds);\n }\n}\n\n\nconst $ad2bcec7a0192558$var$game = new $3MXpL.Engine({\n resolution: {\n width: 256,\n height: 256\n },\n suppressPlayButton: true,\n displayMode: $3MXpL.DisplayMode.FitScreenAndFill,\n pixelArt: true,\n pixelRatio: 4,\n scenes: {\n overworld: {\n scene: (0, $7daec61009a51988$export$f38c40ba0ccca861),\n transitions: {\n out: new $3MXpL.FadeInOut({\n direction: \"out\",\n duration: 1000,\n color: $3MXpL.Color.Black\n }),\n in: new $3MXpL.FadeInOut({\n direction: \"in\",\n duration: 1000,\n color: $3MXpL.Color.Black\n })\n }\n },\n house: {\n scene: (0, $4c16b4f5569f0f92$export$1027d4534a5ce60b),\n transitions: {\n out: new $3MXpL.FadeInOut({\n direction: \"out\",\n duration: 1000,\n color: $3MXpL.Color.Black\n }),\n in: new $3MXpL.FadeInOut({\n direction: \"in\",\n duration: 1000,\n color: $3MXpL.Color.Black\n })\n }\n }\n }\n});\n(0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.registerEntityIdentifierFactory(\"PlayerStart\", (props)=>{\n const player = new (0, $51d548b0596e1d08$export$2616165974278734)({\n name: \"player\",\n anchor: $3MXpL.vec(props.entity.__pivot[0], props.entity.__pivot[1]),\n width: props.entity.width,\n height: props.entity.height,\n pos: props.worldPos,\n z: props.layer.order\n });\n return player;\n});\n(0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.registerEntityIdentifierFactory(\"Door\", (props)=>{\n const trigger = new $3MXpL.Trigger({\n width: props.entity.width,\n height: props.entity.height,\n pos: props.worldPos.add($3MXpL.vec(props.entity.width / 2, props.entity.height / 2)),\n filter: (entity)=>{\n return entity instanceof (0, $51d548b0596e1d08$export$2616165974278734);\n },\n action: ()=>{\n $ad2bcec7a0192558$var$game.goToScene(props.entity.fieldInstances[0].__value);\n }\n });\n return trigger;\n});\nconst $ad2bcec7a0192558$var$inTransition = new $3MXpL.FadeInOut({\n duration: 1000,\n direction: \"in\",\n color: $3MXpL.Color.ExcaliburBlue\n});\n$ad2bcec7a0192558$var$game.start(\"overworld\", {\n loader: $7c4c300842bd4cf2$export$f4c5de44377d2946,\n inTransition: $ad2bcec7a0192558$var$inTransition\n});\n\n\n//# sourceMappingURL=index.a78842eb.js.map\n","/*!\n * excalibur - 0.29.1 - 2024-2-23\n * https://github.com/excaliburjs/Excalibur\n * Copyright (c) 2024 Excalibur.js \n * Licensed BSD-2-Clause\n * @preserve\n */\n/******/ var __webpack_modules__ = ({\n\n/***/ 7835:\n/***/ ((module, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./Director/Loader.css\"],\"names\":[],\"mappings\":\"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\"sourcesContent\":[\"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n/***/ }),\n\n/***/ 7379:\n/***/ ((module, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./Util/Toaster.css\"],\"names\":[],\"mappings\":\";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\"sourcesContent\":[\"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n/***/ }),\n\n/***/ 2609:\n/***/ ((module) => {\n\n\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};\n\n/***/ }),\n\n/***/ 272:\n/***/ ((module) => {\n\n\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};\n\n/***/ }),\n\n/***/ 1324:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n__webpack_require__(7206);\nvar entryUnbind = __webpack_require__(8193);\n\nmodule.exports = entryUnbind('Array', 'sort');\n\n\n/***/ }),\n\n/***/ 3571:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n__webpack_require__(9867);\nvar path = __webpack_require__(8588);\n\nmodule.exports = path.Object.keys;\n\n\n/***/ }),\n\n/***/ 1052:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(688);\nvar tryToString = __webpack_require__(3397);\n\nvar $TypeError = TypeError;\n\n// `Assert: IsCallable(argument) is true`\nmodule.exports = function (argument) {\n if (isCallable(argument)) return argument;\n throw new $TypeError(tryToString(argument) + ' is not a function');\n};\n\n\n/***/ }),\n\n/***/ 9175:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isObject = __webpack_require__(5309);\n\nvar $String = String;\nvar $TypeError = TypeError;\n\n// `Assert: Type(argument) is Object`\nmodule.exports = function (argument) {\n if (isObject(argument)) return argument;\n throw new $TypeError($String(argument) + ' is not an object');\n};\n\n\n/***/ }),\n\n/***/ 1138:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIndexedObject = __webpack_require__(6854);\nvar toAbsoluteIndex = __webpack_require__(7352);\nvar lengthOfArrayLike = __webpack_require__(8344);\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\nvar createMethod = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el !== el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value !== value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) {\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n};\n\n\n/***/ }),\n\n/***/ 567:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4694);\n\nmodule.exports = function (METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function () { return 1; }, 1);\n });\n};\n\n\n/***/ }),\n\n/***/ 7686:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\n\nmodule.exports = uncurryThis([].slice);\n\n\n/***/ }),\n\n/***/ 3097:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar arraySlice = __webpack_require__(7686);\n\nvar floor = Math.floor;\n\nvar sort = function (array, comparefn) {\n var length = array.length;\n\n if (length < 8) {\n // insertion sort\n var i = 1;\n var element, j;\n\n while (i < length) {\n j = i;\n element = array[i];\n while (j && comparefn(array[j - 1], element) > 0) {\n array[j] = array[--j];\n }\n if (j !== i++) array[j] = element;\n }\n } else {\n // merge sort\n var middle = floor(length / 2);\n var left = sort(arraySlice(array, 0, middle), comparefn);\n var right = sort(arraySlice(array, middle), comparefn);\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n\n while (lindex < llength || rindex < rlength) {\n array[lindex + rindex] = (lindex < llength && rindex < rlength)\n ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]\n : lindex < llength ? left[lindex++] : right[rindex++];\n }\n }\n\n return array;\n};\n\nmodule.exports = sort;\n\n\n/***/ }),\n\n/***/ 2177:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\n\nvar toString = uncurryThis({}.toString);\nvar stringSlice = uncurryThis(''.slice);\n\nmodule.exports = function (it) {\n return stringSlice(toString(it), 8, -1);\n};\n\n\n/***/ }),\n\n/***/ 1566:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar TO_STRING_TAG_SUPPORT = __webpack_require__(2522);\nvar isCallable = __webpack_require__(688);\nvar classofRaw = __webpack_require__(2177);\nvar wellKnownSymbol = __webpack_require__(2032);\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar $Object = Object;\n\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result;\n};\n\n\n/***/ }),\n\n/***/ 3891:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar hasOwn = __webpack_require__(4678);\nvar ownKeys = __webpack_require__(990);\nvar getOwnPropertyDescriptorModule = __webpack_require__(7537);\nvar definePropertyModule = __webpack_require__(2131);\n\nmodule.exports = function (target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {\n defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n }\n};\n\n\n/***/ }),\n\n/***/ 2385:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar definePropertyModule = __webpack_require__(2131);\nvar createPropertyDescriptor = __webpack_require__(7781);\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n\n\n/***/ }),\n\n/***/ 7781:\n/***/ ((module) => {\n\n\nmodule.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n\n\n/***/ }),\n\n/***/ 2470:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(688);\nvar definePropertyModule = __webpack_require__(2131);\nvar makeBuiltIn = __webpack_require__(1135);\nvar defineGlobalProperty = __webpack_require__(1604);\n\nmodule.exports = function (O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) { /* empty */ }\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n } return O;\n};\n\n\n/***/ }),\n\n/***/ 1604:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\n\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\n\nmodule.exports = function (key, value) {\n try {\n defineProperty(global, key, { value: value, configurable: true, writable: true });\n } catch (error) {\n global[key] = value;\n } return value;\n};\n\n\n/***/ }),\n\n/***/ 955:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar tryToString = __webpack_require__(3397);\n\nvar $TypeError = TypeError;\n\nmodule.exports = function (O, P) {\n if (!delete O[P]) throw new $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));\n};\n\n\n/***/ }),\n\n/***/ 9924:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4694);\n\n// Detect IE8's incomplete defineProperty implementation\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7;\n});\n\n\n/***/ }),\n\n/***/ 1442:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar isObject = __webpack_require__(5309);\n\nvar document = global.document;\n// typeof document.createElement is 'object' in old IE\nvar EXISTS = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return EXISTS ? document.createElement(it) : {};\n};\n\n\n/***/ }),\n\n/***/ 9016:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar userAgent = __webpack_require__(1370);\n\nvar firefox = userAgent.match(/firefox\\/(\\d+)/i);\n\nmodule.exports = !!firefox && +firefox[1];\n\n\n/***/ }),\n\n/***/ 821:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar UA = __webpack_require__(1370);\n\nmodule.exports = /MSIE|Trident/.test(UA);\n\n\n/***/ }),\n\n/***/ 1370:\n/***/ ((module) => {\n\n\nmodule.exports = typeof navigator != 'undefined' && String(navigator.userAgent) || '';\n\n\n/***/ }),\n\n/***/ 7067:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar userAgent = __webpack_require__(1370);\n\nvar process = global.process;\nvar Deno = global.Deno;\nvar versions = process && process.versions || Deno && Deno.version;\nvar v8 = versions && versions.v8;\nvar match, version;\n\nif (v8) {\n match = v8.split('.');\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n}\n\n// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n// so check `userAgent` even if `.v8` exists, but 0\nif (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n}\n\nmodule.exports = version;\n\n\n/***/ }),\n\n/***/ 4389:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar userAgent = __webpack_require__(1370);\n\nvar webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n\nmodule.exports = !!webkit && +webkit[1];\n\n\n/***/ }),\n\n/***/ 8193:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar uncurryThis = __webpack_require__(9668);\n\nmodule.exports = function (CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n};\n\n\n/***/ }),\n\n/***/ 2367:\n/***/ ((module) => {\n\n\n// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n\n\n/***/ }),\n\n/***/ 5532:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar getOwnPropertyDescriptor = (__webpack_require__(7537).f);\nvar createNonEnumerableProperty = __webpack_require__(2385);\nvar defineBuiltIn = __webpack_require__(2470);\nvar defineGlobalProperty = __webpack_require__(1604);\nvar copyConstructorProperties = __webpack_require__(3891);\nvar isForced = __webpack_require__(1633);\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = global;\n } else if (STATIC) {\n target = global[TARGET] || defineGlobalProperty(TARGET, {});\n } else {\n target = global[TARGET] && global[TARGET].prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n createNonEnumerableProperty(sourceProperty, 'sham', true);\n }\n defineBuiltIn(target, key, sourceProperty, options);\n }\n};\n\n\n/***/ }),\n\n/***/ 4694:\n/***/ ((module) => {\n\n\nmodule.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n\n\n/***/ }),\n\n/***/ 6398:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4694);\n\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function () { /* empty */ }).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != 'function' || test.hasOwnProperty('prototype');\n});\n\n\n/***/ }),\n\n/***/ 8724:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_BIND = __webpack_require__(6398);\n\nvar call = Function.prototype.call;\n\nmodule.exports = NATIVE_BIND ? call.bind(call) : function () {\n return call.apply(call, arguments);\n};\n\n\n/***/ }),\n\n/***/ 453:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar hasOwn = __webpack_require__(4678);\n\nvar FunctionPrototype = Function.prototype;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n\nvar EXISTS = hasOwn(FunctionPrototype, 'name');\n// additional protection from minified / mangled / dropped function names\nvar PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';\nvar CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable));\n\nmodule.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n};\n\n\n/***/ }),\n\n/***/ 9668:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_BIND = __webpack_require__(6398);\n\nvar FunctionPrototype = Function.prototype;\nvar call = FunctionPrototype.call;\nvar uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n\nmodule.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {\n return function () {\n return call.apply(fn, arguments);\n };\n};\n\n\n/***/ }),\n\n/***/ 2160:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar isCallable = __webpack_require__(688);\n\nvar aFunction = function (argument) {\n return isCallable(argument) ? argument : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n};\n\n\n/***/ }),\n\n/***/ 5383:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar aCallable = __webpack_require__(1052);\nvar isNullOrUndefined = __webpack_require__(5268);\n\n// `GetMethod` abstract operation\n// https://tc39.es/ecma262/#sec-getmethod\nmodule.exports = function (V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n};\n\n\n/***/ }),\n\n/***/ 2150:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\n\nvar check = function (it) {\n return it && it.Math === Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == 'object' && globalThis) ||\n check(typeof window == 'object' && window) ||\n // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == 'object' && self) ||\n check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) ||\n check(typeof this == 'object' && this) ||\n // eslint-disable-next-line no-new-func -- fallback\n (function () { return this; })() || Function('return this')();\n\n\n/***/ }),\n\n/***/ 4678:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar toObject = __webpack_require__(298);\n\nvar hasOwnProperty = uncurryThis({}.hasOwnProperty);\n\n// `HasOwnProperty` abstract operation\n// https://tc39.es/ecma262/#sec-hasownproperty\n// eslint-disable-next-line es/no-object-hasown -- safe\nmodule.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n};\n\n\n/***/ }),\n\n/***/ 7390:\n/***/ ((module) => {\n\n\nmodule.exports = {};\n\n\n/***/ }),\n\n/***/ 7913:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar fails = __webpack_require__(4694);\nvar createElement = __webpack_require__(1442);\n\n// Thanks to IE8 for its funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a !== 7;\n});\n\n\n/***/ }),\n\n/***/ 4347:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar fails = __webpack_require__(4694);\nvar classof = __webpack_require__(2177);\n\nvar $Object = Object;\nvar split = uncurryThis(''.split);\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) === 'String' ? split(it, '') : $Object(it);\n} : $Object;\n\n\n/***/ }),\n\n/***/ 1881:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar isCallable = __webpack_require__(688);\nvar store = __webpack_require__(6762);\n\nvar functionToString = uncurryThis(Function.toString);\n\n// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\nif (!isCallable(store.inspectSource)) {\n store.inspectSource = function (it) {\n return functionToString(it);\n };\n}\n\nmodule.exports = store.inspectSource;\n\n\n/***/ }),\n\n/***/ 7804:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_WEAK_MAP = __webpack_require__(4724);\nvar global = __webpack_require__(2150);\nvar isObject = __webpack_require__(5309);\nvar createNonEnumerableProperty = __webpack_require__(2385);\nvar hasOwn = __webpack_require__(4678);\nvar shared = __webpack_require__(6762);\nvar sharedKey = __webpack_require__(1962);\nvar hiddenKeys = __webpack_require__(7390);\n\nvar OBJECT_ALREADY_INITIALIZED = 'Object already initialized';\nvar TypeError = global.TypeError;\nvar WeakMap = global.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw new TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap());\n /* eslint-disable no-self-assign -- prototype methods protection */\n store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */\n set = function (it, metadata) {\n if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function (it) {\n return store.get(it) || {};\n };\n has = function (it) {\n return store.has(it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return hasOwn(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n\n\n/***/ }),\n\n/***/ 688:\n/***/ ((module) => {\n\n\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\nvar documentAll = typeof document == 'object' && document.all;\n\n// `IsCallable` abstract operation\n// https://tc39.es/ecma262/#sec-iscallable\n// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\nmodule.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) {\n return typeof argument == 'function' || argument === documentAll;\n} : function (argument) {\n return typeof argument == 'function';\n};\n\n\n/***/ }),\n\n/***/ 1633:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4694);\nvar isCallable = __webpack_require__(688);\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value === POLYFILL ? true\n : value === NATIVE ? false\n : isCallable(detection) ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n\n\n/***/ }),\n\n/***/ 5268:\n/***/ ((module) => {\n\n\n// we can't use just `it == null` since of `document.all` special case\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\nmodule.exports = function (it) {\n return it === null || it === undefined;\n};\n\n\n/***/ }),\n\n/***/ 5309:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(688);\n\nmodule.exports = function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it);\n};\n\n\n/***/ }),\n\n/***/ 6555:\n/***/ ((module) => {\n\n\nmodule.exports = false;\n\n\n/***/ }),\n\n/***/ 7935:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar getBuiltIn = __webpack_require__(2160);\nvar isCallable = __webpack_require__(688);\nvar isPrototypeOf = __webpack_require__(6148);\nvar USE_SYMBOL_AS_UID = __webpack_require__(4866);\n\nvar $Object = Object;\n\nmodule.exports = USE_SYMBOL_AS_UID ? function (it) {\n return typeof it == 'symbol';\n} : function (it) {\n var $Symbol = getBuiltIn('Symbol');\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n};\n\n\n/***/ }),\n\n/***/ 8344:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toLength = __webpack_require__(7331);\n\n// `LengthOfArrayLike` abstract operation\n// https://tc39.es/ecma262/#sec-lengthofarraylike\nmodule.exports = function (obj) {\n return toLength(obj.length);\n};\n\n\n/***/ }),\n\n/***/ 1135:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar fails = __webpack_require__(4694);\nvar isCallable = __webpack_require__(688);\nvar hasOwn = __webpack_require__(4678);\nvar DESCRIPTORS = __webpack_require__(9924);\nvar CONFIGURABLE_FUNCTION_NAME = (__webpack_require__(453).CONFIGURABLE);\nvar inspectSource = __webpack_require__(1881);\nvar InternalStateModule = __webpack_require__(7804);\n\nvar enforceInternalState = InternalStateModule.enforce;\nvar getInternalState = InternalStateModule.get;\nvar $String = String;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\nvar stringSlice = uncurryThis(''.slice);\nvar replace = uncurryThis(''.replace);\nvar join = uncurryThis([].join);\n\nvar CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () {\n return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;\n});\n\nvar TEMPLATE = String(String).split('String');\n\nvar makeBuiltIn = module.exports = function (value, name, options) {\n if (stringSlice($String(name), 0, 7) === 'Symbol(') {\n name = '[' + replace($String(name), /^Symbol\\(([^)]*)\\).*$/, '$1') + ']';\n }\n if (options && options.getter) name = 'get ' + name;\n if (options && options.setter) name = 'set ' + name;\n if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {\n if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) {\n defineProperty(value, 'length', { value: options.arity });\n }\n try {\n if (options && hasOwn(options, 'constructor') && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false });\n // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) { /* empty */ }\n var state = enforceInternalState(value);\n if (!hasOwn(state, 'source')) {\n state.source = join(TEMPLATE, typeof name == 'string' ? name : '');\n } return value;\n};\n\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n// eslint-disable-next-line no-extend-native -- required\nFunction.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n}, 'toString');\n\n\n/***/ }),\n\n/***/ 1787:\n/***/ ((module) => {\n\n\nvar ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `Math.trunc` method\n// https://tc39.es/ecma262/#sec-math.trunc\n// eslint-disable-next-line es/no-math-trunc -- safe\nmodule.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n};\n\n\n/***/ }),\n\n/***/ 2131:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar IE8_DOM_DEFINE = __webpack_require__(7913);\nvar V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(2666);\nvar anObject = __webpack_require__(9175);\nvar toPropertyKey = __webpack_require__(2358);\n\nvar $TypeError = TypeError;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar $defineProperty = Object.defineProperty;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar ENUMERABLE = 'enumerable';\nvar CONFIGURABLE = 'configurable';\nvar WRITABLE = 'writable';\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\nexports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n } return $defineProperty(O, P, Attributes);\n} : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n\n\n/***/ }),\n\n/***/ 7537:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar call = __webpack_require__(8724);\nvar propertyIsEnumerableModule = __webpack_require__(8208);\nvar createPropertyDescriptor = __webpack_require__(7781);\nvar toIndexedObject = __webpack_require__(6854);\nvar toPropertyKey = __webpack_require__(2358);\nvar hasOwn = __webpack_require__(4678);\nvar IE8_DOM_DEFINE = __webpack_require__(7913);\n\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\nexports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n};\n\n\n/***/ }),\n\n/***/ 6217:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar internalObjectKeys = __webpack_require__(1528);\nvar enumBugKeys = __webpack_require__(2367);\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.es/ecma262/#sec-object.getownpropertynames\n// eslint-disable-next-line es/no-object-getownpropertynames -- safe\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n\n\n/***/ }),\n\n/***/ 5168:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\nexports.f = Object.getOwnPropertySymbols;\n\n\n/***/ }),\n\n/***/ 6148:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\n\nmodule.exports = uncurryThis({}.isPrototypeOf);\n\n\n/***/ }),\n\n/***/ 1528:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar hasOwn = __webpack_require__(4678);\nvar toIndexedObject = __webpack_require__(6854);\nvar indexOf = (__webpack_require__(1138).indexOf);\nvar hiddenKeys = __webpack_require__(7390);\n\nvar push = uncurryThis([].push);\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (hasOwn(O, key = names[i++])) {\n ~indexOf(result, key) || push(result, key);\n }\n return result;\n};\n\n\n/***/ }),\n\n/***/ 1728:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar internalObjectKeys = __webpack_require__(1528);\nvar enumBugKeys = __webpack_require__(2367);\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n// eslint-disable-next-line es/no-object-keys -- safe\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n\n\n/***/ }),\n\n/***/ 8208:\n/***/ ((__unused_webpack_module, exports) => {\n\n\nvar $propertyIsEnumerable = {}.propertyIsEnumerable;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);\n\n// `Object.prototype.propertyIsEnumerable` method implementation\n// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : $propertyIsEnumerable;\n\n\n/***/ }),\n\n/***/ 110:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar call = __webpack_require__(8724);\nvar isCallable = __webpack_require__(688);\nvar isObject = __webpack_require__(5309);\n\nvar $TypeError = TypeError;\n\n// `OrdinaryToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-ordinarytoprimitive\nmodule.exports = function (input, pref) {\n var fn, val;\n if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw new $TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/***/ }),\n\n/***/ 990:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar getBuiltIn = __webpack_require__(2160);\nvar uncurryThis = __webpack_require__(9668);\nvar getOwnPropertyNamesModule = __webpack_require__(6217);\nvar getOwnPropertySymbolsModule = __webpack_require__(5168);\nvar anObject = __webpack_require__(9175);\n\nvar concat = uncurryThis([].concat);\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n};\n\n\n/***/ }),\n\n/***/ 8588:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\n\nmodule.exports = global;\n\n\n/***/ }),\n\n/***/ 1166:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isNullOrUndefined = __webpack_require__(5268);\n\nvar $TypeError = TypeError;\n\n// `RequireObjectCoercible` abstract operation\n// https://tc39.es/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (isNullOrUndefined(it)) throw new $TypeError(\"Can't call method on \" + it);\n return it;\n};\n\n\n/***/ }),\n\n/***/ 1962:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar shared = __webpack_require__(2645);\nvar uid = __webpack_require__(5736);\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n\n\n/***/ }),\n\n/***/ 6762:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar defineGlobalProperty = __webpack_require__(1604);\n\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || defineGlobalProperty(SHARED, {});\n\nmodule.exports = store;\n\n\n/***/ }),\n\n/***/ 2645:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar IS_PURE = __webpack_require__(6555);\nvar store = __webpack_require__(6762);\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: '3.35.1',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)',\n license: 'https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE',\n source: 'https://github.com/zloirock/core-js'\n});\n\n\n/***/ }),\n\n/***/ 4112:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n/* eslint-disable es/no-symbol -- required for testing */\nvar V8_VERSION = __webpack_require__(7067);\nvar fails = __webpack_require__(4694);\nvar global = __webpack_require__(2150);\n\nvar $String = global.String;\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n var symbol = Symbol('symbol detection');\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) ||\n // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n});\n\n\n/***/ }),\n\n/***/ 7352:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIntegerOrInfinity = __webpack_require__(1680);\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\nmodule.exports = function (index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n\n\n/***/ }),\n\n/***/ 6854:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = __webpack_require__(4347);\nvar requireObjectCoercible = __webpack_require__(1166);\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n\n\n/***/ }),\n\n/***/ 1680:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar trunc = __webpack_require__(1787);\n\n// `ToIntegerOrInfinity` abstract operation\n// https://tc39.es/ecma262/#sec-tointegerorinfinity\nmodule.exports = function (argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n};\n\n\n/***/ }),\n\n/***/ 7331:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIntegerOrInfinity = __webpack_require__(1680);\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.es/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n var len = toIntegerOrInfinity(argument);\n return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n\n\n/***/ }),\n\n/***/ 298:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar requireObjectCoercible = __webpack_require__(1166);\n\nvar $Object = Object;\n\n// `ToObject` abstract operation\n// https://tc39.es/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return $Object(requireObjectCoercible(argument));\n};\n\n\n/***/ }),\n\n/***/ 1272:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar call = __webpack_require__(8724);\nvar isObject = __webpack_require__(5309);\nvar isSymbol = __webpack_require__(7935);\nvar getMethod = __webpack_require__(5383);\nvar ordinaryToPrimitive = __webpack_require__(110);\nvar wellKnownSymbol = __webpack_require__(2032);\n\nvar $TypeError = TypeError;\nvar TO_PRIMITIVE = wellKnownSymbol('toPrimitive');\n\n// `ToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-toprimitive\nmodule.exports = function (input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = 'default';\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw new $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = 'number';\n return ordinaryToPrimitive(input, pref);\n};\n\n\n/***/ }),\n\n/***/ 2358:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toPrimitive = __webpack_require__(1272);\nvar isSymbol = __webpack_require__(7935);\n\n// `ToPropertyKey` abstract operation\n// https://tc39.es/ecma262/#sec-topropertykey\nmodule.exports = function (argument) {\n var key = toPrimitive(argument, 'string');\n return isSymbol(key) ? key : key + '';\n};\n\n\n/***/ }),\n\n/***/ 2522:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar wellKnownSymbol = __webpack_require__(2032);\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n\ntest[TO_STRING_TAG] = 'z';\n\nmodule.exports = String(test) === '[object z]';\n\n\n/***/ }),\n\n/***/ 599:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar classof = __webpack_require__(1566);\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n return $String(argument);\n};\n\n\n/***/ }),\n\n/***/ 3397:\n/***/ ((module) => {\n\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n try {\n return $String(argument);\n } catch (error) {\n return 'Object';\n }\n};\n\n\n/***/ }),\n\n/***/ 5736:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\n\nvar id = 0;\nvar postfix = Math.random();\nvar toString = uncurryThis(1.0.toString);\n\nmodule.exports = function (key) {\n return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);\n};\n\n\n/***/ }),\n\n/***/ 4866:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n/* eslint-disable es/no-symbol -- required for testing */\nvar NATIVE_SYMBOL = __webpack_require__(4112);\n\nmodule.exports = NATIVE_SYMBOL\n && !Symbol.sham\n && typeof Symbol.iterator == 'symbol';\n\n\n/***/ }),\n\n/***/ 2666:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar fails = __webpack_require__(4694);\n\n// V8 ~ Chrome 36-\n// https://bugs.chromium.org/p/v8/issues/detail?id=3334\nmodule.exports = DESCRIPTORS && fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function () { /* empty */ }, 'prototype', {\n value: 42,\n writable: false\n }).prototype !== 42;\n});\n\n\n/***/ }),\n\n/***/ 4724:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar isCallable = __webpack_require__(688);\n\nvar WeakMap = global.WeakMap;\n\nmodule.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));\n\n\n/***/ }),\n\n/***/ 2032:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar shared = __webpack_require__(2645);\nvar hasOwn = __webpack_require__(4678);\nvar uid = __webpack_require__(5736);\nvar NATIVE_SYMBOL = __webpack_require__(4112);\nvar USE_SYMBOL_AS_UID = __webpack_require__(4866);\n\nvar Symbol = global.Symbol;\nvar WellKnownSymbolsStore = shared('wks');\nvar createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;\n\nmodule.exports = function (name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) {\n WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name)\n ? Symbol[name]\n : createWellKnownSymbol('Symbol.' + name);\n } return WellKnownSymbolsStore[name];\n};\n\n\n/***/ }),\n\n/***/ 7206:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar $ = __webpack_require__(5532);\nvar uncurryThis = __webpack_require__(9668);\nvar aCallable = __webpack_require__(1052);\nvar toObject = __webpack_require__(298);\nvar lengthOfArrayLike = __webpack_require__(8344);\nvar deletePropertyOrThrow = __webpack_require__(955);\nvar toString = __webpack_require__(599);\nvar fails = __webpack_require__(4694);\nvar internalSort = __webpack_require__(3097);\nvar arrayMethodIsStrict = __webpack_require__(567);\nvar FF = __webpack_require__(9016);\nvar IE_OR_EDGE = __webpack_require__(821);\nvar V8 = __webpack_require__(7067);\nvar WEBKIT = __webpack_require__(4389);\n\nvar test = [];\nvar nativeSort = uncurryThis(test.sort);\nvar push = uncurryThis(test.push);\n\n// IE8-\nvar FAILS_ON_UNDEFINED = fails(function () {\n test.sort(undefined);\n});\n// V8 bug\nvar FAILS_ON_NULL = fails(function () {\n test.sort(null);\n});\n// Old WebKit\nvar STRICT_METHOD = arrayMethodIsStrict('sort');\n\nvar STABLE_SORT = !fails(function () {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n\n var result = '';\n var code, chr, value, index;\n\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for (code = 65; code < 76; code++) {\n chr = String.fromCharCode(code);\n\n switch (code) {\n case 66: case 69: case 70: case 72: value = 3; break;\n case 68: case 71: value = 4; break;\n default: value = 2;\n }\n\n for (index = 0; index < 47; index++) {\n test.push({ k: chr + index, v: value });\n }\n }\n\n test.sort(function (a, b) { return b.v - a.v; });\n\n for (index = 0; index < test.length; index++) {\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n\n return result !== 'DGBEFHACIJK';\n});\n\nvar FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n\nvar getSortCompare = function (comparefn) {\n return function (x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n};\n\n// `Array.prototype.sort` method\n// https://tc39.es/ecma262/#sec-array.prototype.sort\n$({ target: 'Array', proto: true, forced: FORCED }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n\n var array = toObject(this);\n\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n\n for (index = 0; index < arrayLength; index++) {\n if (index in array) push(items, array[index]);\n }\n\n internalSort(items, getSortCompare(comparefn));\n\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n\n while (index < itemsLength) array[index] = items[index++];\n while (index < arrayLength) deletePropertyOrThrow(array, index++);\n\n return array;\n }\n});\n\n\n/***/ }),\n\n/***/ 9867:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar $ = __webpack_require__(5532);\nvar toObject = __webpack_require__(298);\nvar nativeKeys = __webpack_require__(1728);\nvar fails = __webpack_require__(4694);\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeKeys(1); });\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n});\n\n\n/***/ })\n\n/******/ });\n/************************************************************************/\n/******/ // The module cache\n/******/ var __webpack_module_cache__ = {};\n/******/ \n/******/ // The require function\n/******/ function __webpack_require__(moduleId) {\n/******/ \t// Check if module is in cache\n/******/ \tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \tif (cachedModule !== undefined) {\n/******/ \t\treturn cachedModule.exports;\n/******/ \t}\n/******/ \t// Create a new module (and put it into the cache)\n/******/ \tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\tid: moduleId,\n/******/ \t\t// no module.loaded needed\n/******/ \t\texports: {}\n/******/ \t};\n/******/ \n/******/ \t// Execute the module function\n/******/ \t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/ \n/******/ \t// Return the exports of the module\n/******/ \treturn module.exports;\n/******/ }\n/******/ \n/************************************************************************/\n/******/ /* webpack/runtime/compat get default export */\n/******/ (() => {\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = (module) => {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t() => (module['default']) :\n/******/ \t\t\t() => (module);\n/******/ \t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\treturn getter;\n/******/ \t};\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/define property getters */\n/******/ (() => {\n/******/ \t// define getter functions for harmony exports\n/******/ \t__webpack_require__.d = (exports, definition) => {\n/******/ \t\tfor(var key in definition) {\n/******/ \t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t};\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/global */\n/******/ (() => {\n/******/ \t__webpack_require__.g = (function() {\n/******/ \t\tif (typeof globalThis === 'object') return globalThis;\n/******/ \t\ttry {\n/******/ \t\t\treturn this || new Function('return this')();\n/******/ \t\t} catch (e) {\n/******/ \t\t\tif (typeof window === 'object') return window;\n/******/ \t\t}\n/******/ \t})();\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/hasOwnProperty shorthand */\n/******/ (() => {\n/******/ \t__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/make namespace object */\n/******/ (() => {\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = (exports) => {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/ })();\n/******/ \n/************************************************************************/\nvar __webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(() => {\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n y1j: () => (/* reexport */ ActionCompleteEvent),\n fWn: () => (/* reexport */ ActionContext),\n Ia8: () => (/* reexport */ ActionQueue),\n rqv: () => (/* reexport */ ActionSequence),\n zH6: () => (/* reexport */ ActionStartEvent),\n hLI: () => (/* reexport */ ActionsComponent),\n yyv: () => (/* reexport */ ActionsSystem),\n tX5: () => (/* reexport */ ActivateEvent),\n vtX: () => (/* reexport */ Actor),\n r7K: () => (/* reexport */ AddedComponent),\n cE4: () => (/* reexport */ AffineMatrix),\n fwF: () => (/* reexport */ Animation),\n sce: () => (/* reexport */ AnimationDirection),\n AQ6: () => (/* reexport */ AnimationEvents),\n _c7: () => (/* reexport */ AnimationStrategy),\n KUs: () => (/* reexport */ ArcadeSolver),\n Ajp: () => (/* reexport */ AudioContextFactory),\n dkO: () => (/* reexport */ Axes),\n RDh: () => (/* reexport */ Axis),\n _H9: () => (/* reexport */ BaseAlign),\n mxs: () => (/* reexport */ Blink),\n OmD: () => (/* reexport */ BodyComponent),\n kBf: () => (/* reexport */ BoundingBox),\n C4F: () => (/* reexport */ BroadphaseStrategy),\n NQt: () => (/* reexport */ BrowserComponent),\n JjN: () => (/* reexport */ BrowserEvents),\n EK_: () => (/* reexport */ Buttons),\n V1s: () => (/* reexport */ Camera),\n xHm: () => (/* reexport */ CameraEvents),\n Xz7: () => (/* reexport */ Canvas),\n Cdc: () => (/* reexport */ Circle),\n FKn: () => (/* reexport */ CircleCollider),\n SUY: () => (/* reexport */ Clock),\n ab2: () => (/* reexport */ ClosestLine),\n GfZ: () => (/* reexport */ ClosestLineJumpTable),\n YMS: () => (/* reexport */ Collider),\n oyv: () => (/* reexport */ ColliderComponent),\n aUb: () => (/* reexport */ CollisionContact),\n SdD: () => (/* reexport */ CollisionEndEvent),\n JUv: () => (/* reexport */ CollisionGroup),\n jEj: () => (/* reexport */ CollisionGroupManager),\n TFq: () => (/* reexport */ CollisionJumpTable),\n HDU: () => (/* reexport */ CollisionPostSolveEvent),\n R_y: () => (/* reexport */ CollisionPreSolveEvent),\n t50: () => (/* reexport */ CollisionStartEvent),\n s$$: () => (/* reexport */ CollisionSystem),\n v2G: () => (/* reexport */ CollisionType),\n Ilk: () => (/* reexport */ Color),\n s9i: () => (/* reexport */ ColorBlindFlags),\n dxL: () => (/* reexport */ ColorBlindnessMode),\n LLX: () => (/* reexport */ ColorBlindnessPostProcessor),\n wA2: () => (/* reexport */ Component),\n R_p: () => (/* reexport */ CompositeCollider),\n IQ$: () => (/* reexport */ Configurable),\n I5F: () => (/* reexport */ ConsoleAppender),\n X8$: () => (/* reexport */ ContactConstraintPoint),\n FR6: () => (/* reexport */ ContactEndEvent),\n pTZ: () => (/* reexport */ ContactSolveBias),\n U8o: () => (/* reexport */ ContactStartEvent),\n kbG: () => (/* reexport */ CoordPlane),\n FEv: () => (/* reexport */ CrossFade),\n iS_: () => (/* reexport */ DeactivateEvent),\n cGG: () => (/* reexport */ Debug),\n ETM: () => (/* reexport */ DebugConfig),\n RPN: () => (/* reexport */ DebugGraphicsComponent),\n skb: () => (/* reexport */ DebugSystem),\n SLU: () => (/* reexport */ DebugText),\n Q3w: () => (/* reexport */ DefaultAntialiasOptions),\n xK2: () => (/* reexport */ DefaultLoader),\n vrO: () => (/* reexport */ DefaultPhysicsConfig),\n EA2: () => (/* reexport */ DefaultPixelArtOptions),\n RdJ: () => (/* reexport */ DegreeOfFreedom),\n cNu: () => (/* reexport */ Delay),\n wtG: () => (/* reexport */ DeprecatedStaticToConfig),\n gU7: () => (/* reexport */ Detector),\n LSk: () => (/* reexport */ Die),\n Nmp: () => (/* reexport */ Direction),\n twX: () => (/* reexport */ Director),\n UND: () => (/* reexport */ DirectorEvents),\n d1Y: () => (/* reexport */ DisplayMode),\n xrL: () => (/* reexport */ DynamicTree),\n sRW: () => (/* reexport */ DynamicTreeCollisionProcessor),\n cmV: () => (/* binding */ EX_VERSION),\n qWz: () => (/* reexport */ EaseBy),\n N0Q: () => (/* reexport */ EaseTo),\n q8b: () => (/* reexport */ EasingFunctions),\n ynB: () => (/* reexport */ EdgeCollider),\n jT9: () => (/* reexport */ ElasticToActorStrategy),\n wAz: () => (/* reexport */ EmitterType),\n D4V: () => (/* reexport */ Engine),\n NLr: () => (/* reexport */ EngineEvents),\n N6H: () => (/* reexport */ EnterTriggerEvent),\n W1A: () => (/* reexport */ EnterViewPortEvent),\n JHW: () => (/* reexport */ Entity),\n ZZ$: () => (/* reexport */ EntityEvents),\n v2K: () => (/* reexport */ EntityManager),\n pBf: () => (/* reexport */ EventDispatcher),\n vpe: () => (/* reexport */ EventEmitter),\n GMl: () => (/* reexport */ EventTypes),\n zW2: () => (/* reexport */ Events_namespaceObject),\n B0K: () => (/* reexport */ ExResponse),\n Nv7: () => (/* reexport */ ExcaliburGraphicsContext2DCanvas),\n C_p: () => (/* reexport */ ExcaliburGraphicsContextWebGL),\n MUA: () => (/* reexport */ ExitTriggerEvent),\n xqU: () => (/* reexport */ ExitViewPortEvent),\n pTp: () => (/* reexport */ Fade),\n trb: () => (/* reexport */ FadeInOut),\n vUK: () => (/* reexport */ Flags),\n j9l: () => (/* reexport */ Follow),\n Zxw: () => (/* reexport */ Font),\n v51: () => (/* reexport */ FontCache),\n gYv: () => (/* reexport */ FontSource),\n Hdx: () => (/* reexport */ FontStyle),\n Z$d: () => (/* reexport */ FontUnit),\n iqV: () => (/* reexport */ FpsSampler),\n o$7: () => (/* reexport */ FrameStats),\n olM: () => (/* reexport */ Future),\n Zm$: () => (/* reexport */ GameEvent),\n $QH: () => (/* reexport */ GameStartEvent),\n i78: () => (/* reexport */ GameStopEvent),\n nJg: () => (/* reexport */ Gamepad),\n h6u: () => (/* reexport */ GamepadAxisEvent),\n hts: () => (/* reexport */ GamepadButtonEvent),\n j88: () => (/* reexport */ GamepadConnectEvent),\n VME: () => (/* reexport */ GamepadDisconnectEvent),\n fy2: () => (/* reexport */ Gamepads),\n nt: () => (/* reexport */ Gif),\n Ukr: () => (/* reexport */ GlobalCoordinates),\n zsu: () => (/* reexport */ Graphic),\n oA6: () => (/* reexport */ GraphicsComponent),\n TVh: () => (/* reexport */ GraphicsGroup),\n xxj: () => (/* reexport */ GraphicsSystem),\n XdK: () => (/* reexport */ HiddenEvent),\n fBD: () => (/* reexport */ HorizontalFirst),\n Jmb: () => (/* reexport */ ImageFiltering),\n cXo: () => (/* reexport */ ImageSource),\n Dm5: () => (/* reexport */ InitializeEvent),\n IIB: () => (/* reexport */ Input_Index_namespaceObject),\n IX$: () => (/* reexport */ InputHost),\n ebW: () => (/* reexport */ InputMapper),\n zI0: () => (/* reexport */ Integrator),\n LYD: () => (/* reexport */ IsometricEntityComponent),\n cEG: () => (/* reexport */ IsometricEntitySystem),\n SEl: () => (/* reexport */ IsometricMap),\n t9V: () => (/* reexport */ IsometricTile),\n ez5: () => (/* reexport */ KeyEvent),\n N1d: () => (/* reexport */ Keyboard),\n R8U: () => (/* reexport */ Keys),\n SKZ: () => (/* reexport */ KillEvent),\n __J: () => (/* reexport */ Label),\n RI$: () => (/* reexport */ LimitCameraBoundsStrategy),\n x12: () => (/* reexport */ Line),\n ccz: () => (/* reexport */ LineSegment),\n aNw: () => (/* reexport */ Loader),\n XrL: () => (/* reexport */ LoaderEvents),\n xwn: () => (/* reexport */ LockCameraToActorAxisStrategy),\n dNK: () => (/* reexport */ LockCameraToActorStrategy),\n ini: () => (/* reexport */ LogLevel),\n YdH: () => (/* reexport */ Logger),\n F5T: () => (/* reexport */ Material),\n y3G: () => (/* reexport */ Matrix),\n l57: () => (/* reexport */ MatrixLocations),\n xn0: () => (/* reexport */ MediaEvent),\n t2V: () => (/* reexport */ Meet),\n uxB: () => (/* reexport */ MotionComponent),\n cpd: () => (/* reexport */ MotionSystem),\n fiy: () => (/* reexport */ MoveBy),\n $XZ: () => (/* reexport */ MoveTo),\n UG6: () => (/* reexport */ NativePointerButton),\n uqK: () => (/* reexport */ NativeSoundEvent),\n STE: () => (/* reexport */ NativeSoundProcessedEvent),\n Hq9: () => (/* reexport */ None),\n y$z: () => (/* reexport */ Observable),\n mAD: () => (/* reexport */ OffscreenSystem),\n sOq: () => (/* reexport */ Pair),\n hUw: () => (/* reexport */ ParallaxComponent),\n _0G: () => (/* reexport */ ParallelActions),\n Sqs: () => (/* reexport */ ParseGif),\n hpZ: () => (/* reexport */ Particle),\n Vol: () => (/* reexport */ ParticleEmitter),\n vYX: () => (/* reexport */ ParticleTransform),\n wIZ: () => (/* reexport */ Physics),\n cBi: () => (/* reexport */ PhysicsStats),\n c30: () => (/* reexport */ PhysicsWorld),\n PGK: () => (/* reexport */ PointerAbstraction),\n MPV: () => (/* reexport */ PointerButton),\n RFv: () => (/* reexport */ PointerComponent),\n Ux6: () => (/* reexport */ PointerEvent),\n rxy: () => (/* reexport */ PointerEventReceiver),\n I$c: () => (/* reexport */ PointerScope),\n kfC: () => (/* reexport */ PointerSystem),\n VjY: () => (/* reexport */ PointerType),\n mgq: () => (/* reexport */ Polygon),\n YVA: () => (/* reexport */ PolygonCollider),\n Kgp: () => (/* reexport */ Pool),\n HH$: () => (/* reexport */ PostCollisionEvent),\n M_d: () => (/* reexport */ PostDebugDrawEvent),\n rgh: () => (/* reexport */ PostDrawEvent),\n Ra6: () => (/* reexport */ PostFrameEvent),\n KhR: () => (/* reexport */ PostKillEvent),\n gvQ: () => (/* reexport */ PostTransformDrawEvent),\n BS5: () => (/* reexport */ PostUpdateEvent),\n xhz: () => (/* reexport */ PreCollisionEvent),\n xOq: () => (/* reexport */ PreDebugDrawEvent),\n a9j: () => (/* reexport */ PreDrawEvent),\n bHk: () => (/* reexport */ PreFrameEvent),\n CgK: () => (/* reexport */ PreKillEvent),\n A0M: () => (/* reexport */ PreLoadEvent),\n cEd: () => (/* reexport */ PreTransformDrawEvent),\n cuY: () => (/* reexport */ PreUpdateEvent),\n kvE: () => (/* reexport */ Projection),\n SBu: () => (/* reexport */ QuadIndexBuffer),\n PsT: () => (/* reexport */ QuadTree),\n AE_: () => (/* reexport */ Query),\n ctO: () => (/* reexport */ QueryManager),\n OLH: () => (/* reexport */ RadiusAroundActorStrategy),\n kky: () => (/* reexport */ Random),\n nSF: () => (/* reexport */ Raster),\n zHn: () => (/* reexport */ Ray),\n zwx: () => (/* reexport */ RealisticSolver),\n AeJ: () => (/* reexport */ Rectangle),\n hLz: () => (/* reexport */ RemovedComponent),\n wA: () => (/* reexport */ Repeat),\n jhr: () => (/* reexport */ RepeatForever),\n GVs: () => (/* reexport */ Resolution),\n _zO: () => (/* reexport */ Resource),\n LXZ: () => (/* reexport */ ResourceEvents),\n w6$: () => (/* reexport */ RotateBy),\n mhV: () => (/* reexport */ RotateTo),\n MOD: () => (/* reexport */ RotationType),\n kwd: () => (/* reexport */ ScaleBy),\n Lmr: () => (/* reexport */ ScaleTo),\n xsS: () => (/* reexport */ Scene),\n K5l: () => (/* reexport */ SceneEvents),\n lLr: () => (/* reexport */ Screen),\n Z$r: () => (/* reexport */ ScreenAppender),\n IXb: () => (/* reexport */ ScreenElement),\n Xsu: () => (/* reexport */ ScreenEvents),\n SGH: () => (/* reexport */ ScreenShader),\n SMj: () => (/* reexport */ ScrollPreventionMode),\n L34: () => (/* reexport */ Semaphore),\n exe: () => (/* reexport */ Shader),\n bnF: () => (/* reexport */ Shape),\n MFA: () => (/* reexport */ Side),\n kPj: () => (/* reexport */ SolverStrategy),\n $uU: () => (/* reexport */ Sound),\n Sap: () => (/* reexport */ SoundEvents),\n jyi: () => (/* reexport */ Sprite),\n E03: () => (/* reexport */ SpriteFont),\n V6q: () => (/* reexport */ SpriteSheet),\n rg2: () => (/* reexport */ StandardClock),\n DVW: () => (/* reexport */ StateMachine),\n nVo: () => (/* reexport */ StrategyContainer),\n F6N: () => (/* reexport */ Stream),\n xP7: () => (/* reexport */ System),\n Odq: () => (/* reexport */ SystemManager),\n uY9: () => (/* reexport */ SystemPriority),\n Zif: () => (/* reexport */ SystemType),\n c_d: () => (/* reexport */ TagQuery),\n MJk: () => (/* reexport */ TestClock),\n xvT: () => (/* reexport */ Text),\n PHM: () => (/* reexport */ TextAlign),\n dpR: () => (/* reexport */ TextureLoader),\n n9L: () => (/* reexport */ Tile),\n KwO: () => (/* reexport */ TileMap),\n SxM: () => (/* reexport */ TileMapEvents),\n B7y: () => (/* reexport */ Timer),\n x7r: () => (/* reexport */ Toaster),\n wx7: () => (/* reexport */ transform_Transform),\n Uvn: () => (/* reexport */ TransformComponent),\n uTP: () => (/* reexport */ Transition),\n OFT: () => (/* reexport */ TreeNode),\n xzN: () => (/* reexport */ Trigger),\n CcZ: () => (/* reexport */ TriggerEvents),\n M5Z: () => (/* reexport */ TwoPI),\n ZrN: () => (/* reexport */ Util_Index_namespaceObject),\n OWs: () => (/* reexport */ Vector),\n dF9: () => (/* reexport */ VectorView),\n oZy: () => (/* reexport */ VertexBuffer),\n rD2: () => (/* reexport */ VertexLayout),\n KmN: () => (/* reexport */ VerticalFirst),\n VHo: () => (/* reexport */ VisibleEvent),\n ohE: () => (/* reexport */ WebAudio),\n R$E: () => (/* reexport */ WebAudioInstance),\n xQN: () => (/* reexport */ WheelDeltaMode),\n AdJ: () => (/* reexport */ WheelEvent),\n q3I: () => (/* reexport */ World),\n Pab: () => (/* reexport */ canonicalizeAngle),\n uZ5: () => (/* reexport */ clamp),\n TAE: () => (/* reexport */ coroutine),\n McK: () => (/* reexport */ createId),\n F9c: () => (/* reexport */ frac),\n k0b: () => (/* reexport */ hasGraphicsTick),\n hnT: () => (/* reexport */ hasOnInitialize),\n RSJ: () => (/* reexport */ hasOnPostUpdate),\n Mku: () => (/* reexport */ hasOnPreUpdate),\n h90: () => (/* reexport */ hasPostDraw),\n rms: () => (/* reexport */ hasPreDraw),\n ErP: () => (/* reexport */ has_initialize),\n aVg: () => (/* reexport */ has_postupdate),\n lPc: () => (/* reexport */ has_preupdate),\n Z8E: () => (/* reexport */ isAddedComponent),\n k15: () => (/* reexport */ isComponentCtor),\n YsU: () => (/* reexport */ isLoaderConstructor),\n lNv: () => (/* reexport */ isRemovedComponent),\n Xyg: () => (/* reexport */ isSceneConstructor),\n cu9: () => (/* reexport */ isScreenElement),\n p88: () => (/* reexport */ isSystemConstructor),\n MZQ: () => (/* reexport */ maxMessages),\n FUM: () => (/* reexport */ obsolete),\n BxR: () => (/* reexport */ pixelSnapEpsilon),\n vdf: () => (/* reexport */ randomInRange),\n iaL: () => (/* reexport */ randomIntInRange),\n w6H: () => (/* reexport */ range),\n Q4c: () => (/* reexport */ resetObsoleteCounter),\n Xxe: () => (/* reexport */ sign),\n Uxb: () => (/* reexport */ toDegrees),\n Yr5: () => (/* reexport */ toRadians),\n Bhw: () => (/* reexport */ vec),\n yOA: () => (/* reexport */ webgl_util_namespaceObject)\n});\n\n// NAMESPACE OBJECT: ./Graphics/Context/webgl-util.ts\nvar webgl_util_namespaceObject = {};\n__webpack_require__.r(webgl_util_namespaceObject);\n__webpack_require__.d(webgl_util_namespaceObject, {\n getAttributeComponentSize: () => (getAttributeComponentSize),\n getAttributePointerType: () => (getAttributePointerType),\n getGlTypeSizeBytes: () => (getGlTypeSizeBytes)\n});\n\n// NAMESPACE OBJECT: ./Events.ts\nvar Events_namespaceObject = {};\n__webpack_require__.r(Events_namespaceObject);\n__webpack_require__.d(Events_namespaceObject, {\n ActionCompleteEvent: () => (ActionCompleteEvent),\n ActionStartEvent: () => (ActionStartEvent),\n ActivateEvent: () => (ActivateEvent),\n CollisionEndEvent: () => (CollisionEndEvent),\n CollisionPostSolveEvent: () => (CollisionPostSolveEvent),\n CollisionPreSolveEvent: () => (CollisionPreSolveEvent),\n CollisionStartEvent: () => (CollisionStartEvent),\n ContactEndEvent: () => (ContactEndEvent),\n ContactStartEvent: () => (ContactStartEvent),\n DeactivateEvent: () => (DeactivateEvent),\n EnterTriggerEvent: () => (EnterTriggerEvent),\n EnterViewPortEvent: () => (EnterViewPortEvent),\n EventTypes: () => (EventTypes),\n ExitTriggerEvent: () => (ExitTriggerEvent),\n ExitViewPortEvent: () => (ExitViewPortEvent),\n GameEvent: () => (GameEvent),\n GameStartEvent: () => (GameStartEvent),\n GameStopEvent: () => (GameStopEvent),\n GamepadAxisEvent: () => (GamepadAxisEvent),\n GamepadButtonEvent: () => (GamepadButtonEvent),\n GamepadConnectEvent: () => (GamepadConnectEvent),\n GamepadDisconnectEvent: () => (GamepadDisconnectEvent),\n HiddenEvent: () => (HiddenEvent),\n InitializeEvent: () => (InitializeEvent),\n KillEvent: () => (KillEvent),\n PostCollisionEvent: () => (PostCollisionEvent),\n PostDebugDrawEvent: () => (PostDebugDrawEvent),\n PostDrawEvent: () => (PostDrawEvent),\n PostFrameEvent: () => (PostFrameEvent),\n PostKillEvent: () => (PostKillEvent),\n PostTransformDrawEvent: () => (PostTransformDrawEvent),\n PostUpdateEvent: () => (PostUpdateEvent),\n PreCollisionEvent: () => (PreCollisionEvent),\n PreDebugDrawEvent: () => (PreDebugDrawEvent),\n PreDrawEvent: () => (PreDrawEvent),\n PreFrameEvent: () => (PreFrameEvent),\n PreKillEvent: () => (PreKillEvent),\n PreTransformDrawEvent: () => (PreTransformDrawEvent),\n PreUpdateEvent: () => (PreUpdateEvent),\n VisibleEvent: () => (VisibleEvent)\n});\n\n// NAMESPACE OBJECT: ./Util/DrawUtil.ts\nvar DrawUtil_namespaceObject = {};\n__webpack_require__.r(DrawUtil_namespaceObject);\n__webpack_require__.d(DrawUtil_namespaceObject, {\n circle: () => (circle),\n line: () => (line),\n point: () => (point),\n roundRect: () => (roundRect),\n vector: () => (vector)\n});\n\n// NAMESPACE OBJECT: ./Input/Index.ts\nvar Input_Index_namespaceObject = {};\n__webpack_require__.r(Input_Index_namespaceObject);\n__webpack_require__.d(Input_Index_namespaceObject, {\n Axes: () => (Axes),\n Buttons: () => (Buttons),\n Gamepad: () => (Gamepad),\n Gamepads: () => (Gamepads),\n KeyEvent: () => (KeyEvent),\n Keyboard: () => (Keyboard),\n Keys: () => (Keys),\n NativePointerButton: () => (NativePointerButton),\n PointerButton: () => (PointerButton),\n PointerComponent: () => (PointerComponent),\n PointerEvent: () => (PointerEvent),\n PointerEventReceiver: () => (PointerEventReceiver),\n PointerScope: () => (PointerScope),\n PointerSystem: () => (PointerSystem),\n PointerType: () => (PointerType),\n WheelDeltaMode: () => (WheelDeltaMode),\n WheelEvent: () => (WheelEvent)\n});\n\n// NAMESPACE OBJECT: ./Util/Index.ts\nvar Util_Index_namespaceObject = {};\n__webpack_require__.r(Util_Index_namespaceObject);\n__webpack_require__.d(Util_Index_namespaceObject, {\n ConsoleAppender: () => (ConsoleAppender),\n DrawUtil: () => (DrawUtil_namespaceObject),\n EasingFunctions: () => (EasingFunctions),\n LogLevel: () => (LogLevel),\n Logger: () => (Logger),\n Observable: () => (Observable),\n ScreenAppender: () => (ScreenAppender),\n addItemToArray: () => (addItemToArray),\n contains: () => (contains),\n delay: () => (delay),\n fail: () => (fail),\n getPosition: () => (getPosition),\n omit: () => (omit),\n removeItemFromArray: () => (removeItemFromArray)\n});\n\n// EXTERNAL MODULE: ../../node_modules/core-js/es/array/sort.js\nvar sort = __webpack_require__(1324);\n// EXTERNAL MODULE: ../../node_modules/core-js/es/object/keys.js\nvar keys = __webpack_require__(3571);\n;// CONCATENATED MODULE: ./Polyfill.ts\n\n\n/**\n * Polyfill adding function\n */\nfunction polyfill() {\n /* istanbul ignore next */\n if (typeof window === 'undefined') {\n window = {\n audioContext: function () {\n return;\n }\n };\n }\n /* istanbul ignore next */\n if (typeof window !== 'undefined' && !window.requestAnimationFrame) {\n window.requestAnimationFrame =\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n function (callback) {\n window.setInterval(callback, 1000 / 60);\n };\n }\n /* istanbul ignore next */\n if (typeof window !== 'undefined' && !window.cancelAnimationFrame) {\n window.cancelAnimationFrame =\n window.webkitCancelAnimationFrame ||\n window.mozCancelAnimationFrame ||\n function () {\n return;\n };\n }\n /* istanbul ignore next */\n if (typeof window !== 'undefined' && !window.AudioContext) {\n if (window.webkitAudioContext) {\n const ctx = window.webkitAudioContext;\n const replaceMe = ctx.prototype.decodeAudioData;\n window.webkitAudioContext.prototype.decodeAudioData = function (arrayBuffer) {\n return new Promise((resolve, reject) => {\n replaceMe.call(this, arrayBuffer, resolve, reject);\n });\n };\n }\n window.AudioContext =\n window.AudioContext ||\n window.webkitAudioContext ||\n window.mozAudioContext ||\n window.msAudioContext ||\n window.oAudioContext;\n }\n /* istanbul ignore next */\n if (typeof window !== 'undefined' && !window.devicePixelRatio) {\n window.devicePixelRatio = window.devicePixelRatio || 1;\n }\n}\n\n;// CONCATENATED MODULE: ./Flags.ts\n/**\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\n * after which they are frozen and are read-only.\n *\n * Flags are used to enable experimental or preview features in Excalibur.\n */\nclass Flags {\n /**\n * Force excalibur to load the Canvas 2D graphics context fallback\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\n */\n static useCanvasGraphicsContext() {\n Flags.enable('use-canvas-context');\n }\n /**\n * Freeze all flag modifications making them readonly\n */\n static freeze() {\n Flags._FROZEN = true;\n }\n /**\n * Resets internal flag state, not meant to be called by users. Only used for testing.\n *\n * Calling this in your game is UNSUPPORTED\n * @internal\n */\n static _reset() {\n Flags._FROZEN = false;\n Flags._FLAGS = {};\n }\n /**\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\n * @param flagName\n */\n static enable(flagName) {\n if (this._FROZEN) {\n throw Error('Feature flags can only be enabled before Engine constructor time');\n }\n Flags._FLAGS[flagName] = true;\n }\n /**\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\n * @param flagName\n */\n static disable(flagName) {\n if (this._FROZEN) {\n throw Error('Feature flags can only be disabled before Engine constructor time');\n }\n Flags._FLAGS[flagName] = false;\n }\n /**\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\n * @param flagName\n */\n static isEnabled(flagName) {\n return !!Flags._FLAGS[flagName];\n }\n /**\n * Show a list of currently known flags\n */\n static show() {\n return Object.keys(Flags._FLAGS);\n }\n}\nFlags._FROZEN = false;\nFlags._FLAGS = {};\n\n;// CONCATENATED MODULE: ./Id.ts\n/**\n * Create a branded ID type from a number\n */\nfunction createId(type, value) {\n return { type, value };\n}\n;\n\n;// CONCATENATED MODULE: ./Util/Future.ts\n/**\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\n */\nclass Future {\n constructor() {\n this._isCompleted = false;\n this.promise = new Promise((resolve, reject) => {\n this._resolver = resolve;\n this._rejecter = reject;\n });\n }\n get isCompleted() {\n return this._isCompleted;\n }\n resolve(value) {\n if (this._isCompleted) {\n return;\n }\n this._isCompleted = true;\n this._resolver(value);\n }\n reject(error) {\n if (this._isCompleted) {\n return;\n }\n this._isCompleted = true;\n this._rejecter(error);\n }\n}\n\n;// CONCATENATED MODULE: ./EventEmitter.ts\n/**\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\n */\nclass EventEmitter {\n constructor() {\n this._paused = false;\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes = [];\n }\n clear() {\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes.length = 0;\n }\n on(eventName, handler) {\n var _a;\n this._listeners[eventName] = (_a = this._listeners[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listeners[eventName].push(handler);\n return {\n close: () => this.off(eventName, handler)\n };\n }\n once(eventName, handler) {\n var _a;\n this._listenersOnce[eventName] = (_a = this._listenersOnce[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listenersOnce[eventName].push(handler);\n return {\n close: () => this.off(eventName, handler)\n };\n }\n off(eventName, handler) {\n var _a, _b;\n if (handler) {\n const newListeners = (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.filter(h => h !== handler);\n this._listeners[eventName] = newListeners;\n const newOnceListeners = (_b = this._listenersOnce[eventName]) === null || _b === void 0 ? void 0 : _b.filter(h => h !== handler);\n this._listenersOnce[eventName] = newOnceListeners;\n }\n else {\n delete this._listeners[eventName];\n }\n }\n emit(eventName, event) {\n var _a;\n if (this._paused) {\n return;\n }\n (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.forEach((fn) => fn(event));\n const onces = this._listenersOnce[eventName];\n this._listenersOnce[eventName] = [];\n if (onces) {\n onces.forEach((fn) => fn(event));\n }\n this._pipes.forEach((pipe) => {\n pipe.emit(eventName, event);\n });\n }\n pipe(emitter) {\n if (this === emitter) {\n throw Error('Cannot pipe to self');\n }\n this._pipes.push(emitter);\n return {\n close: () => {\n const i = this._pipes.indexOf(emitter);\n if (i > -1) {\n this._pipes.splice(i, 1);\n }\n }\n };\n }\n unpipe(emitter) {\n const i = this._pipes.indexOf(emitter);\n if (i > -1) {\n this._pipes.splice(i, 1);\n }\n }\n pause() {\n this._paused = true;\n }\n unpause() {\n this._paused = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerScope.ts\n/**\n * Determines the scope of handling mouse/touch events.\n */\nvar PointerScope;\n(function (PointerScope) {\n /**\n * Handle events on the `canvas` element only. Events originating outside the\n * `canvas` will not be handled.\n */\n PointerScope[\"Canvas\"] = \"Canvas\";\n /**\n * Handles events on the entire document. All events will be handled by Excalibur.\n */\n PointerScope[\"Document\"] = \"Document\";\n})(PointerScope || (PointerScope = {}));\n\n;// CONCATENATED MODULE: ./Math/Random.ts\n/**\n * @module\n * Pseudo-Random Utility\n *\n * A pseudo-random utility to add seeded random support for help in\n * generating things like terrain or reproducible randomness. Uses the\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\n */\n/**\n * 32-bit mask\n */\nconst BITMASK32 = 0xffffffff;\n/**\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\n * of numbers each time it is called.\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\n *\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\n */\nclass Random {\n /**\n * If no seed is specified, the Date.now() is used\n */\n constructor(seed) {\n this.seed = seed;\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\n this._lowerMask = 0x7fffffff; // 31 bits same as _r\n this._upperMask = 0x80000000; // 34 high bits\n // Word size, 64 bits\n this._w = 32;\n // Degree of recurrence\n this._n = 624;\n // Middle word, an offset used in the recurrence defining the series x, 1<=m>> 0;\n for (let i = 1; i < this._n; i++) {\n const s = this._mt[i - 1] ^ (this._mt[i - 1] >>> (this._w - 2));\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\n this._mt[i] = (((this._f * ((s & 0xffff0000) >>> 16)) << 16) + this._f * (s & 0xffff) + i) >>> 0;\n }\n this._index = this._n;\n }\n /**\n * Apply the twist\n */\n _twist() {\n const mag01 = [0x0, this._a];\n let y = 0, i = 0;\n for (; i < this._n - this._m; i++) {\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\n this._mt[i] = this._mt[i + this._m] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\n }\n for (; i < this._n - 1; i++) {\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\n }\n y = (this._mt[this._n - 1] & this._upperMask) | (this._mt[0] & this._lowerMask);\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\n this._index = 0;\n }\n /**\n * Return next 32 bit integer number in sequence\n */\n nextInt() {\n if (this._index >= this._n) {\n this._twist();\n }\n let y = this._mt[this._index++];\n y ^= y >>> this._u;\n y ^= (y << this._s) & this._b;\n y ^= (y << this._t) & this._c;\n y ^= y >>> this._l;\n return y >>> 0;\n }\n /**\n * Return a random floating point number between [0, 1)\n */\n next() {\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\n }\n /**\n * Return a random floating point in range [min, max) min is included, max is not included\n */\n floating(min, max) {\n return (max - min) * this.next() + min;\n }\n /**\n * Return a random integer in range [min, max] min is included, max is included.\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\n */\n integer(min, max) {\n return Math.floor((max - min + 1) * this.next() + min);\n }\n /**\n * Returns true or false randomly with 50/50 odds by default.\n * By default the likelihood of returning a true is .5 (50%).\n * @param likelihood takes values between [0, 1]\n */\n bool(likelihood = 0.5) {\n return this.next() <= likelihood;\n }\n /**\n * Returns one element from an array at random\n */\n pickOne(array) {\n return array[this.integer(0, array.length - 1)];\n }\n /**\n * Returns a new array random picking elements from the original\n * @param array Original array to pick from\n * @param numPicks can be any positive number\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\n * just that it is possible)\n */\n pickSet(array, numPicks, allowDuplicates = false) {\n if (allowDuplicates) {\n return this._pickSetWithDuplicates(array, numPicks);\n }\n else {\n return this._pickSetWithoutDuplicates(array, numPicks);\n }\n }\n /**\n * Returns a new array randomly picking elements in the original (not reused)\n * @param array Array to pick elements out of\n * @param numPicks must be less than or equal to the number of elements in the array.\n */\n _pickSetWithoutDuplicates(array, numPicks) {\n if (numPicks > array.length || numPicks < 0) {\n throw new Error('Invalid number of elements to pick, must pick a value 0 < n <= length');\n }\n if (numPicks === array.length) {\n return array;\n }\n const result = new Array(numPicks);\n let currentPick = 0;\n const tempArray = array.slice(0);\n while (currentPick < numPicks) {\n const index = this.integer(0, tempArray.length - 1);\n result[currentPick++] = tempArray[index];\n tempArray.splice(index, 1);\n }\n return result;\n }\n /**\n * Returns a new array random picking elements from the original allowing duplicates\n * @param array Array to pick elements out of\n * @param numPicks can be any positive number\n */\n _pickSetWithDuplicates(array, numPicks) {\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\n if (numPicks < 0) {\n throw new Error('Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT');\n }\n const result = new Array(numPicks);\n for (let i = 0; i < numPicks; i++) {\n result[i] = this.pickOne(array);\n }\n return result;\n }\n /**\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\n */\n shuffle(array) {\n const tempArray = array.slice(0);\n let swap = null;\n for (let i = 0; i < tempArray.length - 2; i++) {\n const randomIndex = this.integer(i, tempArray.length - 1);\n swap = tempArray[i];\n tempArray[i] = tempArray[randomIndex];\n tempArray[randomIndex] = swap;\n }\n return tempArray;\n }\n /**\n * Generate a list of random integer numbers\n * @param length the length of the final array\n * @param min the minimum integer number to generate inclusive\n * @param max the maximum integer number to generate inclusive\n */\n range(length, min, max) {\n const result = new Array(length);\n for (let i = 0; i < length; i++) {\n result[i] = this.integer(min, max);\n }\n return result;\n }\n /**\n * Returns the result of a d4 dice roll\n */\n d4() {\n return this.integer(1, 4);\n }\n /**\n * Returns the result of a d6 dice roll\n */\n d6() {\n return this.integer(1, 6);\n }\n /**\n * Returns the result of a d8 dice roll\n */\n d8() {\n return this.integer(1, 8);\n }\n /**\n * Returns the result of a d10 dice roll\n */\n d10() {\n return this.integer(1, 10);\n }\n /**\n * Returns the result of a d12 dice roll\n */\n d12() {\n return this.integer(1, 12);\n }\n /**\n * Returns the result of a d20 dice roll\n */\n d20() {\n return this.integer(1, 20);\n }\n}\n\n;// CONCATENATED MODULE: ./Math/util.ts\n\n/**\n * Two PI constant\n */\nconst TwoPI = Math.PI * 2;\n/**\n * Returns the fractional part of a number\n * @param x\n */\nfunction frac(x) {\n if (x >= 0) {\n return x - Math.floor(x);\n }\n else {\n return x - Math.ceil(x);\n }\n}\n/**\n * Returns the sign of a number, if 0 returns 0\n */\nfunction sign(val) {\n if (val === 0) {\n return 0;\n }\n return val < 0 ? -1 : 1;\n}\n;\n/**\n * Clamps a value between a min and max inclusive\n */\nfunction clamp(val, min, max) {\n return Math.min(Math.max(min, val), max);\n}\n/**\n * Convert an angle to be the equivalent in the range [0, 2PI]\n */\nfunction canonicalizeAngle(angle) {\n let tmpAngle = angle;\n if (angle > TwoPI) {\n while (tmpAngle > TwoPI) {\n tmpAngle -= TwoPI;\n }\n }\n if (angle < 0) {\n while (tmpAngle < 0) {\n tmpAngle += TwoPI;\n }\n }\n return tmpAngle;\n}\n/**\n * Convert radians to degrees\n */\nfunction toDegrees(radians) {\n return (180 / Math.PI) * radians;\n}\n/**\n * Convert degrees to radians\n */\nfunction toRadians(degrees) {\n return (degrees / 180) * Math.PI;\n}\n/**\n * Generate a range of numbers\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\n * @param from inclusive\n * @param to inclusive\n */\nconst range = (from, to) => Array.from(new Array(to - from + 1), (_x, i) => i + from);\n/**\n * Find a random floating point number in range\n */\nfunction randomInRange(min, max, random = new Random()) {\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\n}\n/**\n * Find a random integer in a range\n */\nfunction randomIntInRange(min, max, random = new Random()) {\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\n}\n\n;// CONCATENATED MODULE: ./Math/vector.ts\n\n/**\n * A 2D vector on a plane.\n */\nclass Vector {\n /**\n * A (0, 0) vector\n */\n static get Zero() {\n return new Vector(0, 0);\n }\n /**\n * A (1, 1) vector\n */\n static get One() {\n return new Vector(1, 1);\n }\n /**\n * A (0.5, 0.5) vector\n */\n static get Half() {\n return new Vector(0.5, 0.5);\n }\n /**\n * A unit vector pointing up (0, -1)\n */\n static get Up() {\n return new Vector(0, -1);\n }\n /**\n * A unit vector pointing down (0, 1)\n */\n static get Down() {\n return new Vector(0, 1);\n }\n /**\n * A unit vector pointing left (-1, 0)\n */\n static get Left() {\n return new Vector(-1, 0);\n }\n /**\n * A unit vector pointing right (1, 0)\n */\n static get Right() {\n return new Vector(1, 0);\n }\n /**\n * Returns a vector of unit length in the direction of the specified angle in Radians.\n * @param angle The angle to generate the vector\n */\n static fromAngle(angle) {\n return new Vector(Math.cos(angle), Math.sin(angle));\n }\n /**\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\n */\n static isValid(vec) {\n if (vec === null || vec === undefined) {\n return false;\n }\n if (isNaN(vec.x) || isNaN(vec.y)) {\n return false;\n }\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) {\n return false;\n }\n return true;\n }\n /**\n * Calculates distance between two Vectors\n * @param vec1\n * @param vec2\n */\n static distance(vec1, vec2) {\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\n }\n static min(vec1, vec2) {\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\n }\n static max(vec1, vec2) {\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\n }\n /**\n * @param x X component of the Vector\n * @param y Y component of the Vector\n */\n constructor(x, y) {\n this._x = 0;\n this._y = 0;\n this._x = x;\n this._y = y;\n }\n /**\n * Get the x component of the vector\n */\n get x() {\n return this._x;\n }\n /**\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\n */\n set x(val) {\n this._x = val;\n }\n /**\n * Get the y component of the vector\n */\n get y() {\n return this._y;\n }\n /**\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\n */\n set y(val) {\n this._y = val;\n }\n /**\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\n */\n setTo(x, y) {\n this.x = x;\n this.y = y;\n }\n /**\n * Compares this point against another and tests for equality\n * @param vector The other point to compare to\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\n */\n equals(vector, tolerance = 0.001) {\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\n }\n /**\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\n * @param v The other vector. Leave blank to use origin vector.\n */\n distance(v) {\n if (!v) {\n return Math.sqrt(this.x * this.x + this.y * this.y);\n }\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n }\n squareDistance(v) {\n if (!v) {\n v = Vector.Zero;\n }\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return deltaX * deltaX + deltaY * deltaY;\n }\n /**\n * Clamps the current vector's magnitude mutating it\n * @param magnitude\n */\n clampMagnitude(magnitude) {\n const size = this.size;\n const newSize = clamp(size, 0, magnitude);\n this.size = newSize;\n return this;\n }\n /**\n * The size (magnitude) of the Vector\n */\n get size() {\n return this.distance();\n }\n /**\n * Setting the size mutates the current vector\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\n */\n set size(newLength) {\n const v = this.normalize().scale(newLength);\n this.setTo(v.x, v.y);\n }\n /**\n * Normalizes a vector to have a magnitude of 1.\n */\n normalize() {\n const d = this.distance();\n if (d > 0) {\n return new Vector(this.x / d, this.y / d);\n }\n else {\n return new Vector(0, 1);\n }\n }\n /**\n * Returns the average (midpoint) between the current point and the specified\n */\n average(vec) {\n return this.add(vec).scale(0.5);\n }\n scale(sizeOrScale, dest) {\n const result = dest || new Vector(0, 0);\n if (sizeOrScale instanceof Vector) {\n result.x = this.x * sizeOrScale.x;\n result.y = this.y * sizeOrScale.y;\n }\n else {\n result.x = this.x * sizeOrScale;\n result.y = this.y * sizeOrScale;\n }\n return result;\n }\n /**\n * Adds one vector to another\n * @param v The vector to add\n * @param dest Optionally copy the result into a provided vector\n */\n add(v, dest) {\n if (dest) {\n dest.x = this.x + v.x;\n dest.y = this.y + v.y;\n return dest;\n }\n return new Vector(this.x + v.x, this.y + v.y);\n }\n /**\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\n * @param v The vector to subtract\n */\n sub(v) {\n return new Vector(this.x - v.x, this.y - v.y);\n }\n /**\n * Adds one vector to this one modifying the original\n * @param v The vector to add\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */\n addEqual(v) {\n this.setTo(this.x + v.x, this.y + v.y);\n return this;\n }\n /**\n * Subtracts a vector from this one modifying the original\n * @param v The vector to subtract\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */\n subEqual(v) {\n this.setTo(this.x - v.x, this.y - v.y);\n return this;\n }\n /**\n * Scales this vector by a factor of size and modifies the original\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */\n scaleEqual(size) {\n this.setTo(this.x * size, this.y * size);\n return this;\n }\n /**\n * Performs a dot product with another vector\n * @param v The vector to dot\n */\n dot(v) {\n return this.x * v.x + this.y * v.y;\n }\n cross(v) {\n if (v instanceof Vector) {\n return this.x * v.y - this.y * v.x;\n }\n else if (typeof v === 'number') {\n return new Vector(v * this.y, -v * this.x);\n }\n }\n static cross(num, vec) {\n return new Vector(-num * vec.y, num * vec.x);\n }\n /**\n * Returns the perpendicular vector to this one\n */\n perpendicular() {\n return new Vector(this.y, -this.x);\n }\n /**\n * Returns the normal vector to this one, same as the perpendicular of length 1\n */\n normal() {\n return this.perpendicular().normalize();\n }\n /**\n * Negate the current vector\n */\n negate() {\n return this.scale(-1);\n }\n /**\n * Returns the angle of this vector.\n */\n toAngle() {\n return Math.atan2(this.y, this.x);\n }\n /**\n * Rotates the current vector around a point by a certain number of\n * degrees in radians\n */\n rotate(angle, anchor) {\n if (!anchor) {\n anchor = new Vector(0, 0);\n }\n const sinAngle = Math.sin(angle);\n const cosAngle = Math.cos(angle);\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\n return new Vector(x, y);\n }\n /**\n * Creates new vector that has the same values as the previous.\n */\n clone(dest) {\n const v = dest !== null && dest !== void 0 ? dest : new Vector(0, 0);\n v.x = this.x;\n v.y = this.y;\n return v;\n }\n /**\n * Returns a string representation of the vector.\n */\n toString(fixed) {\n if (fixed) {\n return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\n }\n return `(${this.x}, ${this.y})`;\n }\n}\n/**\n * Shorthand for creating new Vectors - returns a new Vector instance with the\n * provided X and Y components.\n * @param x X component of the Vector\n * @param y Y component of the Vector\n */\nfunction vec(x, y) {\n return new Vector(x, y);\n}\n\n;// CONCATENATED MODULE: ./Color.ts\n/**\n * Provides standard colors (e.g. [[Color.Black]])\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\n */\nclass Color {\n /**\n * Creates a new instance of Color from an r, g, b, a\n * @param r The red component of color (0-255)\n * @param g The green component of color (0-255)\n * @param b The blue component of color (0-255)\n * @param a The alpha component of color (0-1.0)\n */\n constructor(r, g, b, a) {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a != null ? a : 1;\n }\n /**\n * Creates a new instance of Color from an r, g, b, a\n * @param r The red component of color (0-255)\n * @param g The green component of color (0-255)\n * @param b The blue component of color (0-255)\n * @param a The alpha component of color (0-1.0)\n */\n static fromRGB(r, g, b, a) {\n return new Color(r, g, b, a);\n }\n /**\n * Creates a new instance of Color from a rgb string\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\n */\n static fromRGBString(string) {\n const rgbaRegEx = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\n let match = null;\n if ((match = string.match(rgbaRegEx))) {\n const r = parseInt(match[1], 10);\n const g = parseInt(match[2], 10);\n const b = parseInt(match[3], 10);\n let a = 1;\n if (match[4]) {\n a = parseFloat(match[4]);\n }\n return new Color(r, g, b, a);\n }\n else {\n throw new Error('Invalid rgb/a string: ' + string);\n }\n }\n /**\n * Creates a new instance of Color from a hex string\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\n */\n static fromHex(hex) {\n const hexRegEx = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\n let match = null;\n if ((match = hex.match(hexRegEx))) {\n const r = parseInt(match[1], 16);\n const g = parseInt(match[2], 16);\n const b = parseInt(match[3], 16);\n let a = 1;\n if (match[4]) {\n a = parseInt(match[4], 16) / 255;\n }\n return new Color(r, g, b, a);\n }\n else {\n throw new Error('Invalid hex string: ' + hex);\n }\n }\n /**\n * Creates a new instance of Color from hsla values\n * @param h Hue is represented [0-1]\n * @param s Saturation is represented [0-1]\n * @param l Luminance is represented [0-1]\n * @param a Alpha is represented [0-1]\n */\n static fromHSL(h, s, l, a = 1.0) {\n const temp = new HSLColor(h, s, l, a);\n return temp.toRGBA();\n }\n /**\n * Lightens the current color by a specified amount\n * @param factor The amount to lighten by [0-1]\n */\n lighten(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l += (1 - temp.l) * factor;\n return temp.toRGBA();\n }\n /**\n * Darkens the current color by a specified amount\n * @param factor The amount to darken by [0-1]\n */\n darken(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l -= temp.l * factor;\n return temp.toRGBA();\n }\n /**\n * Saturates the current color by a specified amount\n * @param factor The amount to saturate by [0-1]\n */\n saturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s += temp.s * factor;\n return temp.toRGBA();\n }\n /**\n * Desaturates the current color by a specified amount\n * @param factor The amount to desaturate by [0-1]\n */\n desaturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s -= temp.s * factor;\n return temp.toRGBA();\n }\n /**\n * Multiplies a color by another, results in a darker color\n * @param color The other color\n */\n multiply(color) {\n const newR = (((color.r / 255) * this.r) / 255) * 255;\n const newG = (((color.g / 255) * this.g) / 255) * 255;\n const newB = (((color.b / 255) * this.b) / 255) * 255;\n const newA = color.a * this.a;\n return new Color(newR, newG, newB, newA);\n }\n /**\n * Screens a color by another, results in a lighter color\n * @param color The other color\n */\n screen(color) {\n const color1 = color.invert();\n const color2 = color.invert();\n return color1.multiply(color2).invert();\n }\n /**\n * Inverts the current color\n */\n invert() {\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\n }\n /**\n * Averages the current color with another\n * @param color The other color\n */\n average(color) {\n const newR = (color.r + this.r) / 2;\n const newG = (color.g + this.g) / 2;\n const newB = (color.b + this.b) / 2;\n const newA = (color.a + this.a) / 2;\n return new Color(newR, newG, newB, newA);\n }\n equal(color) {\n return this.toString() === color.toString();\n }\n /**\n * Returns a CSS string representation of a color.\n * @param format Color representation, accepts: rgb, hsl, or hex\n */\n toString(format = 'rgb') {\n switch (format) {\n case 'rgb':\n return this.toRGBA();\n case 'hsl':\n return this.toHSLA();\n case 'hex':\n return this.toHex();\n default:\n throw new Error('Invalid Color format');\n }\n }\n /**\n * Returns Hex Value of a color component\n * @param c color component\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\n */\n _componentToHex(c) {\n const hex = c.toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n }\n /**\n * Return Hex representation of a color.\n */\n toHex() {\n return '#' + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\n }\n /**\n * Return RGBA representation of a color.\n */\n toRGBA() {\n const result = String(this.r.toFixed(0)) + ', ' + String(this.g.toFixed(0)) + ', ' + String(this.b.toFixed(0));\n if (this.a !== undefined || this.a !== null) {\n return 'rgba(' + result + ', ' + String(this.a) + ')';\n }\n return 'rgb(' + result + ')';\n }\n /**\n * Return HSLA representation of a color.\n */\n toHSLA() {\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\n }\n /**\n * Returns a CSS string representation of a color.\n */\n fillStyle() {\n return this.toString();\n }\n /**\n * Returns a clone of the current color.\n */\n clone() {\n return new Color(this.r, this.g, this.b, this.a);\n }\n /**\n * Black (#000000)\n */\n static get Black() {\n return Color.fromHex('#000000');\n }\n /**\n * White (#FFFFFF)\n */\n static get White() {\n return Color.fromHex('#FFFFFF');\n }\n /**\n * Gray (#808080)\n */\n static get Gray() {\n return Color.fromHex('#808080');\n }\n /**\n * Light gray (#D3D3D3)\n */\n static get LightGray() {\n return Color.fromHex('#D3D3D3');\n }\n /**\n * Dark gray (#A9A9A9)\n */\n static get DarkGray() {\n return Color.fromHex('#A9A9A9');\n }\n /**\n * Yellow (#FFFF00)\n */\n static get Yellow() {\n return Color.fromHex('#FFFF00');\n }\n /**\n * Orange (#FFA500)\n */\n static get Orange() {\n return Color.fromHex('#FFA500');\n }\n /**\n * Red (#FF0000)\n */\n static get Red() {\n return Color.fromHex('#FF0000');\n }\n /**\n * Vermilion (#FF5B31)\n */\n static get Vermilion() {\n return Color.fromHex('#FF5B31');\n }\n /**\n * Rose (#FF007F)\n */\n static get Rose() {\n return Color.fromHex('#FF007F');\n }\n /**\n * Magenta (#FF00FF)\n */\n static get Magenta() {\n return Color.fromHex('#FF00FF');\n }\n /**\n * Violet (#7F00FF)\n */\n static get Violet() {\n return Color.fromHex('#7F00FF');\n }\n /**\n * Blue (#0000FF)\n */\n static get Blue() {\n return Color.fromHex('#0000FF');\n }\n /**\n * Azure (#007FFF)\n */\n static get Azure() {\n return Color.fromHex('#007FFF');\n }\n /**\n * Cyan (#00FFFF)\n */\n static get Cyan() {\n return Color.fromHex('#00FFFF');\n }\n /**\n * Viridian (#59978F)\n */\n static get Viridian() {\n return Color.fromHex('#59978F');\n }\n /**\n * Green (#00FF00)\n */\n static get Green() {\n return Color.fromHex('#00FF00');\n }\n /**\n * Chartreuse (#7FFF00)\n */\n static get Chartreuse() {\n return Color.fromHex('#7FFF00');\n }\n /**\n * Transparent (#FFFFFF00)\n */\n static get Transparent() {\n return Color.fromHex('#FFFFFF00');\n }\n /**\n * ExcaliburBlue (#176BAA)\n */\n static get ExcaliburBlue() {\n return Color.fromHex('#176BAA');\n }\n}\n/**\n * Internal HSL Color representation\n *\n * http://en.wikipedia.org/wiki/HSL_and_HSV\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\n */\nclass HSLColor {\n constructor(h, s, l, a) {\n this.h = h;\n this.s = s;\n this.l = l;\n this.a = a;\n }\n static hue2rgb(p, q, t) {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n }\n static fromRGBA(r, g, b, a) {\n r /= 255;\n g /= 255;\n b /= 255;\n const max = Math.max(r, g, b), min = Math.min(r, g, b);\n let h, s;\n const l = (max + min) / 2;\n if (max === min) {\n h = s = 0; // achromatic\n }\n else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n return new HSLColor(h, s, l, a);\n }\n toRGBA() {\n let r, g, b;\n if (this.s === 0) {\n r = g = b = this.l; // achromatic\n }\n else {\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\n const p = 2 * this.l - q;\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\n g = HSLColor.hue2rgb(p, q, this.h);\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\n }\n return new Color(r * 255, g * 255, b * 255, this.a);\n }\n toString() {\n const h = this.h.toFixed(0), s = this.s.toFixed(0), l = this.l.toFixed(0), a = this.a.toFixed(0);\n return `hsla(${h}, ${s}, ${l}, ${a})`;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Log.ts\n/* eslint-disable no-console */\n\n\n/**\n * Logging level that Excalibur will tag\n */\nvar LogLevel;\n(function (LogLevel) {\n LogLevel[LogLevel[\"Debug\"] = 0] = \"Debug\";\n LogLevel[LogLevel[\"Info\"] = 1] = \"Info\";\n LogLevel[LogLevel[\"Warn\"] = 2] = \"Warn\";\n LogLevel[LogLevel[\"Error\"] = 3] = \"Error\";\n LogLevel[LogLevel[\"Fatal\"] = 4] = \"Fatal\";\n})(LogLevel || (LogLevel = {}));\n/**\n * Static singleton that represents the logging facility for Excalibur.\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\n * Derive from [[Appender]] to create your own logging appenders.\n */\nclass Logger {\n constructor() {\n this._appenders = [];\n /**\n * Gets or sets the default logging level. Excalibur will only log\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\n */\n this.defaultLevel = LogLevel.Info;\n this._logOnceSet = new Set();\n if (Logger._INSTANCE) {\n throw new Error('Logger is a singleton');\n }\n Logger._INSTANCE = this;\n // Default console appender\n Logger._INSTANCE.addAppender(new ConsoleAppender());\n return Logger._INSTANCE;\n }\n /**\n * Gets the current static instance of Logger\n */\n static getInstance() {\n if (Logger._INSTANCE == null) {\n Logger._INSTANCE = new Logger();\n }\n return Logger._INSTANCE;\n }\n /**\n * Adds a new [[Appender]] to the list of appenders to write to\n */\n addAppender(appender) {\n this._appenders.push(appender);\n }\n /**\n * Clears all appenders from the logger\n */\n clearAppenders() {\n this._appenders.length = 0;\n }\n /**\n * Logs a message at a given LogLevel\n * @param level The LogLevel`to log the message at\n * @param args An array of arguments to write to an appender\n */\n _log(level, args) {\n if (level == null) {\n level = this.defaultLevel;\n }\n const len = this._appenders.length;\n for (let i = 0; i < len; i++) {\n if (level >= this.defaultLevel) {\n this._appenders[i].log(level, args);\n }\n }\n }\n _logOnce(level, args) {\n const serialized = level + args.join('+');\n if (this._logOnceSet.has(serialized)) {\n return;\n }\n else {\n this._logOnceSet.add(serialized);\n this._log(level, args);\n }\n }\n /**\n * Writes a log message at the [[LogLevel.Debug]] level\n * @param args Accepts any number of arguments\n */\n debug(...args) {\n this._log(LogLevel.Debug, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it wont log\n * @param args Accepts any number of arguments\n */\n debugOnce(...args) {\n this._logOnce(LogLevel.Debug, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Info]] level\n * @param args Accepts any number of arguments\n */\n info(...args) {\n this._log(LogLevel.Info, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Info]] level, if it sees the same args again it wont log\n * @param args Accepts any number of arguments\n */\n infoOnce(...args) {\n this._logOnce(LogLevel.Info, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Warn]] level\n * @param args Accepts any number of arguments\n */\n warn(...args) {\n this._log(LogLevel.Warn, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Warn]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */\n warnOnce(...args) {\n this._logOnce(LogLevel.Warn, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Error]] level\n * @param args Accepts any number of arguments\n */\n error(...args) {\n this._log(LogLevel.Error, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Error]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */\n errorOnce(...args) {\n this._logOnce(LogLevel.Error, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Fatal]] level\n * @param args Accepts any number of arguments\n */\n fatal(...args) {\n this._log(LogLevel.Fatal, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */\n fatalOnce(...args) {\n this._logOnce(LogLevel.Fatal, args);\n }\n}\nLogger._INSTANCE = null;\n/**\n * Console appender for browsers (i.e. `console.log`)\n */\nclass ConsoleAppender {\n /**\n * Logs a message at the given [[LogLevel]]\n * @param level Level to log at\n * @param args Arguments to log\n */\n log(level, args) {\n // Check for console support\n if (!console && !console.log && console.warn && console.error) {\n // todo maybe do something better than nothing\n return;\n }\n // Create a new console args array\n const consoleArgs = [];\n consoleArgs.unshift.apply(consoleArgs, args);\n consoleArgs.unshift('[' + LogLevel[level] + '] : ');\n if (level < LogLevel.Warn) {\n // Call .log for Debug/Info\n if (console.log.apply) {\n // this is required on some older browsers that don't support apply on console.log :(\n console.log.apply(console, consoleArgs);\n }\n else {\n console.log(consoleArgs.join(' '));\n }\n }\n else if (level < LogLevel.Error) {\n // Call .warn for Warn\n if (console.warn.apply) {\n console.warn.apply(console, consoleArgs);\n }\n else {\n console.warn(consoleArgs.join(' '));\n }\n }\n else {\n // Call .error for Error/Fatal\n if (console.error.apply) {\n console.error.apply(console, consoleArgs);\n }\n else {\n console.error(consoleArgs.join(' '));\n }\n }\n }\n}\n/**\n * On-screen (canvas) appender\n */\nclass ScreenAppender {\n constructor(options) {\n var _a, _b;\n this._messages = [];\n this._pos = 10;\n this._color = Color.Black;\n this._options = options;\n this.canvas = document.createElement('canvas');\n this._ctx = this.canvas.getContext('2d');\n this.canvas.style.position = 'absolute';\n this.canvas.style.zIndex = (_b = (_a = options.zIndex) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '99';\n document.body.appendChild(this.canvas);\n this._positionScreenAppenderCanvas();\n options.engine.screen.events.on('resize', () => {\n this._positionScreenAppenderCanvas();\n });\n }\n _positionScreenAppenderCanvas() {\n var _a, _b, _c, _d;\n const options = this._options;\n this.canvas.width = (_a = options.width) !== null && _a !== void 0 ? _a : options.engine.screen.resolution.width;\n this.canvas.height = (_b = options.height) !== null && _b !== void 0 ? _b : options.engine.screen.resolution.height;\n this.canvas.style.position = 'absolute';\n const pagePos = options.engine.screen.screenToPageCoordinates(vec(0, 0));\n this.canvas.style.left = pagePos.x + 'px';\n this.canvas.style.top = pagePos.y + 'px';\n this._pos = (_c = options.xPos) !== null && _c !== void 0 ? _c : this._pos;\n this._color = (_d = options.color) !== null && _d !== void 0 ? _d : this._color;\n }\n /**\n * Logs a message at the given [[LogLevel]]\n * @param level Level to log at\n * @param args Arguments to log\n */\n log(level, args) {\n const message = args.join(',');\n this._ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this._messages.unshift('[' + LogLevel[level] + '] : ' + message);\n let pos = 10;\n this._messages = this._messages.slice(0, 1000);\n for (let i = 0; i < this._messages.length; i++) {\n this._ctx.fillStyle = this._color.toRGBA();\n this._ctx.fillText(this._messages[i], this._pos, pos);\n pos += 10;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Side.ts\n\n/**\n * An enum that describes the sides of an axis aligned box for collision\n */\nvar Side;\n(function (Side) {\n Side[\"None\"] = \"None\";\n Side[\"Top\"] = \"Top\";\n Side[\"Bottom\"] = \"Bottom\";\n Side[\"Left\"] = \"Left\";\n Side[\"Right\"] = \"Right\";\n})(Side || (Side = {}));\n(function (Side) {\n /**\n * Returns the opposite side from the current\n */\n function getOpposite(side) {\n if (side === Side.Top) {\n return Side.Bottom;\n }\n if (side === Side.Bottom) {\n return Side.Top;\n }\n if (side === Side.Left) {\n return Side.Right;\n }\n if (side === Side.Right) {\n return Side.Left;\n }\n return Side.None;\n }\n Side.getOpposite = getOpposite;\n /**\n * Given a vector, return the Side most in that direction (via dot product)\n */\n function fromDirection(direction) {\n const directions = [Vector.Left, Vector.Right, Vector.Up, Vector.Down];\n const directionEnum = [Side.Left, Side.Right, Side.Top, Side.Bottom];\n let max = -Number.MAX_VALUE;\n let maxIndex = -1;\n for (let i = 0; i < directions.length; i++) {\n if (directions[i].dot(direction) > max) {\n max = directions[i].dot(direction);\n maxIndex = i;\n }\n }\n return directionEnum[maxIndex];\n }\n Side.fromDirection = fromDirection;\n})(Side || (Side = {}));\n\n;// CONCATENATED MODULE: ./Collision/BoundingBox.ts\n\n\n\n/**\n * Axis Aligned collision primitive for Excalibur.\n */\nclass BoundingBox {\n /**\n * Constructor allows passing of either an object with all coordinate components,\n * or the coordinate components passed separately.\n * @param leftOrOptions Either x coordinate of the left edge or an options object\n * containing the four coordinate components.\n * @param top y coordinate of the top edge\n * @param right x coordinate of the right edge\n * @param bottom y coordinate of the bottom edge\n */\n constructor(leftOrOptions = 0, top = 0, right = 0, bottom = 0) {\n // Cache bounding box point returns\n this._points = [];\n if (typeof leftOrOptions === 'object') {\n this.left = leftOrOptions.left;\n this.top = leftOrOptions.top;\n this.right = leftOrOptions.right;\n this.bottom = leftOrOptions.bottom;\n }\n else if (typeof leftOrOptions === 'number') {\n this.left = leftOrOptions;\n this.top = top;\n this.right = right;\n this.bottom = bottom;\n }\n }\n /**\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\n */\n clone() {\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\n }\n /**\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\n * @param intersection Intersection vector between 2 bounding boxes\n */\n static getSideFromIntersection(intersection) {\n if (!intersection) {\n return Side.None;\n }\n if (intersection) {\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\n if (intersection.x < 0) {\n return Side.Right;\n }\n return Side.Left;\n }\n else {\n if (intersection.y < 0) {\n return Side.Bottom;\n }\n return Side.Top;\n }\n }\n return Side.None;\n }\n static fromPoints(points) {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < points.length; i++) {\n if (points[i].x < minX) {\n minX = points[i].x;\n }\n if (points[i].x > maxX) {\n maxX = points[i].x;\n }\n if (points[i].y < minY) {\n minY = points[i].y;\n }\n if (points[i].y > maxY) {\n maxY = points[i].y;\n }\n }\n return new BoundingBox(minX, minY, maxX, maxY);\n }\n /**\n * Creates a bounding box from a width and height\n * @param width\n * @param height\n * @param anchor Default Vector.Half\n * @param pos Default Vector.Zero\n */\n static fromDimension(width, height, anchor = Vector.Half, pos = Vector.Zero) {\n return new BoundingBox(-width * anchor.x + pos.x, -height * anchor.y + pos.y, width - width * anchor.x + pos.x, height - height * anchor.y + pos.y);\n }\n /**\n * Returns the calculated width of the bounding box\n */\n get width() {\n return this.right - this.left;\n }\n /**\n * Returns the calculated height of the bounding box\n */\n get height() {\n return this.bottom - this.top;\n }\n /**\n * Return whether the bounding box has zero dimensions in height,width or both\n */\n hasZeroDimensions() {\n return this.width === 0 || this.height === 0;\n }\n /**\n * Returns the center of the bounding box\n */\n get center() {\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\n }\n get topLeft() {\n return new Vector(this.left, this.top);\n }\n get bottomRight() {\n return new Vector(this.right, this.bottom);\n }\n get topRight() {\n return new Vector(this.right, this.top);\n }\n get bottomLeft() {\n return new Vector(this.left, this.bottom);\n }\n translate(pos) {\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\n }\n /**\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\n */\n rotate(angle, point = Vector.Zero) {\n const points = this.getPoints().map((p) => p.rotate(angle, point));\n return BoundingBox.fromPoints(points);\n }\n /**\n * Scale a bounding box by a scale factor, optionally provide a point\n * @param scale\n * @param point\n */\n scale(scale, point = Vector.Zero) {\n const shifted = this.translate(point);\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\n }\n /**\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\n * @param matrix\n */\n transform(matrix) {\n // inlined these calculations to not use vectors would speed it up slightly\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\n // const xa = matFirstColumn.scale(this.left);\n const xa1 = matrix.data[0] * this.left;\n const xa2 = matrix.data[1] * this.left;\n // const xb = matFirstColumn.scale(this.right);\n const xb1 = matrix.data[0] * this.right;\n const xb2 = matrix.data[1] * this.right;\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\n // const ya = matSecondColumn.scale(this.top);\n const ya1 = matrix.data[2] * this.top;\n const ya2 = matrix.data[3] * this.top;\n // const yb = matSecondColumn.scale(this.bottom);\n const yb1 = matrix.data[2] * this.bottom;\n const yb2 = matrix.data[3] * this.bottom;\n const matrixPos = matrix.getPosition();\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\n return new BoundingBox({\n left, //: topLeft.x,\n top, //: topLeft.y,\n right, //: bottomRight.x,\n bottom //: bottomRight.y\n });\n }\n /**\n * Returns the perimeter of the bounding box\n */\n getPerimeter() {\n const wx = this.width;\n const wy = this.height;\n return 2 * (wx + wy);\n }\n /**\n * Returns the world space points that make up the corners of the bounding box as a polygon\n */\n getPoints() {\n if (this._left !== this.left ||\n this._right !== this.right ||\n this._top !== this.top ||\n this._bottom !== this.bottom) {\n this._points.length = 0;\n this._points.push(new Vector(this.left, this.top));\n this._points.push(new Vector(this.right, this.top));\n this._points.push(new Vector(this.right, this.bottom));\n this._points.push(new Vector(this.left, this.bottom));\n this._left = this.left;\n this._right = this.right;\n this._top = this.top;\n this._bottom = this.bottom;\n }\n return this._points;\n }\n /**\n * Determines whether a ray intersects with a bounding box\n */\n rayCast(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = +Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\n }\n rayCastTime(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = +Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) {\n return tmin;\n }\n return -1;\n }\n contains(val) {\n if (val instanceof Vector) {\n return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\n }\n else if (val instanceof BoundingBox) {\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) {\n return true;\n }\n return false;\n }\n return false;\n }\n /**\n * Combines this bounding box and another together returning a new bounding box\n * @param other The bounding box to combine\n */\n combine(other) {\n const compositeBB = new BoundingBox(Math.min(this.left, other.left), Math.min(this.top, other.top), Math.max(this.right, other.right), Math.max(this.bottom, other.bottom));\n return compositeBB;\n }\n get dimensions() {\n return new Vector(this.width, this.height);\n }\n /**\n * Returns true if the bounding boxes overlap.\n * @param other\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\n * This epsilon is useful in stable collision simulations.\n */\n overlaps(other, epsilon) {\n const e = epsilon || 0;\n if (other.hasZeroDimensions()) {\n return this.contains(other);\n }\n if (this.hasZeroDimensions()) {\n return other.contains(this);\n }\n const totalBoundingBox = this.combine(other);\n return totalBoundingBox.width + e < other.width + this.width &&\n totalBoundingBox.height + e < other.height + this.height;\n }\n /**\n * Test wether this bounding box intersects with another returning\n * the intersection vector that can be used to resolve the collision. If there\n * is no intersection null is returned.\n * @param other Other [[BoundingBox]] to test intersection with\n * @returns A Vector in the direction of the current BoundingBox, this <- other\n */\n intersect(other) {\n const totalBoundingBox = this.combine(other);\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\n if (totalBoundingBox.width < other.width + this.width &&\n totalBoundingBox.height < other.height + this.height &&\n !totalBoundingBox.dimensions.equals(other.dimensions) &&\n !totalBoundingBox.dimensions.equals(this.dimensions)) {\n // collision\n let overlapX = 0;\n // right edge is between the other's left and right edge\n /**\n * +-this-+\n * | |\n * | +-other-+\n * +----|-+ |\n * | |\n * +-------+\n * <---\n * ^ overlap\n */\n if (this.right >= other.left && this.right <= other.right) {\n overlapX = other.left - this.right;\n // right edge is past the other's right edge\n /**\n * +-other-+\n * | |\n * | +-this-+\n * +----|--+ |\n * | |\n * +------+\n * --->\n * ^ overlap\n */\n }\n else {\n overlapX = other.right - this.left;\n }\n let overlapY = 0;\n // top edge is between the other's top and bottom edge\n /**\n * +-other-+\n * | |\n * | +-this-+ | <- overlap\n * +----|--+ | |\n * | | \\ /\n * +------+ '\n */\n if (this.top <= other.bottom && this.top >= other.top) {\n overlapY = other.bottom - this.top;\n // top edge is above the other top edge\n /**\n * +-this-+ .\n * | | / \\\n * | +-other-+ | <- overlap\n * +----|-+ | |\n * | |\n * +-------+\n */\n }\n else {\n overlapY = other.top - this.bottom;\n }\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\n return new Vector(overlapX, 0);\n }\n else {\n return new Vector(0, overlapY);\n }\n // Case of total containment of one bounding box by another\n }\n else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\n let overlapX = 0;\n // this is wider than the other\n if (this.width - other.width >= 0) {\n // This right edge is closest to the others right edge\n if (this.right - other.right <= other.left - this.left) {\n overlapX = other.left - this.right;\n // This left edge is closest to the others left edge\n }\n else {\n overlapX = other.right - this.left;\n }\n // other is wider than this\n }\n else {\n // This right edge is closest to the others right edge\n if (other.right - this.right <= this.left - other.left) {\n overlapX = this.left - other.right;\n // This left edge is closest to the others left edge\n }\n else {\n overlapX = this.right - other.left;\n }\n }\n let overlapY = 0;\n // this is taller than other\n if (this.height - other.height >= 0) {\n // The bottom edge is closest to the others bottom edge\n if (this.bottom - other.bottom <= other.top - this.top) {\n overlapY = other.top - this.bottom;\n }\n else {\n overlapY = other.bottom - this.top;\n }\n // other is taller than this\n }\n else {\n // The bottom edge is closest to the others bottom edge\n if (other.bottom - this.bottom <= this.top - other.top) {\n overlapY = this.top - other.bottom;\n }\n else {\n overlapY = this.bottom - other.top;\n }\n }\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\n return new Vector(overlapX, 0);\n }\n else {\n return new Vector(0, overlapY);\n }\n }\n else {\n return null;\n }\n }\n /**\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\n * @param bb The other actor to test\n */\n intersectWithSide(bb) {\n const intersect = this.intersect(bb);\n return BoundingBox.getSideFromIntersection(intersect);\n }\n /**\n * Draw a debug bounding box\n * @param ex\n * @param color\n */\n draw(ex, color = Color.Yellow) {\n ex.debug.drawRect(this.left, this.top, this.width, this.height, { color });\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Util.ts\n\n\n/**\n * Find the screen position of an HTML element\n */\nfunction getPosition(el) {\n // do we need the scroll too? technically the offset method before did that\n const rect = el.getBoundingClientRect();\n return vec(rect.x + window.scrollX, rect.y + window.scrollY);\n}\n/**\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\n * @deprecated Will be removed in v0.26.0\n */\nfunction addItemToArray(item, array) {\n if (array.indexOf(item) === -1) {\n array.push(item);\n return true;\n }\n return false;\n}\n/**\n * Remove an item from an list\n * @deprecated Will be removed in v0.26.0\n */\nfunction removeItemFromArray(item, array) {\n let index = -1;\n if ((index = array.indexOf(item)) > -1) {\n array.splice(index, 1);\n return true;\n }\n return false;\n}\n/**\n * See if an array contains something\n */\nfunction contains(array, obj) {\n for (let i = 0; i < array.length; i++) {\n if (array[i] === obj) {\n return true;\n }\n }\n return false;\n}\n/**\n * Used for exhaustive checks at compile time\n */\nfunction fail(message) {\n throw new Error(message);\n}\n/**\n * Create a promise that resolves after a certain number of milliseconds\n *\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\n * excalibur clock which would be unaffected by stop/pause.\n * @param milliseconds\n * @param clock\n */\nfunction delay(milliseconds, clock) {\n var _a;\n const future = new Future();\n const schedule = (_a = clock === null || clock === void 0 ? void 0 : clock.schedule.bind(clock)) !== null && _a !== void 0 ? _a : setTimeout;\n schedule(() => {\n future.resolve();\n }, milliseconds);\n return future.promise;\n}\n/**\n * Remove keys from object literals\n * @param object\n * @param keys\n */\nfunction omit(object, keys) {\n const newObj = {};\n for (const key in object) {\n if (!keys.includes(key)) {\n newObj[key] = object[key];\n }\n }\n return newObj;\n}\n\n;// CONCATENATED MODULE: ./Math/matrix.ts\n\n\n\nvar MatrixLocations;\n(function (MatrixLocations) {\n MatrixLocations[MatrixLocations[\"X\"] = 12] = \"X\";\n MatrixLocations[MatrixLocations[\"Y\"] = 13] = \"Y\";\n})(MatrixLocations || (MatrixLocations = {}));\n/**\n * Excalibur Matrix helper for 4x4 matrices\n *\n * Useful for webgl 4x4 matrices\n */\nclass Matrix {\n constructor() {\n /**\n * 4x4 matrix in column major order\n *\n * | | | | |\n * | ------- | ------- | -------- | -------- |\n * | data[0] | data[4] | data[8] | data[12] |\n * | data[1] | data[5] | data[9] | data[13] |\n * | data[2] | data[6] | data[10] | data[14] |\n * | data[3] | data[7] | data[11] | data[15] |\n *\n */\n this.data = new Float32Array(16);\n this._scaleX = 1;\n this._scaleSignX = 1;\n this._scaleY = 1;\n this._scaleSignY = 1;\n }\n /**\n * Creates an orthographic (flat non-perspective) projection\n * https://en.wikipedia.org/wiki/Orthographic_projection\n * @param left\n * @param right\n * @param bottom\n * @param top\n * @param near\n * @param far\n */\n static ortho(left, right, bottom, top, near, far) {\n const mat = new Matrix();\n mat.data[0] = 2 / (right - left);\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 2 / (top - bottom);\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = -2 / (far - near);\n mat.data[11] = 0;\n mat.data[12] = -(right + left) / (right - left);\n mat.data[13] = -(top + bottom) / (top - bottom);\n mat.data[14] = -(far + near) / (far - near);\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a new Matrix with the same data as the current 4x4\n */\n clone(dest) {\n const mat = dest || new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n mat.data[6] = this.data[6];\n mat.data[7] = this.data[7];\n mat.data[8] = this.data[8];\n mat.data[9] = this.data[9];\n mat.data[10] = this.data[10];\n mat.data[11] = this.data[11];\n mat.data[12] = this.data[12];\n mat.data[13] = this.data[13];\n mat.data[14] = this.data[14];\n mat.data[15] = this.data[15];\n return mat;\n }\n /**\n * Converts the current matrix into a DOMMatrix\n *\n * This is useful when working with the browser Canvas context\n * @returns {DOMMatrix} DOMMatrix\n */\n toDOMMatrix() {\n return new DOMMatrix([...this.data]);\n }\n static fromFloat32Array(data) {\n const matrix = new Matrix();\n matrix.data = data;\n return matrix;\n }\n /**\n * Creates a new identity matrix (a matrix that when applied does nothing)\n */\n static identity() {\n const mat = new Matrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Resets the current matrix to the identity matrix, mutating it\n * @returns {Matrix} Current matrix as identity\n */\n reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a brand new translation matrix at the specified 3d point\n * @param x\n * @param y\n */\n static translation(x, y) {\n const mat = Matrix.identity();\n mat.data[12] = x;\n mat.data[13] = y;\n return mat;\n }\n /**\n * Creates a brand new scaling matrix with the specified scaling factor\n * @param sx\n * @param sy\n */\n static scale(sx, sy) {\n const mat = Matrix.identity();\n mat.data[0] = sx;\n mat.data[5] = sy;\n mat.data[10] = 1;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a brand new rotation matrix with the specified angle\n * @param angleRadians\n */\n static rotation(angleRadians) {\n const mat = Matrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[4] = -Math.sin(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[5] = Math.cos(angleRadians);\n return mat;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\n result.x = resultX;\n result.y = resultY;\n return result;\n }\n else {\n const result = dest || new Matrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n const b11 = other.data[0];\n const b21 = other.data[1];\n const b31 = other.data[2];\n const b41 = other.data[3];\n const b12 = other.data[4];\n const b22 = other.data[5];\n const b32 = other.data[6];\n const b42 = other.data[7];\n const b13 = other.data[8];\n const b23 = other.data[9];\n const b33 = other.data[10];\n const b43 = other.data[11];\n const b14 = other.data[12];\n const b24 = other.data[13];\n const b34 = other.data[14];\n const b44 = other.data[15];\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n /**\n * Applies translation to the current matrix mutating it\n * @param x\n * @param y\n */\n translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n // Doesn't change z\n const z = 0;\n const w = 1;\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\n return this;\n }\n setPosition(x, y) {\n this.data[12] = x;\n this.data[13] = y;\n }\n getPosition() {\n return vec(this.data[12], this.data[13]);\n }\n /**\n * Applies rotation to the current matrix mutating it\n * @param angle in Radians\n */\n rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a31 + sine * a32;\n this.data[3] = cosine * a41 + sine * a42;\n this.data[4] = cosine * a12 - sine * a11;\n this.data[5] = cosine * a22 - sine * a21;\n this.data[6] = cosine * a32 - sine * a31;\n this.data[7] = cosine * a42 - sine * a41;\n return this;\n }\n /**\n * Applies scaling to the current matrix mutating it\n * @param x\n * @param y\n */\n scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a31 * x;\n this.data[3] = a41 * x;\n this.data[4] = a12 * y;\n this.data[5] = a22 * y;\n this.data[6] = a32 * y;\n this.data[7] = a42 * y;\n return this;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[4] = -sine * currentScale.x;\n this.data[5] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[4]).size;\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[5]).size;\n return this._scaleSignY * yscale;\n }\n /**\n * Get the scale of the matrix\n */\n getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (this._scaleX === val) {\n return;\n }\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[4] = xscale.y * val;\n this._scaleX = val;\n }\n setScaleY(val) {\n if (this._scaleY === val) {\n return;\n }\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[5] = yscale.y * val;\n this._scaleY = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n /**\n * Determinant of the upper left 2x2 matrix\n */\n getBasisDeterminant() {\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\n }\n /**\n * Return the affine inverse, optionally store it in a target matrix.\n *\n * It's recommended you call .reset() the target unless you know what you're doing\n * @param target\n */\n getAffineInverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.getBasisDeterminant();\n const inverseDet = 1 / det; // todo zero check\n const a = this.data[0];\n const b = this.data[4];\n const c = this.data[1];\n const d = this.data[5];\n const m = target || Matrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[4] = -b * inverseDet;\n m.data[5] = a * inverseDet;\n const tx = this.data[12];\n const ty = this.data[13];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\n return m;\n }\n isIdentity() {\n return (this.data[0] === 1 &&\n this.data[1] === 0 &&\n this.data[2] === 0 &&\n this.data[3] === 0 &&\n this.data[4] === 0 &&\n this.data[5] === 1 &&\n this.data[6] === 0 &&\n this.data[7] === 0 &&\n this.data[8] === 0 &&\n this.data[9] === 0 &&\n this.data[10] === 1 &&\n this.data[11] === 0 &&\n this.data[12] === 0 &&\n this.data[13] === 0 &&\n this.data[14] === 0 &&\n this.data[15] === 1);\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\n }\n}\n\n;// CONCATENATED MODULE: ./Math/affine-matrix.ts\n\n\n\nclass AffineMatrix {\n constructor() {\n /**\n * | | | |\n * | ------- | ------- | -------- |\n * | data[0] | data[2] | data[4] |\n * | data[1] | data[3] | data[5] |\n * | 0 | 0 | 1 |\n */\n this.data = new Float64Array(6);\n this._scale = new Float64Array([1, 1]);\n this._scaleSignX = 1;\n this._scaleSignY = 1;\n }\n /**\n * Converts the current matrix into a DOMMatrix\n *\n * This is useful when working with the browser Canvas context\n * @returns {DOMMatrix} DOMMatrix\n */\n toDOMMatrix() {\n return new DOMMatrix([...this.data]);\n }\n static identity() {\n const mat = new AffineMatrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\n * Creates a brand new translation matrix at the specified 3d point\n * @param x\n * @param y\n */\n static translation(x, y) {\n const mat = AffineMatrix.identity();\n mat.data[4] = x;\n mat.data[5] = y;\n return mat;\n }\n /**\n * Creates a brand new scaling matrix with the specified scaling factor\n * @param sx\n * @param sy\n */\n static scale(sx, sy) {\n const mat = AffineMatrix.identity();\n mat.data[0] = sx;\n mat.data[3] = sy;\n mat._scale[0] = sx;\n mat._scale[1] = sy;\n return mat;\n }\n /**\n * Creates a brand new rotation matrix with the specified angle\n * @param angleRadians\n */\n static rotation(angleRadians) {\n const mat = AffineMatrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[2] = -Math.sin(angleRadians);\n mat.data[3] = Math.cos(angleRadians);\n return mat;\n }\n setPosition(x, y) {\n this.data[4] = x;\n this.data[5] = y;\n }\n getPosition() {\n return vec(this.data[4], this.data[5]);\n }\n /**\n * Applies rotation to the current matrix mutating it\n * @param angle in Radians\n */\n rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a12 - sine * a11;\n this.data[3] = cosine * a22 - sine * a21;\n return this;\n }\n /**\n * Applies translation to the current matrix mutating it\n * @param x\n * @param y\n */\n translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n // Doesn't change z\n this.data[4] = a11 * x + a12 * y + a13;\n this.data[5] = a21 * x + a22 * y + a23;\n return this;\n }\n /**\n * Applies scaling to the current matrix mutating it\n * @param x\n * @param y\n */\n scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a12 * y;\n this.data[3] = a22 * y;\n this._scale[0] = x;\n this._scale[1] = y;\n return this;\n }\n determinant() {\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\n }\n /**\n * Return the affine inverse, optionally store it in a target matrix.\n *\n * It's recommended you call .reset() the target unless you know what you're doing\n * @param target\n */\n inverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.determinant();\n const inverseDet = 1 / det; // TODO zero check\n const a = this.data[0];\n const b = this.data[2];\n const c = this.data[1];\n const d = this.data[3];\n const m = target || AffineMatrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[2] = -b * inverseDet;\n m.data[3] = a * inverseDet;\n const tx = this.data[4];\n const ty = this.data[5];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\n return m;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\n result.x = resultX;\n result.y = resultY;\n return result;\n }\n else {\n const result = dest || new AffineMatrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n const b11 = other.data[0];\n const b21 = other.data[1];\n // const b31 = 0;\n const b12 = other.data[2];\n const b22 = other.data[3];\n // const b32 = 0;\n const b13 = other.data[4];\n const b23 = other.data[5];\n // const b33 = 1;\n result.data[0] = a11 * b11 + a12 * b21; // + a13 * b31; // zero\n result.data[1] = a21 * b11 + a22 * b21; // + a23 * b31; // zero\n result.data[2] = a11 * b12 + a12 * b22; // + a13 * b32; // zero\n result.data[3] = a21 * b12 + a22 * b22; // + a23 * b32; // zero\n result.data[4] = a11 * b13 + a12 * b23 + a13; // * b33; // one\n result.data[5] = a21 * b13 + a22 * b23 + a23; // * b33; // one\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n to4x4() {\n const mat = new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = this.data[2];\n mat.data[5] = this.data[3];\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = this.data[4];\n mat.data[13] = this.data[5];\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[2] = -sine * currentScale.x;\n this.data[3] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[2]).distance();\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[3]).distance();\n return this._scaleSignY * yscale;\n }\n /**\n * Get the scale of the matrix\n */\n getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (val === this._scale[0]) {\n return;\n }\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[2] = xscale.y * val;\n this._scale[0] = val;\n }\n setScaleY(val) {\n if (val === this._scale[1]) {\n return;\n }\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[3] = yscale.y * val;\n this._scale[1] = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n isIdentity() {\n return (this.data[0] === 1 &&\n this.data[1] === 0 &&\n this.data[2] === 0 &&\n this.data[3] === 1 &&\n this.data[4] === 0 &&\n this.data[5] === 0);\n }\n /**\n * Resets the current matrix to the identity matrix, mutating it\n * @returns {AffineMatrix} Current matrix as identity\n */\n reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\n * Creates a new Matrix with the same data as the current 4x4\n */\n clone(dest) {\n const mat = dest || new AffineMatrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n return mat;\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/transform-stack.ts\n\nclass TransformStack {\n constructor() {\n this._transforms = [];\n this._currentTransform = AffineMatrix.identity();\n }\n save() {\n this._transforms.push(this._currentTransform);\n this._currentTransform = this._currentTransform.clone();\n }\n restore() {\n this._currentTransform = this._transforms.pop();\n }\n translate(x, y) {\n return this._currentTransform.translate(x, y);\n }\n rotate(angle) {\n return this._currentTransform.rotate(angle);\n }\n scale(x, y) {\n return this._currentTransform.scale(x, y);\n }\n set current(matrix) {\n this._currentTransform = matrix;\n }\n get current() {\n return this._currentTransform;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/state-stack.ts\n\nclass StateStack {\n constructor() {\n this._states = [];\n this._currentState = this._getDefaultState();\n }\n _getDefaultState() {\n return {\n opacity: 1,\n z: 0,\n tint: Color.White,\n material: null\n };\n }\n _cloneState() {\n return {\n opacity: this._currentState.opacity,\n z: this._currentState.z,\n tint: this._currentState.tint.clone(),\n material: this._currentState.material // TODO is this going to cause problems when cloning\n };\n }\n save() {\n this._states.push(this._currentState);\n this._currentState = this._cloneState();\n }\n restore() {\n this._currentState = this._states.pop();\n }\n get current() {\n return this._currentState;\n }\n set current(val) {\n this._currentState = val;\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Resource.ts\n\n\nconst ResourceEvents = {\n Complete: 'complete',\n Load: 'load',\n LoadStart: 'loadstart',\n Progress: 'progress',\n Error: 'error'\n};\n/**\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\n */\nclass Resource {\n /**\n * @param path Path to the remote resource\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\n * @param bustCache Whether or not to cache-bust requests\n */\n constructor(path, responseType, bustCache = false) {\n this.path = path;\n this.responseType = responseType;\n this.bustCache = bustCache;\n this.data = null;\n this.logger = Logger.getInstance();\n this.events = new EventEmitter();\n }\n /**\n * Returns true if the Resource is completely loaded and is ready\n * to be drawn.\n */\n isLoaded() {\n return this.data !== null;\n }\n _cacheBust(uri) {\n const query = /\\?\\w*=\\w*/;\n if (query.test(uri)) {\n uri += '&__=' + Date.now();\n }\n else {\n uri += '?__=' + Date.now();\n }\n return uri;\n }\n /**\n * Begin loading the resource and returns a promise to be resolved on completion\n */\n load() {\n return new Promise((resolve, reject) => {\n // Exit early if we already have data\n if (this.data !== null) {\n this.logger.debug('Already have data for resource', this.path);\n this.events.emit('complete', this.data);\n resolve(this.data);\n return;\n }\n const request = new XMLHttpRequest();\n request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true);\n request.responseType = this.responseType;\n request.addEventListener('loadstart', (e) => this.events.emit('loadstart', e));\n request.addEventListener('progress', (e) => this.events.emit('progress', e));\n request.addEventListener('error', (e) => this.events.emit('error', e));\n request.addEventListener('load', (e) => this.events.emit('load', e));\n request.addEventListener('load', () => {\n // XHR on file:// success status is 0, such as with PhantomJS\n if (request.status !== 0 && request.status !== 200) {\n this.logger.error('Failed to load resource ', this.path, ' server responded with error code', request.status);\n this.events.emit('error', request.response);\n reject(new Error(request.statusText));\n return;\n }\n this.data = request.response;\n this.events.emit('complete', this.data);\n this.logger.debug('Completed loading resource', this.path);\n resolve(this.data);\n });\n request.send();\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Watch.ts\n/**\n * Watch an object with a proxy, only fires if property value is different\n */\nfunction watch(type, change) {\n if (!type) {\n return type;\n }\n if (type.__isProxy === undefined) {\n // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value) => {\n // The default behavior to store the value\n if (obj[prop] !== value) {\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === 'string') {\n if (prop[0] !== '_') {\n change(obj);\n }\n }\n }\n // Indicate success\n return true;\n },\n get: (obj, prop) => {\n if (prop !== '__isProxy') {\n return obj[prop];\n }\n return true;\n }\n });\n }\n return type;\n}\nconst createHandler = (path = [], change, typeType) => ({\n get: (target, key) => {\n if (key === '__isProxy') {\n return true;\n }\n if (typeof target[key] === 'object' && target[key] != null) {\n return new Proxy(target[key], createHandler([...path, key], change, typeType));\n }\n return target[key];\n },\n set: (target, key, value) => {\n if (typeof key === 'string') {\n if (key[0] !== '_') {\n change(typeType);\n }\n }\n target[key] = value;\n return true;\n }\n});\n/**\n *\n */\nfunction watchDeep(type, change) {\n if (!type) {\n return type;\n }\n if (type.__isProxy === undefined) {\n // expando hack to mark a proxy\n return new Proxy(type, createHandler([], change, type));\n }\n return type;\n}\n/**\n * Watch an object with a proxy, fires change on any property value change\n */\nfunction watchAny(type, change) {\n if (!type) {\n return type;\n }\n if (type.__isProxy === undefined) {\n // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value) => {\n // The default behavior to store the value\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === 'string') {\n if (prop[0] !== '_') {\n change(obj);\n }\n }\n // Indicate success\n return true;\n },\n get: (obj, prop) => {\n if (prop !== '__isProxy') {\n return obj[prop];\n }\n return true;\n }\n });\n }\n return type;\n}\n\n;// CONCATENATED MODULE: ./Graphics/Graphic.ts\n\n\n\n\n/**\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\n * [[Graphic]] abstract class.\n *\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\n */\nclass Graphic {\n isStale() {\n return this._transformStale;\n }\n /**\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\n */\n get flipHorizontal() {\n return this._flipHorizontal;\n }\n set flipHorizontal(value) {\n this._flipHorizontal = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\n */\n get flipVertical() {\n return this._flipVertical;\n }\n set flipVertical(value) {\n this._flipVertical = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the rotation of the graphic\n */\n get rotation() {\n return this._rotation;\n }\n set rotation(value) {\n this._rotation = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the scale of the graphic, this affects the width and\n */\n get scale() {\n return this._scale;\n }\n set scale(value) {\n this._scale = watch(value, () => {\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n /**\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\n */\n get origin() {\n return this._origin;\n }\n set origin(value) {\n this._origin = watch(value, () => {\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n constructor(options) {\n var _a, _b, _c, _d, _e, _f, _g;\n this.id = Graphic._ID++;\n this.transform = AffineMatrix.identity();\n this.tint = null;\n this._transformStale = true;\n /**\n * Gets or sets wether to show debug information about the graphic\n */\n this.showDebug = false;\n this._flipHorizontal = false;\n this._flipVertical = false;\n this._rotation = 0;\n /**\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\n */\n this.opacity = 1;\n this._scale = Vector.One;\n this._origin = null;\n this._width = 0;\n this._height = 0;\n if (options) {\n this.origin = (_a = options.origin) !== null && _a !== void 0 ? _a : this.origin;\n this.flipHorizontal = (_b = options.flipHorizontal) !== null && _b !== void 0 ? _b : this.flipHorizontal;\n this.flipVertical = (_c = options.flipVertical) !== null && _c !== void 0 ? _c : this.flipVertical;\n this.rotation = (_d = options.rotation) !== null && _d !== void 0 ? _d : this.rotation;\n this.opacity = (_e = options.opacity) !== null && _e !== void 0 ? _e : this.opacity;\n this.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : this.scale;\n this.tint = (_g = options.tint) !== null && _g !== void 0 ? _g : this.tint;\n }\n }\n cloneGraphicOptions() {\n return {\n width: this.width / this.scale.x,\n height: this.height / this.scale.y,\n origin: this.origin ? this.origin.clone() : null,\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n rotation: this.rotation,\n opacity: this.opacity,\n scale: this.scale ? this.scale.clone() : null,\n tint: this.tint ? this.tint.clone() : null\n };\n }\n /**\n * Gets or sets the width of the graphic (always positive)\n */\n get width() {\n return Math.abs(this._width * this.scale.x);\n }\n /**\n * Gets or sets the height of the graphic (always positive)\n */\n get height() {\n return Math.abs(this._height * this.scale.y);\n }\n set width(value) {\n this._width = value;\n this._transformStale = true;\n }\n set height(value) {\n this._height = value;\n this._transformStale = true;\n }\n /**\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\n */\n get localBounds() {\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\n }\n /**\n * Draw the whole graphic to the context including transform\n * @param ex The excalibur graphics context\n * @param x\n * @param y\n */\n draw(ex, x, y) {\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0);\n this._postDraw(ex);\n }\n /**\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\n * @param ex\n * @param x\n * @param y\n */\n _preDraw(ex, x, y) {\n ex.save();\n ex.translate(x, y);\n if (this._transformStale) {\n this.transform.reset();\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\n this._rotate(this.transform);\n this._flip(this.transform);\n this._transformStale = false;\n }\n ex.multiply(this.transform);\n // it is important to multiply alphas so graphics respect the current context\n ex.opacity = ex.opacity * this.opacity;\n if (this.tint) {\n ex.tint = this.tint;\n }\n }\n _rotate(ex) {\n var _a;\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : vec(this.width / 2, this.height / 2);\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\n ex.scale(scaleDirX, scaleDirY);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, this.height / this.scale.y);\n ex.scale(1, -1);\n }\n }\n /**\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\n * @param ex\n */\n _postDraw(ex) {\n if (this.showDebug) {\n ex.debug.drawRect(0, 0, this.width, this.height);\n }\n ex.restore();\n }\n}\nGraphic._ID = 0;\n\n;// CONCATENATED MODULE: ./Graphics/Sprite.ts\n\n\nclass Sprite extends Graphic {\n static from(image) {\n return new Sprite({\n image: image\n });\n }\n constructor(options) {\n var _a, _b;\n super(options);\n this._logger = Logger.getInstance();\n this._dirty = true;\n this.image = options.image;\n const { width, height } = options;\n this.sourceView = (_a = options.sourceView) !== null && _a !== void 0 ? _a : { x: 0, y: 0, width: width !== null && width !== void 0 ? width : 0, height: height !== null && height !== void 0 ? height : 0 };\n this.destSize = (_b = options.destSize) !== null && _b !== void 0 ? _b : { width: width !== null && width !== void 0 ? width : 0, height: height !== null && height !== void 0 ? height : 0 };\n this._updateSpriteDimensions();\n // Fire when loaded\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.image.ready.then(() => {\n this._updateSpriteDimensions();\n });\n }\n get width() {\n return Math.abs(this.destSize.width * this.scale.x);\n }\n get height() {\n return Math.abs(this.destSize.height * this.scale.y);\n }\n set width(newWidth) {\n newWidth /= Math.abs(this.scale.x);\n this.destSize.width = newWidth;\n super.width = Math.ceil(this.destSize.width);\n }\n set height(newHeight) {\n newHeight /= Math.abs(this.scale.y);\n this.destSize.height = newHeight;\n super.height = Math.ceil(this.destSize.height);\n }\n _updateSpriteDimensions() {\n var _a, _b, _c, _d, _e, _f;\n const { width: nativeWidth, height: nativeHeight } = this.image;\n // This code uses || to avoid 0's\n // If the source is not specified, use the native dimension\n this.sourceView.width = ((_a = this.sourceView) === null || _a === void 0 ? void 0 : _a.width) || nativeWidth;\n this.sourceView.height = ((_b = this.sourceView) === null || _b === void 0 ? void 0 : _b.height) || nativeHeight;\n // If the destination is not specified, use the source if specified, then native\n this.destSize.width = ((_c = this.destSize) === null || _c === void 0 ? void 0 : _c.width) || ((_d = this.sourceView) === null || _d === void 0 ? void 0 : _d.width) || nativeWidth;\n this.destSize.height = ((_e = this.destSize) === null || _e === void 0 ? void 0 : _e.height) || ((_f = this.sourceView) === null || _f === void 0 ? void 0 : _f.height) || nativeHeight;\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\n }\n _preDraw(ex, x, y) {\n if (this.image.isLoaded() && this._dirty) {\n this._dirty = false;\n this._updateSpriteDimensions();\n }\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n if (this.image.isLoaded()) {\n ex.drawImage(this.image.image, this.sourceView.x, this.sourceView.y, this.sourceView.width, this.sourceView.height, x, y, this.destSize.width, this.destSize.height);\n }\n else {\n this._logger.warnOnce(`ImageSource ${this.image.path}` +\n ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` +\n `Read https://excaliburjs.com/docs/imagesource for more information.`);\n }\n }\n clone() {\n return new Sprite({\n image: this.image,\n sourceView: { ...this.sourceView },\n destSize: { ...this.destSize },\n ...this.cloneGraphicOptions()\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Filtering.ts\n/**\n * Describes the different image filtering modes\n */\nvar ImageFiltering;\n(function (ImageFiltering) {\n /**\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\n *\n * Useful for Pixel art aesthetics.\n */\n ImageFiltering[\"Pixel\"] = \"Pixel\";\n /**\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\n */\n ImageFiltering[\"Blended\"] = \"Blended\";\n})(ImageFiltering || (ImageFiltering = {}));\n\n;// CONCATENATED MODULE: ./Graphics/Context/texture-loader.ts\n\n\n/**\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\n */\nclass TextureLoader {\n constructor(gl) {\n this._textureMap = new Map();\n this._gl = gl;\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n dispose() {\n for (const [image] of this._textureMap) {\n this.delete(image);\n }\n this._textureMap.clear();\n this._gl = null;\n }\n /**\n * Get the WebGL Texture from a source image\n * @param image\n */\n get(image) {\n return this._textureMap.get(image);\n }\n /**\n * Returns whether a source image has been loaded as a texture\n * @param image\n */\n has(image) {\n return this._textureMap.has(image);\n }\n /**\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\n * @param image Source graphic\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\n */\n load(image, filtering, forceUpdate = false) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) {\n return null;\n }\n let tex = null;\n // If reuse the texture if it's from the same source\n if (this.has(image)) {\n tex = this.get(image);\n }\n // Update existing webgl texture and return early\n if (tex) {\n if (forceUpdate) {\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n }\n return tex;\n }\n // No texture exists create a new one\n tex = gl.createTexture();\n // TODO implement texture gc with weakmap and timer\n TextureLoader.checkImageSizeSupportedAndLog(image);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n // TODO make configurable\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // NEAREST for pixel art, LINEAR for hi-res\n const filterMode = filtering !== null && filtering !== void 0 ? filtering : TextureLoader.filtering;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n this._textureMap.set(image, tex);\n return tex;\n }\n delete(image) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) {\n return null;\n }\n let tex = null;\n if (this.has(image)) {\n tex = this.get(image);\n gl.deleteTexture(tex);\n }\n }\n /**\n * Takes an image and returns if it meets size criteria for hardware\n * @param image\n * @returns if the image will be supported at runtime\n */\n static checkImageSizeSupportedAndLog(image) {\n var _a;\n const originalSrc = (_a = image.dataset.originalSrc) !== null && _a !== void 0 ? _a : 'internal canvas bitmap';\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\n TextureLoader._LOGGER.error(`The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of ` +\n `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image `\n + `for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n` +\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n return false;\n }\n else if (image.width > 4096 || image.height > 4096) {\n // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\n TextureLoader._LOGGER.warn(`The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, ` +\n `it is recommended you resize images to a maximum (4096x4096).\\n\\n` +\n `Images will likely render as black rectangles on some mobile platforms.\\n\\n` +\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n }\n return true;\n }\n}\nTextureLoader._LOGGER = Logger.getInstance();\n/**\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\n */\nTextureLoader.filtering = ImageFiltering.Blended;\nTextureLoader._MAX_TEXTURE_SIZE = 4096;\n\n;// CONCATENATED MODULE: ./Graphics/ImageSource.ts\n\n\n\n\n\n\nclass ImageSource {\n /**\n * The original size of the source image in pixels\n */\n get width() {\n return this.image.naturalWidth;\n }\n /**\n * The original height of the source image in pixels\n */\n get height() {\n return this.image.naturalHeight;\n }\n /**\n * Returns true if the Texture is completely loaded and is ready\n * to be drawn.\n */\n isLoaded() {\n if (!this._src) {\n // this boosts speed of access\n this._src = this.data.src;\n }\n return !!this._src;\n }\n get image() {\n return this.data;\n }\n /**\n * The path to the image, can also be a data url like 'data:image/'\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\n */\n constructor(path, bustCache = false, filtering) {\n this.path = path;\n this._logger = Logger.getInstance();\n /**\n * Access to the underlying html image element\n */\n this.data = new Image();\n this._readyFuture = new Future();\n /**\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\n */\n this.ready = this._readyFuture.promise;\n this._resource = new Resource(path, 'blob', bustCache);\n this.filtering = filtering;\n if (path.endsWith('.svg') || path.endsWith('.gif')) {\n this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\n }\n }\n /**\n * Create an ImageSource from and HTML tag element\n * @param image\n */\n static fromHtmlImageElement(image, options) {\n const imageSource = new ImageSource('');\n imageSource._src = 'image-element';\n imageSource.data = image;\n imageSource.data.setAttribute('data-original-src', 'image-element');\n if (options === null || options === void 0 ? void 0 : options.filtering) {\n imageSource.data.setAttribute('filtering', options === null || options === void 0 ? void 0 : options.filtering);\n }\n else {\n imageSource.data.setAttribute('filtering', ImageFiltering.Blended);\n }\n TextureLoader.checkImageSizeSupportedAndLog(image);\n imageSource._readyFuture.resolve(image);\n return imageSource;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */\n get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * Begins loading the image and returns a promise that resolves when the image is loaded\n */\n async load() {\n if (this.isLoaded()) {\n return this.data;\n }\n try {\n // Load base64 or blob if needed\n let url;\n if (!this.path.includes('data:image/')) {\n const blob = await this._resource.load();\n url = URL.createObjectURL(blob);\n }\n else {\n url = this.path;\n }\n // Decode the image\n const image = new Image();\n // Use Image.onload over Image.decode()\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\n // Otherwise chrome will throw still Image.decode() failures for large textures\n const loadedFuture = new Future();\n image.onload = () => loadedFuture.resolve();\n image.src = url;\n image.setAttribute('data-original-src', this.path);\n await loadedFuture.promise;\n // Set results\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\n // See image-renderer.ts draw()\n this.data = image;\n // emit warning if potentially too big\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\n }\n catch (error) {\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\n }\n // Do a bad thing to pass the filtering as an attribute\n this.data.setAttribute('filtering', this.filtering);\n // todo emit complete\n this._readyFuture.resolve(this.data);\n return this.data;\n }\n /**\n * Build a sprite from this ImageSource\n */\n toSprite() {\n return Sprite.from(this);\n }\n /**\n * Unload images from memory\n */\n unload() {\n this.data = new Image();\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/SpriteFont.ts\n\n\n\n\nclass SpriteFont extends Graphic {\n constructor(options) {\n super(options);\n this._text = '';\n this.alphabet = '';\n this.shadow = null;\n this.caseInsensitive = false;\n this.spacing = 0;\n this.lineHeight = undefined;\n this._logger = Logger.getInstance();\n const { alphabet, spriteSheet, caseInsensitive, spacing, shadow, lineHeight } = options;\n this.alphabet = alphabet;\n this.spriteSheet = spriteSheet;\n this.caseInsensitive = caseInsensitive !== null && caseInsensitive !== void 0 ? caseInsensitive : this.caseInsensitive;\n this.spacing = spacing !== null && spacing !== void 0 ? spacing : this.spacing;\n this.shadow = shadow !== null && shadow !== void 0 ? shadow : this.shadow;\n this.lineHeight = lineHeight !== null && lineHeight !== void 0 ? lineHeight : this.lineHeight;\n }\n _getCharacterSprites(text) {\n const results = [];\n // handle case insensitive\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\n // for each letter in text\n for (let letterIndex = 0; letterIndex < textToRender.length; letterIndex++) {\n // find the sprite index in alphabet , if there is an error pick the first\n const letter = textToRender[letterIndex];\n let spriteIndex = alphabet.indexOf(letter);\n if (spriteIndex === -1) {\n spriteIndex = 0;\n this._logger.warnOnce(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\n this._logger.warnOnce('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\n }\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\n if (letterSprite) {\n results.push(letterSprite);\n }\n else {\n this._logger.warnOnce(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\n this._logger.warnOnce('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\n }\n }\n return results;\n }\n measureText(text, maxWidth) {\n const lines = this._getLinesFromText(text, maxWidth);\n const maxWidthLine = lines.reduce((a, b) => {\n return a.length > b.length ? a : b;\n });\n const sprites = this._getCharacterSprites(maxWidthLine);\n let width = 0;\n let height = 0;\n for (const sprite of sprites) {\n width += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\n }\n _drawImage(ex, x, y, maxWidth) {\n var _a;\n let xCursor = 0;\n let yCursor = 0;\n let height = 0;\n const lines = this._getLinesFromText(this._text, maxWidth);\n for (const line of lines) {\n for (const sprite of this._getCharacterSprites(line)) {\n // draw it in the right spot and increase the cursor by sprite width\n sprite.draw(ex, x + xCursor, y + yCursor);\n xCursor += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n xCursor = 0;\n yCursor += (_a = this.lineHeight) !== null && _a !== void 0 ? _a : height;\n }\n }\n render(ex, text, _color, x, y, maxWidth) {\n // SpriteFont doesn't support _color, yet...\n this._text = text;\n const bounds = this.measureText(text, maxWidth);\n this.width = bounds.width;\n this.height = bounds.height;\n if (this.shadow) {\n ex.save();\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n ex.restore();\n }\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n }\n clone() {\n return new SpriteFont({\n alphabet: this.alphabet,\n spriteSheet: this.spriteSheet,\n spacing: this.spacing\n });\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\n return this._cachedLines;\n }\n const lines = text.split('\\n');\n if (maxWidth == null) {\n return lines;\n }\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i];\n let newLine = '';\n // Note: we subtract the spacing to counter the initial padding on the left side.\n if (this.measureText(line).width > maxWidth) {\n while (this.measureText(line).width > maxWidth) {\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/SpriteSheet.ts\n\n/**\n * Represents a collection of sprites from a source image with some organization in a grid\n */\nclass SpriteSheet {\n /**\n * Build a new sprite sheet from a list of sprites\n *\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\n * @param options\n */\n constructor(options) {\n this.sprites = [];\n const { sprites, rows, columns } = options;\n this.sprites = sprites;\n this.rows = rows !== null && rows !== void 0 ? rows : 1;\n this.columns = columns !== null && columns !== void 0 ? columns : this.sprites.length;\n }\n /**\n * Find a sprite by their x/y integer coordinates in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\n * and `getSprite(1, 0)` is the sprite one to the right.\n * @param x\n * @param y\n */\n getSprite(x, y, options) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n if (x >= this.columns || x < 0) {\n throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\n }\n if (y >= this.rows || y < 0) {\n throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\n }\n const spriteIndex = x + y * this.columns;\n const sprite = this.sprites[spriteIndex];\n if (sprite) {\n if (options) {\n const spriteWithOptions = sprite.clone();\n spriteWithOptions.flipHorizontal = (_a = options.flipHorizontal) !== null && _a !== void 0 ? _a : spriteWithOptions.flipHorizontal;\n spriteWithOptions.flipVertical = (_b = options.flipVertical) !== null && _b !== void 0 ? _b : spriteWithOptions.flipVertical;\n spriteWithOptions.width = (_c = options.width) !== null && _c !== void 0 ? _c : spriteWithOptions.width;\n spriteWithOptions.height = (_d = options.height) !== null && _d !== void 0 ? _d : spriteWithOptions.height;\n spriteWithOptions.rotation = (_e = options.rotation) !== null && _e !== void 0 ? _e : spriteWithOptions.rotation;\n spriteWithOptions.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : spriteWithOptions.scale;\n spriteWithOptions.opacity = (_g = options.opacity) !== null && _g !== void 0 ? _g : spriteWithOptions.opacity;\n spriteWithOptions.tint = (_h = options.tint) !== null && _h !== void 0 ? _h : spriteWithOptions.tint;\n spriteWithOptions.origin = (_j = options.origin) !== null && _j !== void 0 ? _j : spriteWithOptions.origin;\n return spriteWithOptions;\n }\n return sprite;\n }\n throw Error(`Invalid sprite coordinates (${x}, ${y}`);\n }\n /**\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\n * @param options\n */\n static fromImageSourceWithSourceViews(options) {\n const sprites = options.sourceViews.map(sourceView => {\n return new Sprite({\n image: options.image,\n sourceView\n });\n });\n return new SpriteSheet({ sprites });\n }\n /**\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\n *\n * Example:\n * ```\n * const spriteSheet = SpriteSheet.fromImageSource({\n * image: imageSource,\n * grid: {\n * rows: 5,\n * columns: 2,\n * spriteWidth: 32, // pixels\n * spriteHeight: 32 // pixels\n * },\n * // Optionally specify spacing\n * spacing: {\n * // pixels from the top left to start the sprite parsing\n * originOffset: {\n * x: 5,\n * y: 5\n * },\n * // pixels between each sprite while parsing\n * margin: {\n * x: 1,\n * y: 1\n * }\n * }\n * })\n * ```\n * @param options\n */\n static fromImageSource(options) {\n var _a;\n const sprites = [];\n options.spacing = (_a = options.spacing) !== null && _a !== void 0 ? _a : {};\n const { image, grid: { rows, columns: cols, spriteWidth, spriteHeight }, spacing: { originOffset, margin } } = options;\n const offsetDefaults = { x: 0, y: 0, ...originOffset };\n const marginDefaults = { x: 0, y: 0, ...margin };\n for (let x = 0; x < cols; x++) {\n for (let y = 0; y < rows; y++) {\n sprites[x + y * cols] = new Sprite({\n image: image,\n sourceView: {\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\n width: spriteWidth,\n height: spriteHeight\n },\n destSize: { height: spriteHeight, width: spriteWidth }\n });\n }\n }\n return new SpriteSheet({\n sprites: sprites,\n rows: rows,\n columns: cols\n });\n }\n clone() {\n return new SpriteSheet({\n sprites: this.sprites.map(sprite => sprite.clone()),\n rows: this.rows,\n columns: this.columns\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/debug-font.png\n/* harmony default export */ const debug_font = (\"data:image/png;base64,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\");\n;// CONCATENATED MODULE: ./Graphics/Context/debug-text.ts\n\n\n\n\n/**\n * Internal debugtext helper\n */\nclass DebugText {\n constructor() {\n /**\n * base64 font\n */\n this.fontSheet = debug_font;\n this.size = 16;\n // We fire and forget, we don't care if it's loaded or not\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.load();\n }\n load() {\n this._imageSource = new ImageSource(this.fontSheet);\n return this._imageSource.load().then(() => {\n this._spriteSheet = SpriteSheet.fromImageSource({\n image: this._imageSource,\n grid: {\n rows: 4,\n columns: 16,\n spriteWidth: 16,\n spriteHeight: 16\n }\n });\n this._spriteFont = new SpriteFont({\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!\\'&.\"?-()+# ',\n caseInsensitive: true,\n spriteSheet: this._spriteSheet,\n spacing: -6\n });\n });\n }\n /**\n * Writes debug text using the built in sprint font\n * @param ctx\n * @param text\n * @param pos\n */\n write(ctx, text, pos) {\n if (this._imageSource.isLoaded()) {\n this._spriteFont.render(ctx, text, null, pos.x, pos.y);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/render-source.ts\nclass RenderSource {\n constructor(_gl, _texture) {\n this._gl = _gl;\n this._texture = _texture;\n }\n use() {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\n }\n disable() {\n const gl = this._gl;\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/render-target.ts\n\nclass RenderTarget {\n constructor(options) {\n var _a, _b;\n this.antialias = false;\n this.samples = 1;\n this._gl = options.gl;\n this.width = options.width;\n this.height = options.height;\n this.transparency = options.transparency;\n this.antialias = (_a = options.antialias) !== null && _a !== void 0 ? _a : this.antialias;\n this.samples = (_b = options.samples) !== null && _b !== void 0 ? _b : this._gl.getParameter(this._gl.MAX_SAMPLES);\n const gl = this._gl;\n // Determine current context format for blitting later needs to match\n if (gl.drawingBufferFormat) {\n this.bufferFormat = gl.drawingBufferFormat;\n }\n else {\n // Documented in webgl spec\n // https://registry.khronos.org/webgl/specs/latest/1.0/\n if (this.transparency) {\n this.bufferFormat = gl.RGBA8;\n }\n else {\n this.bufferFormat = gl.RGB8;\n }\n }\n this._setupRenderBuffer();\n this._setupFramebuffer();\n }\n setResolution(width, height) {\n const gl = this._gl;\n this.width = width;\n this.height = height;\n // update backing texture size\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // update render buffer size\n if (this._renderBuffer) {\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\n gl.renderbufferStorageMultisample(gl.RENDERBUFFER, Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, this.height);\n }\n }\n get renderBuffer() {\n return this._renderBuffer;\n }\n get renderFrameBuffer() {\n return this._renderFrameBuffer;\n }\n get frameBuffer() {\n return this._frameBuffer;\n }\n get frameTexture() {\n return this._frameTexture;\n }\n _setupRenderBuffer() {\n if (this.antialias) {\n const gl = this._gl;\n // Render buffers can be used as an input to a shader\n this._renderBuffer = gl.createRenderbuffer();\n this._renderFrameBuffer = gl.createFramebuffer();\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\n gl.renderbufferStorageMultisample(gl.RENDERBUFFER, Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, this.height);\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\n gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._renderBuffer);\n }\n }\n _setupFramebuffer() {\n // Allocates frame buffer\n const gl = this._gl;\n this._frameTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // set the filtering so we don't need mips\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // attach the texture as the first color attachment\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\n // After this bind all draw calls will draw to this framebuffer texture\n this._frameBuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\n // Reset after initialized\n this.disable();\n }\n toRenderSource() {\n if (this.renderBuffer) {\n this.blitRenderBufferToFrameBuffer();\n }\n const source = new RenderSource(this._gl, this._frameTexture);\n return source;\n }\n blitToScreen() {\n const gl = this._gl;\n // set to size of canvas's drawingBuffer\n if (this._renderBuffer) {\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n else {\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.frameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n }\n blitRenderBufferToFrameBuffer() {\n if (this._renderBuffer) {\n const gl = this._gl;\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.frameBuffer);\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n }\n copyToTexture(texture) {\n const gl = this._gl;\n if (this._renderBuffer) {\n this.blitRenderBufferToFrameBuffer();\n }\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, this.width, this.height, 0);\n }\n /**\n * When called, all drawing gets redirected to this render target\n */\n use() {\n const gl = this._gl;\n if (this.antialias) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\n }\n else {\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n }\n // very important to set the viewport to the size of the framebuffer texture\n gl.viewport(0, 0, this.width, this.height);\n }\n /**\n * When called, all drawing is sent back to the canvas\n */\n disable() {\n const gl = this._gl;\n // passing null switches rendering back to the canvas\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-vertex.glsl\n/* harmony default export */ const line_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-fragment.glsl\n/* harmony default export */ const line_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/webgl-util.ts\n/**\n * Return the size of the GlType in bytes\n * @param gl\n * @param type\n */\nfunction getGlTypeSizeBytes(gl, type) {\n switch (type) {\n case gl.FLOAT:\n return 4;\n case gl.SHORT:\n return 2;\n case gl.UNSIGNED_SHORT:\n return 2;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n default:\n return 1;\n }\n}\n/**\n * Based on the type return the number of attribute components\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\n * @param gl\n * @param type\n */\nfunction getAttributeComponentSize(gl, type) {\n switch (type) {\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n return 1;\n case gl.FLOAT_VEC2:\n return 2;\n case gl.FLOAT_VEC3:\n return 3;\n case gl.FLOAT_VEC4:\n return 4;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n case gl.UNSIGNED_SHORT:\n case gl.SHORT:\n return 1;\n default:\n return 1;\n }\n}\n/**\n * Based on the attribute return the corresponding supported attrib pointer type\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\n * @param gl\n * @param type\n */\nfunction getAttributePointerType(gl, type) {\n switch (type) {\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n case gl.FLOAT_VEC2:\n case gl.FLOAT_VEC3:\n case gl.FLOAT_VEC4:\n return gl.FLOAT;\n case gl.BYTE:\n return gl.BYTE;\n case gl.UNSIGNED_BYTE:\n return gl.UNSIGNED_BYTE;\n case gl.SHORT:\n return gl.SHORT;\n case gl.UNSIGNED_SHORT:\n return gl.UNSIGNED_SHORT;\n default:\n return gl.FLOAT;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/shader.ts\n\n\nclass Shader {\n get compiled() {\n return this._compiled;\n }\n /**\n * Create a shader program in excalibur\n * @param options specify shader vertex and fragment source\n */\n constructor(options) {\n this._logger = Logger.getInstance();\n this.uniforms = {};\n this.attributes = {};\n this._compiled = false;\n const { gl, vertexSource, fragmentSource } = options;\n this._gl = gl;\n this.vertexSource = vertexSource;\n this.fragmentSource = fragmentSource;\n }\n dispose() {\n const gl = this._gl;\n gl.deleteProgram(this.program);\n this._gl = null;\n }\n /**\n * Binds the shader program\n */\n use() {\n const gl = this._gl;\n gl.useProgram(this.program);\n Shader._ACTIVE_SHADER_INSTANCE = this;\n }\n isCurrentlyBound() {\n return Shader._ACTIVE_SHADER_INSTANCE === this;\n }\n /**\n * Compile the current shader against a webgl context\n */\n compile() {\n const gl = this._gl;\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\n const attributes = this.getAttributes();\n for (const attribute of attributes) {\n this.attributes[attribute.name] = attribute;\n }\n const uniforms = this.getUniforms();\n for (const uniform of uniforms) {\n this.uniforms[uniform.name] = uniform;\n }\n this._compiled = true;\n return this.program;\n }\n getUniforms() {\n const gl = this._gl;\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\n const uniforms = [];\n for (let i = 0; i < uniformCount; i++) {\n const uniform = gl.getActiveUniform(this.program, i);\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\n uniforms.push({\n name: uniform.name,\n glType: uniform.type,\n location: uniformLocation\n });\n }\n return uniforms;\n }\n getAttributes() {\n const gl = this._gl;\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\n const attributes = [];\n for (let i = 0; i < attributeCount; i++) {\n const attribute = gl.getActiveAttrib(this.program, i);\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\n attributes.push({\n name: attribute.name,\n glType: getAttributePointerType(gl, attribute.type),\n size: getAttributeComponentSize(gl, attribute.type),\n location: attributeLocation,\n normalized: false\n });\n }\n return attributes;\n }\n /**\n * Set a texture in a gpu texture slot\n * @param slotNumber\n * @param texture\n */\n setTexture(slotNumber, texture) {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n }\n /**\n * Set an integer uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformInt(name, value) {\n this.setUniform('uniform1i', name, ~~value);\n }\n /**\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformInt(name, value) {\n return this.trySetUniform('uniform1i', name, ~~value);\n }\n /**\n * Set an integer array uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformIntArray(name, value) {\n this.setUniform('uniform1iv', name, value);\n }\n /**\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformIntArray(name, value) {\n return this.trySetUniform('uniform1iv', name, value);\n }\n /**\n * Set a boolean uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformBoolean(name, value) {\n this.setUniform('uniform1i', name, value ? 1 : 0);\n }\n /**\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformBoolean(name, value) {\n return this.trySetUniform('uniform1i', name, value ? 1 : 0);\n }\n /**\n * Set a float uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformFloat(name, value) {\n this.setUniform('uniform1f', name, value);\n }\n /**\n * Set a float uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformFloat(name, value) {\n return this.trySetUniform('uniform1f', name, value);\n }\n /**\n * Set a float array uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformFloatArray(name, value) {\n this.setUniform('uniform1fv', name, value);\n }\n /**\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformFloatArray(name, value) {\n return this.trySetUniform('uniform1fv', name, value);\n }\n /**\n * Set a [[Vector]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformFloatVector(name, value) {\n this.setUniform('uniform2f', name, value.x, value.y);\n }\n /**\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformFloatVector(name, value) {\n return this.trySetUniform('uniform2f', name, value.x, value.y);\n }\n /**\n * Set a [[Color]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformFloatColor(name, value) {\n this.setUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformFloatColor(name, value) {\n return this.trySetUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\n * Set an [[Matrix]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformMatrix(name, value) {\n this.setUniform('uniformMatrix4fv', name, false, value.data);\n }\n /**\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformMatrix(name, value) {\n return this.trySetUniform('uniformMatrix4fv', name, false, value.data);\n }\n /**\n * Set any available uniform type in webgl\n *\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\n */\n setUniform(uniformType, name, ...value) {\n if (!this._compiled) {\n throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n }\n if (!this.isCurrentlyBound()) {\n throw Error('Currently accessed shader instance is not the current active shader in WebGL,' +\n ' must call `shader.use()` before setting uniforms');\n }\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [location, ...value];\n this._gl[uniformType].apply(this._gl, args);\n }\n else {\n throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,` +\n ' unused uniforms are optimized away by most browsers');\n }\n }\n /**\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\n * true if it was set.\n *\n * WILL NOT THROW on error\n *\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\n *\n */\n trySetUniform(uniformType, name, ...value) {\n if (!this._compiled) {\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n return false;\n }\n if (!this.isCurrentlyBound()) {\n this._logger.warn('Currently accessed shader instance is not the current active shader in WebGL,' +\n ' must call `shader.use()` before setting uniforms');\n return false;\n }\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [location, ...value];\n this._gl[uniformType].apply(this._gl, args);\n }\n else {\n return false;\n }\n return true;\n }\n _createProgram(gl, vertexShader, fragmentShader) {\n const program = gl.createProgram();\n if (program === null) {\n throw Error('Could not create graphics shader program');\n }\n // attach the shaders.\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n // link the program.\n gl.linkProgram(program);\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n if (!success) {\n throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\n }\n return program;\n }\n _compileShader(gl, source, type) {\n const typeName = gl.VERTEX_SHADER === type ? 'vertex' : 'fragment';\n const shader = gl.createShader(type);\n if (shader === null) {\n throw Error(`Could not build shader: [${source}]`);\n }\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (!success) {\n const errorInfo = gl.getShaderInfoLog(shader);\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\n }\n return shader;\n }\n _processSourceForError(source, errorInfo) {\n if (!source) {\n return errorInfo;\n }\n const lines = source.split('\\n');\n const errorLineStart = errorInfo.search(/\\d:\\d/);\n const errorLineEnd = errorInfo.indexOf(' ', errorLineStart);\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(':').map(v => Number(v));\n for (let i = 0; i < lines.length; i++) {\n lines[i] = `${i + 1}: ${lines[i]}${error2 === (i + 1) ? ' <----- ERROR!' : ''}`;\n }\n return '\\n\\nSource:\\n' + lines.join('\\n');\n }\n}\nShader._ACTIVE_SHADER_INSTANCE = null;\n\n;// CONCATENATED MODULE: ./Graphics/Context/vertex-buffer.ts\n/**\n * Helper around vertex buffer to simplify creating and uploading geometry\n *\n * Under the hood uses Float32Array\n */\nclass VertexBuffer {\n constructor(options) {\n /**\n * If the vertices never change switching 'static' can be more efficient on the gpu\n *\n * Default is 'dynamic'\n */\n this.type = 'dynamic';\n const { gl, size, type, data } = options;\n this._gl = gl;\n this.buffer = this._gl.createBuffer();\n if (!data && !size) {\n throw Error('Must either provide data or a size to the VertexBuffer');\n }\n if (!data) {\n this.bufferData = new Float32Array(size);\n }\n else {\n this.bufferData = data;\n }\n this.type = type !== null && type !== void 0 ? type : this.type;\n // Allocate buffer\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n /**\n * Bind this vertex buffer\n */\n bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n }\n /**\n * Upload vertex buffer geometry to the GPU\n */\n upload(count) {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n if (count) {\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\n }\n else {\n // TODO always use bufferSubData? need to perf test it\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n }\n dispose() {\n const gl = this._gl;\n gl.deleteBuffer(this.buffer);\n this._gl = null;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/vertex-layout.ts\n\n\n/**\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\n * the memory layout for your vertices inside a particular buffer\n *\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\n *\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\n */\nclass VertexLayout {\n get vertexBuffer() {\n return this._vertexBuffer;\n }\n get attributes() {\n return this._attributes;\n }\n constructor(options) {\n this._logger = Logger.getInstance();\n this._layout = [];\n this._attributes = [];\n this._vertexTotalSizeBytes = 0;\n const { gl, shader, vertexBuffer, attributes } = options;\n this._gl = gl;\n this._vertexBuffer = vertexBuffer;\n this._attributes = attributes;\n this._shader = shader;\n if (shader) {\n this.initialize();\n }\n }\n /**\n * Total number of bytes that the vertex will take up\n */\n get totalVertexSizeBytes() {\n return this._vertexTotalSizeBytes;\n }\n set shader(shader) {\n if (shader && this._shader !== shader) {\n this._shader = shader;\n this.initialize();\n }\n }\n get shader() {\n return this._shader;\n }\n /**\n * Layouts need shader locations and must be bound to a shader\n */\n initialize() {\n if (!this._shader) {\n return;\n }\n if (!this._shader.compiled) {\n throw Error('Shader not compiled, shader must be compiled before defining a vertex layout');\n }\n this._vertexTotalSizeBytes = 0;\n this._layout.length = 0;\n const shaderAttributes = this._shader.attributes;\n for (const attribute of this._attributes) {\n const attrib = shaderAttributes[attribute[0]];\n if (!attrib) {\n throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}` +\n ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\n }\n if (attrib.size !== attribute[1]) {\n throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],`\n + ` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\n }\n this._layout.push(attrib);\n }\n // calc size\n let componentsPerVertex = 0;\n for (const vertAttribute of this._layout) {\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\n componentsPerVertex += vertAttribute.size;\n }\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) {\n this._logger.warn(`The vertex component size (${componentsPerVertex}) does NOT divide evenly into the specified vertex buffer`\n + ` (${this._vertexBuffer.bufferData.length})`);\n }\n }\n /**\n * Bind this layout with it's associated vertex buffer\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\n */\n use(uploadBuffer = false, count) {\n if (!this._shader) {\n throw Error('No shader is associated with this vertex layout, a shader must be set');\n }\n const gl = this._gl;\n if (!this._shader.isCurrentlyBound()) {\n throw Error('Shader associated with this vertex layout is not active! Call shader.use() before layout.use()');\n }\n this._vertexBuffer.bind();\n if (uploadBuffer) {\n this._vertexBuffer.upload(count);\n }\n let offset = 0;\n // TODO switch to VAOs if the extension is\n for (const vert of this._layout) {\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\n gl.enableVertexAttribArray(vert.location);\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsDiagnostics.ts\nclass GraphicsDiagnostics {\n static clear() {\n GraphicsDiagnostics.DrawCallCount = 0;\n GraphicsDiagnostics.DrawnImagesCount = 0;\n }\n}\nGraphicsDiagnostics.DrawCallCount = 0;\nGraphicsDiagnostics.DrawnImagesCount = 0;\n\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-renderer.ts\n\n\n\n\nclass LineRenderer {\n constructor() {\n this.type = 'ex.line';\n this.priority = 0;\n this._maxLines = 10922;\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl,\n vertexSource: line_vertex,\n fragmentSource: line_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n this._vertexBuffer = new VertexBuffer({\n gl,\n size: 6 * 2 * this._maxLines,\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n vertexBuffer: this._vertexBuffer,\n shader: this._shader,\n attributes: [\n ['a_position', 2],\n ['a_color', 4]\n ]\n });\n }\n dispose() {\n this._vertexBuffer.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n draw(start, end, color) {\n // Force a render if the batch is full\n if (this._isFull()) {\n this.flush();\n }\n this._lineCount++;\n const transform = this._context.getTransform();\n const finalStart = transform.multiply(start);\n const finalEnd = transform.multiply(end);\n const vertexBuffer = this._vertexBuffer.bufferData;\n // Start\n vertexBuffer[this._vertexIndex++] = finalStart.x;\n vertexBuffer[this._vertexIndex++] = finalStart.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n // End\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n }\n _isFull() {\n if (this._lineCount >= this._maxLines) {\n return true;\n }\n return false;\n }\n hasPendingDraws() {\n return this._lineCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._lineCount === 0) {\n return;\n }\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\n GraphicsDiagnostics.DrawCallCount++;\n // reset\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-vertex.glsl\n/* harmony default export */ const point_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-fragment.glsl\n/* harmony default export */ const point_fragment = (\"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \\\"premultiply\\\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-renderer.ts\n\n\n\n\n\n\n\nclass PointRenderer {\n constructor() {\n this.type = 'ex.point';\n this.priority = 0;\n this._maxPoints = 10922;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl,\n vertexSource: point_vertex,\n fragmentSource: point_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n this._buffer = new VertexBuffer({\n gl,\n size: 7 * this._maxPoints,\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_color', 4],\n ['a_size', 1]\n ]\n });\n }\n dispose() {\n this._buffer.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n draw(point, color, size) {\n // Force a render if the batch is full\n if (this._isFull()) {\n this.flush();\n }\n this._pointCount++;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const finalPoint = transform.multiply(point);\n if (snapToPixel) {\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\n }\n const vertexBuffer = this._buffer.bufferData;\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\n }\n _isFull() {\n if (this._pointCount >= this._maxPoints) {\n return true;\n }\n return false;\n }\n hasPendingDraws() {\n return this._pointCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._pointCount === 0) {\n return;\n }\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\n GraphicsDiagnostics.DrawCallCount++;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-vertex.glsl\n/* harmony default export */ const screen_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-fragment.glsl\n/* harmony default export */ const screen_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-pass-painter.ts\n\n\n\n\n\n/**\n * This is responsible for painting the entire screen during the render passes\n */\nclass ScreenPassPainter {\n constructor(gl) {\n this._gl = gl;\n this._shader = new Shader({\n gl,\n vertexSource: screen_vertex,\n fragmentSource: screen_fragment\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl,\n type: 'static',\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1, -1, 0, 0,\n -1, 1, 0, 1,\n 1, -1, 1, 0,\n 1, -1, 1, 0,\n -1, 1, 0, 1,\n 1, 1, 1, 1\n ])\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_texcoord', 2]\n ]\n });\n this._buffer.upload();\n }\n renderWithPostProcessor(postprocessor) {\n const gl = this._gl;\n postprocessor.getShader().use();\n postprocessor.getLayout().use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n renderToScreen() {\n const gl = this._gl;\n this._shader.use();\n this._layout.use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/quad-index-buffer.ts\n\n/**\n * Helper that defines and index buffer for quad geometry\n *\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\n * it is almost always worth it in terms of performance to use an index buffer.\n */\nclass QuadIndexBuffer {\n /**\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\n * @param numberOfQuads Specify the max number of quads you want to draw\n * @param useUint16 Optionally force a uint16 buffer\n */\n constructor(gl, numberOfQuads, useUint16) {\n this._logger = Logger.getInstance();\n this._gl = gl;\n this.buffer = gl.createBuffer();\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n const totalVertices = numberOfQuads * 6;\n if (!useUint16) {\n this.bufferData = new Uint32Array(totalVertices);\n }\n else {\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\n const maxUint16 = 65535;\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\n this.bufferGlType = gl.UNSIGNED_SHORT;\n this.bufferData = new Uint16Array(totalVertices);\n // TODO Should we error if this happens?? maybe not might crash mid game\n if (numberOfQuads > maxUint16Index) {\n this._logger.warn(`Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\n }\n }\n let currentQuad = 0;\n for (let i = 0; i < totalVertices; i += 6) {\n // first triangle\n this.bufferData[i + 0] = currentQuad + 0;\n this.bufferData[i + 1] = currentQuad + 1;\n this.bufferData[i + 2] = currentQuad + 2;\n // second triangle\n this.bufferData[i + 3] = currentQuad + 2;\n this.bufferData[i + 4] = currentQuad + 1;\n this.bufferData[i + 5] = currentQuad + 3;\n currentQuad += 4;\n }\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n get size() {\n return this.bufferData.length;\n }\n /**\n * Upload data to the GPU\n */\n upload() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n /**\n * Bind this index buffer\n */\n bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n }\n dispose() {\n const gl = this._gl;\n gl.deleteBuffer(this.buffer);\n this._gl = null;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.frag.glsl\n/* harmony default export */ const image_renderer_frag = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\nuniform bool u_pixelart;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nin vec2 v_res;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\n// Inigo Quilez pixel art filter https://jorenjoestar.github.io/post/pixel_art_filtering/\\r\\nvec2 uv_iq(in vec2 uv, in vec2 texture_size) {\\r\\n vec2 pixel = uv * texture_size;\\r\\n \\r\\n vec2 seam=floor(pixel+.5);\\r\\n vec2 dudv=fwidth(pixel);\\r\\n pixel=seam+clamp((pixel-seam)/dudv,-.5,.5);\\r\\n \\r\\n return pixel/texture_size;\\r\\n}\\r\\n\\r\\nvoid main(){\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n \\r\\n vec4 color=vec4(1.,0,0,1.);\\r\\n \\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n \\r\\n color.rgb=color.rgb*v_opacity;\\r\\n color.a=color.a*v_opacity;\\r\\n fragColor=color*v_tint;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.vert.glsl\n/* harmony default export */ const image_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity\\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture res\\r\\nin vec2 a_res;\\r\\nout vec2 v_res;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main(){\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position=u_matrix*vec4(a_position,0.,1.);\\r\\n \\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity=a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord=a_texcoord;\\r\\n\\r\\n v_res = a_res;\\r\\n\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex=a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint=a_tint;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.ts\n\n\n\n\n\n\n\n\n\n\n\nclass ImageRenderer {\n constructor(options) {\n this.type = 'ex.image';\n this.priority = 0;\n this._maxImages = 10922; // max(uint16) / 6 verts\n this._maxTextures = 0;\n // Per flush vars\n this._imageCount = 0;\n this._textures = [];\n this._vertexIndex = 0;\n this.pixelArtSampler = options.pixelArtSampler;\n this.uvPadding = options.uvPadding;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Transform shader source\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\n const transformedFrag = this._transformFragmentSource(image_renderer_frag, this._maxTextures);\n // Compile shader\n this._shader = new Shader({\n gl,\n fragmentSource: transformedFrag,\n vertexSource: image_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', context.ortho);\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\n this._shader.setUniformIntArray('u_textures', [...Array(this._maxTextures)].map((_, i) => i));\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl,\n size: 12 * 4 * this._maxImages, // 12 components * 4 verts\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_opacity', 1],\n ['a_res', 2],\n ['a_texcoord', 2],\n ['a_textureIndex', 1],\n ['a_tint', 4]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._textures.length = 0;\n this._context = null;\n this._gl = null;\n }\n _transformFragmentSource(source, maxTextures) {\n let newSource = source.replace('%%count%%', maxTextures.toString());\n let texturePickerBuilder = '';\n for (let i = 0; i < maxTextures; i++) {\n if (i === 0) {\n texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\n }\n else {\n texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\n }\n texturePickerBuilder += ` vec2 uv = u_pixelart ? uv_iq(v_texcoord, v_res) : v_texcoord;\\n`;\n texturePickerBuilder += ` color = texture(u_textures[${i}], uv);\\n`;\n texturePickerBuilder += ` }\\n`;\n }\n newSource = newSource.replace('%%texture_picker%%', texturePickerBuilder);\n return newSource;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute('filtering');\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended ||\n maybeFiltering === ImageFiltering.Pixel) {\n filtering = maybeFiltering;\n }\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute('forceUpload');\n if (this._textures.indexOf(texture) === -1) {\n this._textures.push(texture);\n }\n }\n _bindTextures(gl) {\n // Bind textures in the correct order\n for (let i = 0; i < this._maxTextures; i++) {\n gl.activeTexture(gl.TEXTURE0 + i);\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\n }\n }\n _getTextureIdForImage(image) {\n if (image) {\n const maybeTexture = this._context.textureLoader.get(image);\n return this._textures.indexOf(maybeTexture);\n }\n return -1;\n }\n _isFull() {\n if (this._imageCount >= this._maxImages) {\n return true;\n }\n if (this._textures.length >= this._maxTextures) {\n return true;\n }\n return false;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n // Force a render if the batch is full\n if (this._isFull()) {\n this.flush();\n }\n this._imageCount++;\n // This creates and uploads the texture if not already done\n this._addImageAsTexture(image);\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [0, 0, (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0, (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0];\n let dest = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1, (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0, (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0];\n dest = [dx, dy];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n let topLeft = vec(dest[0], dest[1]);\n let topRight = vec(dest[0] + width, dest[1]);\n let bottomLeft = vec(dest[0], dest[1] + height);\n let bottomRight = vec(dest[0] + width, dest[1] + height);\n topLeft = transform.multiply(topLeft);\n topRight = transform.multiply(topRight);\n bottomLeft = transform.multiply(bottomLeft);\n bottomRight = transform.multiply(bottomRight);\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + sign(topLeft.x) * pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + sign(topLeft.y) * pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + sign(topRight.x) * pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + sign(topRight.y) * pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + sign(bottomLeft.x) * pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + sign(bottomLeft.y) * pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + sign(bottomRight.x) * pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + sign(bottomRight.y) * pixelSnapEpsilon);\n }\n const tint = this._context.tint;\n const textureId = this._getTextureIdForImage(image);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = (sx + this.uvPadding) / imageWidth;\n const uvy0 = (sy + this.uvPadding) / imageHeight;\n const uvx1 = (sx + sw - this.uvPadding) / imageWidth;\n const uvy1 = (sy + sh - this.uvPadding) / imageHeight;\n const txWidth = image.width;\n const txHeight = image.height;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n }\n hasPendingDraws() {\n return this._imageCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._imageCount === 0) {\n return;\n }\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true, 4 * 12 * this._imageCount); // 4 verts * 12 components\n // Update ortho matrix uniform\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n // Turn on pixel art aa sampler\n this._shader.setUniformBoolean('u_pixelart', this.pixelArtSampler);\n // Bind textures to\n this._bindTextures(gl);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._imageCount = 0;\n this._vertexIndex = 0;\n this._textures.length = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.frag.glsl\n/* harmony default export */ const rectangle_renderer_frag = (\"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.vert.glsl\n/* harmony default export */ const rectangle_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.ts\n\n\n\n\n\n\n\n\n\n\nclass RectangleRenderer {\n constructor() {\n this.type = 'ex.rectangle';\n this.priority = 0;\n this._maxRectangles = 10922; // max(uint16) / 6 verts\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\n this._shader = new Shader({\n gl,\n fragmentSource: rectangle_renderer_frag,\n vertexSource: rectangle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', context.ortho);\n this._buffer = new VertexBuffer({\n gl,\n size: 16 * 4 * this._maxRectangles,\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_uv', 2],\n ['a_size', 2],\n ['a_opacity', 1],\n ['a_color', 4],\n ['a_strokeColor', 4],\n ['a_strokeThickness', 1]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n _isFull() {\n if (this._rectangleCount >= this._maxRectangles) {\n return true;\n }\n return false;\n }\n draw(...args) {\n if (args[0] instanceof Vector && args[1] instanceof Vector) {\n this.drawLine.apply(this, args);\n }\n else {\n this.drawRectangle.apply(this, args);\n }\n }\n drawLine(start, end, color, thickness = 1) {\n if (this._isFull()) {\n this.flush();\n }\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const dir = end.sub(start);\n const length = dir.size;\n const normal = dir.normalize().perpendicular();\n const halfThick = thickness / 2;\n /**\n * +---------------------^----------------------+\n * | | (normal) |\n * (startx, starty)------------------>(endx, endy)\n * | |\n * + -------------------------------------------+\n */\n const startTop = transform.multiply(normal.scale(halfThick).add(start));\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\n if (snapToPixel) {\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n const stroke = Color.Transparent;\n const strokeThickness = 0;\n const width = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = startTop.x;\n vertexBuffer[this._vertexIndex++] = startTop.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = startBottom.x;\n vertexBuffer[this._vertexIndex++] = startBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = endTop.x;\n vertexBuffer[this._vertexIndex++] = endTop.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = endBottom.x;\n vertexBuffer[this._vertexIndex++] = endBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n }\n drawRectangle(pos, width, height, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) {\n this.flush();\n }\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\n const topRight = transform.multiply(pos.add(vec(width, 0)));\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n }\n hasPendingDraws() {\n return this._rectangleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._rectangleCount === 0) {\n return;\n }\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.frag.glsl\n/* harmony default export */ const circle_renderer_frag = (\"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.vert.glsl\n/* harmony default export */ const circle_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.ts\n\n\n\n\n\n\n\n\n\n\nclass CircleRenderer {\n constructor() {\n this.type = 'ex.circle';\n this.priority = 0;\n this._maxCircles = 10922; // max(uint16) / 6 verts\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl,\n fragmentSource: circle_renderer_frag,\n vertexSource: circle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', context.ortho);\n this._buffer = new VertexBuffer({\n gl,\n size: 14 * 4 * this._maxCircles,\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_uv', 2],\n ['a_opacity', 1],\n ['a_color', 4],\n ['a_strokeColor', 4],\n ['a_strokeThickness', 1]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n _isFull() {\n if (this._circleCount >= this._maxCircles) {\n return true;\n }\n return false;\n }\n draw(pos, radius, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) {\n this.flush();\n }\n this._circleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO UV could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n }\n hasPendingDraws() {\n return this._circleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._circleCount === 0) {\n return;\n }\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Pool.ts\n\nclass Pool {\n constructor(builder, recycler, maxObjects = 100) {\n this.builder = builder;\n this.recycler = recycler;\n this.maxObjects = maxObjects;\n this.totalAllocations = 0;\n this.index = 0;\n this.objects = [];\n this.disableWarnings = false;\n this._logger = Logger.getInstance();\n }\n dispose() {\n this.objects.length = 0;\n }\n preallocate() {\n for (let i = 0; i < this.maxObjects; i++) {\n this.objects[i] = this.builder();\n }\n }\n /**\n * Use many instances out of the in the context and return all to the pool.\n *\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\n * @param context\n */\n using(context) {\n const result = context(this);\n if (result) {\n return this.done(...result);\n }\n return this.done();\n }\n /**\n * Use a single instance out of th pool and immediately return it to the pool\n * @param context\n */\n borrow(context) {\n const object = this.get();\n context(object);\n this.index--;\n }\n /**\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\n * @param args\n */\n get(...args) {\n if (this.index === this.maxObjects) {\n if (!this.disableWarnings) {\n this._logger.warn('Max pooled objects reached, possible memory leak? Doubling');\n }\n this.maxObjects = this.maxObjects * 2;\n }\n if (this.objects[this.index]) {\n // Pool has an available object already constructed\n return this.recycler(this.objects[this.index++], ...args);\n }\n else {\n // New allocation\n this.totalAllocations++;\n const object = (this.objects[this.index++] = this.builder(...args));\n return object;\n }\n }\n done(...objects) {\n // All objects in pool now considered \"free\"\n this.index = 0;\n for (const object of objects) {\n const poolIndex = this.objects.indexOf(object);\n // Build a new object to take the pool place\n this.objects[poolIndex] = this.builder(); // TODO problematic 0-arg only support\n this.totalAllocations++;\n }\n return objects;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/draw-call.ts\n\n\nclass DrawCall {\n constructor() {\n this.z = 0;\n this.priority = 0;\n this.transform = AffineMatrix.identity();\n this.state = {\n z: 0,\n opacity: 1,\n tint: Color.White,\n material: null\n };\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/material.ts\n\n\n\n\nconst defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nin vec2 a_screenuv;\r\nout vec2 v_screenuv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n v_screenuv = a_screenuv;\r\n}\r\n`;\nclass Material {\n constructor(options) {\n this._logger = Logger.getInstance();\n this._color = Color.Transparent;\n this._initialized = false;\n this._images = new Map();\n this._textures = new Map();\n const { color, name, vertexSource, fragmentSource, graphicsContext, images } = options;\n this._name = name !== null && name !== void 0 ? name : 'anonymous material';\n this._vertexSource = vertexSource !== null && vertexSource !== void 0 ? vertexSource : defaultVertexSource;\n this._fragmentSource = fragmentSource;\n this._color = color !== null && color !== void 0 ? color : this._color;\n if (!graphicsContext) {\n throw Error(`Material ${name} must be provided an excalibur webgl graphics context`);\n }\n if (graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this._graphicsContext = graphicsContext;\n this._initialize(graphicsContext);\n }\n else {\n this._logger.warn(`Material ${name} was created in 2D Canvas mode, currently only WebGL is supported`);\n }\n if (images) {\n for (const key in images) {\n this.addImageSource(key, images[key]);\n }\n }\n }\n _initialize(graphicsContextWebGL) {\n if (this._initialized) {\n return;\n }\n const gl = graphicsContextWebGL.__gl;\n // max texture slots - 2 for the graphic texture and screen texture\n this._maxTextureSlots = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) - 2;\n this._shader = graphicsContextWebGL.createShader({\n vertexSource: this._vertexSource,\n fragmentSource: this._fragmentSource\n });\n this._shader.compile();\n this._initialized = true;\n }\n get name() {\n var _a;\n return (_a = this._name) !== null && _a !== void 0 ? _a : 'anonymous material';\n }\n get isUsingScreenTexture() {\n return this._fragmentSource.includes('u_screen_texture');\n }\n update(callback) {\n if (this._shader) {\n this._shader.use();\n callback(this._shader);\n }\n }\n getShader() {\n return this._shader;\n }\n addImageSource(textureUniformName, image) {\n if (this._images.size < this._maxTextureSlots) {\n this._images.set(textureUniformName, image);\n }\n else {\n this._logger.warn(`Max number texture slots ${this._maxTextureSlots} have been reached for material \"${this.name}\", ` +\n `no more textures will be uploaded due to hardware constraints.`);\n }\n }\n removeImageSource(textureName) {\n const image = this._images.get(textureName);\n this._graphicsContext.textureLoader.delete(image.image);\n this._images.delete(textureName);\n }\n _loadImageSource(image) {\n const imageElement = image.image;\n const maybeFiltering = imageElement.getAttribute('filtering');\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended ||\n maybeFiltering === ImageFiltering.Pixel) {\n filtering = maybeFiltering;\n }\n const force = imageElement.getAttribute('forceUpload') === 'true' ? true : false;\n const texture = this._graphicsContext.textureLoader.load(imageElement, filtering, force);\n // remove force attribute after upload\n imageElement.removeAttribute('forceUpload');\n if (!this._textures.has(image)) {\n this._textures.set(image, texture);\n }\n return texture;\n }\n uploadAndBind(gl, startingTextureSlot = 2) {\n let textureSlot = startingTextureSlot;\n for (const [textureName, image] of this._images.entries()) {\n if (!image.isLoaded()) {\n this._logger.warnOnce(`Image named ${textureName} in material ${this.name} not loaded, nothing will be uploaded to the shader.` +\n ` Did you forget to add this to a loader? https://excaliburjs.com/docs/loaders/`);\n continue;\n } // skip unloaded images, maybe warn\n const texture = this._loadImageSource(image);\n gl.activeTexture(gl.TEXTURE0 + textureSlot);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n this._shader.trySetUniformInt(textureName, textureSlot);\n textureSlot++;\n }\n }\n use() {\n if (this._initialized) {\n // bind the shader\n this._shader.use();\n // Apply standard uniforms\n this._shader.trySetUniformFloatColor('u_color', this._color);\n }\n else {\n throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/material-renderer/material-renderer.ts\n\n\n\n\n\n\nclass MaterialRenderer {\n constructor() {\n this.type = 'ex.material';\n this.priority = 0;\n this._textures = [];\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl,\n size: 6 * 4, // 6 components * 4 verts\n type: 'dynamic'\n });\n // Setup a vertex layout/buffer to the material\n this._layout = new VertexLayout({\n gl,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_uv', 2],\n ['a_screenuv', 2]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, 1, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._textures.length = 0;\n this._context = null;\n this._gl = null;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n const gl = this._gl;\n // Extract context info\n const material = this._context.material;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n // material shader\n const shader = material.getShader();\n // construct geometry, or hold on to it in the material?\n // geometry primitive for drawing rectangles?\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n let vertexIndex = 0;\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [0, 0, (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0, (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0];\n let dest = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1, (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0, (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0];\n dest = [dx, dy];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n const topLeft = vec(dest[0], dest[1]);\n const topRight = vec(dest[0] + width, dest[1]);\n const bottomLeft = vec(dest[0], dest[1] + height);\n const bottomRight = vec(dest[0] + width, dest[1] + height);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = (sx) / imageWidth;\n const uvy0 = (sy) / imageHeight;\n const uvx1 = (sx + sw - 0.01) / imageWidth;\n const uvy1 = (sy + sh - 0.01) / imageHeight;\n const topLeftScreen = transform.getPosition();\n const bottomRightScreen = topLeftScreen.add(bottomRight);\n const screenUVX0 = topLeftScreen.x / this._context.width;\n const screenUVY0 = topLeftScreen.y / this._context.height;\n const screenUVX1 = bottomRightScreen.x / this._context.width;\n const screenUVY1 = bottomRightScreen.y / this._context.height;\n // (0, 0) - 0\n vertexBuffer[vertexIndex++] = topLeft.x;\n vertexBuffer[vertexIndex++] = topLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy0;\n vertexBuffer[vertexIndex++] = screenUVX0;\n vertexBuffer[vertexIndex++] = screenUVY0;\n // (0, 1) - 1\n vertexBuffer[vertexIndex++] = bottomLeft.x;\n vertexBuffer[vertexIndex++] = bottomLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy1;\n vertexBuffer[vertexIndex++] = screenUVX0;\n vertexBuffer[vertexIndex++] = screenUVY1;\n // (1, 0) - 2\n vertexBuffer[vertexIndex++] = topRight.x;\n vertexBuffer[vertexIndex++] = topRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy0;\n vertexBuffer[vertexIndex++] = screenUVX1;\n vertexBuffer[vertexIndex++] = screenUVY0;\n // (1, 1) - 3\n vertexBuffer[vertexIndex++] = bottomRight.x;\n vertexBuffer[vertexIndex++] = bottomRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy1;\n vertexBuffer[vertexIndex++] = screenUVX1;\n vertexBuffer[vertexIndex++] = screenUVY1;\n // This creates and uploads the texture if not already done\n const texture = this._addImageAsTexture(image);\n // apply material\n material.use();\n this._layout.shader = shader;\n // apply layout and geometry\n this._layout.use(true);\n // apply time in ms since the page (performance.now())\n shader.trySetUniformFloat('u_time_ms', performance.now());\n // apply opacity\n shader.trySetUniformFloat('u_opacity', opacity);\n // apply resolution\n shader.trySetUniformFloatVector('u_resolution', vec(this._context.width, this._context.height));\n // apply graphic resolution\n shader.trySetUniformFloatVector('u_graphic_resolution', vec(imageWidth, imageHeight));\n // apply size\n shader.trySetUniformFloatVector('u_size', vec(sw, sh));\n // apply orthographic projection\n shader.trySetUniformMatrix('u_matrix', this._context.ortho);\n // apply geometry transform\n shader.trySetUniformMatrix('u_transform', transform.to4x4());\n // bind graphic image texture 'uniform sampler2D u_graphic;'\n gl.activeTexture(gl.TEXTURE0 + 0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n shader.trySetUniformInt('u_graphic', 0);\n // bind the screen texture\n gl.activeTexture(gl.TEXTURE0 + 1);\n gl.bindTexture(gl.TEXTURE_2D, this._context.materialScreenTexture);\n shader.trySetUniformInt('u_screen_texture', 1);\n // bind any additional textures in the material\n material.uploadAndBind(gl);\n // bind quad index buffer\n this._quads.bind();\n // Draw a single quad\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount++;\n GraphicsDiagnostics.DrawCallCount++;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute('filtering');\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended ||\n maybeFiltering === ImageFiltering.Pixel) {\n filtering = maybeFiltering;\n }\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute('forceUpload');\n if (this._textures.indexOf(texture) === -1) {\n this._textures.push(texture);\n }\n return texture;\n }\n hasPendingDraws() {\n return false;\n }\n flush() {\n // flush does not do anything, material renderer renders immediately per draw\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/ExcaliburGraphicsContextWebGL.ts\n\n\n\n\n\n\n\n\n\n// renderers\n\n\n\n\n\n\n\n\n\n\n\n\nconst pixelSnapEpsilon = 0.0001;\nclass ExcaliburGraphicsContextWebGLDebug {\n constructor(_webglCtx) {\n this._webglCtx = _webglCtx;\n this._debugText = new DebugText();\n }\n /**\n * Draw a debugging rectangle to the context\n * @param x\n * @param y\n * @param width\n * @param height\n */\n drawRect(x, y, width, height, rectOptions = { color: Color.Black }) {\n this.drawLine(vec(x, y), vec(x + width, y), { ...rectOptions });\n this.drawLine(vec(x + width, y), vec(x + width, y + height), { ...rectOptions });\n this.drawLine(vec(x + width, y + height), vec(x, y + height), { ...rectOptions });\n this.drawLine(vec(x, y + height), vec(x, y), { ...rectOptions });\n }\n /**\n * Draw a debugging line to the context\n * @param start\n * @param end\n * @param lineOptions\n */\n drawLine(start, end, lineOptions = { color: Color.Black }) {\n this._webglCtx.draw('ex.line', start, end, lineOptions.color);\n }\n /**\n * Draw a debugging point to the context\n * @param point\n * @param pointOptions\n */\n drawPoint(point, pointOptions = { color: Color.Black, size: 5 }) {\n this._webglCtx.draw('ex.point', point, pointOptions.color, pointOptions.size);\n }\n drawText(text, pos) {\n this._debugText.write(this._webglCtx, text, pos);\n }\n}\nclass ExcaliburGraphicsContextWebGL {\n get z() {\n return this._state.current.z;\n }\n set z(value) {\n this._state.current.z = value;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get width() {\n return this.__gl.canvas.width;\n }\n get height() {\n return this.__gl.canvas.height;\n }\n get ortho() {\n return this._ortho;\n }\n /**\n * Checks the underlying webgl implementation if the requested internal resolution is supported\n * @param dim\n */\n checkIfResolutionSupported(dim) {\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\n let supported = true;\n if (dim.width > 4096 || dim.height > 4096) {\n supported = false;\n }\n return supported;\n }\n constructor(options) {\n this._logger = Logger.getInstance();\n this._renderers = new Map();\n this._isDrawLifecycle = false;\n this.useDrawSorting = true;\n this._drawCallPool = new Pool(() => new DrawCall(), (instance) => {\n instance.priority = 0;\n instance.z = 0;\n instance.renderer = undefined;\n instance.args = undefined;\n return instance;\n }, 4000);\n this._drawCalls = [];\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\n this._postProcessTargets = [];\n this._postprocessors = [];\n this._transform = new TransformStack();\n this._state = new StateStack();\n /**\n * Snaps the drawing x/y coordinate to the nearest whole pixel\n */\n this.snapToPixel = false;\n /**\n * Native context smoothing\n */\n this.smoothing = false;\n /**\n * Whether the pixel art sampler is enabled for smooth sub pixel anti-aliasing\n */\n this.pixelArtSampler = false;\n /**\n * UV padding in pixels to use in internal image rendering to prevent texture bleed\n *\n */\n this.uvPadding = .01;\n this.backgroundColor = Color.ExcaliburBlue;\n this.multiSampleAntialiasing = true;\n this.transparency = true;\n this._disposed = false;\n this.debug = new ExcaliburGraphicsContextWebGLDebug(this);\n this._totalPostProcessorTime = 0;\n const { canvasElement, context, enableTransparency, antialiasing, uvPadding, multiSampleAntialiasing, pixelArtSampler, powerPreference, snapToPixel, backgroundColor, useDrawSorting } = options;\n this.__gl = context !== null && context !== void 0 ? context : canvasElement.getContext('webgl2', {\n antialias: antialiasing !== null && antialiasing !== void 0 ? antialiasing : this.smoothing,\n premultipliedAlpha: false,\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : this.transparency,\n depth: false,\n powerPreference: powerPreference !== null && powerPreference !== void 0 ? powerPreference : 'high-performance'\n });\n if (!this.__gl) {\n throw Error('Failed to retrieve webgl context from browser');\n }\n this.textureLoader = new TextureLoader(this.__gl);\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = antialiasing !== null && antialiasing !== void 0 ? antialiasing : this.smoothing;\n this.transparency = enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : this.transparency;\n this.pixelArtSampler = pixelArtSampler !== null && pixelArtSampler !== void 0 ? pixelArtSampler : this.pixelArtSampler;\n this.uvPadding = uvPadding !== null && uvPadding !== void 0 ? uvPadding : this.uvPadding;\n this.multiSampleAntialiasing = typeof multiSampleAntialiasing === 'boolean' ? multiSampleAntialiasing : this.multiSampleAntialiasing;\n this.samples = typeof multiSampleAntialiasing === 'object' ? multiSampleAntialiasing.samples : undefined;\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.useDrawSorting = useDrawSorting !== null && useDrawSorting !== void 0 ? useDrawSorting : this.useDrawSorting;\n this._drawCallPool.disableWarnings = true;\n this._drawCallPool.preallocate();\n this._init();\n }\n dispose() {\n if (!this._disposed) {\n this._disposed = true;\n this.textureLoader.dispose();\n for (const renderer of this._renderers.values()) {\n renderer.dispose();\n }\n this._renderers.clear();\n this._drawCallPool.dispose();\n this._drawCalls.length = 0;\n this.__gl = null;\n }\n }\n _init() {\n const gl = this.__gl;\n // Setup viewport and view matrix\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\n // Clear background\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n // Enable alpha blending\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n // Setup builtin renderers\n this.register(new ImageRenderer({\n uvPadding: this.uvPadding,\n pixelArtSampler: this.pixelArtSampler\n }));\n this.register(new MaterialRenderer());\n this.register(new RectangleRenderer());\n this.register(new CircleRenderer());\n this.register(new PointRenderer());\n this.register(new LineRenderer());\n this.materialScreenTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this.materialScreenTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n gl.bindTexture(gl.TEXTURE_2D, null);\n this._screenRenderer = new ScreenPassPainter(gl);\n this._renderTarget = new RenderTarget({\n gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n });\n this._postProcessTargets = [\n new RenderTarget({\n gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n }),\n new RenderTarget({\n gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n })\n ];\n this._msaaTarget = new RenderTarget({\n gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height,\n antialias: this.multiSampleAntialiasing,\n samples: this.samples\n });\n }\n register(renderer) {\n this._renderers.set(renderer.type, renderer);\n renderer.initialize(this.__gl, this);\n }\n get(rendererName) {\n return this._renderers.get(rendererName);\n }\n _isCurrentRenderer(renderer) {\n if (!this._currentRenderer || this._currentRenderer === renderer) {\n return true;\n }\n return false;\n }\n beginDrawLifecycle() {\n this._isDrawLifecycle = true;\n }\n endDrawLifecycle() {\n this._isDrawLifecycle = false;\n }\n draw(rendererName, ...args) {\n if (!this._isDrawLifecycle) {\n this._logger.warnOnce(`Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` +\n `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\n }\n const renderer = this._renderers.get(rendererName);\n if (renderer) {\n if (this.useDrawSorting) {\n const drawCall = this._drawCallPool.get();\n drawCall.z = this._state.current.z;\n drawCall.priority = renderer.priority;\n drawCall.renderer = rendererName;\n this.getTransform().clone(drawCall.transform);\n drawCall.state.z = this._state.current.z;\n drawCall.state.opacity = this._state.current.opacity;\n drawCall.state.tint = this._state.current.tint;\n drawCall.state.material = this._state.current.material;\n drawCall.args = args;\n this._drawCalls.push(drawCall);\n }\n else {\n // Set the current renderer if not defined\n if (!this._currentRenderer) {\n this._currentRenderer = renderer;\n }\n if (!this._isCurrentRenderer(renderer)) {\n // switching graphics means we must flush the previous\n this._currentRenderer.flush();\n }\n // If we are still using the same renderer we can add to the current batch\n renderer.draw(...args);\n this._currentRenderer = renderer;\n }\n }\n else {\n throw Error(`No renderer with name ${rendererName} has been registered`);\n }\n }\n resetTransform() {\n this._transform.current = AffineMatrix.identity();\n }\n updateViewport(resolution) {\n const gl = this.__gl;\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._msaaTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) {\n return; // zero dimension dest exit early\n }\n else if (dwidth === 0 || dheight === 0) {\n return; // zero dimension dest exit early\n }\n else if (image.width === 0 || image.height === 0) {\n return; // zero dimension source exit early\n }\n if (!image) {\n Logger.getInstance().warn('Cannot draw a null or undefined image');\n // tslint:disable-next-line: no-console\n if (console.trace) {\n // tslint:disable-next-line: no-console\n console.trace();\n }\n return;\n }\n if (this._state.current.material) {\n this.draw('ex.material', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n }\n else {\n this.draw('ex.image', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n }\n }\n drawLine(start, end, color, thickness = 1) {\n this.draw('ex.rectangle', start, end, color, thickness);\n }\n drawRectangle(pos, width, height, color, stroke, strokeThickness) {\n this.draw('ex.rectangle', pos, width, height, color, stroke, strokeThickness);\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.draw('ex.circle', pos, radius, color, stroke, thickness);\n }\n save() {\n this._transform.save();\n this._state.save();\n }\n restore() {\n this._transform.restore();\n this._state.restore();\n }\n translate(x, y) {\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\n }\n rotate(angle) {\n this._transform.rotate(angle);\n }\n scale(x, y) {\n this._transform.scale(x, y);\n }\n transform(matrix) {\n this._transform.current = matrix;\n }\n getTransform() {\n return this._transform.current;\n }\n multiply(m) {\n this._transform.current.multiply(m, this._transform.current);\n }\n addPostProcessor(postprocessor) {\n this._postprocessors.push(postprocessor);\n postprocessor.initialize(this.__gl);\n }\n removePostProcessor(postprocessor) {\n const index = this._postprocessors.indexOf(postprocessor);\n if (index !== -1) {\n this._postprocessors.splice(index, 1);\n }\n }\n clearPostProcessors() {\n this._postprocessors.length = 0;\n }\n updatePostProcessors(delta) {\n for (const postprocessor of this._postprocessors) {\n const shader = postprocessor.getShader();\n shader.use();\n const uniforms = shader.getUniforms();\n this._totalPostProcessorTime += delta;\n if (uniforms.find(u => u.name === 'u_time_ms')) {\n shader.setUniformFloat('u_time_ms', this._totalPostProcessorTime);\n }\n if (uniforms.find(u => u.name === 'u_elapsed_ms')) {\n shader.setUniformFloat('u_elapsed_ms', delta);\n }\n if (uniforms.find(u => u.name === 'u_resolution')) {\n shader.setUniformFloatVector('u_resolution', vec(this.width, this.height));\n }\n if (postprocessor.onUpdate) {\n postprocessor.onUpdate(delta);\n }\n }\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n /**\n * Creates and initializes the material which compiles the internal shader\n * @param options\n * @returns Material\n */\n createMaterial(options) {\n const material = new Material({ ...options, graphicsContext: this });\n return material;\n }\n createShader(options) {\n const gl = this.__gl;\n const { vertexSource, fragmentSource } = options;\n const shader = new Shader({\n gl,\n vertexSource,\n fragmentSource\n });\n shader.compile();\n return shader;\n }\n clear() {\n const gl = this.__gl;\n const currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\n currentTarget.use();\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n // Clear the context with the newly set color. This is\n // the function call that actually does the drawing.\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n /**\n * Flushes all batched rendering to the screen\n */\n flush() {\n // render target captures all draws and redirects to the render target\n let currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\n currentTarget.use();\n if (this.useDrawSorting) {\n // sort draw calls\n // Find the original order of the first instance of the draw call\n const originalSort = new Map();\n for (const [name] of this._renderers) {\n const firstIndex = this._drawCalls.findIndex(dc => dc.renderer === name);\n originalSort.set(name, firstIndex);\n }\n this._drawCalls.sort((a, b) => {\n const zIndex = a.z - b.z;\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\n const priority = a.priority - b.priority;\n if (zIndex === 0) { // sort by z first\n if (priority === 0) { // sort by priority\n return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\n }\n return priority;\n }\n return zIndex;\n });\n const oldTransform = this._transform.current;\n const oldState = this._state.current;\n if (this._drawCalls.length) {\n let currentRendererName = this._drawCalls[0].renderer;\n let currentRenderer = this._renderers.get(currentRendererName);\n for (let i = 0; i < this._drawCalls.length; i++) {\n // hydrate the state for renderers\n this._transform.current = this._drawCalls[i].transform;\n this._state.current = this._drawCalls[i].state;\n if (this._drawCalls[i].renderer !== currentRendererName) {\n // switching graphics renderer means we must flush the previous\n currentRenderer.flush();\n currentRendererName = this._drawCalls[i].renderer;\n currentRenderer = this._renderers.get(currentRendererName);\n }\n // ! hack to grab screen texture before materials run because they might want it\n if (currentRenderer instanceof MaterialRenderer && this.material.isUsingScreenTexture) {\n currentTarget.copyToTexture(this.materialScreenTexture);\n currentTarget.use();\n }\n // If we are still using the same renderer we can add to the current batch\n currentRenderer.draw(...this._drawCalls[i].args);\n }\n if (currentRenderer.hasPendingDraws()) {\n currentRenderer.flush();\n }\n }\n // reset state\n this._transform.current = oldTransform;\n this._state.current = oldState;\n // reclaim draw calls\n this._drawCallPool.done();\n this._drawCalls.length = 0;\n }\n else {\n // This is the final flush at the moment to draw any leftover pending draw\n for (const renderer of this._renderers.values()) {\n if (renderer.hasPendingDraws()) {\n renderer.flush();\n }\n }\n }\n currentTarget.disable();\n // post process step\n if (this._postprocessors.length > 0) {\n const source = currentTarget.toRenderSource();\n source.use();\n }\n // flip flop render targets for post processing\n for (let i = 0; i < this._postprocessors.length; i++) {\n currentTarget = this._postProcessTargets[i % 2];\n this._postProcessTargets[i % 2].use();\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\n this._postProcessTargets[i % 2].toRenderSource().use();\n }\n // Final blit to the screen\n currentTarget.blitToScreen();\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts\n\n\n\n\nconst ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon = 0.0001;\nclass ExcaliburGraphicsContext2DCanvasDebug {\n constructor(_ex) {\n this._ex = _ex;\n this._debugText = new DebugText();\n }\n /**\n * Draw a debug rectangle to the context\n * @param x\n * @param y\n * @param width\n * @param height\n */\n drawRect(x, y, width, height) {\n this._ex.__ctx.save();\n this._ex.__ctx.strokeStyle = 'red';\n this._ex.__ctx.strokeRect(this._ex.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this._ex.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y, this._ex.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this._ex.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this._ex.__ctx.restore();\n }\n drawLine(start, end, lineOptions = { color: Color.Black }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\n this._ex.__ctx.moveTo(this._ex.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this._ex.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this._ex.__ctx.lineTo(this._ex.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this._ex.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this._ex.__ctx.lineWidth = 2;\n this._ex.__ctx.stroke();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawPoint(point, pointOptions = { color: Color.Black, size: 5 }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\n this._ex.__ctx.arc(this._ex.snapToPixel ? ~~(point.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.x, this._ex.snapToPixel ? ~~(point.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.y, pointOptions.size, 0, Math.PI * 2);\n this._ex.__ctx.fill();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawText(text, pos) {\n this._debugText.write(this._ex, text, pos);\n }\n}\nclass ExcaliburGraphicsContext2DCanvas {\n get width() {\n return this.__ctx.canvas.width;\n }\n get height() {\n return this.__ctx.canvas.height;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get smoothing() {\n return this.__ctx.imageSmoothingEnabled;\n }\n set smoothing(value) {\n this.__ctx.imageSmoothingEnabled = value;\n }\n constructor(options) {\n /**\n * Unused in Canvas implementation\n */\n this.useDrawSorting = false;\n /**\n * Unused in Canvas implementation\n */\n this.z = 0;\n this.backgroundColor = Color.ExcaliburBlue;\n this._state = new StateStack();\n this.snapToPixel = false;\n this.debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\n const { canvasElement, context, enableTransparency, snapToPixel, antialiasing: smoothing, backgroundColor } = options;\n this.__ctx = context !== null && context !== void 0 ? context : canvasElement.getContext('2d', {\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : true\n });\n if (!this.__ctx) {\n throw new Error('Cannot build new ExcaliburGraphicsContext2D for some reason!');\n }\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing;\n }\n resetTransform() {\n this.__ctx.resetTransform();\n }\n updateViewport(_resolution) {\n // pass\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) {\n return; // zero dimension dest exit early\n }\n else if (dwidth === 0 || dheight === 0) {\n return; // zero dimension dest exit early\n }\n else if (image.width === 0 || image.height === 0) {\n return; // zero dimension source exit early\n }\n this.__ctx.globalAlpha = this.opacity;\n const args = [image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight]\n .filter((a) => a !== undefined)\n .map((a) => (typeof a === 'number' && this.snapToPixel ? ~~a : a));\n this.__ctx.drawImage.apply(this.__ctx, args);\n GraphicsDiagnostics.DrawCallCount++;\n GraphicsDiagnostics.DrawnImagesCount = 1;\n }\n drawLine(start, end, color, thickness = 1) {\n this.__ctx.save();\n this.__ctx.beginPath();\n this.__ctx.strokeStyle = color.toString();\n this.__ctx.moveTo(this.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this.__ctx.lineTo(this.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this.__ctx.lineWidth = thickness;\n this.__ctx.stroke();\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n drawRectangle(pos, width, height, color) {\n this.__ctx.save();\n this.__ctx.fillStyle = color.toString();\n this.__ctx.fillRect(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, this.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this.__ctx.restore();\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.__ctx.save();\n this.__ctx.beginPath();\n if (stroke) {\n this.__ctx.strokeStyle = stroke.toString();\n }\n if (thickness) {\n this.__ctx.lineWidth = thickness;\n }\n this.__ctx.fillStyle = color.toString();\n this.__ctx.arc(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2);\n this.__ctx.fill();\n if (stroke) {\n this.__ctx.stroke();\n }\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n /**\n * Save the current state of the canvas to the stack (transforms and opacity)\n */\n save() {\n this.__ctx.save();\n this._state.save();\n }\n /**\n * Restore the state of the canvas from the stack\n */\n restore() {\n this.__ctx.restore();\n this._state.restore();\n }\n /**\n * Translate the origin of the context by an x and y\n * @param x\n * @param y\n */\n translate(x, y) {\n this.__ctx.translate(this.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y);\n }\n /**\n * Rotate the context about the current origin\n */\n rotate(angle) {\n this.__ctx.rotate(angle);\n }\n /**\n * Scale the context by an x and y factor\n * @param x\n * @param y\n */\n scale(x, y) {\n this.__ctx.scale(x, y);\n }\n getTransform() {\n throw new Error('Not implemented');\n }\n multiply(_m) {\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\n }\n addPostProcessor(_postprocessor) {\n // pass\n }\n removePostProcessor(_postprocessor) {\n // pass\n }\n clearPostProcessors() {\n // pass\n }\n updatePostProcessors(delta) {\n // pass\n }\n beginDrawLifecycle() {\n // pass\n }\n endDrawLifecycle() {\n // pass\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n createMaterial(options) {\n // pass\n return null;\n }\n clear() {\n // Clear frame\n this.__ctx.clearRect(0, 0, this.width, this.height);\n this.__ctx.fillStyle = this.backgroundColor.toString();\n this.__ctx.fillRect(0, 0, this.width, this.height);\n GraphicsDiagnostics.clear();\n }\n /**\n * Flushes the batched draw calls to the screen\n */\n flush() {\n // pass\n }\n dispose() {\n this.__ctx = null;\n }\n}\n\n;// CONCATENATED MODULE: ./Screen.ts\n\n\n\n\n\n\n\n/**\n * Enum representing the different display modes available to Excalibur.\n */\nvar DisplayMode;\n(function (DisplayMode) {\n /**\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\n */\n DisplayMode[\"Fixed\"] = \"Fixed\";\n /**\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\n * is guaranteed to be on screen.\n */\n DisplayMode[\"FitContainerAndFill\"] = \"FitContainerAndFill\";\n /**\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\n * is guaranteed to be on screen.\n */\n DisplayMode[\"FitScreenAndFill\"] = \"FitScreenAndFill\";\n /**\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\n * (letterbox) that would otherwise be present in [[FitContainer]].\n *\n * **warning** This will clip some drawable area from the user because of the zoom,\n * use [[Screen.contentArea]] to know the safe to draw area.\n */\n DisplayMode[\"FitContainerAndZoom\"] = \"FitContainerAndZoom\";\n /**\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\n * (letterbox) that would otherwise be present in [[FitScreen]].\n *\n * **warning** This will clip some drawable area from the user because of the zoom,\n * use [[Screen.contentArea]] to know the safe to draw area.\n */\n DisplayMode[\"FitScreenAndZoom\"] = \"FitScreenAndZoom\";\n /**\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\n *\n * You may want to center your game here is an example\n * ```html\n * \n * \n *
\n * \n *
\n * \n * ```\n *\n * ```css\n * // css\n * main {\n * display: flex;\n * align-items: center;\n * justify-content: center;\n * height: 100%;\n * width: 100%;\n * }\n * ```\n */\n DisplayMode[\"FitScreen\"] = \"FitScreen\";\n /**\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\n */\n DisplayMode[\"FillScreen\"] = \"FillScreen\";\n /**\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\n */\n DisplayMode[\"FitContainer\"] = \"FitContainer\";\n /**\n * Use the parent DOM container's css width/height for the game resolution dynamically\n */\n DisplayMode[\"FillContainer\"] = \"FillContainer\";\n})(DisplayMode || (DisplayMode = {}));\n/**\n * Convenience class for quick resolutions\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\n */\nclass Resolution {\n /* istanbul ignore next */\n static get SVGA() {\n return { width: 800, height: 600 };\n }\n /* istanbul ignore next */\n static get Standard() {\n return { width: 1920, height: 1080 };\n }\n /* istanbul ignore next */\n static get Atari2600() {\n return { width: 160, height: 192 };\n }\n /* istanbul ignore next */\n static get GameBoy() {\n return { width: 160, height: 144 };\n }\n /* istanbul ignore next */\n static get GameBoyAdvance() {\n return { width: 240, height: 160 };\n }\n /* istanbul ignore next */\n static get NintendoDS() {\n return { width: 256, height: 192 };\n }\n /* istanbul ignore next */\n static get NES() {\n return { width: 256, height: 224 };\n }\n /* istanbul ignore next */\n static get SNES() {\n return { width: 256, height: 244 };\n }\n}\nconst ScreenEvents = {\n ScreenResize: 'resize',\n PixelRatioChange: 'pixelratio',\n FullScreenChange: 'fullscreen'\n};\n/**\n * The Screen handles all aspects of interacting with the screen for Excalibur.\n */\nclass Screen {\n constructor(options) {\n var _a, _b, _c, _d;\n /**\n * Listen to screen events [[ScreenEvents]]\n */\n this.events = new EventEmitter();\n this._antialiasing = true;\n this._canvasImageRendering = 'auto';\n this._resolutionStack = [];\n this._viewportStack = [];\n this._pixelRatioOverride = null;\n this._isFullScreen = false;\n this._isDisposed = false;\n this._logger = Logger.getInstance();\n this._fullscreenChangeHandler = () => {\n if (this._isDisposed) {\n return;\n }\n this._isFullScreen = !this._isFullScreen;\n this._logger.debug('Fullscreen Change', this._isFullScreen);\n this.events.emit('fullscreen', {\n fullscreen: this.isFullScreen\n });\n };\n this._pixelRatioChangeHandler = () => {\n if (this._isDisposed) {\n return;\n }\n this._logger.debug('Pixel Ratio Change', window.devicePixelRatio);\n this._listenForPixelRatio();\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this.applyResolutionAndViewport();\n this.events.emit('pixelratio', {\n pixelRatio: this.pixelRatio\n });\n };\n this._resizeHandler = () => {\n if (this._isDisposed) {\n return;\n }\n const parent = this.parent;\n this._logger.debug('View port resized');\n this._setResolutionAndViewportByDisplayMode(parent);\n this.applyResolutionAndViewport();\n // Emit resize event\n this.events.emit('resize', {\n resolution: this.resolution,\n viewport: this.viewport\n });\n };\n // Asking the window.devicePixelRatio is expensive we do it once\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this._contentArea = new BoundingBox();\n this._unsafeArea = new BoundingBox();\n this.viewport = options.viewport;\n this.resolution = (_a = options.resolution) !== null && _a !== void 0 ? _a : { ...this.viewport };\n this._contentResolution = this.resolution;\n this._displayMode = (_b = options.displayMode) !== null && _b !== void 0 ? _b : DisplayMode.Fixed;\n this._canvas = options.canvas;\n this.graphicsContext = options.context;\n this._antialiasing = (_c = options.antialiasing) !== null && _c !== void 0 ? _c : this._antialiasing;\n this._canvasImageRendering = (_d = options.canvasImageRendering) !== null && _d !== void 0 ? _d : this._canvasImageRendering;\n this._browser = options.browser;\n this._pixelRatioOverride = options.pixelRatio;\n this._applyDisplayMode();\n this._listenForPixelRatio();\n this._canvas.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\n this.applyResolutionAndViewport();\n }\n _listenForPixelRatio() {\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) {\n // Safari <=13.1 workaround, remove any existing handlers\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n }\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.addEventListener) {\n this._mediaQueryList.addEventListener('change', this._pixelRatioChangeHandler, { once: true });\n }\n else {\n this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\n }\n }\n dispose() {\n if (!this._isDisposed) {\n // Clean up handlers\n this._isDisposed = true;\n this.events.clear();\n this._browser.window.off('resize', this._resizeHandler);\n this._browser.window.clear();\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n }\n this.parent.removeEventListener('resize', this._resizeHandler);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.removeEventListener) {\n this._mediaQueryList.removeEventListener('change', this._pixelRatioChangeHandler);\n }\n else {\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n }\n this._canvas.removeEventListener('fullscreenchange', this._fullscreenChangeHandler);\n this._canvas = null;\n }\n }\n _calculateDevicePixelRatio() {\n if (window.devicePixelRatio < 1) {\n return 1;\n }\n const devicePixelRatio = window.devicePixelRatio || 1;\n return devicePixelRatio;\n }\n /**\n * Returns the computed pixel ratio, first using any override, then the device pixel ratio\n */\n get pixelRatio() {\n if (this._pixelRatioOverride) {\n return this._pixelRatioOverride;\n }\n return this._devicePixelRatio;\n }\n /**\n * Get or set the pixel ratio override\n *\n * You will need to call applyResolutionAndViewport() affect change on the screen\n */\n get pixelRatioOverride() {\n return this._pixelRatioOverride;\n }\n set pixelRatioOverride(value) {\n this._pixelRatioOverride = value;\n }\n get isHiDpi() {\n return this.pixelRatio !== 1;\n }\n get displayMode() {\n return this._displayMode;\n }\n get canvas() {\n return this._canvas;\n }\n get parent() {\n switch (this.displayMode) {\n case DisplayMode.FillContainer:\n case DisplayMode.FitContainer:\n case DisplayMode.FitContainerAndFill:\n case DisplayMode.FitContainerAndZoom:\n return this.canvas.parentElement || document.body;\n default:\n return window;\n }\n }\n get resolution() {\n return this._resolution;\n }\n set resolution(resolution) {\n this._resolution = resolution;\n }\n get viewport() {\n if (this._viewport) {\n return this._viewport;\n }\n return this._resolution;\n }\n set viewport(viewport) {\n this._viewport = viewport;\n }\n get aspectRatio() {\n return this._resolution.width / this._resolution.height;\n }\n get scaledWidth() {\n return this._resolution.width * this.pixelRatio;\n }\n get scaledHeight() {\n return this._resolution.height * this.pixelRatio;\n }\n setCurrentCamera(camera) {\n this._camera = camera;\n }\n pushResolutionAndViewport() {\n this._resolutionStack.push(this.resolution);\n this._viewportStack.push(this.viewport);\n this.resolution = { ...this.resolution };\n this.viewport = { ...this.viewport };\n }\n peekViewport() {\n return this._viewportStack[this._viewportStack.length - 1];\n }\n peekResolution() {\n return this._resolutionStack[this._resolutionStack.length - 1];\n }\n popResolutionAndViewport() {\n if (this._resolutionStack.length && this._viewportStack.length) {\n this.resolution = this._resolutionStack.pop();\n this.viewport = this._viewportStack.pop();\n }\n }\n applyResolutionAndViewport() {\n this._canvas.width = this.scaledWidth;\n this._canvas.height = this.scaledHeight;\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n const supported = this.graphicsContext.checkIfResolutionSupported({\n width: this.scaledWidth,\n height: this.scaledHeight\n });\n if (!supported) {\n this._logger.warnOnce(`The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` +\n ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' +\n ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' +\n ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).');\n }\n }\n if (this._canvasImageRendering === 'auto') {\n this._canvas.style.imageRendering = 'auto';\n }\n else {\n this._canvas.style.imageRendering = 'pixelated';\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\n if (this._canvas.style.imageRendering === '') {\n this._canvas.style.imageRendering = 'crisp-edges';\n }\n }\n this._canvas.style.width = this.viewport.width + 'px';\n this._canvas.style.height = this.viewport.height + 'px';\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\n this.graphicsContext.updateViewport(this.resolution);\n this.graphicsContext.resetTransform();\n this.graphicsContext.smoothing = this._antialiasing;\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) {\n this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\n }\n }\n get antialiasing() {\n return this._antialiasing;\n }\n set antialiasing(isSmooth) {\n this._antialiasing = isSmooth;\n this.graphicsContext.smoothing = this._antialiasing;\n }\n /**\n * Returns true if excalibur is fullscreen using the browser fullscreen api\n */\n get isFullScreen() {\n return this._isFullScreen;\n }\n /**\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\n * For example, wire this to a user click handler.\n *\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\n * @param elementId\n */\n goFullScreen(elementId) {\n if (elementId) {\n const maybeElement = document.getElementById(elementId);\n if (maybeElement) {\n if (!maybeElement.getAttribute('ex-fullscreen-listener')) {\n maybeElement.setAttribute('ex-fullscreen-listener', 'true');\n maybeElement.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\n }\n const fullscreenPromise = maybeElement.requestFullscreen();\n return fullscreenPromise;\n }\n }\n return this._canvas.requestFullscreen();\n }\n /**\n * Requests to exit fullscreen using the browser fullscreen api\n */\n exitFullScreen() {\n return document.exitFullscreen();\n }\n /**\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\n * Excalibur screen space.\n *\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\n * bottom right corner (resolutionX, resolutionY). When using *AndFill suffixed display modes screen space\n * (0, 0) is the top left of the safe content area bounding box not the viewport.\n * @param point\n */\n pageToScreenCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n if (!this._isFullScreen) {\n newX -= getPosition(this._canvas).x;\n newY -= getPosition(this._canvas).y;\n }\n // if fullscreen api on it centers with black bars\n // we need to adjust the screen to world coordinates in this case\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = ((newY - screenMarginY) / screenHeight) * this.viewport.height;\n newX = (newX / window.innerWidth) * this.viewport.width;\n }\n else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = ((newX - screenMarginX) / screenWidth) * this.viewport.width;\n newY = (newY / window.innerHeight) * this.viewport.height;\n }\n }\n newX = (newX / this.viewport.width) * this.resolution.width;\n newY = (newY / this.viewport.height) * this.resolution.height;\n // offset by content area\n newX = newX - this.contentArea.left;\n newY = newY - this.contentArea.top;\n return new Vector(newX, newY);\n }\n /**\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\n * this is where html elements might live if you want to position them relative to Excalibur.\n *\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\n * bottom right corner (resolutionX, resolutionY)\n * @param point\n */\n screenToPageCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n // no need to offset by content area, drawing is already offset by this\n newX = (newX / this.resolution.width) * this.viewport.width;\n newY = (newY / this.resolution.height) * this.viewport.height;\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = (newY / this.viewport.height) * screenHeight + screenMarginY;\n newX = (newX / this.viewport.width) * window.innerWidth;\n }\n else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = (newX / this.viewport.width) * screenWidth + screenMarginX;\n newY = (newY / this.viewport.height) * window.innerHeight;\n }\n }\n if (!this._isFullScreen) {\n newX += getPosition(this._canvas).x;\n newY += getPosition(this._canvas).y;\n }\n return new Vector(newX, newY);\n }\n /**\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\n *\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\n * and extends infinitely out relative from the [[Camera]].\n * @param point Screen coordinate to convert\n */\n screenToWorldCoordinates(point) {\n // offset by content area\n point = point.add(vec(this.contentArea.left, this.contentArea.top));\n // the only difference between screen & world is the camera transform\n if (this._camera) {\n return this._camera.inverse.multiply(point);\n }\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n /**\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\n *\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\n * @param point World coordinate to convert\n */\n worldToScreenCoordinates(point) {\n if (this._camera) {\n return this._camera.transform.multiply(point);\n }\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n pageToWorldCoordinates(point) {\n const screen = this.pageToScreenCoordinates(point);\n return this.screenToWorldCoordinates(screen);\n }\n worldToPageCoordinates(point) {\n const screen = this.worldToScreenCoordinates(point);\n return this.screenToPageCoordinates(screen);\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen\n * and the bottom right corner of the screen.\n *\n * World bounds are in world coordinates, useful for culling objects offscreen that are in world space\n */\n getWorldBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Half)\n .scale(vec(1 / this._camera.zoom, 1 / this._camera.zoom))\n .rotate(this._camera.rotation)\n .translate(this._camera.pos);\n return bounds;\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen and the bottom right corner of the screen.\n *\n * Screen bounds are in screen coordinates, useful for culling objects offscreen that are in screen space\n */\n getScreenBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero, Vector.Zero);\n return bounds;\n }\n /**\n * The width of the game canvas in pixels (physical width component of the\n * resolution of the canvas element)\n */\n get canvasWidth() {\n return this.canvas.width;\n }\n /**\n * Returns half width of the game canvas in pixels (half physical width component)\n */\n get halfCanvasWidth() {\n return this.canvas.width / 2;\n }\n /**\n * The height of the game canvas in pixels, (physical height component of\n * the resolution of the canvas element)\n */\n get canvasHeight() {\n return this.canvas.height;\n }\n /**\n * Returns half height of the game canvas in pixels (half physical height component)\n */\n get halfCanvasHeight() {\n return this.canvas.height / 2;\n }\n /**\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get drawWidth() {\n if (this._camera) {\n return this.resolution.width / this._camera.zoom;\n }\n return this.resolution.width;\n }\n /**\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get halfDrawWidth() {\n return this.drawWidth / 2;\n }\n /**\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get drawHeight() {\n if (this._camera) {\n return this.resolution.height / this._camera.zoom;\n }\n return this.resolution.height;\n }\n /**\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get halfDrawHeight() {\n return this.drawHeight / 2;\n }\n /**\n * Returns screen center coordinates including zoom and device pixel ratio.\n */\n get center() {\n return vec(this.halfDrawWidth, this.halfDrawHeight);\n }\n /**\n * Returns the content area in screen space where it is safe to place content\n */\n get contentArea() {\n return this._contentArea;\n }\n /**\n * Returns the unsafe area in screen space, this is the full screen and some space may not be onscreen.\n */\n get unsafeArea() {\n return this._unsafeArea;\n }\n _computeFit() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (window.innerWidth / aspect < window.innerHeight) {\n adjustedWidth = window.innerWidth;\n adjustedHeight = window.innerWidth / aspect;\n }\n else {\n adjustedWidth = window.innerHeight * aspect;\n adjustedHeight = window.innerHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n this._unsafeArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _computeFitScreenAndFill() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitContainerAndFill() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n const parent = this.canvas.parentElement;\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitAndFill(vw, vh) {\n this.viewport = {\n width: vw,\n height: vh\n };\n // if the current screen aspectRatio is less than the original aspectRatio\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\n // compute new resolution to match the original aspect ratio\n this.resolution = {\n width: vw * this._contentResolution.width / vw,\n height: vw * this._contentResolution.width / vw * vh / vw\n };\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\n this._contentArea = new BoundingBox({\n top: clip,\n left: 0,\n right: this._contentResolution.width,\n bottom: this.resolution.height - clip\n });\n this._unsafeArea = new BoundingBox({\n top: -clip,\n left: 0,\n right: this._contentResolution.width,\n bottom: this.resolution.height + clip\n });\n }\n else {\n this.resolution = {\n width: vh * this._contentResolution.height / vh * vw / vh,\n height: vh * this._contentResolution.height / vh\n };\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\n this._contentArea = new BoundingBox({\n top: 0,\n left: clip,\n right: this.resolution.width - clip,\n bottom: this._contentResolution.height\n });\n this._unsafeArea = new BoundingBox({\n top: 0,\n left: -clip,\n right: this.resolution.width + clip,\n bottom: this._contentResolution.height\n });\n }\n }\n _computeFitScreenAndZoom() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n this.canvas.style.position = 'absolute';\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitContainerAndZoom() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n this.canvas.style.position = 'absolute';\n const parent = this.canvas.parentElement;\n parent.style.position = 'relative';\n parent.style.overflow = 'hidden';\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitAndZoom(vw, vh) {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (vw / aspect < vh) {\n adjustedWidth = vw;\n adjustedHeight = vw / aspect;\n }\n else {\n adjustedWidth = vh * aspect;\n adjustedHeight = vh;\n }\n const scaleX = vw / adjustedWidth;\n const scaleY = vh / adjustedHeight;\n const maxScaleFactor = Math.max(scaleX, scaleY);\n const zoomedWidth = adjustedWidth * maxScaleFactor;\n const zoomedHeight = adjustedHeight * maxScaleFactor;\n // Center zoomed dimension if bigger than the screen\n if (zoomedWidth > vw) {\n this.canvas.style.left = -(zoomedWidth - vw) / 2 + 'px';\n }\n else {\n this.canvas.style.left = '';\n }\n if (zoomedHeight > vh) {\n this.canvas.style.top = -(zoomedHeight - vh) / 2 + 'px';\n }\n else {\n this.canvas.style.top = '';\n }\n this.viewport = {\n width: zoomedWidth,\n height: zoomedHeight\n };\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\n // return safe area\n if (this.viewport.width > vw) {\n const clip = (this.viewport.width - vw) / this.viewport.width * this.resolution.width;\n bounds.top = 0;\n bounds.left = clip / 2;\n bounds.right = this.resolution.width - clip / 2;\n bounds.bottom = this.resolution.height;\n }\n if (this.viewport.height > vh) {\n const clip = (this.viewport.height - vh) / this.viewport.height * this.resolution.height;\n bounds.top = clip / 2;\n bounds.left = 0;\n bounds.bottom = this.resolution.height - clip / 2;\n bounds.right = this.resolution.width;\n }\n this._contentArea = bounds;\n }\n _computeFitContainer() {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n const parent = this.canvas.parentElement;\n if (parent.clientWidth / aspect < parent.clientHeight) {\n adjustedWidth = parent.clientWidth;\n adjustedHeight = parent.clientWidth / aspect;\n }\n else {\n adjustedWidth = parent.clientHeight * aspect;\n adjustedHeight = parent.clientHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _applyDisplayMode() {\n this._setResolutionAndViewportByDisplayMode(this.parent);\n // watch resizing\n if (this.parent instanceof Window) {\n this._browser.window.on('resize', this._resizeHandler);\n }\n else {\n this._resizeObserver = new ResizeObserver(() => {\n this._resizeHandler();\n });\n this._resizeObserver.observe(this.parent);\n }\n this.parent.addEventListener('resize', this._resizeHandler);\n }\n /**\n * Sets the resolution and viewport based on the selected display mode.\n */\n _setResolutionAndViewportByDisplayMode(parent) {\n if (this.displayMode === DisplayMode.FillContainer) {\n this.resolution = {\n width: parent.clientWidth,\n height: parent.clientHeight\n };\n this.viewport = this.resolution;\n }\n if (this.displayMode === DisplayMode.FillScreen) {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n this.resolution = {\n width: parent.innerWidth,\n height: parent.innerHeight\n };\n this.viewport = this.resolution;\n }\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n if (this.displayMode === DisplayMode.FitScreen) {\n this._computeFit();\n }\n if (this.displayMode === DisplayMode.FitContainer) {\n this._computeFitContainer();\n }\n if (this.displayMode === DisplayMode.FitScreenAndFill) {\n this._computeFitScreenAndFill();\n }\n if (this.displayMode === DisplayMode.FitContainerAndFill) {\n this._computeFitContainerAndFill();\n }\n if (this.displayMode === DisplayMode.FitScreenAndZoom) {\n this._computeFitScreenAndZoom();\n }\n if (this.displayMode === DisplayMode.FitContainerAndZoom) {\n this._computeFitContainerAndZoom();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Sound/AudioContext.ts\n/**\n * Internal class used to build instances of AudioContext\n */\n/* istanbul ignore next */\nclass AudioContextFactory {\n static create() {\n if (!this._INSTANCE) {\n if (window.AudioContext || window.webkitAudioContext) {\n this._INSTANCE = new AudioContext();\n }\n }\n return this._INSTANCE;\n }\n}\nAudioContextFactory._INSTANCE = null;\n\n;// CONCATENATED MODULE: ./Util/WebAudio.ts\n\n\n/**\n * Patch for detecting legacy web audio in browsers\n * @internal\n * @param source\n */\nfunction isLegacyWebAudioSource(source) {\n return !!source.playbackState;\n}\nclass WebAudio {\n /**\n * Play an empty sound to unlock Safari WebAudio context. Call this function\n * right after a user interaction event.\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\n */\n static unlock() {\n const promise = new Promise((resolve, reject) => {\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) {\n return resolve(true);\n }\n const unlockTimeoutTimer = setTimeout(() => {\n Logger.getInstance().warn('Excalibur was unable to unlock the audio context, audio probably will not play in this browser.');\n resolve(false);\n }, 200);\n const audioContext = AudioContextFactory.create();\n audioContext.resume().then(() => {\n // create empty buffer and play it\n const buffer = audioContext.createBuffer(1, 1, 22050);\n const source = audioContext.createBufferSource();\n let ended = false;\n source.buffer = buffer;\n source.connect(audioContext.destination);\n source.onended = () => (ended = true);\n source.start(0);\n // by checking the play state after some time, we know if we're really unlocked\n setTimeout(() => {\n if (isLegacyWebAudioSource(source)) {\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) {\n WebAudio._UNLOCKED = true;\n }\n }\n else {\n if (audioContext.currentTime > 0 || ended) {\n WebAudio._UNLOCKED = true;\n }\n }\n }, 0);\n clearTimeout(unlockTimeoutTimer);\n resolve(true);\n }, () => {\n reject();\n });\n });\n return promise;\n }\n static isUnlocked() {\n return this._UNLOCKED;\n }\n}\nWebAudio._UNLOCKED = false;\n\n;// CONCATENATED MODULE: ./Graphics/Raster.ts\n\n\n\n\n\n\n/**\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\n *\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\n */\nclass Raster extends Graphic {\n constructor(options) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;\n super(omit(options, ['width', 'height'])); // rasters do some special sauce with width/height\n this.filtering = null;\n this.lineCap = 'butt';\n this.quality = 1;\n this._dirty = true;\n this._smoothing = false;\n this._color = watch(Color.Black, () => this.flagDirty());\n this._lineWidth = 1;\n this._lineDash = [];\n this._padding = 0;\n if (options) {\n this.quality = (_a = options.quality) !== null && _a !== void 0 ? _a : this.quality;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n this.strokeColor = options === null || options === void 0 ? void 0 : options.strokeColor;\n this.smoothing = (_c = options.smoothing) !== null && _c !== void 0 ? _c : this.smoothing;\n this.lineWidth = (_d = options.lineWidth) !== null && _d !== void 0 ? _d : this.lineWidth;\n this.lineDash = (_e = options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineCap = (_f = options.lineCap) !== null && _f !== void 0 ? _f : this.lineCap;\n this.padding = (_g = options.padding) !== null && _g !== void 0 ? _g : this.padding;\n this.filtering = (_h = options.filtering) !== null && _h !== void 0 ? _h : this.filtering;\n }\n this._bitmap = document.createElement('canvas');\n // get the default canvas width/height as a fallback\n const bitmapWidth = (_j = options === null || options === void 0 ? void 0 : options.width) !== null && _j !== void 0 ? _j : this._bitmap.width;\n const bitmapHeight = (_k = options === null || options === void 0 ? void 0 : options.height) !== null && _k !== void 0 ? _k : this._bitmap.height;\n this.width = bitmapWidth;\n this.height = bitmapHeight;\n const maybeCtx = this._bitmap.getContext('2d');\n if (!maybeCtx) {\n /* istanbul ignore next */\n throw new Error('Browser does not support 2d canvas drawing, cannot create Raster graphic');\n }\n else {\n this._ctx = maybeCtx;\n }\n }\n cloneRasterOptions() {\n return {\n color: this.color ? this.color.clone() : null,\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\n smoothing: this.smoothing,\n lineWidth: this.lineWidth,\n lineDash: this.lineDash,\n lineCap: this.lineCap,\n quality: this.quality,\n padding: this.padding\n };\n }\n /**\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\n */\n get dirty() {\n return this._dirty;\n }\n /**\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\n * This should be called any time the graphics state changes such that it affects the outputted drawing\n */\n flagDirty() {\n this._dirty = true;\n }\n /**\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n *\n * Any `padding`s or `quality` set will be factored into the width\n */\n get width() {\n return Math.abs(this._getTotalWidth() * this.scale.x);\n }\n set width(value) {\n value /= Math.abs(this.scale.x);\n this._bitmap.width = value;\n this._originalWidth = value;\n this.flagDirty();\n }\n /**\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n *\n * Any `padding` or `quality` set will be factored into the height\n */\n get height() {\n return Math.abs(this._getTotalHeight() * this.scale.y);\n }\n set height(value) {\n value /= Math.abs(this.scale.y);\n this._bitmap.height = value;\n this._originalHeight = value;\n this.flagDirty();\n }\n _getTotalWidth() {\n var _a;\n return (((_a = this._originalWidth) !== null && _a !== void 0 ? _a : this._bitmap.width) + this.padding * 2) * 1;\n }\n _getTotalHeight() {\n var _a;\n return (((_a = this._originalHeight) !== null && _a !== void 0 ? _a : this._bitmap.height) + this.padding * 2) * 1;\n }\n /**\n * Returns the local bounds of the Raster including the padding\n */\n get localBounds() {\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\n }\n /**\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n */\n get smoothing() {\n return this._smoothing;\n }\n set smoothing(value) {\n this._smoothing = value;\n this.flagDirty();\n }\n /**\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */\n get color() {\n return this._color;\n }\n set color(value) {\n this.flagDirty();\n this._color = watch(value, () => this.flagDirty());\n }\n /**\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */\n get strokeColor() {\n return this._strokeColor;\n }\n set strokeColor(value) {\n this.flagDirty();\n this._strokeColor = watch(value, () => this.flagDirty());\n }\n /**\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */\n get lineWidth() {\n return this._lineWidth;\n }\n set lineWidth(value) {\n this._lineWidth = value;\n this.flagDirty();\n }\n get lineDash() {\n return this._lineDash;\n }\n set lineDash(value) {\n this._lineDash = value;\n this.flagDirty();\n }\n get padding() {\n return this._padding;\n }\n set padding(value) {\n this._padding = value;\n this.flagDirty();\n }\n /**\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\n */\n rasterize() {\n this._dirty = false;\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\n this._ctx.save();\n this._applyRasterProperties(this._ctx);\n this.execute(this._ctx);\n this._ctx.restore();\n }\n _applyRasterProperties(ctx) {\n var _a, _b, _c;\n this._bitmap.width = this._getTotalWidth() * this.quality;\n this._bitmap.height = this._getTotalHeight() * this.quality;\n // Do a bad thing to pass the filtering as an attribute\n this._bitmap.setAttribute('filtering', this.filtering);\n this._bitmap.setAttribute('forceUpload', 'true');\n ctx.scale(this.quality, this.quality);\n ctx.translate(this.padding, this.padding);\n ctx.imageSmoothingEnabled = this.smoothing;\n ctx.lineWidth = this.lineWidth;\n ctx.setLineDash((_a = this.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.lineCap = this.lineCap;\n ctx.strokeStyle = (_b = this.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = (_c = this.color) === null || _c === void 0 ? void 0 : _c.toString();\n }\n _drawImage(ex, x, y) {\n if (this._dirty) {\n this.rasterize();\n }\n ex.scale(1 / this.quality, 1 / this.quality);\n ex.drawImage(this._bitmap, x, y);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Canvas.ts\n\n/**\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\n *\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\n *\n * **Low performance API**\n */\nclass Canvas extends Raster {\n /**\n * Return the 2D graphics context of this canvas\n */\n get ctx() {\n return this._ctx;\n }\n constructor(_options) {\n super(_options);\n this._options = _options;\n }\n clone() {\n return new Canvas({\n ...this._options,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n var _a, _b;\n if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.draw) {\n (_b = this._options) === null || _b === void 0 ? void 0 : _b.draw(ctx);\n }\n if (!this._options.cache) {\n this.flagDirty();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Interfaces/AudioImplementation.ts\nclass ExResponse {\n}\nExResponse.type = {\n any: '',\n blob: 'blob',\n json: 'json',\n text: 'text',\n document: 'document',\n arraybuffer: 'arraybuffer'\n};\n\n;// CONCATENATED MODULE: ./Util/StateMachine.ts\nclass StateMachine {\n constructor() {\n this.states = new Map();\n }\n get currentState() {\n return this._currentState;\n }\n set currentState(state) {\n this._currentState = state;\n }\n static create(machineDescription, data) {\n const machine = new StateMachine();\n machine.data = data;\n for (const stateName in machineDescription.states) {\n machine.states.set(stateName, {\n name: stateName,\n ...machineDescription.states[stateName]\n });\n }\n // validate transitions are states\n for (const state of machine.states.values()) {\n for (const transitionState of state.transitions) {\n if (transitionState === '*') {\n continue;\n }\n if (!machine.states.has(transitionState)) {\n throw Error(`Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`);\n }\n }\n }\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\n return machine;\n }\n in(state) {\n return this.currentState.name === state;\n }\n go(stateName, eventData) {\n var _a, _b;\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes('*')) {\n const potentialNewState = this.states.get(stateName);\n if (this.currentState.onExit) {\n const canExit = (_a = this.currentState) === null || _a === void 0 ? void 0 : _a.onExit({ to: potentialNewState.name, data: this.data });\n if (canExit === false) {\n return false;\n }\n }\n if (potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter) {\n const canEnter = potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter({ from: this.currentState.name, eventData, data: this.data });\n if (canEnter === false) {\n return false;\n }\n }\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\n this.currentState = potentialNewState;\n if ((_b = this.currentState) === null || _b === void 0 ? void 0 : _b.onState) {\n this.currentState.onState();\n }\n return true;\n }\n return false;\n }\n update(elapsedMs) {\n if (this.currentState.onUpdate) {\n this.currentState.onUpdate(this.data, elapsedMs);\n }\n }\n save(saveKey) {\n localStorage.setItem(saveKey, JSON.stringify({\n currentState: this.currentState.name,\n data: this.data\n }));\n }\n restore(saveKey) {\n const state = JSON.parse(localStorage.getItem(saveKey));\n this.currentState = this.states.get(state.currentState);\n this.data = state.data;\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Sound/WebAudioInstance.ts\n\n\n\n\n/**\n * Internal class representing a Web Audio AudioBufferSourceNode instance\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\n */\nclass WebAudioInstance {\n _createNewBufferSource() {\n this._instance = this._audioContext.createBufferSource();\n this._instance.buffer = this._src;\n this._instance.loop = this.loop;\n this._instance.playbackRate.value = this._playbackRate;\n this._instance.connect(this._volumeNode);\n this._volumeNode.connect(this._audioContext.destination);\n }\n _handleEnd() {\n if (!this.loop) {\n this._instance.onended = () => {\n this._playingFuture.resolve(true);\n };\n }\n }\n set loop(value) {\n this._loop = value;\n if (this._instance) {\n this._instance.loop = value;\n if (!this.loop) {\n this._instance.onended = () => {\n this._playingFuture.resolve(true);\n };\n }\n }\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n value = clamp(value, 0, 1.0);\n this._volume = value;\n if (this._stateMachine.in('PLAYING') && this._volumeNode.gain.setTargetAtTime) {\n // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\n // This exponential ramp provides a more pleasant transition in gain\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\n }\n else {\n this._volumeNode.gain.value = value;\n }\n }\n get volume() {\n return this._volume;\n }\n /**\n * Returns the set duration to play, otherwise returns the total duration if unset\n */\n get duration() {\n var _a;\n return (_a = this._duration) !== null && _a !== void 0 ? _a : this.getTotalPlaybackDuration();\n }\n /**\n * Set the duration that this audio should play.\n *\n * Note: if you seek to a specific point the duration will start from that point, for example\n *\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\n */\n set duration(duration) {\n this._duration = duration;\n }\n constructor(_src) {\n this._src = _src;\n this._audioContext = AudioContextFactory.create();\n this._volumeNode = this._audioContext.createGain();\n this._playingFuture = new Future();\n this._stateMachine = StateMachine.create({\n start: 'STOPPED',\n states: {\n PLAYING: {\n onEnter: ({ data }) => {\n // Buffer nodes are single use\n this._createNewBufferSource();\n this._handleEnd();\n if (this.loop) {\n // when looping don't set a duration\n this._instance.start(0, data.pausedAt * this._playbackRate);\n }\n else {\n this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\n }\n data.startedAt = (this._audioContext.currentTime - data.pausedAt);\n data.pausedAt = 0;\n },\n onState: () => this._playStarted(),\n onExit: ({ to }) => {\n // If you've exited early only resolve if explicitly STOPPED\n if (to === 'STOPPED') {\n this._playingFuture.resolve(true);\n }\n // Whenever you're not playing... you stop!\n this._instance.onended = null; // disconnect the wired on-end handler\n this._instance.disconnect();\n this._instance.stop(0);\n this._instance = null;\n },\n transitions: ['STOPPED', 'PAUSED', 'SEEK']\n },\n SEEK: {\n onEnter: ({ eventData: position, data }) => {\n data.pausedAt = (position !== null && position !== void 0 ? position : 0) / this._playbackRate;\n data.startedAt = 0;\n },\n transitions: ['*']\n },\n STOPPED: {\n onEnter: ({ data }) => {\n data.pausedAt = 0;\n data.startedAt = 0;\n this._playingFuture.resolve(true);\n },\n transitions: ['PLAYING', 'PAUSED', 'SEEK']\n },\n PAUSED: {\n onEnter: ({ data }) => {\n // Playback rate will be a scale factor of how fast/slow the audio is being played\n // default is 1.0\n // we need to invert it to get the time scale\n data.pausedAt = (this._audioContext.currentTime - data.startedAt);\n },\n transitions: ['PLAYING', 'STOPPED', 'SEEK']\n }\n }\n }, {\n startedAt: 0,\n pausedAt: 0\n });\n this._volume = 1;\n this._loop = false;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n this._playStarted = () => { };\n this._playbackRate = 1.0;\n this._createNewBufferSource();\n }\n isPlaying() {\n return this._stateMachine.in('PLAYING');\n }\n isPaused() {\n return this._stateMachine.in('PAUSED') || this._stateMachine.in('SEEK');\n }\n isStopped() {\n return this._stateMachine.in('STOPPED');\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n play(playStarted = () => { }) {\n this._playStarted = playStarted;\n this._stateMachine.go('PLAYING');\n return this._playingFuture.promise;\n }\n pause() {\n this._stateMachine.go('PAUSED');\n }\n stop() {\n this._stateMachine.go('STOPPED');\n }\n seek(position) {\n this._stateMachine.go('PAUSED');\n this._stateMachine.go('SEEK', position);\n }\n getTotalPlaybackDuration() {\n return this._src.duration;\n }\n getPlaybackPosition() {\n const { pausedAt, startedAt } = this._stateMachine.data;\n if (pausedAt) {\n return pausedAt * this._playbackRate;\n }\n if (startedAt) {\n return (this._audioContext.currentTime - startedAt) * this._playbackRate;\n }\n return 0;\n }\n set playbackRate(playbackRate) {\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\n }\n get playbackRate() {\n return this._instance.playbackRate.value;\n }\n}\n\n;// CONCATENATED MODULE: ./Events.ts\nvar EventTypes;\n(function (EventTypes) {\n EventTypes[\"Kill\"] = \"kill\";\n EventTypes[\"PreKill\"] = \"prekill\";\n EventTypes[\"PostKill\"] = \"postkill\";\n EventTypes[\"PreDraw\"] = \"predraw\";\n EventTypes[\"PostDraw\"] = \"postdraw\";\n EventTypes[\"PreDebugDraw\"] = \"predebugdraw\";\n EventTypes[\"PostDebugDraw\"] = \"postdebugdraw\";\n EventTypes[\"PreUpdate\"] = \"preupdate\";\n EventTypes[\"PostUpdate\"] = \"postupdate\";\n EventTypes[\"PreFrame\"] = \"preframe\";\n EventTypes[\"PostFrame\"] = \"postframe\";\n EventTypes[\"PreCollision\"] = \"precollision\";\n EventTypes[\"CollisionStart\"] = \"collisionstart\";\n EventTypes[\"CollisionEnd\"] = \"collisionend\";\n EventTypes[\"PostCollision\"] = \"postcollision\";\n EventTypes[\"Initialize\"] = \"initialize\";\n EventTypes[\"Activate\"] = \"activate\";\n EventTypes[\"Deactivate\"] = \"deactivate\";\n EventTypes[\"ExitViewport\"] = \"exitviewport\";\n EventTypes[\"EnterViewport\"] = \"enterviewport\";\n EventTypes[\"ExitTrigger\"] = \"exit\";\n EventTypes[\"EnterTrigger\"] = \"enter\";\n EventTypes[\"Connect\"] = \"connect\";\n EventTypes[\"Disconnect\"] = \"disconnect\";\n EventTypes[\"Button\"] = \"button\";\n EventTypes[\"Axis\"] = \"axis\";\n EventTypes[\"Visible\"] = \"visible\";\n EventTypes[\"Hidden\"] = \"hidden\";\n EventTypes[\"Start\"] = \"start\";\n EventTypes[\"Stop\"] = \"stop\";\n EventTypes[\"PointerUp\"] = \"pointerup\";\n EventTypes[\"PointerDown\"] = \"pointerdown\";\n EventTypes[\"PointerMove\"] = \"pointermove\";\n EventTypes[\"PointerEnter\"] = \"pointerenter\";\n EventTypes[\"PointerLeave\"] = \"pointerleave\";\n EventTypes[\"PointerCancel\"] = \"pointercancel\";\n EventTypes[\"PointerWheel\"] = \"pointerwheel\";\n EventTypes[\"Up\"] = \"up\";\n EventTypes[\"Down\"] = \"down\";\n EventTypes[\"Move\"] = \"move\";\n EventTypes[\"Enter\"] = \"enter\";\n EventTypes[\"Leave\"] = \"leave\";\n EventTypes[\"Cancel\"] = \"cancel\";\n EventTypes[\"Wheel\"] = \"wheel\";\n EventTypes[\"Press\"] = \"press\";\n EventTypes[\"Release\"] = \"release\";\n EventTypes[\"Hold\"] = \"hold\";\n EventTypes[\"PointerDragStart\"] = \"pointerdragstart\";\n EventTypes[\"PointerDragEnd\"] = \"pointerdragend\";\n EventTypes[\"PointerDragEnter\"] = \"pointerdragenter\";\n EventTypes[\"PointerDragLeave\"] = \"pointerdragleave\";\n EventTypes[\"PointerDragMove\"] = \"pointerdragmove\";\n EventTypes[\"ActionStart\"] = \"actionstart\";\n EventTypes[\"ActionComplete\"] = \"actioncomplete\";\n})(EventTypes || (EventTypes = {}));\n/**\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\n * some events are unique to a type, others are not.\n *\n */\nclass GameEvent {\n constructor() {\n this._bubbles = true;\n }\n /**\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\n * to all actors that apply.\n */\n get bubbles() {\n return this._bubbles;\n }\n set bubbles(value) {\n this._bubbles = value;\n }\n /**\n * Prevents event from bubbling\n */\n stopPropagation() {\n this.bubbles = false;\n }\n}\n/**\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\n */\nclass KillEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'prekill' event is emitted directly before an actor is killed.\n */\nclass PreKillEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'postkill' event is emitted directly after the actor is killed.\n */\nclass PostKillEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'start' event is emitted on engine when has started and is ready for interaction.\n */\nclass GameStartEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\n */\nclass GameStopEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\n * transform so that all drawing takes place with the actor as the origin.\n *\n */\nclass PreDrawEvent extends GameEvent {\n constructor(ctx, delta, target) {\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\n * transform so that all drawing takes place with the actor as the origin.\n *\n */\nclass PostDrawEvent extends GameEvent {\n constructor(ctx, delta, target) {\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'pretransformdraw' event is emitted on actors/entities before any graphics transforms have taken place.\n * Useful if you need to completely customize the draw or modify the transform before drawing in the draw step (for example needing\n * latest camera positions)\n *\n */\nclass PreTransformDrawEvent extends GameEvent {\n constructor(ctx, delta, target) {\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'posttransformdraw' event is emitted on actors/entities after all graphics have been draw and transforms reset.\n * Useful if you need to completely custom the draw after everything is done.\n *\n */\nclass PostTransformDrawEvent extends GameEvent {\n constructor(ctx, delta, target) {\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\n */\nclass PreDebugDrawEvent extends GameEvent {\n constructor(ctx, target) {\n super();\n this.ctx = ctx;\n this.target = target;\n }\n}\n/**\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\n */\nclass PostDebugDrawEvent extends GameEvent {\n constructor(ctx, target) {\n super();\n this.ctx = ctx;\n this.target = target;\n }\n}\n/**\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\n */\nclass PreUpdateEvent extends GameEvent {\n constructor(engine, delta, target) {\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\n */\nclass PostUpdateEvent extends GameEvent {\n constructor(engine, delta, target) {\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'preframe' event is emitted on the engine, before the frame begins.\n */\nclass PreFrameEvent extends GameEvent {\n constructor(engine, prevStats) {\n super();\n this.engine = engine;\n this.prevStats = prevStats;\n this.target = engine;\n }\n}\n/**\n * The 'postframe' event is emitted on the engine, after a frame ends.\n */\nclass PostFrameEvent extends GameEvent {\n constructor(engine, stats) {\n super();\n this.engine = engine;\n this.stats = stats;\n this.target = engine;\n }\n}\n/**\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\n */\nclass GamepadConnectEvent extends GameEvent {\n constructor(index, gamepad) {\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n}\n/**\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\n */\nclass GamepadDisconnectEvent extends GameEvent {\n constructor(index, gamepad) {\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n}\n/**\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\n */\nclass GamepadButtonEvent extends GameEvent {\n /**\n * @param button The Gamepad button\n * @param value A numeric value between 0 and 1\n */\n constructor(button, value, target) {\n super();\n this.button = button;\n this.value = value;\n this.target = target;\n }\n}\n/**\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\n */\nclass GamepadAxisEvent extends GameEvent {\n /**\n * @param axis The Gamepad axis\n * @param value A numeric value between -1 and 1\n */\n constructor(axis, value, target) {\n super();\n this.axis = axis;\n this.value = value;\n this.target = target;\n }\n}\n/**\n * Event received by the [[Engine]] when the browser window is visible on a screen.\n */\nclass VisibleEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\n */\nclass HiddenEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\n */\nclass PreCollisionEvent extends GameEvent {\n /**\n * @param actor The actor the event was thrown on\n * @param other The actor that will collided with the current actor\n * @param side The side that will be collided with the current actor\n * @param intersection Intersection vector\n */\n constructor(actor, other, side, intersection, contact) {\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n this.target = actor;\n }\n}\n/**\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\n */\nclass PostCollisionEvent extends GameEvent {\n /**\n * @param actor The actor the event was thrown on\n * @param other The actor that did collide with the current actor\n * @param side The side that did collide with the current actor\n * @param intersection Intersection vector\n */\n constructor(actor, other, side, intersection, contact) {\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n}\nclass ContactStartEvent {\n constructor(target, other, side, contact) {\n this.target = target;\n this.other = other;\n this.side = side;\n this.contact = contact;\n }\n}\nclass ContactEndEvent {\n constructor(target, other, side, lastContact) {\n this.target = target;\n this.other = other;\n this.side = side;\n this.lastContact = lastContact;\n }\n}\nclass CollisionPreSolveEvent {\n constructor(target, other, side, intersection, contact) {\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n}\nclass CollisionPostSolveEvent {\n constructor(target, other, side, intersection, contact) {\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n}\n/**\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\n */\nclass CollisionStartEvent extends GameEvent {\n /**\n *\n * @param actor\n * @param other\n * @param side\n * @param contact\n */\n constructor(actor, other, side, contact) {\n super();\n this.other = other;\n this.side = side;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n}\n/**\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\n */\nclass CollisionEndEvent extends GameEvent {\n /**\n *\n */\n constructor(actor, other, side, lastContact) {\n super();\n this.other = other;\n this.side = side;\n this.lastContact = lastContact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n}\n/**\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\n */\nclass InitializeEvent extends GameEvent {\n /**\n * @param engine The reference to the current engine\n */\n constructor(engine, target) {\n super();\n this.engine = engine;\n this.target = target;\n }\n}\n/**\n * Event thrown on a [[Scene]] on activation\n */\nclass ActivateEvent extends GameEvent {\n /**\n * @param context The context for the scene activation\n */\n constructor(context, target) {\n super();\n this.context = context;\n this.target = target;\n }\n}\n/**\n * Event thrown on a [[Scene]] on deactivation\n */\nclass DeactivateEvent extends GameEvent {\n /**\n * @param context The context for the scene deactivation\n */\n constructor(context, target) {\n super();\n this.context = context;\n this.target = target;\n }\n}\n/**\n * Event thrown on an [[Actor]] when the graphics bounds completely leaves the screen.\n */\nclass ExitViewPortEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * Event thrown on an [[Actor]] when any part of the graphics bounds are on screen.\n */\nclass EnterViewPortEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\nclass EnterTriggerEvent extends GameEvent {\n constructor(target, actor) {\n super();\n this.target = target;\n this.actor = actor;\n }\n}\nclass ExitTriggerEvent extends GameEvent {\n constructor(target, actor) {\n super();\n this.target = target;\n this.actor = actor;\n }\n}\n/**\n * Event thrown on an [[Actor]] when an action starts.\n */\nclass ActionStartEvent extends GameEvent {\n constructor(action, target) {\n super();\n this.action = action;\n this.target = target;\n }\n}\n/**\n * Event thrown on an [[Actor]] when an action completes.\n */\nclass ActionCompleteEvent extends GameEvent {\n constructor(action, target) {\n super();\n this.action = action;\n this.target = target;\n }\n}\n\n;// CONCATENATED MODULE: ./Events/MediaEvents.ts\n\nclass MediaEvent extends GameEvent {\n /**\n * Media event cannot bubble\n */\n set bubbles(_value) {\n // stubbed\n }\n /**\n * Media event cannot bubble\n */\n get bubbles() {\n return false;\n }\n /**\n * Media event cannot bubble, so they have no path\n */\n get _path() {\n return null;\n }\n /**\n * Media event cannot bubble, so they have no path\n */\n set _path(_val) {\n // stubbed\n }\n constructor(target, _name = 'MediaEvent') {\n super();\n this.target = target;\n this._name = _name;\n }\n /**\n * Prevents event from bubbling\n */\n stopPropagation() {\n /**\n * Stub\n */\n }\n /**\n * Action, that calls when event happens\n */\n action() {\n /**\n * Stub\n */\n }\n /**\n * Propagate event further through event path\n */\n propagate() {\n /**\n * Stub\n */\n }\n layPath(_actor) {\n /**\n * Stub\n */\n }\n}\nclass NativeSoundEvent extends MediaEvent {\n constructor(target, track) {\n super(target, 'NativeSoundEvent');\n this.track = track;\n }\n}\nclass NativeSoundProcessedEvent extends MediaEvent {\n constructor(target, _processedData) {\n super(target, 'NativeSoundProcessedEvent');\n this._processedData = _processedData;\n this.data = this._processedData;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Sound.ts\n\n/**\n * Whether or not the browser can play this file as HTML5 Audio\n */\nfunction canPlayFile(file) {\n try {\n const a = new Audio();\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\n const type = file.match(filetype)[1];\n if (a.canPlayType('audio/' + type)) {\n return true;\n }\n else {\n return false;\n }\n }\n catch (e) {\n Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e);\n return false;\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Sound/Sound.ts\n\n\n\n\n\n\n\n\nconst SoundEvents = {\n VolumeChange: 'volumechange',\n Processed: 'processed',\n Pause: 'pause',\n Stop: 'stop',\n PlaybackEnd: 'playbackend',\n Resume: 'resume',\n PlaybackStart: 'playbackstart'\n};\n/**\n * The [[Sound]] object allows games built in Excalibur to load audio\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\n */\nclass Sound {\n /**\n * Indicates whether the clip should loop when complete\n * @param value Set the looping flag\n */\n set loop(value) {\n this._loop = value;\n for (const track of this._tracks) {\n track.loop = this._loop;\n }\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._loop);\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n this._volume = value;\n for (const track of this._tracks) {\n track.volume = this._volume;\n }\n this.events.emit('volumechange', new NativeSoundEvent(this));\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._volume);\n }\n get volume() {\n return this._volume;\n }\n /**\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\n */\n get duration() {\n return this._duration;\n }\n /**\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\n *\n * Note: if you seek to a specific point the duration will start from that point, for example\n *\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\n */\n set duration(duration) {\n this._duration = duration;\n }\n /**\n * Return array of Current AudioInstances playing or being paused\n */\n get instances() {\n return this._tracks;\n }\n get path() {\n return this._resource.path;\n }\n set path(val) {\n this._resource.path = val;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */\n get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\n */\n constructor(...paths) {\n this.events = new EventEmitter();\n this.logger = Logger.getInstance();\n this._loop = false;\n this._volume = 1;\n this._isStopped = false;\n // private _isPaused = false;\n this._tracks = [];\n this._wasPlayingOnHidden = false;\n this._playbackRate = 1.0;\n this._audioContext = AudioContextFactory.create();\n this._resource = new Resource('', ExResponse.type.arraybuffer);\n /**\n * Chrome : MP3, WAV, Ogg\n * Firefox : WAV, Ogg,\n * IE : MP3, WAV coming soon\n * Safari MP3, WAV, Ogg\n */\n for (const path of paths) {\n if (canPlayFile(path)) {\n this.path = path;\n break;\n }\n }\n if (!this.path) {\n this.logger.warn('This browser does not support any of the audio files specified:', paths.join(', '));\n this.logger.warn('Attempting to use', paths[0]);\n this.path = paths[0]; // select the first specified\n }\n }\n isLoaded() {\n return !!this.data;\n }\n async load() {\n var _a, _b;\n if (this.data) {\n return this.data;\n }\n const arraybuffer = await this._resource.load();\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\n this._duration = (_b = (_a = this._duration) !== null && _a !== void 0 ? _a : audiobuffer === null || audiobuffer === void 0 ? void 0 : audiobuffer.duration) !== null && _b !== void 0 ? _b : undefined;\n this.events.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer));\n return this.data = audiobuffer;\n }\n async decodeAudio(data) {\n try {\n return await this._audioContext.decodeAudioData(data.slice(0));\n }\n catch (e) {\n this.logger.error('Unable to decode ' +\n ' this browser may not fully support this format, or the file may be corrupt, ' +\n 'if this is an mp3 try removing id3 tags and album art from the file.');\n return await Promise.reject();\n }\n }\n wireEngine(engine) {\n if (engine) {\n this._engine = engine;\n this._engine.on('hidden', () => {\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\n this._wasPlayingOnHidden = true;\n this.pause();\n }\n });\n this._engine.on('visible', () => {\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.play();\n this._wasPlayingOnHidden = false;\n }\n });\n this._engine.on('start', () => {\n this._isStopped = false;\n });\n this._engine.on('stop', () => {\n this.stop();\n this._isStopped = true;\n });\n }\n }\n /**\n * Returns how many instances of the sound are currently playing\n */\n instanceCount() {\n return this._tracks.length;\n }\n /**\n * Whether or not the sound is playing right now\n */\n isPlaying() {\n return this._tracks.some((t) => t.isPlaying());\n }\n isPaused() {\n return this._tracks.some(t => t.isPaused());\n }\n isStopped() {\n return this._tracks.some(t => t.isStopped());\n }\n /**\n * Play the sound, returns a promise that resolves when the sound is done playing\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\n */\n play(volume) {\n if (!this.isLoaded()) {\n this.logger.warn('Cannot start playing. Resource', this.path, 'is not loaded yet');\n return Promise.resolve(true);\n }\n if (this._isStopped) {\n this.logger.warn('Cannot start playing. Engine is in a stopped state.');\n return Promise.resolve(false);\n }\n this.volume = volume || this.volume;\n if (this.isPaused()) {\n return this._resumePlayback();\n }\n else {\n return this._startPlayback();\n }\n }\n /**\n * Stop the sound, and do not rewind\n */\n pause() {\n if (!this.isPlaying()) {\n return;\n }\n for (const track of this._tracks) {\n track.pause();\n }\n this.events.emit('pause', new NativeSoundEvent(this));\n this.logger.debug('Paused all instances of sound', this.path);\n }\n /**\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\n */\n stop() {\n for (const track of this._tracks) {\n track.stop();\n }\n this.events.emit('stop', new NativeSoundEvent(this));\n this._tracks.length = 0;\n this.logger.debug('Stopped all instances of sound', this.path);\n }\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(playbackRate) {\n this._playbackRate = playbackRate;\n this._tracks.forEach(t => {\n t.playbackRate = this._playbackRate;\n });\n }\n seek(position, trackId = 0) {\n if (this._tracks.length === 0) {\n this._getTrackInstance(this.data);\n }\n this._tracks[trackId].seek(position);\n }\n getTotalPlaybackDuration() {\n if (!this.isLoaded()) {\n this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.` +\n `Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`);\n return 0;\n }\n return this.data.duration;\n }\n /**\n * Return the current playback time of the playing track in seconds from the start.\n *\n * Optionally specify the track to query if multiple are playing at once.\n * @param trackId\n */\n getPlaybackPosition(trackId = 0) {\n if (this._tracks.length) {\n return this._tracks[trackId].getPlaybackPosition();\n }\n return 0;\n }\n /**\n * Get Id of provided AudioInstance in current trackList\n * @param track [[Audio]] which Id is to be given\n */\n getTrackId(track) {\n return this._tracks.indexOf(track);\n }\n async _resumePlayback() {\n if (this.isPaused) {\n const resumed = [];\n // ensure we resume *current* tracks (if paused)\n for (const track of this._tracks) {\n resumed.push(track.play().then(() => {\n this._tracks.splice(this.getTrackId(track), 1);\n return true;\n }));\n }\n this.events.emit('resume', new NativeSoundEvent(this));\n this.logger.debug('Resuming paused instances for sound', this.path, this._tracks);\n // resolve when resumed tracks are done\n await Promise.all(resumed);\n }\n return true;\n }\n /**\n * Starts playback, returns a promise that resolves when playback is complete\n */\n async _startPlayback() {\n const track = this._getTrackInstance(this.data);\n const complete = await track.play(() => {\n this.events.emit('playbackstart', new NativeSoundEvent(this, track));\n this.logger.debug('Playing new instance for sound', this.path);\n });\n this.events.emit('playbackend', new NativeSoundEvent(this, track));\n // cleanup any done tracks\n const trackId = this.getTrackId(track);\n if (trackId !== -1) {\n this._tracks.splice(trackId, 1);\n }\n return complete;\n }\n _getTrackInstance(data) {\n const newTrack = new WebAudioInstance(data);\n newTrack.loop = this.loop;\n newTrack.volume = this.volume;\n newTrack.duration = this.duration;\n newTrack.playbackRate = this._playbackRate;\n this._tracks.push(newTrack);\n return newTrack;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n}\n\n;// CONCATENATED MODULE: ./Director/DefaultLoader.ts\n\n\n\n\n\n\n\n\n\nconst LoaderEvents = {\n // Add event types here\n BeforeLoad: 'beforeload',\n AfterLoad: 'afterload',\n UserAction: 'useraction',\n LoadResourceStart: 'loadresourcestart',\n LoadResourceEnd: 'loadresourceend'\n};\n/**\n * Returns true if the constructor is for an Excalibur Loader\n */\nfunction isLoaderConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n}\nclass DefaultLoader {\n get resources() {\n return this._resources;\n }\n /**\n * @param options Optionally provide the list of resources you want to load at constructor time\n */\n constructor(options) {\n var _a;\n this.events = new EventEmitter();\n this.canvas = new Canvas({\n filtering: ImageFiltering.Blended,\n smoothing: true,\n cache: false,\n draw: this.onDraw.bind(this)\n });\n this._resources = [];\n this._numLoaded = 0;\n this._totalTimeMs = 0;\n this._loadingFuture = new Future();\n if (options && ((_a = options.loadables) === null || _a === void 0 ? void 0 : _a.length)) {\n this.addResources(options.loadables);\n }\n }\n /**\n * Called by the engine before loading\n * @param engine\n */\n onInitialize(engine) {\n this.engine = engine;\n this.canvas.width = this.engine.screen.resolution.width;\n this.canvas.height = this.engine.screen.resolution.height;\n }\n /**\n * Return a promise that resolves when the user interacts with the loading screen in some way, usually a click.\n *\n * It's important to implement this in order to unlock the audio context in the browser. Browsers automatically prevent\n * audio from playing until the user performs an action.\n *\n */\n async onUserAction() {\n return await Promise.resolve();\n }\n /**\n * Overridable lifecycle method, called directly before loading starts\n */\n async onBeforeLoad() {\n // override me\n }\n /**\n * Overridable lifecycle method, called after loading has completed\n */\n async onAfterLoad() {\n // override me\n await delay(500, this.engine.clock); // avoid a flicker\n }\n /**\n * Add a resource to the loader to load\n * @param loadable Resource to add\n */\n addResource(loadable) {\n this._resources.push(loadable);\n }\n /**\n * Add a list of resources to the loader to load\n * @param loadables The list of resources to load\n */\n addResources(loadables) {\n let i = 0;\n const len = loadables.length;\n for (i; i < len; i++) {\n this.addResource(loadables[i]);\n }\n }\n markResourceComplete() {\n this._numLoaded++;\n }\n /**\n * Returns the progress of the loader as a number between [0, 1] inclusive.\n */\n get progress() {\n const total = this._resources.length;\n return total > 0 ? clamp(this._numLoaded, 0, total) / total : 1;\n }\n /**\n * Returns true if the loader has completely loaded all resources\n */\n isLoaded() {\n return this._numLoaded === this._resources.length;\n }\n /**\n * Optionally override the onUpdate\n * @param engine\n * @param elapsedMilliseconds\n */\n onUpdate(engine, elapsedMilliseconds) {\n this._totalTimeMs += elapsedMilliseconds;\n // override me\n }\n /**\n * Optionally override the onDraw\n */\n onDraw(ctx) {\n const seconds = this._totalTimeMs / 1000;\n ctx.fillStyle = Color.Black.toRGBA();\n ctx.fillRect(0, 0, this.engine.screen.resolution.width, this.engine.screen.resolution.height);\n ctx.save();\n ctx.translate(this.engine.screen.resolution.width / 2, this.engine.screen.resolution.height / 2);\n const speed = seconds * 10;\n ctx.strokeStyle = 'white';\n ctx.lineWidth = 10;\n ctx.lineCap = 'round';\n ctx.arc(0, 0, 40, speed, speed + (Math.PI * 3 / 2));\n ctx.stroke();\n ctx.fillStyle = 'white';\n ctx.font = '16px sans-serif';\n const text = (this.progress * 100).toFixed(0) + '%';\n const textbox = ctx.measureText(text);\n const width = Math.abs(textbox.actualBoundingBoxLeft) + Math.abs(textbox.actualBoundingBoxRight);\n const height = Math.abs(textbox.actualBoundingBoxAscent) + Math.abs(textbox.actualBoundingBoxDescent);\n ctx.fillText(text, -width / 2, height / 2); // center\n ctx.restore();\n }\n areResourcesLoaded() {\n return this._loadingFuture.promise;\n }\n /**\n * Not meant to be overridden\n *\n * Begin loading all of the supplied resources, returning a promise\n * that resolves when loading of all is complete AND the user has interacted with the loading screen\n */\n async load() {\n await this.onBeforeLoad();\n this.events.emit('beforeload');\n this.canvas.flagDirty();\n await Promise.all(this._resources.map(async (r) => {\n this.events.emit('loadresourcestart', r);\n await r.load().finally(() => {\n // capture progress\n this._numLoaded++;\n this.canvas.flagDirty();\n this.events.emit('loadresourceend', r);\n });\n }));\n // Wire all sound to the engine\n for (const resource of this._resources) {\n if (resource instanceof Sound) {\n resource.wireEngine(this.engine);\n }\n }\n this._loadingFuture.resolve();\n this.canvas.flagDirty();\n // Unlock browser AudioContext in after user gesture\n // See: https://github.com/excaliburjs/Excalibur/issues/262\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\n await this.onUserAction();\n this.events.emit('useraction');\n await WebAudio.unlock();\n await this.onAfterLoad();\n this.events.emit('afterload');\n return (this.data = this._resources);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n}\n\n;// CONCATENATED MODULE: ./Util/DrawUtil.ts\n\n/* istanbul ignore next */\n/**\n * Draw a line on canvas context\n * @param ctx The canvas context\n * @param color The color of the line\n * @param x1 The start x coordinate\n * @param y1 The start y coordinate\n * @param x2 The ending x coordinate\n * @param y2 The ending y coordinate\n * @param thickness The line thickness\n * @param cap The [[LineCapStyle]] (butt, round, or square)\n */\nfunction line(ctx, color = Color.Red, x1, y1, x2, y2, thickness = 1, cap = 'butt') {\n ctx.save();\n ctx.beginPath();\n ctx.lineWidth = thickness;\n ctx.lineCap = cap;\n ctx.strokeStyle = color.toString();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.closePath();\n ctx.stroke();\n ctx.restore();\n}\n/* istanbul ignore next */\n/**\n * Draw the vector as a point onto the canvas.\n */\nfunction point(ctx, color = Color.Red, point) {\n ctx.beginPath();\n ctx.strokeStyle = color.toString();\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\n ctx.closePath();\n ctx.stroke();\n}\n/**\n * Draw the vector as a line onto the canvas starting a origin point.\n */\n/* istanbul ignore next */\n/**\n *\n */\nfunction vector(ctx, color, origin, vector, scale = 1.0) {\n const c = color ? color.toString() : 'blue';\n const v = vector.scale(scale);\n ctx.beginPath();\n ctx.strokeStyle = c;\n ctx.moveTo(origin.x, origin.y);\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\n ctx.closePath();\n ctx.stroke();\n}\n/**\n * Draw a round rectangle on a canvas context\n * @param ctx The canvas context\n * @param x The top-left x coordinate\n * @param y The top-left y coordinate\n * @param width The width of the rectangle\n * @param height The height of the rectangle\n * @param radius The border radius of the rectangle\n * @param stroke The [[Color]] to stroke rectangle with\n * @param fill The [[Color]] to fill rectangle with\n */\nfunction roundRect(ctx, x, y, width, height, radius = 5, stroke = Color.White, fill = null) {\n let br;\n if (typeof radius === 'number') {\n br = { tl: radius, tr: radius, br: radius, bl: radius };\n }\n else {\n const defaultRadius = { tl: 0, tr: 0, br: 0, bl: 0 };\n for (const prop in defaultRadius) {\n if (defaultRadius.hasOwnProperty(prop)) {\n const side = prop;\n br[side] = radius[side] || defaultRadius[side];\n }\n }\n }\n ctx.beginPath();\n ctx.moveTo(x + br.tl, y);\n ctx.lineTo(x + width - br.tr, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\n ctx.lineTo(x + width, y + height - br.br);\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\n ctx.lineTo(x + br.bl, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\n ctx.lineTo(x, y + br.tl);\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n}\n/**\n *\n */\nfunction circle(ctx, x, y, radius, stroke = Color.White, fill = null) {\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, Math.PI * 2);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n}\n\n;// CONCATENATED MODULE: ./Director/Loader.logo.png\n/* harmony default export */ const Loader_logo = (\"data:image/png;base64,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\");\n// EXTERNAL MODULE: ./Director/Loader.css\nvar Director_Loader = __webpack_require__(7835);\n;// CONCATENATED MODULE: ./Director/Loader.ts\n\n\n\n\n\n\n\n\n/**\n * Pre-loading assets\n *\n * The loader provides a mechanism to preload multiple resources at\n * one time. The loader must be passed to the engine in order to\n * trigger the loading progress bar.\n *\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\n *\n * ## Example: Pre-loading resources for a game\n *\n * ```js\n * // create a loader\n * var loader = new ex.Loader();\n *\n * // create a resource dictionary (best practice is to keep a separate file)\n * var resources = {\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\n * };\n *\n * // loop through dictionary and add to loader\n * for (var loadable in resources) {\n * if (resources.hasOwnProperty(loadable)) {\n * loader.addResource(resources[loadable]);\n * }\n * }\n *\n * // start game\n * game.start(loader).then(function () {\n * console.log(\"Game started!\");\n * });\n * ```\n *\n * ## Customize the Loader\n *\n * The loader can be customized to show different, text, logo, background color, and button.\n *\n * ```typescript\n * const loader = new ex.Loader([playerTexture]);\n *\n * // The loaders button text can simply modified using this\n * loader.playButtonText = 'Start the best game ever';\n *\n * // The logo can be changed by inserting a base64 image string here\n *\n * loader.logo = 'data:image/png;base64,iVBORw...';\n * loader.logoWidth = 15;\n * loader.logoHeight = 14;\n *\n * // The background color can be changed like so by supplying a valid CSS color string\n *\n * loader.backgroundColor = 'red'\n * loader.backgroundColor = '#176BAA'\n *\n * // To build a completely new button\n * loader.startButtonFactory = () => {\n * let myButton = document.createElement('button');\n * myButton.textContent = 'The best button';\n * return myButton;\n * };\n *\n * engine.start(loader).then(() => {});\n * ```\n */\nclass Loader extends DefaultLoader {\n get _image() {\n if (!this._imageElement) {\n this._imageElement = new Image();\n this._imageElement.src = this.logo;\n }\n return this._imageElement;\n }\n get playButtonRootElement() {\n return this._playButtonRootElement;\n }\n get playButtonElement() {\n return this._playButtonElement;\n }\n get _playButton() {\n const existingRoot = document.getElementById('excalibur-play-root');\n if (existingRoot) {\n this._playButtonRootElement = existingRoot;\n }\n if (!this._playButtonRootElement) {\n this._playButtonRootElement = document.createElement('div');\n this._playButtonRootElement.id = 'excalibur-play-root';\n this._playButtonRootElement.style.position = 'absolute';\n document.body.appendChild(this._playButtonRootElement);\n }\n if (!this._styleBlock) {\n this._styleBlock = document.createElement('style');\n this._styleBlock.textContent = this._playButtonStyles;\n document.head.appendChild(this._styleBlock);\n }\n if (!this._playButtonElement) {\n this._playButtonElement = this.startButtonFactory();\n this._playButtonRootElement.appendChild(this._playButtonElement);\n }\n return this._playButtonElement;\n }\n constructor(loadablesOrOptions) {\n const options = Array.isArray(loadablesOrOptions) ? {\n loadables: loadablesOrOptions\n } : loadablesOrOptions;\n super(options);\n this._logger = Logger.getInstance();\n this._originalOptions = { loadables: [] };\n this.events = new EventEmitter();\n this._playButtonShown = false;\n // logo drawing stuff\n // base64 string encoding of the excalibur logo (logo-white.png)\n this.logo = Loader_logo;\n this.logoWidth = 468;\n this.logoHeight = 118;\n /**\n * Gets or sets the color of the loading bar, default is [[Color.White]]\n */\n this.loadingBarColor = Color.White;\n /**\n * Gets or sets the background color of the loader as a hex string\n */\n this.backgroundColor = '#176BAA';\n this.suppressPlayButton = false;\n /** Loads the css from Loader.css */\n this._playButtonStyles = Director_Loader/* default */.Z.toString();\n /**\n * Get/set play button text\n */\n this.playButtonText = 'Play game';\n /**\n * Return a html button element for excalibur to use as a play button\n */\n this.startButtonFactory = () => {\n let buttonElement = document.getElementById('excalibur-play');\n if (!buttonElement) {\n buttonElement = document.createElement('button');\n }\n buttonElement.id = 'excalibur-play';\n buttonElement.textContent = this.playButtonText;\n buttonElement.style.display = 'none';\n return buttonElement;\n };\n this._configuredPixelRatio = null;\n this._originalOptions = { ...Loader._DEFAULT_LOADER_OPTIONS, ...options };\n }\n onInitialize(engine) {\n this.engine = engine;\n this.screen = engine.screen;\n this.canvas.width = this.engine.canvas.width;\n this.canvas.height = this.engine.canvas.height;\n }\n /**\n * Shows the play button and returns a promise that resolves when clicked\n */\n async showPlayButton() {\n var _a, _b;\n if (this.suppressPlayButton) {\n this.hidePlayButton();\n // Delay is to give the logo a chance to show, otherwise don't delay\n await delay(500, (_a = this.engine) === null || _a === void 0 ? void 0 : _a.clock);\n }\n else {\n const resizeHandler = () => {\n try {\n this._positionPlayButton();\n }\n catch (_a) {\n // swallow if can't position\n }\n ;\n };\n if ((_b = this.engine) === null || _b === void 0 ? void 0 : _b.browser) {\n this.engine.browser.window.on('resize', resizeHandler);\n }\n this._playButtonShown = true;\n this._playButton.style.display = 'block';\n document.body.addEventListener('keyup', (evt) => {\n if (evt.key === 'Enter') {\n this._playButton.click();\n }\n });\n this._positionPlayButton();\n const playButtonClicked = new Promise(resolve => {\n const startButtonHandler = (e) => {\n var _a;\n // We want to stop propagation to keep bubbling to the engine pointer handlers\n e.stopPropagation();\n // Hide Button after click\n this.hidePlayButton();\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.browser) {\n this.engine.browser.window.off('resize', resizeHandler);\n }\n if (this._originalOptions.fullscreenAfterLoad) {\n try {\n this._logger.info('requesting fullscreen');\n if (this._originalOptions.fullscreenContainer instanceof HTMLElement) {\n this._originalOptions.fullscreenContainer.requestFullscreen();\n }\n else {\n this.engine.screen.goFullScreen(this._originalOptions.fullscreenContainer);\n }\n }\n catch (error) {\n this._logger.error('could not go fullscreen', error);\n }\n }\n resolve();\n };\n this._playButton.addEventListener('click', startButtonHandler);\n this._playButton.addEventListener('touchend', startButtonHandler);\n this._playButton.addEventListener('pointerup', startButtonHandler);\n });\n return await playButtonClicked;\n }\n }\n hidePlayButton() {\n this._playButtonShown = false;\n this._playButton.style.display = 'none';\n }\n /**\n * Clean up generated elements for the loader\n */\n dispose() {\n if (this._playButtonRootElement.parentElement) {\n this._playButtonRootElement.removeChild(this._playButtonElement);\n document.body.removeChild(this._playButtonRootElement);\n document.head.removeChild(this._styleBlock);\n this._playButtonRootElement = null;\n this._playButtonElement = null;\n this._styleBlock = null;\n }\n }\n async onUserAction() {\n var _a;\n // short delay in showing the button for aesthetics\n await delay(200, (_a = this.engine) === null || _a === void 0 ? void 0 : _a.clock);\n this.canvas.flagDirty();\n // show play button\n await this.showPlayButton();\n }\n async onBeforeLoad() {\n var _a;\n this._configuredPixelRatio = this.screen.pixelRatioOverride;\n // Push the current user entered resolution/viewport\n this.screen.pushResolutionAndViewport();\n // Configure resolution for loader, it expects resolution === viewport\n this.screen.resolution = this.screen.viewport;\n this.screen.pixelRatioOverride = 1;\n this.screen.applyResolutionAndViewport();\n this.canvas.width = this.engine.canvas.width;\n this.canvas.height = this.engine.canvas.height;\n await ((_a = this._image) === null || _a === void 0 ? void 0 : _a.decode()); // decode logo if it exists\n }\n // eslint-disable-next-line require-await\n async onAfterLoad() {\n this.screen.pixelRatioOverride = this._configuredPixelRatio;\n this.screen.popResolutionAndViewport();\n this.screen.applyResolutionAndViewport();\n this.dispose();\n }\n _positionPlayButton() {\n if (this.engine) {\n const screenHeight = this.engine.screen.viewport.height;\n const screenWidth = this.engine.screen.viewport.width;\n if (this._playButtonRootElement) {\n const left = this.engine.canvas.offsetLeft;\n const top = this.engine.canvas.offsetTop;\n const buttonWidth = this._playButton.clientWidth;\n const buttonHeight = this._playButton.clientHeight;\n if (this.playButtonPosition) {\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\n }\n else {\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\n }\n }\n }\n }\n /**\n * Loader draw function. Draws the default Excalibur loading screen.\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\n * to customize the drawing, or just override entire method.\n */\n onDraw(ctx) {\n const canvasHeight = this.engine.canvasHeight / this.engine.pixelRatio;\n const canvasWidth = this.engine.canvasWidth / this.engine.pixelRatio;\n this._positionPlayButton();\n ctx.fillStyle = this.backgroundColor;\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\n let logoY = canvasHeight / 2;\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\n let logoX = canvasWidth / 2 - width / 2;\n if (this.logoPosition) {\n logoX = this.logoPosition.x;\n logoY = this.logoPosition.y;\n }\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\n const oldAntialias = this.engine.getAntialiasing();\n this.engine.setAntialiasing(true);\n if (!this.logoPosition) {\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\n }\n else {\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\n }\n // loading box\n if (!this.suppressPlayButton && this._playButtonShown) {\n this.engine.setAntialiasing(oldAntialias);\n return;\n }\n let loadingX = logoX;\n let loadingY = logoY;\n if (this.loadingBarPosition) {\n loadingX = this.loadingBarPosition.x;\n loadingY = this.loadingBarPosition.y;\n }\n ctx.lineWidth = 2;\n roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\n const progress = width * this.progress;\n const margin = 5;\n const progressWidth = progress - margin * 2;\n const height = 20 - margin * 2;\n roundRect(ctx, loadingX + margin, loadingY + margin, progressWidth > 10 ? progressWidth : 10, height, 5, null, this.loadingBarColor);\n this.engine.setAntialiasing(oldAntialias);\n }\n}\nLoader._DEFAULT_LOADER_OPTIONS = {\n loadables: [],\n fullscreenAfterLoad: false,\n fullscreenContainer: undefined\n};\n\n;// CONCATENATED MODULE: ./Util/Detector.ts\n\n/**\n * This is the list of features that will be used to log the supported\n * features to the console when Detector.logBrowserFeatures() is called.\n */\nconst REPORTED_FEATURES = {\n webgl: 'WebGL',\n webaudio: 'WebAudio',\n gamepadapi: 'Gamepad API'\n};\n/**\n * Excalibur internal feature detection helper class\n */\nclass Detector {\n constructor() {\n this._features = null;\n this.failedTests = [];\n // critical browser features required for ex to run\n this._criticalTests = {\n // Test canvas/2d context support\n canvasSupport: function () {\n const elem = document.createElement('canvas');\n return !!(elem.getContext && elem.getContext('2d'));\n },\n // Test array buffer support ex uses for downloading binary data\n arrayBufferSupport: function () {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', '/');\n try {\n xhr.responseType = 'arraybuffer';\n }\n catch (e) {\n return false;\n }\n return xhr.responseType === 'arraybuffer';\n },\n // Test data urls ex uses for sprites\n dataUrlSupport: function () {\n const canvas = document.createElement('canvas');\n return canvas.toDataURL('image/png').indexOf('data:image/png') === 0;\n },\n // Test object url support for loading\n objectUrlSupport: function () {\n return 'URL' in window && 'revokeObjectURL' in URL && 'createObjectURL' in URL;\n },\n // RGBA support for colors\n rgbaSupport: function () {\n const style = document.createElement('a').style;\n style.cssText = 'background-color:rgba(150,255,150,.5)';\n return ('' + style.backgroundColor).indexOf('rgba') > -1;\n }\n };\n // warnings excalibur performance will be degraded\n this._warningTest = {\n webAudioSupport: function () {\n return !!(window.AudioContext ||\n window.webkitAudioContext ||\n window.mozAudioContext ||\n window.msAudioContext ||\n window.oAudioContext);\n },\n webglSupport: function () {\n const elem = document.createElement('canvas');\n return !!(elem.getContext && elem.getContext('webgl'));\n }\n };\n this._features = this._loadBrowserFeatures();\n }\n /**\n * Returns a map of currently supported browser features. This method\n * treats the features as a singleton and will only calculate feature\n * support if it has not previously been done.\n */\n getBrowserFeatures() {\n if (this._features === null) {\n this._features = this._loadBrowserFeatures();\n }\n return this._features;\n }\n /**\n * Report on non-critical browser support for debugging purposes.\n * Use native browser console colors for visibility.\n */\n logBrowserFeatures() {\n let msg = '%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n';\n const args = ['font-weight: bold; color: navy', 'font-weight: normal; color: inherit'];\n const supported = this.getBrowserFeatures();\n for (const feature of Object.keys(REPORTED_FEATURES)) {\n if (supported[feature]) {\n msg += '(%c\\u2713%c)'; // (✓)\n args.push('font-weight: bold; color: green');\n args.push('font-weight: normal; color: inherit');\n }\n else {\n msg += '(%c\\u2717%c)'; // (✗)\n args.push('font-weight: bold; color: red');\n args.push('font-weight: normal; color: inherit');\n }\n msg += ' ' + REPORTED_FEATURES[feature] + '\\n';\n }\n args.unshift(msg);\n // eslint-disable-next-line no-console\n console.log.apply(console, args);\n }\n /**\n * Executes several IIFE's to get a constant reference to supported\n * features within the current execution context.\n */\n _loadBrowserFeatures() {\n return {\n // IIFE to check canvas support\n canvas: (() => {\n return this._criticalTests.canvasSupport();\n })(),\n // IIFE to check arraybuffer support\n arraybuffer: (() => {\n return this._criticalTests.arrayBufferSupport();\n })(),\n // IIFE to check dataurl support\n dataurl: (() => {\n return this._criticalTests.dataUrlSupport();\n })(),\n // IIFE to check objecturl support\n objecturl: (() => {\n return this._criticalTests.objectUrlSupport();\n })(),\n // IIFE to check rgba support\n rgba: (() => {\n return this._criticalTests.rgbaSupport();\n })(),\n // IIFE to check webaudio support\n webaudio: (() => {\n return this._warningTest.webAudioSupport();\n })(),\n // IIFE to check webgl support\n webgl: (() => {\n return this._warningTest.webglSupport();\n })(),\n // IIFE to check gamepadapi support\n gamepadapi: (() => {\n return !!navigator.getGamepads;\n })()\n };\n }\n test() {\n // Critical test will for ex not to run\n let failedCritical = false;\n for (const test in this._criticalTests) {\n if (!this._criticalTests[test].call(this)) {\n this.failedTests.push(test);\n Logger.getInstance().error('Critical browser feature missing, Excalibur requires:', test);\n failedCritical = true;\n }\n }\n if (failedCritical) {\n return false;\n }\n // Warning tests do not for ex to return false to compatibility\n for (const warning in this._warningTest) {\n if (!this._warningTest[warning]()) {\n Logger.getInstance().warn('Warning browser feature missing, Excalibur will have reduced performance:', warning);\n }\n }\n return true;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/CollisionType.ts\n/**\n * An enum that describes the types of collisions bodies can participate in\n */\nvar CollisionType;\n(function (CollisionType) {\n /**\n * Bodies with the `PreventCollision` setting do not participate in any\n * collisions and do not raise collision events.\n */\n CollisionType[\"PreventCollision\"] = \"PreventCollision\";\n /**\n * Bodies with the `Passive` setting only raise collision events, but are not\n * influenced or moved by other bodies and do not influence or move other bodies.\n * This is useful for use in trigger type behavior.\n */\n CollisionType[\"Passive\"] = \"Passive\";\n /**\n * Bodies with the `Active` setting raise collision events and participate\n * in collisions with other bodies and will be push or moved by bodies sharing\n * the `Active` or `Fixed` setting.\n */\n CollisionType[\"Active\"] = \"Active\";\n /**\n * Bodies with the `Fixed` setting raise collision events and participate in\n * collisions with other bodies. Actors with the `Fixed` setting will not be\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\n * not be pushed or moved by each other, they will not interact except to throw\n * collision events.\n */\n CollisionType[\"Fixed\"] = \"Fixed\";\n})(CollisionType || (CollisionType = {}));\n\n;// CONCATENATED MODULE: ./Math/coord-plane.ts\n/**\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\n */\nvar CoordPlane;\n(function (CoordPlane) {\n /**\n * The world coordinate plane (default) represents world space, any entities drawn with world\n * space move when the camera moves.\n */\n CoordPlane[\"World\"] = \"world\";\n /**\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\n * to screen coordinates ignoring the camera.\n */\n CoordPlane[\"Screen\"] = \"screen\";\n})(CoordPlane || (CoordPlane = {}));\n\n;// CONCATENATED MODULE: ./Math/vector-view.ts\n\nclass VectorView extends Vector {\n constructor(options) {\n super(0, 0);\n this._getX = options.getX;\n this._getY = options.getY;\n this._setX = options.setX;\n this._setY = options.setY;\n }\n get x() {\n return (this._x = this._getX());\n }\n set x(val) {\n this._setX(val);\n this._x = val;\n }\n get y() {\n return (this._y = this._getY());\n }\n set y(val) {\n this._setY(val);\n this._y = val;\n }\n}\n\n;// CONCATENATED MODULE: ./Math/watch-vector.ts\n\n/**\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\n */\nclass WatchVector extends Vector {\n constructor(original, change) {\n super(original.x, original.y);\n this.original = original;\n this.change = change;\n }\n get x() {\n return this._x = this.original.x;\n }\n set x(newX) {\n this.change(newX, this._y);\n this._x = this.original.x = newX;\n }\n get y() {\n return this._y = this.original.y;\n }\n set y(newY) {\n this.change(this._x, newY);\n this._y = this.original.y = newY;\n }\n}\n\n;// CONCATENATED MODULE: ./Math/transform.ts\n\n\n\n\n\nclass transform_Transform {\n constructor() {\n this._parent = null;\n this._children = [];\n this._pos = vec(0, 0);\n this._rotation = 0;\n this._scale = vec(1, 1);\n this._isDirty = false;\n this._isInverseDirty = false;\n this._matrix = AffineMatrix.identity();\n this._inverse = AffineMatrix.identity();\n }\n get parent() {\n return this._parent;\n }\n set parent(transform) {\n if (this._parent) {\n const index = this._parent._children.indexOf(this);\n if (index > -1) {\n this._parent._children.splice(index, 1);\n }\n }\n this._parent = transform;\n if (this._parent) {\n this._parent._children.push(this);\n }\n this.flagDirty();\n }\n get children() {\n return this._children;\n }\n set pos(v) {\n if (!v.equals(this._pos)) {\n this._pos.x = v.x;\n this._pos.y = v.y;\n this.flagDirty();\n }\n }\n get pos() {\n return new WatchVector(this._pos, (x, y) => {\n if (x !== this._pos.x || y !== this._pos.y) {\n this.flagDirty();\n }\n });\n }\n set globalPos(v) {\n let localPos = v.clone();\n if (this.parent) {\n localPos = this.parent.inverse.multiply(v);\n }\n if (!localPos.equals(this._pos)) {\n this._pos = localPos;\n this.flagDirty();\n }\n }\n get globalPos() {\n return new VectorView({\n getX: () => this.matrix.data[4],\n getY: () => this.matrix.data[5],\n setX: (x) => {\n if (this.parent) {\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\n this.pos.x = newX;\n }\n else {\n this.pos.x = x;\n }\n if (x !== this.matrix.data[4]) {\n this.flagDirty();\n }\n },\n setY: (y) => {\n if (this.parent) {\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\n this.pos.y = newY;\n }\n else {\n this.pos.y = y;\n }\n if (y !== this.matrix.data[5]) {\n this.flagDirty();\n }\n }\n });\n }\n set rotation(rotation) {\n const canonRotation = canonicalizeAngle(rotation);\n if (canonRotation !== this._rotation) {\n this.flagDirty();\n }\n this._rotation = canonRotation;\n }\n get rotation() {\n return this._rotation;\n }\n set globalRotation(rotation) {\n let inverseRotation = 0;\n if (this.parent) {\n inverseRotation = this.parent.globalRotation;\n }\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\n if (canonRotation !== this._rotation) {\n this.flagDirty();\n }\n this._rotation = canonRotation;\n }\n get globalRotation() {\n if (this.parent) {\n return this.matrix.getRotation();\n }\n return this.rotation;\n }\n set scale(v) {\n if (!v.equals(this._scale)) {\n this._scale.x = v.x;\n this._scale.y = v.y;\n this.flagDirty();\n }\n }\n get scale() {\n return new WatchVector(this._scale, (x, y) => {\n if (x !== this._scale.x || y !== this._scale.y) {\n this.flagDirty();\n }\n });\n }\n set globalScale(v) {\n let inverseScale = vec(1, 1);\n if (this.parent) {\n inverseScale = this.parent.globalScale;\n }\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\n }\n get globalScale() {\n return new VectorView({\n getX: () => this.parent ? this.matrix.getScaleX() : this.scale.x,\n getY: () => this.parent ? this.matrix.getScaleY() : this.scale.y,\n setX: (x) => {\n if (this.parent) {\n const globalScaleX = this.parent.globalScale.x;\n this.scale.x = x / globalScaleX;\n }\n else {\n this.scale.x = x;\n }\n },\n setY: (y) => {\n if (this.parent) {\n const globalScaleY = this.parent.globalScale.y;\n this.scale.y = y / globalScaleY;\n }\n else {\n this.scale.y = y;\n }\n }\n });\n }\n get matrix() {\n if (this._isDirty) {\n if (this.parent === null) {\n this._matrix = this._calculateMatrix();\n }\n else {\n this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\n }\n this._isDirty = false;\n }\n return this._matrix;\n }\n get inverse() {\n if (this._isInverseDirty) {\n this._inverse = this.matrix.inverse();\n this._isInverseDirty = false;\n }\n return this._inverse;\n }\n _calculateMatrix() {\n const matrix = AffineMatrix.identity()\n .translate(this.pos.x, this.pos.y)\n .rotate(this.rotation)\n .scale(this.scale.x, this.scale.y);\n return matrix;\n }\n flagDirty() {\n this._isDirty = true;\n this._isInverseDirty = true;\n for (let i = 0; i < this._children.length; i++) {\n this._children[i].flagDirty();\n }\n }\n apply(point) {\n return this.matrix.multiply(point);\n }\n applyInverse(point) {\n return this.inverse.multiply(point);\n }\n setTransform(pos, rotation, scale) {\n this._pos.x = pos.x;\n this._pos.y = pos.y;\n this._rotation = canonicalizeAngle(rotation);\n this._scale.x = scale.x;\n this._scale.y = scale.y;\n this.flagDirty();\n }\n /**\n * Clones the current transform\n * **Warning does not clone the parent**\n * @param dest\n */\n clone(dest) {\n const target = dest !== null && dest !== void 0 ? dest : new transform_Transform();\n this._pos.clone(target._pos);\n target._rotation = this._rotation;\n this._scale.clone(target._scale);\n target.flagDirty();\n return target;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Component.ts\n/**\n *\n */\nfunction isComponentCtor(value) {\n return !!value && !!value.prototype && !!value.prototype.constructor;\n}\n/**\n * Type guard to check if a component implements clone\n * @param x\n */\nfunction hasClone(x) {\n return !!(x === null || x === void 0 ? void 0 : x.clone);\n}\n/**\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\n *\n * Implementations of Component must have a zero-arg constructor to support dependencies\n *\n * ```typescript\n * class MyComponent extends ex.Component {\n * // zero arg support required if you want to use component dependencies\n * constructor(public optionalPos?: ex.Vector) {}\n * }\n * ```\n */\nclass Component {\n constructor() {\n // TODO maybe generate a unique id?\n /**\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\n */\n this.owner = undefined;\n }\n /**\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\n */\n clone() {\n const newComponent = new this.constructor();\n for (const prop in this) {\n if (this.hasOwnProperty(prop)) {\n const val = this[prop];\n if (hasClone(val) && prop !== 'owner' && prop !== 'clone') {\n newComponent[prop] = val.clone();\n }\n else {\n newComponent[prop] = val;\n }\n }\n }\n return newComponent;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Observable.ts\n/**\n * Simple Observable implementation\n * @template T is the typescript Type that defines the data being observed\n */\nclass Observable {\n constructor() {\n this.observers = [];\n this.subscriptions = [];\n }\n /**\n * Register an observer to listen to this observable\n * @param observer\n */\n register(observer) {\n this.observers.push(observer);\n }\n /**\n * Register a callback to listen to this observable\n * @param func\n */\n subscribe(func) {\n this.subscriptions.push(func);\n }\n /**\n * Remove an observer from the observable\n * @param observer\n */\n unregister(observer) {\n const i = this.observers.indexOf(observer);\n if (i !== -1) {\n this.observers.splice(i, 1);\n }\n }\n /**\n * Remove a callback that is listening to this observable\n * @param func\n */\n unsubscribe(func) {\n const i = this.subscriptions.indexOf(func);\n if (i !== -1) {\n this.subscriptions.splice(i, 1);\n }\n }\n /**\n * Broadcasts a message to all observers and callbacks\n * @param message\n */\n notifyAll(message) {\n const observersLength = this.observers.length;\n for (let i = 0; i < observersLength; i++) {\n this.observers[i].notify(message);\n }\n const subscriptionsLength = this.subscriptions.length;\n for (let i = 0; i < subscriptionsLength; i++) {\n this.subscriptions[i](message);\n }\n }\n /**\n * Removes all observers and callbacks\n */\n clear() {\n this.observers.length = 0;\n this.subscriptions.length = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Components/TransformComponent.ts\n\n\n\n\n\nclass TransformComponent extends Component {\n constructor() {\n super(...arguments);\n this._logger = Logger.getInstance();\n this._parentComponent = null;\n this._transform = new transform_Transform();\n this._addChildTransform = (child) => {\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) {\n childTxComponent._transform.parent = this._transform;\n childTxComponent._parentComponent = this;\n }\n };\n /**\n * Observable that emits when the z index changes on this component\n */\n this.zIndexChanged$ = new Observable();\n this._z = 0;\n this._coordPlane = CoordPlane.World;\n }\n get() {\n return this._transform;\n }\n onAdd(owner) {\n for (const child of owner.children) {\n this._addChildTransform(child);\n }\n owner.childrenAdded$.subscribe(child => this._addChildTransform(child));\n owner.childrenRemoved$.subscribe(child => {\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) {\n childTxComponent._transform.parent = null;\n childTxComponent._parentComponent = null;\n }\n });\n }\n onRemove(_previousOwner) {\n this._transform.parent = null;\n this._parentComponent = null;\n }\n /**\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\n * For example z=99 would be drawn on top of z=0.\n */\n get z() {\n return this._z;\n }\n set z(val) {\n const oldz = this._z;\n this._z = val;\n if (oldz !== val) {\n this.zIndexChanged$.notifyAll(val);\n }\n }\n /**\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\n */\n get coordPlane() {\n if (this._parentComponent) {\n return this._parentComponent.coordPlane;\n }\n return this._coordPlane;\n }\n set coordPlane(value) {\n var _a;\n if (!this._parentComponent) {\n this._coordPlane = value;\n }\n else {\n this._logger.warn(`Cannot set coordinate plane on child entity ${(_a = this.owner) === null || _a === void 0 ? void 0 : _a.name}, children inherit their coordinate plane from their parents.`);\n }\n }\n get pos() {\n return this._transform.pos;\n }\n set pos(v) {\n this._transform.pos = v;\n }\n get globalPos() {\n return this._transform.globalPos;\n }\n set globalPos(v) {\n this._transform.globalPos = v;\n }\n get rotation() {\n return this._transform.rotation;\n }\n set rotation(rotation) {\n this._transform.rotation = rotation;\n }\n get globalRotation() {\n return this._transform.globalRotation;\n }\n set globalRotation(rotation) {\n this._transform.globalRotation = rotation;\n }\n get scale() {\n return this._transform.scale;\n }\n set scale(v) {\n this._transform.scale = v;\n }\n get globalScale() {\n return this._transform.globalScale;\n }\n set globalScale(v) {\n this._transform.globalScale = v;\n }\n applyInverse(v) {\n return this._transform.applyInverse(v);\n }\n apply(v) {\n return this._transform.apply(v);\n }\n clone() {\n const component = new TransformComponent();\n component._transform = this._transform.clone();\n component._z = this._z;\n return component;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Components/MotionComponent.ts\n\n\nclass MotionComponent extends Component {\n constructor() {\n super(...arguments);\n /**\n * The velocity of an entity in pixels per second\n */\n this.vel = Vector.Zero;\n /**\n * The acceleration of entity in pixels per second^2\n */\n this.acc = Vector.Zero;\n /**\n * The scale rate of change in scale units per second\n */\n this.scaleFactor = Vector.Zero;\n /**\n * The angular velocity which is how quickly the entity is rotating in radians per second\n */\n this.angularVelocity = 0;\n /**\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\n */\n this.torque = 0;\n /**\n * Inertia can be thought of as the resistance to motion\n */\n this.inertia = 1;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Group/CollisionGroupManager.ts\n\n/**\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\n */\nclass CollisionGroupManager {\n /**\n * Create a new named collision group up to a max of 32.\n * @param name Name for the collision group\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\n */\n static create(name, mask) {\n if (this._CURRENT_GROUP > this._MAX_GROUPS) {\n throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\n }\n if (this._GROUPS.get(name)) {\n const existingGroup = this._GROUPS.get(name);\n if (existingGroup.mask === mask) {\n return existingGroup;\n }\n throw new Error(`Collision group ${name} already exists with a different mask!`);\n }\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\n this._CURRENT_BIT = (this._CURRENT_BIT << 1) | 0;\n this._CURRENT_GROUP++;\n this._GROUPS.set(name, group);\n return group;\n }\n /**\n * Get all collision groups currently tracked by excalibur\n */\n static get groups() {\n return Array.from(this._GROUPS.values());\n }\n /**\n * Get a collision group by it's name\n * @param name\n */\n static groupByName(name) {\n return this._GROUPS.get(name);\n }\n /**\n * Resets the managers internal group management state\n */\n static reset() {\n this._GROUPS = new Map();\n this._CURRENT_BIT = this._STARTING_BIT;\n this._CURRENT_GROUP = 1;\n }\n}\n// using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\nCollisionGroupManager._STARTING_BIT = 0b1 | 0;\nCollisionGroupManager._MAX_GROUPS = 32;\nCollisionGroupManager._CURRENT_GROUP = 1;\nCollisionGroupManager._CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\nCollisionGroupManager._GROUPS = new Map();\n\n;// CONCATENATED MODULE: ./Collision/Group/CollisionGroup.ts\n\n/**\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\n *\n * For example:\n *\n * Players have collision group \"player\"\n *\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\n *\n * Enemies have collision group \"enemy\"\n *\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\n *\n * Blocks have collision group \"ground\"\n *\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\n *\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\n * with players and blocks.\n *\n * This is done with bitmasking, see the following pseudo-code\n *\n * PlayerGroup = `0b001`\n * PlayerGroupMask = `0b110`\n *\n * EnemyGroup = `0b010`\n * EnemyGroupMask = `0b101`\n *\n * BlockGroup = `0b100`\n * BlockGroupMask = `0b011`\n *\n * Should Players collide? No because the bitwise mask evaluates to 0\n * `(player1.group & player2.mask) === 0`\n * `(0b001 & 0b110) === 0`\n *\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\n * `(player1.group & enemy1.mask) === 1`\n * `(0b001 & 0b101) === 1`\n *\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\n * `(player1.group & blocks1.mask) === 1`\n * `(0b001 & 0b011) === 1`\n */\nclass CollisionGroup {\n /**\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\n * @param name Name of the collision group\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\n */\n constructor(name, category, mask) {\n this._name = name;\n this._category = category;\n this._mask = mask;\n }\n /**\n * Get the name of the collision group\n */\n get name() {\n return this._name;\n }\n /**\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\n */\n get category() {\n return this._category;\n }\n /**\n * Get the mask for this collision group\n */\n get mask() {\n return this._mask;\n }\n /**\n * Evaluates whether 2 collision groups can collide\n *\n * This means the mask has the same bit set the other category and vice versa\n * @param other CollisionGroup\n */\n canCollide(other) {\n const overlap1 = this.category & other.mask;\n const overlap2 = this.mask & other.category;\n return (overlap1 !== 0) && (overlap2 !== 0);\n }\n /**\n * Inverts the collision group. For example, if before the group specified \"players\",\n * inverting would specify all groups except players\n * @returns CollisionGroup\n */\n invert() {\n const group = CollisionGroupManager.create('~(' + this.name + ')', ~this.mask | 0);\n group._category = ~this.category;\n return group;\n }\n /**\n * Combine collision groups with each other. The new group includes all of the previous groups.\n * @param collisionGroups\n */\n static combine(collisionGroups) {\n const combinedName = collisionGroups.map((c) => c.name).join('+');\n const combinedCategory = collisionGroups.reduce((current, g) => g.category | current, 0b0);\n const combinedMask = ~combinedCategory;\n return CollisionGroupManager.create(combinedName, combinedMask);\n }\n /**\n * Creates a collision group that collides with the listed groups\n * @param collisionGroups\n */\n static collidesWith(collisionGroups) {\n const combinedName = `collidesWith(${collisionGroups.map((c) => c.name).join('+')})`;\n const combinedMask = collisionGroups.reduce((current, g) => g.category | current, 0b0);\n return CollisionGroupManager.create(combinedName, combinedMask);\n }\n toString() {\n return `\r\ncategory: ${this.category.toString(2).padStart(32, '0')}\r\nmask: ${(this.mask >>> 0).toString(2).padStart(32, '0')}\r\n `;\n }\n}\n/**\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\n * it is the default collision group on colliders.\n */\nCollisionGroup.All = new CollisionGroup('Collide with all groups', -1, -1);\n\n;// CONCATENATED MODULE: ./Collision/Detection/Pair.ts\n\n\n/**\n * Models a potential collision between 2 colliders\n */\nclass Pair {\n constructor(colliderA, colliderB) {\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.id = null;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n }\n /**\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\n * @param colliderA\n * @param colliderB\n */\n static canCollide(colliderA, colliderB) {\n var _a, _b;\n const bodyA = (_a = colliderA === null || colliderA === void 0 ? void 0 : colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB === null || colliderB === void 0 ? void 0 : colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n // Prevent self collision\n if (colliderA.id === colliderB.id) {\n return false;\n }\n // Colliders with the same owner do not collide (composite colliders)\n if (colliderA.owner &&\n colliderB.owner &&\n colliderA.owner.id === colliderB.owner.id) {\n return false;\n }\n // if the pair has a member with zero dimension don't collide\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) {\n return false;\n }\n // Body's needed for collision in the current state\n // TODO can we collide without a body?\n if (!bodyA || !bodyB) {\n return false;\n }\n // If both are in the same collision group short circuit\n if (!bodyA.group.canCollide(bodyB.group)) {\n return false;\n }\n // if both are fixed short circuit\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) {\n return false;\n }\n // if the either is prevent collision short circuit\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) {\n return false;\n }\n // if either is dead short circuit\n if (!bodyA.active || !bodyB.active) {\n return false;\n }\n return true;\n }\n /**\n * Returns whether or not it is possible for the pairs to collide\n */\n get canCollide() {\n const colliderA = this.colliderA;\n const colliderB = this.colliderB;\n return Pair.canCollide(colliderA, colliderB);\n }\n /**\n * Runs the collision intersection logic on the members of this pair\n */\n collide() {\n return this.colliderA.collide(this.colliderB);\n }\n /**\n * Check if the collider is part of the pair\n * @param collider\n */\n hasCollider(collider) {\n return collider === this.colliderA || collider === this.colliderB;\n }\n /**\n * Calculates the unique pair hash id for this collision pair (owning id)\n */\n static calculatePairHash(idA, idB) {\n if (idA.value < idB.value) {\n return `#${idA.value}+${idB.value}`;\n }\n else {\n return `#${idB.value}+${idA.value}`;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Math/projection.ts\n/**\n * A 1 dimensional projection on an axis, used to test overlaps\n */\nclass Projection {\n constructor(min, max) {\n this.min = min;\n this.max = max;\n }\n overlaps(projection) {\n return this.max > projection.min && projection.max > this.min;\n }\n getOverlap(projection) {\n if (this.overlaps(projection)) {\n if (this.max > projection.max) {\n return projection.max - this.min;\n }\n else {\n return this.max - projection.min;\n }\n }\n return 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Detection/DynamicTree.ts\n\n\n\n\n/**\n * Dynamic Tree Node used for tracking bounds within the tree\n */\nclass TreeNode {\n constructor(parent) {\n this.parent = parent;\n this.parent = parent || null;\n this.data = null;\n this.bounds = new BoundingBox();\n this.left = null;\n this.right = null;\n this.height = 0;\n }\n isLeaf() {\n return !this.left && !this.right;\n }\n}\n/**\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\n *\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\n * Every non-leaf node is a bounding box that contains child bounding boxes.\n */\nclass DynamicTree {\n constructor(_config, worldBounds = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)) {\n this._config = _config;\n this.worldBounds = worldBounds;\n this.root = null;\n this.nodes = {};\n }\n /**\n * Inserts a node into the dynamic tree\n */\n _insert(leaf) {\n // If there are no nodes in the tree, make this the root leaf\n if (this.root === null) {\n this.root = leaf;\n this.root.parent = null;\n return;\n }\n // Search the tree for a node that is not a leaf and find the best place to insert\n const leafAABB = leaf.bounds;\n let currentRoot = this.root;\n while (!currentRoot.isLeaf()) {\n const left = currentRoot.left;\n const right = currentRoot.right;\n const area = currentRoot.bounds.getPerimeter();\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\n const combinedArea = combinedAABB.getPerimeter();\n // Calculate cost heuristic for creating a new parent and leaf\n const cost = 2 * combinedArea;\n // Minimum cost of pushing the leaf down the tree\n const inheritanceCost = 2 * (combinedArea - area);\n // Cost of descending\n let leftCost = 0;\n const leftCombined = leafAABB.combine(left.bounds);\n let newArea;\n let oldArea;\n if (left.isLeaf()) {\n leftCost = leftCombined.getPerimeter() + inheritanceCost;\n }\n else {\n oldArea = left.bounds.getPerimeter();\n newArea = leftCombined.getPerimeter();\n leftCost = newArea - oldArea + inheritanceCost;\n }\n let rightCost = 0;\n const rightCombined = leafAABB.combine(right.bounds);\n if (right.isLeaf()) {\n rightCost = rightCombined.getPerimeter() + inheritanceCost;\n }\n else {\n oldArea = right.bounds.getPerimeter();\n newArea = rightCombined.getPerimeter();\n rightCost = newArea - oldArea + inheritanceCost;\n }\n // cost is acceptable\n if (cost < leftCost && cost < rightCost) {\n break;\n }\n // Descend to the depths\n if (leftCost < rightCost) {\n currentRoot = left;\n }\n else {\n currentRoot = right;\n }\n }\n // Create the new parent node and insert into the tree\n const oldParent = currentRoot.parent;\n const newParent = new TreeNode(oldParent);\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\n newParent.height = currentRoot.height + 1;\n if (oldParent !== null) {\n // The sibling node was not the root\n if (oldParent.left === currentRoot) {\n oldParent.left = newParent;\n }\n else {\n oldParent.right = newParent;\n }\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n }\n else {\n // The sibling node was the root\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n this.root = newParent;\n }\n // Walk up the tree fixing heights and AABBs\n let currentNode = leaf.parent;\n while (currentNode) {\n currentNode = this._balance(currentNode);\n if (!currentNode.left) {\n throw new Error('Parent of current leaf cannot have a null left child' + currentNode);\n }\n if (!currentNode.right) {\n throw new Error('Parent of current leaf cannot have a null right child' + currentNode);\n }\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode = currentNode.parent;\n }\n }\n /**\n * Removes a node from the dynamic tree\n */\n _remove(leaf) {\n if (leaf === this.root) {\n this.root = null;\n return;\n }\n const parent = leaf.parent;\n const grandParent = parent.parent;\n let sibling;\n if (parent.left === leaf) {\n sibling = parent.right;\n }\n else {\n sibling = parent.left;\n }\n if (grandParent) {\n if (grandParent.left === parent) {\n grandParent.left = sibling;\n }\n else {\n grandParent.right = sibling;\n }\n sibling.parent = grandParent;\n let currentNode = grandParent;\n while (currentNode) {\n currentNode = this._balance(currentNode);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode = currentNode.parent;\n }\n }\n else {\n this.root = sibling;\n sibling.parent = null;\n }\n }\n /**\n * Tracks a body in the dynamic tree\n */\n trackCollider(collider) {\n const node = new TreeNode();\n node.data = collider;\n node.bounds = collider.bounds;\n node.bounds.left -= 2;\n node.bounds.top -= 2;\n node.bounds.right += 2;\n node.bounds.bottom += 2;\n this.nodes[collider.id.value] = node;\n this._insert(node);\n }\n /**\n * Updates the dynamic tree given the current bounds of each body being tracked\n */\n updateCollider(collider) {\n var _a;\n const node = this.nodes[collider.id.value];\n if (!node) {\n return false;\n }\n const b = collider.bounds;\n // if the body is outside the world no longer update it\n if (!this.worldBounds.contains(b)) {\n Logger.getInstance().warn('Collider with id ' + collider.id.value + ' is outside the world bounds and will no longer be tracked for physics');\n this.untrackCollider(collider);\n return false;\n }\n if (node.bounds.contains(b)) {\n return false;\n }\n this._remove(node);\n b.left -= this._config.boundsPadding;\n b.top -= this._config.boundsPadding;\n b.right += this._config.boundsPadding;\n b.bottom += this._config.boundsPadding;\n // THIS IS CAUSING UNNECESSARY CHECKS\n if (collider.owner) {\n const body = (_a = collider.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n if (body) {\n const multdx = ((body.vel.x * 32) / 1000) * this._config.velocityMultiplier;\n const multdy = ((body.vel.y * 32) / 1000) * this._config.velocityMultiplier;\n if (multdx < 0) {\n b.left += multdx;\n }\n else {\n b.right += multdx;\n }\n if (multdy < 0) {\n b.top += multdy;\n }\n else {\n b.bottom += multdy;\n }\n }\n }\n node.bounds = b;\n this._insert(node);\n return true;\n }\n /**\n * Untracks a body from the dynamic tree\n */\n untrackCollider(collider) {\n const node = this.nodes[collider.id.value];\n if (!node) {\n return;\n }\n this._remove(node);\n this.nodes[collider.id.value] = null;\n delete this.nodes[collider.id.value];\n }\n /**\n * Balances the tree about a node\n */\n _balance(node) {\n if (node === null) {\n throw new Error('Cannot balance at null node');\n }\n if (node.isLeaf() || node.height < 2) {\n return node;\n }\n const left = node.left;\n const right = node.right;\n const a = node;\n const b = left;\n const c = right;\n const d = left.left;\n const e = left.right;\n const f = right.left;\n const g = right.right;\n const balance = c.height - b.height;\n // Rotate c node up\n if (balance > 1) {\n // Swap the right node with it's parent\n c.left = a;\n c.parent = a.parent;\n a.parent = c;\n // The original node's old parent should point to the right node\n // this is mega confusing\n if (c.parent) {\n if (c.parent.left === a) {\n c.parent.left = c;\n }\n else {\n c.parent.right = c;\n }\n }\n else {\n this.root = c;\n }\n // Rotate\n if (f.height > g.height) {\n c.right = f;\n a.right = g;\n g.parent = a;\n a.bounds = b.bounds.combine(g.bounds);\n c.bounds = a.bounds.combine(f.bounds);\n a.height = 1 + Math.max(b.height, g.height);\n c.height = 1 + Math.max(a.height, f.height);\n }\n else {\n c.right = g;\n a.right = f;\n f.parent = a;\n a.bounds = b.bounds.combine(f.bounds);\n c.bounds = a.bounds.combine(g.bounds);\n a.height = 1 + Math.max(b.height, f.height);\n c.height = 1 + Math.max(a.height, g.height);\n }\n return c;\n }\n // Rotate left node up\n if (balance < -1) {\n // swap\n b.left = a;\n b.parent = a.parent;\n a.parent = b;\n // node's old parent should point to b\n if (b.parent) {\n if (b.parent.left === a) {\n b.parent.left = b;\n }\n else {\n if (b.parent.right !== a) {\n throw 'Error rotating Dynamic Tree';\n }\n b.parent.right = b;\n }\n }\n else {\n this.root = b;\n }\n // rotate\n if (d.height > e.height) {\n b.right = d;\n a.left = e;\n e.parent = a;\n a.bounds = c.bounds.combine(e.bounds);\n b.bounds = a.bounds.combine(d.bounds);\n a.height = 1 + Math.max(c.height, e.height);\n b.height = 1 + Math.max(a.height, d.height);\n }\n else {\n b.right = e;\n a.left = d;\n d.parent = a;\n a.bounds = c.bounds.combine(d.bounds);\n b.bounds = a.bounds.combine(e.bounds);\n a.height = 1 + Math.max(c.height, d.height);\n b.height = 1 + Math.max(a.height, e.height);\n }\n return b;\n }\n return node;\n }\n /**\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\n */\n getHeight() {\n if (this.root === null) {\n return 0;\n }\n return this.root.height;\n }\n /**\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\n *\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\n * the tree until all possible colliders have been returned.\n */\n query(collider, callback) {\n const bounds = collider.bounds;\n const helper = (currentNode) => {\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\n if (currentNode.isLeaf() && currentNode.data !== collider) {\n if (callback.call(collider, currentNode.data)) {\n return true;\n }\n }\n else {\n return helper(currentNode.left) || helper(currentNode.right);\n }\n }\n return false;\n };\n helper(this.root);\n }\n /**\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\n * long ray to test the tree specified by `max`.\n *\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\n * the tree until all possible bodies that would intersect with the ray have been returned.\n */\n rayCastQuery(ray, max = Infinity, callback) {\n const helper = (currentNode) => {\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\n if (currentNode.isLeaf()) {\n if (callback.call(ray, currentNode.data)) {\n // ray hit a leaf! return the body\n return true;\n }\n }\n else {\n // ray hit but not at a leaf, recurse deeper\n return helper(currentNode.left) || helper(currentNode.right);\n }\n }\n return false; // ray missed\n };\n helper(this.root);\n }\n getNodes() {\n const helper = (currentNode) => {\n if (currentNode) {\n return [currentNode].concat(helper(currentNode.left), helper(currentNode.right));\n }\n else {\n return [];\n }\n };\n return helper(this.root);\n }\n debug(ex) {\n // draw all the nodes in the Dynamic Tree\n const helper = (currentNode) => {\n if (currentNode) {\n if (currentNode.isLeaf()) {\n currentNode.bounds.draw(ex, Color.Green);\n }\n else {\n currentNode.bounds.draw(ex, Color.White);\n }\n if (currentNode.left) {\n helper(currentNode.left);\n }\n if (currentNode.right) {\n helper(currentNode.right);\n }\n }\n };\n helper(this.root);\n }\n}\n\n;// CONCATENATED MODULE: ./Math/ray.ts\n/**\n * A 2D ray that can be cast into the scene to do collision detection\n */\nclass Ray {\n /**\n * @param pos The starting position for the ray\n * @param dir The vector indicating the direction of the ray\n */\n constructor(pos, dir) {\n this.pos = pos;\n this.dir = dir.normalize();\n }\n /**\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\n * This number indicates the mathematical intersection time.\n * @param line The line to test\n */\n intersect(line) {\n const numerator = line.begin.sub(this.pos);\n // Test is line and ray are parallel and non intersecting\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) {\n return -1;\n }\n // Lines are parallel\n const divisor = this.dir.cross(line.getSlope());\n if (divisor === 0) {\n return -1;\n }\n const t = numerator.cross(line.getSlope()) / divisor;\n if (t >= 0) {\n const u = numerator.cross(this.dir) / divisor / line.getLength();\n if (u >= 0 && u <= 1) {\n return t;\n }\n }\n return -1;\n }\n intersectPoint(line) {\n const time = this.intersect(line);\n if (time < 0) {\n return null;\n }\n return this.getPoint(time);\n }\n /**\n * Returns the point of intersection given the intersection time\n */\n getPoint(time) {\n return this.pos.add(this.dir.scale(time));\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Detection/DynamicTreeCollisionProcessor.ts\n\n\n\n\n\n\n\n\n\n/**\n * Responsible for performing the collision broadphase (locating potential collisions) and\n * the narrowphase (actual collision contacts)\n */\nclass DynamicTreeCollisionProcessor {\n constructor(_config) {\n this._config = _config;\n this._pairs = new Set();\n this._collisionPairCache = [];\n this._colliders = [];\n this._dynamicCollisionTree = new DynamicTree(_config.dynamicTree);\n }\n getColliders() {\n return this._colliders;\n }\n rayCast(ray, options) {\n var _a, _b, _c;\n const results = [];\n const maxDistance = (_a = options === null || options === void 0 ? void 0 : options.maxDistance) !== null && _a !== void 0 ? _a : Infinity;\n const collisionGroup = options === null || options === void 0 ? void 0 : options.collisionGroup;\n const collisionMask = !collisionGroup ? (_b = options === null || options === void 0 ? void 0 : options.collisionMask) !== null && _b !== void 0 ? _b : CollisionGroup.All.category : collisionGroup.category;\n const searchAllColliders = (_c = options === null || options === void 0 ? void 0 : options.searchAllColliders) !== null && _c !== void 0 ? _c : false;\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider) => {\n const owner = collider.owner;\n const maybeBody = owner.get(BodyComponent);\n if ((options === null || options === void 0 ? void 0 : options.ignoreCollisionGroupAll) && maybeBody.group === CollisionGroup.All) {\n return false;\n }\n const canCollide = (collisionMask & maybeBody.group.category) !== 0;\n // Early exit if not the right group\n if ((maybeBody === null || maybeBody === void 0 ? void 0 : maybeBody.group) && !canCollide) {\n return false;\n }\n const hit = collider.rayCast(ray, maxDistance);\n if (hit) {\n if (options === null || options === void 0 ? void 0 : options.filter) {\n if (options.filter(hit)) {\n results.push(hit);\n if (!searchAllColliders) {\n // returning true exits the search\n return true;\n }\n }\n }\n else {\n results.push(hit);\n if (!searchAllColliders) {\n // returning true exits the search\n return true;\n }\n }\n }\n return false;\n });\n return results;\n }\n /**\n * Tracks a physics body for collisions\n */\n track(target) {\n if (!target) {\n Logger.getInstance().warn('Cannot track null collider');\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders) {\n c.owner = target.owner;\n this._colliders.push(c);\n this._dynamicCollisionTree.trackCollider(c);\n }\n }\n else {\n this._colliders.push(target);\n this._dynamicCollisionTree.trackCollider(target);\n }\n }\n /**\n * Untracks a physics body\n */\n untrack(target) {\n if (!target) {\n Logger.getInstance().warn('Cannot untrack a null collider');\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders) {\n const index = this._colliders.indexOf(c);\n if (index !== -1) {\n this._colliders.splice(index, 1);\n }\n this._dynamicCollisionTree.untrackCollider(c);\n }\n }\n else {\n const index = this._colliders.indexOf(target);\n if (index !== -1) {\n this._colliders.splice(index, 1);\n }\n this._dynamicCollisionTree.untrackCollider(target);\n }\n }\n _pairExists(colliderA, colliderB) {\n // if the collision pair has been calculated already short circuit\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\n return this._pairs.has(hash);\n }\n /**\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\n */\n broadphase(targets, delta, stats) {\n const seconds = delta / 1000;\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\n const potentialColliders = targets.filter((other) => {\n var _a, _b;\n const body = (_a = other.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n return ((_b = other.owner) === null || _b === void 0 ? void 0 : _b.active) && body.collisionType !== CollisionType.PreventCollision;\n });\n // clear old list of collision pairs\n this._collisionPairCache = [];\n this._pairs.clear();\n // check for normal collision pairs\n let collider;\n for (let j = 0, l = potentialColliders.length; j < l; j++) {\n collider = potentialColliders[j];\n // Query the collision tree for potential colliders\n this._dynamicCollisionTree.query(collider, (other) => {\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const pair = new Pair(collider, other);\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // Always return false, to query whole tree. Returning true in the query method stops searching\n return false;\n });\n }\n if (stats) {\n stats.physics.pairs = this._collisionPairCache.length;\n }\n // Check dynamic tree for fast moving objects\n // Fast moving objects are those moving at least there smallest bound per frame\n if (this._config.continuous.checkForFastBodies) {\n for (const collider of potentialColliders) {\n const body = collider.owner.get(BodyComponent);\n // Skip non-active objects. Does not make sense on other collision types\n if (body.collisionType !== CollisionType.Active) {\n continue;\n }\n // Maximum travel distance next frame\n const updateDistance = body.vel.size * seconds + // velocity term\n body.acc.size * 0.5 * seconds * seconds; // acc term\n // Find the minimum dimension\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\n if (this._config.continuous.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\n if (stats) {\n stats.physics.fastBodies++;\n }\n // start with the oldPos because the integration for actors has already happened\n // objects resting on a surface may be slightly penetrating in the current position\n const updateVec = body.globalPos.sub(body.oldPos);\n const centerPoint = collider.center;\n const furthestPoint = collider.getFurthestPoint(body.vel);\n const origin = furthestPoint.sub(updateVec);\n const ray = new Ray(origin, body.vel);\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\n ray.pos = ray.pos.add(ray.dir.scale(-2 * this._config.continuous.surfaceEpsilon));\n let minCollider;\n let minTranslate = new Vector(Infinity, Infinity);\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + this._config.continuous.surfaceEpsilon * 2, (other) => {\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const hit = other.rayCast(ray, updateDistance + this._config.continuous.surfaceEpsilon * 10);\n if (hit) {\n const translate = hit.point.sub(origin);\n if (translate.size < minTranslate.size) {\n minTranslate = translate;\n minCollider = other;\n }\n }\n }\n return false;\n });\n if (minCollider && Vector.isValid(minTranslate)) {\n const pair = new Pair(collider, minCollider);\n if (!this._pairs.has(pair.id)) {\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // move the fast moving object to the other body\n // need to push into the surface by ex.Physics.surfaceEpsilon\n const shift = centerPoint.sub(furthestPoint);\n body.globalPos = origin\n .add(shift)\n .add(minTranslate)\n .add(ray.dir.scale(10 * this._config.continuous.surfaceEpsilon)); // needed to push the shape slightly into contact\n collider.update(body.transform.get());\n if (stats) {\n stats.physics.fastBodyCollisions++;\n }\n }\n }\n }\n }\n // return cache\n return this._collisionPairCache;\n }\n /**\n * Applies narrow phase on collision pairs to find actual area intersections\n * Adds actual colliding pairs to stats' Frame data\n */\n narrowphase(pairs, stats) {\n let contacts = [];\n for (let i = 0; i < pairs.length; i++) {\n const newContacts = pairs[i].collide();\n contacts = contacts.concat(newContacts);\n if (stats && newContacts.length > 0) {\n for (const c of newContacts) {\n stats.physics.contacts.set(c.id, c);\n }\n }\n }\n if (stats) {\n stats.physics.collisions += contacts.length;\n }\n return contacts;\n }\n /**\n * Update the dynamic tree positions\n */\n update(targets) {\n let updated = 0;\n const len = targets.length;\n for (let i = 0; i < len; i++) {\n if (this._dynamicCollisionTree.updateCollider(targets[i])) {\n updated++;\n }\n }\n return updated;\n }\n debug(ex) {\n this._dynamicCollisionTree.debug(ex);\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/Collider.ts\n\n\n\n/**\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\n * for the purposes of colliding 2 objects in excalibur.\n */\nclass Collider {\n constructor() {\n this.id = createId('collider', Collider._ID++);\n /**\n * Composite collider if any this collider is attached to\n *\n * **WARNING** do not tamper with this property\n */\n this.composite = null;\n this.events = new EventEmitter();\n /**\n * Pixel offset of the collision collider relative to the collider, by default (0, 0) meaning the collider is positioned\n * on top of the collider.\n */\n this.offset = Vector.Zero;\n }\n /**\n * Returns a boolean indicating whether this body collided with\n * or was in stationary contact with\n * the body of the other [[Collider]]\n */\n touching(other) {\n const contact = this.collide(other);\n if (contact) {\n return true;\n }\n return false;\n }\n}\nCollider._ID = 0;\n\n;// CONCATENATED MODULE: ./Collision/SolverStrategy.ts\n/**\n * Possible collision resolution strategies\n *\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\n * like platformers or top down games.\n *\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\n * simulated physical interactions.\n */\nvar SolverStrategy;\n(function (SolverStrategy) {\n SolverStrategy[\"Arcade\"] = \"arcade\";\n SolverStrategy[\"Realistic\"] = \"realistic\";\n})(SolverStrategy || (SolverStrategy = {}));\n\n;// CONCATENATED MODULE: ./Collision/Physics.ts\n\n\n/**\n * Possible broadphase collision pair identification strategies\n *\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\n * potential collision pairs which is O(nlog(n)) faster.\n * @deprecated Unused in Excalibur, will be removed in v0.30\n */\nvar BroadphaseStrategy;\n(function (BroadphaseStrategy) {\n BroadphaseStrategy[BroadphaseStrategy[\"DynamicAABBTree\"] = 0] = \"DynamicAABBTree\";\n})(BroadphaseStrategy || (BroadphaseStrategy = {}));\n/**\n * Possible numerical integrators for position and velocity\n * @deprecated Unused in Excalibur, will be removed in v0.30\n */\nvar Integrator;\n(function (Integrator) {\n Integrator[Integrator[\"Euler\"] = 0] = \"Euler\";\n})(Integrator || (Integrator = {}));\n/**\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\n/* istanbul ignore next */\nclass Physics {\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\n static get gravity() {\n return Physics.acc;\n }\n static set gravity(v) {\n Physics.acc = v;\n }\n /**\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\n static useArcadePhysics() {\n Physics.collisionResolutionStrategy = SolverStrategy.Arcade;\n }\n /**\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\n * simulated physical interactions.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\n static useRealisticPhysics() {\n Physics.collisionResolutionStrategy = SolverStrategy.Realistic;\n }\n}\n/**\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\n *\n * This is a great way to globally simulate effects like gravity.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.acc = new Vector(0, 0);\n/**\n * Globally switches all Excalibur physics behavior on or off.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.enabled = true;\n/**\n * Gets or sets the broadphase pair identification strategy.\n *\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\n * potential collision pairs which is O(nlog(n)) faster.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.broadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\n/**\n * Gets or sets the global collision resolution strategy (narrowphase).\n *\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics.\n *\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\n * simulated physical interactions.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.collisionResolutionStrategy = SolverStrategy.Arcade;\n/**\n * The default mass to use if none is specified\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.defaultMass = 10;\n/**\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.integrator = Integrator.Euler;\n/**\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.dynamicTreeVelocityMultiplier = 2;\n/**\n * Pad RigidBody BoundingBox by a constant amount\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.boundsPadding = 5;\n/**\n * Number of position iterations (overlap) to run in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.positionIterations = 3;\n/**\n * Number of velocity iteration (response) to run in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.velocityIterations = 8;\n/**\n * Amount of overlap to tolerate in pixels\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.slop = 1;\n/**\n * Amount of positional overlap correction to apply each position iteration of the solver\n * O - meaning no correction, 1 - meaning correct all overlap\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.steeringFactor = 0.2;\n/**\n * Warm start set to true re-uses impulses from previous frames back in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.warmStart = true;\n/**\n * By default bodies do not sleep\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.bodiesCanSleepByDefault = false;\n/**\n * Surface epsilon is used to help deal with surface penetration\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.surfaceEpsilon = 0.1;\n/**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.sleepEpsilon = 0.07;\n/**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.wakeThreshold = Physics.sleepEpsilon * 3;\n/**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.sleepBias = 0.9;\n/**\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\n * bodies from tunneling through one another.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.checkForFastBodies = true;\n/**\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\n * Excalibur will always perform the fast body raycast regardless of speed.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.disableMinimumSpeedForFastBody = false;\n\n;// CONCATENATED MODULE: ./Collision/Solver/ContactBias.ts\n/**\n * Tells the Arcade collision solver to prefer certain contacts over others\n */\nvar ContactSolveBias;\n(function (ContactSolveBias) {\n ContactSolveBias[\"None\"] = \"none\";\n ContactSolveBias[\"VerticalFirst\"] = \"vertical-first\";\n ContactSolveBias[\"HorizontalFirst\"] = \"horizontal-first\";\n})(ContactSolveBias || (ContactSolveBias = {}));\n/**\n * Vertical First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\n */\nconst VerticalFirst = {\n 'vertical': 1,\n 'horizontal': 2\n};\n/**\n * Horizontal First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\n */\nconst HorizontalFirst = {\n 'horizontal': 1,\n 'vertical': 2\n};\n/**\n * None value, [[ArcadeSolver]] sorts contacts using distance by default\n */\nconst None = {\n 'horizontal': 0,\n 'vertical': 0\n};\n\n;// CONCATENATED MODULE: ./Collision/PhysicsConfig.ts\n\n\n\n\nconst DefaultPhysicsConfig = {\n enabled: true,\n gravity: vec(0, 0),\n solver: SolverStrategy.Arcade,\n colliders: {\n compositeStrategy: 'together'\n },\n continuous: {\n checkForFastBodies: true,\n disableMinimumSpeedForFastBody: false,\n surfaceEpsilon: 0.1\n },\n bodies: {\n canSleepByDefault: false,\n sleepEpsilon: 0.07,\n wakeThreshold: 0.07 * 3,\n sleepBias: 0.9,\n defaultMass: 10\n },\n dynamicTree: {\n boundsPadding: 5,\n velocityMultiplier: 2\n },\n arcade: {\n contactSolveBias: ContactSolveBias.None\n },\n realistic: {\n positionIterations: 3,\n velocityIterations: 8,\n slop: 1,\n steeringFactor: 0.2,\n warmStart: true\n }\n};\n/**\n * @deprecated will be removed in v0.30\n */\nfunction DeprecatedStaticToConfig() {\n return {\n enabled: Physics.enabled,\n gravity: Physics.gravity,\n solver: Physics.collisionResolutionStrategy,\n continuous: {\n checkForFastBodies: Physics.checkForFastBodies,\n disableMinimumSpeedForFastBody: Physics.disableMinimumSpeedForFastBody,\n surfaceEpsilon: Physics.surfaceEpsilon\n },\n colliders: {\n compositeStrategy: 'together'\n },\n bodies: {\n canSleepByDefault: Physics.bodiesCanSleepByDefault,\n sleepEpsilon: Physics.sleepEpsilon,\n wakeThreshold: Physics.wakeThreshold,\n sleepBias: Physics.sleepBias,\n defaultMass: Physics.defaultMass\n },\n dynamicTree: {\n boundsPadding: Physics.boundsPadding,\n velocityMultiplier: Physics.dynamicTreeVelocityMultiplier\n },\n arcade: {\n contactSolveBias: ContactSolveBias.None\n },\n realistic: {\n positionIterations: Physics.positionIterations,\n velocityIterations: Physics.velocityIterations,\n slop: Physics.slop,\n steeringFactor: Physics.steeringFactor,\n warmStart: Physics.warmStart\n }\n };\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CompositeCollider.ts\n\n\n\n\n\n\n\n\n\nclass CompositeCollider extends Collider {\n /**\n * Treat composite collider's member colliders as either separate colliders for the purposes of onCollisionStart/onCollision\n * or as a single collider together.\n *\n * This property can be overridden on individual [[CompositeColliders]].\n *\n * For composites without gaps or small groups of colliders, you probably want 'together'\n *\n * For composites with deliberate gaps, like a platforming level layout, you probably want 'separate'\n *\n * Default is 'together' if unset\n */\n set compositeStrategy(value) {\n this._compositeStrategy = value;\n }\n get compositeStrategy() {\n return this._compositeStrategy;\n }\n constructor(colliders) {\n super();\n this._collisionProcessor = new DynamicTreeCollisionProcessor(DefaultPhysicsConfig);\n this._dynamicAABBTree = new DynamicTree(DefaultPhysicsConfig.dynamicTree);\n this._colliders = [];\n for (const c of colliders) {\n this.addCollider(c);\n }\n }\n clearColliders() {\n this._colliders = [];\n }\n addCollider(collider) {\n let colliders;\n if (collider instanceof CompositeCollider) {\n colliders = collider.getColliders();\n colliders.forEach(c => c.offset.addEqual(collider.offset));\n }\n else {\n colliders = [collider];\n }\n // Flatten composites\n for (const c of colliders) {\n c.events.pipe(this.events);\n c.composite = this;\n this._colliders.push(c);\n this._collisionProcessor.track(c);\n this._dynamicAABBTree.trackCollider(c);\n }\n }\n removeCollider(collider) {\n collider.events.pipe(this.events);\n collider.composite = null;\n removeItemFromArray(collider, this._colliders);\n this._collisionProcessor.untrack(collider);\n this._dynamicAABBTree.untrackCollider(collider);\n }\n getColliders() {\n return this._colliders;\n }\n get worldPos() {\n var _a, _b;\n return ((_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero).add(this.offset);\n }\n get center() {\n var _a, _b;\n return ((_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero).add(this.offset);\n }\n get bounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider) => acc.combine(collider.bounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox().translate(this.worldPos));\n return results.translate(this.offset);\n }\n get localBounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider) => acc.combine(collider.localBounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox());\n return results;\n }\n get axes() {\n // TODO cache this\n const colliders = this.getColliders();\n let axes = [];\n for (const collider of colliders) {\n axes = axes.concat(collider.axes);\n }\n return axes;\n }\n getFurthestPoint(direction) {\n const colliders = this.getColliders();\n const furthestPoints = [];\n for (const collider of colliders) {\n furthestPoints.push(collider.getFurthestPoint(direction));\n }\n // Pick best point from all colliders\n let bestPoint = furthestPoints[0];\n let maxDistance = -Number.MAX_VALUE;\n for (const point of furthestPoints) {\n const distance = point.dot(direction);\n if (distance > maxDistance) {\n bestPoint = point;\n maxDistance = distance;\n }\n }\n return bestPoint;\n }\n getInertia(mass) {\n const colliders = this.getColliders();\n let totalInertia = 0;\n for (const collider of colliders) {\n totalInertia += collider.getInertia(mass);\n }\n return totalInertia;\n }\n collide(other) {\n let otherColliders = [other];\n if (other instanceof CompositeCollider) {\n otherColliders = other.getColliders();\n }\n const pairs = [];\n for (const c of otherColliders) {\n this._dynamicAABBTree.query(c, (potentialCollider) => {\n pairs.push(new Pair(c, potentialCollider));\n return false;\n });\n }\n let contacts = [];\n for (const p of pairs) {\n contacts = contacts.concat(p.collide());\n }\n return contacts;\n }\n getClosestLineBetween(other) {\n const colliders = this.getColliders();\n const lines = [];\n if (other instanceof CompositeCollider) {\n const otherColliders = other.getColliders();\n for (const colliderA of colliders) {\n for (const colliderB of otherColliders) {\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\n if (maybeLine) {\n lines.push(maybeLine);\n }\n }\n }\n }\n else {\n for (const collider of colliders) {\n const maybeLine = other.getClosestLineBetween(collider);\n if (maybeLine) {\n lines.push(maybeLine);\n }\n }\n }\n if (lines.length) {\n let minLength = lines[0].getLength();\n let minLine = lines[0];\n for (const line of lines) {\n const length = line.getLength();\n if (length < minLength) {\n minLength = length;\n minLine = line;\n }\n }\n return minLine;\n }\n return null;\n }\n contains(point) {\n const colliders = this.getColliders();\n for (const collider of colliders) {\n if (collider.contains(point)) {\n return true;\n }\n }\n return false;\n }\n rayCast(ray, max) {\n const colliders = this.getColliders();\n const hits = [];\n for (const collider of colliders) {\n const hit = collider.rayCast(ray, max);\n if (hit) {\n hits.push(hit);\n }\n }\n if (hits.length) {\n let minHit = hits[0];\n let minDistance = minHit.point.dot(ray.dir);\n for (const hit of hits) {\n const distance = ray.dir.dot(hit.point);\n if (distance < minDistance) {\n minHit = hit;\n minDistance = distance;\n }\n }\n return minHit;\n }\n return null;\n }\n project(axis) {\n const colliders = this.getColliders();\n const projections = [];\n for (const collider of colliders) {\n const proj = collider.project(axis);\n if (proj) {\n projections.push(proj);\n }\n }\n // Merge all proj's on the same axis\n if (projections.length) {\n const newProjection = new Projection(projections[0].min, projections[0].max);\n for (const proj of projections) {\n newProjection.min = Math.min(proj.min, newProjection.min);\n newProjection.max = Math.max(proj.max, newProjection.max);\n }\n return newProjection;\n }\n return null;\n }\n update(transform) {\n if (transform) {\n const colliders = this.getColliders();\n for (const collider of colliders) {\n collider.owner = this.owner;\n collider.update(transform);\n }\n }\n }\n debug(ex, color, options) {\n const colliders = this.getColliders();\n ex.save();\n ex.translate(this.offset.x, this.offset.y);\n for (const collider of colliders) {\n collider.debug(ex, color, options);\n }\n ex.restore();\n }\n clone() {\n const result = new CompositeCollider(this._colliders.map((c) => c.clone()));\n result.offset = this.offset.clone();\n return result;\n }\n}\n\n;// CONCATENATED MODULE: ./Math/line-segment.ts\n\n/**\n * A 2D line segment\n */\nclass LineSegment {\n /**\n * @param begin The starting point of the line segment\n * @param end The ending point of the line segment\n */\n constructor(begin, end) {\n this.begin = begin;\n this.end = end;\n }\n /**\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\n */\n get slope() {\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\n }\n /**\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\n */\n get intercept() {\n return this.begin.y - this.slope * this.begin.x;\n }\n /**\n * Gets the normal of the line\n */\n normal() {\n if (this._normal) {\n return this._normal;\n }\n return this._normal = this.end.sub(this.begin).normal();\n }\n dir() {\n if (this._dir) {\n return this._dir;\n }\n return this._dir = this.end.sub(this.begin);\n }\n getPoints() {\n return [this.begin, this.end];\n }\n /**\n * Returns the slope of the line in the form of a vector of length 1\n */\n getSlope() {\n if (this._slope) {\n return this._slope;\n }\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._slope = end.sub(begin).scale(1 / distance);\n }\n /**\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\n */\n getEdge() {\n const begin = this.begin;\n const end = this.end;\n return end.sub(begin);\n }\n /**\n * Returns the length of the line segment in pixels\n */\n getLength() {\n if (this._length) {\n return this._length;\n }\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._length = distance;\n }\n /**\n * Returns the midpoint of the edge\n */\n get midpoint() {\n return this.begin.add(this.end).scale(0.5);\n }\n /**\n * Flips the direction of the line segment\n */\n flip() {\n return new LineSegment(this.end, this.begin);\n }\n /**\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\n * @param point\n */\n below(point) {\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\n return above2 >= 0;\n }\n /**\n * Returns the clip point\n * @param sideVector Vector that traces the line\n * @param length Length to clip along side\n */\n clip(sideVector, length) {\n let dir = sideVector;\n dir = dir.normalize();\n const near = dir.dot(this.begin) - length;\n const far = dir.dot(this.end) - length;\n const results = [];\n if (near <= 0) {\n results.push(this.begin);\n }\n if (far <= 0) {\n results.push(this.end);\n }\n if (near * far < 0) {\n const clipTime = near / (near - far);\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\n }\n if (results.length !== 2) {\n return null;\n }\n return new LineSegment(results[0], results[1]);\n }\n /**\n * Find the perpendicular distance from the line to a point\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\n * @param point\n */\n distanceToPoint(point, signed = false) {\n const x0 = point.x;\n const y0 = point.y;\n const l = this.getLength();\n const dy = this.end.y - this.begin.y;\n const dx = this.end.x - this.begin.x;\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\n return signed ? distance : Math.abs(distance);\n }\n /**\n * Find the perpendicular line from the line to a point\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\n * (a - p) - ((a - p) * n)n\n * a is a point on the line\n * p is the arbitrary point above the line\n * n is a unit vector in direction of the line\n * @param point\n */\n findVectorToPoint(point) {\n const aMinusP = this.begin.sub(point);\n const n = this.getSlope();\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\n }\n /**\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\n * a new point with the calculated Y value and vice-versa.\n * @param x The known X value of the target point\n * @param y The known Y value of the target point\n * @returns A new point with the other calculated axis value\n */\n findPoint(x = null, y = null) {\n const m = this.slope;\n const b = this.intercept;\n if (x !== null) {\n return new Vector(x, m * x + b);\n }\n else if (y !== null) {\n return new Vector((y - b) / m, y);\n }\n else {\n throw new Error('You must provide an X or a Y value');\n }\n }\n /**\n * @see http://stackoverflow.com/a/11908158/109458\n */\n hasPoint() {\n let currPoint;\n let threshold = 0;\n if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') {\n currPoint = new Vector(arguments[0], arguments[1]);\n threshold = arguments[2] || 0;\n }\n else if (arguments[0] instanceof Vector) {\n currPoint = arguments[0];\n threshold = arguments[1] || 0;\n }\n else {\n throw 'Could not determine the arguments for Vector.hasPoint';\n }\n const dxc = currPoint.x - this.begin.x;\n const dyc = currPoint.y - this.begin.y;\n const dx1 = this.end.x - this.begin.x;\n const dy1 = this.end.y - this.begin.y;\n const cross = dxc * dy1 - dyc * dx1;\n // check whether point lines on the line\n if (Math.abs(cross) > threshold) {\n return false;\n }\n // check whether point lies in-between start and end\n if (Math.abs(dx1) >= Math.abs(dy1)) {\n return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\n }\n else {\n return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/ClosestLineJumpTable.ts\n\n\n\n/**\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n * @param p0 Point where L1 begins\n * @param u Direction and length of L1\n * @param q0 Point were L2 begins\n * @param v Direction and length of L2\n */\nfunction ClosestLine(p0, u, q0, v) {\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\n // w(s, t) = P(s) - Q(t)\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\n //\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\n //\n // The closest point between 2 lines then satisfies this pair of equations\n // 1: u * wClosest = 0\n // 2: v * wClosest = 0\n //\n // Substituting wClosest into the equations we get\n //\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\n // simplify w0\n const w0 = p0.sub(q0);\n // simplify (u * u);\n const a = u.dot(u);\n // simplify (u * v);\n const b = u.dot(v);\n // simplify (v * v)\n const c = v.dot(v);\n // simplify (u * w0)\n const d = u.dot(w0);\n // simplify (v * w0)\n const e = v.dot(w0);\n // denominator ac - b^2\n const denom = a * c - b * b;\n let sDenom = denom;\n let tDenom = denom;\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\n if (denom === 0 || denom <= 0.01) {\n const tClosestParallel = d / b;\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\n }\n // Solve for sClosest for infinite line\n let sClosest = b * e - c * d; // / denom;\n // Solve for tClosest for infinite line\n let tClosest = a * e - b * d; // / denom;\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\n if (sClosest < 0) {\n sClosest = 0;\n tClosest = e;\n tDenom = c;\n }\n else if (sClosest > sDenom) {\n sClosest = sDenom;\n tClosest = e + b;\n tDenom = c;\n }\n if (tClosest < 0) {\n tClosest = 0;\n if (-d < 0) {\n sClosest = 0;\n }\n else if (-d > a) {\n sClosest = sDenom;\n }\n else {\n sClosest = -d;\n sDenom = a;\n }\n }\n else if (tClosest > tDenom) {\n tClosest = tDenom;\n if (-d + b < 0) {\n sClosest = 0;\n }\n else if (-d + b > a) {\n sClosest = sDenom;\n }\n else {\n sClosest = -d + b;\n sDenom = a;\n }\n }\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\n}\nconst ClosestLineJumpTable = {\n PolygonPolygonClosestLine(polygonA, polygonB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = polygonB.worldPos;\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\n const thisDirection = otherDirection.negate();\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\n const thisPoint = polygonA.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const otherPoint = polygonB.rayCast(rayTowardsThis).point.add(rayTowardsThis.dir.scale(0.1));\n const thisFace = polygonA.getClosestFace(thisPoint);\n const otherFace = polygonB.getClosestFace(otherPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const q0 = otherFace.face.begin;\n const v = otherFace.face.getEdge();\n return ClosestLine(p0, u, q0, v);\n },\n PolygonEdgeClosestLine(polygon, edge) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = edge.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const q0 = edgeStart;\n const v = edgeVector;\n return ClosestLine(p0, u, q0, v);\n },\n PolygonCircleClosestLine(polygon, circle) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circle.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // Time of minimum distance\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp\n if (t > 1) {\n t = 1;\n }\n else if (t < 0) {\n t = 0;\n }\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\n const circlex = ((p0.x + u.x * t - otherWorldPos.x) * circle.radius) / (circle.radius + d);\n const circley = ((p0.y + u.y * t - otherWorldPos.y) * circle.radius) / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\n },\n CircleCircleClosestLine(circleA, circleB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circleB.worldPos;\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\n const thisWorldPos = circleA.worldPos;\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\n const thisPoint = circleA.rayCast(rayTowardsOther);\n const otherPoint = circleB.rayCast(rayTowardsThis);\n return new LineSegment(thisPoint.point, otherPoint.point);\n },\n CircleEdgeClosestLine(circle, edge) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n const circleWorldPos = circle.worldPos;\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const p0 = edgeStart;\n const u = edgeVector;\n // Time of minimum distance\n let t = (u.x * (circleWorldPos.x - p0.x) + u.y * (circleWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp to edge\n if (t > 1) {\n t = 1;\n }\n else if (t < 0) {\n t = 0;\n }\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorldPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorldPos.y, 2)) - circle.radius;\n const circlex = ((p0.x + u.x * t - circleWorldPos.x) * circle.radius) / (circle.radius + d);\n const circley = ((p0.y + u.y * t - circleWorldPos.y) * circle.radius) / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorldPos.x + circlex, circleWorldPos.y + circley));\n },\n EdgeEdgeClosestLine(edgeA, edgeB) {\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLineA = edgeA.asLine();\n const edgeStartA = edgeLineA.begin;\n const edgeVectorA = edgeLineA.getEdge();\n const p0 = edgeStartA;\n const u = edgeVectorA;\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLineB = edgeB.asLine();\n const edgeStartB = edgeLineB.begin;\n const edgeVectorB = edgeLineB.getEdge();\n const q0 = edgeStartB;\n const v = edgeVectorB;\n return ClosestLine(p0, u, q0, v);\n }\n};\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CircleCollider.ts\n\n\n\n\n\n\n\n\n\n\n\n/**\n * This is a circle collider for the excalibur rigid body physics simulation\n */\nclass CircleCollider extends Collider {\n get worldPos() {\n return this._globalMatrix.getPosition();\n }\n /**\n * Get the radius of the circle\n */\n get radius() {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n return this._naturalRadius * Math.min(scale.x, scale.y);\n }\n /**\n * Set the radius of the circle\n */\n set radius(val) {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n this._naturalRadius = val / Math.min(scale.x, scale.y);\n }\n constructor(options) {\n super();\n /**\n * Position of the circle relative to the collider, by default (0, 0).\n */\n this.offset = Vector.Zero;\n this._globalMatrix = AffineMatrix.identity();\n this.offset = options.offset || Vector.Zero;\n this.radius = options.radius || 0;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Returns a clone of this shape, not associated with any collider\n */\n clone() {\n return new CircleCollider({\n offset: this.offset.clone(),\n radius: this.radius\n });\n }\n /**\n * Get the center of the collider in world coordinates\n */\n get center() {\n return this._globalMatrix.getPosition();\n }\n /**\n * Tests if a point is contained in this collider\n */\n contains(point) {\n var _a, _b;\n const pos = (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : this.offset;\n const distance = pos.distance(point);\n if (distance <= this.radius) {\n return true;\n }\n return false;\n }\n /**\n * Casts a ray at the Circle collider and returns the nearest point of collision\n * @param ray\n */\n rayCast(ray, max = Infinity) {\n var _a, _b;\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\n const c = this.center;\n const dir = ray.dir;\n const orig = ray.pos;\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\n if (discriminant < 0) {\n // no intersection\n return null;\n }\n else {\n let toi = 0;\n // tangent case\n if (discriminant === 0) {\n toi = -dir.dot(orig.sub(c));\n if (toi > 0 && toi < max) {\n const point = ray.getPoint(toi);\n return {\n point,\n normal: point.sub(c).normalize(),\n collider: this,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n distance: toi\n };\n }\n return null;\n }\n else { // two point\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\n const positiveToi = [];\n if (toi1 >= 0) {\n positiveToi.push(toi1);\n }\n if (toi2 >= 0) {\n positiveToi.push(toi2);\n }\n const minToi = Math.min(...positiveToi);\n if (minToi <= max) {\n const point = ray.getPoint(minToi);\n return {\n point,\n normal: point.sub(c).normalize(),\n collider: this,\n body: (_b = this.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent),\n distance: minToi\n };\n }\n return null;\n }\n }\n }\n getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) {\n return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\n }\n else if (shape instanceof PolygonCollider) {\n return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\n }\n else if (shape instanceof EdgeCollider) {\n return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\n }\n else {\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n }\n /**\n * @inheritdoc\n */\n collide(collider) {\n if (collider instanceof CircleCollider) {\n return CollisionJumpTable.CollideCircleCircle(this, collider);\n }\n else if (collider instanceof PolygonCollider) {\n return CollisionJumpTable.CollideCirclePolygon(this, collider);\n }\n else if (collider instanceof EdgeCollider) {\n return CollisionJumpTable.CollideCircleEdge(this, collider);\n }\n else {\n throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\n }\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */\n getFurthestPoint(direction) {\n return this.center.add(direction.normalize().scale(this.radius));\n }\n /**\n * Find the local point on the shape in the direction specified\n * @param direction\n */\n getFurthestLocalPoint(direction) {\n const dir = direction.normalize();\n return dir.scale(this.radius);\n }\n /**\n * Get the axis aligned bounding box for the circle collider in world coordinates\n */\n get bounds() {\n var _a, _b, _c;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = ((_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero);\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius).rotate(rotation).scale(scale).translate(pos);\n }\n /**\n * Get the axis aligned bounding box for the circle collider in local coordinates\n */\n get localBounds() {\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius);\n }\n /**\n * Get axis not implemented on circles, since there are infinite axis in a circle\n */\n get axes() {\n return [];\n }\n /**\n * Returns the moment of inertia of a circle given it's mass\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */\n getInertia(mass) {\n return (mass * this.radius * this.radius) / 2;\n }\n /* istanbul ignore next */\n update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Project the circle along a specified axis\n */\n project(axis) {\n const scalars = [];\n const point = this.center;\n const dotProduct = point.dot(axis);\n scalars.push(dotProduct);\n scalars.push(dotProduct + this.radius);\n scalars.push(dotProduct - this.radius);\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color, options) {\n var _a, _b, _c, _d;\n const { lineWidth } = { ...{ lineWidth: 1 }, ...options };\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = ((_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero);\n ex.save();\n ex.translate(pos.x, pos.y);\n ex.rotate(rotation);\n ex.scale(scale.x, scale.y);\n ex.drawCircle(((_d = this.offset) !== null && _d !== void 0 ? _d : Vector.Zero), this._naturalRadius, Color.Transparent, color, lineWidth);\n ex.restore();\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Detection/CollisionContact.ts\n\n\n\n/**\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\n * Pair prevents collisions from being evaluated more than one time\n */\nclass CollisionContact {\n constructor(colliderA, colliderB, mtv, normal, tangent, points, localPoints, info) {\n var _a, _b, _c, _d, _e, _f;\n this._canceled = false;\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.mtv = mtv;\n this.normal = normal;\n this.tangent = tangent;\n this.points = points;\n this.localPoints = localPoints;\n this.info = info;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n if (colliderA.composite || colliderB.composite) {\n // Add on the parent composite pair for start/end contact if 'together\n const colliderAId = ((_a = colliderA.composite) === null || _a === void 0 ? void 0 : _a.compositeStrategy) === 'separate' ? colliderA.id : (_c = (_b = colliderA.composite) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : colliderA.id;\n const colliderBId = ((_d = colliderB.composite) === null || _d === void 0 ? void 0 : _d.compositeStrategy) === 'separate' ? colliderB.id : (_f = (_e = colliderB.composite) === null || _e === void 0 ? void 0 : _e.id) !== null && _f !== void 0 ? _f : colliderB.id;\n this.id += '|' + Pair.calculatePairHash(colliderAId, colliderBId);\n }\n }\n /**\n * Match contact awake state, except if body's are Fixed\n */\n matchAwake() {\n const bodyA = this.colliderA.owner.get(BodyComponent);\n const bodyB = this.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.sleeping !== bodyB.sleeping) {\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= bodyA.wakeThreshold) {\n bodyA.setSleeping(false);\n }\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= bodyB.wakeThreshold) {\n bodyB.setSleeping(false);\n }\n }\n }\n }\n isCanceled() {\n return this._canceled;\n }\n cancel() {\n this._canceled = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/SeparatingAxis.ts\nclass SeparatingAxis {\n static findPolygonPolygonSeparation(polyA, polyB) {\n let bestSeparation = -Number.MAX_VALUE;\n let bestSide = null;\n let bestAxis = null;\n let bestSideIndex = -1;\n let bestOtherPoint = null;\n const sides = polyA.getSides();\n const localSides = polyA.getLocalSides();\n for (let i = 0; i < sides.length; i++) {\n const side = sides[i];\n const axis = side.normal();\n const vertB = polyB.getFurthestPoint(axis.negate());\n // Separation on side i's axis\n // We are looking for the largest separation between poly A's sides\n const vertSeparation = side.distanceToPoint(vertB, true);\n if (vertSeparation > bestSeparation) {\n bestSeparation = vertSeparation;\n bestSide = side;\n bestAxis = axis;\n bestSideIndex = i;\n bestOtherPoint = vertB;\n }\n }\n return {\n collider: polyA,\n separation: bestAxis ? bestSeparation : 99,\n axis: bestAxis,\n side: bestSide,\n localSide: localSides[bestSideIndex],\n sideId: bestSideIndex,\n point: bestOtherPoint,\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis.negate()) : null\n };\n }\n static findCirclePolygonSeparation(circle, polygon) {\n const axes = polygon.axes;\n const pc = polygon.center;\n // Special SAT with circles\n const polyDir = pc.sub(circle.worldPos);\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\n let minOverlap = Number.MAX_VALUE;\n let minAxis = null;\n let minIndex = -1;\n for (let i = 0; i < axes.length; i++) {\n const proj1 = polygon.project(axes[i]);\n const proj2 = circle.project(axes[i]);\n const overlap = proj1.getOverlap(proj2);\n if (overlap <= 0) {\n return null;\n }\n else {\n if (overlap < minOverlap) {\n minOverlap = overlap;\n minAxis = axes[i];\n minIndex = i;\n }\n }\n }\n if (minIndex < 0) {\n return null;\n }\n return minAxis.normalize().scale(minOverlap);\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CollisionJumpTable.ts\n\n\n\n\n\n\n\n\nconst CollisionJumpTable = {\n CollideCircleCircle(circleA, circleB) {\n const circleAPos = circleA.worldPos;\n const circleBPos = circleB.worldPos;\n const combinedRadius = circleA.radius + circleB.radius;\n const distance = circleAPos.distance(circleBPos);\n if (distance > combinedRadius) {\n return [];\n }\n // negative means overlap\n const separation = combinedRadius - distance;\n // Normal points from A -> B\n const normal = circleBPos.sub(circleAPos).normalize();\n const tangent = normal.perpendicular();\n const mvt = normal.scale(separation);\n const point = circleA.getFurthestPoint(normal);\n const local = circleA.getFurthestLocalPoint(normal);\n const info = {\n collider: circleA,\n separation,\n axis: normal,\n point: point\n };\n return [new CollisionContact(circleA, circleB, mvt, normal, tangent, [point], [local], info)];\n },\n CollideCirclePolygon(circle, polygon) {\n var _a, _b;\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\n if (!minAxis) {\n return [];\n }\n // make sure that the minAxis is pointing away from circle\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\n const point = circle.getFurthestPoint(minAxis);\n const xf = (_b = (_a = circle.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const local = xf.applyInverse(point);\n const normal = minAxis.normalize();\n const info = {\n collider: circle,\n separation: -minAxis.size,\n axis: normal,\n point: point,\n localPoint: local,\n side: polygon.findSide(normal.negate()),\n localSide: polygon.findLocalSide(normal.negate())\n };\n return [new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [point], [local], info)];\n },\n CollideCircleEdge(circle, edge) {\n // TODO not sure this actually abides by local/world collisions\n // Are edge.begin and edge.end local space or world space? I think they should be local\n // center of the circle in world pos\n const cc = circle.center;\n // vector in the direction of the edge\n const edgeWorld = edge.asLine();\n const e = edgeWorld.end.sub(edgeWorld.begin);\n // amount of overlap with the circle's center along the edge direction\n const u = e.dot(edgeWorld.end.sub(cc));\n const v = e.dot(cc.sub(edgeWorld.begin));\n const side = edge.asLine();\n const localSide = edge.asLocalLine();\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\n if (v <= 0) {\n const da = edgeWorld.begin.sub(cc);\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\n // save some sqrts\n if (dda > circle.radius * circle.radius) {\n return []; // no collision\n }\n const normal = da.normalize();\n const separation = circle.radius - Math.sqrt(dda);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.begin,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.begin], [localSide.begin], info)\n ];\n }\n // Potential region B collision (circle is on the right side of the edge, after the end)\n if (u <= 0) {\n const db = edgeWorld.end.sub(cc);\n const ddb = db.dot(db);\n if (ddb > circle.radius * circle.radius) {\n return [];\n }\n const normal = db.normalize();\n const separation = circle.radius - Math.sqrt(ddb);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.end,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.end], [localSide.end], info)\n ];\n }\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\n const den = e.dot(e);\n const pointOnEdge = edgeWorld.begin\n .scale(u)\n .add(edgeWorld.end.scale(v))\n .scale(1 / den);\n const d = cc.sub(pointOnEdge);\n const dd = d.dot(d);\n if (dd > circle.radius * circle.radius) {\n return []; // no collision\n }\n let normal = e.perpendicular();\n // flip correct direction\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\n normal.x = -normal.x;\n normal.y = -normal.y;\n }\n normal = normal.normalize();\n const separation = circle.radius - Math.sqrt(dd);\n const mvt = normal.scale(separation);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: pointOnEdge,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, mvt, normal.negate(), normal.negate().perpendicular(), [pointOnEdge], [pointOnEdge.sub(edge.worldPos)], info)\n ];\n },\n CollideEdgeEdge() {\n // Edge-edge collision doesn't make sense\n return [];\n },\n CollidePolygonEdge(polygon, edge) {\n var _a;\n const pc = polygon.center;\n const ec = edge.center;\n const dir = ec.sub(pc).normalize();\n // build a temporary polygon from the edge to use SAT\n const linePoly = new PolygonCollider({\n points: [edge.begin, edge.end, edge.end.add(dir.scale(100)), edge.begin.add(dir.scale(100))],\n offset: edge.offset\n });\n linePoly.owner = edge.owner;\n const tx = (_a = edge.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (tx) {\n linePoly.update(edge.owner.get(TransformComponent).get());\n }\n // Gross hack but poly-poly works well\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\n if (contact.length) {\n // Fudge the contact back to edge\n contact[0].colliderB = edge;\n contact[0].id = Pair.calculatePairHash(polygon.id, edge.id);\n }\n return contact;\n },\n CollidePolygonPolygon(polyA, polyB) {\n var _a, _b, _c, _d;\n // Multi contact from SAT\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\n // do a SAT test to find a min axis if it exists\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\n // If there is no overlap from boxA's perspective we can end early\n if (separationA.separation > 0) {\n return [];\n }\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\n // If there is no overlap from boxB's perspective exit now\n if (separationB.separation > 0) {\n return [];\n }\n // Separations are both negative, we want to pick the least negative (minimal movement)\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\n // The incident side is the most opposite from the axes of collision on the other collider\n const other = separation.collider === polyA ? polyB : polyA;\n const incident = other.findSide(separation.axis.negate());\n // Clip incident side by the perpendicular lines at each end of the reference side\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\n const reference = separation.side;\n const refDir = reference.dir().normalize();\n // Find our contact points by clipping the incident by the collision side\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\n let clipLeft = null;\n if (clipRight) {\n clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\n }\n // If there is no left there is no collision\n if (clipLeft) {\n // We only want clip points below the reference edge, discard the others\n const points = clipLeft.getPoints().filter((p) => {\n return reference.below(p);\n });\n let normal = separation.axis;\n let tangent = normal.perpendicular();\n // Point Contact A -> B\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\n normal = normal.negate();\n tangent = normal.perpendicular();\n }\n // Points are clipped from incident which is the other collider\n // Store those as locals\n let localPoints = [];\n if (separation.collider === polyA) {\n const xf = (_b = (_a = polyB.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n localPoints = points.map((p) => xf.applyInverse(p));\n }\n else {\n const xf = (_d = (_c = polyA.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n localPoints = points.map((p) => xf.applyInverse(p));\n }\n return [new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)];\n }\n return [];\n },\n FindContactSeparation(contact, localPoint) {\n var _a, _b, _c, _d;\n const shapeA = contact.colliderA;\n const txA = (_b = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const shapeB = contact.colliderB;\n const txB = (_d = (_c = contact.colliderB.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n // both are circles\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\n const combinedRadius = shapeA.radius + shapeB.radius;\n const distance = txA.pos.distance(txB.pos);\n const separation = combinedRadius - distance;\n return -separation;\n }\n // both are polygons\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\n if (contact.info.localSide) {\n let side;\n let worldPoint;\n if (contact.info.collider === shapeA) {\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\n worldPoint = txB.apply(localPoint);\n }\n else {\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\n worldPoint = txA.apply(localPoint);\n }\n return side.distanceToPoint(worldPoint, true);\n }\n }\n // polygon v circle\n if ((shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider) ||\n (shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider)) {\n const worldPoint = txA.apply(localPoint);\n if (contact.info.side) {\n return contact.info.side.distanceToPoint(worldPoint, true);\n }\n }\n // polygon v edge\n if ((shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider) ||\n (shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider)) {\n let worldPoint;\n if (contact.info.collider === shapeA) {\n worldPoint = txB.apply(localPoint);\n }\n else {\n worldPoint = txA.apply(localPoint);\n }\n if (contact.info.side) {\n return contact.info.side.distanceToPoint(worldPoint, true);\n }\n }\n // circle v edge\n if ((shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider) ||\n (shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider)) {\n // Local point is always on the edge which is always shapeB\n const worldPoint = txB.apply(localPoint);\n let circlePoint;\n if (shapeA instanceof CircleCollider) {\n circlePoint = shapeA.getFurthestPoint(contact.normal);\n }\n const dist = worldPoint.distance(circlePoint);\n if (contact.info.side) {\n return dist > 0 ? -dist : 0;\n }\n }\n return 0;\n }\n};\n\n;// CONCATENATED MODULE: ./Collision/Colliders/EdgeCollider.ts\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Edge is a single line collider to create collisions with a single line.\n */\nclass EdgeCollider extends Collider {\n constructor(options) {\n var _a;\n super();\n this._globalMatrix = AffineMatrix.identity();\n this.begin = options.begin || Vector.Zero;\n this.end = options.end || Vector.Zero;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n }\n /**\n * Returns a clone of this Edge, not associated with any collider\n */\n clone() {\n return new EdgeCollider({\n begin: this.begin.clone(),\n end: this.end.clone()\n });\n }\n get worldPos() {\n var _a;\n const tx = this._transform;\n return (_a = tx === null || tx === void 0 ? void 0 : tx.globalPos.add(this.offset)) !== null && _a !== void 0 ? _a : this.offset;\n }\n /**\n * Get the center of the collision area in world coordinates\n */\n get center() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const pos = begin.average(end);\n return pos;\n }\n _getTransformedBegin() {\n return this._globalMatrix.multiply(this.begin);\n }\n _getTransformedEnd() {\n return this._globalMatrix.multiply(this.end);\n }\n /**\n * Returns the slope of the line in the form of a vector\n */\n getSlope() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return end.sub(begin).scale(1 / distance);\n }\n /**\n * Returns the length of the line segment in pixels\n */\n getLength() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return distance;\n }\n /**\n * Tests if a point is contained in this collision area\n */\n contains() {\n return false;\n }\n /**\n * @inheritdoc\n */\n rayCast(ray, max = Infinity) {\n var _a;\n const numerator = this._getTransformedBegin().sub(ray.pos);\n // Test is line and ray are parallel and non intersecting\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) {\n return null;\n }\n // Lines are parallel\n const divisor = ray.dir.cross(this.getSlope());\n if (divisor === 0) {\n return null;\n }\n const t = numerator.cross(this.getSlope()) / divisor;\n if (t >= 0 && t <= max) {\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\n if (u >= 0 && u <= 1) {\n return {\n distance: t,\n normal: this.asLine().normal(),\n collider: this,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n point: ray.getPoint(t)\n };\n }\n }\n return null;\n }\n /**\n * Returns the closes line between this and another collider, from this -> collider\n * @param shape\n */\n getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) {\n return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\n }\n else if (shape instanceof PolygonCollider) {\n return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\n }\n else if (shape instanceof EdgeCollider) {\n return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\n }\n else {\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n }\n /**\n * @inheritdoc\n */\n collide(shape) {\n if (shape instanceof CircleCollider) {\n return CollisionJumpTable.CollideCircleEdge(shape, this);\n }\n else if (shape instanceof PolygonCollider) {\n return CollisionJumpTable.CollidePolygonEdge(shape, this);\n }\n else if (shape instanceof EdgeCollider) {\n return CollisionJumpTable.CollideEdgeEdge();\n }\n else {\n throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\n }\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */\n getFurthestPoint(direction) {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n if (direction.dot(transformedBegin) > 0) {\n return transformedBegin;\n }\n else {\n return transformedEnd;\n }\n }\n _boundsFromBeginEnd(begin, end, padding = 10) {\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\n // this causes problems for the collision system so we give them some padding\n return new BoundingBox(Math.min(begin.x, end.x) - padding, Math.min(begin.y, end.y) - padding, Math.max(begin.x, end.x) + padding, Math.max(begin.y, end.y) + padding);\n }\n /**\n * Get the axis aligned bounding box for the edge collider in world space\n */\n get bounds() {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\n }\n /**\n * Get the axis aligned bounding box for the edge collider in local space\n */\n get localBounds() {\n return this._boundsFromBeginEnd(this.begin, this.end);\n }\n /**\n * Returns this edge represented as a line in world coordinates\n */\n asLine() {\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\n }\n /**\n * Return this edge as a line in local line coordinates (relative to the position)\n */\n asLocalLine() {\n return new LineSegment(this.begin, this.end);\n }\n /**\n * Get the axis associated with the edge\n */\n get axes() {\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\n const edgeNormal = e.normal();\n const axes = [];\n axes.push(edgeNormal);\n axes.push(edgeNormal.negate());\n axes.push(edgeNormal.normal());\n axes.push(edgeNormal.normal().negate());\n return axes;\n }\n /**\n * Get the moment of inertia for an edge\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */\n getInertia(mass) {\n const length = this.end.sub(this.begin).distance() / 2;\n return mass * length * length;\n }\n /**\n * @inheritdoc\n */\n update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Project the edge along a specified axis\n */\n project(axis) {\n const scalars = [];\n const points = [this._getTransformedBegin(), this._getTransformedEnd()];\n const len = points.length;\n for (let i = 0; i < len; i++) {\n scalars.push(points[i].dot(axis));\n }\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color) {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n ex.drawLine(begin, end, color, 2);\n ex.drawCircle(begin, 2, color);\n ex.drawCircle(end, 2, color);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Debug.ts\n\nclass Debug {\n static registerGraphicsContext(ctx) {\n Debug._ctx = ctx;\n }\n static draw(debugDrawCall) {\n this._drawCalls.push(debugDrawCall);\n }\n static drawPoint(point, options) {\n Debug.draw(ctx => {\n ctx.debug.drawPoint(point, options);\n });\n }\n static drawLine(start, end, options) {\n Debug.draw(ctx => {\n ctx.debug.drawLine(start, end, options);\n });\n }\n static drawLines(points, options) {\n if (points.length > 1) {\n Debug.draw(ctx => {\n for (let i = 0; i < points.length - 1; i++) {\n ctx.debug.drawLine(points[i], points[i + 1], options);\n }\n });\n }\n }\n static drawText(text, pos) {\n Debug.draw(ctx => {\n ctx.debug.drawText(text, pos);\n });\n }\n static drawPolygon(points, options) {\n if (points.length > 1) {\n Debug.draw(ctx => {\n const firstPoint = points[0];\n const polygon = [...points, firstPoint];\n for (let i = 0; i < polygon.length - 1; i++) {\n ctx.debug.drawLine(polygon[i], polygon[i + 1], options);\n }\n });\n }\n }\n static drawCircle(center, radius, options) {\n const { color, strokeColor, width } = {\n color: Color.Black,\n strokeColor: undefined,\n width: undefined,\n ...options\n };\n Debug.draw(ctx => {\n ctx.drawCircle(center, radius, color, strokeColor, width);\n });\n }\n static drawBounds(boundingBox, options) {\n Debug.draw(ctx => {\n ctx.debug.drawRect(boundingBox.left, boundingBox.top, boundingBox.width, boundingBox.height, options);\n });\n }\n static drawRay(ray, options) {\n const { distance, color } = {\n color: Color.Blue,\n distance: 10,\n ...options\n };\n Debug.draw((ctx) => {\n const start = ray.pos;\n const end = ray.pos.add(ray.dir.scale(distance));\n ctx.debug.drawLine(start, end, { color });\n });\n }\n static flush(ctx) {\n ctx.save();\n ctx.z = Debug.z;\n for (const drawCall of Debug._drawCalls) {\n drawCall(ctx);\n }\n ctx.restore();\n Debug.clear();\n }\n static clear() {\n Debug._drawCalls.length = 0;\n }\n}\nDebug._drawCalls = [];\nDebug.z = Infinity;\n\n;// CONCATENATED MODULE: ./Collision/Colliders/PolygonCollider.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Polygon collider for detecting collisions\n */\nclass PolygonCollider extends Collider {\n flagDirty() {\n this._localBoundsDirty = true;\n this._localSidesDirty = true;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n }\n /**\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\n * Excalibur stores these in counter-clockwise order\n */\n set points(points) {\n this._points = points;\n this.flagDirty();\n }\n /**\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\n * Excalibur stores these in counter-clockwise order\n */\n get points() {\n return this._points;\n }\n constructor(options) {\n var _a, _b;\n super();\n this._logger = Logger.getInstance();\n this._transformedPoints = [];\n this._sides = [];\n this._localSides = [];\n this._globalMatrix = AffineMatrix.identity();\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n this._localSidesDirty = true;\n this._localBoundsDirty = true;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n this.points = (_b = options.points) !== null && _b !== void 0 ? _b : [];\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\n if (!counterClockwise) {\n this.points.reverse();\n }\n if (!this.isConvex()) {\n if (!options.suppressConvexWarning) {\n this._logger.warn('Excalibur only supports convex polygon colliders and will not behave properly.' +\n 'Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles');\n }\n }\n // calculate initial transformation\n this._calculateTransformation();\n }\n _isCounterClockwiseWinding(points) {\n // https://stackoverflow.com/a/1165943\n let sum = 0;\n for (let i = 0; i < points.length; i++) {\n sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\n }\n return sum < 0;\n }\n /**\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\n */\n isConvex() {\n // From SO: https://stackoverflow.com/a/45372025\n if (this.points.length < 3) {\n return false;\n }\n let oldPoint = this.points[this.points.length - 2];\n let newPoint = this.points[this.points.length - 1];\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n let oldDirection = 0;\n let orientation = 0;\n let angleSum = 0;\n for (const [i, point] of this.points.entries()) {\n oldPoint = newPoint;\n oldDirection = direction;\n newPoint = point;\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n if (oldPoint.equals(newPoint)) {\n return false; // repeat point\n }\n let angle = direction - oldDirection;\n if (angle <= -Math.PI) {\n angle += Math.PI * 2;\n }\n else if (angle > Math.PI) {\n angle -= Math.PI * 2;\n }\n if (i === 0) {\n if (angle === 0.0) {\n return false;\n }\n orientation = angle > 0 ? 1 : -1;\n }\n else {\n if (orientation * angle <= 0) {\n return false;\n }\n }\n angleSum += angle;\n }\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\n }\n /**\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\n */\n tessellate() {\n const polygons = [];\n for (let i = 1; i < this.points.length - 2; i++) {\n polygons.push([this.points[0], this.points[i + 1], this.points[i + 2]]);\n }\n polygons.push([this.points[0], this.points[1], this.points[2]]);\n return new CompositeCollider(polygons.map(points => Shape.Polygon(points)));\n }\n /**\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\n */\n triangulate() {\n // https://www.youtube.com/watch?v=hTJFcHutls8\n if (this.points.length < 3) {\n throw Error('Invalid polygon');\n }\n const triangles = [];\n // algorithm likes clockwise\n const vertices = [...this.points].reverse();\n let vertexCount = vertices.length;\n /**\n * Returns the previous index based on the current vertex\n */\n function getPrevIndex(index) {\n return index === 0 ? vertexCount - 1 : index - 1;\n }\n /**\n * Retrieves the next index based on the current vertex\n */\n function getNextIndex(index) {\n return index === vertexCount - 1 ? 0 : index + 1;\n }\n /**\n * Whether or not the angle at this vertex index is convex\n */\n function isConvex(index) {\n const prev = getPrevIndex(index);\n const next = getNextIndex(index);\n const va = vertices[prev];\n const vb = vertices[index];\n const vc = vertices[next];\n // Check convexity\n const leftArm = va.sub(vb);\n const rightArm = vc.sub(vb);\n // Positive cross product is convex\n if (leftArm.cross(rightArm) < 0) {\n return false;\n }\n return true;\n }\n const convexVertices = vertices.map((_, i) => isConvex(i));\n /**\n * Quick test for point in triangle\n */\n function isPointInTriangle(point, a, b, c) {\n const ab = b.sub(a);\n const bc = c.sub(b);\n const ca = a.sub(c);\n const ap = point.sub(a);\n const bp = point.sub(b);\n const cp = point.sub(c);\n const cross1 = ab.cross(ap);\n const cross2 = bc.cross(bp);\n const cross3 = ca.cross(cp);\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) {\n return false;\n }\n return true;\n }\n /**\n * Calculate the area of the triangle\n */\n // function triangleArea(a: Vector, b: Vector, c: Vector) {\n // return Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - c.y))/2;\n // }\n /**\n * Find the next suitable ear tip\n */\n function findEarTip() {\n for (let i = 0; i < vertexCount; i++) {\n if (convexVertices[i]) {\n const prev = getPrevIndex(i);\n const next = getNextIndex(i);\n const va = vertices[prev];\n const vb = vertices[i];\n const vc = vertices[next];\n let isEar = true;\n // Check that if any vertices are in the triangle a, b, c\n for (let j = 0; j < vertexCount; j++) {\n // We can skip these verts because they are the triangle we are testing\n if (j === i || j === prev || j === next) {\n continue;\n }\n const point = vertices[j];\n if (isPointInTriangle(point, va, vb, vc)) {\n isEar = false;\n break;\n }\n }\n // Add ear to polygon list and remove from list\n if (isEar) {\n return i;\n }\n }\n }\n // Fall back to any convex vertex\n for (let i = 0; i < vertexCount; i++) {\n if (convexVertices[i]) {\n return i;\n }\n }\n // bail and return the first one?\n return 0;\n }\n /**\n * Cut the ear and produce a triangle, update internal state\n */\n function cutEarTip(index) {\n const prev = getPrevIndex(index);\n const next = getNextIndex(index);\n const va = vertices[prev];\n const vb = vertices[index];\n const vc = vertices[next];\n // Clockwise winding\n // if (triangleArea(va, vb, vc) > 0) {\n triangles.push([va, vb, vc]);\n // }\n vertices.splice(index, 1);\n convexVertices.splice(index, 1);\n vertexCount--;\n }\n // Loop over all the vertices finding ears\n while (vertexCount > 3) {\n const earIndex = findEarTip();\n cutEarTip(earIndex);\n // reclassify vertices\n for (let i = 0; i < vertexCount; i++) {\n convexVertices[i] = isConvex(i);\n }\n }\n // Last triangle after the loop\n triangles.push([vertices[0], vertices[1], vertices[2]]);\n // FIXME: there is a colinear triangle that sneaks in here sometimes\n return new CompositeCollider(triangles.map(points => Shape.Polygon(points, Vector.Zero, true)));\n }\n /**\n * Returns a clone of this ConvexPolygon, not associated with any collider\n */\n clone() {\n return new PolygonCollider({\n offset: this.offset.clone(),\n points: this.points.map((p) => p.clone())\n });\n }\n /**\n * Returns the world position of the collider, which is the current body transform plus any defined offset\n */\n get worldPos() {\n if (this._transform) {\n return this._transform.pos.add(this.offset);\n }\n return this.offset;\n }\n /**\n * Get the center of the collider in world coordinates\n */\n get center() {\n return this.bounds.center;\n }\n /**\n * Calculates the underlying transformation from the body relative space to world space\n */\n _calculateTransformation() {\n const points = this.points;\n const len = points.length;\n this._transformedPoints.length = 0; // clear out old transform\n for (let i = 0; i < len; i++) {\n this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\n }\n }\n /**\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\n */\n getTransformedPoints() {\n if (this._transformedPointsDirty) {\n this._calculateTransformation();\n this._transformedPointsDirty = false;\n }\n return this._transformedPoints;\n }\n /**\n * Gets the sides of the polygon in world space\n */\n getSides() {\n if (this._sidesDirty) {\n const lines = [];\n const points = this.getTransformedPoints();\n const len = points.length;\n for (let i = 0; i < len; i++) {\n // This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n }\n this._sides = lines;\n this._sidesDirty = false;\n }\n return this._sides;\n }\n /**\n * Returns the local coordinate space sides\n */\n getLocalSides() {\n if (this._localSidesDirty) {\n const lines = [];\n const points = this.points;\n const len = points.length;\n for (let i = 0; i < len; i++) {\n // This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n }\n this._localSides = lines;\n this._localSidesDirty = false;\n }\n return this._localSides;\n }\n /**\n * Given a direction vector find the world space side that is most in that direction\n * @param direction\n */\n findSide(direction) {\n const sides = this.getSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for (let side = 0; side < sides.length; side++) {\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\n * Given a direction vector find the local space side that is most in that direction\n * @param direction\n */\n findLocalSide(direction) {\n const sides = this.getLocalSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for (let side = 0; side < sides.length; side++) {\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\n * Get the axis associated with the convex polygon\n */\n get axes() {\n const axes = [];\n const sides = this.getSides();\n for (let i = 0; i < sides.length; i++) {\n axes.push(sides[i].normal());\n }\n return axes;\n }\n /**\n * Updates the transform for the collision geometry\n *\n * Collision geometry (points/bounds) will not change until this is called.\n * @param transform\n */\n update(transform) {\n var _a;\n if (transform) {\n this._transform = transform;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n // This change means an update must be performed in order for geometry to update\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n }\n /**\n * Tests if a point is contained in this collider in world space\n */\n contains(point) {\n // Always cast to the right, as long as we cast in a consistent fixed direction we\n // will be fine\n const testRay = new Ray(point, new Vector(1, 0));\n const intersectCount = this.getSides().reduce(function (accum, side) {\n if (testRay.intersect(side) >= 0) {\n return accum + 1;\n }\n return accum;\n }, 0);\n if (intersectCount % 2 === 0) {\n return false;\n }\n return true;\n }\n getClosestLineBetween(collider) {\n if (collider instanceof CircleCollider) {\n return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\n }\n else if (collider instanceof PolygonCollider) {\n return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\n }\n else if (collider instanceof EdgeCollider) {\n return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\n }\n else {\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n }\n /**\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\n * return null.\n * @param collider\n */\n collide(collider) {\n if (collider instanceof CircleCollider) {\n return CollisionJumpTable.CollideCirclePolygon(collider, this);\n }\n else if (collider instanceof PolygonCollider) {\n return CollisionJumpTable.CollidePolygonPolygon(this, collider);\n }\n else if (collider instanceof EdgeCollider) {\n return CollisionJumpTable.CollidePolygonEdge(this, collider);\n }\n else {\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */\n getFurthestPoint(direction) {\n const pts = this.getTransformedPoints();\n let furthestPoint = null;\n let maxDistance = -Number.MAX_VALUE;\n for (let i = 0; i < pts.length; i++) {\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\n * Find the local point on the collider furthest in the direction specified\n * @param direction\n */\n getFurthestLocalPoint(direction) {\n const pts = this.points;\n let furthestPoint = pts[0];\n let maxDistance = -Number.MAX_VALUE;\n for (let i = 0; i < pts.length; i++) {\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\n * Finds the closes face to the point using perpendicular distance\n * @param point point to test against polygon\n */\n getClosestFace(point) {\n const sides = this.getSides();\n let min = Number.POSITIVE_INFINITY;\n let faceIndex = -1;\n let distance = -1;\n for (let i = 0; i < sides.length; i++) {\n const dist = sides[i].distanceToPoint(point);\n if (dist < min) {\n min = dist;\n faceIndex = i;\n distance = dist;\n }\n }\n if (faceIndex !== -1) {\n return {\n distance: sides[faceIndex].normal().scale(distance),\n face: sides[faceIndex]\n };\n }\n return null;\n }\n /**\n * Get the axis aligned bounding box for the polygon collider in world coordinates\n */\n get bounds() {\n return this.localBounds.transform(this._globalMatrix);\n }\n /**\n * Get the axis aligned bounding box for the polygon collider in local coordinates\n */\n get localBounds() {\n if (this._localBoundsDirty) {\n this._localBounds = BoundingBox.fromPoints(this.points);\n this._localBoundsDirty = false;\n }\n return this._localBounds;\n }\n /**\n * Get the moment of inertia for an arbitrary polygon\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */\n getInertia(mass) {\n if (this._cachedMass === mass && this._cachedInertia) {\n return this._cachedInertia;\n }\n let numerator = 0;\n let denominator = 0;\n const points = this.points;\n for (let i = 0; i < points.length; i++) {\n const iplusone = (i + 1) % points.length;\n const crossTerm = points[iplusone].cross(points[i]);\n numerator +=\n crossTerm *\n (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\n denominator += crossTerm;\n }\n this._cachedMass = mass;\n return this._cachedInertia = (mass / 6) * (numerator / denominator);\n }\n /**\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\n */\n rayCast(ray, max = Infinity) {\n var _a;\n // find the minimum contact time greater than 0\n // contact times less than 0 are behind the ray and we don't want those\n const sides = this.getSides();\n const len = sides.length;\n let minContactTime = Number.MAX_VALUE;\n let contactSide;\n let contactIndex = -1;\n for (let i = 0; i < len; i++) {\n const contactTime = ray.intersect(sides[i]);\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\n minContactTime = contactTime;\n contactSide = sides[i];\n contactIndex = i;\n }\n }\n // contact was found\n if (contactIndex >= 0) {\n return {\n collider: this,\n distance: minContactTime,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n point: ray.getPoint(minContactTime),\n normal: contactSide.normal()\n };\n }\n // no contact found\n return null;\n }\n /**\n * Project the edges of the polygon along a specified axis\n */\n project(axis) {\n const points = this.getTransformedPoints();\n const len = points.length;\n let min = Number.MAX_VALUE;\n let max = -Number.MAX_VALUE;\n for (let i = 0; i < len; i++) {\n const scalar = points[i].dot(axis);\n min = Math.min(min, scalar);\n max = Math.max(max, scalar);\n }\n return new Projection(min, max);\n }\n debug(ex, color, options) {\n const points = this.getTransformedPoints();\n Debug.drawPolygon(points, { color });\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/Shape.ts\n\n\n\n\n\n\n\n/**\n * Excalibur helper for defining colliders quickly\n */\nclass Shape {\n /**\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\n * @param width Width of the box\n * @param height Height of the box\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\n * @param offset Optional offset relative to the collider in local coordinates\n */\n static Box(width, height, anchor = Vector.Half, offset = Vector.Zero) {\n return new PolygonCollider({\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\n offset: offset\n });\n }\n /**\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\n *\n * PolygonColliders are useful for creating convex polygon shapes\n * @param points Points specified in counter clockwise\n * @param offset Optional offset relative to the collider in local coordinates\n */\n static Polygon(points, offset = Vector.Zero, suppressConvexWarning = false) {\n return new PolygonCollider({\n points: points,\n offset: offset,\n suppressConvexWarning\n });\n }\n /**\n * Creates a new [[CircleCollider|circle]] collider\n *\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\n * @param radius Radius of the circle collider\n * @param offset Optional offset relative to the collider in local coordinates\n */\n static Circle(radius, offset = Vector.Zero) {\n return new CircleCollider({\n radius: radius,\n offset: offset\n });\n }\n /**\n * Creates a new [[EdgeCollider|edge]] collider\n *\n * Edge colliders are useful for floors, walls, and other barriers\n * @param begin Beginning of the edge in local coordinates to the collider\n * @param end Ending of the edge in local coordinates to the collider\n */\n static Edge(begin, end) {\n return new EdgeCollider({\n begin: begin,\n end: end\n });\n }\n /**\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\n *\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\n * player experience.\n * @param width\n * @param height\n * @param offset Optional offset\n */\n static Capsule(width, height, offset = Vector.Zero) {\n const logger = Logger.getInstance();\n if (width === height) {\n logger.warn('A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider');\n }\n const vertical = height >= width;\n if (vertical) {\n // height > width, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\n Shape.Box(width, height - width, Vector.Half, offset),\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\n ]);\n return capsule;\n }\n else {\n // width > height, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\n Shape.Box(width - height, height, Vector.Half, offset),\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\n ]);\n return capsule;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/ColliderComponent.ts\n\n\n\n\n\n\n\n\n\n\nclass ColliderComponent extends Component {\n constructor(collider) {\n super();\n this.events = new EventEmitter();\n /**\n * Observable that notifies when a collider is added to the body\n */\n this.$colliderAdded = new Observable();\n /**\n * Observable that notifies when a collider is removed from the body\n */\n this.$colliderRemoved = new Observable();\n this._collidersToRemove = [];\n this.set(collider);\n }\n /**\n * Get the current collider geometry\n */\n get() {\n return this._collider;\n }\n /**\n * Set the collider geometry\n * @param collider\n * @returns the collider you set\n */\n set(collider) {\n this.clear();\n if (collider) {\n this._collider = collider;\n this._collider.owner = this.owner;\n collider.events.pipe(this.events);\n this.$colliderAdded.notifyAll(collider);\n this.update();\n }\n return collider;\n }\n /**\n * Remove collider geometry from collider component\n */\n clear() {\n if (this._collider) {\n this._collidersToRemove.push(this._collider);\n this._collider = null;\n }\n }\n processColliderRemoval() {\n for (const collider of this._collidersToRemove) {\n collider.events.unpipe(this.events);\n this.$colliderRemoved.notifyAll(collider);\n collider.owner = null;\n }\n }\n clone() {\n const clone = new ColliderComponent(this._collider.clone());\n return clone;\n }\n /**\n * Return world space bounds\n */\n get bounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\n * Return local space bounds\n */\n get localBounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\n * Update the collider's transformed geometry\n */\n update() {\n var _a;\n const tx = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (this._collider) {\n this._collider.owner = this.owner;\n if (tx) {\n this._collider.update(tx.get());\n }\n }\n }\n /**\n * Collide component with another\n * @param other\n */\n collide(other) {\n let colliderA = this._collider;\n let colliderB = other._collider;\n if (!colliderA || !colliderB) {\n return [];\n }\n // If we have a composite left hand side :(\n // Might bite us, but to avoid updating all the handlers make composite always left side\n let flipped = false;\n if (colliderB instanceof CompositeCollider) {\n colliderA = colliderB;\n colliderB = this._collider;\n flipped = true;\n }\n if (this._collider) {\n const contacts = colliderA.collide(colliderB);\n if (contacts) {\n if (flipped) {\n contacts.forEach((contact) => {\n contact.mtv = contact.mtv.negate();\n contact.normal = contact.normal.negate();\n contact.tangent = contact.normal.perpendicular();\n contact.colliderA = this._collider;\n contact.colliderB = other._collider;\n });\n }\n return contacts;\n }\n return [];\n }\n return [];\n }\n onAdd(entity) {\n if (this._collider) {\n this.update();\n }\n // Wire up the collider events to the owning entity\n this.events.on('precollision', (evt) => {\n const precollision = evt;\n entity.events.emit('precollision', new PreCollisionEvent(precollision.target.owner, precollision.other.owner, precollision.side, precollision.intersection, precollision.contact));\n if (entity instanceof Actor) {\n entity.onPreCollisionResolve(precollision.target, precollision.other, precollision.side, precollision.contact);\n }\n });\n this.events.on('postcollision', (evt) => {\n const postcollision = evt;\n entity.events.emit('postcollision', new PostCollisionEvent(postcollision.target.owner, postcollision.other.owner, postcollision.side, postcollision.intersection, postcollision.contact));\n if (entity instanceof Actor) {\n entity.onPostCollisionResolve(postcollision.target, postcollision.other, postcollision.side, postcollision.contact);\n }\n });\n this.events.on('collisionstart', (evt) => {\n const start = evt;\n entity.events.emit('collisionstart', new CollisionStartEvent(start.target.owner, start.other.owner, start.side, start.contact));\n if (entity instanceof Actor) {\n entity.onCollisionStart(start.target, start.other, start.side, start.contact);\n }\n });\n this.events.on('collisionend', (evt) => {\n const end = evt;\n entity.events.emit('collisionend', new CollisionEndEvent(end.target.owner, end.other.owner, end.side, end.lastContact));\n if (entity instanceof Actor) {\n entity.onCollisionEnd(end.target, end.other, end.side, end.lastContact);\n }\n });\n }\n onRemove() {\n this.events.clear();\n this.$colliderRemoved.notifyAll(this._collider);\n }\n /**\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\n *\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */\n useBoxCollider(width, height, anchor = Vector.Half, center = Vector.Zero) {\n const collider = Shape.Box(width, height, anchor, center);\n return (this.set(collider));\n }\n /**\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\n * to the anchor of the associated actor\n * of this physics body.\n *\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */\n usePolygonCollider(points, center = Vector.Zero) {\n const poly = Shape.Polygon(points, center);\n return (this.set(poly));\n }\n /**\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */\n useCircleCollider(radius, center = Vector.Zero) {\n const collider = Shape.Circle(radius, center);\n return (this.set(collider));\n }\n /**\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\n * of this physics body.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */\n useEdgeCollider(begin, end) {\n const collider = Shape.Edge(begin, end);\n return (this.set(collider));\n }\n /**\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\n * @param colliders\n */\n useCompositeCollider(colliders) {\n return (this.set(new CompositeCollider(colliders)));\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/BodyComponent.ts\n\n\n\n\n\n\n\n\n\n\n\n\nvar DegreeOfFreedom;\n(function (DegreeOfFreedom) {\n DegreeOfFreedom[\"Rotation\"] = \"rotation\";\n DegreeOfFreedom[\"X\"] = \"x\";\n DegreeOfFreedom[\"Y\"] = \"y\";\n})(DegreeOfFreedom || (DegreeOfFreedom = {}));\n/**\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\n * of physics simulation.\n */\nclass BodyComponent extends Component {\n constructor(options) {\n var _a, _b, _c;\n super();\n this.dependencies = [TransformComponent, MotionComponent];\n this.id = createId('body', BodyComponent._ID++);\n this.events = new EventEmitter();\n this.oldTransform = new transform_Transform();\n /**\n * Indicates whether the old transform has been captured at least once for interpolation\n * @internal\n */\n this.__oldTransformCaptured = false;\n /**\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\n */\n this.enableFixedUpdateInterpolate = true;\n /**\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\n */\n this.collisionType = CollisionType.PreventCollision;\n /**\n * The collision group for the body's colliders, by default body colliders collide with everything\n */\n this.group = CollisionGroup.All;\n this._sleeping = false;\n /**\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\n */\n this.bounciness = 0.2;\n /**\n * The coefficient of friction on this actor\n */\n this.friction = 0.99;\n /**\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\n */\n this.useGravity = true;\n /**\n * Degrees of freedom to limit\n *\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\n */\n this.limitDegreeOfFreedom = [];\n /**\n * The velocity of the actor last frame (vx, vy) in pixels/second\n */\n this.oldVel = new Vector(0, 0);\n /**\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */\n this.oldAcc = Vector.Zero;\n if (options) {\n this.collisionType = (_a = options.type) !== null && _a !== void 0 ? _a : this.collisionType;\n this.group = (_b = options.group) !== null && _b !== void 0 ? _b : this.group;\n this.useGravity = (_c = options.useGravity) !== null && _c !== void 0 ? _c : this.useGravity;\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies,\n ...options.config\n };\n }\n else {\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies\n };\n }\n this.updatePhysicsConfig(this._bodyConfig);\n this._mass = BodyComponent._DEFAULT_CONFIG.defaultMass;\n }\n get matrix() {\n return this.transform.get().matrix;\n }\n /**\n * Called by excalibur to update physics config defaults if they change\n * @param config\n */\n updatePhysicsConfig(config) {\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies,\n ...config\n };\n this.canSleep = this._bodyConfig.canSleepByDefault;\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\n this.wakeThreshold = this._bodyConfig.wakeThreshold;\n }\n /**\n * Called by excalibur to update defaults\n * @param config\n */\n static updateDefaultPhysicsConfig(config) {\n BodyComponent._DEFAULT_CONFIG = config;\n }\n get mass() {\n return this._mass;\n }\n set mass(newMass) {\n this._mass = newMass;\n this._cachedInertia = undefined;\n this._cachedInverseInertia = undefined;\n }\n /**\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\n */\n get inverseMass() {\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\n }\n ;\n /**\n * Whether this body is sleeping or not\n */\n get sleeping() {\n return this._sleeping;\n }\n /**\n * Set the sleep state of the body\n * @param sleeping\n */\n setSleeping(sleeping) {\n this._sleeping = sleeping;\n if (!sleeping) {\n // Give it a kick to keep it from falling asleep immediately\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\n }\n else {\n this.vel = Vector.Zero;\n this.acc = Vector.Zero;\n this.angularVelocity = 0;\n this.sleepMotion = 0;\n }\n }\n /**\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\n */\n updateMotion() {\n if (this._sleeping) {\n this.setSleeping(true);\n }\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\n const bias = this._bodyConfig.sleepBias;\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * this._bodyConfig.sleepEpsilon);\n if (this.canSleep && this.sleepMotion < this._bodyConfig.sleepEpsilon) {\n this.setSleeping(true);\n }\n }\n /**\n * Get the moment of inertia from the [[ColliderComponent]]\n */\n get inertia() {\n if (this._cachedInertia) {\n return this._cachedInertia;\n }\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\n const collider = this.owner.get(ColliderComponent);\n if (collider) {\n collider.$colliderAdded.subscribe(() => {\n this._cachedInertia = null;\n });\n collider.$colliderRemoved.subscribe(() => {\n this._cachedInertia = null;\n });\n const maybeCollider = collider.get();\n if (maybeCollider) {\n return this._cachedInertia = maybeCollider.getInertia(this.mass);\n }\n }\n return 0;\n }\n /**\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\n */\n get inverseInertia() {\n if (this._cachedInverseInertia) {\n return this._cachedInverseInertia;\n }\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\n }\n /**\n * Returns if the owner is active\n */\n get active() {\n var _a;\n return !!((_a = this.owner) === null || _a === void 0 ? void 0 : _a.active);\n }\n /**\n * @deprecated Use globalP0s\n */\n get center() {\n return this.globalPos;\n }\n get transform() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n }\n get motion() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(MotionComponent);\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n /**\n * The (x, y) position of the actor this will be in the middle of the actor if the\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\n */\n get globalPos() {\n return this.transform.globalPos;\n }\n set globalPos(val) {\n this.transform.globalPos = val;\n }\n /**\n * The position of the actor last frame (x, y) in pixels\n */\n get oldPos() {\n return this.oldTransform.pos;\n }\n /**\n * The current velocity vector (vx, vy) of the actor in pixels/second\n */\n get vel() {\n return this.motion.vel;\n }\n set vel(val) {\n this.motion.vel = val;\n }\n /**\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\n * be useful to simulate a gravitational effect.\n */\n get acc() {\n return this.motion.acc;\n }\n set acc(val) {\n this.motion.acc = val;\n }\n /**\n * The current torque applied to the actor\n */\n get torque() {\n return this.motion.torque;\n }\n set torque(val) {\n this.motion.torque = val;\n }\n /**\n * Gets/sets the rotation of the body from the last frame.\n */\n get oldRotation() {\n return this.oldTransform.rotation;\n }\n /**\n * The rotation of the body in radians\n */\n get rotation() {\n return this.transform.globalRotation;\n }\n set rotation(val) {\n this.transform.globalRotation = val;\n }\n /**\n * The scale vector of the actor\n */\n get scale() {\n return this.transform.globalScale;\n }\n set scale(val) {\n this.transform.globalScale = val;\n }\n /**\n * The scale of the actor last frame\n */\n get oldScale() {\n return this.oldTransform.scale;\n }\n /**\n * The scale rate of change of the actor in scale/second\n */\n get scaleFactor() {\n return this.motion.scaleFactor;\n }\n set scaleFactor(scaleFactor) {\n this.motion.scaleFactor = scaleFactor;\n }\n /**\n * Get the angular velocity in radians/second\n */\n get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\n * Set the angular velocity in radians/second\n */\n set angularVelocity(value) {\n this.motion.angularVelocity = value;\n }\n /**\n * Apply a specific impulse to the body\n * @param point\n * @param impulse\n */\n applyImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) {\n return; // only active objects participate in the simulation\n }\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\n finalImpulse.x = 0;\n }\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\n finalImpulse.y = 0;\n }\n this.vel.addEqual(finalImpulse);\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\n * Apply only linear impulse to the body\n * @param impulse\n */\n applyLinearImpulse(impulse) {\n if (this.collisionType !== CollisionType.Active) {\n return; // only active objects participate in the simulation\n }\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\n finalImpulse.x = 0;\n }\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\n finalImpulse.y = 0;\n }\n this.vel = this.vel.add(finalImpulse);\n }\n /**\n * Apply only angular impulse to the body\n * @param point\n * @param impulse\n */\n applyAngularImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) {\n return; // only active objects participate in the simulation\n }\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\n * Sets the old versions of pos, vel, acc, and scale.\n */\n captureOldTransform() {\n // Capture old values before integration step updates them\n this.__oldTransformCaptured = true;\n const tx = this.transform.get();\n tx.clone(this.oldTransform);\n this.oldTransform.parent = tx.parent; // also grab parent\n this.oldVel.setTo(this.vel.x, this.vel.y);\n this.oldAcc.setTo(this.acc.x, this.acc.y);\n }\n clone() {\n const component = super.clone();\n return component;\n }\n}\nBodyComponent._ID = 0;\nBodyComponent._DEFAULT_CONFIG = {\n ...DefaultPhysicsConfig.bodies\n};\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Entity.ts\n\n\n\n\n\n\n/**\n * AddedComponent message\n */\nclass AddedComponent {\n constructor(data) {\n this.data = data;\n this.type = 'Component Added';\n }\n}\n/**\n * Type guard to know if message is f an Added Component\n */\nfunction isAddedComponent(x) {\n return !!x && x.type === 'Component Added';\n}\n/**\n * RemovedComponent message\n */\nclass RemovedComponent {\n constructor(data) {\n this.data = data;\n this.type = 'Component Removed';\n }\n}\n/**\n * Type guard to know if message is for a Removed Component\n */\nfunction isRemovedComponent(x) {\n return !!x && x.type === 'Component Removed';\n}\nconst EntityEvents = {\n Initialize: 'initialize',\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate',\n Kill: 'kill'\n};\n/**\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\n *\n * Entities can be strongly typed with the components they contain\n *\n * ```typescript\n * const entity = new Entity();\n * entity.components.a; // Type ComponentA\n * entity.components.b; // Type ComponentB\n * ```\n */\nclass Entity {\n constructor(componentsOrOptions, name) {\n /**\n * The unique identifier for the entity\n */\n this.id = Entity._ID++;\n this.name = `Entity#${this.id}`;\n /**\n * Listen to or emit events for an entity\n */\n this.events = new EventEmitter();\n this._tags = new Set();\n this.componentAdded$ = new Observable;\n this.componentRemoved$ = new Observable;\n this.tagAdded$ = new Observable;\n this.tagRemoved$ = new Observable;\n /**\n * Current components on the entity\n *\n * **Do not modify**\n *\n * Use addComponent/removeComponent otherwise the ECS will not be notified of changes.\n */\n this.components = new Map();\n this._componentsToRemove = [];\n this._instanceOfComponentCacheDirty = true;\n this._instanceOfComponentCache = new Map();\n /**\n * The current scene that the entity is in, if any\n */\n this.scene = null;\n /**\n * Whether this entity is active, if set to false it will be reclaimed\n */\n this.active = true;\n this._parent = null;\n this.childrenAdded$ = new Observable();\n this.childrenRemoved$ = new Observable();\n this._children = [];\n this._isInitialized = false;\n let componentsToAdd;\n let nameToAdd;\n if (Array.isArray(componentsOrOptions)) {\n componentsToAdd = componentsOrOptions;\n nameToAdd = name;\n }\n else if (componentsOrOptions && typeof componentsOrOptions === 'object') {\n const { components, name } = componentsOrOptions;\n componentsToAdd = components;\n nameToAdd = name;\n }\n if (nameToAdd) {\n this.name = nameToAdd;\n }\n if (componentsToAdd) {\n for (const component of componentsToAdd) {\n this.addComponent(component);\n }\n }\n // this.addComponent(this.tagsComponent);\n }\n /**\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\n * If parented it will be removed from the parent when killed.\n */\n kill() {\n if (this.active) {\n this.active = false;\n this.unparent();\n }\n this.emit('kill', new KillEvent(this));\n }\n isKilled() {\n return !this.active;\n }\n /**\n * Specifically get the tags on the entity from [[TagsComponent]]\n */\n get tags() {\n return this._tags;\n }\n /**\n * Check if a tag exists on the entity\n * @param tag name to check for\n */\n hasTag(tag) {\n return this._tags.has(tag);\n }\n /**\n * Adds a tag to an entity\n * @param tag\n */\n addTag(tag) {\n this._tags.add(tag);\n this.tagAdded$.notifyAll(tag);\n }\n /**\n * Removes a tag on the entity\n *\n * Removals are deferred until the end of update\n * @param tag\n */\n removeTag(tag) {\n this._tags.delete(tag);\n this.tagRemoved$.notifyAll(tag);\n }\n /**\n * The types of the components on the Entity\n */\n get types() {\n return Array.from(this.components.keys());\n }\n /**\n * Returns all component instances on entity\n */\n getComponents() {\n return Array.from(this.components.values());\n }\n /**\n * Verifies that an entity has all the required types\n * @param requiredTypes\n */\n hasAll(requiredTypes) {\n for (let i = 0; i < requiredTypes.length; i++) {\n if (!this.components.has(requiredTypes[i])) {\n return false;\n }\n }\n return true;\n }\n /**\n * Verifies that an entity has all the required tags\n * @param requiredTags\n */\n hasAllTags(requiredTags) {\n for (let i = 0; i < requiredTags.length; i++) {\n if (!this.tags.has(requiredTags[i])) {\n return false;\n }\n }\n return true;\n }\n _getCachedInstanceOfType(type) {\n if (this._instanceOfComponentCacheDirty) {\n this._instanceOfComponentCacheDirty = false;\n this._instanceOfComponentCache.clear();\n }\n if (this._instanceOfComponentCache.has(type)) {\n return this._instanceOfComponentCache.get(type);\n }\n for (const instance of this.components.values()) {\n if (instance instanceof type) {\n this._instanceOfComponentCache.set(type, instance);\n return instance;\n }\n }\n return undefined;\n }\n get(type) {\n const maybeComponent = this._getCachedInstanceOfType(type);\n return maybeComponent !== null && maybeComponent !== void 0 ? maybeComponent : this.components.get(type);\n }\n get parent() {\n return this._parent;\n }\n /**\n * Get the direct children of this entity\n */\n get children() {\n return this._children;\n }\n /**\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\n */\n unparent() {\n if (this._parent) {\n this._parent.removeChild(this);\n this._parent = null;\n }\n }\n /**\n * Adds an entity to be a child of this entity\n * @param entity\n */\n addChild(entity) {\n if (entity.parent === null) {\n if (this.getAncestors().includes(entity)) {\n throw new Error('Cycle detected, cannot add entity');\n }\n this._children.push(entity);\n entity._parent = this;\n this.childrenAdded$.notifyAll(entity);\n }\n else {\n throw new Error('Entity already has a parent, cannot add without unparenting');\n }\n return this;\n }\n /**\n * Remove an entity from children if it exists\n * @param entity\n */\n removeChild(entity) {\n if (entity.parent === this) {\n removeItemFromArray(entity, this._children);\n entity._parent = null;\n this.childrenRemoved$.notifyAll(entity);\n }\n return this;\n }\n /**\n * Removes all children from this entity\n */\n removeAllChildren() {\n // Avoid modifying the array issue by walking backwards\n for (let i = this.children.length - 1; i >= 0; i--) {\n this.removeChild(this.children[i]);\n }\n return this;\n }\n /**\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\n */\n getAncestors() {\n const result = [this];\n let current = this.parent;\n while (current) {\n result.push(current);\n current = current.parent;\n }\n return result.reverse();\n }\n /**\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\n */\n getDescendants() {\n let result = [this];\n let queue = [this];\n while (queue.length > 0) {\n const curr = queue.pop();\n if (curr) {\n queue = queue.concat(curr.children);\n result = result.concat(curr.children);\n }\n }\n return result;\n }\n /**\n * Creates a deep copy of the entity and a copy of all its components\n */\n clone() {\n const newEntity = new Entity();\n for (const c of this.types) {\n const componentInstance = this.get(c);\n if (componentInstance) {\n newEntity.addComponent(componentInstance.clone());\n }\n }\n for (const child of this.children) {\n newEntity.addChild(child.clone());\n }\n return newEntity;\n }\n /**\n * Adds a copy of all the components from another template entity as a \"prefab\"\n * @param templateEntity Entity to use as a template\n * @param force Force component replacement if it already exists on the target entity\n */\n addTemplate(templateEntity, force = false) {\n for (const c of templateEntity.getComponents()) {\n this.addComponent(c.clone(), force);\n }\n for (const child of templateEntity.children) {\n this.addChild(child.clone().addTemplate(child));\n }\n return this;\n }\n /**\n * Adds a component to the entity\n * @param component Component or Entity to add copy of components from\n * @param force Optionally overwrite any existing components of the same type\n */\n addComponent(component, force = false) {\n this._instanceOfComponentCacheDirty = true;\n // if component already exists, skip if not forced\n if (this.has(component.constructor)) {\n if (force) {\n // Remove existing component type if exists when forced\n this.removeComponent(component.constructor, true);\n }\n else {\n // early exit component exits\n return this;\n }\n }\n // TODO circular dependencies will be a problem\n if (component.dependencies && component.dependencies.length) {\n for (const ctor of component.dependencies) {\n this.addComponent(new ctor());\n }\n }\n component.owner = this;\n this.components.set(component.constructor, component);\n if (component.onAdd) {\n component.onAdd(this);\n }\n this.componentAdded$.notifyAll(component);\n return this;\n }\n /**\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\n *\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\n * @param typeOrInstance\n * @param force\n */\n removeComponent(typeOrInstance, force = false) {\n let type;\n if (isComponentCtor(typeOrInstance)) {\n type = typeOrInstance;\n }\n else {\n type = typeOrInstance.constructor;\n }\n if (force) {\n const componentToRemove = this.components.get(type);\n if (componentToRemove) {\n this.componentRemoved$.notifyAll(componentToRemove);\n componentToRemove.owner = undefined;\n if (componentToRemove.onRemove) {\n componentToRemove.onRemove(this);\n }\n }\n this.components.delete(type); // remove after the notify to preserve typing\n this._instanceOfComponentCacheDirty = true;\n }\n else {\n this._componentsToRemove.push(type);\n }\n return this;\n }\n clearComponents() {\n const components = this.types;\n for (const c of components) {\n this.removeComponent(c);\n }\n }\n /**\n * @hidden\n * @internal\n */\n processComponentRemoval() {\n for (const type of this._componentsToRemove) {\n this.removeComponent(type, true);\n }\n this._componentsToRemove.length = 0;\n }\n /**\n * Check if a component type exists\n * @param type\n */\n has(type) {\n return this.components.has(type);\n }\n /**\n * Gets whether the actor is Initialized\n */\n get isInitialized() {\n return this._isInitialized;\n }\n /**\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\n *\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n * @internal\n */\n _initialize(engine) {\n if (!this.isInitialized) {\n this.onInitialize(engine);\n this.events.emit('initialize', new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */\n _preupdate(engine, delta) {\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */\n _postupdate(engine, delta) {\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * `onInitialize` is called before the first update of the entity. This method is meant to be\n * overridden.\n *\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\n */\n onInitialize(engine) {\n // Override me\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before an entity is updated.\n */\n onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after an entity is updated.\n */\n onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n *\n * Entity update lifecycle, called internally\n * @internal\n * @param engine\n * @param delta\n */\n update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n for (const child of this.children) {\n child.update(engine, delta);\n }\n this._postupdate(engine, delta);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n if (handler) {\n this.events.off(eventName, handler);\n }\n else {\n this.events.off(eventName);\n }\n }\n}\nEntity._ID = 0;\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsComponent.ts\n\n\n\n\n\n\n/**\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\n * @param graphic\n */\nfunction hasGraphicsTick(graphic) {\n return !!graphic.tick;\n}\n/**\n * Component to manage drawings, using with the position component\n */\nclass GraphicsComponent extends Component {\n /**\n * Offset to apply to graphics by default\n */\n get offset() {\n return new WatchVector(this._offset, () => {\n this.recalculateBounds();\n });\n }\n set offset(value) {\n this._offset = value;\n this.recalculateBounds();\n }\n /**\n * Anchor to apply to graphics by default\n */\n get anchor() {\n return new WatchVector(this._anchor, () => {\n this.recalculateBounds();\n });\n }\n set anchor(value) {\n this._anchor = value;\n this.recalculateBounds();\n }\n constructor(options) {\n super();\n this._logger = Logger.getInstance();\n this._current = 'default';\n this._graphics = {};\n this._options = {};\n this.material = null;\n /**\n * Sets or gets wether any drawing should be visible in this component\n */\n this.visible = true;\n /**\n * Sets or gets wither all drawings should have an opacity applied\n */\n this.opacity = 1;\n this._offset = Vector.Zero;\n this._anchor = Vector.Half;\n /**\n * Flip all graphics horizontally along the y-axis\n */\n this.flipHorizontal = false;\n /**\n * Flip all graphics vertically along the x-axis\n */\n this.flipVertical = false;\n /**\n * If set to true graphics added to the component will be copied. This can effect performance, but is useful if you don't want\n * changes to a graphic to effect all the places it is used.\n */\n this.copyGraphics = false;\n this._localBounds = null;\n // Defaults\n options = {\n visible: this.visible,\n graphics: {},\n ...options\n };\n const { current, anchor, opacity, visible, graphics, offset, copyGraphics, onPreDraw, onPostDraw, onPreTransformDraw, onPostTransformDraw } = options;\n for (const [key, graphicOrOptions] of Object.entries(graphics)) {\n if (graphicOrOptions instanceof Graphic) {\n this._graphics[key] = graphicOrOptions;\n }\n else {\n this._graphics[key] = graphicOrOptions.graphic;\n this._options[key] = graphicOrOptions.options;\n }\n }\n this.offset = offset !== null && offset !== void 0 ? offset : this.offset;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : this.anchor;\n this.copyGraphics = copyGraphics !== null && copyGraphics !== void 0 ? copyGraphics : this.copyGraphics;\n this.onPreDraw = onPreDraw !== null && onPreDraw !== void 0 ? onPreDraw : this.onPreDraw;\n this.onPostDraw = onPostDraw !== null && onPostDraw !== void 0 ? onPostDraw : this.onPostDraw;\n this.onPreDraw = onPreTransformDraw !== null && onPreTransformDraw !== void 0 ? onPreTransformDraw : this.onPreTransformDraw;\n this.onPostTransformDraw = onPostTransformDraw !== null && onPostTransformDraw !== void 0 ? onPostTransformDraw : this.onPostTransformDraw;\n this.visible = !!visible;\n this._current = current !== null && current !== void 0 ? current : this._current;\n if (current && this._graphics[current]) {\n this.use(current);\n }\n }\n getGraphic(name) {\n return this._graphics[name];\n }\n getOptions(name) {\n return this._options[name];\n }\n /**\n * Get registered graphics names\n */\n getNames() {\n return Object.keys(this._graphics);\n }\n /**\n * Returns the currently displayed graphic\n */\n get current() {\n return this._graphics[this._current];\n }\n /**\n * Returns the currently displayed graphic offsets\n */\n get currentOptions() {\n return this._options[this._current];\n }\n /**\n * Returns all graphics associated with this component\n */\n get graphics() {\n return this._graphics;\n }\n /**\n * Returns all graphics options associated with this component\n */\n get options() {\n return this._options;\n }\n add(nameOrGraphic, graphicOrOptions, options) {\n let name = 'default';\n let graphicToSet = null;\n let optionsToSet = undefined;\n if (typeof nameOrGraphic === 'string' && graphicOrOptions instanceof Graphic) {\n name = nameOrGraphic;\n graphicToSet = graphicOrOptions;\n optionsToSet = options;\n }\n if (nameOrGraphic instanceof Graphic && !(graphicOrOptions instanceof Graphic)) {\n graphicToSet = nameOrGraphic;\n optionsToSet = graphicOrOptions;\n }\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\n this._options[name] = this.copyGraphics ? { ...optionsToSet } : optionsToSet;\n if (name === 'default') {\n this.use('default');\n }\n return graphicToSet;\n }\n /**\n * Removes a registered graphic, if the removed graphic is the current it will switch to the default\n * @param name\n */\n remove(name) {\n delete this._graphics[name];\n delete this._options[name];\n if (this._current === name) {\n this._current = 'default';\n this.recalculateBounds();\n }\n }\n /**\n * Shows a graphic, will be removed\n * @param nameOrGraphic\n * @param options\n * @deprecated will be removed in v0.30.0, use `graphics.use(...)`\n */\n show(nameOrGraphic, options) {\n return this.use(nameOrGraphic, options);\n }\n /**\n * Use a graphic only, will set the default graphic. Returns the new [[Graphic]]\n *\n * Optionally override the stored options\n * @param nameOrGraphic\n * @param options\n */\n use(nameOrGraphic, options) {\n var _a;\n if (nameOrGraphic instanceof Graphic) {\n let graphic = nameOrGraphic;\n if (this.copyGraphics) {\n graphic = nameOrGraphic.clone();\n }\n this._current = 'default';\n this._graphics[this._current] = graphic;\n this._options[this._current] = options;\n }\n else {\n this._current = nameOrGraphic;\n this._options[this._current] = options;\n if (!(this._current in this._graphics)) {\n this._logger.warn(`Graphic ${this._current} is not registered with the graphics component owned by ${(_a = this.owner) === null || _a === void 0 ? void 0 : _a.name}. Nothing will be drawn.`);\n }\n }\n this.recalculateBounds();\n return this.current;\n }\n /**\n * Hide currently shown graphic\n */\n hide() {\n this._current = 'ex.none';\n }\n set localBounds(bounds) {\n this._localBounds = bounds;\n }\n recalculateBounds() {\n let bb = new BoundingBox();\n const graphic = this._graphics[this._current];\n const options = this._options[this._current];\n if (!graphic) {\n this._localBounds = bb;\n return;\n }\n let anchor = this.anchor;\n let offset = this.offset;\n if (options === null || options === void 0 ? void 0 : options.anchor) {\n anchor = options.anchor;\n }\n if (options === null || options === void 0 ? void 0 : options.offset) {\n offset = options.offset;\n }\n const bounds = graphic.localBounds;\n const offsetX = -bounds.width * anchor.x + offset.x;\n const offsetY = -bounds.height * anchor.y + offset.y;\n bb = graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(vec(offsetX, offsetY)).combine(bb);\n this._localBounds = bb;\n }\n get localBounds() {\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) {\n this.recalculateBounds();\n }\n return this._localBounds;\n }\n /**\n * Update underlying graphics if necessary, called internally\n * @param elapsed\n * @internal\n */\n update(elapsed, idempotencyToken = 0) {\n const graphic = this.current;\n if (graphic && hasGraphicsTick(graphic)) {\n graphic.tick(elapsed, idempotencyToken);\n }\n }\n clone() {\n const graphics = new GraphicsComponent();\n graphics._graphics = { ...this._graphics };\n graphics._options = { ...this._options };\n graphics.offset = this.offset.clone();\n graphics.opacity = this.opacity;\n graphics.anchor = this.anchor.clone();\n graphics.copyGraphics = this.copyGraphics;\n graphics.onPreDraw = this.onPreDraw;\n graphics.onPostDraw = this.onPostDraw;\n graphics.visible = this.visible;\n return graphics;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Rectangle.ts\n\n/**\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\n */\nclass Rectangle extends Raster {\n constructor(options) {\n super(options);\n this.width = options.width;\n this.height = options.height;\n this.rasterize();\n }\n clone() {\n return new Rectangle({\n width: this.width,\n height: this.height,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.color) {\n ctx.fillRect(0, 0, this.width, this.height);\n }\n if (this.strokeColor) {\n ctx.strokeRect(0, 0, this.width, this.height);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Circle.ts\n\n\n/**\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\n *\n * Circles default to [[ImageFiltering.Blended]]\n */\nclass Circle extends Raster {\n get radius() {\n return this._radius;\n }\n set radius(value) {\n this._radius = value;\n this.width = this._radius * 2;\n this.height = this._radius * 2;\n this.flagDirty();\n }\n constructor(options) {\n var _a, _b, _c;\n super(options);\n this._radius = 0;\n const lineWidth = (_a = options.lineWidth) !== null && _a !== void 0 ? _a : (options.strokeColor ? 1 : 0); // default lineWidth in canvas is 1px\n this.padding = (_b = options.padding) !== null && _b !== void 0 ? _b : 2 + (lineWidth / 2); // default 2 padding for circles looks nice\n this.radius = options.radius;\n this.filtering = (_c = options.filtering) !== null && _c !== void 0 ? _c : ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Circle({\n radius: this.radius,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.radius > 0) {\n ctx.beginPath();\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\n if (this.color) {\n ctx.fill();\n }\n if (this.strokeColor) {\n ctx.stroke();\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerComponent.ts\n\n/**\n * Add this component to optionally configure how the pointer\n * system detects pointer events.\n *\n * By default the collider shape is used and graphics bounds is not.\n *\n * If both collider shape and graphics bounds are enabled it will fire events if either or\n * are intersecting the pointer.\n */\nclass PointerComponent extends Component {\n constructor() {\n super(...arguments);\n /**\n * Use any existing Collider component geometry for pointer events. This is useful if you want\n * user pointer events only to trigger on the same collision geometry used in the collider component\n * for collision resolution. Default is `true`.\n */\n this.useColliderShape = true;\n /**\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\n * bounds around the graphic to trigger pointer events. Default is `true`.\n */\n this.useGraphicsBounds = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/EasingFunctions.ts\n\n/**\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\n * Given a time, the function will return a value from positive startValue to positive endValue.\n *\n * ```js\n * function Linear (t) {\n * return t * t;\n * }\n *\n * // accelerating from zero velocity\n * function EaseInQuad (t) {\n * return t * t;\n * }\n *\n * // decelerating to zero velocity\n * function EaseOutQuad (t) {\n * return t * (2 - t);\n * }\n *\n * // acceleration until halfway, then deceleration\n * function EaseInOutQuad (t) {\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n * }\n *\n * // accelerating from zero velocity\n * function EaseInCubic (t) {\n * return t * t * t;\n * }\n *\n * // decelerating to zero velocity\n * function EaseOutCubic (t) {\n * return (--t) * t * t + 1;\n * }\n *\n * // acceleration until halfway, then deceleration\n * function EaseInOutCubic (t) {\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n * }\n * ```\n */\nclass EasingFunctions {\n static CreateReversibleEasingFunction(easing) {\n return (time, start, end, duration) => {\n if (end < start) {\n return start - (easing(time, end, start, duration) - end);\n }\n else {\n return easing(time, start, end, duration);\n }\n };\n }\n static CreateVectorEasingFunction(easing) {\n return (time, start, end, duration) => {\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\n };\n }\n}\nEasingFunctions.Linear = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n return (endValue * currentTime) / duration + startValue;\n});\nEasingFunctions.EaseInQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime + startValue;\n});\nEasingFunctions.EaseOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration;\n return -endValue * currentTime * (currentTime - 2) + startValue;\n});\nEasingFunctions.EaseInOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) {\n return (endValue / 2) * currentTime * currentTime + startValue;\n }\n currentTime--;\n return (-endValue / 2) * (currentTime * (currentTime - 2) - 1) + startValue;\n});\nEasingFunctions.EaseInCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime * currentTime + startValue;\n});\nEasingFunctions.EaseOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration;\n currentTime--;\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\n});\nEasingFunctions.EaseInOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) {\n return (endValue / 2) * currentTime * currentTime * currentTime + startValue;\n }\n currentTime -= 2;\n return (endValue / 2) * (currentTime * currentTime * currentTime + 2) + startValue;\n});\n\n;// CONCATENATED MODULE: ./Actions/ActionQueue.ts\n\n/**\n * Action Queues represent an ordered sequence of actions\n *\n * Action queues are part of the [[ActionContext|Action API]] and\n * store the list of actions to be executed for an [[Actor]].\n *\n * Actors implement [[Actor.actions]] which can be manipulated by\n * advanced users to adjust the actions currently being executed in the\n * queue.\n */\nclass ActionQueue {\n constructor(entity) {\n this._actions = [];\n this._currentAction = null;\n this._completedActions = [];\n this._entity = entity;\n }\n /**\n * Add an action to the sequence\n * @param action\n */\n add(action) {\n this._actions.push(action);\n }\n /**\n * Remove an action by reference from the sequence\n * @param action\n */\n remove(action) {\n const index = this._actions.indexOf(action);\n this._actions.splice(index, 1);\n }\n /**\n * Removes all actions from this sequence\n */\n clearActions() {\n this._actions.length = 0;\n this._completedActions.length = 0;\n if (this._currentAction) {\n this._currentAction.stop();\n }\n }\n /**\n *\n * @returns The total list of actions in this sequence complete or not\n */\n getActions() {\n return this._actions.concat(this._completedActions);\n }\n /**\n *\n * @returns `true` if there are more actions to process in the sequence\n */\n hasNext() {\n return this._actions.length > 0;\n }\n /**\n * @returns `true` if the current sequence of actions is done\n */\n isComplete() {\n return this._actions.length === 0;\n }\n /**\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\n */\n reset() {\n this._actions = this.getActions();\n const len = this._actions.length;\n for (let i = 0; i < len; i++) {\n this._actions[i].reset();\n }\n this._completedActions = [];\n }\n /**\n * Update the queue which updates actions and handles completing actions\n * @param elapsedMs\n */\n update(elapsedMs) {\n if (this._actions.length > 0) {\n if (this._currentAction !== this._actions[0]) {\n this._currentAction = this._actions[0];\n this._entity.emit('actionstart', new ActionStartEvent(this._currentAction, this._entity));\n }\n this._currentAction.update(elapsedMs);\n if (this._currentAction.isComplete(this._entity)) {\n this._entity.emit('actioncomplete', new ActionCompleteEvent(this._currentAction, this._entity));\n const complete = this._actions.shift();\n if (complete) {\n this._completedActions.push(complete);\n }\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Repeat.ts\n\nclass Repeat {\n constructor(entity, repeatBuilder, repeat) {\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeat = repeat;\n this._originalRepeat = repeat;\n this._repeatBuilder(this._repeatContext);\n this._repeat--; // current execution is the first repeat\n }\n update(delta) {\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n this._repeat--;\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || (this._repeat <= 0 && this._actionQueue.isComplete());\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._repeat = this._originalRepeat;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/RepeatForever.ts\n\n/**\n * RepeatForever Action implementation, it is recommended you use the fluent action\n * context API.\n *\n *\n */\nclass RepeatForever {\n constructor(entity, repeatBuilder) {\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeatBuilder(this._repeatContext);\n }\n update(delta) {\n if (this._stopped) {\n return;\n }\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n this._stopped = true;\n this._actionQueue.clearActions();\n }\n reset() {\n return;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/MoveBy.ts\n\n\n\n\nclass MoveBy {\n constructor(entity, offsetX, offsetY, speed) {\n this._started = false;\n this._stopped = false;\n this._entity = entity;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = new Vector(offsetX, offsetY);\n if (speed <= 0) {\n Logger.getInstance().error('Attempted to moveBy with speed less than or equal to zero : ' + speed);\n throw new Error('Speed must be greater than 0 pixels per second');\n }\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = this._start.add(this._offset);\n this._distance = this._offset.size;\n this._dir = this._end.sub(this._start).normalize();\n }\n if (this.isComplete(this._entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n else {\n this._motion.vel = this._dir.scale(this._speed);\n }\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/MoveTo.ts\n\n\n\nclass MoveTo {\n constructor(entity, destx, desty, speed) {\n this.entity = entity;\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = new Vector(destx, desty);\n this._speed = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._distance = this._start.distance(this._end);\n this._dir = this._end.sub(this._start).normalize();\n }\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete(this.entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/RotationType.ts\n/**\n * An enum that describes the strategies that rotation actions can use\n */\nvar RotationType;\n(function (RotationType) {\n /**\n * Rotation via `ShortestPath` will use the smallest angle\n * between the starting and ending points. This strategy is the default behavior.\n */\n RotationType[RotationType[\"ShortestPath\"] = 0] = \"ShortestPath\";\n /**\n * Rotation via `LongestPath` will use the largest angle\n * between the starting and ending points.\n */\n RotationType[RotationType[\"LongestPath\"] = 1] = \"LongestPath\";\n /**\n * Rotation via `Clockwise` will travel in a clockwise direction,\n * regardless of the starting and ending points.\n */\n RotationType[RotationType[\"Clockwise\"] = 2] = \"Clockwise\";\n /**\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\n * regardless of the starting and ending points.\n */\n RotationType[RotationType[\"CounterClockwise\"] = 3] = \"CounterClockwise\";\n})(RotationType || (RotationType = {}));\n\n;// CONCATENATED MODULE: ./Actions/Action/RotateTo.ts\n\n\n\n\nclass RotateTo {\n constructor(entity, angleRadians, speed, rotationType) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = angleRadians;\n this._speed = speed;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n }\n else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch (this._rotationType) {\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) {\n this._direction = 1;\n }\n else {\n this._direction = -1;\n }\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) {\n this._direction = -1;\n }\n else {\n this._direction = 1;\n }\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortestPathIsPositive) {\n this._distance = this._shortDistance;\n }\n else {\n this._distance = this._longDistance;\n }\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (!this._shortestPathIsPositive) {\n this._distance = this._shortDistance;\n }\n else {\n this._distance = this._longDistance;\n }\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/RotateBy.ts\n\n\n\n\nclass RotateBy {\n constructor(entity, angleRadiansOffset, speed, rotationType) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = angleRadiansOffset;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n this._end = this._start + this._offset;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n }\n else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch (this._rotationType) {\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) {\n this._direction = 1;\n }\n else {\n this._direction = -1;\n }\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) {\n this._direction = -1;\n }\n else {\n this._direction = 1;\n }\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortDistance >= 0) {\n this._distance = this._shortDistance;\n }\n else {\n this._distance = this._longDistance;\n }\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (this._shortDistance <= 0) {\n this._distance = this._shortDistance;\n }\n else {\n this._distance = this._longDistance;\n }\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._start = undefined;\n this._currentNonCannonAngle = undefined;\n this._distance = undefined;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/ScaleTo.ts\n\n\n\nclass ScaleTo {\n constructor(entity, scaleX, scaleY, speedX, speedY) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._endX = scaleX;\n this._endY = scaleY;\n this._speedX = speedX;\n this._speedY = speedY;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startX = this._tx.scale.x;\n this._startY = this._tx.scale.y;\n this._distanceX = Math.abs(this._endX - this._startX);\n this._distanceY = Math.abs(this._endY - this._startY);\n }\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\n const directionX = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.x = this._speedX * directionX;\n }\n else {\n this._motion.scaleFactor.x = 0;\n }\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\n const directionY = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.y = this._speedY * directionY;\n }\n else {\n this._motion.scaleFactor.y = 0;\n }\n if (this.isComplete()) {\n this._tx.scale = vec(this._endX, this._endY);\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return (this._stopped ||\n (Math.abs(this._tx.scale.x - this._startX) >= (this._distanceX - 0.01) &&\n Math.abs(this._tx.scale.y - this._startY) >= (this._distanceY - 0.01)));\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/ScaleBy.ts\n\n\n\nclass ScaleBy {\n constructor(entity, scaleOffsetX, scaleOffsetY, speed) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\n this._speedX = this._speedY = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startScale = this._tx.scale.clone();\n this._endScale = this._startScale.add(this._offset);\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\n }\n this._motion.scaleFactor.x = this._speedX * this._directionX;\n this._motion.scaleFactor.y = this._speedY * this._directionY;\n if (this.isComplete()) {\n this._tx.scale = this._endScale;\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return (this._stopped ||\n (Math.abs(this._tx.scale.x - this._startScale.x) >= (this._distanceX - 0.01) &&\n Math.abs(this._tx.scale.y - this._startScale.y) >= (this._distanceY - 0.01)));\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/CallMethod.ts\nclass CallMethod {\n constructor(method) {\n this._method = null;\n this._hasBeenCalled = false;\n this._method = method;\n }\n update(_delta) {\n this._method();\n this._hasBeenCalled = true;\n }\n isComplete() {\n return this._hasBeenCalled;\n }\n reset() {\n this._hasBeenCalled = false;\n }\n stop() {\n this._hasBeenCalled = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/EaseTo.ts\n\n\n\nclass EaseTo {\n constructor(entity, x, y, duration, easingFcn) {\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1 * 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._lerpEnd = new Vector(x, y);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) {\n newX =\n this._lerpStart.x -\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n }\n else {\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n }\n if (this._lerpEnd.y < this._lerpStart.y) {\n newY =\n this._lerpStart.y -\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n }\n else {\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n }\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n }\n else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/EaseBy.ts\n\n\n\nclass EaseBy {\n constructor(entity, offsetX, offsetY, duration, easingFcn) {\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1 * 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._offset = new Vector(offsetX, offsetY);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n this._lerpEnd = this._lerpStart.add(this._offset);\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) {\n newX =\n this._lerpStart.x -\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n }\n else {\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n }\n if (this._lerpEnd.y < this._lerpStart.y) {\n newY =\n this._lerpStart.y -\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n }\n else {\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n }\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n }\n else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Blink.ts\n\nclass Blink {\n constructor(entity, timeVisible, timeNotVisible, numBlinks = 1) {\n this._timeVisible = 0;\n this._timeNotVisible = 0;\n this._elapsedTime = 0;\n this._totalTime = 0;\n this._stopped = false;\n this._started = false;\n this._graphics = entity.get(GraphicsComponent);\n this._timeVisible = timeVisible;\n this._timeNotVisible = timeNotVisible;\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\n }\n update(delta) {\n if (!this._started) {\n this._started = true;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n if (!this._graphics) {\n return;\n }\n this._elapsedTime += delta;\n this._totalTime += delta;\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\n this._graphics.visible = false;\n this._elapsedTime = 0;\n }\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\n this._graphics.visible = true;\n this._elapsedTime = 0;\n }\n if (this.isComplete()) {\n this._graphics.visible = true;\n }\n }\n isComplete() {\n return this._stopped || this._totalTime >= this._duration;\n }\n stop() {\n if (this._graphics) {\n this._graphics.visible = true;\n }\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Fade.ts\n\n\nclass Fade {\n constructor(entity, endOpacity, speed) {\n this._multiplier = 1;\n this._started = false;\n this._stopped = false;\n this._graphics = entity.get(GraphicsComponent);\n this._endOpacity = endOpacity;\n this._speed = this._ogspeed = speed;\n }\n update(delta) {\n if (!this._graphics) {\n return;\n }\n if (!this._started) {\n this._started = true;\n this._speed = this._ogspeed;\n // determine direction when we start\n if (this._endOpacity < this._graphics.opacity) {\n this._multiplier = -1;\n }\n else {\n this._multiplier = 1;\n }\n }\n if (this._speed > 0) {\n this._graphics.opacity += (this._multiplier *\n (Math.abs(this._graphics.opacity - this._endOpacity) * delta)) / this._speed;\n }\n this._speed -= delta;\n if (this.isComplete()) {\n this._graphics.opacity = this._endOpacity;\n }\n Logger.getInstance().debug('[Action fade] Actor opacity:', this._graphics.opacity);\n }\n isComplete() {\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Delay.ts\nclass Delay {\n constructor(delay) {\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n this._delay = delay;\n }\n update(delta) {\n if (!this._started) {\n this._started = true;\n }\n this._elapsedTime += delta;\n }\n isComplete() {\n return this._stopped || this._elapsedTime >= this._delay;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Die.ts\n\nclass Die {\n constructor(entity) {\n this._stopped = false;\n this._entity = entity;\n }\n update(_delta) {\n this._entity.get(ActionsComponent).clearActions();\n this._entity.kill();\n this._stopped = true;\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n return;\n }\n reset() {\n return;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Follow.ts\n\n\n\nclass Follow {\n constructor(entity, entityToFollow, followDistance) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._followTx = entityToFollow.get(TransformComponent);\n this._followMotion = entityToFollow.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\n this._speed = 0;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\n if (actorToFollowSpeed !== 0) {\n this._speed = actorToFollowSpeed;\n }\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n if (this._distanceBetween >= this._maximumDistance) {\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n }\n else {\n this._motion.vel = vec(0, 0);\n }\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n isComplete() {\n // the actor following should never stop unless specified to do so\n return this._stopped;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Meet.ts\n\n\n\nclass Meet {\n constructor(actor, actorToMeet, speed) {\n this._started = false;\n this._stopped = false;\n this._speedWasSpecified = false;\n this._tx = actor.get(TransformComponent);\n this._motion = actor.get(MotionComponent);\n this._meetTx = actorToMeet.get(TransformComponent);\n this._meetMotion = actorToMeet.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\n this._speed = speed || 0;\n if (speed !== undefined) {\n this._speedWasSpecified = true;\n }\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) {\n this._speed = actorToMeetSpeed;\n }\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete() {\n return this._stopped || this._distanceBetween <= 1;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._distanceBetween = undefined;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/ActionContext.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * The fluent Action API allows you to perform \"actions\" on\n * [[Actor|Actors]] such as following, moving, rotating, and\n * more. You can implement your own actions by implementing\n * the [[Action]] interface.\n */\nclass ActionContext {\n constructor(entity) {\n this._entity = entity;\n this._queue = new ActionQueue(entity);\n }\n getQueue() {\n return this._queue;\n }\n update(elapsedMs) {\n this._queue.update(elapsedMs);\n }\n /**\n * Clears all queued actions from the Actor\n */\n clearActions() {\n this._queue.clearActions();\n }\n runAction(action) {\n action.reset();\n this._queue.add(action);\n return this;\n }\n easeTo(...args) {\n var _a, _b;\n let x = 0;\n let y = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n x = args[0].x;\n y = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n }\n else {\n x = args[0];\n y = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\n return this;\n }\n easeBy(...args) {\n var _a, _b;\n let offsetX = 0;\n let offsetY = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n offsetX = args[0].x;\n offsetY = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n }\n else {\n offsetX = args[0];\n offsetY = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\n return this;\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n let x = 0;\n let y = 0;\n let speed = 0;\n if (xOrPos instanceof Vector) {\n x = xOrPos.x;\n y = xOrPos.y;\n speed = yOrSpeed;\n }\n else {\n x = xOrPos;\n y = yOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveTo(this._entity, x, y, speed));\n return this;\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n let xOffset = 0;\n let yOffset = 0;\n let speed = 0;\n if (xOffsetOrVector instanceof Vector) {\n xOffset = xOffsetOrVector.x;\n yOffset = xOffsetOrVector.y;\n speed = yOffsetOrSpeed;\n }\n else {\n xOffset = xOffsetOrVector;\n yOffset = yOffsetOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\n return this;\n }\n /**\n * This method will rotate an actor to the specified angle at the speed\n * specified (in radians per second) and return back the actor. This\n * method is part of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadians The angle to rotate to in radians\n * @param speed The angular velocity of the rotation specified in radians per second\n * @param rotationType The [[RotationType]] to use for this rotation\n */\n rotateTo(angleRadians, speed, rotationType) {\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\n return this;\n }\n /**\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\n * in radians/sec and return back the actor. This method is part\n * of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\n * @param speed The speed in radians/sec the actor should rotate at\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\n */\n rotateBy(angleRadiansOffset, speed, rotationType) {\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\n return this;\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n let sizeX = 1;\n let sizeY = 1;\n let speedX = 0;\n let speedY = 0;\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\n sizeX = sizeXOrVector.x;\n sizeY = sizeXOrVector.y;\n speedX = sizeYOrSpeed.x;\n speedY = sizeYOrSpeed.y;\n }\n if (typeof sizeXOrVector === 'number' && typeof sizeYOrSpeed === 'number') {\n sizeX = sizeXOrVector;\n sizeY = sizeYOrSpeed;\n speedX = speedXOrUndefined;\n speedY = speedYOrUndefined;\n }\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\n return this;\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n let sizeOffsetX = 1;\n let sizeOffsetY = 1;\n if (sizeOffsetXOrVector instanceof Vector) {\n sizeOffsetX = sizeOffsetXOrVector.x;\n sizeOffsetY = sizeOffsetXOrVector.y;\n speed = sizeOffsetYOrSpeed;\n }\n if (typeof sizeOffsetXOrVector === 'number' && typeof sizeOffsetYOrSpeed === 'number') {\n sizeOffsetX = sizeOffsetXOrVector;\n sizeOffsetY = sizeOffsetYOrSpeed;\n }\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\n return this;\n }\n /**\n * This method will cause an actor to blink (become visible and not\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\n * the actor should be visible per blink, and the amount of time not visible.\n * This method is part of the actor 'Action' fluent API allowing action chaining.\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\n * @param numBlinks The number of times to blink\n */\n blink(timeVisible, timeNotVisible, numBlinks = 1) {\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\n return this;\n }\n /**\n * This method will cause an actor's opacity to change from its current value\n * to the provided value by a specified time (in milliseconds). This method is\n * part of the actor 'Action' fluent API allowing action chaining.\n * @param opacity The ending opacity\n * @param time The time it should take to fade the actor (in milliseconds)\n */\n fade(opacity, time) {\n this._queue.add(new Fade(this._entity, opacity, time));\n return this;\n }\n /**\n * This method will delay the next action from executing for a certain\n * amount of time (in milliseconds). This method is part of the actor\n * 'Action' fluent API allowing action chaining.\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\n */\n delay(time) {\n this._queue.add(new Delay(time));\n return this;\n }\n /**\n * This method will add an action to the queue that will remove the actor from the\n * scene once it has completed its previous Any actions on the\n * action queue after this action will not be executed.\n */\n die() {\n this._queue.add(new Die(this._entity));\n return this;\n }\n /**\n * This method allows you to call an arbitrary method as the next action in the\n * action queue. This is useful if you want to execute code in after a specific\n * action, i.e An actor arrives at a destination after traversing a path\n */\n callMethod(method) {\n this._queue.add(new CallMethod(method));\n return this;\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\n * will repeat forever\n */\n repeat(repeatBuilder, times) {\n if (!times) {\n this.repeatForever(repeatBuilder);\n return this;\n }\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\n return this;\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n */\n repeatForever(repeatBuilder) {\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\n return this;\n }\n /**\n * This method will cause the entity to follow another at a specified distance\n * @param entity The entity to follow\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\n */\n follow(entity, followDistance) {\n if (followDistance === undefined) {\n this._queue.add(new Follow(this._entity, entity));\n }\n else {\n this._queue.add(new Follow(this._entity, entity, followDistance));\n }\n return this;\n }\n /**\n * This method will cause the entity to move towards another until they\n * collide \"meet\" at a specified speed.\n * @param entity The entity to meet\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\n */\n meet(entity, speed) {\n if (speed === undefined) {\n this._queue.add(new Meet(this._entity, entity));\n }\n else {\n this._queue.add(new Meet(this._entity, entity, speed));\n }\n return this;\n }\n /**\n * Returns a promise that resolves when the current action queue up to now\n * is finished.\n */\n toPromise() {\n const temp = new Promise((resolve) => {\n this._queue.add(new CallMethod(() => {\n resolve();\n }));\n });\n return temp;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/ActionsComponent.ts\n\n\n\n\n;\nclass ActionsComponent extends Component {\n constructor() {\n super(...arguments);\n this.dependencies = [TransformComponent, MotionComponent];\n this._ctx = null;\n }\n onAdd(entity) {\n this._ctx = new ActionContext(entity);\n }\n onRemove() {\n this._ctx = null;\n }\n _getCtx() {\n if (!this._ctx) {\n throw new Error('Actions component not attached to an entity, no context available');\n }\n return this._ctx;\n }\n /**\n * Returns the internal action queue\n * @returns action queue\n */\n getQueue() {\n if (!this._ctx) {\n throw new Error('Actions component not attached to an entity, no queue available');\n }\n return this._ctx.getQueue();\n }\n runAction(action) {\n if (!this._ctx) {\n throw new Error('Actions component not attached to an entity, cannot run action');\n }\n return this._ctx.runAction(action);\n }\n /**\n * Updates the internal action context, performing action and moving through the internal queue\n * @param elapsedMs\n */\n update(elapsedMs) {\n var _a;\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.update(elapsedMs);\n }\n /**\n * Clears all queued actions from the Actor\n */\n clearActions() {\n var _a;\n (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.clearActions();\n }\n easeTo(...args) {\n return this._getCtx().easeTo.apply(this._ctx, args);\n }\n easeBy(...args) {\n return this._getCtx().easeBy.apply(this._ctx, args);\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n return this._getCtx().moveTo.apply(this._ctx, [xOrPos, yOrSpeed, speedOrUndefined]);\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n return this._getCtx().moveBy.apply(this._ctx, [xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined]);\n }\n /**\n * This method will rotate an actor to the specified angle at the speed\n * specified (in radians per second) and return back the actor. This\n * method is part of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadians The angle to rotate to in radians\n * @param speed The angular velocity of the rotation specified in radians per second\n * @param rotationType The [[RotationType]] to use for this rotation\n */\n rotateTo(angleRadians, speed, rotationType) {\n return this._getCtx().rotateTo(angleRadians, speed, rotationType);\n }\n /**\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\n * in radians/sec and return back the actor. This method is part\n * of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\n * @param speed The speed in radians/sec the actor should rotate at\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\n */\n rotateBy(angleRadiansOffset, speed, rotationType) {\n return this._getCtx().rotateBy(angleRadiansOffset, speed, rotationType);\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n return this._getCtx().scaleTo.apply(this._ctx, [sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined]);\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n return this._getCtx().scaleBy.apply(this._ctx, [sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed]);\n }\n /**\n * This method will cause an actor to blink (become visible and not\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\n * the actor should be visible per blink, and the amount of time not visible.\n * This method is part of the actor 'Action' fluent API allowing action chaining.\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\n * @param numBlinks The number of times to blink\n */\n blink(timeVisible, timeNotVisible, numBlinks) {\n return this._getCtx().blink(timeVisible, timeNotVisible, numBlinks);\n }\n /**\n * This method will cause an actor's opacity to change from its current value\n * to the provided value by a specified time (in milliseconds). This method is\n * part of the actor 'Action' fluent API allowing action chaining.\n * @param opacity The ending opacity\n * @param time The time it should take to fade the actor (in milliseconds)\n */\n fade(opacity, time) {\n return this._getCtx().fade(opacity, time);\n }\n /**\n * This method will delay the next action from executing for a certain\n * amount of time (in milliseconds). This method is part of the actor\n * 'Action' fluent API allowing action chaining.\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\n */\n delay(time) {\n return this._getCtx().delay(time);\n }\n /**\n * This method will add an action to the queue that will remove the actor from the\n * scene once it has completed its previous Any actions on the\n * action queue after this action will not be executed.\n */\n die() {\n return this._getCtx().die();\n }\n /**\n * This method allows you to call an arbitrary method as the next action in the\n * action queue. This is useful if you want to execute code in after a specific\n * action, i.e An actor arrives at a destination after traversing a path\n */\n callMethod(method) {\n return this._getCtx().callMethod(method);\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\n * will repeat forever\n */\n repeat(repeatBuilder, times) {\n return this._getCtx().repeat(repeatBuilder, times);\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n */\n repeatForever(repeatBuilder) {\n return this._getCtx().repeatForever(repeatBuilder);\n }\n /**\n * This method will cause the entity to follow another at a specified distance\n * @param entity The entity to follow\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\n */\n follow(entity, followDistance) {\n return this._getCtx().follow(entity, followDistance);\n }\n /**\n * This method will cause the entity to move towards another until they\n * collide \"meet\" at a specified speed.\n * @param entity The entity to meet\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\n */\n meet(entity, speed) {\n return this._getCtx().meet(entity, speed);\n }\n /**\n * Returns a promise that resolves when the current action queue up to now\n * is finished.\n */\n toPromise() {\n return this._getCtx().toPromise();\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/FontCommon.ts\n/**\n * Enum representing the different font size units\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\n */\nvar FontUnit;\n(function (FontUnit) {\n /**\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\n */\n FontUnit[\"Em\"] = \"em\";\n /**\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\n */\n FontUnit[\"Rem\"] = \"rem\";\n /**\n * Pixel is a unit of length in screen pixels\n */\n FontUnit[\"Px\"] = \"px\";\n /**\n * Point is a physical unit length (1/72 of an inch)\n */\n FontUnit[\"Pt\"] = \"pt\";\n /**\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\n */\n FontUnit[\"Percent\"] = \"%\";\n})(FontUnit || (FontUnit = {}));\n/**\n * Enum representing the different horizontal text alignments\n */\nvar TextAlign;\n(function (TextAlign) {\n /**\n * The text is left-aligned.\n */\n TextAlign[\"Left\"] = \"left\";\n /**\n * The text is right-aligned.\n */\n TextAlign[\"Right\"] = \"right\";\n /**\n * The text is centered.\n */\n TextAlign[\"Center\"] = \"center\";\n /**\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\n * right-aligned for right-to-left locales).\n */\n TextAlign[\"Start\"] = \"start\";\n /**\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\n * left-aligned for right-to-left locales).\n */\n TextAlign[\"End\"] = \"end\";\n})(TextAlign || (TextAlign = {}));\n/**\n * Enum representing the different baseline text alignments\n */\nvar BaseAlign;\n(function (BaseAlign) {\n /**\n * The text baseline is the top of the em square.\n */\n BaseAlign[\"Top\"] = \"top\";\n /**\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\n * alphabetic.\n */\n BaseAlign[\"Hanging\"] = \"hanging\";\n /**\n * The text baseline is the middle of the em square.\n */\n BaseAlign[\"Middle\"] = \"middle\";\n /**\n * The text baseline is the normal alphabetic baseline.\n */\n BaseAlign[\"Alphabetic\"] = \"alphabetic\";\n /**\n * The text baseline is the ideographic baseline; this is the bottom of\n * the body of the characters, if the main body of characters protrudes\n * beneath the alphabetic baseline. Currently unsupported; this will\n * act like alphabetic.\n */\n BaseAlign[\"Ideographic\"] = \"ideographic\";\n /**\n * The text baseline is the bottom of the bounding box. This differs\n * from the ideographic baseline in that the ideographic baseline\n * doesn't consider descenders.\n */\n BaseAlign[\"Bottom\"] = \"bottom\";\n})(BaseAlign || (BaseAlign = {}));\n/**\n * Enum representing the different possible font styles\n */\nvar FontStyle;\n(function (FontStyle) {\n FontStyle[\"Normal\"] = \"normal\";\n FontStyle[\"Italic\"] = \"italic\";\n FontStyle[\"Oblique\"] = \"oblique\";\n})(FontStyle || (FontStyle = {}));\n/**\n * Enum representing the text direction, useful for other languages, or writing text in reverse\n */\nvar Direction;\n(function (Direction) {\n Direction[\"LeftToRight\"] = \"ltr\";\n Direction[\"RightToLeft\"] = \"rtl\";\n})(Direction || (Direction = {}));\n\n;// CONCATENATED MODULE: ./Graphics/FontTextInstance.ts\n\n\n\n\nclass FontTextInstance {\n constructor(font, text, color, maxWidth) {\n this.font = font;\n this.text = text;\n this.color = color;\n this.maxWidth = maxWidth;\n this._textFragments = [];\n this.disposed = false;\n this._dirty = true;\n this.canvas = document.createElement('canvas');\n this.ctx = this.canvas.getContext('2d');\n this.dimensions = this.measureText(text);\n this._setDimension(this.dimensions, this.ctx);\n this._lastHashCode = this.getHashCode();\n }\n measureText(text, maxWidth) {\n if (this.disposed) {\n throw Error('Accessing disposed text instance! ' + this.text);\n }\n let lines = null;\n if (maxWidth != null) {\n lines = this._getLinesFromText(text, maxWidth);\n }\n else {\n lines = text.split('\\n');\n }\n const maxWidthLine = lines.reduce((a, b) => {\n return a.length > b.length ? a : b;\n });\n this._applyFont(this.ctx); // font must be applied to the context to measure it\n const metrics = this.ctx.measureText(maxWidthLine);\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\n // TODO lineheight makes the text bounds wonky\n const lineAdjustedHeight = textHeight * lines.length;\n textHeight = lineAdjustedHeight;\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\n const x = 0;\n const y = 0;\n const measurement = new BoundingBox({\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\n bottom: y + bottomBounds + this.font.padding,\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\n });\n return measurement;\n }\n _setDimension(textBounds, bitmap) {\n let lineHeightRatio = 1;\n if (this.font.lineHeight) {\n lineHeightRatio = (this.font.lineHeight / this.font.size);\n }\n // Changing the width and height clears the context properties\n // We double the bitmap width to account for all possible alignment\n // We scale by \"quality\" so we render text without jaggies\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality * lineHeightRatio;\n }\n static getHashCode(font, text, color) {\n var _a;\n const hash = text +\n '__hashcode__' +\n font.fontString +\n font.showDebug +\n font.textAlign +\n font.baseAlign +\n font.direction +\n font.lineHeight +\n JSON.stringify(font.shadow) +\n (font.padding.toString() +\n font.smoothing.toString() +\n font.lineWidth.toString() +\n font.lineDash.toString() +\n ((_a = font.strokeColor) === null || _a === void 0 ? void 0 : _a.toString()) +\n (color ? color.toString() : font.color.toString()));\n return hash;\n }\n getHashCode(includeColor = true) {\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\n }\n _applyRasterProperties(ctx) {\n var _a, _b;\n ctx.translate(this.font.padding, this.font.padding);\n ctx.imageSmoothingEnabled = this.font.smoothing;\n ctx.lineWidth = this.font.lineWidth;\n ctx.setLineDash((_a = this.font.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.strokeStyle = (_b = this.font.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = this.color.toString();\n }\n _applyFont(ctx) {\n ctx.resetTransform();\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\n ctx.scale(this.font.quality, this.font.quality);\n ctx.textAlign = this.font.textAlign;\n ctx.textBaseline = this.font.baseAlign;\n ctx.font = this.font.fontString;\n ctx.direction = this.font.direction;\n if (this.font.shadow) {\n ctx.shadowColor = this.font.shadow.color.toString();\n ctx.shadowBlur = this.font.shadow.blur;\n ctx.shadowOffsetX = this.font.shadow.offset.x;\n ctx.shadowOffsetY = this.font.shadow.offset.y;\n }\n }\n _drawText(ctx, lines, lineHeight) {\n this._applyRasterProperties(ctx);\n this._applyFont(ctx);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (this.color) {\n ctx.fillText(line, 0, i * lineHeight);\n }\n if (this.font.strokeColor) {\n ctx.strokeText(line, 0, i * lineHeight);\n }\n }\n if (this.font.showDebug) {\n // Horizontal line\n /* istanbul ignore next */\n line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\n // Vertical line\n /* istanbul ignore next */\n line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\n }\n }\n _splitTextBitmap(bitmap) {\n const textImages = [];\n let currentX = 0;\n let currentY = 0;\n // 4k is the max for mobile devices\n const width = Math.min(4096, bitmap.canvas.width);\n const height = Math.min(4096, bitmap.canvas.height);\n // Splits the original bitmap into 4k max chunks\n while (currentX < bitmap.canvas.width) {\n while (currentY < bitmap.canvas.height) {\n // create new bitmap\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n // draw current slice to new bitmap in < 4k chunks\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\n textImages.push({ x: currentX, y: currentY, canvas });\n currentY += height;\n }\n currentX += width;\n currentY = 0;\n }\n return textImages;\n }\n flagDirty() {\n this._dirty = true;\n }\n render(ex, x, y, maxWidth) {\n var _a;\n if (this.disposed) {\n throw Error('Accessing disposed text instance! ' + this.text);\n }\n this._ex = ex;\n const hashCode = this.getHashCode();\n if (this._lastHashCode !== hashCode) {\n this._dirty = true;\n }\n // Calculate image chunks\n if (this._dirty) {\n this.dimensions = this.measureText(this.text, maxWidth);\n this._setDimension(this.dimensions, this.ctx);\n const lines = this._getLinesFromText(this.text, maxWidth);\n const lineHeight = (_a = this.font.lineHeight) !== null && _a !== void 0 ? _a : this.dimensions.height / lines.length;\n // draws the text to the main bitmap\n this._drawText(this.ctx, lines, lineHeight);\n // clear any out old fragments\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\n for (const frag of this._textFragments) {\n ex.textureLoader.delete(frag.canvas);\n }\n }\n // splits to < 4k fragments for large text\n this._textFragments = this._splitTextBitmap(this.ctx);\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\n for (const frag of this._textFragments) {\n ex.textureLoader.load(frag.canvas, this.font.filtering, true);\n }\n }\n this._lastHashCode = hashCode;\n this._dirty = false;\n }\n // draws the bitmap fragments to excalibur graphics context\n for (const frag of this._textFragments) {\n ex.drawImage(frag.canvas, 0, 0, frag.canvas.width, frag.canvas.height, frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2, frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2, frag.canvas.width / this.font.quality, frag.canvas.height / this.font.quality);\n }\n }\n dispose() {\n this.disposed = true;\n this.dimensions = undefined;\n this.canvas = undefined;\n this.ctx = undefined;\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) {\n for (const frag of this._textFragments) {\n this._ex.textureLoader.delete(frag.canvas);\n }\n }\n this._textFragments.length = 0;\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\n return this._cachedLines;\n }\n const lines = text.split('\\n');\n if (maxWidth == null) {\n return lines;\n }\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i];\n let newLine = '';\n if (this.measureText(line).width > maxWidth) {\n while (this.measureText(line).width > maxWidth) {\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/FontCache.ts\n\n\nclass FontCache {\n static measureText(text, font, maxWidth) {\n const hash = FontTextInstance.getHashCode(font, text);\n if (FontCache._MEASURE_CACHE.has(hash)) {\n return FontCache._MEASURE_CACHE.get(hash);\n }\n FontCache._LOGGER.debug('Font text measurement cache miss');\n const measurement = font.measureTextWithoutCache(text, maxWidth);\n FontCache._MEASURE_CACHE.set(hash, measurement);\n return measurement;\n }\n static getTextInstance(text, font, color) {\n const hash = FontTextInstance.getHashCode(font, text, color);\n let textInstance = FontCache._TEXT_CACHE.get(hash);\n if (!textInstance) {\n textInstance = new FontTextInstance(font, text, color);\n FontCache._TEXT_CACHE.set(hash, textInstance);\n FontCache._LOGGER.debug('Font text instance cache miss');\n }\n // Cache the bitmap for certain amount of time\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\n return textInstance;\n }\n static checkAndClearCache() {\n const deferred = [];\n const currentHashCodes = new Set();\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries()) {\n // if bitmap hasn't been used in 100 ms clear it\n if (time + FontCache.FONT_TIMEOUT < performance.now()) {\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\n deferred.push(textInstance);\n textInstance.dispose();\n }\n else {\n const hash = textInstance.getHashCode(false);\n currentHashCodes.add(hash);\n }\n }\n // Deferred removal of text instances\n deferred.forEach((t) => {\n FontCache._TEXT_USAGE.delete(t);\n });\n // Regenerate text instance cache\n this._TEXT_CACHE.clear();\n for (const [textInstance] of this._TEXT_USAGE.entries()) {\n this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\n }\n // Regenerated measurement cache\n const newTextMeasurementCache = new Map();\n for (const current of currentHashCodes) {\n if (FontCache._MEASURE_CACHE.has(current)) {\n newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\n }\n }\n this._MEASURE_CACHE.clear();\n this._MEASURE_CACHE = newTextMeasurementCache;\n }\n static get cacheSize() {\n return FontCache._TEXT_USAGE.size;\n }\n /**\n * Force clear all cached text bitmaps\n */\n static clearCache() {\n for (const [textInstance] of FontCache._TEXT_USAGE.entries()) {\n textInstance.dispose();\n }\n FontCache._TEXT_USAGE.clear();\n FontCache._TEXT_CACHE.clear();\n FontCache._MEASURE_CACHE.clear();\n }\n}\nFontCache.FONT_TIMEOUT = 500;\nFontCache._LOGGER = Logger.getInstance();\nFontCache._TEXT_USAGE = new Map();\nFontCache._TEXT_CACHE = new Map();\nFontCache._MEASURE_CACHE = new Map();\n\n;// CONCATENATED MODULE: ./Graphics/Font.ts\n\n\n\n\n\n\n\n/**\n * Represents a system or web font in Excalibur\n *\n * If no options specified, the system sans-serif 10 pixel is used\n *\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\n */\nclass Font extends Graphic {\n constructor(options = {}) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;\n super(options); // <- Graphics properties\n /**\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\n *\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\n */\n this.filtering = ImageFiltering.Blended;\n /**\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\n *\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\n *\n * (Default 2)\n */\n this.quality = 2;\n // Raster properties for fonts\n this.padding = 2;\n this.smoothing = false;\n this.lineWidth = 1;\n this.lineDash = [];\n this.color = Color.Black;\n this.family = 'sans-serif';\n this.style = FontStyle.Normal;\n this.bold = false;\n this.unit = FontUnit.Px;\n this.textAlign = TextAlign.Left;\n this.baseAlign = BaseAlign.Top;\n this.direction = Direction.LeftToRight;\n /**\n * Font line height in pixels, default line height if unset\n */\n this.lineHeight = undefined;\n this.size = 10;\n this.shadow = null;\n this._textBounds = new BoundingBox();\n this._textMeasurement = new FontTextInstance(this, '', Color.Black);\n // Raster properties\n this.smoothing = (_a = options === null || options === void 0 ? void 0 : options.smoothing) !== null && _a !== void 0 ? _a : this.smoothing;\n this.padding = (_b = options === null || options === void 0 ? void 0 : options.padding) !== null && _b !== void 0 ? _b : this.padding;\n this.color = (_c = options === null || options === void 0 ? void 0 : options.color) !== null && _c !== void 0 ? _c : this.color;\n this.strokeColor = (_d = options === null || options === void 0 ? void 0 : options.strokeColor) !== null && _d !== void 0 ? _d : this.strokeColor;\n this.lineDash = (_e = options === null || options === void 0 ? void 0 : options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineWidth = (_f = options === null || options === void 0 ? void 0 : options.lineWidth) !== null && _f !== void 0 ? _f : this.lineWidth;\n this.filtering = (_g = options === null || options === void 0 ? void 0 : options.filtering) !== null && _g !== void 0 ? _g : this.filtering;\n // Font specific properties\n this.family = (_h = options === null || options === void 0 ? void 0 : options.family) !== null && _h !== void 0 ? _h : this.family;\n this.style = (_j = options === null || options === void 0 ? void 0 : options.style) !== null && _j !== void 0 ? _j : this.style;\n this.bold = (_k = options === null || options === void 0 ? void 0 : options.bold) !== null && _k !== void 0 ? _k : this.bold;\n this.size = (_l = options === null || options === void 0 ? void 0 : options.size) !== null && _l !== void 0 ? _l : this.size;\n this.unit = (_m = options === null || options === void 0 ? void 0 : options.unit) !== null && _m !== void 0 ? _m : this.unit;\n this.textAlign = (_o = options === null || options === void 0 ? void 0 : options.textAlign) !== null && _o !== void 0 ? _o : this.textAlign;\n this.baseAlign = (_p = options === null || options === void 0 ? void 0 : options.baseAlign) !== null && _p !== void 0 ? _p : this.baseAlign;\n this.direction = (_q = options === null || options === void 0 ? void 0 : options.direction) !== null && _q !== void 0 ? _q : this.direction;\n this.lineHeight = (_r = options === null || options === void 0 ? void 0 : options.lineHeight) !== null && _r !== void 0 ? _r : this.lineHeight;\n this.quality = (_s = options === null || options === void 0 ? void 0 : options.quality) !== null && _s !== void 0 ? _s : this.quality;\n if (options === null || options === void 0 ? void 0 : options.shadow) {\n this.shadow = {};\n this.shadow.blur = (_t = options.shadow.blur) !== null && _t !== void 0 ? _t : this.shadow.blur;\n this.shadow.offset = (_u = options.shadow.offset) !== null && _u !== void 0 ? _u : this.shadow.offset;\n this.shadow.color = (_v = options.shadow.color) !== null && _v !== void 0 ? _v : this.shadow.color;\n }\n }\n clone() {\n return new Font({\n ...this.cloneGraphicOptions(),\n size: this.size,\n unit: this.unit,\n family: this.family,\n style: this.style,\n bold: this.bold,\n textAlign: this.textAlign,\n baseAlign: this.baseAlign,\n direction: this.direction,\n shadow: this.shadow\n ? {\n blur: this.shadow.blur,\n offset: this.shadow.offset,\n color: this.shadow.color\n }\n : null\n });\n }\n get fontString() {\n return `${this.style} ${this.bold ? 'bold' : ''} ${this.size}${this.unit} ${this.family}`;\n }\n get localBounds() {\n return this._textBounds;\n }\n _drawImage(_ex, _x, _y) {\n // TODO weird vestigial drawimage\n }\n _rotate(ex) {\n var _a;\n // TODO this needs to change depending on the bounding box...\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : this._textBounds.center;\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this._textBounds.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\n ex.scale(1, -1);\n }\n }\n measureTextWithoutCache(text, maxWidth) {\n return this._textMeasurement.measureText(text, maxWidth);\n }\n /**\n * Returns a BoundingBox that is the total size of the text including multiple lines\n *\n * Does not include any padding or adjustment\n * @param text\n * @returns BoundingBox\n */\n measureText(text, maxWidth) {\n return FontCache.measureText(text, this, maxWidth);\n }\n _postDraw(ex) {\n ex.restore();\n }\n render(ex, text, colorOverride, x, y, maxWidth) {\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\n // Apply affine transformations\n this._textBounds = textInstance.dimensions;\n this._preDraw(ex, x, y);\n textInstance.render(ex, x, y, maxWidth);\n this._postDraw(ex);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Text.ts\n\n\n\n/**\n * Represent Text graphics in excalibur\n *\n * Useful for in game labels, ui, or overlays\n */\nclass Text extends Graphic {\n constructor(options) {\n var _a, _b;\n super(options);\n this._text = '';\n this._textWidth = 0;\n this._textHeight = 0;\n // This order is important font, color, then text\n this.font = (_a = options.font) !== null && _a !== void 0 ? _a : new Font();\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : this.color;\n this.text = options.text;\n this.maxWidth = options.maxWidth;\n }\n clone() {\n var _a, _b;\n return new Text({\n text: this.text.slice(),\n color: (_b = (_a = this.color) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : Color.Black,\n font: this.font.clone(),\n maxWidth: this.maxWidth\n });\n }\n get text() {\n return this._text;\n }\n set text(value) {\n this._text = value;\n this._calculateDimension();\n }\n get font() {\n return this._font;\n }\n set font(font) {\n this._font = font;\n }\n get width() {\n if (this._textWidth === 0) {\n this._calculateDimension();\n }\n return this._textWidth * this.scale.x;\n }\n get height() {\n if (this._textHeight === 0) {\n this._calculateDimension();\n }\n return this._textHeight * this.scale.y;\n }\n _calculateDimension() {\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n }\n get localBounds() {\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\n }\n _rotate(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _flip(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _preDraw(ex, x, y) {\n if (this.isStale() || this.font.isStale()) {\n this.font.flipHorizontal = this.flipHorizontal;\n this.font.flipVertical = this.flipVertical;\n this.font.rotation = this.rotation;\n this.font.origin = this.origin;\n this.font.opacity = this.opacity;\n }\n this.font.tint = this.tint;\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n var _a;\n let color = Color.Black;\n if (this.font instanceof Font) {\n color = (_a = this.color) !== null && _a !== void 0 ? _a : this.font.color;\n }\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\n if (this.font.showDebug) {\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\n if (this.maxWidth != null) {\n ex.debug.drawRect(x, y, this.maxWidth, this.height, {\n color: Color.Yellow\n });\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Actor.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Type guard for checking if something is an Actor\n * @param x\n */\nfunction isActor(x) {\n return x instanceof Actor;\n}\nconst ActorEvents = {\n CollisionStart: 'collisionstart',\n CollisionEnd: 'collisionend',\n PreCollision: 'precollision',\n PostCollision: 'postcollision',\n Kill: 'kill',\n PreKill: 'prekill',\n PostKill: 'postkill',\n PreDraw: 'predraw',\n PostDraw: 'postdraw',\n PreTransformDraw: 'pretransformdraw',\n PostTransformDraw: 'posttransformdraw',\n PreDebugDraw: 'predebugdraw',\n PostDebugDraw: 'postdebugdraw',\n PointerUp: 'pointerup',\n PointerDown: 'pointerdown',\n PointerEnter: 'pointerenter',\n PointerLeave: 'pointerleave',\n PointerMove: 'pointermove',\n PointerCancel: 'pointercancel',\n Wheel: 'pointerwheel',\n PointerDrag: 'pointerdragstart',\n PointerDragEnd: 'pointerdragend',\n PointerDragEnter: 'pointerdragenter',\n PointerDragLeave: 'pointerdragleave',\n PointerDragMove: 'pointerdragmove',\n EnterViewPort: 'enterviewport',\n ExitViewPort: 'exitviewport',\n ActionStart: 'actionstart',\n ActionComplete: 'actioncomplete'\n};\n/**\n * The most important primitive in Excalibur is an `Actor`. Anything that\n * can move on the screen, collide with another `Actor`, respond to events,\n * or interact with the current scene, must be an actor. An `Actor` **must**\n * be part of a [[Scene]] for it to be drawn to the screen.\n */\nclass Actor extends Entity {\n /**\n * Gets the position vector of the actor in pixels\n */\n get pos() {\n return this.transform.pos;\n }\n /**\n * Sets the position vector of the actor in pixels\n */\n set pos(thePos) {\n this.transform.pos = thePos.clone();\n }\n /**\n * Gets the position vector of the actor from the last frame\n */\n get oldPos() {\n return this.body.oldPos;\n }\n /**\n * Sets the position vector of the actor in the last frame\n */\n set oldPos(thePos) {\n this.body.oldPos.setTo(thePos.x, thePos.y);\n }\n /**\n * Gets the velocity vector of the actor in pixels/sec\n */\n get vel() {\n return this.motion.vel;\n }\n /**\n * Sets the velocity vector of the actor in pixels/sec\n */\n set vel(theVel) {\n this.motion.vel = theVel.clone();\n }\n /**\n * Gets the velocity vector of the actor from the last frame\n */\n get oldVel() {\n return this.body.oldVel;\n }\n /**\n * Sets the velocity vector of the actor from the last frame\n */\n set oldVel(theVel) {\n this.body.oldVel.setTo(theVel.x, theVel.y);\n }\n /**\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\n * useful to simulate a gravitational effect.\n */\n get acc() {\n return this.motion.acc;\n }\n /**\n * Sets the acceleration vector of teh actor in pixels/second/second\n */\n set acc(theAcc) {\n this.motion.acc = theAcc.clone();\n }\n /**\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */\n set oldAcc(theAcc) {\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\n }\n /**\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */\n get oldAcc() {\n return this.body.oldAcc;\n }\n /**\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\n */\n get rotation() {\n return this.transform.rotation;\n }\n /**\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\n */\n set rotation(theAngle) {\n this.transform.rotation = theAngle;\n }\n /**\n * Gets the rotational velocity of the actor in radians/second\n */\n get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\n * Sets the rotational velocity of the actor in radians/sec\n */\n set angularVelocity(angularVelocity) {\n this.motion.angularVelocity = angularVelocity;\n }\n get scale() {\n return this.get(TransformComponent).scale;\n }\n set scale(scale) {\n this.get(TransformComponent).scale = scale;\n }\n /**\n * The anchor to apply all actor related transformations like rotation,\n * translation, and scaling. By default the anchor is in the center of\n * the actor. By default it is set to the center of the actor (.5, .5)\n *\n * An anchor of (.5, .5) will ensure that drawings are centered.\n *\n * Use `anchor.setTo` to set the anchor to a different point using\n * values between 0 and 1. For example, anchoring to the top-left would be\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\n */\n get anchor() {\n return this._anchor;\n }\n set anchor(vec) {\n this._anchor = watch(vec, (v) => this._handleAnchorChange(v));\n this._handleAnchorChange(vec);\n }\n _handleAnchorChange(v) {\n if (this.graphics) {\n this.graphics.anchor = v;\n }\n }\n /**\n * The offset in pixels to apply to all actor graphics\n *\n * Default offset of (0, 0)\n */\n get offset() {\n return this._offset;\n }\n set offset(vec) {\n this._offset = watch(vec, (v) => this._handleOffsetChange(v));\n this._handleOffsetChange(vec);\n }\n _handleOffsetChange(v) {\n if (this.graphics) {\n this.graphics.offset = v;\n }\n }\n /**\n * Indicates whether the actor is physically in the viewport\n */\n get isOffScreen() {\n return this.hasTag('ex.offscreen');\n }\n get draggable() {\n return this._draggable;\n }\n set draggable(isDraggable) {\n if (isDraggable) {\n if (isDraggable && !this._draggable) {\n this.events.on('pointerdragstart', this._pointerDragStartHandler);\n this.events.on('pointerdragend', this._pointerDragEndHandler);\n this.events.on('pointerdragmove', this._pointerDragMoveHandler);\n this.events.on('pointerdragleave', this._pointerDragLeaveHandler);\n }\n else if (!isDraggable && this._draggable) {\n this.events.off('pointerdragstart', this._pointerDragStartHandler);\n this.events.off('pointerdragend', this._pointerDragEndHandler);\n this.events.off('pointerdragmove', this._pointerDragMoveHandler);\n this.events.off('pointerdragleave', this._pointerDragLeaveHandler);\n }\n this._draggable = isDraggable;\n }\n }\n /**\n * Sets the color of the actor's current graphic\n */\n get color() {\n return this._color;\n }\n set color(v) {\n this._color = v.clone();\n const currentGraphic = this.graphics.current;\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) {\n currentGraphic.color = this._color;\n }\n }\n // #endregion\n /**\n *\n * @param config\n */\n constructor(config) {\n super();\n this.events = new EventEmitter();\n this._anchor = watch(Vector.Half, (v) => this._handleAnchorChange(v));\n this._offset = watch(Vector.Zero, (v) => this._handleOffsetChange(v));\n /**\n * Convenience reference to the global logger\n */\n this.logger = Logger.getInstance();\n /**\n * Draggable helper\n */\n this._draggable = false;\n this._dragging = false;\n this._pointerDragStartHandler = () => {\n this._dragging = true;\n };\n this._pointerDragEndHandler = () => {\n this._dragging = false;\n };\n this._pointerDragMoveHandler = (pe) => {\n if (this._dragging) {\n this.pos = pe.worldPos;\n }\n };\n this._pointerDragLeaveHandler = (pe) => {\n if (this._dragging) {\n this.pos = pe.worldPos;\n }\n };\n const { name, x, y, pos, coordPlane, scale, width, height, radius, collider, vel, acc, rotation, angularVelocity, z, color, visible, opacity, anchor, offset, collisionType, collisionGroup } = {\n ...config\n };\n this.name = name !== null && name !== void 0 ? name : this.name;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : Actor.defaults.anchor.clone();\n this.offset = offset !== null && offset !== void 0 ? offset : Vector.Zero;\n this.transform = new TransformComponent();\n this.addComponent(this.transform);\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.rotation = rotation !== null && rotation !== void 0 ? rotation : 0;\n this.scale = scale !== null && scale !== void 0 ? scale : vec(1, 1);\n this.z = z !== null && z !== void 0 ? z : 0;\n this.transform.coordPlane = coordPlane !== null && coordPlane !== void 0 ? coordPlane : CoordPlane.World;\n this.pointer = new PointerComponent;\n this.addComponent(this.pointer);\n this.graphics = new GraphicsComponent({\n anchor: this.anchor,\n offset: this.offset,\n opacity: opacity\n });\n this.addComponent(this.graphics);\n this.motion = new MotionComponent;\n this.addComponent(this.motion);\n this.vel = vel !== null && vel !== void 0 ? vel : Vector.Zero;\n this.acc = acc !== null && acc !== void 0 ? acc : Vector.Zero;\n this.angularVelocity = angularVelocity !== null && angularVelocity !== void 0 ? angularVelocity : 0;\n this.actions = new ActionsComponent;\n this.addComponent(this.actions);\n this.body = new BodyComponent;\n this.addComponent(this.body);\n this.body.collisionType = collisionType !== null && collisionType !== void 0 ? collisionType : CollisionType.Passive;\n if (collisionGroup) {\n this.body.group = collisionGroup;\n }\n if (collider) {\n this.collider = new ColliderComponent(collider);\n this.addComponent(this.collider);\n }\n else if (radius) {\n this.collider = new ColliderComponent(Shape.Circle(radius));\n this.addComponent(this.collider);\n }\n else {\n if (width > 0 && height > 0) {\n this.collider = new ColliderComponent(Shape.Box(width, height, this.anchor));\n this.addComponent(this.collider);\n }\n else {\n this.collider = new ColliderComponent();\n this.addComponent(this.collider); // no collider\n }\n }\n this.graphics.visible = visible !== null && visible !== void 0 ? visible : true;\n if (color) {\n this.color = color;\n if (width && height) {\n this.graphics.add(new Rectangle({\n color: color,\n width,\n height\n }));\n }\n else if (radius) {\n this.graphics.add(new Circle({\n color: color,\n radius\n }));\n }\n }\n }\n clone() {\n const clone = new Actor({\n color: this.color.clone(),\n anchor: this.anchor.clone(),\n offset: this.offset.clone()\n });\n clone.clearComponents();\n clone.processComponentRemoval();\n // Clone builtins, order is important, same as ctor\n clone.addComponent(clone.transform = this.transform.clone(), true);\n clone.addComponent(clone.pointer = this.pointer.clone(), true);\n clone.addComponent(clone.graphics = this.graphics.clone(), true);\n clone.addComponent(clone.motion = this.motion.clone(), true);\n clone.addComponent(clone.actions = this.actions.clone(), true);\n clone.addComponent(clone.body = this.body.clone(), true);\n clone.addComponent(clone.collider = this.collider.clone(), true);\n const builtInComponents = [\n this.transform,\n this.pointer,\n this.graphics,\n this.motion,\n this.actions,\n this.body,\n this.collider\n ];\n // Clone non-builtin the current actors components\n const components = this.getComponents();\n for (const c of components) {\n if (!builtInComponents.includes(c)) {\n clone.addComponent(c.clone(), true);\n }\n }\n return clone;\n }\n /**\n * `onInitialize` is called before the first update of the actor. This method is meant to be\n * overridden. This is where initialization of child actors should take place.\n *\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\n */\n onInitialize(engine) {\n // Override me\n }\n /**\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\n *\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n * @internal\n */\n _initialize(engine) {\n super._initialize(engine);\n for (const child of this.children) {\n child._initialize(engine);\n }\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n // #endregion\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _prekill handler for [[onPreKill]] lifecycle event\n * @internal\n */\n _prekill(scene) {\n this.events.emit('prekill', new PreKillEvent(this));\n this.onPreKill(scene);\n }\n /**\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\n *\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\n */\n onPreKill(scene) {\n // Override me\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _prekill handler for [[onPostKill]] lifecycle event\n * @internal\n */\n _postkill(scene) {\n this.events.emit('postkill', new PostKillEvent(this));\n this.onPostKill(scene);\n }\n /**\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\n *\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\n */\n onPostKill(scene) {\n // Override me\n }\n /**\n * If the current actor is a member of the scene, this will remove\n * it from the scene graph. It will no longer be drawn or updated.\n */\n kill() {\n if (this.scene) {\n this._prekill(this.scene);\n this.events.emit('kill', new KillEvent(this));\n super.kill();\n this._postkill(this.scene);\n }\n else {\n this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\n }\n }\n /**\n * If the current actor is killed, it will now not be killed.\n */\n unkill() {\n this.active = true;\n }\n /**\n * Indicates wether the actor has been killed.\n */\n isKilled() {\n return !this.active;\n }\n /**\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\n */\n get z() {\n return this.get(TransformComponent).z;\n }\n /**\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\n * The z-index determines the relative order an actor is drawn in.\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\n * @param newZ new z-index to assign\n */\n set z(newZ) {\n this.get(TransformComponent).z = newZ;\n }\n /**\n * Get the center point of an actor (global position)\n */\n get center() {\n const globalPos = this.getGlobalPos();\n return new Vector(globalPos.x + this.width / 2 - this.anchor.x * this.width, globalPos.y + this.height / 2 - this.anchor.y * this.height);\n }\n /**\n * Get the local center point of an actor\n */\n get localCenter() {\n return new Vector(this.pos.x + this.width / 2 - this.anchor.x * this.width, this.pos.y + this.height / 2 - this.anchor.y * this.height);\n }\n get width() {\n return this.collider.localBounds.width * this.getGlobalScale().x;\n }\n get height() {\n return this.collider.localBounds.height * this.getGlobalScale().y;\n }\n /**\n * Gets this actor's rotation taking into account any parent relationships\n * @returns Rotation angle in radians\n */\n getGlobalRotation() {\n return this.get(TransformComponent).globalRotation;\n }\n /**\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\n * @returns Position in world coordinates\n */\n getGlobalPos() {\n return this.get(TransformComponent).globalPos;\n }\n /**\n * Gets the global scale of the Actor\n */\n getGlobalScale() {\n return this.get(TransformComponent).globalScale;\n }\n // #region Collision\n /**\n * Tests whether the x/y specified are contained in the actor\n * @param x X coordinate to test (in world coordinates)\n * @param y Y coordinate to test (in world coordinates)\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\n */\n contains(x, y, recurse = false) {\n const point = vec(x, y);\n const collider = this.get(ColliderComponent);\n collider.update();\n const geom = collider.get();\n if (!geom) {\n return false;\n }\n const containment = geom.contains(point);\n if (recurse) {\n return (containment ||\n this.children.some((child) => {\n return child.contains(x, y, true);\n }));\n }\n return containment;\n }\n /**\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\n * @param actor Actor to test\n * @param distance Distance in pixels to test\n */\n within(actor, distance) {\n const collider = this.get(ColliderComponent);\n const otherCollider = actor.get(ColliderComponent);\n const me = collider.get();\n const other = otherCollider.get();\n if (me && other) {\n return me.getClosestLineBetween(other).getLength() <= distance;\n }\n return false;\n }\n // #endregion\n // #region Update\n /**\n * Called by the Engine, updates the state of the actor\n * @internal\n * @param engine The reference to the current game engine\n * @param delta The time elapsed since the last update in milliseconds\n */\n update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this._postupdate(engine, delta);\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before an actor is updated.\n */\n onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after an actor is updated.\n */\n onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n * Fires before every collision resolution for a confirmed contact\n * @param self\n * @param other\n * @param side\n * @param contact\n */\n onPreCollisionResolve(self, other, side, contact) {\n // Override me\n }\n /**\n * Fires after every resolution for a confirmed contact.\n * @param self\n * @param other\n * @param side\n * @param contact\n */\n onPostCollisionResolve(self, other, side, contact) {\n // Override me\n }\n /**\n * Fires once when 2 entities with a ColliderComponent first start colliding or touching, if the Colliders stay in contact this\n * does not continue firing until they separate and re-collide.\n * @param self\n * @param other\n * @param side\n * @param contact\n */\n onCollisionStart(self, other, side, contact) {\n // Override me\n }\n /**\n * Fires once when 2 entities with a ColliderComponent separate after having been in contact.\n * @param self\n * @param other\n * @param side\n * @param lastContact\n */\n onCollisionEnd(self, other, side, lastContact) {\n // Override me\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */\n _preupdate(engine, delta) {\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */\n _postupdate(engine, delta) {\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n}\n// #region Properties\n/**\n * Set defaults for all Actors\n */\nActor.defaults = {\n anchor: Vector.Half\n};\n\n;// CONCATENATED MODULE: ./ScreenElement.ts\n\n\n\n\n\n/**\n * Type guard to detect a screen element\n */\nfunction isScreenElement(actor) {\n return actor instanceof ScreenElement;\n}\n/**\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\n * not participate in collisions. Drawn on top of all other actors.\n */\nclass ScreenElement extends Actor {\n constructor(config) {\n var _a, _b;\n super({ ...config });\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\n this.anchor = (_a = config === null || config === void 0 ? void 0 : config.anchor) !== null && _a !== void 0 ? _a : vec(0, 0);\n this.body.collisionType = (_b = config === null || config === void 0 ? void 0 : config.collisionType) !== null && _b !== void 0 ? _b : CollisionType.PreventCollision;\n this.pointer.useGraphicsBounds = true;\n this.pointer.useColliderShape = false;\n if (!(config === null || config === void 0 ? void 0 : config.collider) &&\n (config === null || config === void 0 ? void 0 : config.width) > 0 &&\n (config === null || config === void 0 ? void 0 : config.height) > 0) {\n this.collider.useBoxCollider(this.width, this.height, this.anchor);\n }\n }\n _initialize(engine) {\n this._engine = engine;\n super._initialize(engine);\n }\n contains(x, y, useWorld = true) {\n if (useWorld) {\n return super.contains(x, y);\n }\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\n return super.contains(coords.x, coords.y);\n }\n}\n\n;// CONCATENATED MODULE: ./Timer.ts\n\n\n/**\n * The Excalibur timer hooks into the internal timer and fires callbacks,\n * after a certain interval, optionally repeating.\n */\nclass Timer {\n get complete() {\n return this._complete;\n }\n constructor(fcn, interval, repeats, numberOfRepeats, randomRange, random) {\n this._logger = Logger.getInstance();\n this.id = 0;\n this._elapsedTime = 0;\n this._totalTimeAlive = 0;\n this._running = false;\n this._numberOfTicks = 0;\n this.interval = 10;\n this.repeats = false;\n this.maxNumberOfRepeats = -1;\n this.randomRange = [0, 0];\n this._baseInterval = 10;\n this._generateRandomInterval = () => {\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\n };\n this._complete = false;\n this.scene = null;\n if (typeof fcn !== 'function') {\n const options = fcn;\n fcn = options.fcn;\n interval = options.interval;\n repeats = options.repeats;\n numberOfRepeats = options.numberOfRepeats;\n randomRange = options.randomRange;\n random = options.random;\n }\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\n this.maxNumberOfRepeats = numberOfRepeats;\n if (!repeats) {\n throw new Error('repeats must be set to true if numberOfRepeats is set');\n }\n }\n this.id = Timer._MAX_ID++;\n this._callbacks = [];\n this._baseInterval = this.interval = interval;\n if (!!randomRange) {\n if (randomRange[0] > randomRange[1]) {\n throw new Error('min value must be lower than max value for range');\n }\n //We use the instance of ex.Random to generate the range\n this.random = random !== null && random !== void 0 ? random : new Random();\n this.randomRange = randomRange;\n this.interval = this._generateRandomInterval();\n this.on(() => {\n this.interval = this._generateRandomInterval();\n });\n }\n ;\n this.repeats = repeats || this.repeats;\n if (fcn) {\n this.on(fcn);\n }\n }\n /**\n * Adds a new callback to be fired after the interval is complete\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\n */\n on(fcn) {\n this._callbacks.push(fcn);\n }\n /**\n * Removes a callback from the callback list to be fired after the interval is complete.\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\n */\n off(fcn) {\n const index = this._callbacks.indexOf(fcn);\n this._callbacks.splice(index, 1);\n }\n /**\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\n * @param delta Number of elapsed milliseconds since the last update.\n */\n update(delta) {\n if (this._running) {\n this._totalTimeAlive += delta;\n this._elapsedTime += delta;\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n if (!this.complete && this._elapsedTime >= this.interval) {\n this._callbacks.forEach((c) => {\n c.call(this);\n });\n this._numberOfTicks++;\n if (this.repeats) {\n this._elapsedTime = 0;\n }\n else {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n }\n }\n }\n /**\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\n *\n * Warning** you may need to call `timer.start()` again if the timer had completed\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\n */\n reset(newInterval, newNumberOfRepeats) {\n if (!!newInterval && newInterval >= 0) {\n this._baseInterval = this.interval = newInterval;\n }\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\n this.maxNumberOfRepeats = newNumberOfRepeats;\n if (!this.repeats) {\n throw new Error('repeats must be set to true if numberOfRepeats is set');\n }\n }\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n get timesRepeated() {\n return this._numberOfTicks;\n }\n getTimeRunning() {\n return this._totalTimeAlive;\n }\n /**\n * @returns milliseconds until the next action callback, if complete will return 0\n */\n get timeToNextAction() {\n if (this.complete) {\n return 0;\n }\n return this.interval - this._elapsedTime;\n }\n /**\n * @returns milliseconds elapsed toward the next action\n */\n get timeElapsedTowardNextAction() {\n return this._elapsedTime;\n }\n get isRunning() {\n return this._running;\n }\n /**\n * Pauses the timer, time will no longer increment towards the next call\n */\n pause() {\n this._running = false;\n return this;\n }\n /**\n * Resumes the timer, time will now increment towards the next call.\n */\n resume() {\n this._running = true;\n return this;\n }\n /**\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\n */\n start() {\n if (!this.scene) {\n this._logger.warn('Cannot start a timer not part of a scene, timer wont start until added');\n }\n this._running = true;\n if (this.complete) {\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n return this;\n }\n /**\n * Stops the timer and resets the elapsed time counter towards the next action invocation\n */\n stop() {\n this._running = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n return this;\n }\n /**\n * Cancels the timer, preventing any further executions.\n */\n cancel() {\n this.pause();\n if (this.scene) {\n this.scene.cancelTimer(this);\n }\n }\n}\nTimer._MAX_ID = 0;\n\n;// CONCATENATED MODULE: ./Graphics/ParallaxComponent.ts\n\n\nclass ParallaxComponent extends Component {\n constructor(parallaxFactor) {\n super();\n this.parallaxFactor = vec(1.0, 1.0);\n this.parallaxFactor = parallaxFactor !== null && parallaxFactor !== void 0 ? parallaxFactor : this.parallaxFactor;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/DebugGraphicsComponent.ts\n\n/**\n * Provide arbitrary drawing for the purposes of debugging your game\n *\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\n *\n */\nclass DebugGraphicsComponent extends Component {\n constructor(draw, useTransform = true) {\n super();\n this.draw = draw;\n this.useTransform = useTransform;\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/TileMap.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst TileMapEvents = {\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate',\n PreDraw: 'predraw',\n PostDraw: 'postdraw'\n};\n/**\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\n *\n * TileMaps are useful for top down or side scrolling grid oriented games.\n */\nclass TileMap extends Entity {\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n flagTilesDirty() {\n for (let i = 0; i < this.tiles.length; i++) {\n if (this.tiles[i]) {\n this.tiles[i].flagDirty();\n }\n }\n }\n get x() {\n var _a;\n return (_a = this.transform.pos.x) !== null && _a !== void 0 ? _a : 0;\n }\n set x(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos) {\n this.get(TransformComponent).pos = vec(val, this.y);\n }\n }\n get y() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos.y) !== null && _b !== void 0 ? _b : 0;\n }\n set y(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos) {\n this.transform.pos = vec(this.x, val);\n }\n }\n get z() {\n var _a;\n return (_a = this.transform.z) !== null && _a !== void 0 ? _a : 0;\n }\n set z(val) {\n if (this.transform) {\n this.transform.z = val;\n }\n }\n get rotation() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.rotation) !== null && _b !== void 0 ? _b : 0;\n }\n set rotation(val) {\n if (this.transform) {\n this.transform.rotation = val;\n }\n }\n get scale() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : Vector.One;\n }\n set scale(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.scale) {\n this.transform.scale = val;\n }\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n get vel() {\n return this._motion.vel;\n }\n set vel(val) {\n this._motion.vel = val;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * @param options\n */\n constructor(options) {\n var _a, _b, _c;\n super([], options.name);\n this.events = new EventEmitter();\n this._token = 0;\n this.logger = Logger.getInstance();\n this.tiles = [];\n this._rows = [];\n this._cols = [];\n this.renderFromTopOfGraphic = false;\n this.meshingLookBehind = 10;\n this._collidersDirty = true;\n this._originalOffsets = new WeakMap();\n this.meshingLookBehind = (_a = options.meshingLookBehind) !== null && _a !== void 0 ? _a : this.meshingLookBehind;\n this.addComponent(new TransformComponent());\n this.addComponent(new MotionComponent());\n this.addComponent(new BodyComponent({\n type: CollisionType.Fixed\n }));\n this.addComponent(new GraphicsComponent({\n onPostDraw: (ctx, delta) => this.draw(ctx, delta)\n }));\n this.addComponent(new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false));\n this.addComponent(new ColliderComponent());\n this._graphics = this.get(GraphicsComponent);\n this.transform = this.get(TransformComponent);\n this._motion = this.get(MotionComponent);\n this.collider = this.get(ColliderComponent);\n this._composite = this.collider.useCompositeCollider([]);\n this.transform.pos = (_b = options.pos) !== null && _b !== void 0 ? _b : Vector.Zero;\n this._oldPos = this.transform.pos.clone();\n this._oldScale = this.transform.scale.clone();\n this.renderFromTopOfGraphic = (_c = options.renderFromTopOfGraphic) !== null && _c !== void 0 ? _c : this.renderFromTopOfGraphic;\n this.tileWidth = options.tileWidth;\n this.tileHeight = options.tileHeight;\n this.rows = options.rows;\n this.columns = options.columns;\n this.tiles = new Array(this.rows * this.columns);\n this._rows = new Array(this.rows);\n this._cols = new Array(this.columns);\n let currentCol = [];\n for (let i = 0; i < this.columns; i++) {\n for (let j = 0; j < this.rows; j++) {\n const tile = new Tile({\n x: i,\n y: j,\n map: this\n });\n tile.map = this;\n this.tiles[i + j * this.columns] = tile;\n currentCol.push(tile);\n if (!this._rows[j]) {\n this._rows[j] = [];\n }\n this._rows[j].push(tile);\n }\n this._cols[i] = currentCol;\n currentCol = [];\n }\n this._graphics.localBounds = new BoundingBox({\n left: 0,\n top: 0,\n right: this.columns * this.tileWidth * this.scale.x,\n bottom: this.rows * this.tileHeight * this.scale.y\n });\n }\n _initialize(engine) {\n super._initialize(engine);\n this._engine = engine;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n }\n else {\n return this._originalOffsets.get(collider);\n }\n }\n /**\n * Tiles colliders based on the solid tiles in the tilemap.\n */\n _updateColliders() {\n this.collider.$colliderRemoved.notifyAll(this._composite);\n this._composite.clearColliders();\n const colliders = [];\n this._composite = this.collider.useCompositeCollider([]);\n let current;\n /**\n * Returns wether or not the 2 boxes share an edge and are the same height\n * @param prev\n * @param next\n * @returns true if they share and edge, false if not\n */\n const shareEdges = (prev, next) => {\n if (prev && next) {\n // same top/bottom\n return prev.top === next.top &&\n prev.bottom === next.bottom &&\n // Shared right/left edge\n prev.right === next.left;\n }\n return false;\n };\n /**\n * Potentially merges the current collider into a list of previous ones, mutating the list\n * If checkAndCombine returns true, the collider was successfully merged and should be thrown away\n * @param current current collider to test\n * @param colliders List of colliders to consider merging with\n * @param maxLookBack The amount of colliders to look back for combination\n * @returns false when no combination found, true when successfully combined\n */\n const checkAndCombine = (current, colliders, maxLookBack = this.meshingLookBehind) => {\n if (!current) {\n return false;\n }\n // walk backwards through the list of colliders and combine with the first that shares an edge\n for (let i = colliders.length - 1; i >= 0; i--) {\n if (maxLookBack-- < 0) {\n // blunt the O(n^2) algorithm a bit\n return false;\n }\n const prev = colliders[i];\n if (shareEdges(prev, current)) {\n colliders[i] = prev.combine(current);\n return true;\n }\n }\n return false;\n };\n // ? configurable bias perhaps, horizontal strips vs. vertical ones\n // Bad tile collider packing algorithm\n for (let i = 0; i < this.columns; i++) {\n // Scan column for colliders\n for (let j = 0; j < this.rows; j++) {\n const tile = this.tiles[i + j * this.columns];\n // Current tile in column is solid build up current collider\n if (tile.solid) {\n // Use custom collider otherwise bounding box\n if (tile.getColliders().length > 0) {\n // tile with custom collider interrupting the current run\n for (const collider of tile.getColliders()) {\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n //we push any current collider before nulling the current run\n if (current && !checkAndCombine(current, colliders)) {\n colliders.push(current);\n }\n current = null;\n // Use the bounding box\n }\n else {\n if (!current) {\n // no current run, start one\n current = tile.defaultGeometry;\n }\n else {\n // combine with current run\n current = current.combine(tile.defaultGeometry);\n }\n }\n }\n else {\n // Not solid skip and cut off the current collider\n // End of run check and combine\n if (current && !checkAndCombine(current, colliders)) {\n colliders.push(current);\n }\n current = null;\n }\n }\n // After a column is complete check to see if it can be merged into the last one\n // Eno of run check and combine\n if (current && !checkAndCombine(current, colliders)) {\n // else new collider if no combination\n colliders.push(current);\n }\n current = null;\n }\n for (const c of colliders) {\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n this.collider.update();\n // Notify that colliders have been updated\n this.collider.$colliderAdded.notifyAll(this._composite);\n }\n /**\n * Returns the [[Tile]] by index (row major order)\n */\n getTileByIndex(index) {\n return this.tiles[index];\n }\n /**\n * Returns the [[Tile]] by its x and y integer coordinates\n *\n * For example, if I want the tile in fifth column (x), and second row (y):\n * `getTile(4, 1)` 0 based, so 0 is the first in row/column\n */\n getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\n return null;\n }\n return this.tiles[x + y * this.columns];\n }\n /**\n * Returns the [[Tile]] by testing a point in world coordinates,\n * returns `null` if no Tile was found.\n */\n getTileByPoint(point) {\n const { x, y } = this._getTileCoordinates(point);\n const tile = this.getTile(x, y);\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) {\n return tile;\n }\n return null;\n }\n _getTileCoordinates(point) {\n // Convert to Tile Space point\n point = this.transform.applyInverse(point);\n const x = Math.floor(point.x / this.tileWidth);\n const y = Math.floor(point.y / this.tileHeight);\n return { x, y };\n }\n getRows() {\n return this._rows;\n }\n getColumns() {\n return this._cols;\n }\n /**\n * Returns the on screen tiles for a tilemap, this will overshoot by a small amount because of the internal quad tree data structure.\n *\n * Useful if you need to perform specific logic on onscreen tiles\n */\n getOnScreenTiles() {\n let worldBounds = this._engine.screen.getWorldBounds();\n const maybeParallax = this.get(ParallaxComponent);\n if (maybeParallax && this.isInitialized) {\n let pos = this.pos;\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\n pos = pos.sub(parallaxOffset);\n // adjust world bounds by parallax factor\n worldBounds = worldBounds.translate(pos);\n }\n const bounds = this.transform.coordPlane === CoordPlane.Screen ?\n this._engine.screen.getScreenBounds() :\n worldBounds;\n const topLeft = this._getTileCoordinates(bounds.topLeft);\n const topRight = this._getTileCoordinates(bounds.topRight);\n const bottomRight = this._getTileCoordinates(bounds.bottomRight);\n const bottomLeft = this._getTileCoordinates(bounds.bottomLeft);\n const tileStartX = Math.min(clamp(topLeft.x, 0, this.columns - 1), clamp(topRight.x, 0, this.columns - 1));\n const tileStartY = Math.min(clamp(topLeft.y, 0, this.rows - 1), clamp(topRight.y, 0, this.rows - 1));\n const tileEndX = Math.max(clamp(bottomRight.x, 0, this.columns - 1), clamp(bottomLeft.x, 0, this.columns - 1));\n const tileEndY = Math.max(clamp(bottomRight.y, 0, this.rows - 1), clamp(bottomLeft.y, 0, this.rows - 1));\n const tiles = [];\n for (let x = tileStartX; x <= tileEndX; x++) {\n for (let y = tileStartY; y <= tileEndY; y++) {\n tiles.push(this.getTile(x, y));\n }\n }\n return tiles;\n }\n update(engine, delta) {\n this._initialize(engine);\n this.onPreUpdate(engine, delta);\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n if (!this._oldPos.equals(this.pos) ||\n this._oldRotation !== this.rotation ||\n !this._oldScale.equals(this.scale)) {\n this.flagCollidersDirty();\n this.flagTilesDirty();\n }\n if (this._collidersDirty) {\n this._collidersDirty = false;\n this._updateColliders();\n }\n this._token++;\n this.pos.clone(this._oldPos);\n this._oldRotation = this.rotation;\n this.scale.clone(this._oldScale);\n this.transform.pos = this.pos;\n this.onPostUpdate(engine, delta);\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n }\n /**\n * Draws the tile map to the screen. Called by the [[Scene]].\n * @param ctx ExcaliburGraphicsContext\n * @param delta The number of milliseconds since the last draw\n */\n draw(ctx, delta) {\n if (!this.isInitialized) {\n return;\n }\n this.emit('predraw', new PreDrawEvent(ctx, delta, this)); // TODO fix event\n let graphics, graphicsIndex, graphicsLen;\n const tiles = this.getOnScreenTiles();\n for (let i = 0; i < tiles.length; i++) {\n const tile = tiles[i];\n // get non-negative tile sprites\n const offsets = tile.getGraphicsOffsets();\n graphics = tile.getGraphics();\n for (graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++) {\n // draw sprite, warning if sprite doesn't exist\n const graphic = graphics[graphicsIndex];\n const offset = offsets[graphicsIndex];\n if (graphic) {\n if (hasGraphicsTick(graphic)) {\n graphic === null || graphic === void 0 ? void 0 : graphic.tick(delta, this._token);\n }\n const offsetY = this.renderFromTopOfGraphic ? 0 : (graphic.height - this.tileHeight);\n graphic.draw(ctx, tile.x * this.tileWidth + offset.x, tile.y * this.tileHeight - offsetY + offset.y);\n }\n }\n }\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\n }\n debug(gfx, debugFlags) {\n const { showAll, showGrid, gridColor, gridWidth, showSolidBounds: showColliderBounds, solidBoundsColor: colliderBoundsColor, showColliderGeometry } = debugFlags.tilemap;\n const { geometryColor, geometryLineWidth, geometryPointSize } = debugFlags.collider;\n const width = this.tileWidth * this.columns * this.scale.x;\n const height = this.tileHeight * this.rows * this.scale.y;\n const pos = this.pos;\n if (showGrid || showAll) {\n for (let r = 0; r < this.rows + 1; r++) {\n const yOffset = vec(0, r * this.tileHeight * this.scale.y);\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), gridColor, gridWidth);\n }\n for (let c = 0; c < this.columns + 1; c++) {\n const xOffset = vec(c * this.tileWidth * this.scale.x, 0);\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), gridColor, gridWidth);\n }\n }\n if (showAll || showColliderBounds || showColliderGeometry) {\n const colliders = this._composite.getColliders();\n gfx.save();\n gfx.translate(this.pos.x, this.pos.y);\n gfx.scale(this.scale.x, this.scale.y);\n for (const collider of colliders) {\n const bounds = collider.localBounds;\n const pos = collider.worldPos.sub(this.pos);\n if (showColliderBounds) {\n gfx.drawRectangle(pos, bounds.width, bounds.height, colliderBoundsColor);\n }\n }\n gfx.restore();\n if (showColliderGeometry) {\n for (const collider of colliders) {\n collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize });\n }\n }\n }\n if (showAll || showColliderBounds) {\n gfx.save();\n gfx.z = 999;\n if (showColliderBounds) {\n for (let i = 0; i < this.tiles.length; i++) {\n this.tiles[i].bounds.draw(gfx);\n }\n }\n gfx.restore();\n }\n }\n}\n/**\n * TileMap Tile\n *\n * A light-weight object that occupies a space in a collision map. Generally\n * created by a [[TileMap]].\n *\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\n * of the sprites in the array so the last one will be drawn on top. You can\n * use transparency to create layers this way.\n */\nclass Tile extends Entity {\n /**\n * Return the world position of the top left corner of the tile\n */\n get pos() {\n if (this._posDirty) {\n this._recalculate();\n this._posDirty = false;\n }\n return this._pos;\n }\n /**\n * Width of the tile in pixels\n */\n get width() {\n return this._width;\n }\n /**\n * Height of the tile in pixels\n */\n get height() {\n return this._height;\n }\n /**\n * Wether this tile should be treated as solid by the tilemap\n */\n get solid() {\n return this._solid;\n }\n /**\n * Wether this tile should be treated as solid by the tilemap\n */\n set solid(val) {\n var _a;\n (_a = this.map) === null || _a === void 0 ? void 0 : _a.flagCollidersDirty();\n this._solid = val;\n }\n /**\n * Current list of graphics for this tile\n */\n getGraphics() {\n return this._graphics;\n }\n /**\n * Current list of offsets for this tile's graphics\n */\n getGraphicsOffsets() {\n return this._offsets;\n }\n /**\n * Add another [[Graphic]] to this TileMap tile\n * @param graphic\n */\n addGraphic(graphic, options) {\n this._graphics.push(graphic);\n if (options === null || options === void 0 ? void 0 : options.offset) {\n this._offsets.push(options.offset);\n }\n else {\n this._offsets.push(Vector.Zero);\n }\n }\n /**\n * Remove an instance of a [[Graphic]] from this tile\n */\n removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) {\n this._graphics.splice(index, 1);\n this._offsets.splice(index, 1);\n }\n }\n /**\n * Clear all graphics from this tile\n */\n clearGraphics() {\n this._graphics.length = 0;\n this._offsets.length = 0;\n }\n /**\n * Returns the list of colliders\n */\n getColliders() {\n return this._colliders;\n }\n /**\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\n *\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\n *\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\n * @param collider\n */\n addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\n * Removes a collider from the [[Tile]]\n * @param collider\n */\n removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) {\n this._colliders.splice(index, 1);\n }\n this.map.flagCollidersDirty();\n }\n /**\n * Clears all colliders from the [[Tile]]\n */\n clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n constructor(options) {\n var _a, _b;\n super();\n this._posDirty = false;\n this._solid = false;\n this._graphics = [];\n this._offsets = [];\n /**\n * Current list of colliders for this tile\n */\n this._colliders = [];\n /**\n * Arbitrary data storage per tile, useful for any game specific data\n */\n this.data = new Map();\n this.x = options.x;\n this.y = options.y;\n this.map = options.map;\n this._width = options.map.tileWidth * this.map.scale.x;\n this._height = options.map.tileHeight * this.map.scale.y;\n this.solid = (_a = options.solid) !== null && _a !== void 0 ? _a : this.solid;\n this._graphics = (_b = options.graphics) !== null && _b !== void 0 ? _b : [];\n this._recalculate();\n }\n flagDirty() {\n return this._posDirty = true;\n }\n _recalculate() {\n const geometryPos = this.map.pos.add(vec(this.x * this.map.tileWidth, this.y * this.map.tileHeight));\n this._geometry = new BoundingBox(geometryPos.x, geometryPos.y, geometryPos.x + this.map.tileWidth, geometryPos.y + this.map.tileHeight);\n this._width = this.map.tileWidth * this.map.scale.x;\n this._height = this.map.tileHeight * this.map.scale.y;\n this._pos = this.map.pos.add(vec(this.x * this._width, this.y * this._height));\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\n if (this.map.rotation) {\n this._bounds = this._bounds.rotate(this.map.rotation, this.map.pos);\n }\n this._posDirty = false;\n }\n /**\n * Tile bounds in world space\n */\n get bounds() {\n if (this._posDirty) {\n this._recalculate();\n }\n return this._bounds;\n }\n get defaultGeometry() {\n return this._geometry;\n }\n /**\n * Tile position in world space\n */\n get center() {\n if (this._posDirty) {\n this._recalculate();\n }\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\n }\n}\n\n;// CONCATENATED MODULE: ./Camera.ts\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Container to house convenience strategy methods\n * @internal\n */\nclass StrategyContainer {\n constructor(camera) {\n this.camera = camera;\n }\n /**\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\n * @param actor The actor to lock the camera to\n */\n lockToActor(actor) {\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\n }\n /**\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\n * @param actor The actor to lock the camera to\n * @param axis The axis to follow the actor on\n */\n lockToActorAxis(actor, axis) {\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\n }\n /**\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\n * correct and bounce around the target\n * @param actor Target actor to elastically follow\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\n */\n elasticToActor(actor, cameraElasticity, cameraFriction) {\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\n }\n /**\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\n * @param actor Target actor to follow when it is \"radius\" pixels away\n * @param radius Number of pixels away before the camera will follow\n */\n radiusAroundActor(actor, radius) {\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\n }\n /**\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\n * @param box The bounding box to limit the camera to.\n */\n limitCameraBounds(box) {\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\n }\n}\n/**\n * Camera axis enum\n */\nvar Axis;\n(function (Axis) {\n Axis[Axis[\"X\"] = 0] = \"X\";\n Axis[Axis[\"Y\"] = 1] = \"Y\";\n})(Axis || (Axis = {}));\n/**\n * Lock a camera to the exact x/y position of an actor.\n */\nclass LockCameraToActorStrategy {\n constructor(target) {\n this.target = target;\n this.action = (target, camera, engine, delta) => {\n const center = target.center;\n return center;\n };\n }\n}\n/**\n * Lock a camera to a specific axis around an actor.\n */\nclass LockCameraToActorAxisStrategy {\n constructor(target, axis) {\n this.target = target;\n this.axis = axis;\n this.action = (target, cam, _eng, _delta) => {\n const center = target.center;\n const currentFocus = cam.getFocus();\n if (this.axis === Axis.X) {\n return new Vector(center.x, currentFocus.y);\n }\n else {\n return new Vector(currentFocus.x, center.y);\n }\n };\n }\n}\n/**\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\n */\nclass ElasticToActorStrategy {\n /**\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\n * correct and bounce around the target\n * @param target Target actor to elastically follow\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\n */\n constructor(target, cameraElasticity, cameraFriction) {\n this.target = target;\n this.cameraElasticity = cameraElasticity;\n this.cameraFriction = cameraFriction;\n this.action = (target, cam, _eng, _delta) => {\n const position = target.center;\n let focus = cam.getFocus();\n let cameraVel = cam.vel.clone();\n // Calculate the stretch vector, using the spring equation\n // F = kX\n // https://en.wikipedia.org/wiki/Hooke's_law\n // Apply to the current camera velocity\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\n cameraVel = cameraVel.add(stretch);\n // Calculate the friction (-1 to apply a force in the opposition of motion)\n // Apply to the current camera velocity\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\n cameraVel = cameraVel.add(friction);\n // Update position by velocity deltas\n focus = focus.add(cameraVel);\n return focus;\n };\n }\n}\nclass RadiusAroundActorStrategy {\n /**\n *\n * @param target Target actor to follow when it is \"radius\" pixels away\n * @param radius Number of pixels away before the camera will follow\n */\n constructor(target, radius) {\n this.target = target;\n this.radius = radius;\n this.action = (target, cam, _eng, _delta) => {\n const position = target.center;\n const focus = cam.getFocus();\n const direction = position.sub(focus);\n const distance = direction.size;\n if (distance >= this.radius) {\n const offset = distance - this.radius;\n return focus.add(direction.normalize().scale(offset));\n }\n return focus;\n };\n }\n}\n/**\n * Prevent a camera from going beyond the given camera dimensions.\n */\nclass LimitCameraBoundsStrategy {\n constructor(target) {\n this.target = target;\n /**\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\n *\n * Note that this strategy does not perform any movement by itself.\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\n *\n * Make sure that the camera bounds are at least as large as the viewport size.\n * @param target The bounding box to limit the camera to\n */\n this.boundSizeChecked = false; // Check and warn only once\n this.action = (target, cam, _eng, _delta) => {\n const focus = cam.getFocus();\n if (!this.boundSizeChecked) {\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) {\n Logger.getInstance().warn('Camera bounds should not be smaller than the engine viewport');\n }\n this.boundSizeChecked = true;\n }\n let focusX = focus.x;\n let focusY = focus.y;\n if (focus.x < target.left + _eng.halfDrawWidth) {\n focusX = target.left + _eng.halfDrawWidth;\n }\n else if (focus.x > target.right - _eng.halfDrawWidth) {\n focusX = target.right - _eng.halfDrawWidth;\n }\n if (focus.y < target.top + _eng.halfDrawHeight) {\n focusY = target.top + _eng.halfDrawHeight;\n }\n else if (focus.y > target.bottom - _eng.halfDrawHeight) {\n focusY = target.bottom - _eng.halfDrawHeight;\n }\n return vec(focusX, focusY);\n };\n }\n}\nconst CameraEvents = {\n Initialize: 'initialize',\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate'\n};\n/**\n * Cameras\n *\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\n * to move around your game and set focus. They are used to determine\n * what is \"off screen\" and can be used to scale the game.\n *\n */\nclass Camera {\n constructor() {\n this.events = new EventEmitter();\n this.transform = AffineMatrix.identity();\n this.inverse = AffineMatrix.identity();\n this._cameraStrategies = [];\n this.strategy = new StrategyContainer(this);\n /**\n * Get or set current zoom of the camera, defaults to 1\n */\n this._z = 1;\n /**\n * Get or set rate of change in zoom, defaults to 0\n */\n this.dz = 0;\n /**\n * Get or set zoom acceleration\n */\n this.az = 0;\n /**\n * Current rotation of the camera\n */\n this.rotation = 0;\n this._angularVelocity = 0;\n /**\n * Get or set the camera's position\n */\n this._posChanged = false;\n this._pos = watchAny(Vector.Zero, () => (this._posChanged = true));\n /**\n * Interpolated camera position if more draws are running than updates\n *\n * Enabled when `Engine.fixedUpdateFps` is enabled, in all other cases this will be the same as pos\n */\n this.drawPos = this.pos.clone();\n this._oldPos = this.pos.clone();\n /**\n * Get or set the camera's velocity\n */\n this.vel = Vector.Zero;\n /**\n * Get or set the camera's acceleration\n */\n this.acc = Vector.Zero;\n this._cameraMoving = false;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = null;\n this._lerpEnd = null;\n //camera effects\n this._isShaking = false;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._elapsedShakeTime = 0;\n this._xShake = 0;\n this._yShake = 0;\n this._isZooming = false;\n this._zoomStart = 1;\n this._zoomEnd = 1;\n this._currentZoomTime = 0;\n this._zoomDuration = 0;\n this._zoomEasing = EasingFunctions.EaseInOutCubic;\n this._easing = EasingFunctions.EaseInOutCubic;\n this._halfWidth = 0;\n this._halfHeight = 0;\n this._viewport = null;\n this._isInitialized = false;\n this._snapPos = vec(0, 0);\n }\n get zoom() {\n return this._z;\n }\n set zoom(val) {\n this._z = val;\n if (this._engine) {\n this._halfWidth = this._engine.halfDrawWidth;\n this._halfHeight = this._engine.halfDrawHeight;\n }\n }\n /**\n * Get or set the camera's angular velocity\n */\n get angularVelocity() {\n return this._angularVelocity;\n }\n set angularVelocity(value) {\n this._angularVelocity = value;\n }\n get pos() {\n return this._pos;\n }\n set pos(vec) {\n this._pos = watchAny(vec, () => (this._posChanged = true));\n this._posChanged = true;\n }\n /**\n * Get the camera's x position\n */\n get x() {\n return this.pos.x;\n }\n /**\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\n */\n set x(value) {\n if (!this._follow && !this._cameraMoving) {\n this.pos = vec(value, this.pos.y);\n }\n }\n /**\n * Get the camera's y position\n */\n get y() {\n return this.pos.y;\n }\n /**\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\n */\n set y(value) {\n if (!this._follow && !this._cameraMoving) {\n this.pos = vec(this.pos.x, value);\n }\n }\n /**\n * Get or set the camera's x velocity\n */\n get dx() {\n return this.vel.x;\n }\n set dx(value) {\n this.vel = vec(value, this.vel.y);\n }\n /**\n * Get or set the camera's y velocity\n */\n get dy() {\n return this.vel.y;\n }\n set dy(value) {\n this.vel = vec(this.vel.x, value);\n }\n /**\n * Get or set the camera's x acceleration\n */\n get ax() {\n return this.acc.x;\n }\n set ax(value) {\n this.acc = vec(value, this.acc.y);\n }\n /**\n * Get or set the camera's y acceleration\n */\n get ay() {\n return this.acc.y;\n }\n set ay(value) {\n this.acc = vec(this.acc.x, value);\n }\n /**\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\n */\n getFocus() {\n return this.pos;\n }\n /**\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\n * @param pos The target position to move to\n * @param duration The duration in milliseconds the move should last\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\n */\n move(pos, duration, easingFn = EasingFunctions.EaseInOutCubic) {\n if (typeof easingFn !== 'function') {\n throw 'Please specify an EasingFunction';\n }\n // cannot move when following an actor\n if (this._follow) {\n return Promise.reject(pos);\n }\n // resolve existing promise, if any\n if (this._lerpPromise && this._lerpResolve) {\n this._lerpResolve(pos);\n }\n this._lerpPromise = new Promise((resolve) => {\n this._lerpResolve = resolve;\n });\n this._lerpStart = this.getFocus().clone();\n this._lerpDuration = duration;\n this._lerpEnd = pos;\n this._currentLerpTime = 0;\n this._cameraMoving = true;\n this._easing = easingFn;\n return this._lerpPromise;\n }\n /**\n * Sets the camera to shake at the specified magnitudes for the specified duration\n * @param magnitudeX The x magnitude of the shake\n * @param magnitudeY The y magnitude of the shake\n * @param duration The duration of the shake in milliseconds\n */\n shake(magnitudeX, magnitudeY, duration) {\n this._isShaking = true;\n this._shakeMagnitudeX = magnitudeX;\n this._shakeMagnitudeY = magnitudeY;\n this._shakeDuration = duration;\n }\n /**\n * Zooms the camera in or out by the specified scale over the specified duration.\n * If no duration is specified, it take effect immediately.\n * @param scale The scale of the zoom\n * @param duration The duration of the zoom in milliseconds\n */\n zoomOverTime(scale, duration = 0, easingFn = EasingFunctions.EaseInOutCubic) {\n this._zoomPromise = new Promise((resolve) => {\n this._zoomResolve = resolve;\n });\n if (duration) {\n this._isZooming = true;\n this._zoomEasing = easingFn;\n this._currentZoomTime = 0;\n this._zoomDuration = duration;\n this._zoomStart = this.zoom;\n this._zoomEnd = scale;\n }\n else {\n this._isZooming = false;\n this.zoom = scale;\n return Promise.resolve(true);\n }\n return this._zoomPromise;\n }\n /**\n * Gets the bounding box of the viewport of this camera in world coordinates\n */\n get viewport() {\n if (this._viewport) {\n return this._viewport;\n }\n return new BoundingBox(0, 0, 0, 0);\n }\n /**\n * Adds a new camera strategy to this camera\n * @param cameraStrategy Instance of an [[CameraStrategy]]\n */\n addStrategy(cameraStrategy) {\n this._cameraStrategies.push(cameraStrategy);\n }\n /**\n * Removes a camera strategy by reference\n * @param cameraStrategy Instance of an [[CameraStrategy]]\n */\n removeStrategy(cameraStrategy) {\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\n }\n /**\n * Clears all camera strategies from the camera\n */\n clearAllStrategies() {\n this._cameraStrategies.length = 0;\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */\n _preupdate(engine, delta) {\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before a scene is updated.\n */\n onPreUpdate(engine, delta) {\n // Overridable\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */\n _postupdate(engine, delta) {\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */\n onPostUpdate(engine, delta) {\n // Overridable\n }\n get isInitialized() {\n return this._isInitialized;\n }\n _initialize(engine) {\n if (!this.isInitialized) {\n this._engine = engine;\n this._screen = engine.screen;\n const currentRes = this._screen.contentArea;\n let center = vec(currentRes.width / 2, currentRes.height / 2);\n if (!this._engine.loadingComplete) {\n // If there was a loading screen, we peek the configured resolution\n const res = this._screen.peekResolution();\n if (res) {\n center = vec(res.width / 2, res.height / 2);\n }\n }\n this._halfWidth = center.x;\n this._halfHeight = center.y;\n // If the user has not set the camera pos, apply default center screen position\n if (!this._posChanged) {\n this.pos = center;\n }\n this.pos.clone(this.drawPos);\n // First frame bootstrap\n // Ensure camera tx is correct\n // Run update twice to ensure properties are init'd\n this.updateTransform(this.pos);\n // Run strategies for first frame\n this.runStrategies(engine, engine.clock.elapsed());\n // Setup the first frame viewport\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform(this.pos);\n this.pos.clone(this._oldPos);\n this.onInitialize(engine);\n this.events.emit('initialize', new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */\n onInitialize(engine) {\n // Overridable\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n runStrategies(engine, delta) {\n for (const s of this._cameraStrategies) {\n this.pos = s.action.call(s, s.target, this, engine, delta);\n }\n }\n updateViewport() {\n // recalculate viewport\n this._viewport = new BoundingBox(this.x - this._halfWidth, this.y - this._halfHeight, this.x + this._halfWidth, this.y + this._halfHeight);\n }\n update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this.pos.clone(this._oldPos);\n // Update placements based on linear algebra\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\n this.zoom += (this.dz * delta) / 1000;\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\n this.dz += (this.az * delta) / 1000;\n this.rotation += (this.angularVelocity * delta) / 1000;\n if (this._isZooming) {\n if (this._currentZoomTime < this._zoomDuration) {\n const zoomEasing = this._zoomEasing;\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\n this.zoom = newZoom;\n this._currentZoomTime += delta;\n }\n else {\n this._isZooming = false;\n this.zoom = this._zoomEnd;\n this._currentZoomTime = 0;\n this._zoomResolve(true);\n }\n }\n if (this._cameraMoving) {\n if (this._currentLerpTime < this._lerpDuration) {\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\n this.pos = lerpPoint;\n this._currentLerpTime += delta;\n }\n else {\n this.pos = this._lerpEnd;\n const end = this._lerpEnd.clone();\n this._lerpStart = null;\n this._lerpEnd = null;\n this._currentLerpTime = 0;\n this._cameraMoving = false;\n // Order matters here, resolve should be last so any chain promises have a clean slate\n this._lerpResolve(end);\n }\n }\n if (this._isDoneShaking()) {\n this._isShaking = false;\n this._elapsedShakeTime = 0;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._xShake = 0;\n this._yShake = 0;\n }\n else {\n this._elapsedShakeTime += delta;\n this._xShake = ((Math.random() * this._shakeMagnitudeX) | 0) + 1;\n this._yShake = ((Math.random() * this._shakeMagnitudeY) | 0) + 1;\n }\n this.runStrategies(engine, delta);\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform(this.pos);\n this._postupdate(engine, delta);\n }\n /**\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\n * @param ctx Canvas context to apply transformations\n */\n draw(ctx) {\n // default to the current position\n this.pos.clone(this.drawPos);\n // interpolation if fixed update is on\n // must happen on the draw, because more draws are potentially happening than updates\n if (this._engine.fixedUpdateFps) {\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n const interpolatedPos = this.pos.scale(blend).add(this._oldPos.scale(1.0 - blend));\n interpolatedPos.clone(this.drawPos);\n this.updateTransform(interpolatedPos);\n }\n // Snap camera to pixel\n if (ctx.snapToPixel) {\n const snapPos = this.drawPos.clone(this._snapPos);\n snapPos.x = ~~(snapPos.x + pixelSnapEpsilon * sign(snapPos.x));\n snapPos.y = ~~(snapPos.y + pixelSnapEpsilon * sign(snapPos.y));\n snapPos.clone(this.drawPos);\n this.updateTransform(snapPos);\n }\n ctx.multiply(this.transform);\n }\n updateTransform(pos) {\n // center the camera\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\n const cameraPos = vec(-pos.x + newCanvasWidth / 2 + this._xShake, -pos.y + newCanvasHeight / 2 + this._yShake);\n // Calculate camera transform\n this.transform.reset();\n this.transform.scale(this.zoom, this.zoom);\n // rotate about the focus\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\n this.transform.rotate(this.rotation);\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\n this.transform.translate(cameraPos.x, cameraPos.y);\n this.transform.inverse(this.inverse);\n }\n _isDoneShaking() {\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\n }\n}\n\n;// CONCATENATED MODULE: ./Trigger.ts\n\n\n\n\n\nconst TriggerEvents = {\n ExitTrigger: 'exit',\n EnterTrigger: 'enter'\n};\nconst triggerDefaults = {\n pos: Vector.Zero,\n width: 10,\n height: 10,\n visible: false,\n action: () => {\n return;\n },\n filter: () => true,\n repeat: -1\n};\n/**\n * Triggers are a method of firing arbitrary code on collision. These are useful\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\n */\nclass Trigger extends Actor {\n /**\n *\n * @param opts Trigger options\n */\n constructor(opts) {\n super({ x: opts.pos.x, y: opts.pos.y, width: opts.width, height: opts.height });\n this.events = new EventEmitter();\n /**\n * Action to fire when triggered by collision\n */\n this.action = () => {\n return;\n };\n /**\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\n * filter return true for the collided actor.\n */\n this.filter = () => true;\n /**\n * Number of times to repeat before killing the trigger,\n */\n this.repeat = -1;\n opts = {\n ...triggerDefaults,\n ...opts\n };\n this.filter = opts.filter || this.filter;\n this.repeat = opts.repeat || this.repeat;\n this.action = opts.action || this.action;\n if (opts.target) {\n this.target = opts.target;\n }\n this.graphics.visible = opts.visible;\n this.body.collisionType = CollisionType.Passive;\n this.events.on('collisionstart', (evt) => {\n if (this.filter(evt.other)) {\n this.events.emit('enter', new EnterTriggerEvent(this, evt.other));\n this._dispatchAction();\n // remove trigger if its done, -1 repeat forever\n if (this.repeat === 0) {\n this.kill();\n }\n }\n });\n this.events.on('collisionend', (evt) => {\n if (this.filter(evt.other)) {\n this.events.emit('exit', new ExitTriggerEvent(this, evt.other));\n }\n });\n }\n set target(target) {\n this._target = target;\n this.filter = (actor) => actor === target;\n }\n get target() {\n return this._target;\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n _dispatchAction() {\n if (this.repeat !== 0) {\n this.action.call(this);\n this.repeat--;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Priority.ts\n/**\n * Higher priorities run earlier than others in the system update\n */\nconst SystemPriority = {\n Highest: -Infinity,\n Higher: -5,\n Average: 0,\n Lower: 5,\n Lowest: Infinity\n};\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/System.ts\n\n/**\n * Enum that determines whether to run the system in the update or draw phase\n */\nvar SystemType;\n(function (SystemType) {\n SystemType[\"Update\"] = \"update\";\n SystemType[\"Draw\"] = \"draw\";\n})(SystemType || (SystemType = {}));\n/**\n * An Excalibur [[System]] that updates entities of certain types.\n * Systems are scene specific\n *\n *\n *\n * Excalibur Systems currently require at least 1 Component type to operated\n *\n * Multiple types are declared as a type union\n * For example:\n *\n * ```typescript\n * class MySystem extends System {\n * public readonly types = ['a', 'b'] as const;\n * public readonly systemType = SystemType.Update;\n * public update(entities: Entity) {\n * ...\n * }\n * }\n * ```\n */\nclass System {\n constructor() {\n /**\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\n * For a system to execute after all other a higher priority value (10 for example) must be set.\n */\n this.priority = SystemPriority.Average;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/EntityManager.ts\n\n\n// Add/Remove entities and components\nclass EntityManager {\n constructor(_world) {\n this._world = _world;\n this.entities = [];\n this._entityIndex = {};\n this._entitiesToRemove = [];\n }\n /**\n * Runs the entity lifecycle\n * @param scene\n * @param elapsed\n */\n updateEntities(scene, elapsed) {\n for (const entity of this.entities) {\n entity.update(scene.engine, elapsed);\n if (!entity.active) {\n this.removeEntity(entity);\n }\n }\n }\n findEntitiesForRemoval() {\n for (const entity of this.entities) {\n if (!entity.active) {\n this.removeEntity(entity);\n }\n }\n }\n /**\n * Adds an entity to be tracked by the EntityManager\n * @param entity\n */\n addEntity(entity) {\n entity.active = true;\n entity.scene = this._world.scene;\n if (entity && !this._entityIndex[entity.id]) {\n this._entityIndex[entity.id] = entity;\n this.entities.push(entity);\n this._world.queryManager.addEntity(entity);\n // if entity has children\n entity.children.forEach((c) => {\n c.scene = entity.scene;\n this.addEntity(c);\n });\n entity.childrenAdded$.register({\n notify: (e) => {\n this.addEntity(e);\n }\n });\n entity.childrenRemoved$.register({\n notify: (e) => {\n this.removeEntity(e, false);\n }\n });\n }\n }\n removeEntity(idOrEntity, deferred = true) {\n var _a, _b;\n let id = 0;\n if (idOrEntity instanceof Entity) {\n id = idOrEntity.id;\n }\n else {\n id = idOrEntity;\n }\n const entity = this._entityIndex[id];\n if (entity && entity.active) {\n entity.active = false;\n }\n if (entity && deferred) {\n this._entitiesToRemove.push(entity);\n return;\n }\n delete this._entityIndex[id];\n if (entity) {\n entity.scene = null;\n removeItemFromArray(entity, this.entities);\n this._world.queryManager.removeEntity(entity);\n // if entity has children\n entity.children.forEach((c) => {\n c.scene = null;\n this.removeEntity(c, deferred);\n });\n entity.childrenAdded$.clear();\n entity.childrenRemoved$.clear();\n // stats\n if ((_b = (_a = this._world) === null || _a === void 0 ? void 0 : _a.scene) === null || _b === void 0 ? void 0 : _b.engine) {\n this._world.scene.engine.stats.currFrame.actors.killed++;\n }\n }\n }\n processEntityRemovals() {\n for (const entity of this._entitiesToRemove) {\n if (entity.active) {\n continue;\n }\n this.removeEntity(entity, false);\n }\n this._entitiesToRemove.length = 0;\n }\n processComponentRemovals() {\n for (const entity of this.entities) {\n entity.processComponentRemoval();\n }\n }\n getById(id) {\n return this._entityIndex[id];\n }\n getByName(name) {\n return this.entities.filter(e => e.name === name);\n }\n clear() {\n for (let i = this.entities.length - 1; i >= 0; i--) {\n this.removeEntity(this.entities[i]);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Query.ts\n\n/**\n * Represents query for entities that match a list of types that is cached and observable\n *\n * Queries can be strongly typed by supplying a type union in the optional type parameter\n * ```typescript\n * const queryAB = new ex.Query(['A', 'B']);\n * ```\n */\nclass Query {\n constructor(requiredComponents) {\n this.requiredComponents = requiredComponents;\n this.components = new Set();\n this.entities = [];\n /**\n * This fires right after the component is added\n */\n this.entityAdded$ = new Observable();\n /**\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\n */\n this.entityRemoved$ = new Observable();\n if (requiredComponents.length === 0) {\n throw new Error('Cannot create query without components');\n }\n for (const type of requiredComponents) {\n this.components.add(type);\n }\n this.id = Query.createId(requiredComponents);\n }\n static createId(requiredComponents) {\n // TODO what happens if a user defines the same type name as a built in type\n // ! TODO this could be dangerous depending on the bundler's settings for names\n // Maybe some kind of hash function is better here?\n return requiredComponents.slice().map(c => c.name).sort().join('-');\n }\n /**\n * Potentially adds an entity to a query index, returns true if added, false if not\n * @param entity\n */\n checkAndAdd(entity) {\n if (!this.entities.includes(entity) && entity.hasAll(Array.from(this.components))) {\n this.entities.push(entity);\n this.entityAdded$.notifyAll(entity);\n return true;\n }\n return false;\n }\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index > -1) {\n this.entities.splice(index, 1);\n this.entityRemoved$.notifyAll(entity);\n }\n }\n /**\n * Returns a list of entities that match the query\n * @param sort Optional sorting function to sort entities returned from the query\n */\n getEntities(sort) {\n if (sort) {\n this.entities.sort(sort);\n }\n return this.entities;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/TagQuery.ts\n\nclass TagQuery {\n constructor(requiredTags) {\n this.requiredTags = requiredTags;\n this.tags = new Set();\n this.entities = [];\n /**\n * This fires right after the component is added\n */\n this.entityAdded$ = new Observable();\n /**\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\n */\n this.entityRemoved$ = new Observable();\n if (requiredTags.length === 0) {\n throw new Error('Cannot create tag query without tags');\n }\n for (const tag of requiredTags) {\n this.tags.add(tag);\n }\n this.id = TagQuery.createId(requiredTags);\n }\n static createId(requiredComponents) {\n return requiredComponents.slice().sort().join('-');\n }\n checkAndAdd(entity) {\n if (!this.entities.includes(entity) && entity.hasAllTags(Array.from(this.tags))) {\n this.entities.push(entity);\n this.entityAdded$.notifyAll(entity);\n return true;\n }\n return false;\n }\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index > -1) {\n this.entities.splice(index, 1);\n this.entityRemoved$.notifyAll(entity);\n }\n }\n /**\n * Returns a list of entities that match the query\n * @param sort Optional sorting function to sort entities returned from the query\n */\n getEntities(sort) {\n if (sort) {\n this.entities.sort(sort);\n }\n return this.entities;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/QueryManager.ts\n\n\n/**\n * The query manager is responsible for updating all queries when entities/components change\n */\nclass QueryManager {\n constructor(_world) {\n this._world = _world;\n this._queries = new Map();\n this._addComponentHandlers = new Map();\n this._removeComponentHandlers = new Map();\n this._componentToQueriesIndex = new Map();\n this._tagQueries = new Map();\n this._addTagHandlers = new Map();\n this._removeTagHandlers = new Map();\n this._tagToQueriesIndex = new Map();\n this._createAddComponentHandler = (entity) => (c) => {\n this.addComponent(entity, c);\n };\n this._createRemoveComponentHandler = (entity) => (c) => {\n this.removeComponent(entity, c);\n };\n this._createAddTagHandler = (entity) => (tag) => {\n this.addTag(entity, tag);\n };\n this._createRemoveTagHandler = (entity) => (tag) => {\n this.removeTag(entity, tag);\n };\n }\n createQuery(requiredComponents) {\n const id = Query.createId(requiredComponents);\n if (this._queries.has(id)) {\n // short circuit if query is already created\n return this._queries.get(id);\n }\n const query = new Query(requiredComponents);\n this._queries.set(query.id, query);\n // index maintenance\n for (const component of requiredComponents) {\n const queries = this._componentToQueriesIndex.get(component);\n if (!queries) {\n this._componentToQueriesIndex.set(component, [query]);\n }\n else {\n queries.push(query);\n }\n }\n for (const entity of this._world.entities) {\n this.addEntity(entity);\n }\n return query;\n }\n createTagQuery(requiredTags) {\n const id = TagQuery.createId(requiredTags);\n if (this._tagQueries.has(id)) {\n // short circuit if query is already created\n return this._tagQueries.get(id);\n }\n const query = new TagQuery(requiredTags);\n this._tagQueries.set(query.id, query);\n // index maintenance\n for (const tag of requiredTags) {\n const queries = this._tagToQueriesIndex.get(tag);\n if (!queries) {\n this._tagToQueriesIndex.set(tag, [query]);\n }\n else {\n queries.push(query);\n }\n }\n for (const entity of this._world.entities) {\n this.addEntity(entity);\n }\n return query;\n }\n /**\n * Scans queries and locates any that need this entity added\n * @param entity\n */\n addEntity(entity) {\n const maybeAddComponent = this._addComponentHandlers.get(entity);\n const maybeRemoveComponent = this._removeComponentHandlers.get(entity);\n const addComponent = maybeAddComponent !== null && maybeAddComponent !== void 0 ? maybeAddComponent : this._createAddComponentHandler(entity);\n const removeComponent = maybeRemoveComponent !== null && maybeRemoveComponent !== void 0 ? maybeRemoveComponent : this._createRemoveComponentHandler(entity);\n this._addComponentHandlers.set(entity, addComponent);\n this._removeComponentHandlers.set(entity, removeComponent);\n const maybeAddTag = this._addTagHandlers.get(entity);\n const maybeRemoveTag = this._removeTagHandlers.get(entity);\n const addTag = maybeAddTag !== null && maybeAddTag !== void 0 ? maybeAddTag : this._createAddTagHandler(entity);\n const removeTag = maybeRemoveTag !== null && maybeRemoveTag !== void 0 ? maybeRemoveTag : this._createRemoveTagHandler(entity);\n this._addTagHandlers.set(entity, addTag);\n this._removeTagHandlers.set(entity, removeTag);\n for (const query of this._queries.values()) {\n query.checkAndAdd(entity);\n }\n for (const tagQuery of this._tagQueries.values()) {\n tagQuery.checkAndAdd(entity);\n }\n entity.componentAdded$.subscribe(addComponent);\n entity.componentRemoved$.subscribe(removeComponent);\n entity.tagAdded$.subscribe(addTag);\n entity.tagRemoved$.subscribe(removeTag);\n }\n /**\n * Scans queries and locates any that need this entity removed\n * @param entity\n */\n removeEntity(entity) {\n // Handle components\n const addComponent = this._addComponentHandlers.get(entity);\n const removeComponent = this._removeComponentHandlers.get(entity);\n for (const query of this._queries.values()) {\n query.removeEntity(entity);\n }\n if (addComponent) {\n entity.componentAdded$.unsubscribe(addComponent);\n }\n if (removeComponent) {\n entity.componentRemoved$.unsubscribe(removeComponent);\n }\n // Handle tags\n const addTag = this._addTagHandlers.get(entity);\n const removeTag = this._removeTagHandlers.get(entity);\n for (const tagQuery of this._tagQueries.values()) {\n tagQuery.removeEntity(entity);\n }\n if (addTag) {\n entity.tagAdded$.unsubscribe(addTag);\n }\n if (removeTag) {\n entity.tagRemoved$.unsubscribe(removeTag);\n }\n }\n /**\n * Updates any queries when a component is added to an entity\n * @param entity\n * @param component\n */\n addComponent(entity, component) {\n var _a;\n const queries = (_a = this._componentToQueriesIndex.get(component.constructor)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries) {\n query.checkAndAdd(entity);\n }\n }\n /**\n * Updates any queries when a component is removed from an entity\n * @param entity\n * @param component\n */\n removeComponent(entity, component) {\n var _a;\n const queries = (_a = this._componentToQueriesIndex.get(component.constructor)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries) {\n query.removeEntity(entity);\n }\n }\n /**\n * Updates any queries when a tag is added to an entity\n * @param entity\n * @param tag\n */\n addTag(entity, tag) {\n var _a;\n const queries = (_a = this._tagToQueriesIndex.get(tag)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries) {\n query.checkAndAdd(entity);\n }\n }\n /**\n * Updates any queries when a component is removed from an entity\n * @param entity\n * @param tag\n */\n removeTag(entity, tag) {\n var _a;\n const queries = (_a = this._tagToQueriesIndex.get(tag)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries) {\n query.removeEntity(entity);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/SystemManager.ts\n\n\n/**\n *\n */\nfunction isSystemConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n}\n/**\n * The SystemManager is responsible for keeping track of all systems in a scene.\n * Systems are scene specific\n */\nclass SystemManager {\n constructor(_world) {\n this._world = _world;\n /**\n * List of systems, to add a new system call [[SystemManager.addSystem]]\n */\n this.systems = [];\n this.initialized = false;\n }\n /**\n * Get a system registered in the manager by type\n * @param systemType\n */\n get(systemType) {\n return this.systems.find((s) => s instanceof systemType);\n }\n /**\n * Adds a system to the manager, it will now be updated every frame\n * @param systemOrCtor\n */\n addSystem(systemOrCtor) {\n let system;\n if (systemOrCtor instanceof System) {\n system = systemOrCtor;\n }\n else {\n system = new systemOrCtor(this._world);\n }\n this.systems.push(system);\n this.systems.sort((a, b) => a.priority - b.priority);\n // If systems are added and the manager has already been init'd\n // then immediately init the system\n if (this.initialized && system.initialize) {\n system.initialize(this._world, this._world.scene);\n }\n }\n /**\n * Removes a system from the manager, it will no longer be updated\n * @param system\n */\n removeSystem(system) {\n removeItemFromArray(system, this.systems);\n }\n /**\n * Initialize all systems in the manager\n *\n * Systems added after initialize() will be initialized on add\n */\n initialize() {\n if (!this.initialized) {\n this.initialized = true;\n for (const s of this.systems) {\n if (s.initialize) {\n s.initialize(this._world, this._world.scene);\n }\n }\n }\n }\n /**\n * Updates all systems\n * @param type whether this is an update or draw system\n * @param scene context reference\n * @param delta time in milliseconds\n */\n updateSystems(type, scene, delta) {\n const systems = this.systems.filter((s) => s.systemType === type);\n for (const s of systems) {\n if (s.preupdate) {\n s.preupdate(scene, delta);\n }\n }\n for (const s of systems) {\n s.update(delta);\n }\n for (const s of systems) {\n if (s.postupdate) {\n s.postupdate(scene, delta);\n }\n }\n }\n clear() {\n for (let i = this.systems.length - 1; i >= 0; i--) {\n this.removeSystem(this.systems[i]);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/World.ts\n\n\n\n\n\n/**\n * The World is a self-contained entity component system for a particular context.\n */\nclass World {\n /**\n * The context type is passed to the system updates\n * @param scene\n */\n constructor(scene) {\n this.scene = scene;\n this.queryManager = new QueryManager(this);\n this.entityManager = new EntityManager(this);\n this.systemManager = new SystemManager(this);\n }\n /**\n * Query the ECS world for entities that match your components\n * @param requiredTypes\n */\n query(requiredTypes) {\n return this.queryManager.createQuery(requiredTypes);\n }\n queryTags(requiredTags) {\n return this.queryManager.createTagQuery(requiredTags);\n }\n /**\n * Update systems by type and time elapsed in milliseconds\n */\n update(type, delta) {\n if (type === SystemType.Update) {\n this.entityManager.updateEntities(this.scene, delta);\n }\n this.systemManager.updateSystems(type, this.scene, delta);\n this.entityManager.findEntitiesForRemoval();\n this.entityManager.processComponentRemovals();\n this.entityManager.processEntityRemovals();\n }\n add(entityOrSystem) {\n if (entityOrSystem instanceof Entity) {\n this.entityManager.addEntity(entityOrSystem);\n }\n if (entityOrSystem instanceof System || isSystemConstructor(entityOrSystem)) {\n this.systemManager.addSystem(entityOrSystem);\n }\n }\n /**\n * Get a system out of the ECS world\n */\n get(system) {\n return this.systemManager.get(system);\n }\n remove(entityOrSystem, deferred = true) {\n if (entityOrSystem instanceof Entity) {\n this.entityManager.removeEntity(entityOrSystem, deferred);\n }\n if (entityOrSystem instanceof System) {\n this.systemManager.removeSystem(entityOrSystem);\n }\n }\n get entities() {\n return this.entityManager.entities;\n }\n clearEntities() {\n this.entityManager.clear();\n }\n clearSystems() {\n this.systemManager.clear();\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Integrator.ts\n\nclass EulerIntegrator {\n static integrate(transform, motion, totalAcc, elapsedMs) {\n const seconds = elapsedMs / 1000;\n // This code looks a little wild, but it's to avoid creating any new Vector instances\n // integration is done in a tight loop so this is key to avoid GC'ing\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\n transform.pos\n .add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS)\n .addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\n const rotation = transform.rotation + motion.angularVelocity * seconds;\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\n const tx = transform.get();\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\n }\n}\n// Scratch vectors to avoid allocation\nEulerIntegrator._POS = new Vector(0, 0);\nEulerIntegrator._SCALE = new Vector(1, 1);\nEulerIntegrator._ACC = new Vector(0, 0);\nEulerIntegrator._VEL = new Vector(0, 0);\nEulerIntegrator._VEL_ACC = new Vector(0, 0);\nEulerIntegrator._SCALE_FACTOR = new Vector(0, 0);\n\n;// CONCATENATED MODULE: ./Collision/MotionSystem.ts\n\n\n\n\n\n\n\nclass MotionSystem extends System {\n constructor(world, physics) {\n super();\n this.world = world;\n this.physics = physics;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._physicsConfigDirty = false;\n physics.$configUpdate.subscribe(() => this._physicsConfigDirty = true);\n this.query = this.world.query([TransformComponent, MotionComponent]);\n }\n update(elapsedMs) {\n let transform;\n let motion;\n const entities = this.query.entities;\n for (let i = 0; i < entities.length; i++) {\n transform = entities[i].get(TransformComponent);\n motion = entities[i].get(MotionComponent);\n const optionalBody = entities[i].get(BodyComponent);\n if (this._physicsConfigDirty && optionalBody) {\n optionalBody.updatePhysicsConfig(this.physics.config.bodies);\n }\n if (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.sleeping) {\n continue;\n }\n const totalAcc = motion.acc.clone();\n if ((optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.collisionType) === CollisionType.Active && (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.useGravity)) {\n totalAcc.addEqual(this.physics.config.gravity);\n }\n optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.captureOldTransform();\n // Update transform and motion based on Euler linear algebra\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Solver/ArcadeSolver.ts\n\n\n\n\n\n/**\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\n * and negates velocity along the collision normal.\n *\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\n *\n */\nclass ArcadeSolver {\n constructor(config) {\n this.config = config;\n this.directionMap = new Map();\n this.distanceMap = new Map();\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter(c => !c.isCanceled());\n // Locate collision bias order\n let bias;\n switch (this.config.contactSolveBias) {\n case ContactSolveBias.HorizontalFirst: {\n bias = HorizontalFirst;\n break;\n }\n case ContactSolveBias.VerticalFirst: {\n bias = VerticalFirst;\n break;\n }\n default: {\n bias = None;\n }\n }\n // Sort by bias (None, VerticalFirst, HorizontalFirst) to avoid artifacts with seams\n // Sort contacts by distance to avoid artifacts with seams\n // It's important to solve in a specific order\n contacts.sort((a, b) => {\n const aDir = this.directionMap.get(a.id);\n const bDir = this.directionMap.get(b.id);\n const aDist = this.distanceMap.get(a.id);\n const bDist = this.distanceMap.get(b.id);\n return (bias[aDir] - bias[bDir]) || (aDist - bDist);\n });\n for (const contact of contacts) {\n // Solve position first in arcade\n this.solvePosition(contact);\n // Solve velocity second in arcade\n this.solveVelocity(contact);\n }\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n const epsilon = .0001;\n for (const contact of contacts) {\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\n this.distanceMap.set(contact.id, distance);\n this.directionMap.set(contact.id, side === Side.Left || side === Side.Right ? 'horizontal' : 'vertical');\n // Publish collision events on both participants\n contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\n contact.colliderB.events.emit('precollision', new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact));\n }\n }\n postSolve(contacts) {\n var _a, _b;\n for (const contact of contacts) {\n if (contact.isCanceled()) {\n continue;\n }\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n continue;\n }\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n // Publish collision events on both participants\n contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\n contact.colliderB.events.emit('postcollision', new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact));\n }\n }\n solvePosition(contact) {\n var _a, _b;\n const epsilon = .0001;\n // if bounds no longer intersect skip to the next\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\n // Cancel the contact to prevent and solving\n contact.cancel();\n return;\n }\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n return;\n }\n let mtv = contact.mtv;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n return;\n }\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) {\n // split overlaps if both are Active\n mtv = mtv.scale(0.5);\n }\n // Resolve overlaps\n if (bodyA.collisionType === CollisionType.Active) {\n bodyA.globalPos.x -= mtv.x;\n bodyA.globalPos.y -= mtv.y;\n colliderA.update(bodyA.transform.get());\n }\n if (bodyB.collisionType === CollisionType.Active) {\n bodyB.globalPos.x += mtv.x;\n bodyB.globalPos.y += mtv.y;\n colliderB.update(bodyB.transform.get());\n }\n }\n }\n solveVelocity(contact) {\n var _a, _b;\n if (contact.isCanceled()) {\n return;\n }\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n return;\n }\n const normal = contact.normal;\n const opposite = normal.negate();\n if (bodyA.collisionType === CollisionType.Active) {\n // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform when sliding off\n if (bodyA.vel.normalize().dot(opposite) < 0) {\n // Cancel out velocity opposite direction of collision normal\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\n bodyA.vel = bodyA.vel.add(velAdj);\n }\n }\n if (bodyB.collisionType === CollisionType.Active) {\n // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform\n if (bodyB.vel.normalize().dot(normal) < 0) {\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\n bodyB.vel = bodyB.vel.add(velAdj);\n }\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Solver/ContactConstraintPoint.ts\n\n\n/**\n * Holds information about contact points, meant to be reused over multiple frames of contact\n */\nclass ContactConstraintPoint {\n constructor(point, local, contact) {\n this.point = point;\n this.local = local;\n this.contact = contact;\n /**\n * Impulse accumulated over time in normal direction\n */\n this.normalImpulse = 0;\n /**\n * Impulse accumulated over time in the tangent direction\n */\n this.tangentImpulse = 0;\n /**\n * Effective mass seen in the normal direction\n */\n this.normalMass = 0;\n /**\n * Effective mass seen in the tangent direction\n */\n this.tangentMass = 0;\n /**\n * Direction from center of mass of bodyA to contact point\n */\n this.aToContact = new Vector(0, 0);\n /**\n * Direction from center of mass of bodyB to contact point\n */\n this.bToContact = new Vector(0, 0);\n /**\n * Original contact velocity combined with bounciness\n */\n this.originalVelocityAndRestitution = 0;\n this.update();\n }\n /**\n * Updates the contact information\n */\n update() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const normal = this.contact.normal;\n const tangent = this.contact.tangent;\n this.aToContact = this.point.sub(bodyA.globalPos);\n this.bToContact = this.point.sub(bodyB.globalPos);\n const aToContactNormal = this.aToContact.cross(normal);\n const bToContactNormal = this.bToContact.cross(normal);\n this.normalMass =\n bodyA.inverseMass +\n bodyB.inverseMass +\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = this.aToContact.cross(tangent);\n const bToContactTangent = this.bToContact.cross(tangent);\n this.tangentMass =\n bodyA.inverseMass +\n bodyB.inverseMass +\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n }\n return this;\n }\n /**\n * Returns the relative velocity between bodyA and bodyB\n */\n getRelativeVelocity() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Relative velocity in linear terms\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\n return velB.sub(velA);\n }\n return Vector.Zero;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Solver/RealisticSolver.ts\n\n\n\n\n\n\n\nclass RealisticSolver {\n constructor(config) {\n this.config = config;\n this.lastFrameContacts = new Map();\n // map contact id to contact points\n this.idToContactConstraint = new Map();\n }\n getContactConstraints(id) {\n var _a;\n return (_a = this.idToContactConstraint.get(id)) !== null && _a !== void 0 ? _a : [];\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter(c => !c.isCanceled());\n // Solve velocity first\n this.solveVelocity(contacts);\n // Solve position last because non-overlap is the most important\n this.solvePosition(contacts);\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n var _a, _b, _c;\n const epsilon = .0001;\n for (const contact of contacts) {\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderA.events.emit('beforecollisionresolve', new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit('precollision', new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n contact.colliderB.events.emit('beforecollisionresolve', new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n // Match awake state for sleeping\n contact.matchAwake();\n }\n // Keep track of contacts that done\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\n for (const contact of contacts) {\n // Remove all current contacts that are not done\n const index = finishedContactIds.indexOf(contact.id);\n if (index > -1) {\n finishedContactIds.splice(index, 1);\n }\n const contactPoints = (_a = this.idToContactConstraint.get(contact.id)) !== null && _a !== void 0 ? _a : [];\n let pointIndex = 0;\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n for (const point of contact.points) {\n const normal = contact.normal;\n const tangent = contact.tangent;\n const aToContact = point.sub(bodyA.globalPos);\n const bToContact = point.sub(bodyB.globalPos);\n const aToContactNormal = aToContact.cross(normal);\n const bToContactNormal = bToContact.cross(normal);\n const normalMass = bodyA.inverseMass +\n bodyB.inverseMass +\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = aToContact.cross(tangent);\n const bToContactTangent = bToContact.cross(tangent);\n const tangentMass = bodyA.inverseMass +\n bodyB.inverseMass +\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n // Preserve normal/tangent impulse by re-using the contact point if it's close\n if (contactPoints[pointIndex] && ((_c = (_b = contactPoints[pointIndex]) === null || _b === void 0 ? void 0 : _b.point) === null || _c === void 0 ? void 0 : _c.squareDistance(point)) < 4) {\n contactPoints[pointIndex].point = point;\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\n }\n else {\n // new contact if it's not close or doesn't exist\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\n }\n // Update contact point calculations\n contactPoints[pointIndex].aToContact = aToContact;\n contactPoints[pointIndex].bToContact = bToContact;\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\n // Calculate relative velocity before solving to accurately do restitution\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\n if (relativeVelocity < -0.1) { // TODO what's a good threshold here?\n contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\n }\n pointIndex++;\n }\n }\n this.idToContactConstraint.set(contact.id, contactPoints);\n }\n // Clean up any contacts that did not occur last frame\n for (const id of finishedContactIds) {\n this.idToContactConstraint.delete(id);\n }\n // Warm contacts with accumulated impulse\n // Useful for tall stacks\n if (this.config.warmStart) {\n this.warmStart(contacts);\n }\n else {\n for (const contact of contacts) {\n const contactPoints = this.getContactConstraints(contact.id);\n for (const point of contactPoints) {\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n }\n postSolve(contacts) {\n for (const contact of contacts) {\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip post solve for active+passive collisions\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n continue;\n }\n // Update motion values for sleeping\n bodyA.updateMotion();\n bodyB.updateMotion();\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderA.events.emit('aftercollisionresolve', new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit('postcollision', new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n contact.colliderB.events.emit('aftercollisionresolve', new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n }\n // Store contacts\n this.lastFrameContacts.clear();\n for (const c of contacts) {\n this.lastFrameContacts.set(c.id, c);\n }\n }\n /**\n * Warm up body's based on previous frame contact points\n * @param contacts\n */\n warmStart(contacts) {\n var _a, _b, _c;\n for (const contact of contacts) {\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const contactPoints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of contactPoints) {\n if (this.config.warmStart) {\n const normalImpulse = contact.normal.scale(point.normalImpulse);\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\n const impulse = normalImpulse.add(tangentImpulse);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n else {\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n }\n }\n /**\n * Iteratively solve the position overlap constraint\n * @param contacts\n */\n solvePosition(contacts) {\n var _a, _b, _c;\n for (let i = 0; i < this.config.positionIterations; i++) {\n for (const contact of contacts) {\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n continue;\n }\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of constraints) {\n const normal = contact.normal;\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\n const steeringConstant = this.config.steeringFactor; //0.2;\n const maxCorrection = -5;\n const slop = this.config.slop; //1;\n // Clamp to avoid over-correction\n // Remember that we are shooting for 0 overlap in the end\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\n const impulse = normal.scale(-steeringForce * point.normalMass);\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\n // We adjust position and rotation instead of doing the velocity\n if (bodyA.collisionType === CollisionType.Active) {\n // TODO make applyPseudoImpulse function?\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\n impulseForce.x = 0;\n }\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\n impulseForce.y = 0;\n }\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\n }\n }\n if (bodyB.collisionType === CollisionType.Active) {\n const impulseForce = impulse.scale(bodyB.inverseMass);\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\n impulseForce.x = 0;\n }\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\n impulseForce.y = 0;\n }\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\n }\n }\n }\n }\n }\n }\n }\n solveVelocity(contacts) {\n var _a, _b, _c;\n for (let i = 0; i < this.config.velocityIterations; i++) {\n for (const contact of contacts) {\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n continue;\n }\n const friction = Math.min(bodyA.friction, bodyB.friction);\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n // Friction constraint\n for (const point of constraints) {\n const relativeVelocity = point.getRelativeVelocity();\n // Negate velocity in tangent direction to simulate friction\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\n let impulseDelta = tangentVelocity * point.tangentMass;\n // Clamping based in Erin Catto's GDC 2006 talk\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\n // But deltas can vary\n const maxFriction = friction * point.normalImpulse;\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\n impulseDelta = newImpulse - point.tangentImpulse;\n point.tangentImpulse = newImpulse;\n const impulse = contact.tangent.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n // Bounce constraint\n for (const point of constraints) {\n // Need to recalc relative velocity because the previous step could have changed vel\n const relativeVelocity = point.getRelativeVelocity();\n // Compute impulse in normal direction\n const normalVelocity = relativeVelocity.dot(contact.normal);\n // Per Erin it is a mistake to apply the restitution inside the iteration\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\n // Clamping based in Erin Catto's GDC 2014 talk\n // Accumulated impulse stored in the contact is always positive (dV > 0)\n // But deltas can be negative\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\n impulseDelta = newImpulse - point.normalImpulse;\n point.normalImpulse = newImpulse;\n const impulse = contact.normal.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n }\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/CollisionSystem.ts\n\n\n\n\n\n\n\n\n\n\n\nclass CollisionSystem extends System {\n get _processor() {\n return this._physics.collisionProcessor;\n }\n ;\n constructor(world, _physics) {\n super();\n this._physics = _physics;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._configDirty = false;\n this._lastFrameContacts = new Map();\n this._currentFrameContacts = new Map();\n this._arcadeSolver = new ArcadeSolver(_physics.config.arcade);\n this._realisticSolver = new RealisticSolver(_physics.config.realistic);\n this._physics.$configUpdate.subscribe(() => this._configDirty = true);\n this._trackCollider = (c) => this._processor.track(c);\n this._untrackCollider = (c) => this._processor.untrack(c);\n this.query = world.query([TransformComponent, MotionComponent, ColliderComponent]);\n this.query.entityAdded$.subscribe(e => {\n const colliderComponent = e.get(ColliderComponent);\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\n const collider = colliderComponent.get();\n if (collider) {\n this._processor.track(collider);\n }\n });\n this.query.entityRemoved$.subscribe(e => {\n const colliderComponent = e.get(ColliderComponent);\n const collider = colliderComponent.get();\n if (colliderComponent && collider) {\n this._processor.untrack(collider);\n }\n });\n }\n initialize(world, scene) {\n this._engine = scene.engine;\n }\n update(elapsedMs) {\n var _a, _b, _c, _d;\n if (!this._physics.config.enabled) {\n return;\n }\n // Collect up all the colliders and update them\n let colliders = [];\n for (const entity of this.query.entities) {\n const colliderComp = entity.get(ColliderComponent);\n const collider = colliderComp === null || colliderComp === void 0 ? void 0 : colliderComp.get();\n if (colliderComp && ((_a = colliderComp.owner) === null || _a === void 0 ? void 0 : _a.active) && collider) {\n colliderComp.update();\n if (collider instanceof CompositeCollider) {\n const compositeColliders = collider.getColliders();\n if (!collider.compositeStrategy) {\n collider.compositeStrategy = this._physics.config.colliders.compositeStrategy;\n }\n colliders = colliders.concat(compositeColliders);\n }\n else {\n colliders.push(collider);\n }\n }\n }\n // Update the spatial partitioning data structures\n // TODO if collider invalid it will break the processor\n // TODO rename \"update\" to something more specific\n this._processor.update(colliders);\n // Run broadphase on all colliders and locates potential collisions\n const pairs = this._processor.broadphase(colliders, elapsedMs);\n this._currentFrameContacts.clear();\n // Given possible pairs find actual contacts\n let contacts = this._processor.narrowphase(pairs, (_d = (_c = (_b = this._engine) === null || _b === void 0 ? void 0 : _b.debug) === null || _c === void 0 ? void 0 : _c.stats) === null || _d === void 0 ? void 0 : _d.currFrame);\n const solver = this.getSolver();\n // Solve, this resolves the position/velocity so entities aren't overlapping\n contacts = solver.solve(contacts);\n // Record contacts for start/end\n for (const contact of contacts) {\n if (contact.isCanceled()) {\n continue;\n }\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\n const index = contact.id.indexOf('|');\n if (index > 0) {\n const compositeId = contact.id.substring(index + 1);\n this._currentFrameContacts.set(compositeId, contact);\n }\n else {\n this._currentFrameContacts.set(contact.id, contact);\n }\n }\n // Emit contact start/end events\n this.runContactStartEnd();\n // reset the last frame cache\n this._lastFrameContacts.clear();\n // Keep track of collisions contacts that have started or ended\n this._lastFrameContacts = new Map(this._currentFrameContacts);\n // Process deferred collider removals\n for (const entity of this.query.entities) {\n const collider = entity.get(ColliderComponent);\n if (collider) {\n collider.processColliderRemoval();\n }\n }\n }\n getSolver() {\n if (this._configDirty) {\n this._configDirty = false;\n this._arcadeSolver = new ArcadeSolver(this._physics.config.arcade);\n this._realisticSolver = new RealisticSolver(this._physics.config.realistic);\n }\n return this._physics.config.solver === SolverStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\n }\n debug(ex) {\n this._processor.debug(ex);\n }\n runContactStartEnd() {\n // If composite colliders are 'together' collisions may have a duplicate id because we want to treat those as a singular start/end\n for (const [id, c] of this._currentFrameContacts) {\n // find all new contacts\n if (!this._lastFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n const side = Side.fromDirection(c.mtv);\n const opposite = Side.getOpposite(side);\n colliderA.events.emit('collisionstart', new CollisionStartEvent(colliderA, colliderB, side, c));\n colliderA.events.emit('contactstart', new ContactStartEvent(colliderA, colliderB, side, c));\n colliderB.events.emit('collisionstart', new CollisionStartEvent(colliderB, colliderA, opposite, c));\n colliderB.events.emit('contactstart', new ContactStartEvent(colliderB, colliderA, opposite, c));\n }\n }\n // find all contacts that have ceased\n for (const [id, c] of this._lastFrameContacts) {\n if (!this._currentFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n const side = Side.fromDirection(c.mtv);\n const opposite = Side.getOpposite(side);\n colliderA.events.emit('collisionend', new CollisionEndEvent(colliderA, colliderB, side, c));\n colliderA.events.emit('contactend', new ContactEndEvent(colliderA, colliderB, side, c));\n colliderB.events.emit('collisionend', new CollisionEndEvent(colliderB, colliderA, opposite, c));\n colliderB.events.emit('contactend', new ContactEndEvent(colliderB, colliderA, opposite, c));\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Animation.ts\n\n\n\n\nvar AnimationDirection;\n(function (AnimationDirection) {\n /**\n * Animation is playing forwards\n */\n AnimationDirection[\"Forward\"] = \"forward\";\n /**\n * Animation is playing backwards\n */\n AnimationDirection[\"Backward\"] = \"backward\";\n})(AnimationDirection || (AnimationDirection = {}));\nvar AnimationStrategy;\n(function (AnimationStrategy) {\n /**\n * Animation ends without displaying anything\n */\n AnimationStrategy[\"End\"] = \"end\";\n /**\n * Animation loops to the first frame after the last frame\n */\n AnimationStrategy[\"Loop\"] = \"loop\";\n /**\n * Animation plays to the last frame, then backwards to the first frame, then repeats\n */\n AnimationStrategy[\"PingPong\"] = \"pingpong\";\n /**\n * Animation ends stopping on the last frame\n */\n AnimationStrategy[\"Freeze\"] = \"freeze\";\n})(AnimationStrategy || (AnimationStrategy = {}));\nconst AnimationEvents = {\n Frame: 'frame',\n Loop: 'loop',\n End: 'end'\n};\n/**\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\n *\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\n */\nclass Animation extends Graphic {\n constructor(options) {\n var _a, _b, _c;\n super(options);\n this.events = new EventEmitter();\n this.frames = [];\n this.strategy = AnimationStrategy.Loop;\n this.frameDuration = 100;\n this._idempotencyToken = -1;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = 0;\n this._pingPongDirection = 1;\n this._done = false;\n this._playing = true;\n this._speed = 1;\n this._reversed = false;\n this.frames = options.frames;\n this.speed = (_a = options.speed) !== null && _a !== void 0 ? _a : this.speed;\n this.strategy = (_b = options.strategy) !== null && _b !== void 0 ? _b : this.strategy;\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : (_c = options.frameDuration) !== null && _c !== void 0 ? _c : this.frameDuration;\n if (options.reverse) {\n this.reverse();\n }\n this.goToFrame(0);\n }\n clone() {\n return new Animation({\n frames: this.frames.map((f) => ({ ...f })),\n frameDuration: this.frameDuration,\n speed: this.speed,\n reverse: this._reversed,\n strategy: this.strategy,\n ...this.cloneGraphicOptions()\n });\n }\n get width() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) {\n return Math.abs(maybeFrame.graphic.width * this.scale.x);\n }\n return 0;\n }\n get height() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) {\n return Math.abs(maybeFrame.graphic.height * this.scale.y);\n }\n return 0;\n }\n /**\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\n * and optional [[AnimationStrategy]]\n *\n * Example:\n * ```typescript\n * const spriteSheet = SpriteSheet.fromImageSource({...});\n *\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\n * ```\n * @param spriteSheet\n * @param frameIndices\n * @param durationPerFrameMs\n * @param strategy\n */\n static fromSpriteSheet(spriteSheet, frameIndices, durationPerFrameMs, strategy = AnimationStrategy.Loop) {\n const maxIndex = spriteSheet.sprites.length - 1;\n const invalidIndices = frameIndices.filter((index) => index < 0 || index > maxIndex);\n if (invalidIndices.length) {\n Animation._LOGGER.warn(`Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(',')} no frame will be shown`);\n }\n return new Animation({\n frames: spriteSheet.sprites\n .filter((_, index) => frameIndices.indexOf(index) > -1)\n .map((f) => ({\n graphic: f,\n duration: durationPerFrameMs\n })),\n strategy: strategy\n });\n }\n /**\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\n *\n * Example:\n * ```typescript\n * const spriteSheet = SpriteSheet.fromImageSource({...});\n *\n * const anim = Animation.fromSpriteSheetCoordinates({\n * spriteSheet,\n * frameCoordinates: [\n * {x: 0, y: 5, duration: 100, options { flipHorizontal: true }},\n * {x: 1, y: 5, duration: 200},\n * {x: 2, y: 5, duration: 100},\n * {x: 3, y: 5, duration: 500}\n * ],\n * strategy: AnimationStrategy.PingPong\n * });\n * ```\n * @param options\n * @returns Animation\n */\n static fromSpriteSheetCoordinates(options) {\n const { spriteSheet, frameCoordinates, durationPerFrameMs, speed, strategy, reverse } = options;\n const defaultDuration = durationPerFrameMs !== null && durationPerFrameMs !== void 0 ? durationPerFrameMs : 100;\n const frames = [];\n for (const coord of frameCoordinates) {\n const { x, y, duration, options } = coord;\n const sprite = spriteSheet.getSprite(x, y, options);\n if (sprite) {\n frames.push({\n graphic: sprite,\n duration: duration !== null && duration !== void 0 ? duration : defaultDuration\n });\n }\n else {\n Animation._LOGGER.warn(`Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`);\n }\n }\n return new Animation({\n frames,\n strategy,\n speed,\n reverse\n });\n }\n /**\n * Current animation speed\n *\n * 1 meaning normal 1x speed.\n * 2 meaning 2x speed and so on.\n */\n get speed() {\n return this._speed;\n }\n /**\n * Current animation speed\n *\n * 1 meaning normal 1x speed.\n * 2 meaning 2x speed and so on.\n */\n set speed(val) {\n this._speed = clamp(Math.abs(val), 0, Infinity);\n }\n /**\n * Returns the current Frame of the animation\n *\n * Use [[Animation.currentFrameIndex]] to get the frame number and\n * [[Animation.goToFrame]] to set the current frame index\n */\n get currentFrame() {\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) {\n return this.frames[this._currentFrame];\n }\n return null;\n }\n /**\n * Returns the current frame index of the animation\n *\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\n */\n get currentFrameIndex() {\n return this._currentFrame;\n }\n /**\n * Returns the amount of time in milliseconds left in the current frame\n */\n get currentFrameTimeLeft() {\n return this._timeLeftInFrame;\n }\n /**\n * Returns `true` if the animation is playing\n */\n get isPlaying() {\n return this._playing;\n }\n /**\n * Reverses the play direction of the Animation, this preserves the current frame\n */\n reverse() {\n // Don't mutate with the original frame list, create a copy\n this.frames = this.frames.slice().reverse();\n this._reversed = !this._reversed;\n }\n /**\n * Returns the current play direction of the animation\n */\n get direction() {\n // Keep logically consistent with ping-pong direction\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\n const reversed = (this._reversed && this._pingPongDirection === 1) ? true : false;\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\n }\n /**\n * Plays or resumes the animation from the current frame\n */\n play() {\n this._playing = true;\n }\n /**\n * Pauses the animation on the current frame\n */\n pause() {\n this._playing = false;\n this._firstTick = true; // firstTick must be set to emit the proper frame event\n }\n /**\n * Reset the animation back to the beginning, including if the animation were done\n */\n reset() {\n this._done = false;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame) {\n this._timeLeftInFrame = ((maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration);\n }\n }\n /**\n * Returns `true` if the animation can end\n */\n get canFinish() {\n switch (this.strategy) {\n case AnimationStrategy.End:\n case AnimationStrategy.Freeze: {\n return true;\n }\n default: {\n return false;\n }\n }\n }\n /**\n * Returns `true` if the animation is done, for looping type animations\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\n *\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\n */\n get done() {\n return this._done;\n }\n /**\n * Jump the animation immediately to a specific frame if it exists\n *\n * Optionally specify an override for the duration of the frame, useful for\n * keeping multiple animations in sync with one another.\n * @param frameNumber\n * @param duration\n */\n goToFrame(frameNumber, duration) {\n this._currentFrame = frameNumber;\n this._timeLeftInFrame = duration !== null && duration !== void 0 ? duration : this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame && !this._done) {\n this._timeLeftInFrame = duration !== null && duration !== void 0 ? duration : ((maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration);\n this.events.emit('frame', { ...maybeFrame, frameIndex: this.currentFrameIndex });\n }\n }\n _nextFrame() {\n const currentFrame = this._currentFrame;\n if (this._done) {\n return currentFrame;\n }\n let next = -1;\n switch (this.strategy) {\n case AnimationStrategy.Loop: {\n next = (currentFrame + 1) % this.frames.length;\n if (next === 0) {\n this.events.emit('loop', this);\n }\n break;\n }\n case AnimationStrategy.End: {\n next = currentFrame + 1;\n if (next >= this.frames.length) {\n this._done = true;\n this._currentFrame = this.frames.length;\n this.events.emit('end', this);\n }\n break;\n }\n case AnimationStrategy.Freeze: {\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\n if (next >= this.frames.length - 1) {\n this._done = true;\n this.events.emit('end', this);\n }\n break;\n }\n case AnimationStrategy.PingPong: {\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\n this._pingPongDirection = -1;\n this.events.emit('loop', this);\n }\n if (currentFrame + this._pingPongDirection < 0) {\n this._pingPongDirection = 1;\n this.events.emit('loop', this);\n }\n next = currentFrame + (this._pingPongDirection % this.frames.length);\n break;\n }\n }\n return next;\n }\n /**\n * Called internally by Excalibur to update the state of the animation potential update the current frame\n * @param elapsedMilliseconds Milliseconds elapsed\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\n */\n tick(elapsedMilliseconds, idempotencyToken = 0) {\n if (this._idempotencyToken === idempotencyToken) {\n return;\n }\n this._idempotencyToken = idempotencyToken;\n if (!this._playing) {\n return;\n }\n // if it's the first frame emit frame event\n if (this._firstTick) {\n this._firstTick = false;\n this.events.emit('frame', { ...this.currentFrame, frameIndex: this.currentFrameIndex });\n }\n this._timeLeftInFrame -= elapsedMilliseconds * this._speed;\n if (this._timeLeftInFrame <= 0) {\n this.goToFrame(this._nextFrame());\n }\n }\n _drawImage(ctx, x, y) {\n if (this.currentFrame) {\n this.currentFrame.graphic.draw(ctx, x, y);\n }\n }\n}\nAnimation._LOGGER = Logger.getInstance();\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsGroup.ts\n\n\n\n\n\nclass GraphicsGroup extends Graphic {\n constructor(options) {\n super(options);\n this._logger = Logger.getInstance();\n this.members = [];\n this.members = options.members;\n this._updateDimensions();\n }\n clone() {\n return new GraphicsGroup({\n members: [...this.members],\n ...this.cloneGraphicOptions()\n });\n }\n _updateDimensions() {\n const bb = this.localBounds;\n this.width = bb.width;\n this.height = bb.height;\n return bb;\n }\n get localBounds() {\n let bb = new BoundingBox();\n for (const member of this.members) {\n if (member instanceof Graphic) {\n bb = member.localBounds.combine(bb);\n }\n else {\n const { graphic, offset: pos, useBounds } = member;\n const shouldUseBounds = useBounds === undefined ? true : useBounds;\n if (graphic) {\n if (shouldUseBounds) {\n bb = graphic.localBounds.translate(pos).combine(bb);\n }\n }\n else {\n this._logger.warnOnce(`Graphics group member has an null or undefined graphic, member definition: ${JSON.stringify(member)}.`);\n }\n }\n }\n return bb;\n }\n _isAnimationOrGroup(graphic) {\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\n }\n tick(elapsedMilliseconds, idempotencyToken) {\n for (const member of this.members) {\n let graphic;\n if (member instanceof Graphic) {\n graphic = member;\n }\n else {\n graphic = member.graphic;\n }\n if (this._isAnimationOrGroup(graphic)) {\n graphic.tick(elapsedMilliseconds, idempotencyToken);\n }\n }\n }\n reset() {\n for (const member of this.members) {\n let graphic;\n if (member instanceof Graphic) {\n graphic = member;\n }\n else {\n graphic = member.graphic;\n }\n if (this._isAnimationOrGroup(graphic)) {\n graphic.reset();\n }\n }\n }\n _preDraw(ex, x, y) {\n this._updateDimensions();\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n const pos = Vector.Zero;\n for (const member of this.members) {\n let graphic;\n if (member instanceof Graphic) {\n graphic = member;\n }\n else {\n graphic = member.graphic;\n member.offset.clone(pos);\n }\n if (!graphic) {\n continue;\n }\n ex.save();\n ex.translate(x, y);\n graphic.draw(ex, pos.x, pos.y);\n if (this.showDebug) {\n /* istanbul ignore next */\n ex.debug.drawRect(0, 0, this.width, this.height);\n }\n ex.restore();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Configurable.ts\n/**\n * Configurable helper extends base type and makes all properties available as option bag arguments\n * @internal\n * @param base\n */\nfunction Configurable(base) {\n return class extends base {\n assign(props) {\n //set the value of every property that was passed in,\n //if the constructor previously set this value, it will be overridden here\n for (const k in props) {\n // eslint-disable-next-line\n if (typeof this[k] !== 'function') {\n // eslint-disable-next-line\n this[k] = props[k];\n }\n }\n }\n constructor(...args) {\n super(...args);\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\n //of whatever ctor is the implementation, so args.length doesn't work here.\n const size = args.filter(function (value) {\n return value !== undefined;\n }).length;\n if (size === 1 && args[0] && typeof args[0] === 'object' && !(args[0] instanceof Array)) {\n this.assign(args[0]);\n }\n }\n };\n}\n\n;// CONCATENATED MODULE: ./Particles.ts\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * An enum that represents the types of emitter nozzles\n */\nvar EmitterType;\n(function (EmitterType) {\n /**\n * Constant for the circular emitter type\n */\n EmitterType[EmitterType[\"Circle\"] = 0] = \"Circle\";\n /**\n * Constant for the rectangular emitter type\n */\n EmitterType[EmitterType[\"Rectangle\"] = 1] = \"Rectangle\";\n})(EmitterType || (EmitterType = {}));\n/**\n * @hidden\n */\nclass ParticleImpl extends Entity {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite) {\n super();\n this.position = new Vector(0, 0);\n this.velocity = new Vector(0, 0);\n this.acceleration = new Vector(0, 0);\n this.particleRotationalVelocity = 0;\n this.currentRotation = 0;\n this.focus = null;\n this.focusAccel = 0;\n this.opacity = 1;\n this.beginColor = Color.White;\n this.endColor = Color.White;\n // Life is counted in ms\n this.life = 300;\n this.fadeFlag = false;\n // Color transitions\n this._rRate = 1;\n this._gRate = 1;\n this._bRate = 1;\n this._aRate = 0;\n this._currentColor = Color.White;\n this.emitter = null;\n this.particleSize = 5;\n this.particleSprite = null;\n this.sizeRate = 0;\n this.elapsedMultiplier = 0;\n this.visible = true;\n this.isOffscreen = false;\n let emitter = emitterOrConfig;\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\n const config = emitterOrConfig;\n emitter = config.emitter;\n life = config.life;\n opacity = config.opacity;\n endColor = config.endColor;\n beginColor = config.beginColor;\n position = config.position;\n velocity = config.velocity;\n acceleration = config.acceleration;\n startSize = config.startSize;\n endSize = config.endSize;\n particleSprite = config.particleSprite;\n }\n this.emitter = emitter;\n this.life = life || this.life;\n this.opacity = opacity || this.opacity;\n this.endColor = endColor || this.endColor.clone();\n this.beginColor = beginColor || this.beginColor.clone();\n this._currentColor = this.beginColor.clone();\n this.particleSprite = particleSprite;\n if (this.emitter.particleTransform === ParticleTransform.Global) {\n const globalPos = this.emitter.transform.globalPos;\n this.position = (position || this.position).add(globalPos);\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\n }\n else {\n this.velocity = velocity || this.velocity;\n this.position = (position || this.position);\n }\n this.acceleration = acceleration || this.acceleration;\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\n this._aRate = this.opacity / this.life;\n this.startSize = startSize || 0;\n this.endSize = endSize || 0;\n if (this.endSize > 0 && this.startSize > 0) {\n this.sizeRate = (this.endSize - this.startSize) / this.life;\n this.particleSize = this.startSize;\n }\n this.addComponent((this.transform = new TransformComponent()));\n this.addComponent((this.graphics = new GraphicsComponent()));\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // TODO wut\n if (this.particleSprite) {\n this.graphics.opacity = this.opacity;\n this.graphics.use(this.particleSprite);\n }\n else {\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\n this.graphics.onPostDraw = (ctx) => {\n ctx.save();\n this.graphics.opacity = this.opacity;\n const tmpColor = this._currentColor.clone();\n tmpColor.a = 1;\n ctx.debug.drawPoint(vec(0, 0), { color: tmpColor, size: this.particleSize });\n ctx.restore();\n };\n }\n }\n kill() {\n this.emitter.removeParticle(this);\n }\n update(engine, delta) {\n this.life = this.life - delta;\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\n if (this.life < 0) {\n this.kill();\n }\n if (this.fadeFlag) {\n this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\n }\n if (this.startSize > 0 && this.endSize > 0) {\n this.particleSize = clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize));\n }\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\n if (this.focus) {\n const accel = this.focus\n .sub(this.position)\n .normalize()\n .scale(this.focusAccel)\n .scale(delta / 1000);\n this.velocity = this.velocity.add(accel);\n }\n else {\n this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\n }\n this.position = this.position.add(this.velocity.scale(delta / 1000));\n if (this.particleRotationalVelocity) {\n this.currentRotation = (this.currentRotation + (this.particleRotationalVelocity * delta) / 1000) % (2 * Math.PI);\n }\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // todo wut\n this.graphics.opacity = this.opacity;\n }\n}\n/**\n * Particle is used in a [[ParticleEmitter]]\n */\nclass Particle extends Configurable(ParticleImpl) {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite) {\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite);\n }\n}\nvar ParticleTransform;\n(function (ParticleTransform) {\n /**\n * [[ParticleTransform.Global]] is the default and emits particles as if\n * they were world space objects, useful for most effects.\n */\n ParticleTransform[\"Global\"] = \"global\";\n /**\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\n * as they would in a parent/child actor relationship.\n */\n ParticleTransform[\"Local\"] = \"local\";\n})(ParticleTransform || (ParticleTransform = {}));\n/**\n * Using a particle emitter is a great way to create interesting effects\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\n * extend [[Actor]] allowing you to use all of the features that come with.\n */\nclass ParticleEmitter extends Actor {\n /**\n * Gets the opacity of each particle from 0 to 1.0\n */\n get opacity() {\n return this.graphics.opacity;\n }\n /**\n * Gets the opacity of each particle from 0 to 1.0\n */\n set opacity(opacity) {\n this.graphics.opacity = opacity;\n }\n /**\n * Gets or sets the sprite that a particle should use\n */\n get particleSprite() {\n return this._sprite;\n }\n set particleSprite(val) {\n if (val) {\n this._sprite = val;\n }\n }\n /**\n * @param config particle emitter options bag\n */\n constructor(config) {\n var _a, _b;\n super({ width: (_a = config.width) !== null && _a !== void 0 ? _a : 0, height: (_b = config.height) !== null && _b !== void 0 ? _b : 0 });\n this._particlesToEmit = 0;\n this.numParticles = 0;\n /**\n * Gets or sets the isEmitting flag\n */\n this.isEmitting = true;\n /**\n * Gets or sets the backing particle collection\n */\n this.particles = [];\n /**\n * Gets or sets the backing deadParticle collection\n */\n this.deadParticles = [];\n /**\n * Gets or sets the minimum particle velocity\n */\n this.minVel = 0;\n /**\n * Gets or sets the maximum particle velocity\n */\n this.maxVel = 0;\n /**\n * Gets or sets the acceleration vector for all particles\n */\n this.acceleration = new Vector(0, 0);\n /**\n * Gets or sets the minimum angle in radians\n */\n this.minAngle = 0;\n /**\n * Gets or sets the maximum angle in radians\n */\n this.maxAngle = 0;\n /**\n * Gets or sets the emission rate for particles (particles/sec)\n */\n this.emitRate = 1; //particles/sec\n /**\n * Gets or sets the life of each particle in milliseconds\n */\n this.particleLife = 2000;\n /**\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\n */\n this.fadeFlag = false;\n /**\n * Gets or sets the optional focus where all particles should accelerate towards\n */\n this.focus = null;\n /**\n * Gets or sets the acceleration for focusing particles if a focus has been specified\n */\n this.focusAccel = null;\n /**\n * Gets or sets the optional starting size for the particles\n */\n this.startSize = null;\n /**\n * Gets or sets the optional ending size for the particles\n */\n this.endSize = null;\n /**\n * Gets or sets the minimum size of all particles\n */\n this.minSize = 5;\n /**\n * Gets or sets the maximum size of all particles\n */\n this.maxSize = 5;\n /**\n * Gets or sets the beginning color of all particles\n */\n this.beginColor = Color.White;\n /**\n * Gets or sets the ending color of all particles\n */\n this.endColor = Color.White;\n this._sprite = null;\n /**\n * Gets or sets the emitter type for the particle emitter\n */\n this.emitterType = EmitterType.Rectangle;\n /**\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\n */\n this.radius = 0;\n /**\n * Gets or sets the particle rotational speed velocity\n */\n this.particleRotationalVelocity = 0;\n /**\n * Indicates whether particles should start with a random rotation\n */\n this.randomRotation = false;\n /**\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\n * they were world space objects, useful for most effects.\n *\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\n * as they would in a parent/child actor relationship.\n */\n this.particleTransform = ParticleTransform.Global;\n const { x, y, pos, isEmitting, minVel, maxVel, acceleration, minAngle, maxAngle, emitRate, particleLife, opacity, fadeFlag, focus, focusAccel, startSize, endSize, minSize, maxSize, beginColor, endColor, particleSprite, emitterType, radius, particleRotationalVelocity, particleTransform, randomRotation, random } = { ...config };\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.isEmitting = isEmitting !== null && isEmitting !== void 0 ? isEmitting : this.isEmitting;\n this.minVel = minVel !== null && minVel !== void 0 ? minVel : this.minVel;\n this.maxVel = maxVel !== null && maxVel !== void 0 ? maxVel : this.maxVel;\n this.acceleration = acceleration !== null && acceleration !== void 0 ? acceleration : this.acceleration;\n this.minAngle = minAngle !== null && minAngle !== void 0 ? minAngle : this.minAngle;\n this.maxAngle = maxAngle !== null && maxAngle !== void 0 ? maxAngle : this.maxAngle;\n this.emitRate = emitRate !== null && emitRate !== void 0 ? emitRate : this.emitRate;\n this.particleLife = particleLife !== null && particleLife !== void 0 ? particleLife : this.particleLife;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.fadeFlag = fadeFlag !== null && fadeFlag !== void 0 ? fadeFlag : this.fadeFlag;\n this.focus = focus !== null && focus !== void 0 ? focus : this.focus;\n this.focusAccel = focusAccel !== null && focusAccel !== void 0 ? focusAccel : this.focusAccel;\n this.startSize = startSize !== null && startSize !== void 0 ? startSize : this.startSize;\n this.endSize = endSize !== null && endSize !== void 0 ? endSize : this.endSize;\n this.minSize = minSize !== null && minSize !== void 0 ? minSize : this.minSize;\n this.maxSize = maxSize !== null && maxSize !== void 0 ? maxSize : this.maxSize;\n this.beginColor = beginColor !== null && beginColor !== void 0 ? beginColor : this.beginColor;\n this.endColor = endColor !== null && endColor !== void 0 ? endColor : this.endColor;\n this.particleSprite = particleSprite !== null && particleSprite !== void 0 ? particleSprite : this.particleSprite;\n this.emitterType = emitterType !== null && emitterType !== void 0 ? emitterType : this.emitterType;\n this.radius = radius !== null && radius !== void 0 ? radius : this.radius;\n this.particleRotationalVelocity = particleRotationalVelocity !== null && particleRotationalVelocity !== void 0 ? particleRotationalVelocity : this.particleRotationalVelocity;\n this.randomRotation = randomRotation !== null && randomRotation !== void 0 ? randomRotation : this.randomRotation;\n this.particleTransform = particleTransform !== null && particleTransform !== void 0 ? particleTransform : this.particleTransform;\n this.body.collisionType = CollisionType.PreventCollision;\n this.random = random !== null && random !== void 0 ? random : new Random();\n }\n removeParticle(particle) {\n this.deadParticles.push(particle);\n }\n /**\n * Causes the emitter to emit particles\n * @param particleCount Number of particles to emit right now\n */\n emitParticles(particleCount) {\n var _a;\n for (let i = 0; i < particleCount; i++) {\n const p = this._createParticle();\n this.particles.push(p);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\n if (this.particleTransform === ParticleTransform.Global) {\n this.scene.world.add(p);\n }\n else {\n this.addChild(p);\n }\n }\n }\n }\n clearParticles() {\n this.particles.length = 0;\n }\n // Creates a new particle given the constraints of the emitter\n _createParticle() {\n // todo implement emitter constraints;\n let ranX = 0;\n let ranY = 0;\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\n const dx = vel * Math.cos(angle);\n const dy = vel * Math.sin(angle);\n if (this.emitterType === EmitterType.Rectangle) {\n ranX = randomInRange(0, this.width, this.random);\n ranY = randomInRange(0, this.height, this.random);\n }\n else if (this.emitterType === EmitterType.Circle) {\n const radius = randomInRange(0, this.radius, this.random);\n ranX = radius * Math.cos(angle);\n ranY = radius * Math.sin(angle);\n }\n const p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new Vector(ranX, ranY), new Vector(dx, dy), this.acceleration, this.startSize, this.endSize, this.particleSprite);\n p.fadeFlag = this.fadeFlag;\n p.particleSize = size;\n p.particleRotationalVelocity = this.particleRotationalVelocity;\n if (this.randomRotation) {\n p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\n }\n if (this.focus) {\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\n p.focusAccel = this.focusAccel;\n }\n return p;\n }\n update(engine, delta) {\n var _a;\n super.update(engine, delta);\n if (this.isEmitting) {\n this._particlesToEmit += this.emitRate * (delta / 1000);\n if (this._particlesToEmit > 1.0) {\n this.emitParticles(Math.floor(this._particlesToEmit));\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\n }\n }\n // deferred removal\n for (let i = 0; i < this.deadParticles.length; i++) {\n removeItemFromArray(this.deadParticles[i], this.particles);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\n this.scene.world.remove(this.deadParticles[i], false);\n }\n }\n this.deadParticles.length = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/TransformInterpolation.ts\n\n/**\n * Blend 2 transforms for interpolation, will interpolate from the context of newTx's parent if it exists\n */\nfunction blendTransform(oldTx, newTx, blend, target) {\n if (oldTx.parent !== newTx.parent) {\n // Caller expects a local transform\n // Adjust old tx to be local to the new parent whatever that is\n const oldTxWithNewParent = oldTx.clone();\n const oldGlobalPos = oldTx.globalPos.clone();\n const oldGlobalScale = oldTx.globalScale.clone();\n const oldGlobalRotation = oldTx.globalRotation;\n oldTxWithNewParent.parent = newTx.parent;\n oldTxWithNewParent.globalPos = oldGlobalPos;\n oldTxWithNewParent.globalScale = oldGlobalScale;\n oldTxWithNewParent.globalRotation = oldGlobalRotation;\n oldTx = oldTxWithNewParent;\n }\n let interpolatedPos = newTx.pos;\n let interpolatedScale = newTx.scale;\n let interpolatedRotation = newTx.rotation;\n interpolatedPos = newTx.pos.scale(blend).add(oldTx.pos.scale(1.0 - blend));\n interpolatedScale = newTx.scale.scale(blend).add(oldTx.scale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(oldTx.rotation) + blend * Math.cos(newTx.rotation);\n const sine = (1.0 - blend) * Math.sin(oldTx.rotation) + blend * Math.sin(newTx.rotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n const tx = target !== null && target !== void 0 ? target : new transform_Transform();\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\n return tx;\n}\n/**\n *\n */\nfunction blendGlobalTransform(oldTx, newTx, blend, target) {\n let interpolatedPos = newTx.globalPos;\n let interpolatedScale = newTx.globalScale;\n let interpolatedRotation = newTx.globalRotation;\n interpolatedPos = newTx.globalPos.scale(blend).add(oldTx.globalPos.scale(1.0 - blend));\n interpolatedScale = newTx.globalScale.scale(blend).add(oldTx.globalScale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(oldTx.globalRotation) + blend * Math.cos(newTx.globalRotation);\n const sine = (1.0 - blend) * Math.sin(oldTx.globalRotation) + blend * Math.sin(newTx.globalRotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n const tx = target !== null && target !== void 0 ? target : new Transform();\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\n return tx;\n}\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsSystem.ts\n\n\n\n\n\n // this import seems to bomb wallaby\n\n\n\n\n\n\n\n\nclass GraphicsSystem extends System {\n get sortedTransforms() {\n return this._sortedTransforms;\n }\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Average;\n this._token = 0;\n this._sortedTransforms = [];\n this._zHasChanged = false;\n this._zIndexUpdate = () => {\n this._zHasChanged = true;\n };\n this._targetInterpolationTransform = new transform_Transform();\n this.query = this.world.query([TransformComponent, GraphicsComponent]);\n this.query.entityAdded$.subscribe(e => {\n const tx = e.get(TransformComponent);\n this._sortedTransforms.push(tx);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n });\n this.query.entityRemoved$.subscribe(e => {\n const tx = e.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) {\n this._sortedTransforms.splice(index, 1);\n }\n });\n }\n initialize(world, scene) {\n this._camera = scene.camera;\n this._engine = scene.engine;\n }\n preupdate() {\n // Graphics context could be switched to fallback in a new frame\n this._graphicsContext = this._engine.graphicsContext;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b) => {\n return a.z - b.z;\n });\n this._zHasChanged = false;\n }\n }\n update(delta) {\n this._token++;\n let graphics;\n FontCache.checkAndClearCache();\n // This is a performance enhancement, most things are in world space\n // so if we can only do this once saves a ton of transform updates\n this._graphicsContext.save();\n if (this._camera) {\n this._camera.draw(this._graphicsContext);\n }\n for (const transform of this._sortedTransforms) {\n const entity = transform.owner;\n // If the entity is offscreen skip\n if (entity.hasTag('ex.offscreen')) {\n continue;\n }\n graphics = entity.get(GraphicsComponent);\n // Exit if graphics set to not visible\n if (!graphics.visible) {\n continue;\n }\n // Optionally run the onPreTransformDraw graphics lifecycle draw\n if (graphics.onPreTransformDraw) {\n graphics.onPreTransformDraw(this._graphicsContext, delta);\n }\n entity.events.emit('pretransformdraw', new PreTransformDrawEvent(this._graphicsContext, delta, entity));\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.restore();\n }\n this._graphicsContext.save();\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n }\n // Tick any graphics state (but only once) for animations and graphics groups\n graphics.update(delta, this._token);\n // Apply parallax\n const parallax = entity.get(ParallaxComponent);\n if (parallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\n const parallaxOffset = this._camera.drawPos.scale(oneMinusFactor);\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\n }\n // Position the entity + estimate lag\n this._applyTransform(entity);\n // If there is a material enable it on the context\n if (graphics.material) {\n this._graphicsContext.material = graphics.material;\n }\n // Optionally run the onPreDraw graphics lifecycle draw\n if (graphics.onPreDraw) {\n graphics.onPreDraw(this._graphicsContext, delta);\n }\n entity.events.emit('predraw', new PreDrawEvent(this._graphicsContext, delta, entity));\n // TODO remove this hack on the particle redo\n // Remove this line after removing the wallaby import\n const particleOpacity = (entity instanceof Particle) ? entity.opacity : 1;\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\n // Draw the graphics component\n this._drawGraphicsComponent(graphics, transform);\n // Optionally run the onPostDraw graphics lifecycle draw\n if (graphics.onPostDraw) {\n graphics.onPostDraw(this._graphicsContext, delta);\n }\n entity.events.emit('postdraw', new PostDrawEvent(this._graphicsContext, delta, entity));\n this._graphicsContext.restore();\n // Reset the transform back to the original world space\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.save();\n if (this._camera) {\n this._camera.draw(this._graphicsContext);\n }\n }\n // Optionally run the onPreTransformDraw graphics lifecycle draw\n if (graphics.onPostTransformDraw) {\n graphics.onPostTransformDraw(this._graphicsContext, delta);\n }\n entity.events.emit('posttransformdraw', new PostTransformDrawEvent(this._graphicsContext, delta, entity));\n }\n this._graphicsContext.restore();\n }\n _drawGraphicsComponent(graphicsComponent, transformComponent) {\n var _a, _b;\n if (graphicsComponent.visible) {\n const flipHorizontal = graphicsComponent.flipHorizontal;\n const flipVertical = graphicsComponent.flipVertical;\n const graphic = graphicsComponent.current;\n const options = (_a = graphicsComponent.currentOptions) !== null && _a !== void 0 ? _a : {};\n if (graphic) {\n let anchor = graphicsComponent.anchor;\n let offset = graphicsComponent.offset;\n let scaleX = 1;\n let scaleY = 1;\n // handle specific overrides\n if (options === null || options === void 0 ? void 0 : options.anchor) {\n anchor = options.anchor;\n }\n if (options === null || options === void 0 ? void 0 : options.offset) {\n offset = options.offset;\n }\n const globalScale = transformComponent.globalScale;\n scaleX *= graphic.scale.x * globalScale.x;\n scaleY *= graphic.scale.y * globalScale.y;\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\n const offsetX = -graphic.width * anchor.x + offset.x * scaleX;\n const offsetY = -graphic.height * anchor.y + offset.y * scaleY;\n const oldFlipHorizontal = graphic.flipHorizontal;\n const oldFlipVertical = graphic.flipVertical;\n if (flipHorizontal || flipVertical) {\n // flip any currently flipped graphics\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\n }\n graphic === null || graphic === void 0 ? void 0 : graphic.draw(this._graphicsContext, offsetX, offsetY);\n if (flipHorizontal || flipVertical) {\n graphic.flipHorizontal = oldFlipHorizontal;\n graphic.flipVertical = oldFlipVertical;\n }\n // TODO move debug code out?\n if (((_b = this._engine) === null || _b === void 0 ? void 0 : _b.isDebug) && this._engine.debug.graphics.showBounds) {\n const offset = vec(offsetX, offsetY);\n if (graphic instanceof GraphicsGroup) {\n for (const member of graphic.members) {\n let g;\n let pos = Vector.Zero;\n if (member instanceof Graphic) {\n g = member;\n }\n else {\n g = member.graphic;\n pos = member.offset;\n }\n g === null || g === void 0 ? void 0 : g.localBounds.translate(offset.add(pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n }\n else {\n /* istanbul ignore next */\n graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n }\n }\n }\n }\n /**\n * This applies the current entity transform to the graphics context\n * @param entity\n */\n _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors) {\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n const optionalBody = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(BodyComponent);\n let tx = transform.get();\n if (optionalBody) {\n if (this._engine.fixedUpdateFps &&\n optionalBody.__oldTransformCaptured &&\n optionalBody.enableFixedUpdateInterpolate) {\n // Interpolate graphics if needed\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n tx = blendTransform(optionalBody.oldTransform, transform.get(), blend, this._targetInterpolationTransform);\n }\n }\n if (transform) {\n this._graphicsContext.z = transform.z;\n this._graphicsContext.translate(tx.pos.x, tx.pos.y);\n this._graphicsContext.scale(tx.scale.x, tx.scale.y);\n this._graphicsContext.rotate(tx.rotation);\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Debug/DebugSystem.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nclass DebugSystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Lowest;\n this.query = this.world.query([TransformComponent]);\n }\n initialize(world, scene) {\n this._graphicsContext = scene.engine.graphicsContext;\n this._camera = scene.camera;\n this._engine = scene.engine;\n this._collisionSystem = world.systemManager.get(CollisionSystem);\n }\n update() {\n var _a;\n if (!this._engine.isDebug) {\n return;\n }\n const filterSettings = this._engine.debug.filter;\n let id;\n let name;\n const entitySettings = this._engine.debug.entity;\n let tx;\n const txSettings = this._engine.debug.transform;\n let motion;\n const motionSettings = this._engine.debug.motion;\n let colliderComp;\n const colliderSettings = this._engine.debug.collider;\n const physicsSettings = this._engine.debug.physics;\n let graphics;\n const graphicsSettings = this._engine.debug.graphics;\n let debugDraw;\n let body;\n const bodySettings = this._engine.debug.body;\n const cameraSettings = this._engine.debug.camera;\n for (const entity of this.query.entities) {\n if (entity.hasTag('offscreen')) {\n // skip offscreen entities\n continue;\n }\n if (entity instanceof Particle) {\n // Particles crush the renderer :(\n continue;\n }\n if (filterSettings.useFilter) {\n const allIds = filterSettings.ids.length === 0;\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\n if (!idMatch) {\n continue;\n }\n const allNames = filterSettings.nameQuery === '';\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\n if (!nameMatch) {\n continue;\n }\n }\n let cursor = Vector.Zero;\n const lineHeight = vec(0, 16);\n id = entity.id;\n name = entity.name;\n tx = entity.get(TransformComponent);\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n this._pushCameraTransform(tx);\n this._graphicsContext.save();\n if (tx.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n }\n this._graphicsContext.z = txSettings.debugZIndex;\n this._applyTransform(entity);\n if (tx) {\n if (txSettings.showAll || txSettings.showPosition) {\n this._graphicsContext.debug.drawPoint(Vector.Zero, { size: 4, color: txSettings.positionColor });\n }\n if (txSettings.showAll || txSettings.showPositionLabel) {\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showZIndex) {\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showId) {\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? 'child of id(' + ((_a = entity.parent) === null || _a === void 0 ? void 0 : _a.id) + ')' : ''}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showName) {\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showRotation) {\n this._graphicsContext.drawLine(Vector.Zero, Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero), txSettings.rotationColor, 2);\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showScale) {\n this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\n }\n }\n graphics = entity.get(GraphicsComponent);\n if (graphics) {\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\n const bounds = graphics.localBounds;\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\n }\n }\n debugDraw = entity.get(DebugGraphicsComponent);\n if (debugDraw) {\n if (!debugDraw.useTransform) {\n this._graphicsContext.restore();\n }\n debugDraw.draw(this._graphicsContext, this._engine.debug);\n if (!debugDraw.useTransform) {\n this._graphicsContext.save();\n this._applyTransform(entity);\n }\n }\n body = entity.get(BodyComponent);\n if (body) {\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showCollisionType) {\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMass) {\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMotion) {\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showSleeping) {\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping : 'cant sleep'})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n }\n this._graphicsContext.restore();\n // World space\n this._graphicsContext.save();\n if (tx.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n }\n this._graphicsContext.z = txSettings.debugZIndex;\n motion = entity.get(MotionComponent);\n if (motion) {\n if (motionSettings.showAll || motionSettings.showVelocity) {\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\n cursor = cursor.add(lineHeight);\n }\n if (motionSettings.showAll || motionSettings.showAcceleration) {\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\n }\n }\n // Colliders live in world space already so after the restore()\n colliderComp = entity.get(ColliderComponent);\n if (colliderComp) {\n const collider = colliderComp.get();\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) {\n collider.debug(this._graphicsContext, colliderSettings.geometryColor, {\n lineWidth: colliderSettings.geometryLineWidth,\n pointSize: colliderSettings.geometryPointSize\n });\n }\n if (colliderSettings.showAll || colliderSettings.showBounds) {\n if (collider instanceof CompositeCollider) {\n const colliders = collider.getColliders();\n for (const collider of colliders) {\n const bounds = collider.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\n if (colliderSettings.showAll || colliderSettings.showOwner) {\n this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\n }\n }\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\n }\n else if (collider) {\n const bounds = colliderComp.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\n if (colliderSettings.showAll || colliderSettings.showOwner) {\n this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\n }\n }\n }\n }\n this._graphicsContext.restore();\n this._popCameraTransform(tx);\n }\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) {\n this._collisionSystem.debug(this._graphicsContext);\n }\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) {\n for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts) {\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) {\n for (const point of contact.points) {\n this._graphicsContext.debug.drawPoint(point, {\n size: physicsSettings.contactSize,\n color: physicsSettings.collisionContactColor\n });\n }\n }\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) {\n for (const point of contact.points) {\n this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\n color: physicsSettings.collisionNormalColor\n });\n }\n }\n }\n }\n this._graphicsContext.restore();\n if (cameraSettings) {\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (cameraSettings.showAll || cameraSettings.showFocus) {\n this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\n }\n if (cameraSettings.showAll || cameraSettings.showZoom) {\n this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\n }\n this._graphicsContext.restore();\n }\n this._graphicsContext.flush();\n }\n postupdate(engine, elapsedMs) {\n if (this._engine.isDebug) {\n this._graphicsContext.save();\n if (this._camera) {\n this._camera.draw(this._graphicsContext);\n }\n Debug.flush(this._graphicsContext);\n this._graphicsContext.restore();\n }\n }\n /**\n * This applies the current entity transform to the graphics context\n * @param entity\n */\n _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors) {\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n if (transform) {\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\n this._graphicsContext.rotate(transform.rotation);\n }\n }\n }\n /**\n * Applies the current camera transform if in world coordinates\n * @param transform\n */\n _pushCameraTransform(transform) {\n // Establish camera offset per entity\n if (transform.coordPlane === CoordPlane.World) {\n this._graphicsContext.save();\n if (this._camera) {\n this._camera.draw(this._graphicsContext);\n }\n }\n }\n /**\n * Resets the current camera transform if in world coordinates\n * @param transform\n */\n _popCameraTransform(transform) {\n if (transform.coordPlane === CoordPlane.World) {\n // Apply camera world offset\n this._graphicsContext.restore();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerSystem.ts\n\n\n\n\n\n/**\n * The PointerSystem is responsible for dispatching pointer events to entities\n * that need them.\n *\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\n * the [[Collider]]'s shape for pointer events.\n */\nclass PointerSystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n /**\n * Optionally override component configuration for all entities\n */\n this.overrideUseColliderShape = false;\n /**\n * Optionally override component configuration for all entities\n */\n this.overrideUseGraphicsBounds = false;\n this.lastFrameEntityToPointers = new Map();\n this.currentFrameEntityToPointers = new Map();\n this._sortedTransforms = [];\n this._sortedEntities = [];\n this._zHasChanged = false;\n this._zIndexUpdate = () => {\n this._zHasChanged = true;\n };\n this.query = this.world.query([TransformComponent, PointerComponent]);\n this.query.entityAdded$.subscribe(e => {\n const tx = e.get(TransformComponent);\n this._sortedTransforms.push(tx);\n this._sortedEntities.push(tx.owner);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n });\n this.query.entityRemoved$.subscribe(e => {\n const tx = e.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) {\n this._sortedTransforms.splice(index, 1);\n this._sortedEntities.splice(index, 1);\n }\n });\n }\n initialize(world, scene) {\n this._engine = scene.engine;\n this._scene = scene;\n }\n preupdate() {\n // event receiver might change per frame\n this._receivers = [this._engine.input.pointers, this._scene.input.pointers];\n this._engineReceiver = this._engine.input.pointers;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b) => {\n return b.z - a.z;\n });\n this._sortedEntities = this._sortedTransforms.map(t => t.owner);\n this._zHasChanged = false;\n }\n }\n entityCurrentlyUnderPointer(entity, pointerId) {\n return this.currentFrameEntityToPointers.has(entity.id) &&\n this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entityWasUnderPointer(entity, pointerId) {\n return this.lastFrameEntityToPointers.has(entity.id) &&\n this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entered(entity, pointerId) {\n return this.entityCurrentlyUnderPointer(entity, pointerId) &&\n !this.lastFrameEntityToPointers.has(entity.id);\n }\n left(entity, pointerId) {\n return !this.currentFrameEntityToPointers.has(entity.id) &&\n this.entityWasUnderPointer(entity, pointerId);\n }\n addPointerToEntity(entity, pointerId) {\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\n this.currentFrameEntityToPointers.set(entity.id, [pointerId]);\n return;\n }\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\n }\n update() {\n // Locate all the pointer/entity mappings\n this._processPointerToEntity(this._sortedEntities);\n // Dispatch pointer events on entities\n this._dispatchEvents(this._sortedEntities);\n // Clear last frame's events\n this._receivers.forEach(r => r.update());\n this.lastFrameEntityToPointers.clear();\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\n this.currentFrameEntityToPointers.clear();\n this._receivers.forEach(r => r.clear());\n }\n _processPointerToEntity(entities) {\n var _a;\n let transform;\n let collider;\n let graphics;\n let pointer;\n const receiver = this._engineReceiver;\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\n // doesn't seem to cause issues tho for perf\n // Pre-process find entities under pointers\n for (const entity of entities) {\n transform = entity.get(TransformComponent);\n pointer = (_a = entity.get(PointerComponent)) !== null && _a !== void 0 ? _a : new PointerComponent;\n // Check collider contains pointer\n collider = entity.get(ColliderComponent);\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\n collider.update();\n const geom = collider.get();\n if (geom) {\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries()) {\n if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\n this.addPointerToEntity(entity, pointerId);\n }\n }\n }\n }\n // Check graphics contains pointer\n graphics = entity.get(GraphicsComponent);\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries()) {\n if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\n this.addPointerToEntity(entity, pointerId);\n }\n }\n }\n }\n }\n _processDownAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastDownPerPointer = new Map(); // TODO will this get confused between receivers?\n // Loop through down and dispatch to entities\n for (const event of receiver.currentFrameDown) {\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit('pointerdown', event);\n if (receiver.isDragStart(event.pointerId)) {\n entity.events.emit('pointerdragstart', event);\n }\n }\n lastDownPerPointer.set(event.pointerId, event);\n }\n return lastDownPerPointer;\n }\n _processUpAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastUpPerPointer = new Map();\n // Loop through up and dispatch to entities\n for (const event of receiver.currentFrameUp) {\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit('pointerup', event);\n if (receiver.isDragEnd(event.pointerId)) {\n entity.events.emit('pointerdragend', event);\n }\n }\n lastUpPerPointer.set(event.pointerId, event);\n }\n return lastUpPerPointer;\n }\n _processMoveAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastMovePerPointer = new Map();\n // Loop through move and dispatch to entities\n for (const event of receiver.currentFrameMove) {\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n // move\n entity.events.emit('pointermove', event);\n if (receiver.isDragging(event.pointerId)) {\n entity.events.emit('pointerdragmove', event);\n }\n }\n lastMovePerPointer.set(event.pointerId, event);\n }\n return lastMovePerPointer;\n }\n _processEnterLeaveAndEmit(entity, lastUpDownMoveEvents) {\n const receiver = this._engineReceiver;\n // up, down, and move are considered for enter and leave\n for (const event of lastUpDownMoveEvents) {\n // enter\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\n entity.events.emit('pointerenter', event);\n if (receiver.isDragging(event.pointerId)) {\n entity.events.emit('pointerdragenter', event);\n }\n break;\n }\n if (event.active && entity.active &&\n // leave can happen on move\n (this.left(entity, event.pointerId) ||\n // or leave can happen on pointer up\n (this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === 'up'))) {\n entity.events.emit('pointerleave', event);\n if (receiver.isDragging(event.pointerId)) {\n entity.events.emit('pointerdragleave', event);\n }\n break;\n }\n }\n }\n _processCancelAndEmit(entity) {\n const receiver = this._engineReceiver;\n // cancel\n for (const event of receiver.currentFrameCancel) {\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit('pointercancel', event);\n }\n }\n }\n _processWheelAndEmit(entity) {\n const receiver = this._engineReceiver;\n // wheel\n for (const event of receiver.currentFrameWheel) {\n // Currently the wheel only fires under the primary pointer '0'\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) {\n entity.events.emit('pointerwheel', event);\n }\n }\n }\n _dispatchEvents(entities) {\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\n // Filter preserves z order\n const entitiesWithEvents = entities.filter(e => lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\n let lastMovePerPointer;\n let lastUpPerPointer;\n let lastDownPerPointer;\n // Dispatch events in entity z order\n for (const entity of entitiesWithEvents) {\n lastDownPerPointer = this._processDownAndEmit(entity);\n lastUpPerPointer = this._processUpAndEmit(entity);\n lastMovePerPointer = this._processMoveAndEmit(entity);\n const lastUpDownMoveEvents = [\n ...lastMovePerPointer.values(),\n ...lastDownPerPointer.values(),\n ...lastUpPerPointer.values()\n ];\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\n this._processCancelAndEmit(entity);\n this._processWheelAndEmit(entity);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/ActionsSystem.ts\n\n\n\nclass ActionsSystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._actions = [];\n this.query = this.world.query([ActionsComponent]);\n this.query.entityAdded$.subscribe(e => this._actions.push(e.get(ActionsComponent)));\n this.query.entityRemoved$.subscribe(e => {\n const action = e.get(ActionsComponent);\n const index = this._actions.indexOf(action);\n if (index > -1) {\n this._actions.splice(index, 1);\n }\n });\n }\n update(delta) {\n for (const actions of this._actions) {\n actions.update(delta);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/IsometricEntityComponent.ts\n\nclass IsometricEntityComponent extends Component {\n /**\n * Specify the isometric map to use to position this entity's z-index\n * @param mapOrOptions\n */\n constructor(mapOrOptions) {\n super();\n /**\n * Vertical \"height\" in the isometric world\n */\n this.elevation = 0;\n this.columns = mapOrOptions.columns;\n this.rows = mapOrOptions.rows;\n this.tileWidth = mapOrOptions.tileWidth;\n this.tileHeight = mapOrOptions.tileHeight;\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/IsometricEntitySystem.ts\n\n\n\n\nclass IsometricEntitySystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Lower;\n this.query = this.world.query([TransformComponent, IsometricEntityComponent]);\n }\n update() {\n let transform;\n let iso;\n for (const entity of this.query.entities) {\n transform = entity.get(TransformComponent);\n iso = entity.get(IsometricEntityComponent);\n const maxZindexPerElevation = Math.max(iso.columns * iso.tileWidth, iso.rows * iso.tileHeight);\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\n transform.z = newZ;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/OffscreenSystem.ts\n\n\n\n\n\n\n\n\nclass OffscreenSystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Higher;\n this.query = this.world.query([TransformComponent, GraphicsComponent]);\n }\n initialize(world, scene) {\n this._camera = scene.camera;\n this._screen = scene.engine.screen;\n }\n update() {\n this._worldBounds = this._screen.getWorldBounds();\n let transform;\n let graphics;\n let maybeParallax;\n for (const entity of this.query.entities) {\n graphics = entity.get(GraphicsComponent);\n transform = entity.get(TransformComponent);\n maybeParallax = entity.get(ParallaxComponent);\n let parallaxOffset;\n if (maybeParallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\n }\n // Figure out if entities are offscreen\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\n if (entityOffscreen && !entity.hasTag('ex.offscreen')) {\n entity.events.emit('exitviewport', new ExitViewPortEvent(entity));\n entity.addTag('ex.offscreen');\n }\n if (!entityOffscreen && entity.hasTag('ex.offscreen')) {\n entity.events.emit('enterviewport', new EnterViewPortEvent(entity));\n entity.removeTag('ex.offscreen');\n }\n }\n }\n _isOffscreen(transform, graphics, parallaxOffset) {\n if (transform.coordPlane === CoordPlane.World) {\n let bounds = graphics.localBounds;\n if (parallaxOffset) {\n bounds = bounds.translate(parallaxOffset);\n }\n const transformedBounds = bounds.transform(transform.get().matrix);\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\n return graphicsOffscreen;\n }\n else {\n // TODO screen coordinates\n return false;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/PhysicsWorld.ts\n\n\n\n\nclass PhysicsWorld {\n get config() {\n return watchDeep(this._config, change => {\n this.$configUpdate.notifyAll(change);\n });\n }\n set config(newConfig) {\n this._config = newConfig;\n this.$configUpdate.notifyAll(newConfig);\n }\n /**\n * Spatial data structure for locating potential collision pairs and ray casts\n */\n get collisionProcessor() {\n if (this._configDirty) {\n this._configDirty = false;\n // preserve tracked colliders if config updates\n const colliders = this._collisionProcessor.getColliders();\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this._config);\n for (const collider of colliders) {\n this._collisionProcessor.track(collider);\n }\n }\n return this._collisionProcessor;\n }\n constructor(config) {\n this.$configUpdate = new Observable;\n this._configDirty = false;\n this.config = config;\n this.$configUpdate.subscribe((config) => {\n this._configDirty = true;\n BodyComponent.updateDefaultPhysicsConfig(config.bodies);\n });\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this.config);\n }\n /**\n * Raycast into the scene's physics world\n * @param ray\n * @param options\n */\n rayCast(ray, options) {\n return this.collisionProcessor.rayCast(ray, options);\n }\n}\n\n;// CONCATENATED MODULE: ./Input/Gamepad.ts\n\n\nconst GamepadEvents = {\n GamepadConnect: 'connect',\n GamepadDisconnect: 'disconnect',\n GamepadButton: 'button',\n GamepadAxis: 'axis'\n};\n/**\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\n * to provide controller support for your games.\n */\nclass Gamepads {\n constructor() {\n this.events = new EventEmitter();\n /**\n * Whether or not to poll for Gamepad input (default: `false`)\n */\n this.enabled = false;\n /**\n * Whether or not Gamepad API is supported\n */\n this.supported = !!navigator.getGamepads;\n this._gamePadTimeStamps = [0, 0, 0, 0];\n this._oldPads = [];\n this._pads = [];\n this._initSuccess = false;\n this._navigator = navigator;\n this._minimumConfiguration = null;\n this._enabled = true;\n }\n init() {\n if (!this.supported) {\n return;\n }\n if (this._initSuccess) {\n return;\n }\n // In Chrome, this will return 4 undefined items until a button is pressed\n // In FF, this will not return any items until a button is pressed\n this._oldPads = this._clonePads(this._navigator.getGamepads());\n if (this._oldPads.length && this._oldPads[0]) {\n this._initSuccess = true;\n }\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n /**\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\n * all other controllers with more axis or buttons are valid as well. If no minimum\n * configuration is set all pads are valid.\n */\n setMinimumGamepadConfiguration(config) {\n this._enableAndUpdate(); // if config is used, implicitly enable\n this._minimumConfiguration = config;\n }\n /**\n * When implicitly enabled, set the enabled flag and run an update so information is updated\n */\n _enableAndUpdate() {\n if (!this.enabled) {\n this.enabled = true;\n this.update();\n }\n }\n /**\n * Checks a navigator gamepad against the minimum configuration if present.\n */\n _isGamepadValid(pad) {\n if (!this._minimumConfiguration) {\n return true;\n }\n if (!pad) {\n return false;\n }\n const axesLength = pad.axes.filter((value) => {\n return typeof value !== undefined;\n }).length;\n const buttonLength = pad.buttons.filter((value) => {\n return typeof value !== undefined;\n }).length;\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n this.events.off(eventName, handler);\n }\n /**\n * Updates Gamepad state and publishes Gamepad events\n */\n update() {\n if (!this.enabled || !this.supported) {\n return;\n }\n if (!this._enabled) {\n return;\n }\n this.init();\n const gamepads = this._navigator.getGamepads();\n for (let i = 0; i < gamepads.length; i++) {\n if (!gamepads[i]) {\n const gamepad = this.at(i);\n // If was connected, but now isn't emit the disconnect event\n if (gamepad.connected) {\n this.events.emit('disconnect', new GamepadDisconnectEvent(i, gamepad));\n }\n // Reset connection status\n gamepad.connected = false;\n continue;\n }\n else {\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) {\n this.events.emit('connect', new GamepadConnectEvent(i, this.at(i)));\n }\n // Set connection status\n this.at(i).connected = true;\n }\n this.at(i).update();\n // Only supported in Chrome\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) {\n continue;\n }\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\n // Add reference to navigator gamepad\n this.at(i).navigatorGamepad = gamepads[i];\n // Buttons\n let b, bi, a, ai, value;\n for (b in Buttons) {\n bi = Buttons[b];\n if (typeof bi === 'number') {\n if (gamepads[i].buttons[bi]) {\n value = gamepads[i].buttons[bi].value;\n if (value !== this._oldPads[i].getButton(bi)) {\n if (gamepads[i].buttons[bi].pressed) {\n this.at(i).updateButton(bi, value);\n this.at(i).events.emit('button', new GamepadButtonEvent(bi, value, this.at(i)));\n }\n else {\n this.at(i).updateButton(bi, 0);\n }\n }\n }\n }\n }\n // Axes\n for (a in Axes) {\n ai = Axes[a];\n if (typeof ai === 'number') {\n value = gamepads[i].axes[ai];\n if (value !== this._oldPads[i].getAxes(ai)) {\n this.at(i).updateAxes(ai, value);\n this.at(i).events.emit('axis', new GamepadAxisEvent(ai, value, this.at(i)));\n }\n }\n }\n this._oldPads[i] = this._clonePad(gamepads[i]);\n }\n }\n /**\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\n */\n at(index) {\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\n if (index >= this._pads.length) {\n // Ensure there is a pad to retrieve\n for (let i = this._pads.length - 1, max = index; i < max; i++) {\n this._pads.push(new Gamepad());\n this._oldPads.push(new Gamepad());\n }\n }\n return this._pads[index];\n }\n /**\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\n */\n getValidGamepads() {\n this._enableAndUpdate();\n const result = [];\n for (let i = 0; i < this._pads.length; i++) {\n if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) {\n result.push(this.at(i));\n }\n }\n return result;\n }\n /**\n * Gets the number of connected gamepads\n */\n count() {\n return this._pads.filter((p) => p.connected).length;\n }\n _clonePads(pads) {\n const arr = [];\n for (let i = 0, len = pads.length; i < len; i++) {\n arr.push(this._clonePad(pads[i]));\n }\n return arr;\n }\n /**\n * Fastest way to clone a known object is to do it yourself\n */\n _clonePad(pad) {\n let i, len;\n const clonedPad = new Gamepad();\n if (!pad) {\n return clonedPad;\n }\n for (i = 0, len = pad.buttons.length; i < len; i++) {\n if (pad.buttons[i]) {\n clonedPad.updateButton(i, pad.buttons[i].value);\n }\n }\n for (i = 0, len = pad.axes.length; i < len; i++) {\n clonedPad.updateAxes(i, pad.axes[i]);\n }\n return clonedPad;\n }\n}\n/**\n * The minimum value an axis has to move before considering it a change\n */\nGamepads.MinAxisMoveThreshold = 0.05;\n/**\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\n * for more information on handling controller input.\n */\nclass Gamepad {\n constructor() {\n this.events = new EventEmitter();\n this.connected = false;\n this._axes = new Array(4);\n this._buttons = new Array(16);\n this._buttonsUp = new Array(16);\n this._buttonsDown = new Array(16);\n for (let i = 0; i < this._buttons.length; i++) {\n this._buttons[i] = 0;\n }\n for (let i = 0; i < this._axes.length; i++) {\n this._axes[i] = 0;\n }\n }\n update() {\n // Reset buttonsDown and buttonsUp after update is complete\n this._buttonsDown = new Array(16);\n this._buttonsUp = new Array(16);\n }\n /**\n * Whether or not the given button is pressed\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\n * @param button The button to query\n * @param threshold The threshold over which the button is considered to be pressed\n */\n isButtonPressed(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\n * Tests if a certain button is held down. This is persisted between frames.\n * @param button The button to query\n * @param threshold The threshold over which the button is considered to be pressed\n */\n isButtonHeld(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\n * @param button Test whether a button was just pressed\n * @param threshold The threshold over which the button is considered to be pressed\n */\n wasButtonPressed(button, threshold = 1) {\n return this._buttonsDown[button] >= threshold;\n }\n /**\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\n * @param button Test whether a button was just released\n */\n wasButtonReleased(button) {\n return Boolean(this._buttonsUp[button]);\n }\n /**\n * Gets the given button value between 0 and 1\n */\n getButton(button) {\n return this._buttons[button];\n }\n /**\n * Gets the given axis value between -1 and 1. Values below\n * [[MinAxisMoveThreshold]] are considered 0.\n */\n getAxes(axes) {\n const value = this._axes[axes];\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) {\n return 0;\n }\n else {\n return value;\n }\n }\n updateButton(buttonIndex, value) {\n // button was just released\n if (value === 0 && this._buttons[buttonIndex]) {\n this._buttonsUp[buttonIndex] = 1;\n // button was just pressed\n }\n else {\n this._buttonsDown[buttonIndex] = value;\n }\n this._buttons[buttonIndex] = value;\n }\n updateAxes(axesIndex, value) {\n this._axes[axesIndex] = value;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n}\n/**\n * Gamepad Buttons enumeration\n */\nvar Buttons;\n(function (Buttons) {\n /**\n * Face 1 button (e.g. A)\n */\n Buttons[Buttons[\"Face1\"] = 0] = \"Face1\";\n /**\n * Face 2 button (e.g. B)\n */\n Buttons[Buttons[\"Face2\"] = 1] = \"Face2\";\n /**\n * Face 3 button (e.g. X)\n */\n Buttons[Buttons[\"Face3\"] = 2] = \"Face3\";\n /**\n * Face 4 button (e.g. Y)\n */\n Buttons[Buttons[\"Face4\"] = 3] = \"Face4\";\n /**\n * Left bumper button\n */\n Buttons[Buttons[\"LeftBumper\"] = 4] = \"LeftBumper\";\n /**\n * Right bumper button\n */\n Buttons[Buttons[\"RightBumper\"] = 5] = \"RightBumper\";\n /**\n * Left trigger button\n */\n Buttons[Buttons[\"LeftTrigger\"] = 6] = \"LeftTrigger\";\n /**\n * Right trigger button\n */\n Buttons[Buttons[\"RightTrigger\"] = 7] = \"RightTrigger\";\n /**\n * Select button\n */\n Buttons[Buttons[\"Select\"] = 8] = \"Select\";\n /**\n * Start button\n */\n Buttons[Buttons[\"Start\"] = 9] = \"Start\";\n /**\n * Left analog stick press (e.g. L3)\n */\n Buttons[Buttons[\"LeftStick\"] = 10] = \"LeftStick\";\n /**\n * Right analog stick press (e.g. R3)\n */\n Buttons[Buttons[\"RightStick\"] = 11] = \"RightStick\";\n /**\n * D-pad up\n */\n Buttons[Buttons[\"DpadUp\"] = 12] = \"DpadUp\";\n /**\n * D-pad down\n */\n Buttons[Buttons[\"DpadDown\"] = 13] = \"DpadDown\";\n /**\n * D-pad left\n */\n Buttons[Buttons[\"DpadLeft\"] = 14] = \"DpadLeft\";\n /**\n * D-pad right\n */\n Buttons[Buttons[\"DpadRight\"] = 15] = \"DpadRight\";\n})(Buttons || (Buttons = {}));\n/**\n * Gamepad Axes enumeration\n */\nvar Axes;\n(function (Axes) {\n /**\n * Left analogue stick X direction\n */\n Axes[Axes[\"LeftStickX\"] = 0] = \"LeftStickX\";\n /**\n * Left analogue stick Y direction\n */\n Axes[Axes[\"LeftStickY\"] = 1] = \"LeftStickY\";\n /**\n * Right analogue stick X direction\n */\n Axes[Axes[\"RightStickX\"] = 2] = \"RightStickX\";\n /**\n * Right analogue stick Y direction\n */\n Axes[Axes[\"RightStickY\"] = 3] = \"RightStickY\";\n})(Axes || (Axes = {}));\n\n;// CONCATENATED MODULE: ./Input/InputMapper.ts\n/**\n * This allows you to map multiple inputs to specific commands! This is especially useful when\n * you need to allow multiple input sources to control a specific action.\n */\nclass InputMapper {\n constructor(inputs) {\n this.inputs = inputs;\n this._handlers = new Map();\n }\n /**\n * Executes the input map, called internally by Excalibur\n */\n execute() {\n for (const [input, command] of this._handlers.entries()) {\n const results = input(this.inputs);\n if (results) {\n command(results);\n }\n }\n }\n /**\n * This allows you to map multiple inputs to specific commands! This is useful\n *\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\n *\n * Example:\n * ```typescript\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\n *\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\n * ```\n * @param inputHandler\n * @param commandHandler\n */\n on(inputHandler, commandHandler) {\n this._handlers.set(inputHandler, commandHandler);\n }\n}\n\n;// CONCATENATED MODULE: ./Util/IFrame.ts\n/**\n * Checks if excalibur is in a x-origin iframe\n */\nfunction isCrossOriginIframe() {\n try {\n // Try and listen to events on top window frame if within an iframe.\n //\n // See https://github.com/excaliburjs/Excalibur/issues/1294\n //\n // Attempt to add an event listener, which triggers a DOMException on\n // cross-origin iframes\n const noop = () => {\n return;\n };\n window.top.addEventListener('blur', noop);\n window.top.removeEventListener('blur', noop);\n }\n catch (_a) {\n return true;\n }\n return false;\n}\n\n;// CONCATENATED MODULE: ./Input/Keyboard.ts\n\n\n\n\n/**\n * Enum representing physical input key codes\n */\nvar Keys;\n(function (Keys) {\n // NUMPAD\n Keys[\"Num0\"] = \"Numpad0\";\n Keys[\"Num1\"] = \"Numpad1\";\n Keys[\"Num2\"] = \"Numpad2\";\n Keys[\"Num3\"] = \"Numpad3\";\n Keys[\"Num4\"] = \"Numpad4\";\n Keys[\"Num5\"] = \"Numpad5\";\n Keys[\"Num6\"] = \"Numpad6\";\n Keys[\"Num7\"] = \"Numpad7\";\n Keys[\"Num8\"] = \"Numpad8\";\n Keys[\"Num9\"] = \"Numpad9\";\n Keys[\"NumAdd\"] = \"NumpadAdd\";\n Keys[\"NumSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumDivide\"] = \"NumpadDivide\";\n // NumComma = 'NumpadComma', // not x-browser\n Keys[\"NumDecimal\"] = \"NumpadDecimal\";\n Keys[\"Numpad0\"] = \"Numpad0\";\n Keys[\"Numpad1\"] = \"Numpad1\";\n Keys[\"Numpad2\"] = \"Numpad2\";\n Keys[\"Numpad3\"] = \"Numpad3\";\n Keys[\"Numpad4\"] = \"Numpad4\";\n Keys[\"Numpad5\"] = \"Numpad5\";\n Keys[\"Numpad6\"] = \"Numpad6\";\n Keys[\"Numpad7\"] = \"Numpad7\";\n Keys[\"Numpad8\"] = \"Numpad8\";\n Keys[\"Numpad9\"] = \"Numpad9\";\n Keys[\"NumpadAdd\"] = \"NumpadAdd\";\n Keys[\"NumpadSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumpadMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumpadDivide\"] = \"NumpadDivide\";\n // NumpadComma = 'NumpadComma', // not x-browser\n Keys[\"NumpadDecimal\"] = \"NumpadDecimal\";\n // MODIFIERS\n Keys[\"NumLock\"] = \"NumLock\";\n Keys[\"ShiftLeft\"] = \"ShiftLeft\";\n Keys[\"ShiftRight\"] = \"ShiftRight\";\n Keys[\"AltLeft\"] = \"AltLeft\";\n Keys[\"AltRight\"] = \"AltRight\";\n Keys[\"ControlLeft\"] = \"ControlLeft\";\n Keys[\"ControlRight\"] = \"ControlRight\";\n Keys[\"MetaLeft\"] = \"MetaLeft\";\n Keys[\"MetaRight\"] = \"MetaRight\";\n // NUMBERS\n Keys[\"Key0\"] = \"Digit0\";\n Keys[\"Key1\"] = \"Digit1\";\n Keys[\"Key2\"] = \"Digit2\";\n Keys[\"Key3\"] = \"Digit3\";\n Keys[\"Key4\"] = \"Digit4\";\n Keys[\"Key5\"] = \"Digit5\";\n Keys[\"Key6\"] = \"Digit6\";\n Keys[\"Key7\"] = \"Digit7\";\n Keys[\"Key8\"] = \"Digit8\";\n Keys[\"Key9\"] = \"Digit9\";\n Keys[\"Digit0\"] = \"Digit0\";\n Keys[\"Digit1\"] = \"Digit1\";\n Keys[\"Digit2\"] = \"Digit2\";\n Keys[\"Digit3\"] = \"Digit3\";\n Keys[\"Digit4\"] = \"Digit4\";\n Keys[\"Digit5\"] = \"Digit5\";\n Keys[\"Digit6\"] = \"Digit6\";\n Keys[\"Digit7\"] = \"Digit7\";\n Keys[\"Digit8\"] = \"Digit8\";\n Keys[\"Digit9\"] = \"Digit9\";\n // FUNCTION KEYS\n Keys[\"F1\"] = \"F1\";\n Keys[\"F2\"] = \"F2\";\n Keys[\"F3\"] = \"F3\";\n Keys[\"F4\"] = \"F4\";\n Keys[\"F5\"] = \"F5\";\n Keys[\"F6\"] = \"F6\";\n Keys[\"F7\"] = \"F7\";\n Keys[\"F8\"] = \"F8\";\n Keys[\"F9\"] = \"F9\";\n Keys[\"F10\"] = \"F10\";\n Keys[\"F11\"] = \"F11\";\n Keys[\"F12\"] = \"F12\";\n // LETTERS\n Keys[\"A\"] = \"KeyA\";\n Keys[\"B\"] = \"KeyB\";\n Keys[\"C\"] = \"KeyC\";\n Keys[\"D\"] = \"KeyD\";\n Keys[\"E\"] = \"KeyE\";\n Keys[\"F\"] = \"KeyF\";\n Keys[\"G\"] = \"KeyG\";\n Keys[\"H\"] = \"KeyH\";\n Keys[\"I\"] = \"KeyI\";\n Keys[\"J\"] = \"KeyJ\";\n Keys[\"K\"] = \"KeyK\";\n Keys[\"L\"] = \"KeyL\";\n Keys[\"M\"] = \"KeyM\";\n Keys[\"N\"] = \"KeyN\";\n Keys[\"O\"] = \"KeyO\";\n Keys[\"P\"] = \"KeyP\";\n Keys[\"Q\"] = \"KeyQ\";\n Keys[\"R\"] = \"KeyR\";\n Keys[\"S\"] = \"KeyS\";\n Keys[\"T\"] = \"KeyT\";\n Keys[\"U\"] = \"KeyU\";\n Keys[\"V\"] = \"KeyV\";\n Keys[\"W\"] = \"KeyW\";\n Keys[\"X\"] = \"KeyX\";\n Keys[\"Y\"] = \"KeyY\";\n Keys[\"Z\"] = \"KeyZ\";\n Keys[\"KeyA\"] = \"KeyA\";\n Keys[\"KeyB\"] = \"KeyB\";\n Keys[\"KeyC\"] = \"KeyC\";\n Keys[\"KeyD\"] = \"KeyD\";\n Keys[\"KeyE\"] = \"KeyE\";\n Keys[\"KeyF\"] = \"KeyF\";\n Keys[\"KeyG\"] = \"KeyG\";\n Keys[\"KeyH\"] = \"KeyH\";\n Keys[\"KeyI\"] = \"KeyI\";\n Keys[\"KeyJ\"] = \"KeyJ\";\n Keys[\"KeyK\"] = \"KeyK\";\n Keys[\"KeyL\"] = \"KeyL\";\n Keys[\"KeyM\"] = \"KeyM\";\n Keys[\"KeyN\"] = \"KeyN\";\n Keys[\"KeyO\"] = \"KeyO\";\n Keys[\"KeyP\"] = \"KeyP\";\n Keys[\"KeyQ\"] = \"KeyQ\";\n Keys[\"KeyR\"] = \"KeyR\";\n Keys[\"KeyS\"] = \"KeyS\";\n Keys[\"KeyT\"] = \"KeyT\";\n Keys[\"KeyU\"] = \"KeyU\";\n Keys[\"KeyV\"] = \"KeyV\";\n Keys[\"KeyW\"] = \"KeyW\";\n Keys[\"KeyX\"] = \"KeyX\";\n Keys[\"KeyY\"] = \"KeyY\";\n Keys[\"KeyZ\"] = \"KeyZ\";\n // SYMBOLS\n Keys[\"Semicolon\"] = \"Semicolon\";\n Keys[\"Quote\"] = \"Quote\";\n Keys[\"Comma\"] = \"Comma\";\n Keys[\"Minus\"] = \"Minus\";\n Keys[\"Period\"] = \"Period\";\n Keys[\"Slash\"] = \"Slash\";\n Keys[\"Equal\"] = \"Equal\";\n Keys[\"BracketLeft\"] = \"BracketLeft\";\n Keys[\"Backslash\"] = \"Backslash\";\n Keys[\"BracketRight\"] = \"BracketRight\";\n Keys[\"Backquote\"] = \"Backquote\";\n // DIRECTIONS\n Keys[\"Up\"] = \"ArrowUp\";\n Keys[\"Down\"] = \"ArrowDown\";\n Keys[\"Left\"] = \"ArrowLeft\";\n Keys[\"Right\"] = \"ArrowRight\";\n Keys[\"ArrowUp\"] = \"ArrowUp\";\n Keys[\"ArrowDown\"] = \"ArrowDown\";\n Keys[\"ArrowLeft\"] = \"ArrowLeft\";\n Keys[\"ArrowRight\"] = \"ArrowRight\";\n // OTHER\n Keys[\"Space\"] = \"Space\";\n Keys[\"Backspace\"] = \"Backspace\";\n Keys[\"Delete\"] = \"Delete\";\n Keys[\"Esc\"] = \"Escape\";\n Keys[\"Escape\"] = \"Escape\";\n Keys[\"Enter\"] = \"Enter\";\n Keys[\"NumpadEnter\"] = \"NumpadEnter\";\n Keys[\"ContextMenu\"] = \"ContextMenu\";\n})(Keys || (Keys = {}));\n/**\n * Event thrown on a game object for a key event\n */\nclass KeyEvent extends GameEvent {\n /**\n * @param key The key responsible for throwing the event\n * @param value The key's typed value the browser detected\n * @param originalEvent The original keyboard event that Excalibur handled\n */\n constructor(key, value, originalEvent) {\n super();\n this.key = key;\n this.value = value;\n this.originalEvent = originalEvent;\n }\n}\nconst KeyEvents = {\n Press: 'press',\n Hold: 'hold',\n Release: 'release'\n};\n/**\n * Provides keyboard support for Excalibur.\n */\nclass Keyboard {\n constructor() {\n this.events = new EventEmitter();\n this._enabled = true;\n /**\n * Keys that are currently held down\n */\n this._keys = [];\n /**\n * Keys up in the current frame\n */\n this._keysUp = [];\n /**\n * Keys down in the current frame\n */\n this._keysDown = [];\n this._releaseAllKeys = (ev) => {\n for (const code of this._keys) {\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit('up', keyEvent);\n this.events.emit('release', keyEvent);\n }\n this._keysUp = Array.from((new Set(this._keys.concat(this._keysUp))));\n this._keys.length = 0;\n };\n this._handleKeyDown = (ev) => {\n if (!this._enabled) {\n return;\n }\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) {\n this._releaseAllKeys(ev);\n }\n const code = ev.code;\n if (this._keys.indexOf(code) === -1) {\n this._keys.push(code);\n this._keysDown.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit('down', keyEvent);\n this.events.emit('press', keyEvent);\n }\n };\n this._handleKeyUp = (ev) => {\n if (!this._enabled) {\n return;\n }\n const code = ev.code;\n const key = this._keys.indexOf(code);\n this._keys.splice(key, 1);\n this._keysUp.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n // alias the old api, we may want to deprecate this in the future\n this.events.emit('up', keyEvent);\n this.events.emit('release', keyEvent);\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (ev.key === 'Meta') {\n this._releaseAllKeys(ev);\n }\n };\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Initialize Keyboard event listeners\n */\n init(keyboardOptions) {\n let { global } = keyboardOptions;\n const { grabWindowFocus } = keyboardOptions;\n if (!global) {\n if (isCrossOriginIframe()) {\n global = window;\n // Workaround for iframes like for itch.io or codesandbox\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\n if (grabWindowFocus) {\n window.focus();\n }\n Logger.getInstance().warn('Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus');\n }\n else {\n global = window.top;\n }\n }\n global.addEventListener('blur', () => {\n this._keys.length = 0; // empties array efficiently\n });\n // key up is on window because canvas cannot have focus\n global.addEventListener('keyup', this._handleKeyUp);\n // key down is on window because canvas cannot have focus\n global.addEventListener('keydown', this._handleKeyDown);\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n update() {\n // Reset keysDown and keysUp after update is complete\n this._keysDown.length = 0;\n this._keysUp.length = 0;\n // Emit synthetic \"hold\" event\n for (let i = 0; i < this._keys.length; i++) {\n this.events.emit('hold', new KeyEvent(this._keys[i]));\n }\n }\n /**\n * Gets list of keys being pressed down\n */\n getKeys() {\n return this._keys;\n }\n /**\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\n * @param key Test whether a key was just pressed\n */\n wasPressed(key) {\n return this._keysDown.indexOf(key) > -1;\n }\n /**\n * Tests if a certain key is held down. This is persisted between frames.\n * @param key Test whether a key is held down\n */\n isHeld(key) {\n return this._keys.indexOf(key) > -1;\n }\n /**\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\n * @param key Test whether a key was just released\n */\n wasReleased(key) {\n return this._keysUp.indexOf(key) > -1;\n }\n /**\n * Trigger a manual key event\n * @param type\n * @param key\n * @param character\n */\n triggerEvent(type, key, character) {\n if (type === 'down') {\n this._handleKeyDown(new KeyboardEvent('keydown', {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n }\n if (type === 'up') {\n this._handleKeyUp(new KeyboardEvent('keyup', {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Math/global-coordinates.ts\n\nclass GlobalCoordinates {\n static fromPagePosition(xOrPos, yOrEngine, engineOrUndefined) {\n let pageX;\n let pageY;\n let pagePos;\n let engine;\n if (arguments.length === 3) {\n pageX = xOrPos;\n pageY = yOrEngine;\n pagePos = new Vector(pageX, pageY);\n engine = engineOrUndefined;\n }\n else {\n pagePos = xOrPos;\n pageX = pagePos.x;\n pageY = pagePos.y;\n engine = yOrEngine;\n }\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\n }\n constructor(worldPos, pagePos, screenPos) {\n this.worldPos = worldPos;\n this.pagePos = pagePos;\n this.screenPos = screenPos;\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerEvent.ts\nclass PointerEvent {\n cancel() {\n this.active = false;\n }\n get pagePos() {\n return this.coordinates.pagePos;\n }\n get screenPos() {\n return this.coordinates.screenPos;\n }\n get worldPos() {\n return this.coordinates.worldPos;\n }\n constructor(type, pointerId, button, pointerType, coordinates, nativeEvent) {\n this.type = type;\n this.pointerId = pointerId;\n this.button = button;\n this.pointerType = pointerType;\n this.coordinates = coordinates;\n this.nativeEvent = nativeEvent;\n this.active = true;\n }\n ;\n}\n\n;// CONCATENATED MODULE: ./Input/WheelEvent.ts\nclass WheelEvent {\n cancel() {\n this.active = false;\n }\n constructor(x, y, pageX, pageY, screenX, screenY, index, deltaX, deltaY, deltaZ, deltaMode, ev) {\n this.x = x;\n this.y = y;\n this.pageX = pageX;\n this.pageY = pageY;\n this.screenX = screenX;\n this.screenY = screenY;\n this.index = index;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.deltaZ = deltaZ;\n this.deltaMode = deltaMode;\n this.ev = ev;\n this.active = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerAbstraction.ts\n\n\nclass PointerAbstraction {\n constructor() {\n this.events = new EventEmitter();\n /**\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\n */\n this.lastPagePos = Vector.Zero;\n /**\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\n */\n this.lastScreenPos = Vector.Zero;\n /**\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\n */\n this.lastWorldPos = Vector.Zero;\n this._onPointerMove = (ev) => {\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this._onPointerDown = (ev) => {\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this.on('move', this._onPointerMove);\n this.on('down', this._onPointerDown);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n}\n\n;// CONCATENATED MODULE: ./Input/WheelDeltaMode.ts\nvar WheelDeltaMode;\n(function (WheelDeltaMode) {\n WheelDeltaMode[\"Pixel\"] = \"Pixel\";\n WheelDeltaMode[\"Line\"] = \"Line\";\n WheelDeltaMode[\"Page\"] = \"Page\";\n})(WheelDeltaMode || (WheelDeltaMode = {}));\n\n;// CONCATENATED MODULE: ./Input/NativePointerButton.ts\n/**\n * Native browser button enumeration\n */\nvar NativePointerButton;\n(function (NativePointerButton) {\n NativePointerButton[NativePointerButton[\"NoButton\"] = -1] = \"NoButton\";\n NativePointerButton[NativePointerButton[\"Left\"] = 0] = \"Left\";\n NativePointerButton[NativePointerButton[\"Middle\"] = 1] = \"Middle\";\n NativePointerButton[NativePointerButton[\"Right\"] = 2] = \"Right\";\n NativePointerButton[NativePointerButton[\"Unknown\"] = 3] = \"Unknown\";\n})(NativePointerButton || (NativePointerButton = {}));\n\n;// CONCATENATED MODULE: ./Input/PointerButton.ts\n/**\n * The mouse button being pressed.\n */\nvar PointerButton;\n(function (PointerButton) {\n PointerButton[\"Left\"] = \"Left\";\n PointerButton[\"Middle\"] = \"Middle\";\n PointerButton[\"Right\"] = \"Right\";\n PointerButton[\"Unknown\"] = \"Unknown\";\n PointerButton[\"NoButton\"] = \"NoButton\";\n})(PointerButton || (PointerButton = {}));\n\n;// CONCATENATED MODULE: ./Input/PointerType.ts\n/**\n * The type of pointer for a [[PointerEvent]].\n */\nvar PointerType;\n(function (PointerType) {\n PointerType[\"Touch\"] = \"Touch\";\n PointerType[\"Mouse\"] = \"Mouse\";\n PointerType[\"Pen\"] = \"Pen\";\n PointerType[\"Unknown\"] = \"Unknown\";\n})(PointerType || (PointerType = {}));\n\n;// CONCATENATED MODULE: ./Input/PointerEventReceiver.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst PointerEvents = {\n Move: 'move',\n Down: 'down',\n Up: 'up',\n Wheel: 'wheel'\n};\n/**\n * Is this event a native touch event?\n */\nfunction isTouchEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\n}\n/**\n * Is this event a native pointer event\n */\nfunction isPointerEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\n}\n/**\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\n */\nclass PointerEventReceiver {\n constructor(target, engine) {\n this.target = target;\n this.engine = engine;\n this.events = new EventEmitter();\n this.primary = new PointerAbstraction();\n this._activeNativePointerIdsToNormalized = new Map();\n this.lastFramePointerCoords = new Map();\n this.currentFramePointerCoords = new Map();\n this.currentFramePointerDown = new Map();\n this.lastFramePointerDown = new Map();\n this.currentFrameDown = [];\n this.currentFrameUp = [];\n this.currentFrameMove = [];\n this.currentFrameCancel = [];\n this.currentFrameWheel = [];\n this._enabled = true;\n this._pointers = [this.primary];\n this._boundHandle = this._handle.bind(this);\n this._boundWheel = this._handleWheel.bind(this);\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n /**\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\n * handlers.\n * @param target\n * @param engine\n */\n recreate(target, engine) {\n const eventReceiver = new PointerEventReceiver(target, engine);\n eventReceiver.primary = this.primary;\n eventReceiver._pointers = this._pointers;\n return eventReceiver;\n }\n /**\n * Locates a specific pointer by id, creates it if it doesn't exist\n * @param index\n */\n at(index) {\n if (index >= this._pointers.length) {\n // Ensure there is a pointer to retrieve\n for (let i = this._pointers.length - 1, max = index; i < max; i++) {\n this._pointers.push(new PointerAbstraction());\n }\n }\n return this._pointers[index];\n }\n /**\n * The number of pointers currently being tracked by excalibur\n */\n count() {\n return this._pointers.length;\n }\n /**\n * Is the specified pointer id down this frame\n * @param pointerId\n */\n isDown(pointerId) {\n var _a;\n return (_a = this.currentFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\n * Was the specified pointer id down last frame\n * @param pointerId\n */\n wasDown(pointerId) {\n var _a;\n return (_a = this.lastFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\n * Whether the Pointer is currently dragging.\n */\n isDragging(pointerId) {\n return this.isDown(pointerId);\n }\n /**\n * Whether the Pointer just started dragging.\n */\n isDragStart(pointerId) {\n return this.isDown(pointerId) && !this.wasDown(pointerId);\n }\n /**\n * Whether the Pointer just ended dragging.\n */\n isDragEnd(pointerId) {\n return !this.isDown(pointerId) && this.wasDown(pointerId);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Called internally by excalibur\n *\n * Updates the current frame pointer info and emits raw pointer events\n *\n * This does not emit events to entities, see PointerSystem\n */\n update() {\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\n for (const event of this.currentFrameDown) {\n this.emit('down', event);\n const pointer = this.at(event.pointerId);\n pointer.emit('down', event);\n this.primary.emit('pointerdown', event);\n }\n for (const event of this.currentFrameUp) {\n this.emit('up', event);\n const pointer = this.at(event.pointerId);\n pointer.emit('up', event);\n }\n for (const event of this.currentFrameMove) {\n this.emit('move', event);\n const pointer = this.at(event.pointerId);\n pointer.emit('move', event);\n }\n for (const event of this.currentFrameCancel) {\n this.emit('cancel', event);\n const pointer = this.at(event.pointerId);\n pointer.emit('cancel', event);\n }\n for (const event of this.currentFrameWheel) {\n this.emit('wheel', event);\n this.primary.emit('pointerwheel', event);\n this.primary.emit('wheel', event);\n }\n }\n /**\n * Clears the current frame event and pointer data\n */\n clear() {\n for (const event of this.currentFrameUp) {\n this.currentFramePointerCoords.delete(event.pointerId);\n const ids = this._activeNativePointerIdsToNormalized.entries();\n for (const [native, normalized] of ids) {\n if (normalized === event.pointerId) {\n this._activeNativePointerIdsToNormalized.delete(native);\n }\n }\n }\n this.currentFrameDown.length = 0;\n this.currentFrameUp.length = 0;\n this.currentFrameMove.length = 0;\n this.currentFrameCancel.length = 0;\n this.currentFrameWheel.length = 0;\n }\n /**\n * Initializes the pointer event receiver so that it can start listening to native\n * browser events.\n */\n init(options) {\n var _a;\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\n // It is important on mobile to have touch action 'none'\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\n if (this.target === this.engine.canvas) {\n this.engine.canvas.style.touchAction = 'none';\n }\n else {\n document.body.style.touchAction = 'none';\n }\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.addEventListener('pointerdown', this._boundHandle);\n this.target.addEventListener('pointerup', this._boundHandle);\n this.target.addEventListener('pointermove', this._boundHandle);\n this.target.addEventListener('pointercancel', this._boundHandle);\n }\n else {\n // Touch Events\n this.target.addEventListener('touchstart', this._boundHandle);\n this.target.addEventListener('touchend', this._boundHandle);\n this.target.addEventListener('touchmove', this._boundHandle);\n this.target.addEventListener('touchcancel', this._boundHandle);\n // Mouse Events\n this.target.addEventListener('mousedown', this._boundHandle);\n this.target.addEventListener('mouseup', this._boundHandle);\n this.target.addEventListener('mousemove', this._boundHandle);\n }\n // MDN MouseWheelEvent\n const wheelOptions = {\n passive: !(this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas)\n };\n if ('onwheel' in document.createElement('div')) {\n // Modern Browsers\n this.target.addEventListener('wheel', this._boundWheel, wheelOptions);\n }\n else if (document.onmousewheel !== undefined) {\n // Webkit and IE\n this.target.addEventListener('mousewheel', this._boundWheel, wheelOptions);\n }\n else {\n // Remaining browser and older Firefox\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel, wheelOptions);\n }\n const grabWindowFocus = (_a = options === null || options === void 0 ? void 0 : options.grabWindowFocus) !== null && _a !== void 0 ? _a : true;\n // Handle cross origin iframe\n if (grabWindowFocus && isCrossOriginIframe()) {\n const grabFocus = () => {\n window.focus();\n };\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.addEventListener('pointerdown', grabFocus);\n }\n else {\n // Touch Events\n this.target.addEventListener('touchstart', grabFocus);\n // Mouse Events\n this.target.addEventListener('mousedown', grabFocus);\n }\n }\n }\n detach() {\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.removeEventListener('pointerdown', this._boundHandle);\n this.target.removeEventListener('pointerup', this._boundHandle);\n this.target.removeEventListener('pointermove', this._boundHandle);\n this.target.removeEventListener('pointercancel', this._boundHandle);\n }\n else {\n // Touch Events\n this.target.removeEventListener('touchstart', this._boundHandle);\n this.target.removeEventListener('touchend', this._boundHandle);\n this.target.removeEventListener('touchmove', this._boundHandle);\n this.target.removeEventListener('touchcancel', this._boundHandle);\n // Mouse Events\n this.target.removeEventListener('mousedown', this._boundHandle);\n this.target.removeEventListener('mouseup', this._boundHandle);\n this.target.removeEventListener('mousemove', this._boundHandle);\n }\n if ('onwheel' in document.createElement('div')) {\n // Modern Browsers\n this.target.removeEventListener('wheel', this._boundWheel);\n }\n else if (document.onmousewheel !== undefined) {\n // Webkit and IE\n this.target.addEventListener('mousewheel', this._boundWheel);\n }\n else {\n // Remaining browser and older Firefox\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel);\n }\n }\n /**\n * Take native pointer id and map it to index in active pointers\n * @param nativePointerId\n */\n _normalizePointerId(nativePointerId) {\n // Add to the the native pointer set id\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\n // Native pointer ids in ascending order\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b) => a - b);\n // The index into sorted ids will be the new id, will always have an id\n const id = currentPointerIds.findIndex(p => p === nativePointerId);\n // Save the mapping so we can reverse it later\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\n // ignore pointer because game isn't watching\n return id;\n }\n /**\n * Responsible for handling and parsing pointer events\n */\n _handle(ev) {\n if (!this._enabled) {\n return;\n }\n ev.preventDefault();\n const eventCoords = new Map();\n let button;\n let pointerType;\n if (isTouchEvent(ev)) {\n button = PointerButton.Unknown;\n pointerType = PointerType.Touch;\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\n for (let i = 0; i < ev.changedTouches.length; i++) {\n const touch = ev.changedTouches[i];\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\n const nativePointerId = i + 1;\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n }\n else {\n button = this._nativeButtonToPointerButton(ev.button);\n pointerType = PointerType.Mouse;\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\n let nativePointerId = 1;\n if (isPointerEvent(ev)) {\n nativePointerId = ev.pointerId;\n pointerType = this._stringToPointerType(ev.pointerType);\n }\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n for (const [pointerId, coord] of eventCoords.entries()) {\n switch (ev.type) {\n case 'mousedown':\n case 'pointerdown':\n case 'touchstart':\n this.currentFrameDown.push(new PointerEvent('down', pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, true);\n break;\n case 'mouseup':\n case 'pointerup':\n case 'touchend':\n this.currentFrameUp.push(new PointerEvent('up', pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, false);\n break;\n case 'mousemove':\n case 'pointermove':\n case 'touchmove':\n this.currentFrameMove.push(new PointerEvent('move', pointerId, button, pointerType, coord, ev));\n break;\n case 'touchcancel':\n case 'pointercancel':\n this.currentFrameCancel.push(new PointerEvent('cancel', pointerId, button, pointerType, coord, ev));\n break;\n }\n }\n }\n _handleWheel(ev) {\n if (!this._enabled) {\n return;\n }\n // Should we prevent page scroll because of this event\n if (this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\n (this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas)) {\n ev.preventDefault();\n }\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\n const world = this.engine.screen.screenToWorldCoordinates(screen);\n /**\n * A constant used to normalize wheel events across different browsers\n *\n * This normalization factor is pulled from\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\n */\n const ScrollWheelNormalizationFactor = -1 / 40;\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\n const deltaY = ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\n const deltaZ = ev.deltaZ || 0;\n let deltaMode = WheelDeltaMode.Pixel;\n if (ev.deltaMode) {\n if (ev.deltaMode === 1) {\n deltaMode = WheelDeltaMode.Line;\n }\n else if (ev.deltaMode === 2) {\n deltaMode = WheelDeltaMode.Page;\n }\n }\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\n this.currentFrameWheel.push(we);\n }\n /**\n * Triggers an excalibur pointer event in a world space pos\n *\n * Useful for testing pointers in excalibur\n * @param type\n * @param pos\n */\n triggerEvent(type, pos) {\n const page = this.engine.screen.worldToPageCoordinates(pos);\n // Send an event to the event receiver\n if (window.PointerEvent) {\n this._handle(new window.PointerEvent('pointer' + type, {\n pointerId: 0,\n clientX: page.x,\n clientY: page.y\n }));\n }\n else {\n // Safari hack\n this._handle(new window.MouseEvent('mouse' + type, {\n clientX: page.x,\n clientY: page.y\n }));\n }\n // Force update pointer system\n const pointerSystem = this.engine.currentScene.world.get(PointerSystem);\n pointerSystem.preupdate(this.engine.currentScene, 1);\n pointerSystem.update(1);\n }\n _nativeButtonToPointerButton(s) {\n switch (s) {\n case NativePointerButton.NoButton:\n return PointerButton.NoButton;\n case NativePointerButton.Left:\n return PointerButton.Left;\n case NativePointerButton.Middle:\n return PointerButton.Middle;\n case NativePointerButton.Right:\n return PointerButton.Right;\n case NativePointerButton.Unknown:\n return PointerButton.Unknown;\n default:\n return fail(s);\n }\n }\n _stringToPointerType(s) {\n switch (s) {\n case 'touch':\n return PointerType.Touch;\n case 'mouse':\n return PointerType.Mouse;\n case 'pen':\n return PointerType.Pen;\n default:\n return PointerType.Unknown;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Input/InputHost.ts\n\n\n\n\nclass InputHost {\n constructor(options) {\n this._enabled = true;\n const { pointerTarget, grabWindowFocus, engine } = options;\n this.keyboard = new Keyboard();\n this.pointers = new PointerEventReceiver(pointerTarget, engine);\n this.gamepads = new Gamepads();\n this.keyboard.init({ grabWindowFocus });\n this.pointers.init({ grabWindowFocus });\n this.gamepads.init();\n this.inputMapper = new InputMapper({\n keyboard: this.keyboard,\n pointers: this.pointers,\n gamepads: this.gamepads\n });\n }\n get enabled() {\n return this._enabled;\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n this.keyboard.toggleEnabled(this._enabled);\n this.pointers.toggleEnabled(this._enabled);\n this.gamepads.toggleEnabled(this._enabled);\n }\n update() {\n if (this._enabled) {\n this.inputMapper.execute();\n this.keyboard.update();\n this.gamepads.update();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Scene.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nclass PreLoadEvent {\n}\nconst SceneEvents = {\n Initialize: 'initialize',\n Activate: 'activate',\n Deactivate: 'deactivate',\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate',\n PreDraw: 'predraw',\n PostDraw: 'postdraw',\n PreDebugDraw: 'predebugdraw',\n PostDebugDraw: 'postdebugdraw',\n PreLoad: 'preload'\n};\n/**\n *\n */\nfunction isSceneConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n}\n/**\n * [[Actor|Actors]] are composed together into groupings called Scenes in\n * Excalibur. The metaphor models the same idea behind real world\n * actors in a scene. Only actors in scenes will be updated and drawn.\n *\n * Typical usages of a scene include: levels, menus, loading screens, etc.\n */\nclass Scene {\n /**\n * The actors in the current scene\n */\n get actors() {\n return this.world.entityManager.entities.filter((e) => {\n return e instanceof Actor;\n });\n }\n /**\n * The entities in the current scene\n */\n get entities() {\n return this.world.entityManager.entities;\n }\n /**\n * The triggers in the current scene\n */\n get triggers() {\n return this.world.entityManager.entities.filter((e) => {\n return e instanceof Trigger;\n });\n }\n /**\n * The [[TileMap]]s in the scene, if any\n */\n get tileMaps() {\n return this.world.entityManager.entities.filter((e) => {\n return e instanceof TileMap;\n });\n }\n get timers() {\n return this._timers;\n }\n constructor() {\n // Initialize systems\n this._logger = Logger.getInstance();\n this.events = new EventEmitter();\n /**\n * Gets or sets the current camera for the scene\n */\n this.camera = new Camera();\n /**\n * The ECS world for the scene\n */\n this.world = new World(this);\n /**\n * The Excalibur physics world for the scene. Used to interact\n * with colliders included in the scene.\n *\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\n */\n this.physics = new PhysicsWorld(DefaultPhysicsConfig);\n this._isInitialized = false;\n this._timers = [];\n this._cancelQueue = [];\n // Update\n this.world.add(ActionsSystem);\n this.world.add(new MotionSystem(this.world, this.physics));\n this.world.add(new CollisionSystem(this.world, this.physics));\n this.world.add(PointerSystem);\n this.world.add(IsometricEntitySystem);\n // Draw\n this.world.add(OffscreenSystem);\n this.world.add(GraphicsSystem);\n this.world.add(DebugSystem);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Event hook to provide Scenes a way of loading scene specific resources.\n *\n * This is called before the Scene.onInitialize during scene transition. It will only ever fire once for a scene.\n * @param loader\n */\n onPreLoad(loader) {\n // will be overridden\n }\n /**\n * Event hook fired directly before transition, either \"in\" or \"out\" of the scene\n *\n * This overrides the Engine scene definition. However transitions specified in goToScene take highest precedence\n *\n * ```typescript\n * // Overrides all\n * Engine.goToScene('scene', { destinationIn: ..., sourceOut: ... });\n * ```\n *\n * This can be used to configure custom transitions for a scene dynamically\n */\n onTransition(direction) {\n // will be overridden\n return undefined;\n }\n /**\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\n * overridden. This is where initialization of child actors should take place.\n */\n onInitialize(engine) {\n // will be overridden\n }\n /**\n * This is called when the scene is made active and started. It is meant to be overridden,\n * this is where you should setup any DOM UI or event handlers needed for the scene.\n */\n onActivate(context) {\n // will be overridden\n }\n /**\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\n */\n onDeactivate(context) {\n // will be overridden\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before a scene is updated.\n */\n onPreUpdate(engine, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */\n onPostUpdate(engine, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreDraw` is called directly before a scene is drawn.\n *\n */\n onPreDraw(ctx, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostDraw` is called directly after a scene is drawn.\n *\n */\n onPostDraw(ctx, delta) {\n // will be overridden\n }\n /**\n * Initializes actors in the scene\n */\n _initializeChildren() {\n for (const child of this.entities) {\n child._initialize(this.engine);\n }\n }\n /**\n * Gets whether or not the [[Scene]] has been initialized\n */\n get isInitialized() {\n return this._isInitialized;\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Initializes the scene before the first update, meant to be called by engine not by users of\n * Excalibur\n * @internal\n */\n async _initialize(engine) {\n var _a;\n if (!this.isInitialized) {\n try {\n this.engine = engine;\n // PhysicsWorld config is watched so things will automagically update\n this.physics.config = this.engine.physics;\n this.input = new InputHost({\n pointerTarget: engine.pointerScope === PointerScope.Canvas ? engine.canvas : document,\n grabWindowFocus: engine.grabWindowFocus,\n engine\n });\n // Initialize camera first\n this.camera._initialize(engine);\n this.world.systemManager.initialize();\n // This order is important! we want to be sure any custom init that add actors\n // fire before the actor init\n await this.onInitialize(engine);\n this._initializeChildren();\n this._logger.debug('Scene.onInitialize', this, engine);\n this.events.emit('initialize', new InitializeEvent(engine, this));\n }\n catch (e) {\n this._logger.error(`Error during scene initialization for scene ${(_a = engine.director) === null || _a === void 0 ? void 0 : _a.getSceneName(this)}!`);\n throw e;\n }\n this._isInitialized = true;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\n * @internal\n */\n async _activate(context) {\n var _a, _b;\n try {\n this._logger.debug('Scene.onActivate', this);\n this.input.toggleEnabled(true);\n await this.onActivate(context);\n }\n catch (e) {\n this._logger.error(`Error during scene activation for scene ${(_b = (_a = this.engine) === null || _a === void 0 ? void 0 : _a.director) === null || _b === void 0 ? void 0 : _b.getSceneName(this)}!`);\n throw e;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\n * @internal\n */\n async _deactivate(context) {\n this._logger.debug('Scene.onDeactivate', this);\n this.input.toggleEnabled(false);\n await this.onDeactivate(context);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */\n _preupdate(engine, delta) {\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */\n _postupdate(engine, delta) {\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\n * @internal\n */\n _predraw(ctx, delta) {\n this.emit('predraw', new PreDrawEvent(ctx, delta, this));\n this.onPreDraw(ctx, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\n * @internal\n */\n _postdraw(ctx, delta) {\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\n this.onPostDraw(ctx, delta);\n }\n /**\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\n * @param engine Reference to the current Engine\n * @param delta The number of milliseconds since the last update\n */\n update(engine, delta) {\n var _a;\n if (!this.isInitialized) {\n this._logger.warnOnce(`Scene update called before initialize for scene ${(_a = engine.director) === null || _a === void 0 ? void 0 : _a.getSceneName(this)}!`);\n return;\n }\n this._preupdate(engine, delta);\n // TODO differed entity removal for timers\n let i, len;\n // Remove timers in the cancel queue before updating them\n for (i = 0, len = this._cancelQueue.length; i < len; i++) {\n this.removeTimer(this._cancelQueue[i]);\n }\n this._cancelQueue.length = 0;\n // Cycle through timers updating timers\n for (const timer of this._timers) {\n timer.update(delta);\n }\n this.world.update(SystemType.Update, delta);\n // Camera last keeps renders smooth that are based on entity/actor\n if (this.camera) {\n this.camera.update(engine, delta);\n }\n this._collectActorStats(engine);\n this._postupdate(engine, delta);\n this.input.update();\n }\n /**\n * Draws all the actors in the Scene. Called by the [[Engine]].\n * @param ctx The current rendering context\n * @param delta The number of milliseconds since the last draw\n */\n draw(ctx, delta) {\n var _a;\n if (!this.isInitialized) {\n this._logger.warnOnce(`Scene draw called before initialize!`);\n return;\n }\n this._predraw(ctx, delta);\n this.world.update(SystemType.Draw, delta);\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.isDebug) {\n this.debugDraw(ctx);\n }\n this._postdraw(ctx, delta);\n }\n /**\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\n * @param ctx The current rendering context\n */\n /* istanbul ignore next */\n debugDraw(ctx) {\n this.emit('predebugdraw', new PreDebugDrawEvent(ctx, this));\n // pass\n this.emit('postdebugdraw', new PostDebugDrawEvent(ctx, this));\n }\n /**\n * Checks whether an actor is contained in this scene or not\n */\n contains(actor) {\n return this.actors.indexOf(actor) > -1;\n }\n add(entity) {\n this.emit('entityadded', { target: entity });\n this.world.add(entity);\n entity.scene = this;\n if (entity instanceof Timer) {\n if (!contains(this._timers, entity)) {\n this.addTimer(entity);\n }\n return;\n }\n }\n /**\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\n * and adds it to this scene.\n *\n * Useful if you want to have an object be present in only 1 scene at a time.\n * @param entity\n */\n transfer(entity) {\n let scene;\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\n scene = entity.scene;\n entity.scene.world.remove(entity, false);\n }\n if (entity instanceof Timer && entity.scene) {\n scene = entity.scene;\n entity.scene.removeTimer(entity);\n }\n scene === null || scene === void 0 ? void 0 : scene.emit('entityremoved', { target: entity });\n this.add(entity);\n }\n remove(entity) {\n if (entity instanceof Entity) {\n this.emit('entityremoved', { target: entity });\n if (entity.active) {\n entity.kill();\n }\n this.world.remove(entity);\n }\n if (entity instanceof Timer) {\n this.removeTimer(entity);\n }\n }\n /**\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\n *\n * By default entities use deferred removal\n * @param deferred\n */\n clear(deferred = true) {\n for (let i = this.entities.length - 1; i >= 0; i--) {\n this.world.remove(this.entities[i], deferred);\n }\n for (let i = this.timers.length - 1; i >= 0; i--) {\n this.removeTimer(this.timers[i]);\n }\n }\n /**\n * Adds a [[Timer]] to the scene\n * @param timer The timer to add\n */\n addTimer(timer) {\n this._timers.push(timer);\n timer.scene = this;\n return timer;\n }\n /**\n * Removes a [[Timer]] from the scene.\n * @warning Can be dangerous, use [[cancelTimer]] instead\n * @param timer The timer to remove\n */\n removeTimer(timer) {\n const i = this._timers.indexOf(timer);\n if (i !== -1) {\n this._timers.splice(i, 1);\n }\n return timer;\n }\n /**\n * Cancels a [[Timer]], removing it from the scene nicely\n * @param timer The timer to cancel\n */\n cancelTimer(timer) {\n this._cancelQueue.push(timer);\n return timer;\n }\n /**\n * Tests whether a [[Timer]] is active in the scene\n */\n isTimerActive(timer) {\n return this._timers.indexOf(timer) > -1 && !timer.complete;\n }\n isCurrentScene() {\n if (this.engine) {\n return this.engine.currentScene === this;\n }\n return false;\n }\n _collectActorStats(engine) {\n const screenElements = this.actors.filter((a) => a instanceof ScreenElement);\n for (const _ui of screenElements) {\n engine.stats.currFrame.actors.ui++;\n }\n for (const actor of this.actors) {\n engine.stats.currFrame.actors.alive++;\n for (const child of actor.children) {\n if (isScreenElement(child)) {\n // TODO not true\n engine.stats.currFrame.actors.ui++;\n }\n else {\n engine.stats.currFrame.actors.alive++;\n }\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ColorBlindnessMode.ts\nvar ColorBlindnessMode;\n(function (ColorBlindnessMode) {\n ColorBlindnessMode[\"Protanope\"] = \"Protanope\";\n ColorBlindnessMode[\"Deuteranope\"] = \"Deuteranope\";\n ColorBlindnessMode[\"Tritanope\"] = \"Tritanope\";\n})(ColorBlindnessMode || (ColorBlindnessMode = {}));\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/color-blind-fragment.glsl\n/* harmony default export */ const color_blind_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ScreenShader.ts\n\n\n\n/**\n * Helper that defines a whole screen renderer, just provide a fragment source!\n *\n * Currently supports 1 varying\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\n */\nclass ScreenShader {\n constructor(gl, fragmentSource) {\n this._shader = new Shader({\n gl,\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\n fragmentSource: fragmentSource\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl,\n type: 'static',\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1, -1, 0, 0,\n -1, 1, 0, 1,\n 1, -1, 1, 0,\n 1, -1, 1, 0,\n -1, 1, 0, 1,\n 1, 1, 1, 1\n ])\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_texcoord', 2]\n ]\n });\n this._buffer.upload();\n }\n getShader() {\n return this._shader;\n }\n getLayout() {\n return this._layout;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ColorBlindnessPostProcessor.ts\n\n\n\nclass ColorBlindnessPostProcessor {\n constructor(_colorBlindnessMode, simulate = false) {\n this._colorBlindnessMode = _colorBlindnessMode;\n this._simulate = false;\n this._simulate = simulate;\n }\n initialize(gl) {\n this._shader = new ScreenShader(gl, color_blind_fragment);\n this.simulate = this._simulate;\n this.colorBlindnessMode = this._colorBlindnessMode;\n }\n getShader() {\n return this._shader.getShader();\n }\n getLayout() {\n return this._shader.getLayout();\n }\n set colorBlindnessMode(colorBlindMode) {\n this._colorBlindnessMode = colorBlindMode;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) {\n shader.setUniformInt('u_type', 0);\n }\n else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) {\n shader.setUniformInt('u_type', 1);\n }\n else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) {\n shader.setUniformInt('u_type', 2);\n }\n }\n }\n get colorBlindnessMode() {\n return this._colorBlindnessMode;\n }\n set simulate(value) {\n this._simulate = value;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n shader.setUniformBoolean('u_simulate', value);\n }\n }\n get simulate() {\n return this._simulate;\n }\n}\n\n;// CONCATENATED MODULE: ./Debug/DebugFlags.ts\n\n\n\nclass ColorBlindFlags {\n constructor(engine) {\n this._engine = engine;\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\n }\n /**\n * Correct colors for a specified color blindness\n * @param colorBlindness\n */\n correct(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = false;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Simulate colors for a specified color blindness\n * @param colorBlindness\n */\n simulate(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = true;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Remove color blindness post processor\n */\n clear() {\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\n }\n}\n\n;// CONCATENATED MODULE: ./Debug/DebugConfig.ts\n\n\n/**\n * Debug statistics and flags for Excalibur. If polling these values, it would be\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\n * updated during a frame.\n */\nclass DebugConfig {\n constructor(engine) {\n /**\n * Performance statistics\n */\n this.stats = {\n /**\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\n * Best accessed on [[postframe]] event. See [[FrameStats]]\n */\n currFrame: new FrameStats(),\n /**\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\n */\n prevFrame: new FrameStats()\n };\n /**\n * Filter debug context to named entities or entity ids\n */\n this.filter = {\n /**\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\n */\n useFilter: false,\n /**\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\n */\n nameQuery: '',\n /**\n * Query for Entity ids, if the id matches it will be included\n */\n ids: []\n };\n /**\n * Entity debug settings\n */\n this.entity = {\n showAll: false,\n showId: false,\n showName: false\n };\n /**\n * Transform component debug settings\n */\n this.transform = {\n showAll: false,\n debugZIndex: 10000000,\n showPosition: false,\n showPositionLabel: false,\n positionColor: Color.Yellow,\n showZIndex: false,\n showScale: false,\n scaleColor: Color.Green,\n showRotation: false,\n rotationColor: Color.Blue\n };\n /**\n * Graphics component debug settings\n */\n this.graphics = {\n showAll: false,\n showBounds: false,\n boundsColor: Color.Yellow\n };\n /**\n * Collider component debug settings\n */\n this.collider = {\n showAll: false,\n showBounds: false,\n boundsColor: Color.Blue,\n showOwner: false,\n showGeometry: true,\n geometryColor: Color.Green,\n geometryLineWidth: 1,\n geometryPointSize: .5\n };\n /**\n * Physics simulation debug settings\n */\n this.physics = {\n showAll: false,\n showBroadphaseSpacePartitionDebug: false,\n showCollisionNormals: false,\n collisionNormalColor: Color.Cyan,\n showCollisionContacts: true,\n contactSize: 2,\n collisionContactColor: Color.Red\n };\n /**\n * Motion component debug settings\n */\n this.motion = {\n showAll: false,\n showVelocity: false,\n velocityColor: Color.Yellow,\n showAcceleration: false,\n accelerationColor: Color.Red\n };\n /**\n * Body component debug settings\n */\n this.body = {\n showAll: false,\n showCollisionGroup: false,\n showCollisionType: false,\n showSleeping: false,\n showMotion: false,\n showMass: false\n };\n /**\n * Camera debug settings\n */\n this.camera = {\n showAll: false,\n showFocus: false,\n focusColor: Color.Red,\n showZoom: false\n };\n this.tilemap = {\n showAll: false,\n showGrid: false,\n gridColor: Color.Red,\n gridWidth: .5,\n showSolidBounds: false,\n solidBoundsColor: Color.fromHex('#8080807F'), // grayish\n showColliderGeometry: true\n };\n this.isometric = {\n showAll: false,\n showPosition: false,\n positionColor: Color.Yellow,\n positionSize: 1,\n showGrid: false,\n gridColor: Color.Red,\n gridWidth: 1,\n showColliderGeometry: true\n };\n this._engine = engine;\n this.colorBlindMode = new ColorBlindFlags(this._engine);\n }\n /**\n * Switch the current excalibur clock with the [[TestClock]] and return\n * it in the same running state.\n *\n * This is useful when you need to debug frame by frame.\n */\n useTestClock() {\n const clock = this._engine.clock;\n const wasRunning = clock.isRunning();\n clock.stop();\n const testClock = clock.toTestClock();\n if (wasRunning) {\n testClock.start();\n }\n this._engine.clock = testClock;\n return testClock;\n }\n /**\n * Switch the current excalibur clock with the [[StandardClock]] and\n * return it in the same running state.\n *\n * This is useful when you need to switch back to normal mode after\n * debugging.\n */\n useStandardClock() {\n const currentClock = this._engine.clock;\n const wasRunning = currentClock.isRunning();\n currentClock.stop();\n const standardClock = currentClock.toStandardClock();\n if (wasRunning) {\n standardClock.start();\n }\n this._engine.clock = standardClock;\n return standardClock;\n }\n}\n/**\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\n * creating instances of this every frame.\n */\nclass FrameStats {\n constructor() {\n this._id = 0;\n this._delta = 0;\n this._fps = 0;\n this._actorStats = {\n alive: 0,\n killed: 0,\n ui: 0,\n get remaining() {\n return this.alive - this.killed;\n },\n get total() {\n return this.remaining + this.ui;\n }\n };\n this._durationStats = {\n update: 0,\n draw: 0,\n get total() {\n return this.update + this.draw;\n }\n };\n this._physicsStats = new PhysicsStats();\n this._graphicsStats = {\n drawCalls: 0,\n drawnImages: 0\n };\n }\n /**\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\n * @param [otherStats] Optional stats to clone\n */\n reset(otherStats) {\n if (otherStats) {\n this.id = otherStats.id;\n this.delta = otherStats.delta;\n this.fps = otherStats.fps;\n this.actors.alive = otherStats.actors.alive;\n this.actors.killed = otherStats.actors.killed;\n this.actors.ui = otherStats.actors.ui;\n this.duration.update = otherStats.duration.update;\n this.duration.draw = otherStats.duration.draw;\n this._physicsStats.reset(otherStats.physics);\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\n }\n else {\n this.id = this.delta = this.fps = 0;\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\n this.duration.update = this.duration.draw = 0;\n this._physicsStats.reset();\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\n }\n }\n /**\n * Provides a clone of this instance.\n */\n clone() {\n const fs = new FrameStats();\n fs.reset(this);\n return fs;\n }\n /**\n * Gets the frame's id\n */\n get id() {\n return this._id;\n }\n /**\n * Sets the frame's id\n */\n set id(value) {\n this._id = value;\n }\n /**\n * Gets the frame's delta (time since last frame)\n */\n get delta() {\n return this._delta;\n }\n /**\n * Sets the frame's delta (time since last frame). Internal use only.\n * @internal\n */\n set delta(value) {\n this._delta = value;\n }\n /**\n * Gets the frame's frames-per-second (FPS)\n */\n get fps() {\n return this._fps;\n }\n /**\n * Sets the frame's frames-per-second (FPS). Internal use only.\n * @internal\n */\n set fps(value) {\n this._fps = value;\n }\n /**\n * Gets the frame's actor statistics\n */\n get actors() {\n return this._actorStats;\n }\n /**\n * Gets the frame's duration statistics\n */\n get duration() {\n return this._durationStats;\n }\n /**\n * Gets the frame's physics statistics\n */\n get physics() {\n return this._physicsStats;\n }\n /**\n * Gets the frame's graphics statistics\n */\n get graphics() {\n return this._graphicsStats;\n }\n}\nclass PhysicsStats {\n constructor() {\n this._pairs = 0;\n this._collisions = 0;\n this._contacts = new Map();\n this._fastBodies = 0;\n this._fastBodyCollisions = 0;\n this._broadphase = 0;\n this._narrowphase = 0;\n }\n /**\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\n * @param [otherStats] Optional stats to clone\n */\n reset(otherStats) {\n if (otherStats) {\n this.pairs = otherStats.pairs;\n this.collisions = otherStats.collisions;\n this.contacts = otherStats.contacts;\n this.fastBodies = otherStats.fastBodies;\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\n this.broadphase = otherStats.broadphase;\n this.narrowphase = otherStats.narrowphase;\n }\n else {\n this.pairs = this.collisions = this.fastBodies = 0;\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\n this.contacts.clear();\n }\n }\n /**\n * Provides a clone of this instance.\n */\n clone() {\n const ps = new PhysicsStats();\n ps.reset(this);\n return ps;\n }\n get pairs() {\n return this._pairs;\n }\n set pairs(value) {\n this._pairs = value;\n }\n get collisions() {\n return this._collisions;\n }\n set collisions(value) {\n this._collisions = value;\n }\n get contacts() {\n return this._contacts;\n }\n set contacts(contacts) {\n this._contacts = contacts;\n }\n get fastBodies() {\n return this._fastBodies;\n }\n set fastBodies(value) {\n this._fastBodies = value;\n }\n get fastBodyCollisions() {\n return this._fastBodyCollisions;\n }\n set fastBodyCollisions(value) {\n this._fastBodyCollisions = value;\n }\n get broadphase() {\n return this._broadphase;\n }\n set broadphase(value) {\n this._broadphase = value;\n }\n get narrowphase() {\n return this._narrowphase;\n }\n set narrowphase(value) {\n this._narrowphase = value;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Browser.ts\nclass BrowserComponent {\n on(eventName, handler) {\n if (this._nativeHandlers[eventName]) {\n this.off(eventName, this._nativeHandlers[eventName]);\n }\n this._nativeHandlers[eventName] = this._decorate(handler);\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\n }\n off(eventName, handler) {\n if (!handler) {\n handler = this._nativeHandlers[eventName];\n }\n this.nativeComponent.removeEventListener(eventName, handler);\n this._nativeHandlers[eventName] = null;\n }\n _decorate(handler) {\n return (evt) => {\n if (!this._paused) {\n handler(evt);\n }\n };\n }\n pause() {\n this._paused = true;\n }\n resume() {\n this._paused = false;\n }\n clear() {\n for (const event in this._nativeHandlers) {\n this.off(event);\n }\n }\n constructor(nativeComponent) {\n this.nativeComponent = nativeComponent;\n this._paused = false;\n this._nativeHandlers = {};\n }\n}\nclass BrowserEvents {\n constructor(_windowGlobal, _documentGlobal) {\n this._windowGlobal = _windowGlobal;\n this._documentGlobal = _documentGlobal;\n this._windowComponent = new BrowserComponent(this._windowGlobal);\n this._documentComponent = new BrowserComponent(this._documentGlobal);\n }\n get window() {\n return this._windowComponent;\n }\n get document() {\n return this._documentComponent;\n }\n pause() {\n this.window.pause();\n this.document.pause();\n }\n resume() {\n this.window.resume();\n this.document.resume();\n }\n clear() {\n this.window.clear();\n this.document.clear();\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/ExcaliburGraphicsContext.ts\n\nconst DefaultAntialiasOptions = {\n pixelArtSampler: false,\n nativeContextAntialiasing: false,\n multiSampleAntialiasing: true,\n filtering: ImageFiltering.Blended,\n canvasImageRendering: 'auto'\n};\nconst DefaultPixelArtOptions = {\n pixelArtSampler: true,\n nativeContextAntialiasing: false,\n multiSampleAntialiasing: true,\n filtering: ImageFiltering.Blended,\n canvasImageRendering: 'auto'\n};\n\n;// CONCATENATED MODULE: ./Util/Fps.ts\nclass FpsSampler {\n constructor(options) {\n var _a;\n this._samplePeriod = 100;\n this._currentFrameTime = 0;\n this._frames = 0;\n this._previousSampleTime = 0;\n this._beginFrameTime = 0;\n this._fps = options.initialFps;\n this._samplePeriod = (_a = options.samplePeriod) !== null && _a !== void 0 ? _a : this._samplePeriod;\n this._currentFrameTime = 1000 / options.initialFps;\n this._nowFn = options.nowFn;\n this._previousSampleTime = this._nowFn();\n }\n /**\n * Start of code block to sample FPS for\n */\n start() {\n this._beginFrameTime = this._nowFn();\n }\n /**\n * End of code block to sample FPS for\n */\n end() {\n this._frames++;\n const time = this._nowFn();\n this._currentFrameTime = time - this._beginFrameTime;\n if (time >= this._previousSampleTime + this._samplePeriod) {\n this._fps = (this._frames * 1000) / (time - this._previousSampleTime);\n this._previousSampleTime = time;\n this._frames = 0;\n }\n }\n /**\n * Return the currently sampled fps over the last sample period, by default every 100ms\n */\n get fps() {\n return this._fps;\n }\n /**\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\n */\n get instant() {\n return 1000 / this._currentFrameTime;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Clock.ts\n\n\n/**\n * Abstract Clock is the base type of all Clocks\n *\n * It has a few opinions\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\n * 2. The default timing api is implemented in now()\n *\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\n * method is unique to your clock implementation.\n */\nclass Clock {\n constructor(options) {\n var _a, _b, _c;\n this._onFatalException = () => { };\n this._maxFps = Infinity;\n this._lastTime = 0;\n this._elapsed = 1;\n this._scheduledCbs = [];\n this._totalElapsed = 0;\n this._options = options;\n this.tick = options.tick;\n this._lastTime = (_a = this.now()) !== null && _a !== void 0 ? _a : 0;\n this._maxFps = (_b = options.maxFps) !== null && _b !== void 0 ? _b : this._maxFps;\n this._onFatalException = (_c = options.onFatalException) !== null && _c !== void 0 ? _c : this._onFatalException;\n this.fpsSampler = new FpsSampler({\n initialFps: 60,\n nowFn: () => this.now()\n });\n }\n /**\n * Get the elapsed time for the last completed frame\n */\n elapsed() {\n return this._elapsed;\n }\n /**\n * Get the current time in milliseconds\n */\n now() {\n return performance.now();\n }\n toTestClock() {\n const testClock = new TestClock({\n ...this._options,\n defaultUpdateMs: 16.6\n });\n return testClock;\n }\n toStandardClock() {\n const clock = new StandardClock({\n ...this._options\n });\n return clock;\n }\n setFatalExceptionHandler(handler) {\n this._onFatalException = handler;\n }\n /**\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\n *\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\n * stopped or paused.\n * @param cb callback to fire\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\n */\n schedule(cb, timeoutMs = 0) {\n // Scheduled based on internal elapsed time\n const scheduledTime = this._totalElapsed + timeoutMs;\n this._scheduledCbs.push([cb, scheduledTime]);\n }\n _runScheduledCbs() {\n // walk backwards to delete items as we loop\n for (let i = this._scheduledCbs.length - 1; i > -1; i--) {\n if (this._scheduledCbs[i][1] <= this._totalElapsed) {\n this._scheduledCbs[i][0](this._elapsed);\n this._scheduledCbs.splice(i, 1);\n }\n }\n }\n update(overrideUpdateMs) {\n try {\n this.fpsSampler.start();\n // Get the time to calculate time-elapsed\n const now = this.now();\n let elapsed = now - this._lastTime || 1; // first frame\n // Constrain fps\n const fpsInterval = (1000 / this._maxFps);\n // only run frame if enough time has elapsed\n if (elapsed >= fpsInterval) {\n let leftover = 0;\n if (fpsInterval !== 0) {\n leftover = (elapsed % fpsInterval);\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\n }\n // Resolves issue #138 if the game has been paused, or blurred for\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\n // and provides more expected behavior when the engine comes back\n // into focus\n if (elapsed > 200) {\n elapsed = 1;\n }\n // tick the mainloop and run scheduled callbacks\n this._elapsed = overrideUpdateMs || elapsed;\n this._totalElapsed += this._elapsed;\n this._runScheduledCbs();\n this.tick(overrideUpdateMs || elapsed);\n if (fpsInterval !== 0) {\n this._lastTime = now - leftover;\n }\n else {\n this._lastTime = now;\n }\n this.fpsSampler.end();\n }\n }\n catch (e) {\n this._onFatalException(e);\n this.stop();\n }\n }\n}\n/**\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\n */\nclass StandardClock extends Clock {\n constructor(options) {\n super(options);\n this._running = false;\n }\n isRunning() {\n return this._running;\n }\n start() {\n if (this._running) {\n return;\n }\n this._running = true;\n const mainloop = () => {\n // stop the loop\n if (!this._running) {\n return;\n }\n try {\n // request next loop\n this._requestId = window.requestAnimationFrame(mainloop);\n this.update();\n }\n catch (e) {\n window.cancelAnimationFrame(this._requestId);\n throw e;\n }\n };\n // begin the first frame\n mainloop();\n }\n stop() {\n window.cancelAnimationFrame(this._requestId);\n this._running = false;\n }\n}\n/**\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\n */\nclass TestClock extends Clock {\n constructor(options) {\n super({\n ...options\n });\n this._logger = Logger.getInstance();\n this._running = false;\n this._currentTime = 0;\n this._updateMs = options.defaultUpdateMs;\n }\n /**\n * Get the current time in milliseconds\n */\n now() {\n var _a;\n return (_a = this._currentTime) !== null && _a !== void 0 ? _a : 0;\n }\n isRunning() {\n return this._running;\n }\n start() {\n this._running = true;\n }\n stop() {\n this._running = false;\n }\n /**\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\n * @param overrideUpdateMs\n */\n step(overrideUpdateMs) {\n const time = overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs;\n if (this._running) {\n // to be comparable to RAF this needs to be a full blown Task\n // For example, images cannot decode synchronously in a single step\n this.update(time);\n this._currentTime += time;\n }\n else {\n this._logger.warn('The clock is not running, no step will be performed');\n }\n }\n /**\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\n * @param numberOfSteps\n * @param overrideUpdateMs\n */\n run(numberOfSteps, overrideUpdateMs) {\n for (let i = 0; i < numberOfSteps; i++) {\n this.step(overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs);\n }\n }\n}\n\n// EXTERNAL MODULE: ./Util/Toaster.css\nvar Util_Toaster = __webpack_require__(7379);\n;// CONCATENATED MODULE: ./Util/Toaster.ts\n\n/**\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\n */\nclass Toaster {\n constructor() {\n this._toasterCss = Util_Toaster/* default */.Z.toString();\n this._isInitialized = false;\n }\n _initialize() {\n if (!this._isInitialized) {\n this._container = document.createElement('div');\n this._container.id = 'ex-toast-container';\n document.body.appendChild(this._container);\n this._isInitialized = true;\n this._styleBlock = document.createElement('style');\n this._styleBlock.textContent = this._toasterCss;\n document.head.appendChild(this._styleBlock);\n }\n }\n dispose() {\n this._container.parentElement.removeChild(this._container);\n this._styleBlock.parentElement.removeChild(this._styleBlock);\n this._isInitialized = false;\n }\n _createFragment(message) {\n const toastMessage = document.createElement('span');\n toastMessage.innerText = message;\n return toastMessage;\n }\n /**\n * Display a toast message to a player\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\n * @param linkTarget Optionally specify a link location\n * @param linkName Optionally specify a name for that link location\n */\n toast(message, linkTarget, linkName) {\n this._initialize();\n const toast = document.createElement('div');\n toast.className = 'ex-toast-message';\n const messageFragments = message.split('[LINK]').map(message => this._createFragment(message));\n if (linkTarget) {\n const link = document.createElement('a');\n link.href = linkTarget;\n if (linkName) {\n link.innerText = linkName;\n }\n else {\n link.innerText = linkTarget;\n }\n messageFragments.splice(1, 0, link);\n }\n // Assembly message\n const finalMessage = document.createElement('div');\n messageFragments.forEach(message => {\n finalMessage.appendChild(message);\n });\n toast.appendChild(finalMessage);\n // Dismiss button\n const dismissBtn = document.createElement('button');\n dismissBtn.innerText = 'x';\n dismissBtn.addEventListener('click', () => {\n this._container.removeChild(toast);\n });\n toast.appendChild(dismissBtn);\n // Escape to dismiss\n const keydownHandler = (evt) => {\n if (evt.key === 'Escape') {\n try {\n this._container.removeChild(toast);\n }\n catch (_a) {\n // pass\n }\n }\n document.removeEventListener('keydown', keydownHandler);\n };\n document.addEventListener('keydown', keydownHandler);\n // Insert into container\n const first = this._container.firstChild;\n this._container.insertBefore(toast, first);\n }\n}\n\n;// CONCATENATED MODULE: ./Director/Director.ts\n\n\n\n\n\n\nconst DirectorEvents = {\n NavigationStart: 'navigationstart',\n Navigation: 'navigation',\n NavigationEnd: 'navigationend'\n};\n/**\n * The Director is responsible for managing scenes and changing scenes in Excalibur.\n *\n * It deals with transitions, scene loaders, switching scenes\n *\n * This is used internally by Excalibur, generally not mean to\n * be instantiated end users directly.\n */\nclass Director {\n /**\n * Gets whether the director currently transitioning between scenes\n *\n * Useful if you need to block behavior during transition\n */\n get isTransitioning() {\n return this._isTransitioning;\n }\n constructor(_engine, scenes) {\n this._engine = _engine;\n this.events = new EventEmitter();\n this._logger = Logger.getInstance();\n this._initialized = false;\n /**\n * All registered scenes in Excalibur\n */\n this.scenes = {};\n /**\n * Holds all instantiated scenes\n */\n this._sceneToInstance = new Map();\n this._sceneToLoader = new Map();\n this._sceneToTransition = new Map();\n /**\n * Used to keep track of scenes that have already been loaded so we don't load multiple times\n */\n this._loadedScenes = new Set();\n this._isTransitioning = false;\n this.rootScene = this.currentScene = new Scene();\n this.add('root', this.rootScene);\n this.currentScene = this.rootScene;\n this.currentSceneName = 'root';\n for (const sceneKey in scenes) {\n const sceneOrOptions = scenes[sceneKey];\n this.add(sceneKey, sceneOrOptions);\n if (sceneKey === 'root') {\n this.rootScene = this.getSceneInstance('root');\n this.currentScene = this.rootScene;\n }\n }\n }\n /**\n * Initialize the director's internal state\n */\n async onInitialize() {\n if (!this._initialized) {\n this._initialized = true;\n if (this._deferredGoto) {\n const deferredScene = this._deferredGoto;\n const deferredTransition = this._deferredTransition;\n this._deferredGoto = null;\n this._deferredTransition = null;\n await this.swapScene(deferredScene);\n if (deferredTransition) {\n await this.playTransition(deferredTransition);\n }\n }\n else {\n await this.swapScene('root');\n }\n }\n }\n get isInitialized() {\n return this._initialized;\n }\n /**\n * Configures the start scene, and optionally the transition & loader for the director\n *\n * Typically this is called at the beginning of the game to the start scene and transition and never again.\n * @param startScene\n * @param options\n */\n configureStart(startScene, options) {\n const maybeLoaderOrCtor = options === null || options === void 0 ? void 0 : options.loader;\n if (maybeLoaderOrCtor instanceof DefaultLoader) {\n this.mainLoader = maybeLoaderOrCtor;\n }\n else if (isLoaderConstructor(maybeLoaderOrCtor)) {\n this.mainLoader = new maybeLoaderOrCtor();\n }\n else {\n this.mainLoader = new Loader();\n }\n let maybeStartTransition;\n if (options) {\n const { inTransition } = options;\n maybeStartTransition = inTransition;\n }\n this.startScene = startScene;\n // Fire and forget promise for the initial scene\n if (maybeStartTransition) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.swapScene(this.startScene).then(() => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.playTransition(maybeStartTransition);\n });\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.swapScene(this.startScene);\n }\n this.currentSceneName = this.startScene;\n }\n _getLoader(sceneName) {\n return this._sceneToLoader.get(sceneName);\n }\n _getInTransition(sceneName) {\n var _a;\n const sceneOrRoute = this.scenes[sceneName];\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) {\n return null;\n }\n return (_a = sceneOrRoute === null || sceneOrRoute === void 0 ? void 0 : sceneOrRoute.transitions) === null || _a === void 0 ? void 0 : _a.in;\n }\n _getOutTransition(sceneName) {\n var _a;\n const sceneOrRoute = this.scenes[sceneName];\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) {\n return null;\n }\n return (_a = sceneOrRoute === null || sceneOrRoute === void 0 ? void 0 : sceneOrRoute.transitions) === null || _a === void 0 ? void 0 : _a.out;\n }\n getDeferredScene() {\n const maybeDeferred = this.getSceneDefinition(this._deferredGoto);\n if (this._deferredGoto && maybeDeferred) {\n return maybeDeferred;\n }\n return null;\n }\n /**\n * Returns a scene by name if it exists, might be the constructor and not the instance of a scene\n * @param name\n */\n getSceneDefinition(name) {\n const maybeScene = this.scenes[name];\n if (maybeScene instanceof Scene || isSceneConstructor(maybeScene)) {\n return maybeScene;\n }\n else if (maybeScene) {\n return maybeScene.scene;\n }\n return undefined;\n }\n getSceneName(scene) {\n for (const [name, sceneInstance] of this._sceneToInstance) {\n if (scene === sceneInstance) {\n return name;\n }\n }\n return 'unknown scene name';\n }\n /**\n * Returns the same Director, but asserts a scene DOES exist to the type system\n * @param name\n */\n assertAdded(name) {\n return this;\n }\n /**\n * Returns the same Director, but asserts a scene DOES NOT exist to the type system\n * @param name\n */\n assertRemoved(name) {\n return this;\n }\n /**\n * Adds additional Scenes to the game!\n * @param name\n * @param sceneOrRoute\n */\n add(name, sceneOrRoute) {\n if (!(sceneOrRoute instanceof Scene) && !(isSceneConstructor(sceneOrRoute))) {\n const { loader, transitions } = sceneOrRoute;\n const { in: inTransition, out: outTransition } = transitions !== null && transitions !== void 0 ? transitions : {};\n this._sceneToTransition.set(name, { in: inTransition, out: outTransition });\n if (isLoaderConstructor(loader)) {\n this._sceneToLoader.set(name, new loader());\n }\n else {\n this._sceneToLoader.set(name, loader);\n }\n }\n if (this.scenes[name]) {\n this._logger.warn('Scene', name, 'already exists overwriting');\n }\n this.scenes[name] = sceneOrRoute;\n return this.assertAdded(name);\n }\n remove(nameOrScene) {\n if (nameOrScene instanceof Scene || isSceneConstructor(nameOrScene)) {\n const sceneOrCtor = nameOrScene;\n // remove scene\n for (const key in this.scenes) {\n if (this.scenes.hasOwnProperty(key)) {\n const potentialSceneOrOptions = this.scenes[key];\n let scene;\n if (potentialSceneOrOptions instanceof Scene || isSceneConstructor(potentialSceneOrOptions)) {\n scene = potentialSceneOrOptions;\n }\n else {\n scene = potentialSceneOrOptions.scene;\n }\n if (scene === sceneOrCtor) {\n if (key === this.currentSceneName) {\n throw new Error(`Cannot remove a currently active scene: ${key}`);\n }\n this._sceneToTransition.delete(key);\n this._sceneToLoader.delete(key);\n delete this.scenes[key];\n }\n }\n }\n }\n if (typeof nameOrScene === 'string') {\n if (nameOrScene === this.currentSceneName) {\n throw new Error(`Cannot remove a currently active scene: ${nameOrScene}`);\n }\n // remove scene\n this._sceneToTransition.delete(nameOrScene);\n this._sceneToLoader.delete(nameOrScene);\n delete this.scenes[nameOrScene];\n }\n }\n /**\n * Go to a specific scene, and optionally override loaders and transitions\n * @param destinationScene\n * @param options\n */\n async goto(destinationScene, options) {\n var _a, _b, _c, _d, _e, _f;\n const maybeDest = this.getSceneInstance(destinationScene);\n if (!maybeDest) {\n this._logger.warn(`Scene ${destinationScene} does not exist! Check the name, are you sure you added it?`);\n return;\n }\n const sourceScene = this.currentSceneName;\n const engineInputEnabled = (_b = (_a = this._engine.input) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;\n this._isTransitioning = true;\n const maybeSourceOut = (_c = this.getSceneInstance(sourceScene)) === null || _c === void 0 ? void 0 : _c.onTransition('out');\n const maybeDestinationIn = maybeDest === null || maybeDest === void 0 ? void 0 : maybeDest.onTransition('in');\n options = {\n // Engine configuration then dynamic scene transitions\n ...{ sourceOut: (_d = this._getOutTransition(this.currentSceneName)) !== null && _d !== void 0 ? _d : maybeSourceOut },\n ...{ destinationIn: (_e = this._getInTransition(destinationScene)) !== null && _e !== void 0 ? _e : maybeDestinationIn },\n // Goto options\n ...options\n };\n const { sourceOut, destinationIn, sceneActivationData } = options;\n const outTransition = sourceOut !== null && sourceOut !== void 0 ? sourceOut : this._getOutTransition(this.currentSceneName);\n const inTransition = destinationIn !== null && destinationIn !== void 0 ? destinationIn : this._getInTransition(destinationScene);\n const hideLoader = (outTransition === null || outTransition === void 0 ? void 0 : outTransition.hideLoader) || (inTransition === null || inTransition === void 0 ? void 0 : inTransition.hideLoader);\n if (hideLoader) {\n // Start hidden loader early and take advantage of the transition\n // Don't await and block on a hidden loader\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.maybeLoadScene(destinationScene, hideLoader);\n }\n this._emitEvent('navigationstart', sourceScene, destinationScene);\n // Run the out transition on the current scene if present\n await this.playTransition(outTransition);\n // Run the loader if present\n await this.maybeLoadScene(destinationScene, hideLoader);\n // Give incoming transition a chance to grab info from previous\n await (inTransition === null || inTransition === void 0 ? void 0 : inTransition.onPreviousSceneDeactivate(this.currentScene));\n // Swap to the new scene\n await this.swapScene(destinationScene, sceneActivationData);\n this._emitEvent('navigation', sourceScene, destinationScene);\n // Run the in transition on the new scene if present\n await this.playTransition(inTransition);\n this._emitEvent('navigationend', sourceScene, destinationScene);\n (_f = this._engine.input) === null || _f === void 0 ? void 0 : _f.toggleEnabled(engineInputEnabled);\n this._isTransitioning = false;\n }\n /**\n * Retrieves a scene instance by key if it's registered.\n *\n * This will call any constructors that were given as a definition\n * @param scene\n */\n getSceneInstance(scene) {\n const sceneDefinition = this.getSceneDefinition(scene);\n if (!sceneDefinition) {\n return undefined;\n }\n if (this._sceneToInstance.has(scene)) {\n return this._sceneToInstance.get(scene);\n }\n if (sceneDefinition instanceof Scene) {\n this._sceneToInstance.set(scene, sceneDefinition);\n return sceneDefinition;\n }\n const newScene = new sceneDefinition();\n this._sceneToInstance.set(scene, newScene);\n return newScene;\n }\n /**\n * Triggers scene loading if has not already been loaded\n * @param scene\n * @param hideLoader\n */\n async maybeLoadScene(scene, hideLoader = false) {\n var _a;\n const loader = (_a = this._getLoader(scene)) !== null && _a !== void 0 ? _a : new DefaultLoader();\n const sceneToLoad = this.getSceneDefinition(scene);\n const sceneToLoadInstance = this.getSceneInstance(scene);\n if (sceneToLoad && sceneToLoadInstance && !this._loadedScenes.has(sceneToLoadInstance)) {\n sceneToLoadInstance.onPreLoad(loader);\n sceneToLoadInstance.events.emit('preload', { loader });\n if (hideLoader) {\n // Don't await a hidden loader\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this._engine.load(loader, hideLoader);\n }\n else {\n await this._engine.load(loader);\n }\n this._loadedScenes.add(sceneToLoadInstance);\n }\n }\n /**\n * Plays a transition in the current scene\n * @param transition\n */\n async playTransition(transition) {\n var _a, _b, _c, _d, _e, _f, _g;\n if (!this.isInitialized) {\n this._deferredTransition = transition;\n return;\n }\n if (transition) {\n this.currentTransition = transition;\n const currentScene = this._engine.currentScene;\n const sceneInputEnabled = (_b = (_a = currentScene.input) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;\n (_c = currentScene.input) === null || _c === void 0 ? void 0 : _c.toggleEnabled(!transition.blockInput);\n (_d = this._engine.input) === null || _d === void 0 ? void 0 : _d.toggleEnabled(!transition.blockInput);\n await this.currentTransition.play(this._engine);\n (_e = currentScene.input) === null || _e === void 0 ? void 0 : _e.toggleEnabled(sceneInputEnabled);\n }\n (_f = this.currentTransition) === null || _f === void 0 ? void 0 : _f.kill();\n (_g = this.currentTransition) === null || _g === void 0 ? void 0 : _g.reset();\n this.currentTransition = null;\n }\n /**\n * Swaps the current and destination scene after performing required lifecycle events\n * @param destinationScene\n * @param data\n */\n async swapScene(destinationScene, data) {\n const engine = this._engine;\n // if not yet initialized defer goToScene\n if (!this.isInitialized) {\n this._deferredGoto = destinationScene;\n return;\n }\n const maybeDest = this.getSceneInstance(destinationScene);\n if (maybeDest) {\n const previousScene = this.currentScene;\n const nextScene = maybeDest;\n this._logger.debug('Going to scene:', destinationScene);\n // only deactivate when initialized\n if (this.currentScene.isInitialized) {\n const context = { engine, previousScene, nextScene };\n await this.currentScene._deactivate(context);\n this.currentScene.events.emit('deactivate', new DeactivateEvent(context, this.currentScene));\n }\n // wait for the scene to be loaded if needed\n const destLoader = this._sceneToLoader.get(destinationScene);\n await (destLoader === null || destLoader === void 0 ? void 0 : destLoader.areResourcesLoaded());\n // set current scene to new one\n this.currentScene = nextScene;\n this.currentSceneName = destinationScene;\n engine.screen.setCurrentCamera(nextScene.camera);\n // initialize the current scene if has not been already\n await this.currentScene._initialize(engine);\n const context = { engine, previousScene, nextScene, data };\n await this.currentScene._activate(context);\n this.currentScene.events.emit('activate', new ActivateEvent(context, this.currentScene));\n }\n else {\n this._logger.error('Scene', destinationScene, 'does not exist!');\n }\n }\n _emitEvent(eventName, sourceScene, destinationScene) {\n const source = this.getSceneDefinition(sourceScene);\n const dest = this.getSceneDefinition(destinationScene);\n this.events.emit(eventName, {\n sourceScene: source,\n sourceName: sourceScene,\n destinationScene: dest,\n destinationName: destinationScene\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Engine.ts\n\n\n\n\n\n\npolyfill();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst EngineEvents = {\n FallbackGraphicsContext: 'fallbackgraphicscontext',\n Initialize: 'initialize',\n Visible: 'visible',\n Hidden: 'hidden',\n Start: 'start',\n Stop: 'stop',\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate',\n PreFrame: 'preframe',\n PostFrame: 'postframe',\n PreDraw: 'predraw',\n PostDraw: 'postdraw'\n};\n/**\n * Enum representing the different mousewheel event bubble prevention\n */\nvar ScrollPreventionMode;\n(function (ScrollPreventionMode) {\n /**\n * Do not prevent any page scrolling\n */\n ScrollPreventionMode[ScrollPreventionMode[\"None\"] = 0] = \"None\";\n /**\n * Prevent page scroll if mouse is over the game canvas\n */\n ScrollPreventionMode[ScrollPreventionMode[\"Canvas\"] = 1] = \"Canvas\";\n /**\n * Prevent all page scrolling via mouse wheel\n */\n ScrollPreventionMode[ScrollPreventionMode[\"All\"] = 2] = \"All\";\n})(ScrollPreventionMode || (ScrollPreventionMode = {}));\n/**\n * The Excalibur Engine\n *\n * The [[Engine]] is the main driver for a game. It is responsible for\n * starting/stopping the game, maintaining state, transmitting events,\n * loading resources, and managing the scene.\n */\nclass Engine {\n /**\n * The width of the game canvas in pixels (physical width component of the\n * resolution of the canvas element)\n */\n get canvasWidth() {\n return this.screen.canvasWidth;\n }\n /**\n * Returns half width of the game canvas in pixels (half physical width component)\n */\n get halfCanvasWidth() {\n return this.screen.halfCanvasWidth;\n }\n /**\n * The height of the game canvas in pixels, (physical height component of\n * the resolution of the canvas element)\n */\n get canvasHeight() {\n return this.screen.canvasHeight;\n }\n /**\n * Returns half height of the game canvas in pixels (half physical height component)\n */\n get halfCanvasHeight() {\n return this.screen.halfCanvasHeight;\n }\n /**\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get drawWidth() {\n return this.screen.drawWidth;\n }\n /**\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get halfDrawWidth() {\n return this.screen.halfDrawWidth;\n }\n /**\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get drawHeight() {\n return this.screen.drawHeight;\n }\n /**\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get halfDrawHeight() {\n return this.screen.halfDrawHeight;\n }\n /**\n * Returns whether excalibur detects the current screen to be HiDPI\n */\n get isHiDpi() {\n return this.screen.isHiDpi;\n }\n /**\n * Access [[stats]] that holds frame statistics.\n */\n get stats() {\n return this.debug.stats;\n }\n /**\n * The current [[Scene]] being drawn and updated on screen\n */\n get currentScene() {\n return this.director.currentScene;\n }\n /**\n * The current [[Scene]] being drawn and updated on screen\n */\n get currentSceneName() {\n return this.director.currentSceneName;\n }\n /**\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\n */\n get rootScene() {\n return this.director.rootScene;\n }\n /**\n * Contains all the scenes currently registered with Excalibur\n */\n get scenes() {\n return this.director.scenes;\n }\n ;\n /**\n * Indicates whether the engine is set to fullscreen or not\n */\n get isFullscreen() {\n return this.screen.isFullScreen;\n }\n /**\n * Indicates the current [[DisplayMode]] of the engine.\n */\n get displayMode() {\n return this.screen.displayMode;\n }\n /**\n * Returns the calculated pixel ration for use in rendering\n */\n get pixelRatio() {\n return this.screen.pixelRatio;\n }\n get isDebug() {\n return this._isDebug;\n }\n /**\n * Hints the graphics context to truncate fractional world space coordinates\n */\n get snapToPixel() {\n return this.graphicsContext.snapToPixel;\n }\n ;\n set snapToPixel(shouldSnapToPixel) {\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\n }\n ;\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\n * the game will be rendered full screen (taking up all available browser window space).\n * You can customize the game rendering through [[EngineOptions]].\n *\n * Example:\n *\n * ```js\n * var game = new ex.Engine({\n * width: 0, // the width of the canvas\n * height: 0, // the height of the canvas\n * enableCanvasTransparency: true, // the transparencySection of the canvas\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\n * });\n *\n * // call game.start, which is a Promise\n * game.start().then(function () {\n * // ready, set, go!\n * });\n * ```\n */\n constructor(options) {\n var _a, _b, _c, _d, _e, _f, _g;\n /**\n * Current Excalibur version string\n *\n * Useful for plugins or other tools that need to know what features are available\n */\n this.version = EX_VERSION;\n /**\n * Listen to and emit events on the Engine\n */\n this.events = new EventEmitter();\n /**\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\n *\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\n * one that bounces between 30fps and 60fps\n */\n this.maxFps = Number.POSITIVE_INFINITY;\n this._inputEnabled = true;\n this._suppressPlayButton = false;\n /**\n * Indicates whether audio should be paused when the game is no longer visible.\n */\n this.pauseAudioWhenHidden = true;\n /**\n * Indicates whether the engine should draw with debug information\n */\n this._isDebug = false;\n /**\n * Sets the Transparency for the engine.\n */\n this.enableCanvasTransparency = true;\n /**\n * The action to take when a fatal exception is thrown\n */\n this.onFatalException = (e) => {\n Logger.getInstance().fatal(e, e.stack);\n };\n this._toaster = new Toaster();\n this._timescale = 1.0;\n this._isInitialized = false;\n this._originalOptions = {};\n this._performanceThresholdTriggered = false;\n this._fpsSamples = [];\n this._disposed = false;\n this._isLoading = false;\n this._hideLoader = false;\n this._isReadyFuture = new Future();\n /**\n * Returns the current frames elapsed milliseconds\n */\n this.currentFrameElapsedMs = 0;\n /**\n * Returns the current frame lag when in fixed update mode\n */\n this.currentFrameLagMs = 0;\n this._lagMs = 0;\n this._screenShotRequests = [];\n options = { ...Engine._DEFAULT_ENGINE_OPTIONS, ...options };\n this._originalOptions = options;\n Flags.freeze();\n // Initialize browser events facade\n this.browser = new BrowserEvents(window, document);\n // Check compatibility\n const detector = new Detector();\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\n const message = document.createElement('div');\n message.innerText = 'Sorry, your browser does not support all the features needed for Excalibur';\n document.body.appendChild(message);\n detector.failedTests.forEach(function (test) {\n const testMessage = document.createElement('div');\n testMessage.innerText = 'Browser feature missing ' + test;\n document.body.appendChild(testMessage);\n });\n if (options.canvasElementId) {\n const canvas = document.getElementById(options.canvasElementId);\n if (canvas) {\n canvas.parentElement.removeChild(canvas);\n }\n }\n return;\n }\n else {\n this._compatible = true;\n }\n // Use native console API for color fun\n // eslint-disable-next-line no-console\n if (console.log && !options.suppressConsoleBootMessage) {\n // eslint-disable-next-line no-console\n console.log(`%cPowered by Excalibur.js (v${EX_VERSION})`, 'background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;');\n // eslint-disable-next-line no-console\n console.log('\\n\\\r\n /| ________________\\n\\\r\nO|===|* >________________>\\n\\\r\n \\\\|');\n // eslint-disable-next-line no-console\n console.log('Visit', 'http://excaliburjs.com', 'for more information');\n }\n // Suppress play button\n if (options.suppressPlayButton) {\n this._suppressPlayButton = true;\n }\n this._logger = Logger.getInstance();\n // If debug is enabled, let's log browser features to the console.\n if (this._logger.defaultLevel === LogLevel.Debug) {\n detector.logBrowserFeatures();\n }\n this._logger.debug('Building engine...');\n this.canvasElementId = options.canvasElementId;\n if (options.canvasElementId) {\n this._logger.debug('Using Canvas element specified: ' + options.canvasElementId);\n //test for existence of element\n if (document.getElementById(options.canvasElementId) === null) {\n throw new Error('Cannot find existing element in the DOM, please ensure element is created prior to engine creation.');\n }\n this.canvas = document.getElementById(options.canvasElementId);\n }\n else if (options.canvasElement) {\n this._logger.debug('Using Canvas element specified:', options.canvasElement);\n this.canvas = options.canvasElement;\n }\n else {\n this._logger.debug('Using generated canvas element');\n this.canvas = document.createElement('canvas');\n }\n let displayMode = (_a = options.displayMode) !== null && _a !== void 0 ? _a : DisplayMode.Fixed;\n if ((options.width && options.height) || options.viewport) {\n if (options.displayMode === undefined) {\n displayMode = DisplayMode.Fixed;\n }\n this._logger.debug('Engine viewport is size ' + options.width + ' x ' + options.height);\n }\n else if (!options.displayMode) {\n this._logger.debug('Engine viewport is fit');\n displayMode = DisplayMode.FitScreen;\n }\n this._originalDisplayMode = displayMode;\n let pixelArtSampler;\n let uvPadding;\n let nativeContextAntialiasing;\n let canvasImageRendering;\n let filtering;\n let multiSampleAntialiasing;\n if (typeof options.antialiasing === 'object') {\n ({\n pixelArtSampler,\n nativeContextAntialiasing,\n multiSampleAntialiasing,\n filtering,\n canvasImageRendering\n } = {\n ...(options.pixelArt ? DefaultPixelArtOptions : DefaultAntialiasOptions),\n ...options.antialiasing\n });\n }\n else {\n pixelArtSampler = !!options.pixelArt;\n nativeContextAntialiasing = false;\n multiSampleAntialiasing = options.antialiasing;\n canvasImageRendering = options.antialiasing ? 'auto' : 'pixelated';\n filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\n }\n if (nativeContextAntialiasing && multiSampleAntialiasing) {\n this._logger.warnOnce(`Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing` +\n ` at the same time, they are incompatible settings. If you aren\\'t sure use multiSampleAntialiasing`);\n }\n if (options.pixelArt) {\n uvPadding = .25;\n }\n if (!options.antialiasing || filtering === ImageFiltering.Pixel) {\n uvPadding = 0;\n }\n // Override with any user option, if non default to .25 for pixel art, 0.01 for everything else\n uvPadding = (_c = (_b = options.uvPadding) !== null && _b !== void 0 ? _b : uvPadding) !== null && _c !== void 0 ? _c : 0.01;\n // Canvas 2D fallback can be flagged on\n let useCanvasGraphicsContext = Flags.isEnabled('use-canvas-context');\n if (!useCanvasGraphicsContext) {\n // Attempt webgl first\n try {\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n pixelArtSampler: pixelArtSampler,\n antialiasing: nativeContextAntialiasing,\n multiSampleAntialiasing: multiSampleAntialiasing,\n uvPadding: uvPadding,\n powerPreference: options.powerPreference,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n }\n catch (e) {\n this._logger.warn(`Excalibur could not load webgl for some reason (${e.message}) and loaded a Canvas 2D fallback. ` +\n `Some features of Excalibur will not work in this mode. \\n\\n` +\n 'Read more about this issue at https://excaliburjs.com/docs/webgl');\n // fallback to canvas in case of failure\n useCanvasGraphicsContext = true;\n }\n }\n if (useCanvasGraphicsContext) {\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n antialiasing: nativeContextAntialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n }\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: nativeContextAntialiasing,\n canvasImageRendering: canvasImageRendering,\n browser: this.browser,\n viewport: (_d = options.viewport) !== null && _d !== void 0 ? _d : (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\n resolution: options.resolution,\n displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : ((_e = options.pixelRatio) !== null && _e !== void 0 ? _e : null)\n });\n // TODO REMOVE STATIC!!!\n // Set default filtering based on antialiasing\n TextureLoader.filtering = filtering;\n if (options.backgroundColor) {\n this.backgroundColor = options.backgroundColor.clone();\n }\n this.grabWindowFocus = options.grabWindowFocus;\n this.pointerScope = options.pointerScope;\n this.maxFps = (_f = options.maxFps) !== null && _f !== void 0 ? _f : this.maxFps;\n this.fixedUpdateFps = (_g = options.fixedUpdateFps) !== null && _g !== void 0 ? _g : this.fixedUpdateFps;\n this.clock = new StandardClock({\n maxFps: this.maxFps,\n tick: this._mainloop.bind(this),\n onFatalException: (e) => this.onFatalException(e)\n });\n this.enableCanvasTransparency = options.enableCanvasTransparency;\n if (typeof options.physics === 'boolean') {\n this.physics = {\n ...DefaultPhysicsConfig,\n ...DeprecatedStaticToConfig(),\n enabled: options.physics\n };\n }\n else {\n this.physics = {\n ...DefaultPhysicsConfig,\n ...DeprecatedStaticToConfig(),\n ...options.physics\n };\n }\n this.debug = new DebugConfig(this);\n this.director = new Director(this, options.scenes);\n this._initialize(options);\n window.___EXCALIBUR_DEVTOOL = this;\n }\n _monitorPerformanceThresholdAndTriggerFallback() {\n const { allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\n let { threshold, showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\n if (threshold === undefined) {\n threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\n }\n if (showPlayerMessage === undefined) {\n showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\n }\n if (!Flags.isEnabled('use-canvas-context') && allow && this.ready && !this._performanceThresholdTriggered) {\n // Calculate Average fps for last X number of frames after start\n if (this._fpsSamples.length === threshold.numberOfFrames) {\n this._fpsSamples.splice(0, 1);\n }\n this._fpsSamples.push(this.clock.fpsSampler.fps);\n let total = 0;\n for (let i = 0; i < this._fpsSamples.length; i++) {\n total += this._fpsSamples[i];\n }\n const average = total / this._fpsSamples.length;\n if (this._fpsSamples.length === threshold.numberOfFrames) {\n if (average <= threshold.fps) {\n this._performanceThresholdTriggered = true;\n this._logger.warn(`Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` +\n 'this might mean your browser doesn\\'t have webgl enabled or hardware acceleration is unavailable.\\n\\n' +\n 'If in Chrome:\\n' +\n ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n' +\n ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' +\n 'If in Firefox, visit about:config\\n' +\n ' * Ensure webgl.disabled = false\\n' +\n ' * Ensure webgl.force-enabled = true\\n' +\n ' * Ensure layers.acceleration.force-enabled = true\\n\\n' +\n 'Read more about this issue at https://excaliburjs.com/docs/performance');\n if (showPlayerMessage) {\n this._toaster.toast('Excalibur is encountering performance issues. ' +\n 'It\\'s possible that your browser doesn\\'t have hardware acceleration enabled. ' +\n 'Visit [LINK] for more information and potential solutions.', 'https://excaliburjs.com/docs/performance');\n }\n this.useCanvas2DFallback();\n this.emit('fallbackgraphicscontext', this.graphicsContext);\n }\n }\n }\n }\n /**\n * Switches the engine's graphics context to the 2D Canvas.\n * @warning Some features of Excalibur will not work in this mode.\n */\n useCanvas2DFallback() {\n var _a, _b, _c;\n // Swap out the canvas\n const newCanvas = this.canvas.cloneNode(false);\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\n this.canvas = newCanvas;\n const options = { ...this._originalOptions, antialiasing: this.getAntialiasing() };\n const displayMode = this._originalDisplayMode;\n // New graphics context\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n antialiasing: options.antialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n // Reset screen\n if (this.screen) {\n this.screen.dispose();\n }\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: (_a = options.antialiasing) !== null && _a !== void 0 ? _a : true,\n browser: this.browser,\n viewport: (_b = options.viewport) !== null && _b !== void 0 ? _b : (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\n resolution: options.resolution,\n displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : ((_c = options.pixelRatio) !== null && _c !== void 0 ? _c : null)\n });\n this.screen.setCurrentCamera(this.currentScene.camera);\n // Reset pointers\n this.input.pointers.detach();\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\n this.input.pointers.init();\n }\n /**\n * Attempts to completely clean up excalibur resources, including removing the canvas from the dom.\n *\n * To start again you will need to new up an Engine.\n */\n dispose() {\n if (!this._disposed) {\n this._disposed = true;\n this.stop();\n this.input.toggleEnabled(false);\n this.canvas.parentNode.removeChild(this.canvas);\n this.canvas = null;\n this.screen.dispose();\n this.graphicsContext.dispose();\n this.graphicsContext = null;\n }\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen\n * and the bottom right corner of the screen.\n */\n getWorldBounds() {\n return this.screen.getWorldBounds();\n }\n /**\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\n */\n get timescale() {\n return this._timescale;\n }\n /**\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\n * when using time-based movement.\n */\n set timescale(value) {\n if (value <= 0) {\n Logger.getInstance().error('Cannot set engine.timescale to a value of 0 or less than 0.');\n return;\n }\n this._timescale = value;\n }\n /**\n * Adds a [[Timer]] to the [[currentScene]].\n * @param timer The timer to add to the [[currentScene]].\n */\n addTimer(timer) {\n return this.currentScene.addTimer(timer);\n }\n /**\n * Removes a [[Timer]] from the [[currentScene]].\n * @param timer The timer to remove to the [[currentScene]].\n */\n removeTimer(timer) {\n return this.currentScene.removeTimer(timer);\n }\n /**\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\n * would levels or menus.\n * @param key The name of the scene, must be unique\n * @param scene The scene to add to the engine\n */\n addScene(key, scene) {\n this.director.add(key, scene);\n return this;\n }\n /**\n * @internal\n */\n removeScene(entity) {\n this.director.remove(entity);\n }\n add(entity) {\n if (arguments.length === 2) {\n this.director.add(arguments[0], arguments[1]);\n return;\n }\n const maybeDeferred = this.director.getDeferredScene();\n if (maybeDeferred instanceof Scene) {\n maybeDeferred.add(entity);\n }\n else {\n this.currentScene.add(entity);\n }\n }\n remove(entity) {\n if (entity instanceof Entity) {\n this.currentScene.remove(entity);\n }\n if (entity instanceof Scene || isSceneConstructor(entity)) {\n this.removeScene(entity);\n }\n if (typeof entity === 'string') {\n this.removeScene(entity);\n }\n }\n /**\n * Changes the current scene with optionally supplied:\n * * Activation data\n * * Transitions\n * * Loaders\n *\n * Example:\n * ```typescript\n * game.goToScene('myScene', {\n * sceneActivationData: {any: 'thing at all'},\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\n * loader: MyLoader\n * });\n * ```\n *\n * Scenes are defined in the Engine constructor\n * ```typescript\n * const engine = new ex.Engine({\n scenes: {...}\n });\n * ```\n * Or by adding dynamically\n *\n * ```typescript\n * engine.addScene('myScene', new ex.Scene());\n * ```\n * @param destinationScene\n * @param options\n * @deprecated use goToScene, it now behaves the same as goto\n */\n async goto(destinationScene, options) {\n await this.director.goto(destinationScene, options);\n }\n /**\n * Changes the current scene with optionally supplied:\n * * Activation data\n * * Transitions\n * * Loaders\n *\n * Example:\n * ```typescript\n * game.goToScene('myScene', {\n * sceneActivationData: {any: 'thing at all'},\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\n * loader: MyLoader\n * });\n * ```\n *\n * Scenes are defined in the Engine constructor\n * ```typescript\n * const engine = new ex.Engine({\n scenes: {...}\n });\n * ```\n * Or by adding dynamically\n *\n * ```typescript\n * engine.addScene('myScene', new ex.Scene());\n * ```\n * @param destinationScene\n * @param options\n */\n async goToScene(destinationScene, options) {\n await this.director.goto(destinationScene, options);\n }\n /**\n * Transforms the current x, y from screen coordinates to world coordinates\n * @param point Screen coordinate to convert\n */\n screenToWorldCoordinates(point) {\n return this.screen.screenToWorldCoordinates(point);\n }\n /**\n * Transforms a world coordinate, to a screen coordinate\n * @param point World coordinate to convert\n */\n worldToScreenCoordinates(point) {\n return this.screen.worldToScreenCoordinates(point);\n }\n /**\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\n */\n _initialize(options) {\n var _a, _b;\n this.pageScrollPreventionMode = options.scrollPreventionMode;\n // initialize inputs\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n const grabWindowFocus = (_b = (_a = this._originalOptions) === null || _a === void 0 ? void 0 : _a.grabWindowFocus) !== null && _b !== void 0 ? _b : true;\n this.input = new InputHost({\n pointerTarget,\n grabWindowFocus,\n engine: this\n });\n this.inputMapper = this.input.inputMapper;\n // Issue #385 make use of the visibility api\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\n this.browser.document.on('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n this.events.emit('hidden', new HiddenEvent(this));\n this._logger.debug('Window hidden');\n }\n else if (document.visibilityState === 'visible') {\n this.events.emit('visible', new VisibleEvent(this));\n this._logger.debug('Window visible');\n }\n });\n if (!this.canvasElementId && !options.canvasElement) {\n document.body.appendChild(this.canvas);\n }\n }\n toggleInputEnabled(enabled) {\n this._inputEnabled = enabled;\n this.input.toggleEnabled(this._inputEnabled);\n }\n onInitialize(engine) {\n // Override me\n }\n /**\n * If supported by the browser, this will set the antialiasing flag on the\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\n * image resources.\n * @param isSmooth Set smoothing to true or false\n * @deprecated Set in engine constructor, will be removed in v0.30\n */\n setAntialiasing(isSmooth) {\n this.screen.antialiasing = isSmooth;\n }\n /**\n * Return the current smoothing status of the canvas\n * @deprecated Set in engine constructor, will be removed in v0.30\n */\n getAntialiasing() {\n return this.screen.antialiasing;\n }\n /**\n * Gets whether the actor is Initialized\n */\n get isInitialized() {\n return this._isInitialized;\n }\n async _overrideInitialize(engine) {\n if (!this.isInitialized) {\n await this.director.onInitialize();\n await this.onInitialize(engine);\n this.events.emit('initialize', new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * Updates the entire state of the game\n * @param delta Number of milliseconds elapsed since the last update.\n */\n _update(delta) {\n var _a;\n if (this._isLoading) {\n // suspend updates until loading is finished\n (_a = this._loader) === null || _a === void 0 ? void 0 : _a.onUpdate(this, delta);\n // Update input listeners\n this.input.update();\n return;\n }\n // Publish preupdate events\n this._preupdate(delta);\n // process engine level events\n this.currentScene.update(this, delta);\n // Update graphics postprocessors\n this.graphicsContext.updatePostProcessors(delta);\n // Publish update event\n this._postupdate(delta);\n // Update input listeners\n this.input.update();\n }\n /**\n * @internal\n */\n _preupdate(delta) {\n this.emit('preupdate', new PreUpdateEvent(this, delta, this));\n this.onPreUpdate(this, delta);\n }\n onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * @internal\n */\n _postupdate(delta) {\n this.emit('postupdate', new PostUpdateEvent(this, delta, this));\n this.onPostUpdate(this, delta);\n }\n onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n * Draws the entire game\n * @param delta Number of milliseconds elapsed since the last draw.\n */\n _draw(delta) {\n var _a, _b;\n this.graphicsContext.beginDrawLifecycle();\n this.graphicsContext.clear();\n this._predraw(this.graphicsContext, delta);\n // Drawing nothing else while loading\n if (this._isLoading) {\n if (!this._hideLoader) {\n (_a = this._loader) === null || _a === void 0 ? void 0 : _a.canvas.draw(this.graphicsContext, 0, 0);\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n }\n return;\n }\n // Use scene background color if present, fallback to engine\n this.graphicsContext.backgroundColor = (_b = this.currentScene.backgroundColor) !== null && _b !== void 0 ? _b : this.backgroundColor;\n this.currentScene.draw(this.graphicsContext, delta);\n this._postdraw(this.graphicsContext, delta);\n // Flush any pending drawings\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n this._checkForScreenShots();\n }\n /**\n * @internal\n */\n _predraw(ctx, delta) {\n this.emit('predraw', new PreDrawEvent(ctx, delta, this));\n this.onPreDraw(ctx, delta);\n }\n onPreDraw(ctx, delta) {\n // Override me\n }\n /**\n * @internal\n */\n _postdraw(ctx, delta) {\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\n this.onPostDraw(ctx, delta);\n }\n onPostDraw(ctx, delta) {\n // Override me\n }\n /**\n * Enable or disable Excalibur debugging functionality.\n * @param toggle a value that debug drawing will be changed to\n */\n showDebug(toggle) {\n this._isDebug = toggle;\n }\n /**\n * Toggle Excalibur debugging functionality.\n */\n toggleDebug() {\n this._isDebug = !this._isDebug;\n return this._isDebug;\n }\n /**\n * Returns true when loading is totally complete and the player has clicked start\n */\n get loadingComplete() {\n return !this._isLoading;\n }\n get ready() {\n return this._isReadyFuture.isCompleted;\n }\n isReady() {\n return this._isReadyFuture.promise;\n }\n async start(sceneNameOrLoader, options) {\n if (!this._compatible) {\n throw new Error('Excalibur is incompatible with your browser');\n }\n this._isLoading = true;\n let loader;\n if (sceneNameOrLoader instanceof DefaultLoader) {\n loader = sceneNameOrLoader;\n }\n else if (typeof sceneNameOrLoader === 'string') {\n this.director.configureStart(sceneNameOrLoader, options);\n loader = this.director.mainLoader;\n }\n // Start the excalibur clock which drives the mainloop\n this._logger.debug('Starting game clock...');\n this.browser.resume();\n this.clock.start();\n this._logger.debug('Game clock started');\n await this.load(loader !== null && loader !== void 0 ? loader : new Loader());\n // Initialize before ready\n await this._overrideInitialize(this);\n this._isReadyFuture.resolve();\n this.emit('start', new GameStartEvent(this));\n return this._isReadyFuture.promise;\n }\n _mainloop(elapsed) {\n this.emit('preframe', new PreFrameEvent(this, this.stats.prevFrame));\n const delta = elapsed * this.timescale;\n this.currentFrameElapsedMs = delta;\n // reset frame stats (reuse existing instances)\n const frameId = this.stats.prevFrame.id + 1;\n this.stats.currFrame.reset();\n this.stats.currFrame.id = frameId;\n this.stats.currFrame.delta = delta;\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\n GraphicsDiagnostics.clear();\n const beforeUpdate = this.clock.now();\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\n if (this.fixedUpdateFps) {\n this._lagMs += delta;\n while (this._lagMs >= fixedTimestepMs) {\n this._update(fixedTimestepMs);\n this._lagMs -= fixedTimestepMs;\n }\n }\n else {\n this._update(delta);\n }\n const afterUpdate = this.clock.now();\n this.currentFrameLagMs = this._lagMs;\n this._draw(delta);\n const afterDraw = this.clock.now();\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\n this.emit('postframe', new PostFrameEvent(this, this.stats.currFrame));\n this.stats.prevFrame.reset(this.stats.currFrame);\n this._monitorPerformanceThresholdAndTriggerFallback();\n }\n /**\n * Stops Excalibur's main loop, useful for pausing the game.\n */\n stop() {\n if (this.clock.isRunning()) {\n this.emit('stop', new GameStopEvent(this));\n this.browser.pause();\n this.clock.stop();\n this._logger.debug('Game stopped');\n }\n }\n /**\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\n */\n isRunning() {\n return this.clock.isRunning();\n }\n /**\n * Takes a screen shot of the current viewport and returns it as an\n * HTML Image Element.\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\n */\n screenshot(preserveHiDPIResolution = false) {\n const screenShotPromise = new Promise((resolve) => {\n this._screenShotRequests.push({ preserveHiDPIResolution, resolve });\n });\n return screenShotPromise;\n }\n _checkForScreenShots() {\n // We must grab the draw buffer before we yield to the browser\n // the draw buffer is cleared after compositing\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\n // forces the browser to copy buffers which can have a mass perf impact on mobile\n for (const request of this._screenShotRequests) {\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\n const screenshot = document.createElement('canvas');\n screenshot.width = finalWidth;\n screenshot.height = finalHeight;\n const ctx = screenshot.getContext('2d');\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\n const result = new Image();\n const raw = screenshot.toDataURL('image/png');\n result.src = raw;\n request.resolve(result);\n }\n // Reset state\n this._screenShotRequests.length = 0;\n }\n /**\n * Another option available to you to load resources into the game.\n * Immediately after calling this the game will pause and the loading screen\n * will appear.\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\n */\n async load(loader, hideLoader = false) {\n try {\n // early exit if loaded\n if (loader.isLoaded()) {\n return;\n }\n this._loader = loader;\n this._isLoading = true;\n this._hideLoader = hideLoader;\n if (loader instanceof Loader) {\n loader.suppressPlayButton = this._suppressPlayButton;\n }\n this._loader.onInitialize(this);\n await loader.load();\n }\n catch (e) {\n this._logger.error('Error loading resources, things may not behave properly', e);\n await Promise.resolve();\n }\n finally {\n this._isLoading = false;\n this._hideLoader = false;\n this._loader = null;\n }\n }\n}\n/**\n * Default [[EngineOptions]]\n */\nEngine._DEFAULT_ENGINE_OPTIONS = {\n width: 0,\n height: 0,\n enableCanvasTransparency: true,\n useDrawSorting: true,\n configurePerformanceCanvas2DFallback: {\n allow: false,\n showPlayerMessage: false,\n threshold: { fps: 20, numberOfFrames: 100 }\n },\n canvasElementId: '',\n canvasElement: undefined,\n snapToPixel: false,\n antialiasing: true,\n pixelArt: false,\n powerPreference: 'high-performance',\n pointerScope: PointerScope.Canvas,\n suppressConsoleBootMessage: null,\n suppressMinimumBrowserFeatureDetection: null,\n suppressHiDPIScaling: null,\n suppressPlayButton: null,\n grabWindowFocus: true,\n scrollPreventionMode: ScrollPreventionMode.Canvas,\n backgroundColor: Color.fromHex('#2185d0') // Excalibur blue\n};\n\n;// CONCATENATED MODULE: ./Math/Index.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Debug/index.ts\n\n\n\n\n;// CONCATENATED MODULE: ./EventDispatcher.ts\n\n/**\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\n */\nclass EventDispatcher {\n constructor() {\n this._handlers = {};\n this._wiredEventDispatchers = [];\n this._deferedHandlerRemovals = [];\n }\n /**\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\n */\n clear() {\n this._handlers = {};\n this._wiredEventDispatchers = [];\n }\n _processDeferredHandlerRemovals() {\n for (const eventHandler of this._deferedHandlerRemovals) {\n this._removeHandler(eventHandler.name, eventHandler.handler);\n }\n this._deferedHandlerRemovals.length = 0;\n }\n /**\n * Emits an event for target\n * @param eventName The name of the event to publish\n * @param event Optionally pass an event data object to the handler\n */\n emit(eventName, event) {\n this._processDeferredHandlerRemovals();\n if (!eventName) {\n // key not mapped\n return;\n }\n eventName = eventName.toLowerCase();\n if (typeof event === 'undefined' || event === null) {\n event = new GameEvent();\n }\n let i, len;\n if (this._handlers[eventName]) {\n i = 0;\n len = this._handlers[eventName].length;\n for (i; i < len; i++) {\n this._handlers[eventName][i](event);\n }\n }\n i = 0;\n len = this._wiredEventDispatchers.length;\n for (i; i < len; i++) {\n this._wiredEventDispatchers[i].emit(eventName, event);\n }\n }\n /**\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\n * @param eventName The name of the event to subscribe to\n * @param handler The handler callback to fire on this event\n */\n on(eventName, handler) {\n this._processDeferredHandlerRemovals();\n eventName = eventName.toLowerCase();\n if (!this._handlers[eventName]) {\n this._handlers[eventName] = [];\n }\n this._handlers[eventName].push(handler);\n }\n /**\n * Unsubscribe an event handler(s) from an event. If a specific handler\n * is specified for an event, only that handler will be unsubscribed.\n * Otherwise all handlers will be unsubscribed for that event.\n * @param eventName The name of the event to unsubscribe\n * @param handler Optionally the specific handler to unsubscribe\n */\n off(eventName, handler) {\n this._deferedHandlerRemovals.push({ name: eventName, handler });\n }\n _removeHandler(eventName, handler) {\n eventName = eventName.toLowerCase();\n const eventHandlers = this._handlers[eventName];\n if (eventHandlers) {\n // if no explicit handler is give with the event name clear all handlers\n if (!handler) {\n this._handlers[eventName].length = 0;\n }\n else {\n const index = eventHandlers.indexOf(handler);\n if (index > -1) {\n this._handlers[eventName].splice(index, 1);\n }\n }\n }\n }\n /**\n * Once listens to an event one time, then unsubscribes from that event\n * @param eventName The name of the event to subscribe to once\n * @param handler The handler of the event that will be auto unsubscribed\n */\n once(eventName, handler) {\n this._processDeferredHandlerRemovals();\n const metaHandler = (event) => {\n const ev = event || new GameEvent();\n this.off(eventName, metaHandler);\n handler(ev);\n };\n this.on(eventName, metaHandler);\n }\n /**\n * Wires this event dispatcher to also receive events from another\n */\n wire(eventDispatcher) {\n eventDispatcher._wiredEventDispatchers.push(this);\n }\n /**\n * Unwires this event dispatcher from another\n */\n unwire(eventDispatcher) {\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\n if (index > -1) {\n eventDispatcher._wiredEventDispatchers.splice(index, 1);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Label.ts\n\n\n\n\n\n/**\n * Labels are the way to draw small amounts of text to the screen. They are\n * actors and inherit all of the benefits and capabilities.\n */\nclass Label extends Actor {\n get font() {\n return this._font;\n }\n set font(newFont) {\n this._font = newFont;\n this._text.font = newFont;\n }\n /**\n * The text to draw.\n */\n get text() {\n return this._text.text;\n }\n set text(text) {\n this._text.text = text;\n }\n get color() {\n return this._text.color;\n }\n set color(color) {\n if (this._text) {\n this._text.color = color;\n }\n }\n get opacity() {\n return this._text.opacity;\n }\n set opacity(opacity) {\n this._text.opacity = opacity;\n }\n /**\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\n */\n get spriteFont() {\n return this._spriteFont;\n }\n set spriteFont(sf) {\n if (sf) {\n this._spriteFont = sf;\n this._text.font = this._spriteFont;\n }\n }\n /**\n * Build a new label\n * @param options\n */\n constructor(options) {\n super(options);\n this._font = new Font();\n this._text = new Text({ text: '', font: this._font });\n const { text, pos, x, y, spriteFont, font, color } = { text: '', ...options };\n this.pos = pos !== null && pos !== void 0 ? pos : (x && y ? vec(x, y) : this.pos);\n this.text = text !== null && text !== void 0 ? text : this.text;\n this.font = font !== null && font !== void 0 ? font : this.font;\n this.spriteFont = spriteFont !== null && spriteFont !== void 0 ? spriteFont : this.spriteFont;\n this._text.color = color !== null && color !== void 0 ? color : this.color;\n const gfx = this.get(GraphicsComponent);\n gfx.anchor = Vector.Zero;\n gfx.use(this._text);\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n /**\n * Returns the width of the text in the label (in pixels);\n */\n getTextWidth() {\n return this._text.width;\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/IsometricMap.ts\n\n\n\n\n\n\n\n\n\n\nclass IsometricTile extends Entity {\n getGraphics() {\n return this._graphics;\n }\n /**\n * Tile graphics\n */\n addGraphic(graphic, options) {\n this._graphics.push(graphic);\n this._gfx.visible = this.map.visible;\n this._gfx.opacity = this.map.opacity;\n if (options === null || options === void 0 ? void 0 : options.offset) {\n this._gfx.offset = options.offset;\n }\n // TODO detect when this changes on the map and apply to all tiles\n this._gfx.localBounds = this._recalculateBounds();\n }\n _recalculateBounds() {\n let bounds = this._tileBounds.clone();\n for (const graphic of this._graphics) {\n const offset = vec(this.map.graphicsOffset.x - this.map.tileWidth / 2, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\n bounds = bounds.combine(graphic.localBounds.translate(offset));\n }\n return bounds;\n }\n removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) {\n this._graphics.splice(index, 1);\n }\n this._gfx.localBounds = this._recalculateBounds();\n }\n clearGraphics() {\n this._graphics.length = 0;\n this._gfx.visible = false;\n this._gfx.localBounds = this._recalculateBounds();\n }\n getColliders() {\n return this._colliders;\n }\n /**\n * Adds a collider to the IsometricTile\n *\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\n * @param collider\n */\n addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\n * Removes a collider from the IsometricTile\n * @param collider\n */\n removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) {\n this._colliders.splice(index, 1);\n }\n this.map.flagCollidersDirty();\n }\n /**\n * Clears all colliders from the IsometricTile\n */\n clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n /**\n * Returns the top left corner of the [[IsometricTile]] in world space\n */\n get pos() {\n return this.map.tileToWorld(vec(this.x, this.y));\n }\n /**\n * Returns the center of the [[IsometricTile]]\n */\n get center() {\n return this.pos.add(vec(0, this.map.tileHeight / 2));\n }\n /**\n * Construct a new IsometricTile\n * @param x tile coordinate in x (not world position)\n * @param y tile coordinate in y (not world position)\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\n * @param map reference to owning IsometricMap\n */\n constructor(x, y, graphicsOffset, map) {\n super([\n new TransformComponent(),\n new GraphicsComponent({\n offset: graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : Vector.Zero,\n onPostDraw: (gfx, elapsed) => this.draw(gfx, elapsed)\n }),\n new IsometricEntityComponent(map)\n ]);\n /**\n * Indicates whether this tile is solid\n */\n this.solid = false;\n this._tileBounds = new BoundingBox();\n this._graphics = [];\n /**\n * Tile colliders\n */\n this._colliders = [];\n /**\n * Arbitrary data storage per tile, useful for any game specific data\n */\n this.data = new Map();\n this.x = x;\n this.y = y;\n this.map = map;\n this._transform = this.get(TransformComponent);\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\n const halfTileWidth = this.map.tileWidth / 2;\n const halfTileHeight = this.map.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n // The x position shifts left with every y step\n const xPos = (this.x - this.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (this.x + this.y) * halfTileHeight;\n this._transform.pos = vec(xPos, yPos);\n this._isometricEntityComponent.elevation = map.elevation;\n this._gfx = this.get(GraphicsComponent);\n this._gfx.visible = false; // start not visible\n const totalWidth = this.map.tileWidth;\n const totalHeight = this.map.tileHeight;\n // initial guess at gfx bounds based on the tile\n const offset = vec(0, (this.map.renderFromTopOfGraphic ? totalHeight : 0));\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\n left: -totalWidth / 2,\n top: -totalHeight,\n right: totalWidth / 2,\n bottom: totalHeight\n }).translate(offset);\n }\n draw(gfx, _elapsed) {\n const halfTileWidth = this.map.tileWidth / 2;\n gfx.save();\n // shift left origin to corner of map, not the left corner of the first sprite\n gfx.translate(-halfTileWidth, 0);\n for (const graphic of this._graphics) {\n graphic.draw(gfx, this.map.graphicsOffset.x, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\n }\n gfx.restore();\n }\n}\n/**\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\n *\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\n *\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\n * your art assets.\n */\nclass IsometricMap extends Entity {\n constructor(options) {\n super([\n new TransformComponent(),\n new BodyComponent({\n type: CollisionType.Fixed\n }),\n new ColliderComponent(),\n new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false)\n ], options.name);\n this.elevation = 0;\n /**\n * Whether tiles should be visible\n */\n this.visible = true;\n /**\n * Opacity of tiles\n */\n this.opacity = 1.0;\n /**\n * Render the tile graphic from the top instead of the bottom\n *\n * default is `false` meaning rendering from the bottom\n */\n this.renderFromTopOfGraphic = false;\n this.graphicsOffset = vec(0, 0);\n this._collidersDirty = false;\n this._originalOffsets = new WeakMap();\n const { pos, tileWidth, tileHeight, columns: width, rows: height, renderFromTopOfGraphic, graphicsOffset, elevation } = options;\n this.transform = this.get(TransformComponent);\n if (pos) {\n this.transform.pos = pos;\n }\n this.collider = this.get(ColliderComponent);\n if (this.collider) {\n this.collider.set(this._composite = new CompositeCollider([]));\n }\n this.renderFromTopOfGraphic = renderFromTopOfGraphic !== null && renderFromTopOfGraphic !== void 0 ? renderFromTopOfGraphic : this.renderFromTopOfGraphic;\n this.graphicsOffset = graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : this.graphicsOffset;\n this.elevation = elevation !== null && elevation !== void 0 ? elevation : this.elevation;\n this.tileWidth = tileWidth;\n this.tileHeight = tileHeight;\n this.columns = width;\n this.rows = height;\n this.tiles = new Array(width * height);\n // build up tile representation\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\n this.tiles[x + y * width] = tile;\n this.addChild(tile);\n }\n }\n }\n update() {\n if (this._collidersDirty) {\n this.updateColliders();\n this._collidersDirty = false;\n }\n }\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n }\n else {\n return this._originalOffsets.get(collider);\n }\n }\n updateColliders() {\n this._composite.clearColliders();\n const pos = this.get(TransformComponent).pos;\n for (const tile of this.tiles) {\n if (tile.solid) {\n for (const collider of tile.getColliders()) {\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = this.tileToWorld(vec(tile.x, tile.y))\n .sub(pos)\n .add(originalOffset)\n .sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n }\n }\n this.collider.update();\n }\n /**\n * Convert world space coordinates to the tile x, y coordinate\n * @param worldCoordinate\n */\n worldToTile(worldCoordinate) {\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n return vec(~~((worldCoordinate.x / halfTileWidth + (worldCoordinate.y / halfTileHeight)) / 2), ~~((worldCoordinate.y / halfTileHeight - (worldCoordinate.x / halfTileWidth)) / 2));\n }\n /**\n * Given a tile coordinate, return the top left corner in world space\n * @param tileCoordinate\n */\n tileToWorld(tileCoordinate) {\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // The x position shifts left with every y step\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\n return vec(xPos, yPos).add(this.transform.pos);\n }\n /**\n * Returns the [[IsometricTile]] by its x and y coordinates\n */\n getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\n return null;\n }\n return this.tiles[x + y * this.columns];\n }\n /**\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\n * returns `null` if no Tile was found.\n */\n getTileByPoint(point) {\n const tileCoord = this.worldToTile(point);\n const tile = this.getTile(tileCoord.x, tileCoord.y);\n return tile;\n }\n _getMaxZIndex() {\n let maxZ = Number.NEGATIVE_INFINITY;\n for (const tile of this.tiles) {\n const currentZ = tile.get(TransformComponent).z;\n if (currentZ > maxZ) {\n maxZ = currentZ;\n }\n }\n return maxZ;\n }\n /**\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\n * @param gfx\n */\n debug(gfx, debugFlags) {\n const { showAll, showPosition, positionColor, positionSize, showGrid, gridColor, gridWidth, showColliderGeometry } = debugFlags.isometric;\n const { geometryColor, geometryLineWidth, geometryPointSize } = debugFlags.collider;\n gfx.save();\n gfx.z = this._getMaxZIndex() + 0.5;\n if (showAll || showGrid) {\n for (let y = 0; y < this.rows + 1; y++) {\n const left = this.tileToWorld(vec(0, y));\n const right = this.tileToWorld(vec(this.columns, y));\n gfx.drawLine(left, right, gridColor, gridWidth);\n }\n for (let x = 0; x < this.columns + 1; x++) {\n const top = this.tileToWorld(vec(x, 0));\n const bottom = this.tileToWorld(vec(x, this.rows));\n gfx.drawLine(top, bottom, gridColor, gridWidth);\n }\n }\n if (showAll || showPosition) {\n for (const tile of this.tiles) {\n gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), positionSize, positionColor);\n }\n }\n if (showAll || showColliderGeometry) {\n for (const tile of this.tiles) {\n if (tile.solid) { // only draw solid tiles\n for (const collider of tile.getColliders()) {\n collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize });\n }\n }\n }\n }\n gfx.restore();\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/index.ts\n\n\n\n\n\n;// CONCATENATED MODULE: ./Actions/Action/ActionSequence.ts\n\n/**\n * Action that can represent a sequence of actions, this can be useful in conjunction with\n * [[ParallelActions]] to run multiple sequences in parallel.\n */\nclass ActionSequence {\n constructor(entity, actionBuilder) {\n this._stopped = false;\n this._sequenceBuilder = actionBuilder;\n this._sequenceContext = new ActionContext(entity);\n this._actionQueue = this._sequenceContext.getQueue();\n this._sequenceBuilder(this._sequenceContext);\n }\n update(delta) {\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || this._actionQueue.isComplete();\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._stopped = false;\n this._actionQueue.reset();\n }\n clone(entity) {\n return new ActionSequence(entity, this._sequenceBuilder);\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/ParallelActions.ts\n/**\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\n */\nclass ParallelActions {\n constructor(parallelActions) {\n this._actions = parallelActions;\n }\n update(delta) {\n for (let i = 0; i < this._actions.length; i++) {\n this._actions[i].update(delta);\n }\n }\n isComplete(entity) {\n return this._actions.every(a => a.isComplete(entity));\n }\n reset() {\n this._actions.forEach(a => a.reset());\n }\n stop() {\n this._actions.forEach(a => a.stop());\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Index.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Collision/Detection/QuadTree.ts\n\n\n/**\n * QuadTree spatial data structure. Useful for quickly retrieving all objects that might\n * be in a specific location.\n */\nclass QuadTree {\n constructor(bounds, options) {\n this.bounds = bounds;\n this.options = options;\n this._defaultOptions = {\n maxDepth: 10,\n capacity: 10,\n level: 0\n };\n this.items = [];\n this._isDivided = false;\n this.topLeft = null;\n this.topRight = null;\n this.bottomLeft = null;\n this.bottomRight = null;\n this.options = { ...this._defaultOptions, ...options };\n this.halfWidth = bounds.width / 2;\n this.halfHeight = bounds.height / 2;\n }\n /**\n * Splits the quad tree one level deeper\n */\n _split() {\n this._isDivided = true;\n const newLevelOptions = {\n maxDepth: this.options.maxDepth,\n capacity: this.options.capacity,\n level: this.options.level + 1\n };\n this.topLeft = new QuadTree(new BoundingBox({\n left: this.bounds.left,\n top: this.bounds.top,\n right: this.bounds.left + this.halfWidth,\n bottom: this.bounds.top + this.halfHeight\n }), newLevelOptions);\n this.topRight = new QuadTree(new BoundingBox({\n left: this.bounds.left + this.halfWidth,\n top: this.bounds.top,\n right: this.bounds.right,\n bottom: this.bounds.top + this.halfHeight\n }), newLevelOptions);\n this.bottomLeft = new QuadTree(new BoundingBox({\n left: this.bounds.left,\n top: this.bounds.top + this.halfHeight,\n right: this.bounds.left + this.halfWidth,\n bottom: this.bounds.bottom\n }), newLevelOptions);\n this.bottomRight = new QuadTree(new BoundingBox({\n left: this.bounds.left + this.halfWidth,\n top: this.bounds.top + this.halfHeight,\n right: this.bounds.right,\n bottom: this.bounds.bottom\n }), newLevelOptions);\n }\n _insertIntoSubNodes(item) {\n var _a, _b, _c, _d;\n if ((_a = this.topLeft) === null || _a === void 0 ? void 0 : _a.bounds.overlaps(item.bounds)) {\n this.topLeft.insert(item);\n }\n if ((_b = this.topRight) === null || _b === void 0 ? void 0 : _b.bounds.overlaps(item.bounds)) {\n this.topRight.insert(item);\n }\n if ((_c = this.bottomLeft) === null || _c === void 0 ? void 0 : _c.bounds.overlaps(item.bounds)) {\n this.bottomLeft.insert(item);\n }\n if ((_d = this.bottomRight) === null || _d === void 0 ? void 0 : _d.bounds.overlaps(item.bounds)) {\n this.bottomRight.insert(item);\n }\n }\n /**\n * Insert an item to be tracked in the QuadTree\n * @param item\n */\n insert(item) {\n // add to subnodes if it matches\n if (this._isDivided) {\n this._insertIntoSubNodes(item);\n return;\n }\n // leaf case\n this.items.push(item);\n // capacity\n if (this.items.length > this.options.capacity && this.options.level < this.options.maxDepth) {\n if (!this._isDivided) {\n this._split();\n }\n // divide this level's items into it's subnodes\n for (const item of this.items) {\n this._insertIntoSubNodes(item);\n }\n // clear this level\n this.items.length = 0;\n }\n }\n /**\n * Remove a tracked item in the QuadTree\n * @param item\n */\n remove(item) {\n var _a, _b, _c, _d;\n if (!this.bounds.overlaps(item.bounds)) {\n return;\n }\n if (!this._isDivided) {\n const index = this.items.indexOf(item);\n if (index > -1) {\n this.items.splice(index, 1);\n }\n return;\n }\n if ((_a = this.topLeft) === null || _a === void 0 ? void 0 : _a.bounds.overlaps(item.bounds)) {\n this.topLeft.remove(item);\n }\n if ((_b = this.topRight) === null || _b === void 0 ? void 0 : _b.bounds.overlaps(item.bounds)) {\n this.topRight.remove(item);\n }\n if ((_c = this.bottomLeft) === null || _c === void 0 ? void 0 : _c.bounds.overlaps(item.bounds)) {\n this.bottomLeft.remove(item);\n }\n if ((_d = this.bottomRight) === null || _d === void 0 ? void 0 : _d.bounds.overlaps(item.bounds)) {\n this.bottomRight.remove(item);\n }\n }\n /**\n * Query the structure for all objects that intersect the bounding box\n * @param boundingBox\n * @returns items\n */\n query(boundingBox) {\n let results = this.items;\n if (this._isDivided) {\n if (this.topLeft.bounds.overlaps(boundingBox)) {\n results = results.concat(this.topLeft.query(boundingBox));\n }\n if (this.topRight.bounds.overlaps(boundingBox)) {\n results = results.concat(this.topRight.query(boundingBox));\n }\n if (this.bottomLeft.bounds.overlaps(boundingBox)) {\n results = results.concat(this.bottomLeft.query(boundingBox));\n }\n if (this.bottomRight.bounds.overlaps(boundingBox)) {\n results = results.concat(this.bottomRight.query(boundingBox));\n }\n }\n results = results.filter((item, index) => {\n return results.indexOf(item) >= index;\n });\n return results;\n }\n clear() {\n this.items = [];\n this._isDivided = false;\n this.topLeft = null;\n this.topRight = null;\n this.bottomLeft = null;\n this.bottomRight = null;\n }\n getAllItems() {\n let results = this.items;\n if (this._isDivided) {\n results = results.concat(this.topLeft.getAllItems());\n results = results.concat(this.topRight.getAllItems());\n results = results.concat(this.bottomLeft.getAllItems());\n results = results.concat(this.bottomRight.getAllItems());\n }\n results = results.filter((item, index) => {\n return results.indexOf(item) >= index;\n });\n return results;\n }\n getTreeDepth() {\n if (!this._isDivided) {\n return 0;\n }\n return 1 + Math.max(this.topLeft.getTreeDepth(), this.topRight.getTreeDepth(), this.bottomLeft.getTreeDepth(), this.bottomRight.getTreeDepth());\n }\n debug(ctx) {\n this.bounds.draw(ctx, Color.Yellow);\n if (this._isDivided) {\n this.topLeft.bounds.draw(ctx, Color.Yellow);\n this.topRight.bounds.draw(ctx, Color.Yellow);\n this.bottomLeft.bounds.draw(ctx, Color.Yellow);\n this.bottomRight.bounds.draw(ctx, Color.Yellow);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Index.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Interfaces/LifecycleEvents.ts\n/**\n * Type guard checking for internal initialize method\n * @internal\n * @param a\n */\nfunction has_initialize(a) {\n return !!a._initialize;\n}\n/**\n *\n */\nfunction hasOnInitialize(a) {\n return !!a.onInitialize;\n}\n/**\n *\n */\nfunction has_preupdate(a) {\n return !!a._preupdate;\n}\n/**\n *\n */\nfunction hasOnPreUpdate(a) {\n return !!a.onPreUpdate;\n}\n/**\n *\n */\nfunction has_postupdate(a) {\n return !!a.onPostUpdate;\n}\n/**\n *\n */\nfunction hasOnPostUpdate(a) {\n return !!a.onPostUpdate;\n}\n/**\n *\n */\nfunction hasPreDraw(a) {\n return !!a.onPreDraw;\n}\n/**\n *\n */\nfunction hasPostDraw(a) {\n return !!a.onPostDraw;\n}\n\n;// CONCATENATED MODULE: ./Interfaces/Index.ts\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Resources/Sound/Index.ts\n\n\n\n\n;// CONCATENATED MODULE: ./Resources/Gif.ts\n\n\n\n\n\n\n/**\n * The [[Texture]] object allows games built in Excalibur to load image resources.\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\n * to pre-load before starting a level or game.\n */\nclass Gif {\n /**\n * @param path Path to the image resource\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\n * @param bustCache Optionally load texture with cache busting\n */\n constructor(path, color = Color.Magenta, bustCache = false) {\n this.path = path;\n this.color = color;\n this._stream = null;\n this._gif = null;\n this._textures = [];\n this._animation = null;\n this._transparentColor = null;\n this._resource = new Resource(path, 'arraybuffer', bustCache);\n this._transparentColor = color;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */\n get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * Begins loading the texture and returns a promise to be resolved on completion\n */\n async load() {\n const arraybuffer = await this._resource.load();\n this._stream = new Stream(arraybuffer);\n this._gif = new ParseGif(this._stream, this._transparentColor);\n const images = this._gif.images.map(i => new ImageSource(i.src, false));\n // Load all textures\n await Promise.all(images.map(t => t.load()));\n return this.data = this._textures = images;\n }\n isLoaded() {\n return !!this.data;\n }\n /**\n * Return a frame of the gif as a sprite by id\n * @param id\n */\n toSprite(id = 0) {\n const sprite = this._textures[id].toSprite();\n return sprite;\n }\n /**\n * Return the gif as a spritesheet\n */\n toSpriteSheet() {\n const sprites = this._textures.map((image) => {\n return image.toSprite();\n });\n return new SpriteSheet({ sprites });\n }\n /**\n * Transform the GIF into an animation with duration per frame\n */\n toAnimation(durationPerFrameMs) {\n const spriteSheet = this.toSpriteSheet();\n const length = spriteSheet.sprites.length;\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\n return this._animation;\n }\n get readCheckBytes() {\n return this._gif.checkBytes;\n }\n}\nconst bitsToNum = (ba) => {\n return ba.reduce(function (s, n) {\n return s * 2 + n;\n }, 0);\n};\nconst byteToBitArr = (bite) => {\n const a = [];\n for (let i = 7; i >= 0; i--) {\n a.push(!!(bite & (1 << i)));\n }\n return a;\n};\nclass Stream {\n constructor(dataArray) {\n this.data = null;\n this.len = 0;\n this.position = 0;\n this.readByte = () => {\n if (this.position >= this.data.byteLength) {\n throw new Error('Attempted to read past end of stream.');\n }\n return this.data[this.position++];\n };\n this.readBytes = (n) => {\n const bytes = [];\n for (let i = 0; i < n; i++) {\n bytes.push(this.readByte());\n }\n return bytes;\n };\n this.read = (n) => {\n let s = '';\n for (let i = 0; i < n; i++) {\n s += String.fromCharCode(this.readByte());\n }\n return s;\n };\n this.readUnsigned = () => {\n // Little-endian.\n const a = this.readBytes(2);\n return (a[1] << 8) + a[0];\n };\n this.data = new Uint8Array(dataArray);\n this.len = this.data.byteLength;\n if (this.len === 0) {\n throw new Error('No data loaded from file');\n }\n }\n}\nconst lzwDecode = function (minCodeSize, data) {\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\n const readCode = function (size) {\n let code = 0;\n for (let i = 0; i < size; i++) {\n if (data.charCodeAt(pos >> 3) & (1 << (pos & 7))) {\n code |= 1 << i;\n }\n pos++;\n }\n return code;\n };\n const output = [];\n const clearCode = 1 << minCodeSize;\n const eoiCode = clearCode + 1;\n let codeSize = minCodeSize + 1;\n let dict = [];\n const clear = function () {\n dict = [];\n codeSize = minCodeSize + 1;\n for (let i = 0; i < clearCode; i++) {\n dict[i] = [i];\n }\n dict[clearCode] = [];\n dict[eoiCode] = null;\n };\n let code;\n let last;\n while (true) {\n last = code;\n code = readCode(codeSize);\n if (code === clearCode) {\n clear();\n continue;\n }\n if (code === eoiCode) {\n break;\n }\n if (code < dict.length) {\n if (last !== clearCode) {\n dict.push(dict[last].concat(dict[code][0]));\n }\n }\n else {\n if (code !== dict.length) {\n throw new Error('Invalid LZW code.');\n }\n dict.push(dict[last].concat(dict[last][0]));\n }\n output.push.apply(output, dict[code]);\n if (dict.length === 1 << codeSize && codeSize < 12) {\n // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\n codeSize++;\n }\n }\n // I don't know if this is technically an error, but some GIFs do it.\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\n return output;\n};\n// The actual parsing; returns an object with properties.\nclass ParseGif {\n constructor(stream, color = Color.Magenta) {\n this._st = null;\n this._handler = {};\n this._transparentColor = null;\n this.frames = [];\n this.images = [];\n this.globalColorTable = [];\n this.checkBytes = [];\n // LZW (GIF-specific)\n this.parseColorTable = (entries) => {\n // Each entry is 3 bytes, for RGB.\n const ct = [];\n for (let i = 0; i < entries; i++) {\n const rgb = this._st.readBytes(3);\n const rgba = '#' +\n rgb\n .map((x) => {\n const hex = x.toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n })\n .join('');\n ct.push(rgba);\n }\n return ct;\n };\n this.readSubBlocks = () => {\n let size, data;\n data = '';\n do {\n size = this._st.readByte();\n data += this._st.read(size);\n } while (size !== 0);\n return data;\n };\n this.parseHeader = () => {\n const hdr = {\n sig: null,\n ver: null,\n width: null,\n height: null,\n colorRes: null,\n globalColorTableSize: null,\n gctFlag: null,\n sorted: null,\n globalColorTable: [],\n bgColor: null,\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n };\n hdr.sig = this._st.read(3);\n hdr.ver = this._st.read(3);\n if (hdr.sig !== 'GIF') {\n throw new Error('Not a GIF file.'); // XXX: This should probably be handled more nicely.\n }\n hdr.width = this._st.readUnsigned();\n hdr.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n hdr.gctFlag = bits.shift();\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\n hdr.sorted = bits.shift();\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\n hdr.bgColor = this._st.readByte();\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n if (hdr.gctFlag) {\n hdr.globalColorTable = this.parseColorTable(1 << (hdr.globalColorTableSize + 1));\n this.globalColorTable = hdr.globalColorTable;\n }\n if (this._handler.hdr && this._handler.hdr(hdr)) {\n this.checkBytes.push(this._handler.hdr);\n }\n };\n this.parseExt = (block) => {\n const parseGCExt = (block) => {\n this.checkBytes.push(this._st.readByte()); // Always 4\n const bits = byteToBitArr(this._st.readByte());\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\n block.userInput = bits.shift();\n block.transparencyGiven = bits.shift();\n block.delayTime = this._st.readUnsigned();\n block.transparencyIndex = this._st.readByte();\n block.terminator = this._st.readByte();\n if (this._handler.gce && this._handler.gce(block)) {\n this.checkBytes.push(this._handler.gce);\n }\n };\n const parseComExt = (block) => {\n block.comment = this.readSubBlocks();\n if (this._handler.com && this._handler.com(block)) {\n this.checkBytes.push(this._handler.com);\n }\n };\n const parsePTExt = (block) => {\n this.checkBytes.push(this._st.readByte()); // Always 12\n block.ptHeader = this._st.readBytes(12);\n block.ptData = this.readSubBlocks();\n if (this._handler.pte && this._handler.pte(block)) {\n this.checkBytes.push(this._handler.pte);\n }\n };\n const parseAppExt = (block) => {\n const parseNetscapeExt = (block) => {\n this.checkBytes.push(this._st.readByte()); // Always 3\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\n block.iterations = this._st.readUnsigned();\n block.terminator = this._st.readByte();\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) {\n this.checkBytes.push(this._handler.app);\n }\n };\n const parseUnknownAppExt = (block) => {\n block.appData = this.readSubBlocks();\n // FIXME: This won't work if a handler wants to match on any identifier.\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) {\n this.checkBytes.push(this._handler.app[block.identifier]);\n }\n };\n this.checkBytes.push(this._st.readByte()); // Always 11\n block.identifier = this._st.read(8);\n block.authCode = this._st.read(3);\n switch (block.identifier) {\n case 'NETSCAPE':\n parseNetscapeExt(block);\n break;\n default:\n parseUnknownAppExt(block);\n break;\n }\n };\n const parseUnknownExt = (block) => {\n block.data = this.readSubBlocks();\n if (this._handler.unknown && this._handler.unknown(block)) {\n this.checkBytes.push(this._handler.unknown);\n }\n };\n block.label = this._st.readByte();\n switch (block.label) {\n case 0xf9:\n block.extType = 'gce';\n parseGCExt(block);\n break;\n case 0xfe:\n block.extType = 'com';\n parseComExt(block);\n break;\n case 0x01:\n block.extType = 'pte';\n parsePTExt(block);\n break;\n case 0xff:\n block.extType = 'app';\n parseAppExt(block);\n break;\n default:\n block.extType = 'unknown';\n parseUnknownExt(block);\n break;\n }\n };\n this.parseImg = (img) => {\n const deinterlace = (pixels, width) => {\n // Of course this defeats the purpose of interlacing. And it's *probably*\n // the least efficient way it's ever been implemented. But nevertheless...\n const newPixels = new Array(pixels.length);\n const rows = pixels.length / width;\n const cpRow = (toRow, fromRow) => {\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\n newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels));\n };\n const offsets = [0, 4, 2, 1];\n const steps = [8, 8, 4, 2];\n let fromRow = 0;\n for (let pass = 0; pass < 4; pass++) {\n for (let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) {\n cpRow(toRow, fromRow);\n fromRow++;\n }\n }\n return newPixels;\n };\n img.leftPos = this._st.readUnsigned();\n img.topPos = this._st.readUnsigned();\n img.width = this._st.readUnsigned();\n img.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n img.lctFlag = bits.shift();\n img.interlaced = bits.shift();\n img.sorted = bits.shift();\n img.reserved = bits.splice(0, 2);\n img.lctSize = bitsToNum(bits.splice(0, 3));\n if (img.lctFlag) {\n img.lct = this.parseColorTable(1 << (img.lctSize + 1));\n }\n img.lzwMinCodeSize = this._st.readByte();\n const lzwData = this.readSubBlocks();\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\n if (img.interlaced) {\n // Move\n img.pixels = deinterlace(img.pixels, img.width);\n }\n this.frames.push(img);\n this.arrayToImage(img);\n if (this._handler.img && this._handler.img(img)) {\n this.checkBytes.push(this._handler);\n }\n };\n this.parseBlock = () => {\n const block = {\n sentinel: this._st.readByte(),\n type: ''\n };\n const blockChar = String.fromCharCode(block.sentinel);\n switch (blockChar) {\n case '!':\n block.type = 'ext';\n this.parseExt(block);\n break;\n case ',':\n block.type = 'img';\n this.parseImg(block);\n break;\n case ';':\n block.type = 'eof';\n if (this._handler.eof && this._handler.eof(block)) {\n this.checkBytes.push(this._handler.eof);\n }\n break;\n default:\n throw new Error('Unknown block: 0x' + block.sentinel.toString(16));\n }\n if (block.type !== 'eof') {\n this.parseBlock();\n }\n };\n this.arrayToImage = (frame) => {\n let count = 0;\n const c = document.createElement('canvas');\n c.id = count.toString();\n c.width = frame.width;\n c.height = frame.height;\n count++;\n const context = c.getContext('2d');\n const pixSize = 1;\n let y = 0;\n let x = 0;\n for (let i = 0; i < frame.pixels.length; i++) {\n if (x % frame.width === 0) {\n y++;\n x = 0;\n }\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) {\n context.fillStyle = `rgba(0, 0, 0, 0)`;\n }\n else {\n context.fillStyle = this.globalColorTable[frame.pixels[i]];\n }\n context.fillRect(x, y, pixSize, pixSize);\n x++;\n }\n const img = new Image();\n img.src = c.toDataURL();\n this.images.push(img);\n };\n this._st = stream;\n this._handler = {};\n this._transparentColor = color;\n this.parseHeader();\n this.parseBlock();\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Font.ts\n\n\nclass FontSource {\n constructor(\n /**\n * Path to the font resource relative from the HTML document hosting the game, or absolute\n */\n path, \n /**\n * The font family name\n */\n family, { bustCache, ...options } = {}) {\n this.path = path;\n this.family = family;\n this._isLoaded = false;\n this._resource = new Resource(path, 'blob', bustCache);\n this._options = options;\n }\n async load() {\n if (this.isLoaded()) {\n return this.data;\n }\n try {\n const blob = await this._resource.load();\n const url = URL.createObjectURL(blob);\n if (!this.data) {\n this.data = new FontFace(this.family, `url(${url})`);\n document.fonts.add(this.data);\n }\n await this.data.load();\n this._isLoaded = true;\n }\n catch (error) {\n throw `Error loading FontSource from path '${this.path}' with error [${error.message}]`;\n }\n return this.data;\n }\n isLoaded() {\n return this._isLoaded;\n }\n /**\n * Build a font from this FontSource.\n * @param options {FontOptions} Override the font options\n */\n toFont(options) {\n return new Font({ family: this.family, ...this._options, ...options });\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Index.ts\n\n\n\n\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/index.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Util/Coroutine.ts\n/**\n * Excalibur coroutine helper, returns a promise when complete. Coroutines run before frame update.\n *\n * Each coroutine yield is 1 excalibur frame. Coroutines get passed the elapsed time our of yield. Coroutines\n * run internally on the excalibur clock.\n *\n * If you yield a promise it will be awaited before resumed\n * If you yield a number it will wait that many ms before resumed\n * @param engine\n * @param coroutineGenerator\n */\nfunction coroutine(engine, coroutineGenerator) {\n return new Promise((resolve, reject) => {\n const generator = coroutineGenerator();\n const loop = (elapsedMs) => {\n try {\n const { done, value } = generator.next(elapsedMs);\n if (done) {\n resolve();\n }\n if (value instanceof Promise) {\n value.then(() => {\n // schedule next loop\n engine.clock.schedule(loop);\n });\n }\n else if (value === undefined || value === (void 0)) {\n // schedule next frame\n engine.clock.schedule(loop);\n }\n else {\n // schedule value milliseconds from now\n engine.clock.schedule(loop, value || 0);\n }\n }\n catch (e) {\n reject(e);\n }\n };\n loop(engine.clock.elapsed()); // run first frame immediately\n });\n}\n\n;// CONCATENATED MODULE: ./Director/Transition.ts\n\n\n\n\n\n\n\n\n\n/**\n * Base Transition that can be extended to provide custom scene transitions in Excalibur.\n */\nclass Transition extends Entity {\n /**\n * Returns a number between [0, 1] indicating what state the transition is in.\n *\n * * For 'out' direction transitions start at 0 and end at 1\n * * For 'in' direction transitions start at 1 and end at 0\n */\n get progress() {\n return this._currentProgress;\n }\n get complete() {\n if (this.direction === 'out') {\n return this.progress >= 1;\n }\n else {\n return this.progress <= 0;\n }\n }\n constructor(options) {\n var _a, _b, _c, _d;\n super();\n this._logger = Logger.getInstance();\n this.transform = new TransformComponent();\n this.graphics = new GraphicsComponent();\n this._completeFuture = new Future();\n // State needs to be reset between uses\n this.started = false;\n this._currentDistance = 0;\n this._currentProgress = 0;\n this.done = this._completeFuture.promise;\n this.name = `Transition#${this.id}`;\n this.duration = options.duration;\n this.easing = (_a = options.easing) !== null && _a !== void 0 ? _a : EasingFunctions.Linear;\n this.direction = (_b = options.direction) !== null && _b !== void 0 ? _b : 'out';\n this.hideLoader = (_c = options.hideLoader) !== null && _c !== void 0 ? _c : false;\n this.blockInput = (_d = options.blockInput) !== null && _d !== void 0 ? _d : false;\n this.transform.coordPlane = CoordPlane.Screen;\n this.transform.pos = Vector.Zero;\n this.transform.z = Infinity; // Transitions sit on top of everything\n this.graphics.anchor = Vector.Zero;\n this.addComponent(this.transform);\n this.addComponent(this.graphics);\n if (this.direction === 'out') {\n this._currentProgress = 0;\n }\n else {\n this._currentProgress = 1;\n }\n }\n /**\n * Overridable lifecycle method, called before each update.\n *\n * **WARNING BE SURE** to call `super.updateTransition()` if overriding in your own custom implementation\n * @param engine\n * @param delta\n */\n updateTransition(engine, delta) {\n if (this.complete) {\n return;\n }\n this._currentDistance += clamp(delta / this.duration, 0, 1);\n if (this._currentDistance >= 1) {\n this._currentDistance = 1;\n }\n if (this.direction === 'out') {\n this._currentProgress = clamp(this.easing(this._currentDistance, 0, 1, 1), 0, 1);\n }\n else {\n this._currentProgress = clamp(this.easing(this._currentDistance, 1, 0, 1), 0, 1);\n }\n }\n /**\n * Overridable lifecycle method, called right before the previous scene has deactivated.\n *\n * This gives incoming transition a chance to grab info from previous scene if desired\n * @param scene\n */\n async onPreviousSceneDeactivate(scene) {\n // override me\n }\n /**\n * Overridable lifecycle method, called once at the beginning of the transition\n *\n * `progress` is given between 0 and 1\n * @param progress\n */\n onStart(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called every frame of the transition\n *\n * `progress` is given between 0 and 1\n * @param progress\n */\n onUpdate(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called at the end of the transition,\n *\n * `progress` is given between 0 and 1\n * @param progress\n */\n onEnd(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called when the transition is reset\n *\n * Use this to override and provide your own reset logic for internal state in custom transition implementations\n */\n onReset() {\n // override me\n }\n /**\n * reset() is called by the engine to reset transitions\n */\n reset() {\n this.started = false;\n this._completeFuture = new Future();\n this.done = this._completeFuture.promise;\n this._currentDistance = 0;\n if (this.direction === 'out') {\n this._currentProgress = 0;\n }\n else {\n this._currentProgress = 1;\n }\n this.onReset();\n }\n play(engine, targetScene) {\n if (this.started) {\n this.reset();\n this._logger.warn(`Attempted to play a transition ${this.name} that is already playing, reset transition.`);\n }\n const currentScene = targetScene !== null && targetScene !== void 0 ? targetScene : engine.currentScene;\n currentScene.add(this);\n const self = this;\n return coroutine(engine, function* () {\n while (!self.complete) {\n const elapsed = yield; // per frame\n self.updateTransition(engine, elapsed);\n self.execute();\n }\n });\n }\n /**\n * execute() is called by the engine every frame to update the Transition lifecycle onStart/onUpdate/onEnd\n */\n execute() {\n if (!this.isInitialized) {\n return;\n }\n if (!this.started) {\n this.started = true;\n this.onStart(this.progress);\n }\n this.onUpdate(this.progress);\n if (this.complete && !this._completeFuture.isCompleted) {\n this.onEnd(this.progress);\n this._completeFuture.resolve();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Director/FadeInOut.ts\n\n\n\nclass FadeInOut extends Transition {\n constructor(options) {\n var _a, _b;\n super({\n ...options,\n duration: (_a = options.duration) !== null && _a !== void 0 ? _a : 2000\n });\n this.name = `FadeInOut#${this.id}`;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n }\n onInitialize(engine) {\n this.transform.pos = engine.screen.unsafeArea.topLeft;\n this.screenCover = new Rectangle({\n width: engine.screen.resolution.width,\n height: engine.screen.resolution.height,\n color: this.color\n });\n this.graphics.add(this.screenCover);\n this.graphics.opacity = this.progress;\n }\n onReset() {\n this.graphics.opacity = this.progress;\n }\n onStart(progress) {\n this.graphics.opacity = progress;\n }\n onEnd(progress) {\n this.graphics.opacity = progress;\n }\n onUpdate(progress) {\n this.graphics.opacity = progress;\n }\n}\n\n;// CONCATENATED MODULE: ./Director/CrossFade.ts\n\n\n\n/**\n * CrossFades between the previous scene and the destination scene\n *\n * Note: CrossFade only works as an \"in\" transition\n */\nclass CrossFade extends Transition {\n constructor(options) {\n super({ direction: 'in', ...options }); // default the correct direction\n this.name = `CrossFade#${this.id}`;\n }\n async onPreviousSceneDeactivate(scene) {\n this.image = await scene.engine.screenshot(true);\n // Firefox is particularly slow\n // needed in case the image isn't ready yet\n await this.image.decode();\n }\n onInitialize(engine) {\n this.engine = engine;\n this.transform.pos = engine.screen.unsafeArea.topLeft;\n this.screenCover = ImageSource.fromHtmlImageElement(this.image).toSprite();\n this.graphics.add(this.screenCover);\n this.transform.scale = vec(1 / engine.screen.pixelRatio, 1 / engine.screen.pixelRatio);\n this.graphics.opacity = this.progress;\n }\n onStart(_progress) {\n this.graphics.opacity = this.progress;\n }\n onReset() {\n this.graphics.opacity = this.progress;\n }\n onEnd(progress) {\n this.graphics.opacity = progress;\n }\n onUpdate(progress) {\n this.graphics.opacity = progress;\n }\n}\n\n;// CONCATENATED MODULE: ./Director/index.ts\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Graphics/Line.ts\n\n\n\nclass Line extends Graphic {\n constructor(options) {\n super();\n this.color = Color.Black;\n this.thickness = 1;\n const { start, end, color, thickness } = options;\n this.start = start;\n this.end = end;\n this.color = color !== null && color !== void 0 ? color : this.color;\n this.thickness = thickness !== null && thickness !== void 0 ? thickness : this.thickness;\n this._localBounds = this._calculateBounds();\n const { width, height } = this._localBounds;\n this.width = width;\n this.height = height;\n }\n get localBounds() {\n return this._localBounds;\n }\n _calculateBounds() {\n const lineNormal = this.end.sub(this.start).normal();\n const halfThickness = this.thickness / 2;\n const points = [\n this.start.add(lineNormal.scale(halfThickness)),\n this.end.add(lineNormal.scale(halfThickness)),\n this.end.add(lineNormal.scale(-halfThickness)),\n this.start.add(lineNormal.scale(-halfThickness))\n ];\n return BoundingBox.fromPoints(points);\n }\n _drawImage(ctx, _x, _y) {\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\n }\n clone() {\n return new Line({\n start: this.start,\n end: this.end,\n color: this.color,\n thickness: this.thickness\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Polygon.ts\n\n\n\n/**\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\n *\n * Polygons default to [[ImageFiltering.Blended]]\n */\nclass Polygon extends Raster {\n get points() {\n return this._points;\n }\n set points(points) {\n this._points = points;\n const min = this.minPoint;\n this.width = this._points.reduce((max, p) => Math.max(p.x, max), 0) - min.x;\n this.height = this._points.reduce((max, p) => Math.max(p.y, max), 0) - min.y;\n this.flagDirty();\n }\n get minPoint() {\n const minX = this._points.reduce((min, p) => Math.min(p.x, min), Infinity);\n const minY = this._points.reduce((min, p) => Math.min(p.y, min), Infinity);\n return vec(minX, minY);\n }\n constructor(options) {\n super(options);\n this.points = options.points;\n this.filtering = ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Polygon({\n points: this.points.map((p) => p.clone()),\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.points && this.points.length) {\n ctx.beginPath();\n // Iterate through the supplied points and construct a 'polygon'\n const min = this.minPoint.negate();\n const firstPoint = this.points[0].add(min);\n ctx.moveTo(firstPoint.x, firstPoint.y);\n this.points.forEach((point) => {\n ctx.lineTo(point.x + min.x, point.y + min.y);\n });\n ctx.lineTo(firstPoint.x, firstPoint.y);\n ctx.closePath();\n if (this.color) {\n ctx.fill();\n }\n if (this.strokeColor) {\n ctx.stroke();\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/index.ts\n// Graphics\n\n\n\n\n\n\n\n// Graphics ECS\n\n\n\n\n\n// Raster graphics\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// Post Processor\n\n\n\n\n\n\n// Rendering\n\n\n\n\n\n// Debug\n\n// Util\n\n\n\n;// CONCATENATED MODULE: ./Input/Index.ts\n// This import site is deprecated\n// TODO remove deprecated exports in v0.29.0\n\n\n\n\n\n\n\n\n\n\n\n// Re-export hack to deprecate import site gently\n\n\n;// CONCATENATED MODULE: ./Util/Index.ts\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Util/Decorators.ts\n\n\nconst maxMessages = 5;\nconst obsoleteMessage = {};\nconst resetObsoleteCounter = () => {\n for (const message in obsoleteMessage) {\n obsoleteMessage[message] = 0;\n }\n};\nconst logMessage = (message, options) => {\n const suppressObsoleteMessages = Flags.isEnabled('suppress-obsolete-message');\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\n Logger.getInstance().warn(message);\n // tslint:disable-next-line: no-console\n if (console.trace && options.showStackTrace) {\n // tslint:disable-next-line: no-console\n console.trace();\n }\n }\n obsoleteMessage[message]++;\n};\n/**\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\n */\nfunction obsolete(options) {\n options = {\n message: 'This feature will be removed in future versions of Excalibur.',\n alternateMethod: null,\n showStackTrace: false,\n ...options\n };\n return function (target, property, descriptor) {\n if (descriptor &&\n !(typeof descriptor.value === 'function' || typeof descriptor.get === 'function' || typeof descriptor.set === 'function')) {\n throw new SyntaxError('Only classes/functions/getters/setters can be marked as obsolete');\n }\n const methodSignature = `${target.name || ''}${target.name && property ? '.' : ''}${property ? property : ''}`;\n const message = `${methodSignature} is marked obsolete: ${options.message}` +\n (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : '');\n if (!obsoleteMessage[message]) {\n obsoleteMessage[message] = 0;\n }\n // If descriptor is null it is a class\n const method = descriptor ? { ...descriptor } : target;\n if (!descriptor) {\n // with es2015 classes we need to change our decoration tactic\n class DecoratedClass extends method {\n constructor(...args) {\n logMessage(message, options);\n super(...args);\n }\n }\n return DecoratedClass;\n }\n if (descriptor && descriptor.value) {\n method.value = function () {\n logMessage(message, options);\n return descriptor.value.apply(this, arguments);\n };\n return method;\n }\n if (descriptor && descriptor.get) {\n method.get = function () {\n logMessage(message, options);\n return descriptor.get.apply(this, arguments);\n };\n }\n if (descriptor && descriptor.set) {\n method.set = function () {\n logMessage(message, options);\n return descriptor.set.apply(this, arguments);\n };\n }\n return method;\n };\n}\n\n;// CONCATENATED MODULE: ./Util/Semaphore.ts\n\nclass AsyncWaitQueue {\n constructor() {\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\n this._queue = [];\n }\n get length() {\n return this._queue.length;\n }\n enqueue() {\n const future = new Future();\n this._queue.push(future);\n return future.promise;\n }\n dequeue(value) {\n const future = this._queue.shift();\n future.resolve(value);\n }\n}\n/**\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\n *\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\n * around browser limitations like max Image.decode() calls in chromium being 256.\n */\nclass Semaphore {\n constructor(_count) {\n this._count = _count;\n this._waitQueue = new AsyncWaitQueue();\n }\n get count() {\n return this._count;\n }\n get waiting() {\n return this._waitQueue.length;\n }\n // eslint-disable-next-line require-await\n async enter() {\n if (this._count !== 0) {\n this._count--;\n return Promise.resolve();\n }\n return this._waitQueue.enqueue();\n }\n exit(count = 1) {\n if (count === 0) {\n return;\n }\n while (count !== 0 && this._waitQueue.length !== 0) {\n this._waitQueue.dequeue(null);\n count--;\n }\n this._count += count;\n }\n}\n\n;// CONCATENATED MODULE: ./index.ts\n/**\n * The current Excalibur version string\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\n */\nconst EX_VERSION = \"0.29.1\";\n\npolyfill();\n// This file is used as the bundle entry point and exports everything\n// that will be exposed as the `ex` global variable.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// ex.Events namespace\n\n\n// ex.Input namespace\n// TODO deprecated import site remove in v0.29.0\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// ex.Util namespaces\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// ex.Deprecated\n// import * as deprecated from './Deprecated';\n// export { deprecated as Deprecated };\n// export * from './Deprecated';\n\n})();\n\nvar __webpack_exports__ActionCompleteEvent = __webpack_exports__.y1j;\nvar __webpack_exports__ActionContext = __webpack_exports__.fWn;\nvar __webpack_exports__ActionQueue = __webpack_exports__.Ia8;\nvar __webpack_exports__ActionSequence = __webpack_exports__.rqv;\nvar __webpack_exports__ActionStartEvent = __webpack_exports__.zH6;\nvar __webpack_exports__ActionsComponent = __webpack_exports__.hLI;\nvar __webpack_exports__ActionsSystem = __webpack_exports__.yyv;\nvar __webpack_exports__ActivateEvent = __webpack_exports__.tX5;\nvar __webpack_exports__Actor = __webpack_exports__.vtX;\nvar __webpack_exports__AddedComponent = __webpack_exports__.r7K;\nvar __webpack_exports__AffineMatrix = __webpack_exports__.cE4;\nvar __webpack_exports__Animation = __webpack_exports__.fwF;\nvar __webpack_exports__AnimationDirection = __webpack_exports__.sce;\nvar __webpack_exports__AnimationEvents = __webpack_exports__.AQ6;\nvar __webpack_exports__AnimationStrategy = __webpack_exports__._c7;\nvar __webpack_exports__ArcadeSolver = __webpack_exports__.KUs;\nvar __webpack_exports__AudioContextFactory = __webpack_exports__.Ajp;\nvar __webpack_exports__Axes = __webpack_exports__.dkO;\nvar __webpack_exports__Axis = __webpack_exports__.RDh;\nvar __webpack_exports__BaseAlign = __webpack_exports__._H9;\nvar __webpack_exports__Blink = __webpack_exports__.mxs;\nvar __webpack_exports__BodyComponent = __webpack_exports__.OmD;\nvar __webpack_exports__BoundingBox = __webpack_exports__.kBf;\nvar __webpack_exports__BroadphaseStrategy = __webpack_exports__.C4F;\nvar __webpack_exports__BrowserComponent = __webpack_exports__.NQt;\nvar __webpack_exports__BrowserEvents = __webpack_exports__.JjN;\nvar __webpack_exports__Buttons = __webpack_exports__.EK_;\nvar __webpack_exports__Camera = __webpack_exports__.V1s;\nvar __webpack_exports__CameraEvents = __webpack_exports__.xHm;\nvar __webpack_exports__Canvas = __webpack_exports__.Xz7;\nvar __webpack_exports__Circle = __webpack_exports__.Cdc;\nvar __webpack_exports__CircleCollider = __webpack_exports__.FKn;\nvar __webpack_exports__Clock = __webpack_exports__.SUY;\nvar __webpack_exports__ClosestLine = __webpack_exports__.ab2;\nvar __webpack_exports__ClosestLineJumpTable = __webpack_exports__.GfZ;\nvar __webpack_exports__Collider = __webpack_exports__.YMS;\nvar __webpack_exports__ColliderComponent = __webpack_exports__.oyv;\nvar __webpack_exports__CollisionContact = __webpack_exports__.aUb;\nvar __webpack_exports__CollisionEndEvent = __webpack_exports__.SdD;\nvar __webpack_exports__CollisionGroup = __webpack_exports__.JUv;\nvar __webpack_exports__CollisionGroupManager = __webpack_exports__.jEj;\nvar __webpack_exports__CollisionJumpTable = __webpack_exports__.TFq;\nvar __webpack_exports__CollisionPostSolveEvent = __webpack_exports__.HDU;\nvar __webpack_exports__CollisionPreSolveEvent = __webpack_exports__.R_y;\nvar __webpack_exports__CollisionStartEvent = __webpack_exports__.t50;\nvar __webpack_exports__CollisionSystem = __webpack_exports__.s$$;\nvar __webpack_exports__CollisionType = __webpack_exports__.v2G;\nvar __webpack_exports__Color = __webpack_exports__.Ilk;\nvar __webpack_exports__ColorBlindFlags = __webpack_exports__.s9i;\nvar __webpack_exports__ColorBlindnessMode = __webpack_exports__.dxL;\nvar __webpack_exports__ColorBlindnessPostProcessor = __webpack_exports__.LLX;\nvar __webpack_exports__Component = __webpack_exports__.wA2;\nvar __webpack_exports__CompositeCollider = __webpack_exports__.R_p;\nvar __webpack_exports__Configurable = __webpack_exports__.IQ$;\nvar __webpack_exports__ConsoleAppender = __webpack_exports__.I5F;\nvar __webpack_exports__ContactConstraintPoint = __webpack_exports__.X8$;\nvar __webpack_exports__ContactEndEvent = __webpack_exports__.FR6;\nvar __webpack_exports__ContactSolveBias = __webpack_exports__.pTZ;\nvar __webpack_exports__ContactStartEvent = __webpack_exports__.U8o;\nvar __webpack_exports__CoordPlane = __webpack_exports__.kbG;\nvar __webpack_exports__CrossFade = __webpack_exports__.FEv;\nvar __webpack_exports__DeactivateEvent = __webpack_exports__.iS_;\nvar __webpack_exports__Debug = __webpack_exports__.cGG;\nvar __webpack_exports__DebugConfig = __webpack_exports__.ETM;\nvar __webpack_exports__DebugGraphicsComponent = __webpack_exports__.RPN;\nvar __webpack_exports__DebugSystem = __webpack_exports__.skb;\nvar __webpack_exports__DebugText = __webpack_exports__.SLU;\nvar __webpack_exports__DefaultAntialiasOptions = __webpack_exports__.Q3w;\nvar __webpack_exports__DefaultLoader = __webpack_exports__.xK2;\nvar __webpack_exports__DefaultPhysicsConfig = __webpack_exports__.vrO;\nvar __webpack_exports__DefaultPixelArtOptions = __webpack_exports__.EA2;\nvar __webpack_exports__DegreeOfFreedom = __webpack_exports__.RdJ;\nvar __webpack_exports__Delay = __webpack_exports__.cNu;\nvar __webpack_exports__DeprecatedStaticToConfig = __webpack_exports__.wtG;\nvar __webpack_exports__Detector = __webpack_exports__.gU7;\nvar __webpack_exports__Die = __webpack_exports__.LSk;\nvar __webpack_exports__Direction = __webpack_exports__.Nmp;\nvar __webpack_exports__Director = __webpack_exports__.twX;\nvar __webpack_exports__DirectorEvents = __webpack_exports__.UND;\nvar __webpack_exports__DisplayMode = __webpack_exports__.d1Y;\nvar __webpack_exports__DynamicTree = __webpack_exports__.xrL;\nvar __webpack_exports__DynamicTreeCollisionProcessor = __webpack_exports__.sRW;\nvar __webpack_exports__EX_VERSION = __webpack_exports__.cmV;\nvar __webpack_exports__EaseBy = __webpack_exports__.qWz;\nvar __webpack_exports__EaseTo = __webpack_exports__.N0Q;\nvar __webpack_exports__EasingFunctions = __webpack_exports__.q8b;\nvar __webpack_exports__EdgeCollider = __webpack_exports__.ynB;\nvar __webpack_exports__ElasticToActorStrategy = __webpack_exports__.jT9;\nvar __webpack_exports__EmitterType = __webpack_exports__.wAz;\nvar __webpack_exports__Engine = __webpack_exports__.D4V;\nvar __webpack_exports__EngineEvents = __webpack_exports__.NLr;\nvar __webpack_exports__EnterTriggerEvent = __webpack_exports__.N6H;\nvar __webpack_exports__EnterViewPortEvent = __webpack_exports__.W1A;\nvar __webpack_exports__Entity = __webpack_exports__.JHW;\nvar __webpack_exports__EntityEvents = __webpack_exports__.ZZ$;\nvar __webpack_exports__EntityManager = __webpack_exports__.v2K;\nvar __webpack_exports__EventDispatcher = __webpack_exports__.pBf;\nvar __webpack_exports__EventEmitter = __webpack_exports__.vpe;\nvar __webpack_exports__EventTypes = __webpack_exports__.GMl;\nvar __webpack_exports__Events = __webpack_exports__.zW2;\nvar __webpack_exports__ExResponse = __webpack_exports__.B0K;\nvar __webpack_exports__ExcaliburGraphicsContext2DCanvas = __webpack_exports__.Nv7;\nvar __webpack_exports__ExcaliburGraphicsContextWebGL = __webpack_exports__.C_p;\nvar __webpack_exports__ExitTriggerEvent = __webpack_exports__.MUA;\nvar __webpack_exports__ExitViewPortEvent = __webpack_exports__.xqU;\nvar __webpack_exports__Fade = __webpack_exports__.pTp;\nvar __webpack_exports__FadeInOut = __webpack_exports__.trb;\nvar __webpack_exports__Flags = __webpack_exports__.vUK;\nvar __webpack_exports__Follow = __webpack_exports__.j9l;\nvar __webpack_exports__Font = __webpack_exports__.Zxw;\nvar __webpack_exports__FontCache = __webpack_exports__.v51;\nvar __webpack_exports__FontSource = __webpack_exports__.gYv;\nvar __webpack_exports__FontStyle = __webpack_exports__.Hdx;\nvar __webpack_exports__FontUnit = __webpack_exports__.Z$d;\nvar __webpack_exports__FpsSampler = __webpack_exports__.iqV;\nvar __webpack_exports__FrameStats = __webpack_exports__.o$7;\nvar __webpack_exports__Future = __webpack_exports__.olM;\nvar __webpack_exports__GameEvent = __webpack_exports__.Zm$;\nvar __webpack_exports__GameStartEvent = __webpack_exports__.$QH;\nvar __webpack_exports__GameStopEvent = __webpack_exports__.i78;\nvar __webpack_exports__Gamepad = __webpack_exports__.nJg;\nvar __webpack_exports__GamepadAxisEvent = __webpack_exports__.h6u;\nvar __webpack_exports__GamepadButtonEvent = __webpack_exports__.hts;\nvar __webpack_exports__GamepadConnectEvent = __webpack_exports__.j88;\nvar __webpack_exports__GamepadDisconnectEvent = __webpack_exports__.VME;\nvar __webpack_exports__Gamepads = __webpack_exports__.fy2;\nvar __webpack_exports__Gif = __webpack_exports__.nt;\nvar __webpack_exports__GlobalCoordinates = __webpack_exports__.Ukr;\nvar __webpack_exports__Graphic = __webpack_exports__.zsu;\nvar __webpack_exports__GraphicsComponent = __webpack_exports__.oA6;\nvar __webpack_exports__GraphicsGroup = __webpack_exports__.TVh;\nvar __webpack_exports__GraphicsSystem = __webpack_exports__.xxj;\nvar __webpack_exports__HiddenEvent = __webpack_exports__.XdK;\nvar __webpack_exports__HorizontalFirst = __webpack_exports__.fBD;\nvar __webpack_exports__ImageFiltering = __webpack_exports__.Jmb;\nvar __webpack_exports__ImageSource = __webpack_exports__.cXo;\nvar __webpack_exports__InitializeEvent = __webpack_exports__.Dm5;\nvar __webpack_exports__Input = __webpack_exports__.IIB;\nvar __webpack_exports__InputHost = __webpack_exports__.IX$;\nvar __webpack_exports__InputMapper = __webpack_exports__.ebW;\nvar __webpack_exports__Integrator = __webpack_exports__.zI0;\nvar __webpack_exports__IsometricEntityComponent = __webpack_exports__.LYD;\nvar __webpack_exports__IsometricEntitySystem = __webpack_exports__.cEG;\nvar __webpack_exports__IsometricMap = __webpack_exports__.SEl;\nvar __webpack_exports__IsometricTile = __webpack_exports__.t9V;\nvar __webpack_exports__KeyEvent = __webpack_exports__.ez5;\nvar __webpack_exports__Keyboard = __webpack_exports__.N1d;\nvar __webpack_exports__Keys = __webpack_exports__.R8U;\nvar __webpack_exports__KillEvent = __webpack_exports__.SKZ;\nvar __webpack_exports__Label = __webpack_exports__.__J;\nvar __webpack_exports__LimitCameraBoundsStrategy = __webpack_exports__.RI$;\nvar __webpack_exports__Line = __webpack_exports__.x12;\nvar __webpack_exports__LineSegment = __webpack_exports__.ccz;\nvar __webpack_exports__Loader = __webpack_exports__.aNw;\nvar __webpack_exports__LoaderEvents = __webpack_exports__.XrL;\nvar __webpack_exports__LockCameraToActorAxisStrategy = __webpack_exports__.xwn;\nvar __webpack_exports__LockCameraToActorStrategy = __webpack_exports__.dNK;\nvar __webpack_exports__LogLevel = __webpack_exports__.ini;\nvar __webpack_exports__Logger = __webpack_exports__.YdH;\nvar __webpack_exports__Material = __webpack_exports__.F5T;\nvar __webpack_exports__Matrix = __webpack_exports__.y3G;\nvar __webpack_exports__MatrixLocations = __webpack_exports__.l57;\nvar __webpack_exports__MediaEvent = __webpack_exports__.xn0;\nvar __webpack_exports__Meet = __webpack_exports__.t2V;\nvar __webpack_exports__MotionComponent = __webpack_exports__.uxB;\nvar __webpack_exports__MotionSystem = __webpack_exports__.cpd;\nvar __webpack_exports__MoveBy = __webpack_exports__.fiy;\nvar __webpack_exports__MoveTo = __webpack_exports__.$XZ;\nvar __webpack_exports__NativePointerButton = __webpack_exports__.UG6;\nvar __webpack_exports__NativeSoundEvent = __webpack_exports__.uqK;\nvar __webpack_exports__NativeSoundProcessedEvent = __webpack_exports__.STE;\nvar __webpack_exports__None = __webpack_exports__.Hq9;\nvar __webpack_exports__Observable = __webpack_exports__.y$z;\nvar __webpack_exports__OffscreenSystem = __webpack_exports__.mAD;\nvar __webpack_exports__Pair = __webpack_exports__.sOq;\nvar __webpack_exports__ParallaxComponent = __webpack_exports__.hUw;\nvar __webpack_exports__ParallelActions = __webpack_exports__._0G;\nvar __webpack_exports__ParseGif = __webpack_exports__.Sqs;\nvar __webpack_exports__Particle = __webpack_exports__.hpZ;\nvar __webpack_exports__ParticleEmitter = __webpack_exports__.Vol;\nvar __webpack_exports__ParticleTransform = __webpack_exports__.vYX;\nvar __webpack_exports__Physics = __webpack_exports__.wIZ;\nvar __webpack_exports__PhysicsStats = __webpack_exports__.cBi;\nvar __webpack_exports__PhysicsWorld = __webpack_exports__.c30;\nvar __webpack_exports__PointerAbstraction = __webpack_exports__.PGK;\nvar __webpack_exports__PointerButton = __webpack_exports__.MPV;\nvar __webpack_exports__PointerComponent = __webpack_exports__.RFv;\nvar __webpack_exports__PointerEvent = __webpack_exports__.Ux6;\nvar __webpack_exports__PointerEventReceiver = __webpack_exports__.rxy;\nvar __webpack_exports__PointerScope = __webpack_exports__.I$c;\nvar __webpack_exports__PointerSystem = __webpack_exports__.kfC;\nvar __webpack_exports__PointerType = __webpack_exports__.VjY;\nvar __webpack_exports__Polygon = __webpack_exports__.mgq;\nvar __webpack_exports__PolygonCollider = __webpack_exports__.YVA;\nvar __webpack_exports__Pool = __webpack_exports__.Kgp;\nvar __webpack_exports__PostCollisionEvent = __webpack_exports__.HH$;\nvar __webpack_exports__PostDebugDrawEvent = __webpack_exports__.M_d;\nvar __webpack_exports__PostDrawEvent = __webpack_exports__.rgh;\nvar __webpack_exports__PostFrameEvent = __webpack_exports__.Ra6;\nvar __webpack_exports__PostKillEvent = __webpack_exports__.KhR;\nvar __webpack_exports__PostTransformDrawEvent = __webpack_exports__.gvQ;\nvar __webpack_exports__PostUpdateEvent = __webpack_exports__.BS5;\nvar __webpack_exports__PreCollisionEvent = __webpack_exports__.xhz;\nvar __webpack_exports__PreDebugDrawEvent = __webpack_exports__.xOq;\nvar __webpack_exports__PreDrawEvent = __webpack_exports__.a9j;\nvar __webpack_exports__PreFrameEvent = __webpack_exports__.bHk;\nvar __webpack_exports__PreKillEvent = __webpack_exports__.CgK;\nvar __webpack_exports__PreLoadEvent = __webpack_exports__.A0M;\nvar __webpack_exports__PreTransformDrawEvent = __webpack_exports__.cEd;\nvar __webpack_exports__PreUpdateEvent = __webpack_exports__.cuY;\nvar __webpack_exports__Projection = __webpack_exports__.kvE;\nvar __webpack_exports__QuadIndexBuffer = __webpack_exports__.SBu;\nvar __webpack_exports__QuadTree = __webpack_exports__.PsT;\nvar __webpack_exports__Query = __webpack_exports__.AE_;\nvar __webpack_exports__QueryManager = __webpack_exports__.ctO;\nvar __webpack_exports__RadiusAroundActorStrategy = __webpack_exports__.OLH;\nvar __webpack_exports__Random = __webpack_exports__.kky;\nvar __webpack_exports__Raster = __webpack_exports__.nSF;\nvar __webpack_exports__Ray = __webpack_exports__.zHn;\nvar __webpack_exports__RealisticSolver = __webpack_exports__.zwx;\nvar __webpack_exports__Rectangle = __webpack_exports__.AeJ;\nvar __webpack_exports__RemovedComponent = __webpack_exports__.hLz;\nvar __webpack_exports__Repeat = __webpack_exports__.wA;\nvar __webpack_exports__RepeatForever = __webpack_exports__.jhr;\nvar __webpack_exports__Resolution = __webpack_exports__.GVs;\nvar __webpack_exports__Resource = __webpack_exports__._zO;\nvar __webpack_exports__ResourceEvents = __webpack_exports__.LXZ;\nvar __webpack_exports__RotateBy = __webpack_exports__.w6$;\nvar __webpack_exports__RotateTo = __webpack_exports__.mhV;\nvar __webpack_exports__RotationType = __webpack_exports__.MOD;\nvar __webpack_exports__ScaleBy = __webpack_exports__.kwd;\nvar __webpack_exports__ScaleTo = __webpack_exports__.Lmr;\nvar __webpack_exports__Scene = __webpack_exports__.xsS;\nvar __webpack_exports__SceneEvents = __webpack_exports__.K5l;\nvar __webpack_exports__Screen = __webpack_exports__.lLr;\nvar __webpack_exports__ScreenAppender = __webpack_exports__.Z$r;\nvar __webpack_exports__ScreenElement = __webpack_exports__.IXb;\nvar __webpack_exports__ScreenEvents = __webpack_exports__.Xsu;\nvar __webpack_exports__ScreenShader = __webpack_exports__.SGH;\nvar __webpack_exports__ScrollPreventionMode = __webpack_exports__.SMj;\nvar __webpack_exports__Semaphore = __webpack_exports__.L34;\nvar __webpack_exports__Shader = __webpack_exports__.exe;\nvar __webpack_exports__Shape = __webpack_exports__.bnF;\nvar __webpack_exports__Side = __webpack_exports__.MFA;\nvar __webpack_exports__SolverStrategy = __webpack_exports__.kPj;\nvar __webpack_exports__Sound = __webpack_exports__.$uU;\nvar __webpack_exports__SoundEvents = __webpack_exports__.Sap;\nvar __webpack_exports__Sprite = __webpack_exports__.jyi;\nvar __webpack_exports__SpriteFont = __webpack_exports__.E03;\nvar __webpack_exports__SpriteSheet = __webpack_exports__.V6q;\nvar __webpack_exports__StandardClock = __webpack_exports__.rg2;\nvar __webpack_exports__StateMachine = __webpack_exports__.DVW;\nvar __webpack_exports__StrategyContainer = __webpack_exports__.nVo;\nvar __webpack_exports__Stream = __webpack_exports__.F6N;\nvar __webpack_exports__System = __webpack_exports__.xP7;\nvar __webpack_exports__SystemManager = __webpack_exports__.Odq;\nvar __webpack_exports__SystemPriority = __webpack_exports__.uY9;\nvar __webpack_exports__SystemType = __webpack_exports__.Zif;\nvar __webpack_exports__TagQuery = __webpack_exports__.c_d;\nvar __webpack_exports__TestClock = __webpack_exports__.MJk;\nvar __webpack_exports__Text = __webpack_exports__.xvT;\nvar __webpack_exports__TextAlign = __webpack_exports__.PHM;\nvar __webpack_exports__TextureLoader = __webpack_exports__.dpR;\nvar __webpack_exports__Tile = __webpack_exports__.n9L;\nvar __webpack_exports__TileMap = __webpack_exports__.KwO;\nvar __webpack_exports__TileMapEvents = __webpack_exports__.SxM;\nvar __webpack_exports__Timer = __webpack_exports__.B7y;\nvar __webpack_exports__Toaster = __webpack_exports__.x7r;\nvar __webpack_exports__Transform = __webpack_exports__.wx7;\nvar __webpack_exports__TransformComponent = __webpack_exports__.Uvn;\nvar __webpack_exports__Transition = __webpack_exports__.uTP;\nvar __webpack_exports__TreeNode = __webpack_exports__.OFT;\nvar __webpack_exports__Trigger = __webpack_exports__.xzN;\nvar __webpack_exports__TriggerEvents = __webpack_exports__.CcZ;\nvar __webpack_exports__TwoPI = __webpack_exports__.M5Z;\nvar __webpack_exports__Util = __webpack_exports__.ZrN;\nvar __webpack_exports__Vector = __webpack_exports__.OWs;\nvar __webpack_exports__VectorView = __webpack_exports__.dF9;\nvar __webpack_exports__VertexBuffer = __webpack_exports__.oZy;\nvar __webpack_exports__VertexLayout = __webpack_exports__.rD2;\nvar __webpack_exports__VerticalFirst = __webpack_exports__.KmN;\nvar __webpack_exports__VisibleEvent = __webpack_exports__.VHo;\nvar __webpack_exports__WebAudio = __webpack_exports__.ohE;\nvar __webpack_exports__WebAudioInstance = __webpack_exports__.R$E;\nvar __webpack_exports__WheelDeltaMode = __webpack_exports__.xQN;\nvar __webpack_exports__WheelEvent = __webpack_exports__.AdJ;\nvar __webpack_exports__World = __webpack_exports__.q3I;\nvar __webpack_exports__canonicalizeAngle = __webpack_exports__.Pab;\nvar __webpack_exports__clamp = __webpack_exports__.uZ5;\nvar __webpack_exports__coroutine = __webpack_exports__.TAE;\nvar __webpack_exports__createId = __webpack_exports__.McK;\nvar __webpack_exports__frac = __webpack_exports__.F9c;\nvar __webpack_exports__hasGraphicsTick = __webpack_exports__.k0b;\nvar __webpack_exports__hasOnInitialize = __webpack_exports__.hnT;\nvar __webpack_exports__hasOnPostUpdate = __webpack_exports__.RSJ;\nvar __webpack_exports__hasOnPreUpdate = __webpack_exports__.Mku;\nvar __webpack_exports__hasPostDraw = __webpack_exports__.h90;\nvar __webpack_exports__hasPreDraw = __webpack_exports__.rms;\nvar __webpack_exports__has_initialize = __webpack_exports__.ErP;\nvar __webpack_exports__has_postupdate = __webpack_exports__.aVg;\nvar __webpack_exports__has_preupdate = __webpack_exports__.lPc;\nvar __webpack_exports__isAddedComponent = __webpack_exports__.Z8E;\nvar __webpack_exports__isComponentCtor = __webpack_exports__.k15;\nvar __webpack_exports__isLoaderConstructor = __webpack_exports__.YsU;\nvar __webpack_exports__isRemovedComponent = __webpack_exports__.lNv;\nvar __webpack_exports__isSceneConstructor = __webpack_exports__.Xyg;\nvar __webpack_exports__isScreenElement = __webpack_exports__.cu9;\nvar __webpack_exports__isSystemConstructor = __webpack_exports__.p88;\nvar __webpack_exports__maxMessages = __webpack_exports__.MZQ;\nvar __webpack_exports__obsolete = __webpack_exports__.FUM;\nvar __webpack_exports__pixelSnapEpsilon = __webpack_exports__.BxR;\nvar __webpack_exports__randomInRange = __webpack_exports__.vdf;\nvar __webpack_exports__randomIntInRange = __webpack_exports__.iaL;\nvar __webpack_exports__range = __webpack_exports__.w6H;\nvar __webpack_exports__resetObsoleteCounter = __webpack_exports__.Q4c;\nvar __webpack_exports__sign = __webpack_exports__.Xxe;\nvar __webpack_exports__toDegrees = __webpack_exports__.Uxb;\nvar __webpack_exports__toRadians = __webpack_exports__.Yr5;\nvar __webpack_exports__vec = __webpack_exports__.Bhw;\nvar __webpack_exports__webgl = __webpack_exports__.yOA;\nexport { __webpack_exports__ActionCompleteEvent as ActionCompleteEvent, __webpack_exports__ActionContext as ActionContext, __webpack_exports__ActionQueue as ActionQueue, __webpack_exports__ActionSequence as ActionSequence, __webpack_exports__ActionStartEvent as ActionStartEvent, __webpack_exports__ActionsComponent as ActionsComponent, __webpack_exports__ActionsSystem as ActionsSystem, __webpack_exports__ActivateEvent as ActivateEvent, __webpack_exports__Actor as Actor, __webpack_exports__AddedComponent as AddedComponent, __webpack_exports__AffineMatrix as AffineMatrix, __webpack_exports__Animation as Animation, __webpack_exports__AnimationDirection as AnimationDirection, __webpack_exports__AnimationEvents as AnimationEvents, __webpack_exports__AnimationStrategy as AnimationStrategy, __webpack_exports__ArcadeSolver as ArcadeSolver, __webpack_exports__AudioContextFactory as AudioContextFactory, __webpack_exports__Axes as Axes, __webpack_exports__Axis as Axis, __webpack_exports__BaseAlign as BaseAlign, __webpack_exports__Blink as Blink, __webpack_exports__BodyComponent as BodyComponent, __webpack_exports__BoundingBox as BoundingBox, __webpack_exports__BroadphaseStrategy as BroadphaseStrategy, __webpack_exports__BrowserComponent as BrowserComponent, __webpack_exports__BrowserEvents as BrowserEvents, __webpack_exports__Buttons as Buttons, __webpack_exports__Camera as Camera, __webpack_exports__CameraEvents as CameraEvents, __webpack_exports__Canvas as Canvas, __webpack_exports__Circle as Circle, __webpack_exports__CircleCollider as CircleCollider, __webpack_exports__Clock as Clock, __webpack_exports__ClosestLine as ClosestLine, __webpack_exports__ClosestLineJumpTable as ClosestLineJumpTable, __webpack_exports__Collider as Collider, __webpack_exports__ColliderComponent as ColliderComponent, __webpack_exports__CollisionContact as CollisionContact, __webpack_exports__CollisionEndEvent as CollisionEndEvent, __webpack_exports__CollisionGroup as CollisionGroup, __webpack_exports__CollisionGroupManager as CollisionGroupManager, __webpack_exports__CollisionJumpTable as CollisionJumpTable, __webpack_exports__CollisionPostSolveEvent as CollisionPostSolveEvent, __webpack_exports__CollisionPreSolveEvent as CollisionPreSolveEvent, __webpack_exports__CollisionStartEvent as CollisionStartEvent, __webpack_exports__CollisionSystem as CollisionSystem, __webpack_exports__CollisionType as CollisionType, __webpack_exports__Color as Color, __webpack_exports__ColorBlindFlags as ColorBlindFlags, __webpack_exports__ColorBlindnessMode as ColorBlindnessMode, __webpack_exports__ColorBlindnessPostProcessor as ColorBlindnessPostProcessor, __webpack_exports__Component as Component, __webpack_exports__CompositeCollider as CompositeCollider, __webpack_exports__Configurable as Configurable, __webpack_exports__ConsoleAppender as ConsoleAppender, __webpack_exports__ContactConstraintPoint as ContactConstraintPoint, __webpack_exports__ContactEndEvent as ContactEndEvent, __webpack_exports__ContactSolveBias as ContactSolveBias, __webpack_exports__ContactStartEvent as ContactStartEvent, __webpack_exports__CoordPlane as CoordPlane, __webpack_exports__CrossFade as CrossFade, __webpack_exports__DeactivateEvent as DeactivateEvent, __webpack_exports__Debug as Debug, __webpack_exports__DebugConfig as DebugConfig, __webpack_exports__DebugGraphicsComponent as DebugGraphicsComponent, __webpack_exports__DebugSystem as DebugSystem, __webpack_exports__DebugText as DebugText, __webpack_exports__DefaultAntialiasOptions as DefaultAntialiasOptions, __webpack_exports__DefaultLoader as DefaultLoader, __webpack_exports__DefaultPhysicsConfig as DefaultPhysicsConfig, __webpack_exports__DefaultPixelArtOptions as DefaultPixelArtOptions, __webpack_exports__DegreeOfFreedom as DegreeOfFreedom, __webpack_exports__Delay as Delay, __webpack_exports__DeprecatedStaticToConfig as DeprecatedStaticToConfig, __webpack_exports__Detector as Detector, __webpack_exports__Die as Die, __webpack_exports__Direction as Direction, __webpack_exports__Director as Director, __webpack_exports__DirectorEvents as DirectorEvents, __webpack_exports__DisplayMode as DisplayMode, __webpack_exports__DynamicTree as DynamicTree, __webpack_exports__DynamicTreeCollisionProcessor as DynamicTreeCollisionProcessor, __webpack_exports__EX_VERSION as EX_VERSION, __webpack_exports__EaseBy as EaseBy, __webpack_exports__EaseTo as EaseTo, __webpack_exports__EasingFunctions as EasingFunctions, __webpack_exports__EdgeCollider as EdgeCollider, __webpack_exports__ElasticToActorStrategy as ElasticToActorStrategy, __webpack_exports__EmitterType as EmitterType, __webpack_exports__Engine as Engine, __webpack_exports__EngineEvents as EngineEvents, __webpack_exports__EnterTriggerEvent as EnterTriggerEvent, __webpack_exports__EnterViewPortEvent as EnterViewPortEvent, __webpack_exports__Entity as Entity, __webpack_exports__EntityEvents as EntityEvents, __webpack_exports__EntityManager as EntityManager, __webpack_exports__EventDispatcher as EventDispatcher, __webpack_exports__EventEmitter as EventEmitter, __webpack_exports__EventTypes as EventTypes, __webpack_exports__Events as Events, __webpack_exports__ExResponse as ExResponse, __webpack_exports__ExcaliburGraphicsContext2DCanvas as ExcaliburGraphicsContext2DCanvas, __webpack_exports__ExcaliburGraphicsContextWebGL as ExcaliburGraphicsContextWebGL, __webpack_exports__ExitTriggerEvent as ExitTriggerEvent, __webpack_exports__ExitViewPortEvent as ExitViewPortEvent, __webpack_exports__Fade as Fade, __webpack_exports__FadeInOut as FadeInOut, __webpack_exports__Flags as Flags, __webpack_exports__Follow as Follow, __webpack_exports__Font as Font, __webpack_exports__FontCache as FontCache, __webpack_exports__FontSource as FontSource, __webpack_exports__FontStyle as FontStyle, __webpack_exports__FontUnit as FontUnit, __webpack_exports__FpsSampler as FpsSampler, __webpack_exports__FrameStats as FrameStats, __webpack_exports__Future as Future, __webpack_exports__GameEvent as GameEvent, __webpack_exports__GameStartEvent as GameStartEvent, __webpack_exports__GameStopEvent as GameStopEvent, __webpack_exports__Gamepad as Gamepad, __webpack_exports__GamepadAxisEvent as GamepadAxisEvent, __webpack_exports__GamepadButtonEvent as GamepadButtonEvent, __webpack_exports__GamepadConnectEvent as GamepadConnectEvent, __webpack_exports__GamepadDisconnectEvent as GamepadDisconnectEvent, __webpack_exports__Gamepads as Gamepads, __webpack_exports__Gif as Gif, __webpack_exports__GlobalCoordinates as GlobalCoordinates, __webpack_exports__Graphic as Graphic, __webpack_exports__GraphicsComponent as GraphicsComponent, __webpack_exports__GraphicsGroup as GraphicsGroup, __webpack_exports__GraphicsSystem as GraphicsSystem, __webpack_exports__HiddenEvent as HiddenEvent, __webpack_exports__HorizontalFirst as HorizontalFirst, __webpack_exports__ImageFiltering as ImageFiltering, __webpack_exports__ImageSource as ImageSource, __webpack_exports__InitializeEvent as InitializeEvent, __webpack_exports__Input as Input, __webpack_exports__InputHost as InputHost, __webpack_exports__InputMapper as InputMapper, __webpack_exports__Integrator as Integrator, __webpack_exports__IsometricEntityComponent as IsometricEntityComponent, __webpack_exports__IsometricEntitySystem as IsometricEntitySystem, __webpack_exports__IsometricMap as IsometricMap, __webpack_exports__IsometricTile as IsometricTile, __webpack_exports__KeyEvent as KeyEvent, __webpack_exports__Keyboard as Keyboard, __webpack_exports__Keys as Keys, __webpack_exports__KillEvent as KillEvent, __webpack_exports__Label as Label, __webpack_exports__LimitCameraBoundsStrategy as LimitCameraBoundsStrategy, __webpack_exports__Line as Line, __webpack_exports__LineSegment as LineSegment, __webpack_exports__Loader as Loader, __webpack_exports__LoaderEvents as LoaderEvents, __webpack_exports__LockCameraToActorAxisStrategy as LockCameraToActorAxisStrategy, __webpack_exports__LockCameraToActorStrategy as LockCameraToActorStrategy, __webpack_exports__LogLevel as LogLevel, __webpack_exports__Logger as Logger, __webpack_exports__Material as Material, __webpack_exports__Matrix as Matrix, __webpack_exports__MatrixLocations as MatrixLocations, __webpack_exports__MediaEvent as MediaEvent, __webpack_exports__Meet as Meet, __webpack_exports__MotionComponent as MotionComponent, __webpack_exports__MotionSystem as MotionSystem, __webpack_exports__MoveBy as MoveBy, __webpack_exports__MoveTo as MoveTo, __webpack_exports__NativePointerButton as NativePointerButton, __webpack_exports__NativeSoundEvent as NativeSoundEvent, __webpack_exports__NativeSoundProcessedEvent as NativeSoundProcessedEvent, __webpack_exports__None as None, __webpack_exports__Observable as Observable, __webpack_exports__OffscreenSystem as OffscreenSystem, __webpack_exports__Pair as Pair, __webpack_exports__ParallaxComponent as ParallaxComponent, __webpack_exports__ParallelActions as ParallelActions, __webpack_exports__ParseGif as ParseGif, __webpack_exports__Particle as Particle, __webpack_exports__ParticleEmitter as ParticleEmitter, __webpack_exports__ParticleTransform as ParticleTransform, __webpack_exports__Physics as Physics, __webpack_exports__PhysicsStats as PhysicsStats, __webpack_exports__PhysicsWorld as PhysicsWorld, __webpack_exports__PointerAbstraction as PointerAbstraction, __webpack_exports__PointerButton as PointerButton, __webpack_exports__PointerComponent as PointerComponent, __webpack_exports__PointerEvent as PointerEvent, __webpack_exports__PointerEventReceiver as PointerEventReceiver, __webpack_exports__PointerScope as PointerScope, __webpack_exports__PointerSystem as PointerSystem, __webpack_exports__PointerType as PointerType, __webpack_exports__Polygon as Polygon, __webpack_exports__PolygonCollider as PolygonCollider, __webpack_exports__Pool as Pool, __webpack_exports__PostCollisionEvent as PostCollisionEvent, __webpack_exports__PostDebugDrawEvent as PostDebugDrawEvent, __webpack_exports__PostDrawEvent as PostDrawEvent, __webpack_exports__PostFrameEvent as PostFrameEvent, __webpack_exports__PostKillEvent as PostKillEvent, __webpack_exports__PostTransformDrawEvent as PostTransformDrawEvent, __webpack_exports__PostUpdateEvent as PostUpdateEvent, __webpack_exports__PreCollisionEvent as PreCollisionEvent, __webpack_exports__PreDebugDrawEvent as PreDebugDrawEvent, __webpack_exports__PreDrawEvent as PreDrawEvent, __webpack_exports__PreFrameEvent as PreFrameEvent, __webpack_exports__PreKillEvent as PreKillEvent, __webpack_exports__PreLoadEvent as PreLoadEvent, __webpack_exports__PreTransformDrawEvent as PreTransformDrawEvent, __webpack_exports__PreUpdateEvent as PreUpdateEvent, __webpack_exports__Projection as Projection, __webpack_exports__QuadIndexBuffer as QuadIndexBuffer, __webpack_exports__QuadTree as QuadTree, __webpack_exports__Query as Query, __webpack_exports__QueryManager as QueryManager, __webpack_exports__RadiusAroundActorStrategy as RadiusAroundActorStrategy, __webpack_exports__Random as Random, __webpack_exports__Raster as Raster, __webpack_exports__Ray as Ray, __webpack_exports__RealisticSolver as RealisticSolver, __webpack_exports__Rectangle as Rectangle, __webpack_exports__RemovedComponent as RemovedComponent, __webpack_exports__Repeat as Repeat, __webpack_exports__RepeatForever as RepeatForever, __webpack_exports__Resolution as Resolution, __webpack_exports__Resource as Resource, __webpack_exports__ResourceEvents as ResourceEvents, __webpack_exports__RotateBy as RotateBy, __webpack_exports__RotateTo as RotateTo, __webpack_exports__RotationType as RotationType, __webpack_exports__ScaleBy as ScaleBy, __webpack_exports__ScaleTo as ScaleTo, __webpack_exports__Scene as Scene, __webpack_exports__SceneEvents as SceneEvents, __webpack_exports__Screen as Screen, __webpack_exports__ScreenAppender as ScreenAppender, __webpack_exports__ScreenElement as ScreenElement, __webpack_exports__ScreenEvents as ScreenEvents, __webpack_exports__ScreenShader as ScreenShader, __webpack_exports__ScrollPreventionMode as ScrollPreventionMode, __webpack_exports__Semaphore as Semaphore, __webpack_exports__Shader as Shader, __webpack_exports__Shape as Shape, __webpack_exports__Side as Side, __webpack_exports__SolverStrategy as SolverStrategy, __webpack_exports__Sound as Sound, __webpack_exports__SoundEvents as SoundEvents, __webpack_exports__Sprite as Sprite, __webpack_exports__SpriteFont as SpriteFont, __webpack_exports__SpriteSheet as SpriteSheet, __webpack_exports__StandardClock as StandardClock, __webpack_exports__StateMachine as StateMachine, __webpack_exports__StrategyContainer as StrategyContainer, __webpack_exports__Stream as Stream, __webpack_exports__System as System, __webpack_exports__SystemManager as SystemManager, __webpack_exports__SystemPriority as SystemPriority, __webpack_exports__SystemType as SystemType, __webpack_exports__TagQuery as TagQuery, __webpack_exports__TestClock as TestClock, __webpack_exports__Text as Text, __webpack_exports__TextAlign as TextAlign, __webpack_exports__TextureLoader as TextureLoader, __webpack_exports__Tile as Tile, __webpack_exports__TileMap as TileMap, __webpack_exports__TileMapEvents as TileMapEvents, __webpack_exports__Timer as Timer, __webpack_exports__Toaster as Toaster, __webpack_exports__Transform as Transform, __webpack_exports__TransformComponent as TransformComponent, __webpack_exports__Transition as Transition, __webpack_exports__TreeNode as TreeNode, __webpack_exports__Trigger as Trigger, __webpack_exports__TriggerEvents as TriggerEvents, __webpack_exports__TwoPI as TwoPI, __webpack_exports__Util as Util, __webpack_exports__Vector as Vector, __webpack_exports__VectorView as VectorView, __webpack_exports__VertexBuffer as VertexBuffer, __webpack_exports__VertexLayout as VertexLayout, __webpack_exports__VerticalFirst as VerticalFirst, __webpack_exports__VisibleEvent as VisibleEvent, __webpack_exports__WebAudio as WebAudio, __webpack_exports__WebAudioInstance as WebAudioInstance, __webpack_exports__WheelDeltaMode as WheelDeltaMode, __webpack_exports__WheelEvent as WheelEvent, __webpack_exports__World as World, __webpack_exports__canonicalizeAngle as canonicalizeAngle, __webpack_exports__clamp as clamp, __webpack_exports__coroutine as coroutine, __webpack_exports__createId as createId, __webpack_exports__frac as frac, __webpack_exports__hasGraphicsTick as hasGraphicsTick, __webpack_exports__hasOnInitialize as hasOnInitialize, __webpack_exports__hasOnPostUpdate as hasOnPostUpdate, __webpack_exports__hasOnPreUpdate as hasOnPreUpdate, __webpack_exports__hasPostDraw as hasPostDraw, __webpack_exports__hasPreDraw as hasPreDraw, __webpack_exports__has_initialize as has_initialize, __webpack_exports__has_postupdate as has_postupdate, __webpack_exports__has_preupdate as has_preupdate, __webpack_exports__isAddedComponent as isAddedComponent, __webpack_exports__isComponentCtor as isComponentCtor, __webpack_exports__isLoaderConstructor as isLoaderConstructor, __webpack_exports__isRemovedComponent as isRemovedComponent, __webpack_exports__isSceneConstructor as isSceneConstructor, __webpack_exports__isScreenElement as isScreenElement, __webpack_exports__isSystemConstructor as isSystemConstructor, __webpack_exports__maxMessages as maxMessages, __webpack_exports__obsolete as obsolete, __webpack_exports__pixelSnapEpsilon as pixelSnapEpsilon, __webpack_exports__randomInRange as randomInRange, __webpack_exports__randomIntInRange as randomIntInRange, __webpack_exports__range as range, __webpack_exports__resetObsoleteCounter as resetObsoleteCounter, __webpack_exports__sign as sign, __webpack_exports__toDegrees as toDegrees, __webpack_exports__toRadians as toRadians, __webpack_exports__vec as vec, __webpack_exports__webgl as webgl };\n\n//# sourceMappingURL=excalibur.js.map","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./Director/Loader.css\"],\"names\":[],\"mappings\":\"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\"sourcesContent\":[\"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./Util/Toaster.css\"],\"names\":[],\"mappings\":\";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\"sourcesContent\":[\"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};","\"use strict\";\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};","'use strict';\nrequire('../../modules/es.array.sort');\nvar entryUnbind = require('../../internals/entry-unbind');\n\nmodule.exports = entryUnbind('Array', 'sort');\n","'use strict';\nrequire('../../modules/es.object.keys');\nvar path = require('../../internals/path');\n\nmodule.exports = path.Object.keys;\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar tryToString = require('../internals/try-to-string');\n\nvar $TypeError = TypeError;\n\n// `Assert: IsCallable(argument) is true`\nmodule.exports = function (argument) {\n if (isCallable(argument)) return argument;\n throw new $TypeError(tryToString(argument) + ' is not a function');\n};\n","'use strict';\nvar isObject = require('../internals/is-object');\n\nvar $String = String;\nvar $TypeError = TypeError;\n\n// `Assert: Type(argument) is Object`\nmodule.exports = function (argument) {\n if (isObject(argument)) return argument;\n throw new $TypeError($String(argument) + ' is not an object');\n};\n","'use strict';\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\nvar createMethod = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el !== el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value !== value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) {\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = function (METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function () { return 1; }, 1);\n });\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = uncurryThis([].slice);\n","'use strict';\nvar arraySlice = require('../internals/array-slice');\n\nvar floor = Math.floor;\n\nvar sort = function (array, comparefn) {\n var length = array.length;\n\n if (length < 8) {\n // insertion sort\n var i = 1;\n var element, j;\n\n while (i < length) {\n j = i;\n element = array[i];\n while (j && comparefn(array[j - 1], element) > 0) {\n array[j] = array[--j];\n }\n if (j !== i++) array[j] = element;\n }\n } else {\n // merge sort\n var middle = floor(length / 2);\n var left = sort(arraySlice(array, 0, middle), comparefn);\n var right = sort(arraySlice(array, middle), comparefn);\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n\n while (lindex < llength || rindex < rlength) {\n array[lindex + rindex] = (lindex < llength && rindex < rlength)\n ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]\n : lindex < llength ? left[lindex++] : right[rindex++];\n }\n }\n\n return array;\n};\n\nmodule.exports = sort;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nvar toString = uncurryThis({}.toString);\nvar stringSlice = uncurryThis(''.slice);\n\nmodule.exports = function (it) {\n return stringSlice(toString(it), 8, -1);\n};\n","'use strict';\nvar TO_STRING_TAG_SUPPORT = require('../internals/to-string-tag-support');\nvar isCallable = require('../internals/is-callable');\nvar classofRaw = require('../internals/classof-raw');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar $Object = Object;\n\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result;\n};\n","'use strict';\nvar hasOwn = require('../internals/has-own-property');\nvar ownKeys = require('../internals/own-keys');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar definePropertyModule = require('../internals/object-define-property');\n\nmodule.exports = function (target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {\n defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n }\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar definePropertyModule = require('../internals/object-define-property');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","'use strict';\nmodule.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar definePropertyModule = require('../internals/object-define-property');\nvar makeBuiltIn = require('../internals/make-built-in');\nvar defineGlobalProperty = require('../internals/define-global-property');\n\nmodule.exports = function (O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) { /* empty */ }\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n } return O;\n};\n","'use strict';\nvar global = require('../internals/global');\n\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\n\nmodule.exports = function (key, value) {\n try {\n defineProperty(global, key, { value: value, configurable: true, writable: true });\n } catch (error) {\n global[key] = value;\n } return value;\n};\n","'use strict';\nvar tryToString = require('../internals/try-to-string');\n\nvar $TypeError = TypeError;\n\nmodule.exports = function (O, P) {\n if (!delete O[P]) throw new $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\n// Detect IE8's incomplete defineProperty implementation\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7;\n});\n","'use strict';\nvar global = require('../internals/global');\nvar isObject = require('../internals/is-object');\n\nvar document = global.document;\n// typeof document.createElement is 'object' in old IE\nvar EXISTS = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return EXISTS ? document.createElement(it) : {};\n};\n","'use strict';\nvar userAgent = require('../internals/engine-user-agent');\n\nvar firefox = userAgent.match(/firefox\\/(\\d+)/i);\n\nmodule.exports = !!firefox && +firefox[1];\n","'use strict';\nvar UA = require('../internals/engine-user-agent');\n\nmodule.exports = /MSIE|Trident/.test(UA);\n","'use strict';\nmodule.exports = typeof navigator != 'undefined' && String(navigator.userAgent) || '';\n","'use strict';\nvar global = require('../internals/global');\nvar userAgent = require('../internals/engine-user-agent');\n\nvar process = global.process;\nvar Deno = global.Deno;\nvar versions = process && process.versions || Deno && Deno.version;\nvar v8 = versions && versions.v8;\nvar match, version;\n\nif (v8) {\n match = v8.split('.');\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n}\n\n// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n// so check `userAgent` even if `.v8` exists, but 0\nif (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n}\n\nmodule.exports = version;\n","'use strict';\nvar userAgent = require('../internals/engine-user-agent');\n\nvar webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n\nmodule.exports = !!webkit && +webkit[1];\n","'use strict';\nvar global = require('../internals/global');\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = function (CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n};\n","'use strict';\n// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n","'use strict';\nvar global = require('../internals/global');\nvar getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar defineBuiltIn = require('../internals/define-built-in');\nvar defineGlobalProperty = require('../internals/define-global-property');\nvar copyConstructorProperties = require('../internals/copy-constructor-properties');\nvar isForced = require('../internals/is-forced');\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = global;\n } else if (STATIC) {\n target = global[TARGET] || defineGlobalProperty(TARGET, {});\n } else {\n target = global[TARGET] && global[TARGET].prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n createNonEnumerableProperty(sourceProperty, 'sham', true);\n }\n defineBuiltIn(target, key, sourceProperty, options);\n }\n};\n","'use strict';\nmodule.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function () { /* empty */ }).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != 'function' || test.hasOwnProperty('prototype');\n});\n","'use strict';\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar call = Function.prototype.call;\n\nmodule.exports = NATIVE_BIND ? call.bind(call) : function () {\n return call.apply(call, arguments);\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar hasOwn = require('../internals/has-own-property');\n\nvar FunctionPrototype = Function.prototype;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n\nvar EXISTS = hasOwn(FunctionPrototype, 'name');\n// additional protection from minified / mangled / dropped function names\nvar PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';\nvar CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable));\n\nmodule.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n};\n","'use strict';\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar FunctionPrototype = Function.prototype;\nvar call = FunctionPrototype.call;\nvar uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n\nmodule.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {\n return function () {\n return call.apply(fn, arguments);\n };\n};\n","'use strict';\nvar global = require('../internals/global');\nvar isCallable = require('../internals/is-callable');\n\nvar aFunction = function (argument) {\n return isCallable(argument) ? argument : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n};\n","'use strict';\nvar aCallable = require('../internals/a-callable');\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\n\n// `GetMethod` abstract operation\n// https://tc39.es/ecma262/#sec-getmethod\nmodule.exports = function (V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n};\n","'use strict';\nvar check = function (it) {\n return it && it.Math === Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == 'object' && globalThis) ||\n check(typeof window == 'object' && window) ||\n // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == 'object' && self) ||\n check(typeof global == 'object' && global) ||\n check(typeof this == 'object' && this) ||\n // eslint-disable-next-line no-new-func -- fallback\n (function () { return this; })() || Function('return this')();\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar toObject = require('../internals/to-object');\n\nvar hasOwnProperty = uncurryThis({}.hasOwnProperty);\n\n// `HasOwnProperty` abstract operation\n// https://tc39.es/ecma262/#sec-hasownproperty\n// eslint-disable-next-line es/no-object-hasown -- safe\nmodule.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n};\n","'use strict';\nmodule.exports = {};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\nvar createElement = require('../internals/document-create-element');\n\n// Thanks to IE8 for its funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a !== 7;\n});\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar fails = require('../internals/fails');\nvar classof = require('../internals/classof-raw');\n\nvar $Object = Object;\nvar split = uncurryThis(''.split);\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) === 'String' ? split(it, '') : $Object(it);\n} : $Object;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar isCallable = require('../internals/is-callable');\nvar store = require('../internals/shared-store');\n\nvar functionToString = uncurryThis(Function.toString);\n\n// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\nif (!isCallable(store.inspectSource)) {\n store.inspectSource = function (it) {\n return functionToString(it);\n };\n}\n\nmodule.exports = store.inspectSource;\n","'use strict';\nvar NATIVE_WEAK_MAP = require('../internals/weak-map-basic-detection');\nvar global = require('../internals/global');\nvar isObject = require('../internals/is-object');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar hasOwn = require('../internals/has-own-property');\nvar shared = require('../internals/shared-store');\nvar sharedKey = require('../internals/shared-key');\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar OBJECT_ALREADY_INITIALIZED = 'Object already initialized';\nvar TypeError = global.TypeError;\nvar WeakMap = global.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw new TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap());\n /* eslint-disable no-self-assign -- prototype methods protection */\n store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */\n set = function (it, metadata) {\n if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function (it) {\n return store.get(it) || {};\n };\n has = function (it) {\n return store.has(it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return hasOwn(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n","'use strict';\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\nvar documentAll = typeof document == 'object' && document.all;\n\n// `IsCallable` abstract operation\n// https://tc39.es/ecma262/#sec-iscallable\n// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\nmodule.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) {\n return typeof argument == 'function' || argument === documentAll;\n} : function (argument) {\n return typeof argument == 'function';\n};\n","'use strict';\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value === POLYFILL ? true\n : value === NATIVE ? false\n : isCallable(detection) ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n","'use strict';\n// we can't use just `it == null` since of `document.all` special case\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\nmodule.exports = function (it) {\n return it === null || it === undefined;\n};\n","'use strict';\nvar isCallable = require('../internals/is-callable');\n\nmodule.exports = function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it);\n};\n","'use strict';\nmodule.exports = false;\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar isCallable = require('../internals/is-callable');\nvar isPrototypeOf = require('../internals/object-is-prototype-of');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar $Object = Object;\n\nmodule.exports = USE_SYMBOL_AS_UID ? function (it) {\n return typeof it == 'symbol';\n} : function (it) {\n var $Symbol = getBuiltIn('Symbol');\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n};\n","'use strict';\nvar toLength = require('../internals/to-length');\n\n// `LengthOfArrayLike` abstract operation\n// https://tc39.es/ecma262/#sec-lengthofarraylike\nmodule.exports = function (obj) {\n return toLength(obj.length);\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\nvar hasOwn = require('../internals/has-own-property');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar CONFIGURABLE_FUNCTION_NAME = require('../internals/function-name').CONFIGURABLE;\nvar inspectSource = require('../internals/inspect-source');\nvar InternalStateModule = require('../internals/internal-state');\n\nvar enforceInternalState = InternalStateModule.enforce;\nvar getInternalState = InternalStateModule.get;\nvar $String = String;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\nvar stringSlice = uncurryThis(''.slice);\nvar replace = uncurryThis(''.replace);\nvar join = uncurryThis([].join);\n\nvar CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () {\n return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;\n});\n\nvar TEMPLATE = String(String).split('String');\n\nvar makeBuiltIn = module.exports = function (value, name, options) {\n if (stringSlice($String(name), 0, 7) === 'Symbol(') {\n name = '[' + replace($String(name), /^Symbol\\(([^)]*)\\).*$/, '$1') + ']';\n }\n if (options && options.getter) name = 'get ' + name;\n if (options && options.setter) name = 'set ' + name;\n if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {\n if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) {\n defineProperty(value, 'length', { value: options.arity });\n }\n try {\n if (options && hasOwn(options, 'constructor') && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false });\n // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) { /* empty */ }\n var state = enforceInternalState(value);\n if (!hasOwn(state, 'source')) {\n state.source = join(TEMPLATE, typeof name == 'string' ? name : '');\n } return value;\n};\n\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n// eslint-disable-next-line no-extend-native -- required\nFunction.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n}, 'toString');\n","'use strict';\nvar ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `Math.trunc` method\n// https://tc39.es/ecma262/#sec-math.trunc\n// eslint-disable-next-line es/no-math-trunc -- safe\nmodule.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\nvar V8_PROTOTYPE_DEFINE_BUG = require('../internals/v8-prototype-define-bug');\nvar anObject = require('../internals/an-object');\nvar toPropertyKey = require('../internals/to-property-key');\n\nvar $TypeError = TypeError;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar $defineProperty = Object.defineProperty;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar ENUMERABLE = 'enumerable';\nvar CONFIGURABLE = 'configurable';\nvar WRITABLE = 'writable';\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\nexports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n } return $defineProperty(O, P, Attributes);\n} : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar call = require('../internals/function-call');\nvar propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toPropertyKey = require('../internals/to-property-key');\nvar hasOwn = require('../internals/has-own-property');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\n\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\nexports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n};\n","'use strict';\nvar internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.es/ecma262/#sec-object.getownpropertynames\n// eslint-disable-next-line es/no-object-getownpropertynames -- safe\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n","'use strict';\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\nexports.f = Object.getOwnPropertySymbols;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = uncurryThis({}.isPrototypeOf);\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar hasOwn = require('../internals/has-own-property');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar indexOf = require('../internals/array-includes').indexOf;\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar push = uncurryThis([].push);\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (hasOwn(O, key = names[i++])) {\n ~indexOf(result, key) || push(result, key);\n }\n return result;\n};\n","'use strict';\nvar internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n// eslint-disable-next-line es/no-object-keys -- safe\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n","'use strict';\nvar $propertyIsEnumerable = {}.propertyIsEnumerable;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);\n\n// `Object.prototype.propertyIsEnumerable` method implementation\n// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : $propertyIsEnumerable;\n","'use strict';\nvar call = require('../internals/function-call');\nvar isCallable = require('../internals/is-callable');\nvar isObject = require('../internals/is-object');\n\nvar $TypeError = TypeError;\n\n// `OrdinaryToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-ordinarytoprimitive\nmodule.exports = function (input, pref) {\n var fn, val;\n if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw new $TypeError(\"Can't convert object to primitive value\");\n};\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar anObject = require('../internals/an-object');\n\nvar concat = uncurryThis([].concat);\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n};\n","'use strict';\nvar global = require('../internals/global');\n\nmodule.exports = global;\n","'use strict';\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\n\nvar $TypeError = TypeError;\n\n// `RequireObjectCoercible` abstract operation\n// https://tc39.es/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (isNullOrUndefined(it)) throw new $TypeError(\"Can't call method on \" + it);\n return it;\n};\n","'use strict';\nvar shared = require('../internals/shared');\nvar uid = require('../internals/uid');\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n","'use strict';\nvar global = require('../internals/global');\nvar defineGlobalProperty = require('../internals/define-global-property');\n\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || defineGlobalProperty(SHARED, {});\n\nmodule.exports = store;\n","'use strict';\nvar IS_PURE = require('../internals/is-pure');\nvar store = require('../internals/shared-store');\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: '3.35.1',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)',\n license: 'https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE',\n source: 'https://github.com/zloirock/core-js'\n});\n","'use strict';\n/* eslint-disable es/no-symbol -- required for testing */\nvar V8_VERSION = require('../internals/engine-v8-version');\nvar fails = require('../internals/fails');\nvar global = require('../internals/global');\n\nvar $String = global.String;\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n var symbol = Symbol('symbol detection');\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) ||\n // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n});\n","'use strict';\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\nmodule.exports = function (index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n","'use strict';\n// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = require('../internals/indexed-object');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n","'use strict';\nvar trunc = require('../internals/math-trunc');\n\n// `ToIntegerOrInfinity` abstract operation\n// https://tc39.es/ecma262/#sec-tointegerorinfinity\nmodule.exports = function (argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n};\n","'use strict';\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.es/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n var len = toIntegerOrInfinity(argument);\n return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n","'use strict';\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nvar $Object = Object;\n\n// `ToObject` abstract operation\n// https://tc39.es/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return $Object(requireObjectCoercible(argument));\n};\n","'use strict';\nvar call = require('../internals/function-call');\nvar isObject = require('../internals/is-object');\nvar isSymbol = require('../internals/is-symbol');\nvar getMethod = require('../internals/get-method');\nvar ordinaryToPrimitive = require('../internals/ordinary-to-primitive');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar $TypeError = TypeError;\nvar TO_PRIMITIVE = wellKnownSymbol('toPrimitive');\n\n// `ToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-toprimitive\nmodule.exports = function (input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = 'default';\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw new $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = 'number';\n return ordinaryToPrimitive(input, pref);\n};\n","'use strict';\nvar toPrimitive = require('../internals/to-primitive');\nvar isSymbol = require('../internals/is-symbol');\n\n// `ToPropertyKey` abstract operation\n// https://tc39.es/ecma262/#sec-topropertykey\nmodule.exports = function (argument) {\n var key = toPrimitive(argument, 'string');\n return isSymbol(key) ? key : key + '';\n};\n","'use strict';\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n\ntest[TO_STRING_TAG] = 'z';\n\nmodule.exports = String(test) === '[object z]';\n","'use strict';\nvar classof = require('../internals/classof');\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n return $String(argument);\n};\n","'use strict';\nvar $String = String;\n\nmodule.exports = function (argument) {\n try {\n return $String(argument);\n } catch (error) {\n return 'Object';\n }\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nvar id = 0;\nvar postfix = Math.random();\nvar toString = uncurryThis(1.0.toString);\n\nmodule.exports = function (key) {\n return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);\n};\n","'use strict';\n/* eslint-disable es/no-symbol -- required for testing */\nvar NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');\n\nmodule.exports = NATIVE_SYMBOL\n && !Symbol.sham\n && typeof Symbol.iterator == 'symbol';\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\n\n// V8 ~ Chrome 36-\n// https://bugs.chromium.org/p/v8/issues/detail?id=3334\nmodule.exports = DESCRIPTORS && fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function () { /* empty */ }, 'prototype', {\n value: 42,\n writable: false\n }).prototype !== 42;\n});\n","'use strict';\nvar global = require('../internals/global');\nvar isCallable = require('../internals/is-callable');\n\nvar WeakMap = global.WeakMap;\n\nmodule.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));\n","'use strict';\nvar global = require('../internals/global');\nvar shared = require('../internals/shared');\nvar hasOwn = require('../internals/has-own-property');\nvar uid = require('../internals/uid');\nvar NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar Symbol = global.Symbol;\nvar WellKnownSymbolsStore = shared('wks');\nvar createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;\n\nmodule.exports = function (name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) {\n WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name)\n ? Symbol[name]\n : createWellKnownSymbol('Symbol.' + name);\n } return WellKnownSymbolsStore[name];\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar aCallable = require('../internals/a-callable');\nvar toObject = require('../internals/to-object');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar deletePropertyOrThrow = require('../internals/delete-property-or-throw');\nvar toString = require('../internals/to-string');\nvar fails = require('../internals/fails');\nvar internalSort = require('../internals/array-sort');\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\nvar FF = require('../internals/engine-ff-version');\nvar IE_OR_EDGE = require('../internals/engine-is-ie-or-edge');\nvar V8 = require('../internals/engine-v8-version');\nvar WEBKIT = require('../internals/engine-webkit-version');\n\nvar test = [];\nvar nativeSort = uncurryThis(test.sort);\nvar push = uncurryThis(test.push);\n\n// IE8-\nvar FAILS_ON_UNDEFINED = fails(function () {\n test.sort(undefined);\n});\n// V8 bug\nvar FAILS_ON_NULL = fails(function () {\n test.sort(null);\n});\n// Old WebKit\nvar STRICT_METHOD = arrayMethodIsStrict('sort');\n\nvar STABLE_SORT = !fails(function () {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n\n var result = '';\n var code, chr, value, index;\n\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for (code = 65; code < 76; code++) {\n chr = String.fromCharCode(code);\n\n switch (code) {\n case 66: case 69: case 70: case 72: value = 3; break;\n case 68: case 71: value = 4; break;\n default: value = 2;\n }\n\n for (index = 0; index < 47; index++) {\n test.push({ k: chr + index, v: value });\n }\n }\n\n test.sort(function (a, b) { return b.v - a.v; });\n\n for (index = 0; index < test.length; index++) {\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n\n return result !== 'DGBEFHACIJK';\n});\n\nvar FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n\nvar getSortCompare = function (comparefn) {\n return function (x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n};\n\n// `Array.prototype.sort` method\n// https://tc39.es/ecma262/#sec-array.prototype.sort\n$({ target: 'Array', proto: true, forced: FORCED }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n\n var array = toObject(this);\n\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n\n for (index = 0; index < arrayLength; index++) {\n if (index in array) push(items, array[index]);\n }\n\n internalSort(items, getSortCompare(comparefn));\n\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n\n while (index < itemsLength) array[index] = items[index++];\n while (index < arrayLength) deletePropertyOrThrow(array, index++);\n\n return array;\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar toObject = require('../internals/to-object');\nvar nativeKeys = require('../internals/object-keys');\nvar fails = require('../internals/fails');\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeKeys(1); });\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n});\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import 'core-js/es/array/sort';\r\nimport 'core-js/es/object/keys';\r\n\r\n/**\r\n * Polyfill adding function\r\n */\r\nexport function polyfill() {\r\n /* istanbul ignore next */\r\n if (typeof window === 'undefined') {\r\n window = {\r\n audioContext: function () {\r\n return;\r\n }\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.requestAnimationFrame) {\r\n (window).requestAnimationFrame =\r\n (window).webkitRequestAnimationFrame ||\r\n (window).mozRequestAnimationFrame ||\r\n function (callback: Function) {\r\n window.setInterval(callback, 1000 / 60);\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.cancelAnimationFrame) {\r\n (window).cancelAnimationFrame =\r\n (window).webkitCancelAnimationFrame ||\r\n (window).mozCancelAnimationFrame ||\r\n function () {\r\n return;\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !(window).AudioContext) {\r\n if ((window).webkitAudioContext) {\r\n const ctx = (window).webkitAudioContext;\r\n const replaceMe = ctx.prototype.decodeAudioData;\r\n (window).webkitAudioContext.prototype.decodeAudioData = function (arrayBuffer: ArrayBuffer) {\r\n return new Promise((resolve, reject) => {\r\n replaceMe.call(this, arrayBuffer, resolve, reject);\r\n });\r\n };\r\n }\r\n\r\n (window).AudioContext =\r\n (window).AudioContext ||\r\n (window).webkitAudioContext ||\r\n (window).mozAudioContext ||\r\n (window).msAudioContext ||\r\n (window).oAudioContext;\r\n }\r\n\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !(window).devicePixelRatio) {\r\n (window).devicePixelRatio = window.devicePixelRatio || 1;\r\n }\r\n}\r\n","\r\n/**\r\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\r\n * after which they are frozen and are read-only.\r\n *\r\n * Flags are used to enable experimental or preview features in Excalibur.\r\n */\r\nexport class Flags {\r\n private static _FROZEN = false;\r\n private static _FLAGS: Record = {};\r\n\r\n\r\n /**\r\n * Force excalibur to load the Canvas 2D graphics context fallback\r\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\r\n */\r\n public static useCanvasGraphicsContext() {\r\n Flags.enable('use-canvas-context');\r\n }\r\n\r\n /**\r\n * Freeze all flag modifications making them readonly\r\n */\r\n public static freeze() {\r\n Flags._FROZEN = true;\r\n }\r\n\r\n /**\r\n * Resets internal flag state, not meant to be called by users. Only used for testing.\r\n *\r\n * Calling this in your game is UNSUPPORTED\r\n * @internal\r\n */\r\n public static _reset() {\r\n Flags._FROZEN = false;\r\n Flags._FLAGS = {};\r\n }\r\n /**\r\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */\r\n public static enable(flagName: string): void {\r\n if (this._FROZEN) {\r\n throw Error('Feature flags can only be enabled before Engine constructor time');\r\n }\r\n Flags._FLAGS[flagName] = true;\r\n }\r\n\r\n /**\r\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */\r\n public static disable(flagName: string): void {\r\n if (this._FROZEN) {\r\n throw Error('Feature flags can only be disabled before Engine constructor time');\r\n }\r\n Flags._FLAGS[flagName] = false;\r\n }\r\n\r\n /**\r\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\r\n * @param flagName\r\n */\r\n public static isEnabled(flagName: string): boolean {\r\n return !!Flags._FLAGS[flagName];\r\n }\r\n\r\n /**\r\n * Show a list of currently known flags\r\n */\r\n public static show(): string[] {\r\n return Object.keys(Flags._FLAGS);\r\n }\r\n}\r\n","export type Id = {\r\n type: T,\r\n value: number\r\n};\r\n\r\n/**\r\n * Create a branded ID type from a number\r\n */\r\nexport function createId(type: T, value: number): Id {\r\n return { type, value };\r\n};\r\n","\r\n/**\r\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\r\n */\r\nexport class Future {\r\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\r\n private _resolver: (value: T) => void;\r\n private _rejecter: (error: Error) => void;\r\n private _isCompleted: boolean = false;\r\n\r\n constructor() {\r\n this.promise = new Promise((resolve, reject) => {\r\n this._resolver = resolve;\r\n this._rejecter = reject;\r\n });\r\n }\r\n\r\n public readonly promise: Promise;\r\n\r\n public get isCompleted(): boolean {\r\n return this._isCompleted;\r\n }\r\n\r\n public resolve(value: T): void {\r\n if (this._isCompleted) {\r\n return;\r\n }\r\n this._isCompleted = true;\r\n this._resolver(value);\r\n }\r\n\r\n public reject(error: Error): void {\r\n if (this._isCompleted) {\r\n return;\r\n }\r\n this._isCompleted = true;\r\n this._rejecter(error);\r\n }\r\n}","export type EventMap = Record;\r\nexport type EventKey = string & keyof T;\r\nexport type Handler = (event: EventType) => void;\r\n\r\n/**\r\n * Interface that represents a handle to a subscription that can be closed\r\n */\r\nexport interface Subscription {\r\n close(): void;\r\n}\r\n\r\n/**\r\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\r\n */\r\nexport class EventEmitter {\r\n private _paused = false;\r\n private _listeners: Record[]> = {};\r\n private _listenersOnce: Record[]> = {};\r\n private _pipes: EventEmitter[] = [];\r\n\r\n clear() {\r\n this._listeners = {};\r\n this._listenersOnce = {};\r\n this._pipes.length = 0;\r\n }\r\n\r\n on>(eventName: TEventName, handler: Handler): Subscription;\r\n on(eventName: string, handler: Handler): Subscription;\r\n on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._listeners[eventName] = this._listeners[eventName] ?? [];\r\n this._listeners[eventName].push(handler);\r\n return {\r\n close: () => this.off(eventName, handler)\r\n };\r\n }\r\n\r\n once>(eventName: TEventName, handler: Handler): Subscription;\r\n once(eventName: string, handler: Handler): Subscription;\r\n once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._listenersOnce[eventName] = this._listenersOnce[eventName] ?? [];\r\n this._listenersOnce[eventName].push(handler);\r\n return {\r\n close: () => this.off(eventName, handler)\r\n };\r\n }\r\n\r\n off>(eventName: TEventName, handler: Handler): void;\r\n off(eventName: string, handler: Handler): void;\r\n off(eventName: string): void;\r\n off | string>(eventName: TEventName, handler?: Handler): void {\r\n if (handler) {\r\n const newListeners = this._listeners[eventName]?.filter(h => h !== handler);\r\n this._listeners[eventName] = newListeners;\r\n\r\n const newOnceListeners = this._listenersOnce[eventName]?.filter(h => h !== handler);\r\n this._listenersOnce[eventName] = newOnceListeners;\r\n } else {\r\n delete this._listeners[eventName];\r\n }\r\n }\r\n\r\n emit>(eventName: TEventName, event: TEventMap[TEventName]): void;\r\n emit(eventName: string, event?: any): void;\r\n emit | string>(eventName: TEventName, event?: TEventMap[TEventName]): void {\r\n if (this._paused) {\r\n return;\r\n }\r\n this._listeners[eventName]?.forEach((fn) => fn(event));\r\n const onces = this._listenersOnce[eventName];\r\n this._listenersOnce[eventName] = [];\r\n if (onces) {\r\n onces.forEach((fn) => fn(event));\r\n }\r\n this._pipes.forEach((pipe) => {\r\n pipe.emit(eventName, event);\r\n });\r\n }\r\n\r\n pipe(emitter: EventEmitter): Subscription {\r\n if (this === emitter) {\r\n throw Error('Cannot pipe to self');\r\n }\r\n this._pipes.push(emitter);\r\n return {\r\n close: () => {\r\n const i = this._pipes.indexOf(emitter);\r\n if (i > -1) {\r\n this._pipes.splice(i, 1);\r\n }\r\n }\r\n };\r\n }\r\n\r\n unpipe(emitter: EventEmitter): void {\r\n const i = this._pipes.indexOf(emitter);\r\n if (i > -1) {\r\n this._pipes.splice(i, 1);\r\n }\r\n }\r\n\r\n pause(): void {\r\n this._paused = true;\r\n }\r\n\r\n unpause(): void {\r\n this._paused = false;\r\n }\r\n}","/**\r\n * Determines the scope of handling mouse/touch events.\r\n */\r\n\r\nexport enum PointerScope {\r\n /**\r\n * Handle events on the `canvas` element only. Events originating outside the\r\n * `canvas` will not be handled.\r\n */\r\n Canvas = 'Canvas',\r\n\r\n /**\r\n * Handles events on the entire document. All events will be handled by Excalibur.\r\n */\r\n Document = 'Document'\r\n}\r\n","/**\r\n * @module\r\n * Pseudo-Random Utility\r\n *\r\n * A pseudo-random utility to add seeded random support for help in\r\n * generating things like terrain or reproducible randomness. Uses the\r\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\r\n */\r\n\r\n/**\r\n * 32-bit mask\r\n */\r\nconst BITMASK32: number = 0xffffffff;\r\n\r\n/**\r\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\r\n * of numbers each time it is called.\r\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\r\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\r\n *\r\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\r\n */\r\nexport class Random {\r\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\r\n private _lowerMask: number = 0x7fffffff; // 31 bits same as _r\r\n private _upperMask: number = 0x80000000; // 34 high bits\r\n\r\n // Word size, 64 bits\r\n private _w: number = 32;\r\n\r\n // Degree of recurrence\r\n private _n: number = 624;\r\n\r\n // Middle word, an offset used in the recurrence defining the series x, 1<=m(this._n);\r\n // need to mask to support higher bit machines\r\n this._mt[0] = (seed || Date.now()) >>> 0;\r\n\r\n for (let i = 1; i < this._n; i++) {\r\n const s = this._mt[i - 1] ^ (this._mt[i - 1] >>> (this._w - 2));\r\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\r\n this._mt[i] = (((this._f * ((s & 0xffff0000) >>> 16)) << 16) + this._f * (s & 0xffff) + i) >>> 0;\r\n }\r\n this._index = this._n;\r\n }\r\n\r\n /**\r\n * Apply the twist\r\n */\r\n private _twist(): void {\r\n const mag01 = [0x0, this._a];\r\n let y = 0,\r\n i = 0;\r\n for (; i < this._n - this._m; i++) {\r\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\r\n this._mt[i] = this._mt[i + this._m] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n }\r\n for (; i < this._n - 1; i++) {\r\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\r\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n }\r\n y = (this._mt[this._n - 1] & this._upperMask) | (this._mt[0] & this._lowerMask);\r\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n\r\n this._index = 0;\r\n }\r\n\r\n /**\r\n * Return next 32 bit integer number in sequence\r\n */\r\n public nextInt(): number {\r\n if (this._index >= this._n) {\r\n this._twist();\r\n }\r\n\r\n let y = this._mt[this._index++];\r\n\r\n y ^= y >>> this._u;\r\n y ^= (y << this._s) & this._b;\r\n y ^= (y << this._t) & this._c;\r\n y ^= y >>> this._l;\r\n\r\n return y >>> 0;\r\n }\r\n\r\n /**\r\n * Return a random floating point number between [0, 1)\r\n */\r\n public next(): number {\r\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\r\n }\r\n\r\n /**\r\n * Return a random floating point in range [min, max) min is included, max is not included\r\n */\r\n public floating(min: number, max: number): number {\r\n return (max - min) * this.next() + min;\r\n }\r\n\r\n /**\r\n * Return a random integer in range [min, max] min is included, max is included.\r\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\r\n */\r\n public integer(min: number, max: number): number {\r\n return Math.floor((max - min + 1) * this.next() + min);\r\n }\r\n\r\n /**\r\n * Returns true or false randomly with 50/50 odds by default.\r\n * By default the likelihood of returning a true is .5 (50%).\r\n * @param likelihood takes values between [0, 1]\r\n */\r\n public bool(likelihood: number = 0.5): boolean {\r\n return this.next() <= likelihood;\r\n }\r\n\r\n /**\r\n * Returns one element from an array at random\r\n */\r\n public pickOne(array: Array): T {\r\n return array[this.integer(0, array.length - 1)];\r\n }\r\n\r\n /**\r\n * Returns a new array random picking elements from the original\r\n * @param array Original array to pick from\r\n * @param numPicks can be any positive number\r\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\r\n * just that it is possible)\r\n */\r\n public pickSet(array: Array, numPicks: number, allowDuplicates: boolean = false): Array {\r\n if (allowDuplicates) {\r\n return this._pickSetWithDuplicates(array, numPicks);\r\n } else {\r\n return this._pickSetWithoutDuplicates(array, numPicks);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a new array randomly picking elements in the original (not reused)\r\n * @param array Array to pick elements out of\r\n * @param numPicks must be less than or equal to the number of elements in the array.\r\n */\r\n private _pickSetWithoutDuplicates(array: Array, numPicks: number): Array {\r\n if (numPicks > array.length || numPicks < 0) {\r\n throw new Error('Invalid number of elements to pick, must pick a value 0 < n <= length');\r\n }\r\n if (numPicks === array.length) {\r\n return array;\r\n }\r\n\r\n const result: Array = new Array(numPicks);\r\n let currentPick = 0;\r\n const tempArray = array.slice(0);\r\n while (currentPick < numPicks) {\r\n const index = this.integer(0, tempArray.length - 1);\r\n result[currentPick++] = tempArray[index];\r\n tempArray.splice(index, 1);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new array random picking elements from the original allowing duplicates\r\n * @param array Array to pick elements out of\r\n * @param numPicks can be any positive number\r\n */\r\n private _pickSetWithDuplicates(array: Array, numPicks: number): Array {\r\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\r\n if (numPicks < 0) {\r\n throw new Error('Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT');\r\n }\r\n const result = new Array(numPicks);\r\n for (let i = 0; i < numPicks; i++) {\r\n result[i] = this.pickOne(array);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\r\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\r\n */\r\n public shuffle(array: Array): Array {\r\n const tempArray = array.slice(0);\r\n let swap: T = null;\r\n for (let i = 0; i < tempArray.length - 2; i++) {\r\n const randomIndex = this.integer(i, tempArray.length - 1);\r\n swap = tempArray[i];\r\n tempArray[i] = tempArray[randomIndex];\r\n tempArray[randomIndex] = swap;\r\n }\r\n\r\n return tempArray;\r\n }\r\n\r\n /**\r\n * Generate a list of random integer numbers\r\n * @param length the length of the final array\r\n * @param min the minimum integer number to generate inclusive\r\n * @param max the maximum integer number to generate inclusive\r\n */\r\n public range(length: number, min: number, max: number): Array {\r\n const result: Array = new Array(length);\r\n for (let i = 0; i < length; i++) {\r\n result[i] = this.integer(min, max);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns the result of a d4 dice roll\r\n */\r\n public d4() {\r\n return this.integer(1, 4);\r\n }\r\n\r\n /**\r\n * Returns the result of a d6 dice roll\r\n */\r\n public d6() {\r\n return this.integer(1, 6);\r\n }\r\n\r\n /**\r\n * Returns the result of a d8 dice roll\r\n */\r\n public d8() {\r\n return this.integer(1, 8);\r\n }\r\n\r\n /**\r\n * Returns the result of a d10 dice roll\r\n */\r\n public d10() {\r\n return this.integer(1, 10);\r\n }\r\n\r\n /**\r\n * Returns the result of a d12 dice roll\r\n */\r\n public d12() {\r\n return this.integer(1, 12);\r\n }\r\n\r\n /**\r\n * Returns the result of a d20 dice roll\r\n */\r\n public d20() {\r\n return this.integer(1, 20);\r\n }\r\n}\r\n","import { Random } from './Random';\r\n\r\n/**\r\n * Two PI constant\r\n */\r\nexport const TwoPI: number = Math.PI * 2;\r\n\r\n/**\r\n * Returns the fractional part of a number\r\n * @param x\r\n */\r\nexport function frac(x: number): number {\r\n if (x >= 0) {\r\n return x - Math.floor(x);\r\n } else {\r\n return x - Math.ceil(x);\r\n }\r\n}\r\n\r\n/**\r\n * Returns the sign of a number, if 0 returns 0\r\n */\r\nexport function sign(val: number): number {\r\n if (val === 0) {\r\n return 0;\r\n }\r\n return val < 0 ? -1 : 1;\r\n};\r\n\r\n/**\r\n * Clamps a value between a min and max inclusive\r\n */\r\nexport function clamp(val: number, min: number, max: number) {\r\n return Math.min(Math.max(min, val), max);\r\n}\r\n\r\n\r\n/**\r\n * Convert an angle to be the equivalent in the range [0, 2PI]\r\n */\r\nexport function canonicalizeAngle(angle: number): number {\r\n let tmpAngle = angle;\r\n if (angle > TwoPI) {\r\n while (tmpAngle > TwoPI) {\r\n tmpAngle -= TwoPI;\r\n }\r\n }\r\n\r\n if (angle < 0) {\r\n while (tmpAngle < 0) {\r\n tmpAngle += TwoPI;\r\n }\r\n }\r\n return tmpAngle;\r\n}\r\n\r\n/**\r\n * Convert radians to degrees\r\n */\r\nexport function toDegrees(radians: number): number {\r\n return (180 / Math.PI) * radians;\r\n}\r\n\r\n/**\r\n * Convert degrees to radians\r\n */\r\nexport function toRadians(degrees: number): number {\r\n return (degrees / 180) * Math.PI;\r\n}\r\n\r\n/**\r\n * Generate a range of numbers\r\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\r\n * @param from inclusive\r\n * @param to inclusive\r\n */\r\nexport const range = (from: number, to: number) => Array.from(new Array(to - from + 1), (_x, i) => i + from);\r\n\r\n/**\r\n * Find a random floating point number in range\r\n */\r\nexport function randomInRange(min: number, max: number, random: Random = new Random()): number {\r\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\r\n}\r\n\r\n/**\r\n * Find a random integer in a range\r\n */\r\nexport function randomIntInRange(min: number, max: number, random: Random = new Random()): number {\r\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\r\n}","import { Clonable } from '../Interfaces/Clonable';\r\nimport { clamp } from './util';\r\n\r\n/**\r\n * A 2D vector on a plane.\r\n */\r\n\r\nexport class Vector implements Clonable {\r\n /**\r\n * A (0, 0) vector\r\n */\r\n public static get Zero() {\r\n return new Vector(0, 0);\r\n }\r\n\r\n /**\r\n * A (1, 1) vector\r\n */\r\n public static get One() {\r\n return new Vector(1, 1);\r\n }\r\n\r\n /**\r\n * A (0.5, 0.5) vector\r\n */\r\n public static get Half() {\r\n return new Vector(0.5, 0.5);\r\n }\r\n\r\n /**\r\n * A unit vector pointing up (0, -1)\r\n */\r\n public static get Up() {\r\n return new Vector(0, -1);\r\n }\r\n\r\n /**\r\n * A unit vector pointing down (0, 1)\r\n */\r\n public static get Down() {\r\n return new Vector(0, 1);\r\n }\r\n\r\n /**\r\n * A unit vector pointing left (-1, 0)\r\n */\r\n public static get Left() {\r\n return new Vector(-1, 0);\r\n }\r\n /**\r\n * A unit vector pointing right (1, 0)\r\n */\r\n public static get Right() {\r\n return new Vector(1, 0);\r\n }\r\n\r\n /**\r\n * Returns a vector of unit length in the direction of the specified angle in Radians.\r\n * @param angle The angle to generate the vector\r\n */\r\n public static fromAngle(angle: number) {\r\n return new Vector(Math.cos(angle), Math.sin(angle));\r\n }\r\n\r\n /**\r\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\r\n */\r\n public static isValid(vec: Vector) {\r\n if (vec === null || vec === undefined) {\r\n return false;\r\n }\r\n if (isNaN(vec.x) || isNaN(vec.y)) {\r\n return false;\r\n }\r\n\r\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Calculates distance between two Vectors\r\n * @param vec1\r\n * @param vec2\r\n */\r\n public static distance(vec1: Vector, vec2: Vector) {\r\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\r\n }\r\n\r\n public static min(vec1: Vector, vec2: Vector) {\r\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\r\n }\r\n\r\n public static max(vec1: Vector, vec2: Vector) {\r\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\r\n }\r\n\r\n /**\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */\r\n constructor(x: number, y: number) {\r\n this._x = x;\r\n this._y = y;\r\n }\r\n\r\n protected _x = 0;\r\n /**\r\n * Get the x component of the vector\r\n */\r\n public get x(): number {\r\n return this._x;\r\n }\r\n\r\n /**\r\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */\r\n public set x(val: number) {\r\n this._x = val;\r\n }\r\n\r\n protected _y = 0;\r\n /**\r\n * Get the y component of the vector\r\n */\r\n public get y(): number {\r\n return this._y;\r\n }\r\n\r\n /**\r\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */\r\n public set y(val: number) {\r\n this._y = val;\r\n }\r\n\r\n /**\r\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\r\n */\r\n setTo(x: number, y: number) {\r\n (this.x as number) = x;\r\n (this.y as number) = y;\r\n }\r\n\r\n /**\r\n * Compares this point against another and tests for equality\r\n * @param vector The other point to compare to\r\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\r\n */\r\n public equals(vector: Vector, tolerance: number = 0.001): boolean {\r\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\r\n }\r\n\r\n /**\r\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\r\n * @param v The other vector. Leave blank to use origin vector.\r\n */\r\n public distance(v?: Vector): number {\r\n if (!v) {\r\n return Math.sqrt(this.x * this.x + this.y * this.y);\r\n }\r\n const deltaX = this.x - v.x;\r\n const deltaY = this.y - v.y;\r\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\r\n }\r\n\r\n public squareDistance(v?: Vector): number {\r\n if (!v) {\r\n v = Vector.Zero;\r\n }\r\n const deltaX = this.x - v.x;\r\n const deltaY = this.y - v.y;\r\n return deltaX * deltaX + deltaY * deltaY;\r\n }\r\n\r\n /**\r\n * Clamps the current vector's magnitude mutating it\r\n * @param magnitude\r\n */\r\n public clampMagnitude(magnitude: number): Vector {\r\n const size = this.size;\r\n const newSize = clamp(size, 0, magnitude);\r\n this.size = newSize;\r\n return this;\r\n }\r\n\r\n /**\r\n * The size (magnitude) of the Vector\r\n */\r\n public get size(): number {\r\n return this.distance();\r\n }\r\n\r\n /**\r\n * Setting the size mutates the current vector\r\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\r\n */\r\n public set size(newLength: number) {\r\n const v = this.normalize().scale(newLength);\r\n this.setTo(v.x, v.y);\r\n }\r\n\r\n /**\r\n * Normalizes a vector to have a magnitude of 1.\r\n */\r\n public normalize(): Vector {\r\n const d = this.distance();\r\n if (d > 0) {\r\n return new Vector(this.x / d, this.y / d);\r\n } else {\r\n return new Vector(0, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Returns the average (midpoint) between the current point and the specified\r\n */\r\n public average(vec: Vector): Vector {\r\n return this.add(vec).scale(0.5);\r\n }\r\n\r\n /**\r\n * Scales a vector's by a factor of size\r\n * @param size The factor to scale the magnitude by\r\n * @param dest Optionally provide a destination vector for the result\r\n */\r\n public scale(scale: Vector, dest?: Vector): Vector;\r\n public scale(size: number, dest?: Vector): Vector;\r\n public scale(sizeOrScale: number | Vector, dest?: Vector): Vector {\r\n const result = dest || new Vector(0, 0);\r\n if (sizeOrScale instanceof Vector) {\r\n result.x = this.x * sizeOrScale.x;\r\n result.y = this.y * sizeOrScale.y;\r\n } else {\r\n result.x = this.x * sizeOrScale;\r\n result.y = this.y * sizeOrScale;\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Adds one vector to another\r\n * @param v The vector to add\r\n * @param dest Optionally copy the result into a provided vector\r\n */\r\n public add(v: Vector, dest?: Vector): Vector {\r\n if (dest) {\r\n dest.x = this.x + v.x;\r\n dest.y = this.y + v.y;\r\n return dest;\r\n }\r\n return new Vector(this.x + v.x, this.y + v.y);\r\n }\r\n\r\n /**\r\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\r\n * @param v The vector to subtract\r\n */\r\n public sub(v: Vector): Vector {\r\n return new Vector(this.x - v.x, this.y - v.y);\r\n }\r\n\r\n /**\r\n * Adds one vector to this one modifying the original\r\n * @param v The vector to add\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public addEqual(v: Vector): Vector {\r\n this.setTo(this.x + v.x, this.y + v.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * Subtracts a vector from this one modifying the original\r\n * @param v The vector to subtract\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public subEqual(v: Vector): Vector {\r\n this.setTo(this.x - v.x, this.y - v.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * Scales this vector by a factor of size and modifies the original\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public scaleEqual(size: number): Vector {\r\n this.setTo(this.x * size, this.y * size);\r\n return this;\r\n }\r\n\r\n /**\r\n * Performs a dot product with another vector\r\n * @param v The vector to dot\r\n */\r\n public dot(v: Vector): number {\r\n return this.x * v.x + this.y * v.y;\r\n }\r\n\r\n /**\r\n * Performs a 2D cross product with scalar. 2D cross products with a scalar return a vector.\r\n * @param v The scalar to cross\r\n */\r\n public cross(v: number): Vector;\r\n /**\r\n * Performs a 2D cross product with another vector. 2D cross products return a scalar value not a vector.\r\n * @param v The vector to cross\r\n */\r\n public cross(v: Vector): number;\r\n public cross(v: any): any {\r\n if (v instanceof Vector) {\r\n return this.x * v.y - this.y * v.x;\r\n } else if (typeof v === 'number') {\r\n return new Vector(v * this.y, -v * this.x);\r\n }\r\n }\r\n\r\n static cross(num: number, vec: Vector): Vector {\r\n return new Vector(-num * vec.y, num * vec.x);\r\n }\r\n\r\n /**\r\n * Returns the perpendicular vector to this one\r\n */\r\n public perpendicular(): Vector {\r\n return new Vector(this.y, -this.x);\r\n }\r\n\r\n /**\r\n * Returns the normal vector to this one, same as the perpendicular of length 1\r\n */\r\n public normal(): Vector {\r\n return this.perpendicular().normalize();\r\n }\r\n\r\n /**\r\n * Negate the current vector\r\n */\r\n public negate(): Vector {\r\n return this.scale(-1);\r\n }\r\n\r\n /**\r\n * Returns the angle of this vector.\r\n */\r\n public toAngle(): number {\r\n return Math.atan2(this.y, this.x);\r\n }\r\n\r\n /**\r\n * Rotates the current vector around a point by a certain number of\r\n * degrees in radians\r\n */\r\n public rotate(angle: number, anchor?: Vector): Vector {\r\n if (!anchor) {\r\n anchor = new Vector(0, 0);\r\n }\r\n const sinAngle = Math.sin(angle);\r\n const cosAngle = Math.cos(angle);\r\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\r\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\r\n return new Vector(x, y);\r\n }\r\n\r\n /**\r\n * Creates new vector that has the same values as the previous.\r\n */\r\n public clone(dest?: Vector): Vector {\r\n const v = dest ?? new Vector(0, 0);\r\n v.x = this.x;\r\n v.y = this.y;\r\n return v;\r\n }\r\n\r\n /**\r\n * Returns a string representation of the vector.\r\n */\r\n public toString(fixed?: number): string {\r\n if (fixed) {\r\n return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\r\n }\r\n return `(${this.x}, ${this.y})`;\r\n }\r\n}\r\n\r\n/**\r\n * Shorthand for creating new Vectors - returns a new Vector instance with the\r\n * provided X and Y components.\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */\r\nexport function vec(x: number, y: number): Vector {\r\n return new Vector(x, y);\r\n}\r\n","\r\n/**\r\n * Provides standard colors (e.g. [[Color.Black]])\r\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\r\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\r\n */\r\nexport class Color {\r\n /**\r\n * Red channel\r\n */\r\n public r: number;\r\n /**\r\n * Green channel\r\n */\r\n public g: number;\r\n /**\r\n * Blue channel\r\n */\r\n public b: number;\r\n /**\r\n * Alpha channel (between 0 and 1)\r\n */\r\n public a: number;\r\n\r\n /**\r\n * Hue\r\n */\r\n public h: number;\r\n /**\r\n * Saturation\r\n */\r\n public s: number;\r\n /**\r\n * Lightness\r\n */\r\n public l: number;\r\n\r\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */\r\n constructor(r: number, g: number, b: number, a?: number) {\r\n this.r = r;\r\n this.g = g;\r\n this.b = b;\r\n this.a = a != null ? a : 1;\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */\r\n public static fromRGB(r: number, g: number, b: number, a?: number): Color {\r\n return new Color(r, g, b, a);\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from a rgb string\r\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\r\n */\r\n public static fromRGBString(string: string): Color {\r\n const rgbaRegEx: RegExp = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\r\n let match = null;\r\n if ((match = string.match(rgbaRegEx))) {\r\n const r = parseInt(match[1], 10);\r\n const g = parseInt(match[2], 10);\r\n const b = parseInt(match[3], 10);\r\n let a = 1;\r\n if (match[4]) {\r\n a = parseFloat(match[4]);\r\n }\r\n return new Color(r, g, b, a);\r\n } else {\r\n throw new Error('Invalid rgb/a string: ' + string);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from a hex string\r\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\r\n */\r\n public static fromHex(hex: string): Color {\r\n const hexRegEx: RegExp = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\r\n let match = null;\r\n if ((match = hex.match(hexRegEx))) {\r\n const r = parseInt(match[1], 16);\r\n const g = parseInt(match[2], 16);\r\n const b = parseInt(match[3], 16);\r\n let a = 1;\r\n if (match[4]) {\r\n a = parseInt(match[4], 16) / 255;\r\n }\r\n return new Color(r, g, b, a);\r\n } else {\r\n throw new Error('Invalid hex string: ' + hex);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from hsla values\r\n * @param h Hue is represented [0-1]\r\n * @param s Saturation is represented [0-1]\r\n * @param l Luminance is represented [0-1]\r\n * @param a Alpha is represented [0-1]\r\n */\r\n public static fromHSL(h: number, s: number, l: number, a: number = 1.0): Color {\r\n const temp = new HSLColor(h, s, l, a);\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Lightens the current color by a specified amount\r\n * @param factor The amount to lighten by [0-1]\r\n */\r\n public lighten(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.l += (1 - temp.l) * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Darkens the current color by a specified amount\r\n * @param factor The amount to darken by [0-1]\r\n */\r\n public darken(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.l -= temp.l * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Saturates the current color by a specified amount\r\n * @param factor The amount to saturate by [0-1]\r\n */\r\n public saturate(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.s += temp.s * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Desaturates the current color by a specified amount\r\n * @param factor The amount to desaturate by [0-1]\r\n */\r\n public desaturate(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.s -= temp.s * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Multiplies a color by another, results in a darker color\r\n * @param color The other color\r\n */\r\n public multiply(color: Color): Color {\r\n const newR = (((color.r / 255) * this.r) / 255) * 255;\r\n const newG = (((color.g / 255) * this.g) / 255) * 255;\r\n const newB = (((color.b / 255) * this.b) / 255) * 255;\r\n const newA = color.a * this.a;\r\n return new Color(newR, newG, newB, newA);\r\n }\r\n\r\n /**\r\n * Screens a color by another, results in a lighter color\r\n * @param color The other color\r\n */\r\n public screen(color: Color): Color {\r\n const color1 = color.invert();\r\n const color2 = color.invert();\r\n return color1.multiply(color2).invert();\r\n }\r\n\r\n /**\r\n * Inverts the current color\r\n */\r\n public invert(): Color {\r\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\r\n }\r\n\r\n /**\r\n * Averages the current color with another\r\n * @param color The other color\r\n */\r\n public average(color: Color): Color {\r\n const newR = (color.r + this.r) / 2;\r\n const newG = (color.g + this.g) / 2;\r\n const newB = (color.b + this.b) / 2;\r\n const newA = (color.a + this.a) / 2;\r\n return new Color(newR, newG, newB, newA);\r\n }\r\n\r\n public equal(color: Color): boolean {\r\n return this.toString() === color.toString();\r\n }\r\n\r\n /**\r\n * Returns a CSS string representation of a color.\r\n * @param format Color representation, accepts: rgb, hsl, or hex\r\n */\r\n public toString(format: 'rgb' | 'hsl' | 'hex' = 'rgb') {\r\n switch (format) {\r\n case 'rgb':\r\n return this.toRGBA();\r\n case 'hsl':\r\n return this.toHSLA();\r\n case 'hex':\r\n return this.toHex();\r\n default:\r\n throw new Error('Invalid Color format');\r\n }\r\n }\r\n\r\n /**\r\n * Returns Hex Value of a color component\r\n * @param c color component\r\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\r\n */\r\n private _componentToHex(c: number) {\r\n const hex = c.toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n }\r\n\r\n /**\r\n * Return Hex representation of a color.\r\n */\r\n public toHex() {\r\n return '#' + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\r\n }\r\n\r\n /**\r\n * Return RGBA representation of a color.\r\n */\r\n public toRGBA() {\r\n const result = String(this.r.toFixed(0)) + ', ' + String(this.g.toFixed(0)) + ', ' + String(this.b.toFixed(0));\r\n if (this.a !== undefined || this.a !== null) {\r\n return 'rgba(' + result + ', ' + String(this.a) + ')';\r\n }\r\n return 'rgb(' + result + ')';\r\n }\r\n\r\n /**\r\n * Return HSLA representation of a color.\r\n */\r\n public toHSLA() {\r\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\r\n }\r\n\r\n /**\r\n * Returns a CSS string representation of a color.\r\n */\r\n public fillStyle() {\r\n return this.toString();\r\n }\r\n\r\n /**\r\n * Returns a clone of the current color.\r\n */\r\n public clone(): Color {\r\n return new Color(this.r, this.g, this.b, this.a);\r\n }\r\n\r\n /**\r\n * Black (#000000)\r\n */\r\n public static get Black(): Color {\r\n return Color.fromHex('#000000');\r\n }\r\n\r\n /**\r\n * White (#FFFFFF)\r\n */\r\n public static get White(): Color {\r\n return Color.fromHex('#FFFFFF');\r\n }\r\n\r\n /**\r\n * Gray (#808080)\r\n */\r\n public static get Gray(): Color {\r\n return Color.fromHex('#808080');\r\n }\r\n\r\n /**\r\n * Light gray (#D3D3D3)\r\n */\r\n public static get LightGray(): Color {\r\n return Color.fromHex('#D3D3D3');\r\n }\r\n\r\n /**\r\n * Dark gray (#A9A9A9)\r\n */\r\n public static get DarkGray(): Color {\r\n return Color.fromHex('#A9A9A9');\r\n }\r\n\r\n /**\r\n * Yellow (#FFFF00)\r\n */\r\n public static get Yellow(): Color {\r\n return Color.fromHex('#FFFF00');\r\n }\r\n\r\n /**\r\n * Orange (#FFA500)\r\n */\r\n public static get Orange(): Color {\r\n return Color.fromHex('#FFA500');\r\n }\r\n\r\n /**\r\n * Red (#FF0000)\r\n */\r\n public static get Red(): Color {\r\n return Color.fromHex('#FF0000');\r\n }\r\n\r\n /**\r\n * Vermilion (#FF5B31)\r\n */\r\n public static get Vermilion(): Color {\r\n return Color.fromHex('#FF5B31');\r\n }\r\n\r\n /**\r\n * Rose (#FF007F)\r\n */\r\n public static get Rose(): Color {\r\n return Color.fromHex('#FF007F');\r\n }\r\n\r\n /**\r\n * Magenta (#FF00FF)\r\n */\r\n public static get Magenta(): Color {\r\n return Color.fromHex('#FF00FF');\r\n }\r\n\r\n /**\r\n * Violet (#7F00FF)\r\n */\r\n public static get Violet(): Color {\r\n return Color.fromHex('#7F00FF');\r\n }\r\n\r\n /**\r\n * Blue (#0000FF)\r\n */\r\n public static get Blue(): Color {\r\n return Color.fromHex('#0000FF');\r\n }\r\n\r\n /**\r\n * Azure (#007FFF)\r\n */\r\n public static get Azure(): Color {\r\n return Color.fromHex('#007FFF');\r\n }\r\n\r\n /**\r\n * Cyan (#00FFFF)\r\n */\r\n public static get Cyan(): Color {\r\n return Color.fromHex('#00FFFF');\r\n }\r\n\r\n /**\r\n * Viridian (#59978F)\r\n */\r\n public static get Viridian(): Color {\r\n return Color.fromHex('#59978F');\r\n }\r\n\r\n /**\r\n * Green (#00FF00)\r\n */\r\n public static get Green(): Color {\r\n return Color.fromHex('#00FF00');\r\n }\r\n\r\n /**\r\n * Chartreuse (#7FFF00)\r\n */\r\n public static get Chartreuse(): Color {\r\n return Color.fromHex('#7FFF00');\r\n }\r\n\r\n /**\r\n * Transparent (#FFFFFF00)\r\n */\r\n public static get Transparent(): Color {\r\n return Color.fromHex('#FFFFFF00');\r\n }\r\n\r\n /**\r\n * ExcaliburBlue (#176BAA)\r\n */\r\n public static get ExcaliburBlue(): Color {\r\n return Color.fromHex('#176BAA');\r\n }\r\n}\r\n\r\n/**\r\n * Internal HSL Color representation\r\n *\r\n * http://en.wikipedia.org/wiki/HSL_and_HSV\r\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\r\n */\r\nclass HSLColor {\r\n constructor(public h: number, public s: number, public l: number, public a: number) {}\r\n\r\n public static hue2rgb(p: number, q: number, t: number): number {\r\n if (t < 0) {\r\n t += 1;\r\n }\r\n if (t > 1) {\r\n t -= 1;\r\n }\r\n if (t < 1 / 6) {\r\n return p + (q - p) * 6 * t;\r\n }\r\n if (t < 1 / 2) {\r\n return q;\r\n }\r\n if (t < 2 / 3) {\r\n return p + (q - p) * (2 / 3 - t) * 6;\r\n }\r\n return p;\r\n }\r\n\r\n public static fromRGBA(r: number, g: number, b: number, a: number): HSLColor {\r\n r /= 255;\r\n g /= 255;\r\n b /= 255;\r\n const max = Math.max(r, g, b),\r\n min = Math.min(r, g, b);\r\n let h, s;\r\n const l = (max + min) / 2;\r\n\r\n if (max === min) {\r\n h = s = 0; // achromatic\r\n } else {\r\n const d = max - min;\r\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\r\n switch (max) {\r\n case r:\r\n h = (g - b) / d + (g < b ? 6 : 0);\r\n break;\r\n case g:\r\n h = (b - r) / d + 2;\r\n break;\r\n case b:\r\n h = (r - g) / d + 4;\r\n break;\r\n }\r\n h /= 6;\r\n }\r\n\r\n return new HSLColor(h, s, l, a);\r\n }\r\n\r\n public toRGBA(): Color {\r\n let r: number, g: number, b: number;\r\n\r\n if (this.s === 0) {\r\n r = g = b = this.l; // achromatic\r\n } else {\r\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\r\n const p = 2 * this.l - q;\r\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\r\n g = HSLColor.hue2rgb(p, q, this.h);\r\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\r\n }\r\n\r\n return new Color(r * 255, g * 255, b * 255, this.a);\r\n }\r\n\r\n public toString(): string {\r\n const h = this.h.toFixed(0),\r\n s = this.s.toFixed(0),\r\n l = this.l.toFixed(0),\r\n a = this.a.toFixed(0);\r\n return `hsla(${h}, ${s}, ${l}, ${a})`;\r\n }\r\n}\r\n","/* eslint-disable no-console */\r\n\r\nimport { Engine } from '../Engine';\r\nimport { vec } from '../Math/vector';\r\nimport { Color } from '../Color';\r\n\r\n/**\r\n * Logging level that Excalibur will tag\r\n */\r\nexport enum LogLevel {\r\n Debug,\r\n Info,\r\n Warn,\r\n Error,\r\n Fatal\r\n}\r\n\r\n/**\r\n * Static singleton that represents the logging facility for Excalibur.\r\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\r\n * Derive from [[Appender]] to create your own logging appenders.\r\n */\r\nexport class Logger {\r\n private static _INSTANCE: Logger = null;\r\n private _appenders: Appender[] = [];\r\n\r\n constructor() {\r\n if (Logger._INSTANCE) {\r\n throw new Error('Logger is a singleton');\r\n }\r\n Logger._INSTANCE = this;\r\n // Default console appender\r\n Logger._INSTANCE.addAppender(new ConsoleAppender());\r\n return Logger._INSTANCE;\r\n }\r\n\r\n /**\r\n * Gets or sets the default logging level. Excalibur will only log\r\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\r\n */\r\n public defaultLevel: LogLevel = LogLevel.Info;\r\n\r\n /**\r\n * Gets the current static instance of Logger\r\n */\r\n public static getInstance(): Logger {\r\n if (Logger._INSTANCE == null) {\r\n Logger._INSTANCE = new Logger();\r\n }\r\n return Logger._INSTANCE;\r\n }\r\n\r\n /**\r\n * Adds a new [[Appender]] to the list of appenders to write to\r\n */\r\n public addAppender(appender: Appender): void {\r\n this._appenders.push(appender);\r\n }\r\n\r\n /**\r\n * Clears all appenders from the logger\r\n */\r\n public clearAppenders(): void {\r\n this._appenders.length = 0;\r\n }\r\n\r\n /**\r\n * Logs a message at a given LogLevel\r\n * @param level The LogLevel`to log the message at\r\n * @param args An array of arguments to write to an appender\r\n */\r\n private _log(level: LogLevel, args: any[]): void {\r\n if (level == null) {\r\n level = this.defaultLevel;\r\n }\r\n\r\n const len = this._appenders.length;\r\n\r\n for (let i = 0; i < len; i++) {\r\n if (level >= this.defaultLevel) {\r\n this._appenders[i].log(level, args);\r\n }\r\n }\r\n }\r\n\r\n\r\n private _logOnceSet = new Set();\r\n private _logOnce(level: LogLevel, args: any[]): void {\r\n const serialized = level + args.join('+');\r\n if (this._logOnceSet.has(serialized)) {\r\n return;\r\n } else {\r\n this._logOnceSet.add(serialized);\r\n this._log(level, args);\r\n }\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Debug]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public debug(...args: any[]): void {\r\n this._log(LogLevel.Debug, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it wont log\r\n * @param args Accepts any number of arguments\r\n */\r\n public debugOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Debug, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Info]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public info(...args: any[]): void {\r\n this._log(LogLevel.Info, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Info]] level, if it sees the same args again it wont log\r\n * @param args Accepts any number of arguments\r\n */\r\n public infoOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Info, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Warn]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public warn(...args: any[]): void {\r\n this._log(LogLevel.Warn, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Warn]] level, if it sees the same args again it won't log\r\n * @param args Accepts any number of arguments\r\n */\r\n public warnOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Warn, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Error]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public error(...args: any[]): void {\r\n this._log(LogLevel.Error, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Error]] level, if it sees the same args again it won't log\r\n * @param args Accepts any number of arguments\r\n */\r\n public errorOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Error, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Fatal]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public fatal(...args: any[]): void {\r\n this._log(LogLevel.Fatal, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it won't log\r\n * @param args Accepts any number of arguments\r\n */\r\n public fatalOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Fatal, args);\r\n }\r\n}\r\n\r\n/**\r\n * Contract for any log appender (such as console/screen)\r\n */\r\nexport interface Appender {\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n log(level: LogLevel, args: any[]): void;\r\n}\r\n\r\n/**\r\n * Console appender for browsers (i.e. `console.log`)\r\n */\r\nexport class ConsoleAppender implements Appender {\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n public log(level: LogLevel, args: any[]): void {\r\n // Check for console support\r\n if (!console && !console.log && console.warn && console.error) {\r\n // todo maybe do something better than nothing\r\n return;\r\n }\r\n\r\n // Create a new console args array\r\n const consoleArgs: any[] = [];\r\n consoleArgs.unshift.apply(consoleArgs, args);\r\n consoleArgs.unshift('[' + LogLevel[level] + '] : ');\r\n\r\n if (level < LogLevel.Warn) {\r\n // Call .log for Debug/Info\r\n if (console.log.apply) {\r\n // this is required on some older browsers that don't support apply on console.log :(\r\n console.log.apply(console, consoleArgs);\r\n } else {\r\n console.log(consoleArgs.join(' '));\r\n }\r\n } else if (level < LogLevel.Error) {\r\n // Call .warn for Warn\r\n if (console.warn.apply) {\r\n console.warn.apply(console, consoleArgs);\r\n } else {\r\n console.warn(consoleArgs.join(' '));\r\n }\r\n } else {\r\n // Call .error for Error/Fatal\r\n if (console.error.apply) {\r\n console.error.apply(console, consoleArgs);\r\n } else {\r\n console.error(consoleArgs.join(' '));\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport interface ScreenAppenderOptions {\r\n engine: Engine;\r\n /**\r\n * Optionally set the width of the overlay canvas\r\n */\r\n width?: number;\r\n /**\r\n * Optionally set the height of the overlay canvas\r\n */\r\n height?: number;\r\n /**\r\n * Adjust the text offset from the left side of the screen\r\n */\r\n xPos?: number;\r\n /**\r\n * Provide a text color\r\n */\r\n color?: Color;\r\n /**\r\n * Optionally set the CSS zindex of the overlay canvas\r\n */\r\n zIndex?: number;\r\n}\r\n\r\n/**\r\n * On-screen (canvas) appender\r\n */\r\nexport class ScreenAppender implements Appender {\r\n\r\n private _messages: string[] = [];\r\n public canvas: HTMLCanvasElement;\r\n private _ctx: CanvasRenderingContext2D;\r\n private _pos = 10;\r\n private _color = Color.Black;\r\n private _options: ScreenAppenderOptions;\r\n constructor(options: ScreenAppenderOptions) {\r\n this._options = options;\r\n this.canvas = document.createElement('canvas');\r\n this._ctx = this.canvas.getContext('2d')!;\r\n this.canvas.style.position = 'absolute';\r\n this.canvas.style.zIndex = options.zIndex?.toString() ?? '99';\r\n document.body.appendChild(this.canvas);\r\n this._positionScreenAppenderCanvas();\r\n options.engine.screen.events.on('resize', () => {\r\n this._positionScreenAppenderCanvas();\r\n });\r\n }\r\n\r\n private _positionScreenAppenderCanvas() {\r\n const options = this._options;\r\n this.canvas.width = options.width ?? options.engine.screen.resolution.width;\r\n this.canvas.height = options.height ?? options.engine.screen.resolution.height;\r\n this.canvas.style.position = 'absolute';\r\n const pagePos = options.engine.screen.screenToPageCoordinates(vec(0, 0));\r\n this.canvas.style.left = pagePos.x + 'px';\r\n this.canvas.style.top = pagePos.y + 'px';\r\n this._pos = options.xPos ?? this._pos;\r\n this._color = options.color ?? this._color;\r\n }\r\n\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n public log(level: LogLevel, args: any[]): void {\r\n const message = args.join(',');\r\n\r\n this._ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\r\n\r\n this._messages.unshift('[' + LogLevel[level] + '] : ' + message);\r\n\r\n let pos = 10;\r\n\r\n this._messages = this._messages.slice(0, 1000);\r\n for (let i = 0; i < this._messages.length; i++) {\r\n this._ctx.fillStyle = this._color.toRGBA();\r\n this._ctx.fillText(this._messages[i], this._pos, pos);\r\n pos += 10;\r\n }\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\n\r\n/**\r\n * An enum that describes the sides of an axis aligned box for collision\r\n */\r\nexport enum Side {\r\n None = 'None',\r\n Top = 'Top',\r\n Bottom = 'Bottom',\r\n Left = 'Left',\r\n Right = 'Right'\r\n}\r\n\r\nexport module Side {\r\n /**\r\n * Returns the opposite side from the current\r\n */\r\n export function getOpposite(side: Side): Side {\r\n if (side === Side.Top) {\r\n return Side.Bottom;\r\n }\r\n if (side === Side.Bottom) {\r\n return Side.Top;\r\n }\r\n if (side === Side.Left) {\r\n return Side.Right;\r\n }\r\n if (side === Side.Right) {\r\n return Side.Left;\r\n }\r\n\r\n return Side.None;\r\n }\r\n\r\n /**\r\n * Given a vector, return the Side most in that direction (via dot product)\r\n */\r\n export function fromDirection(direction: Vector): Side {\r\n const directions = [Vector.Left, Vector.Right, Vector.Up, Vector.Down];\r\n const directionEnum = [Side.Left, Side.Right, Side.Top, Side.Bottom];\r\n\r\n let max = -Number.MAX_VALUE;\r\n let maxIndex = -1;\r\n for (let i = 0; i < directions.length; i++) {\r\n if (directions[i].dot(direction) > max) {\r\n max = directions[i].dot(direction);\r\n maxIndex = i;\r\n }\r\n }\r\n return directionEnum[maxIndex];\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Ray } from '../Math/ray';\r\nimport { Color } from '../Color';\r\nimport { Side } from './Side';\r\nimport { ExcaliburGraphicsContext } from '../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { AffineMatrix } from '../Math/affine-matrix';\r\n\r\nexport interface BoundingBoxOptions {\r\n left: number;\r\n right: number;\r\n top: number;\r\n bottom: number;\r\n}\r\n\r\n/**\r\n * Axis Aligned collision primitive for Excalibur.\r\n */\r\nexport class BoundingBox {\r\n public top: number;\r\n public right: number;\r\n public bottom: number;\r\n public left: number;\r\n\r\n /**\r\n * Constructor allows passing of either an object with all coordinate components,\r\n * or the coordinate components passed separately.\r\n * @param leftOrOptions Either x coordinate of the left edge or an options object\r\n * containing the four coordinate components.\r\n * @param top y coordinate of the top edge\r\n * @param right x coordinate of the right edge\r\n * @param bottom y coordinate of the bottom edge\r\n */\r\n constructor(leftOrOptions: number | BoundingBoxOptions = 0, top: number = 0, right: number = 0, bottom: number = 0) {\r\n if (typeof leftOrOptions === 'object') {\r\n this.left = leftOrOptions.left;\r\n this.top = leftOrOptions.top;\r\n this.right = leftOrOptions.right;\r\n this.bottom = leftOrOptions.bottom;\r\n } else if (typeof leftOrOptions === 'number') {\r\n this.left = leftOrOptions;\r\n this.top = top;\r\n this.right = right;\r\n this.bottom = bottom;\r\n }\r\n }\r\n\r\n /**\r\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\r\n */\r\n public clone(): BoundingBox {\r\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\r\n }\r\n\r\n /**\r\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\r\n * @param intersection Intersection vector between 2 bounding boxes\r\n */\r\n public static getSideFromIntersection(intersection: Vector): Side {\r\n if (!intersection) {\r\n return Side.None;\r\n }\r\n if (intersection) {\r\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\r\n if (intersection.x < 0) {\r\n return Side.Right;\r\n }\r\n return Side.Left;\r\n } else {\r\n if (intersection.y < 0) {\r\n return Side.Bottom;\r\n }\r\n return Side.Top;\r\n }\r\n }\r\n return Side.None;\r\n }\r\n\r\n public static fromPoints(points: Vector[]): BoundingBox {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n for (let i = 0; i < points.length; i++) {\r\n if (points[i].x < minX) {\r\n minX = points[i].x;\r\n }\r\n if (points[i].x > maxX) {\r\n maxX = points[i].x;\r\n }\r\n if (points[i].y < minY) {\r\n minY = points[i].y;\r\n }\r\n if (points[i].y > maxY) {\r\n maxY = points[i].y;\r\n }\r\n }\r\n return new BoundingBox(minX, minY, maxX, maxY);\r\n }\r\n\r\n /**\r\n * Creates a bounding box from a width and height\r\n * @param width\r\n * @param height\r\n * @param anchor Default Vector.Half\r\n * @param pos Default Vector.Zero\r\n */\r\n public static fromDimension(width: number, height: number, anchor: Vector = Vector.Half, pos: Vector = Vector.Zero) {\r\n return new BoundingBox(\r\n -width * anchor.x + pos.x,\r\n -height * anchor.y + pos.y,\r\n width - width * anchor.x + pos.x,\r\n height - height * anchor.y + pos.y\r\n );\r\n }\r\n\r\n /**\r\n * Returns the calculated width of the bounding box\r\n */\r\n public get width() {\r\n return this.right - this.left;\r\n }\r\n\r\n /**\r\n * Returns the calculated height of the bounding box\r\n */\r\n public get height() {\r\n return this.bottom - this.top;\r\n }\r\n\r\n /**\r\n * Return whether the bounding box has zero dimensions in height,width or both\r\n */\r\n public hasZeroDimensions() {\r\n return this.width === 0 || this.height === 0;\r\n }\r\n\r\n /**\r\n * Returns the center of the bounding box\r\n */\r\n public get center(): Vector {\r\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\r\n }\r\n\r\n public get topLeft(): Vector {\r\n return new Vector(this.left, this.top);\r\n }\r\n\r\n public get bottomRight(): Vector {\r\n return new Vector(this.right, this.bottom);\r\n }\r\n\r\n public get topRight(): Vector {\r\n return new Vector(this.right, this.top);\r\n }\r\n\r\n public get bottomLeft(): Vector {\r\n return new Vector(this.left, this.bottom);\r\n }\r\n\r\n public translate(pos: Vector): BoundingBox {\r\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\r\n }\r\n\r\n /**\r\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\r\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\r\n */\r\n public rotate(angle: number, point: Vector = Vector.Zero): BoundingBox {\r\n const points = this.getPoints().map((p) => p.rotate(angle, point));\r\n return BoundingBox.fromPoints(points);\r\n }\r\n\r\n /**\r\n * Scale a bounding box by a scale factor, optionally provide a point\r\n * @param scale\r\n * @param point\r\n */\r\n public scale(scale: Vector, point: Vector = Vector.Zero): BoundingBox {\r\n const shifted = this.translate(point);\r\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\r\n }\r\n\r\n /**\r\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\r\n * @param matrix\r\n */\r\n public transform(matrix: AffineMatrix) {\r\n // inlined these calculations to not use vectors would speed it up slightly\r\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\r\n // const xa = matFirstColumn.scale(this.left);\r\n const xa1 = matrix.data[0] * this.left;\r\n const xa2 = matrix.data[1] * this.left;\r\n\r\n // const xb = matFirstColumn.scale(this.right);\r\n const xb1 = matrix.data[0] * this.right;\r\n const xb2 = matrix.data[1] * this.right;\r\n\r\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\r\n // const ya = matSecondColumn.scale(this.top);\r\n const ya1 = matrix.data[2] * this.top;\r\n const ya2 = matrix.data[3] * this.top;\r\n\r\n // const yb = matSecondColumn.scale(this.bottom);\r\n const yb1 = matrix.data[2] * this.bottom;\r\n const yb2 = matrix.data[3] * this.bottom;\r\n\r\n const matrixPos = matrix.getPosition();\r\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\r\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\r\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\r\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\r\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\r\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\r\n\r\n return new BoundingBox({\r\n left,//: topLeft.x,\r\n top,//: topLeft.y,\r\n right,//: bottomRight.x,\r\n bottom//: bottomRight.y\r\n });\r\n }\r\n\r\n /**\r\n * Returns the perimeter of the bounding box\r\n */\r\n public getPerimeter(): number {\r\n const wx = this.width;\r\n const wy = this.height;\r\n return 2 * (wx + wy);\r\n }\r\n\r\n\r\n // Cache bounding box point returns\r\n private _points: Vector[] = [];\r\n private _left?: number;\r\n private _right?: number;\r\n private _top?: number;\r\n private _bottom?: number;\r\n\r\n /**\r\n * Returns the world space points that make up the corners of the bounding box as a polygon\r\n */\r\n public getPoints(): Vector[] {\r\n if (this._left !== this.left ||\r\n this._right !== this.right ||\r\n this._top !== this.top ||\r\n this._bottom !== this.bottom\r\n ) {\r\n this._points.length = 0;\r\n this._points.push(new Vector(this.left, this.top));\r\n this._points.push(new Vector(this.right, this.top));\r\n this._points.push(new Vector(this.right, this.bottom));\r\n this._points.push(new Vector(this.left, this.bottom));\r\n this._left = this.left;\r\n this._right = this.right;\r\n this._top = this.top;\r\n this._bottom = this.bottom;\r\n }\r\n return this._points;\r\n }\r\n\r\n /**\r\n * Determines whether a ray intersects with a bounding box\r\n */\r\n public rayCast(ray: Ray, farClipDistance = Infinity): boolean {\r\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\r\n let tmin = -Infinity;\r\n let tmax = +Infinity;\r\n\r\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\r\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\r\n\r\n const tx1 = (this.left - ray.pos.x) * xinv;\r\n const tx2 = (this.right - ray.pos.x) * xinv;\r\n tmin = Math.min(tx1, tx2);\r\n tmax = Math.max(tx1, tx2);\r\n\r\n const ty1 = (this.top - ray.pos.y) * yinv;\r\n const ty2 = (this.bottom - ray.pos.y) * yinv;\r\n tmin = Math.max(tmin, Math.min(ty1, ty2));\r\n tmax = Math.min(tmax, Math.max(ty1, ty2));\r\n\r\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\r\n }\r\n\r\n public rayCastTime(ray: Ray, farClipDistance = Infinity): number {\r\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\r\n let tmin = -Infinity;\r\n let tmax = +Infinity;\r\n\r\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\r\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\r\n\r\n const tx1 = (this.left - ray.pos.x) * xinv;\r\n const tx2 = (this.right - ray.pos.x) * xinv;\r\n tmin = Math.min(tx1, tx2);\r\n tmax = Math.max(tx1, tx2);\r\n\r\n const ty1 = (this.top - ray.pos.y) * yinv;\r\n const ty2 = (this.bottom - ray.pos.y) * yinv;\r\n tmin = Math.max(tmin, Math.min(ty1, ty2));\r\n tmax = Math.min(tmax, Math.max(ty1, ty2));\r\n\r\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) {\r\n return tmin;\r\n }\r\n return -1;\r\n }\r\n\r\n /**\r\n * Tests whether a point is contained within the bounding box\r\n * @param p The point to test\r\n */\r\n public contains(p: Vector): boolean;\r\n\r\n /**\r\n * Tests whether another bounding box is totally contained in this one\r\n * @param bb The bounding box to test\r\n */\r\n public contains(bb: BoundingBox): boolean;\r\n public contains(val: any): boolean {\r\n if (val instanceof Vector) {\r\n return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\r\n } else if (val instanceof BoundingBox) {\r\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Combines this bounding box and another together returning a new bounding box\r\n * @param other The bounding box to combine\r\n */\r\n public combine(other: BoundingBox): BoundingBox {\r\n const compositeBB = new BoundingBox(\r\n Math.min(this.left, other.left),\r\n Math.min(this.top, other.top),\r\n Math.max(this.right, other.right),\r\n Math.max(this.bottom, other.bottom)\r\n );\r\n return compositeBB;\r\n }\r\n\r\n public get dimensions(): Vector {\r\n return new Vector(this.width, this.height);\r\n }\r\n\r\n /**\r\n * Returns true if the bounding boxes overlap.\r\n * @param other\r\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\r\n * This epsilon is useful in stable collision simulations.\r\n */\r\n public overlaps(other: BoundingBox, epsilon?: number): boolean {\r\n const e = epsilon || 0;\r\n if (other.hasZeroDimensions()){\r\n return this.contains(other);\r\n }\r\n if (this.hasZeroDimensions()) {\r\n return other.contains(this);\r\n }\r\n const totalBoundingBox = this.combine(other);\r\n return totalBoundingBox.width + e < other.width + this.width &&\r\n totalBoundingBox.height + e < other.height + this.height;\r\n }\r\n\r\n /**\r\n * Test wether this bounding box intersects with another returning\r\n * the intersection vector that can be used to resolve the collision. If there\r\n * is no intersection null is returned.\r\n * @param other Other [[BoundingBox]] to test intersection with\r\n * @returns A Vector in the direction of the current BoundingBox, this <- other\r\n */\r\n public intersect(other: BoundingBox): Vector {\r\n const totalBoundingBox = this.combine(other);\r\n\r\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\r\n if (\r\n totalBoundingBox.width < other.width + this.width &&\r\n totalBoundingBox.height < other.height + this.height &&\r\n !totalBoundingBox.dimensions.equals(other.dimensions) &&\r\n !totalBoundingBox.dimensions.equals(this.dimensions)\r\n ) {\r\n // collision\r\n let overlapX = 0;\r\n // right edge is between the other's left and right edge\r\n /**\r\n * +-this-+\r\n * | |\r\n * | +-other-+\r\n * +----|-+ |\r\n * | |\r\n * +-------+\r\n * <---\r\n * ^ overlap\r\n */\r\n if (this.right >= other.left && this.right <= other.right) {\r\n overlapX = other.left - this.right;\r\n // right edge is past the other's right edge\r\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+\r\n * +----|--+ |\r\n * | |\r\n * +------+\r\n * --->\r\n * ^ overlap\r\n */\r\n } else {\r\n overlapX = other.right - this.left;\r\n }\r\n\r\n let overlapY = 0;\r\n // top edge is between the other's top and bottom edge\r\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+ | <- overlap\r\n * +----|--+ | |\r\n * | | \\ /\r\n * +------+ '\r\n */\r\n if (this.top <= other.bottom && this.top >= other.top) {\r\n overlapY = other.bottom - this.top;\r\n // top edge is above the other top edge\r\n /**\r\n * +-this-+ .\r\n * | | / \\\r\n * | +-other-+ | <- overlap\r\n * +----|-+ | |\r\n * | |\r\n * +-------+\r\n */\r\n } else {\r\n overlapY = other.top - this.bottom;\r\n }\r\n\r\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\r\n return new Vector(overlapX, 0);\r\n } else {\r\n return new Vector(0, overlapY);\r\n }\r\n // Case of total containment of one bounding box by another\r\n } else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\r\n let overlapX = 0;\r\n // this is wider than the other\r\n if (this.width - other.width >= 0) {\r\n // This right edge is closest to the others right edge\r\n if (this.right - other.right <= other.left - this.left) {\r\n overlapX = other.left - this.right;\r\n // This left edge is closest to the others left edge\r\n } else {\r\n overlapX = other.right - this.left;\r\n }\r\n // other is wider than this\r\n } else {\r\n // This right edge is closest to the others right edge\r\n if (other.right - this.right <= this.left - other.left) {\r\n overlapX = this.left - other.right;\r\n // This left edge is closest to the others left edge\r\n } else {\r\n overlapX = this.right - other.left;\r\n }\r\n }\r\n\r\n let overlapY = 0;\r\n // this is taller than other\r\n if (this.height - other.height >= 0) {\r\n // The bottom edge is closest to the others bottom edge\r\n if (this.bottom - other.bottom <= other.top - this.top) {\r\n overlapY = other.top - this.bottom;\r\n } else {\r\n overlapY = other.bottom - this.top;\r\n }\r\n // other is taller than this\r\n } else {\r\n // The bottom edge is closest to the others bottom edge\r\n if (other.bottom - this.bottom <= this.top - other.top) {\r\n overlapY = this.top - other.bottom;\r\n } else {\r\n overlapY = this.bottom - other.top;\r\n }\r\n }\r\n\r\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\r\n return new Vector(overlapX, 0);\r\n } else {\r\n return new Vector(0, overlapY);\r\n }\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\r\n * @param bb The other actor to test\r\n */\r\n public intersectWithSide(bb: BoundingBox): Side {\r\n const intersect = this.intersect(bb);\r\n return BoundingBox.getSideFromIntersection(intersect);\r\n }\r\n\r\n /**\r\n * Draw a debug bounding box\r\n * @param ex\r\n * @param color\r\n */\r\n public draw(ex: ExcaliburGraphicsContext, color: Color = Color.Yellow) {\r\n ex.debug.drawRect(this.left, this.top, this.width, this.height, { color });\r\n }\r\n}\r\n","import { Vector, vec } from '../Math/vector';\r\nimport { Clock } from './Clock';\r\nimport { Future } from './Future';\r\n\r\n/**\r\n * Find the screen position of an HTML element\r\n */\r\nexport function getPosition(el: HTMLElement): Vector {\r\n // do we need the scroll too? technically the offset method before did that\r\n const rect = el.getBoundingClientRect();\r\n return vec(rect.x + window.scrollX, rect.y + window.scrollY);\r\n}\r\n\r\n/**\r\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\r\n * @deprecated Will be removed in v0.26.0\r\n */\r\nexport function addItemToArray(item: T, array: T[]): boolean {\r\n if (array.indexOf(item) === -1) {\r\n array.push(item);\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Remove an item from an list\r\n * @deprecated Will be removed in v0.26.0\r\n */\r\nexport function removeItemFromArray(item: T, array: T[]): boolean {\r\n let index = -1;\r\n if ((index = array.indexOf(item)) > -1) {\r\n array.splice(index, 1);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * See if an array contains something\r\n */\r\nexport function contains(array: Array, obj: any): boolean {\r\n for (let i = 0; i < array.length; i++) {\r\n if (array[i] === obj) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Used for exhaustive checks at compile time\r\n */\r\nexport function fail(message: never): never {\r\n throw new Error(message);\r\n}\r\n\r\n/**\r\n * Create a promise that resolves after a certain number of milliseconds\r\n *\r\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\r\n * excalibur clock which would be unaffected by stop/pause.\r\n * @param milliseconds\r\n * @param clock\r\n */\r\nexport function delay(milliseconds: number, clock?: Clock): Promise {\r\n const future = new Future();\r\n const schedule = clock?.schedule.bind(clock) ?? setTimeout;\r\n schedule(() => {\r\n future.resolve();\r\n }, milliseconds);\r\n return future.promise;\r\n}\r\n\r\n/**\r\n * Remove keys from object literals\r\n * @param object\r\n * @param keys\r\n */\r\nexport function omit(object: TObject, keys: Keys[]) {\r\n const newObj: Omit = {} as any;\r\n for (const key in object) {\r\n if (!keys.includes(key as any)) {\r\n (newObj as any)[key] = object[key];\r\n }\r\n }\r\n return newObj;\r\n}","import { sign } from './util';\r\nimport { Vector, vec } from './vector';\r\nimport { canonicalizeAngle } from './util';\r\n\r\nexport enum MatrixLocations {\r\n X = 12,\r\n Y = 13\r\n}\r\n\r\n/**\r\n * Excalibur Matrix helper for 4x4 matrices\r\n *\r\n * Useful for webgl 4x4 matrices\r\n */\r\nexport class Matrix {\r\n /**\r\n * 4x4 matrix in column major order\r\n *\r\n * | | | | |\r\n * | ------- | ------- | -------- | -------- |\r\n * | data[0] | data[4] | data[8] | data[12] |\r\n * | data[1] | data[5] | data[9] | data[13] |\r\n * | data[2] | data[6] | data[10] | data[14] |\r\n * | data[3] | data[7] | data[11] | data[15] |\r\n *\r\n */\r\n public data: Float32Array = new Float32Array(16);\r\n\r\n /**\r\n * Creates an orthographic (flat non-perspective) projection\r\n * https://en.wikipedia.org/wiki/Orthographic_projection\r\n * @param left\r\n * @param right\r\n * @param bottom\r\n * @param top\r\n * @param near\r\n * @param far\r\n */\r\n public static ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix {\r\n const mat = new Matrix();\r\n mat.data[0] = 2 / (right - left);\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 2 / (top - bottom);\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = -2 / (far - near);\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = -(right + left) / (right - left);\r\n mat.data[13] = -(top + bottom) / (top - bottom);\r\n mat.data[14] = -(far + near) / (far - near);\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */\r\n public clone(dest?: Matrix): Matrix {\r\n const mat = dest || new Matrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = this.data[2];\r\n mat.data[3] = this.data[3];\r\n\r\n mat.data[4] = this.data[4];\r\n mat.data[5] = this.data[5];\r\n mat.data[6] = this.data[6];\r\n mat.data[7] = this.data[7];\r\n\r\n mat.data[8] = this.data[8];\r\n mat.data[9] = this.data[9];\r\n mat.data[10] = this.data[10];\r\n mat.data[11] = this.data[11];\r\n\r\n mat.data[12] = this.data[12];\r\n mat.data[13] = this.data[13];\r\n mat.data[14] = this.data[14];\r\n mat.data[15] = this.data[15];\r\n return mat;\r\n }\r\n\r\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */\r\n public toDOMMatrix(): DOMMatrix {\r\n return new DOMMatrix([...this.data]);\r\n }\r\n\r\n public static fromFloat32Array(data: Float32Array) {\r\n const matrix = new Matrix();\r\n matrix.data = data;\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Creates a new identity matrix (a matrix that when applied does nothing)\r\n */\r\n public static identity(): Matrix {\r\n const mat = new Matrix();\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 1;\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = 0;\r\n mat.data[13] = 0;\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {Matrix} Current matrix as identity\r\n */\r\n public reset(): Matrix {\r\n const mat = this;\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 1;\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = 0;\r\n mat.data[13] = 0;\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */\r\n public static translation(x: number, y: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[12] = x;\r\n mat.data[13] = y;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */\r\n public static scale(sx: number, sy: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[0] = sx;\r\n mat.data[5] = sy;\r\n mat.data[10] = 1;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */\r\n public static rotation(angleRadians: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[0] = Math.cos(angleRadians);\r\n mat.data[4] = -Math.sin(angleRadians);\r\n mat.data[1] = Math.sin(angleRadians);\r\n mat.data[5] = Math.cos(angleRadians);\r\n return mat;\r\n }\r\n\r\n /**\r\n * Multiply the current matrix by a vector producing a new vector\r\n * @param vector\r\n * @param dest\r\n */\r\n multiply(vector: Vector, dest?: Vector): Vector;\r\n /**\r\n * Multiply the current matrix by another matrix producing a new matrix\r\n * @param matrix\r\n * @param dest\r\n */\r\n multiply(matrix: Matrix, dest?: Matrix): Matrix;\r\n multiply(vectorOrMatrix: Vector | Matrix, dest?: Vector | Matrix): Vector | Matrix {\r\n if (vectorOrMatrix instanceof Vector) {\r\n const result = (dest as Vector) || new Vector(0, 0);\r\n const vector = vectorOrMatrix;\r\n // these shenanigans are to allow dest and vector to be the same instance\r\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\r\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\r\n\r\n result.x = resultX;\r\n result.y = resultY;\r\n return result;\r\n } else {\r\n const result = (dest as Matrix) || new Matrix();\r\n const other = vectorOrMatrix;\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const a13 = this.data[8];\r\n const a23 = this.data[9];\r\n const a33 = this.data[10];\r\n const a43 = this.data[11];\r\n\r\n const a14 = this.data[12];\r\n const a24 = this.data[13];\r\n const a34 = this.data[14];\r\n const a44 = this.data[15];\r\n\r\n const b11 = other.data[0];\r\n const b21 = other.data[1];\r\n const b31 = other.data[2];\r\n const b41 = other.data[3];\r\n\r\n const b12 = other.data[4];\r\n const b22 = other.data[5];\r\n const b32 = other.data[6];\r\n const b42 = other.data[7];\r\n\r\n const b13 = other.data[8];\r\n const b23 = other.data[9];\r\n const b33 = other.data[10];\r\n const b43 = other.data[11];\r\n\r\n const b14 = other.data[12];\r\n const b24 = other.data[13];\r\n const b34 = other.data[14];\r\n const b44 = other.data[15];\r\n\r\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\r\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\r\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\r\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\r\n\r\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\r\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\r\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\r\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\r\n\r\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\r\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\r\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\r\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\r\n\r\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\r\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\r\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\r\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\r\n\r\n const s = this.getScale();\r\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\r\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\r\n\r\n return result;\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const a13 = this.data[8];\r\n const a23 = this.data[9];\r\n const a33 = this.data[10];\r\n const a43 = this.data[11];\r\n\r\n const a14 = this.data[12];\r\n const a24 = this.data[13];\r\n const a34 = this.data[14];\r\n const a44 = this.data[15];\r\n\r\n // Doesn't change z\r\n const z = 0;\r\n const w = 1;\r\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\r\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\r\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\r\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\r\n\r\n return this;\r\n }\r\n\r\n public setPosition(x: number, y: number) {\r\n this.data[12] = x;\r\n this.data[13] = y;\r\n }\r\n\r\n public getPosition(): Vector {\r\n return vec(this.data[12], this.data[13]);\r\n }\r\n\r\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */\r\n rotate(angle: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * a11 + sine * a12;\r\n this.data[1] = cosine * a21 + sine * a22;\r\n this.data[2] = cosine * a31 + sine * a32;\r\n this.data[3] = cosine * a41 + sine * a42;\r\n\r\n this.data[4] = cosine * a12 - sine * a11;\r\n this.data[5] = cosine * a22 - sine * a21;\r\n this.data[6] = cosine * a32 - sine * a31;\r\n this.data[7] = cosine * a42 - sine * a41;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n this.data[0] = a11 * x;\r\n this.data[1] = a21 * x;\r\n this.data[2] = a31 * x;\r\n this.data[3] = a41 * x;\r\n\r\n this.data[4] = a12 * y;\r\n this.data[5] = a22 * y;\r\n this.data[6] = a32 * y;\r\n this.data[7] = a42 * y;\r\n\r\n return this;\r\n }\r\n\r\n public setRotation(angle: number) {\r\n const currentScale = this.getScale();\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * currentScale.x;\r\n this.data[1] = sine * currentScale.y;\r\n this.data[4] = -sine * currentScale.x;\r\n this.data[5] = cosine * currentScale.y;\r\n }\r\n\r\n public getRotation(): number {\r\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\r\n return canonicalizeAngle(angle);\r\n }\r\n\r\n public getScaleX(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const xscale = vec(this.data[0], this.data[4]).size;\r\n return this._scaleSignX * xscale;\r\n }\r\n\r\n public getScaleY(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const yscale = vec(this.data[1], this.data[5]).size;\r\n return this._scaleSignY * yscale;\r\n }\r\n\r\n /**\r\n * Get the scale of the matrix\r\n */\r\n public getScale(): Vector {\r\n return vec(this.getScaleX(), this.getScaleY());\r\n }\r\n\r\n private _scaleX = 1;\r\n private _scaleSignX = 1;\r\n public setScaleX(val: number) {\r\n if (this._scaleX === val) {\r\n return;\r\n }\r\n\r\n this._scaleSignX = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\r\n this.data[0] = xscale.x * val;\r\n this.data[4] = xscale.y * val;\r\n this._scaleX = val;\r\n }\r\n\r\n private _scaleY = 1;\r\n private _scaleSignY = 1;\r\n public setScaleY(val: number) {\r\n if (this._scaleY === val) {\r\n return;\r\n }\r\n this._scaleSignY = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\r\n this.data[1] = yscale.x * val;\r\n this.data[5] = yscale.y * val;\r\n this._scaleY = val;\r\n }\r\n\r\n public setScale(scale: Vector) {\r\n this.setScaleX(scale.x);\r\n this.setScaleY(scale.y);\r\n }\r\n\r\n /**\r\n * Determinant of the upper left 2x2 matrix\r\n */\r\n public getBasisDeterminant() {\r\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\r\n }\r\n\r\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */\r\n public getAffineInverse(target?: Matrix): Matrix {\r\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\r\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\r\n // Since we are actually only doing 2D transformations we can use this hack\r\n // We don't actually use the 3rd or 4th dimension\r\n\r\n const det = this.getBasisDeterminant();\r\n const inverseDet = 1 / det; // todo zero check\r\n const a = this.data[0];\r\n const b = this.data[4];\r\n const c = this.data[1];\r\n const d = this.data[5];\r\n\r\n const m = target || Matrix.identity();\r\n // inverts rotation and scale\r\n m.data[0] = d * inverseDet;\r\n m.data[1] = -c * inverseDet;\r\n m.data[4] = -b * inverseDet;\r\n m.data[5] = a * inverseDet;\r\n\r\n const tx = this.data[12];\r\n const ty = this.data[13];\r\n // invert translation\r\n // transform translation into the matrix basis created by rot/scale\r\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\r\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\r\n\r\n return m;\r\n }\r\n\r\n public isIdentity(): boolean {\r\n return (\r\n this.data[0] === 1 &&\r\n this.data[1] === 0 &&\r\n this.data[2] === 0 &&\r\n this.data[3] === 0 &&\r\n this.data[4] === 0 &&\r\n this.data[5] === 1 &&\r\n this.data[6] === 0 &&\r\n this.data[7] === 0 &&\r\n this.data[8] === 0 &&\r\n this.data[9] === 0 &&\r\n this.data[10] === 1 &&\r\n this.data[11] === 0 &&\r\n this.data[12] === 0 &&\r\n this.data[13] === 0 &&\r\n this.data[14] === 0 &&\r\n this.data[15] === 1\r\n );\r\n }\r\n\r\n public toString() {\r\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\r\n }\r\n}\r\n","import { Matrix } from './matrix';\r\nimport { canonicalizeAngle, sign } from './util';\r\nimport { vec, Vector } from './vector';\r\n\r\n\r\nexport class AffineMatrix {\r\n /**\r\n * | | | |\r\n * | ------- | ------- | -------- |\r\n * | data[0] | data[2] | data[4] |\r\n * | data[1] | data[3] | data[5] |\r\n * | 0 | 0 | 1 |\r\n */\r\n public data = new Float64Array(6);\r\n\r\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */\r\n public toDOMMatrix(): DOMMatrix {\r\n return new DOMMatrix([...this.data]);\r\n }\r\n\r\n public static identity(): AffineMatrix {\r\n const mat = new AffineMatrix();\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n\r\n mat.data[2] = 0;\r\n mat.data[3] = 1;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 0;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */\r\n public static translation(x: number, y: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[4] = x;\r\n mat.data[5] = y;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */\r\n public static scale(sx: number, sy: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[0] = sx;\r\n mat.data[3] = sy;\r\n mat._scale[0] = sx;\r\n mat._scale[1] = sy;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */\r\n public static rotation(angleRadians: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[0] = Math.cos(angleRadians);\r\n mat.data[1] = Math.sin(angleRadians);\r\n mat.data[2] = -Math.sin(angleRadians);\r\n mat.data[3] = Math.cos(angleRadians);\r\n return mat;\r\n }\r\n\r\n public setPosition(x: number, y: number) {\r\n this.data[4] = x;\r\n this.data[5] = y;\r\n }\r\n\r\n public getPosition(): Vector {\r\n return vec(this.data[4], this.data[5]);\r\n }\r\n\r\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */\r\n rotate(angle: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * a11 + sine * a12;\r\n this.data[1] = cosine * a21 + sine * a22;\r\n\r\n this.data[2] = cosine * a12 - sine * a11;\r\n this.data[3] = cosine * a22 - sine * a21;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n // const a31 = 0;\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n // const a32 = 0;\r\n\r\n const a13 = this.data[4];\r\n const a23 = this.data[5];\r\n // const a33 = 1;\r\n\r\n // Doesn't change z\r\n this.data[4] = a11 * x + a12 * y + a13;\r\n this.data[5] = a21 * x + a22 * y + a23;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n\r\n this.data[0] = a11 * x;\r\n this.data[1] = a21 * x;\r\n\r\n this.data[2] = a12 * y;\r\n this.data[3] = a22 * y;\r\n\r\n this._scale[0] = x;\r\n this._scale[1] = y;\r\n return this;\r\n }\r\n\r\n public determinant() {\r\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\r\n }\r\n\r\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */\r\n public inverse(target?: AffineMatrix): AffineMatrix {\r\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\r\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\r\n // Since we are actually only doing 2D transformations we can use this hack\r\n // We don't actually use the 3rd or 4th dimension\r\n\r\n const det = this.determinant();\r\n const inverseDet = 1 / det; // TODO zero check\r\n const a = this.data[0];\r\n const b = this.data[2];\r\n const c = this.data[1];\r\n const d = this.data[3];\r\n\r\n const m = target || AffineMatrix.identity();\r\n // inverts rotation and scale\r\n m.data[0] = d * inverseDet;\r\n m.data[1] = -c * inverseDet;\r\n m.data[2] = -b * inverseDet;\r\n m.data[3] = a * inverseDet;\r\n\r\n const tx = this.data[4];\r\n const ty = this.data[5];\r\n // invert translation\r\n // transform translation into the matrix basis created by rot/scale\r\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\r\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\r\n\r\n return m;\r\n }\r\n\r\n /**\r\n * Multiply the current matrix by a vector producing a new vector\r\n * @param vector\r\n * @param dest\r\n */\r\n multiply(vector: Vector, dest?: Vector): Vector;\r\n /**\r\n * Multiply the current matrix by another matrix producing a new matrix\r\n * @param matrix\r\n * @param dest\r\n */\r\n multiply(matrix: AffineMatrix, dest?: AffineMatrix): AffineMatrix;\r\n multiply(vectorOrMatrix: Vector | AffineMatrix, dest?: Vector | AffineMatrix): Vector | AffineMatrix {\r\n if (vectorOrMatrix instanceof Vector) {\r\n const result = (dest as Vector) || new Vector(0, 0);\r\n const vector = vectorOrMatrix;\r\n // these shenanigans are to allow dest and vector to be the same instance\r\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\r\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\r\n\r\n result.x = resultX;\r\n result.y = resultY;\r\n return result;\r\n } else {\r\n const result = (dest as AffineMatrix) || new AffineMatrix();\r\n const other = vectorOrMatrix;\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n // const a31 = 0;\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n // const a32 = 0;\r\n\r\n const a13 = this.data[4];\r\n const a23 = this.data[5];\r\n // const a33 = 1;\r\n\r\n const b11 = other.data[0];\r\n const b21 = other.data[1];\r\n // const b31 = 0;\r\n\r\n const b12 = other.data[2];\r\n const b22 = other.data[3];\r\n // const b32 = 0;\r\n\r\n const b13 = other.data[4];\r\n const b23 = other.data[5];\r\n // const b33 = 1;\r\n\r\n\r\n result.data[0] = a11 * b11 + a12 * b21;// + a13 * b31; // zero\r\n result.data[1] = a21 * b11 + a22 * b21;// + a23 * b31; // zero\r\n\r\n result.data[2] = a11 * b12 + a12 * b22;// + a13 * b32; // zero\r\n result.data[3] = a21 * b12 + a22 * b22;// + a23 * b32; // zero\r\n\r\n result.data[4] = a11 * b13 + a12 * b23 + a13;// * b33; // one\r\n result.data[5] = a21 * b13 + a22 * b23 + a23;// * b33; // one\r\n\r\n const s = this.getScale();\r\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\r\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\r\n\r\n return result;\r\n }\r\n }\r\n\r\n to4x4() {\r\n const mat = new Matrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = this.data[2];\r\n mat.data[5] = this.data[3];\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = this.data[4];\r\n mat.data[13] = this.data[5];\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n public setRotation(angle: number) {\r\n const currentScale = this.getScale();\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * currentScale.x;\r\n this.data[1] = sine * currentScale.y;\r\n this.data[2] = -sine * currentScale.x;\r\n this.data[3] = cosine * currentScale.y;\r\n }\r\n\r\n public getRotation(): number {\r\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\r\n return canonicalizeAngle(angle);\r\n }\r\n\r\n public getScaleX(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const xscale = vec(this.data[0], this.data[2]).distance();\r\n return this._scaleSignX * xscale;\r\n }\r\n\r\n public getScaleY(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const yscale = vec(this.data[1], this.data[3]).distance();\r\n return this._scaleSignY * yscale;\r\n }\r\n\r\n /**\r\n * Get the scale of the matrix\r\n */\r\n public getScale(): Vector {\r\n return vec(this.getScaleX(), this.getScaleY());\r\n }\r\n\r\n private _scale = new Float64Array([1, 1]);\r\n private _scaleSignX = 1;\r\n public setScaleX(val: number) {\r\n if (val === this._scale[0]) {\r\n return;\r\n }\r\n this._scaleSignX = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\r\n this.data[0] = xscale.x * val;\r\n this.data[2] = xscale.y * val;\r\n this._scale[0] = val;\r\n }\r\n\r\n private _scaleSignY = 1;\r\n public setScaleY(val: number) {\r\n if (val === this._scale[1]) {\r\n return;\r\n }\r\n this._scaleSignY = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\r\n this.data[1] = yscale.x * val;\r\n this.data[3] = yscale.y * val;\r\n this._scale[1] = val;\r\n }\r\n\r\n public setScale(scale: Vector) {\r\n this.setScaleX(scale.x);\r\n this.setScaleY(scale.y);\r\n }\r\n\r\n public isIdentity(): boolean {\r\n return (\r\n this.data[0] === 1 &&\r\n this.data[1] === 0 &&\r\n this.data[2] === 0 &&\r\n this.data[3] === 1 &&\r\n this.data[4] === 0 &&\r\n this.data[5] === 0\r\n );\r\n }\r\n\r\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {AffineMatrix} Current matrix as identity\r\n */\r\n public reset(): AffineMatrix {\r\n const mat = this;\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n\r\n mat.data[2] = 0;\r\n mat.data[3] = 1;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 0;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */\r\n public clone(dest?: AffineMatrix): AffineMatrix {\r\n const mat = dest || new AffineMatrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n\r\n mat.data[2] = this.data[2];\r\n mat.data[3] = this.data[3];\r\n\r\n mat.data[4] = this.data[4];\r\n mat.data[5] = this.data[5];\r\n return mat;\r\n }\r\n\r\n public toString() {\r\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\r\n }\r\n\r\n}","import { AffineMatrix } from '../../Math/affine-matrix';\r\n\r\nexport class TransformStack {\r\n private _transforms: AffineMatrix[] = [];\r\n private _currentTransform: AffineMatrix = AffineMatrix.identity();\r\n\r\n public save(): void {\r\n this._transforms.push(this._currentTransform);\r\n this._currentTransform = this._currentTransform.clone();\r\n }\r\n\r\n public restore(): void {\r\n this._currentTransform = this._transforms.pop();\r\n }\r\n\r\n public translate(x: number, y: number): AffineMatrix {\r\n return this._currentTransform.translate(x, y);\r\n }\r\n\r\n public rotate(angle: number): AffineMatrix {\r\n return this._currentTransform.rotate(angle);\r\n }\r\n\r\n public scale(x: number, y: number): AffineMatrix {\r\n return this._currentTransform.scale(x, y);\r\n }\r\n\r\n public set current(matrix: AffineMatrix) {\r\n this._currentTransform = matrix;\r\n }\r\n\r\n public get current(): AffineMatrix {\r\n return this._currentTransform;\r\n }\r\n}\r\n","import { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContextState } from './ExcaliburGraphicsContext';\r\nimport { Material } from './material';\r\n\r\nexport class StateStack {\r\n private _states: ExcaliburGraphicsContextState[] = [];\r\n private _currentState: ExcaliburGraphicsContextState = this._getDefaultState();\r\n\r\n private _getDefaultState() {\r\n return {\r\n opacity: 1,\r\n z: 0,\r\n tint: Color.White,\r\n material: null as Material\r\n };\r\n }\r\n\r\n private _cloneState() {\r\n return {\r\n opacity: this._currentState.opacity,\r\n z: this._currentState.z,\r\n tint: this._currentState.tint.clone(),\r\n material: this._currentState.material // TODO is this going to cause problems when cloning\r\n };\r\n }\r\n\r\n public save(): void {\r\n this._states.push(this._currentState);\r\n this._currentState = this._cloneState();\r\n }\r\n\r\n public restore(): void {\r\n this._currentState = this._states.pop();\r\n }\r\n\r\n public get current(): ExcaliburGraphicsContextState {\r\n return this._currentState;\r\n }\r\n\r\n public set current(val: ExcaliburGraphicsContextState) {\r\n this._currentState = val;\r\n }\r\n}\r\n","import { Loadable } from '../Interfaces/Loadable';\r\nimport { Logger } from '../Util/Log';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport type ResourceEvents = {\r\n complete: any,\r\n load: ProgressEvent,\r\n loadstart: ProgressEvent,\r\n progress: ProgressEvent,\r\n error: ProgressEvent\r\n}\r\n\r\nexport const ResourceEvents = {\r\n Complete: 'complete',\r\n Load: 'load',\r\n LoadStart: 'loadstart',\r\n Progress: 'progress',\r\n Error: 'error'\r\n};\r\n\r\n/**\r\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\r\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\r\n */\r\nexport class Resource implements Loadable {\r\n public data: T = null;\r\n public logger: Logger = Logger.getInstance();\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * @param path Path to the remote resource\r\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\r\n * @param bustCache Whether or not to cache-bust requests\r\n */\r\n constructor(\r\n public path: string,\r\n public responseType: '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text',\r\n public bustCache: boolean = false\r\n ) {}\r\n\r\n /**\r\n * Returns true if the Resource is completely loaded and is ready\r\n * to be drawn.\r\n */\r\n public isLoaded(): boolean {\r\n return this.data !== null;\r\n }\r\n\r\n\r\n private _cacheBust(uri: string): string {\r\n const query: RegExp = /\\?\\w*=\\w*/;\r\n if (query.test(uri)) {\r\n uri += '&__=' + Date.now();\r\n } else {\r\n uri += '?__=' + Date.now();\r\n }\r\n return uri;\r\n }\r\n /**\r\n * Begin loading the resource and returns a promise to be resolved on completion\r\n */\r\n public load(): Promise {\r\n return new Promise((resolve, reject) => {\r\n // Exit early if we already have data\r\n if (this.data !== null) {\r\n this.logger.debug('Already have data for resource', this.path);\r\n this.events.emit('complete', this.data as any);\r\n resolve(this.data);\r\n return;\r\n }\r\n\r\n const request = new XMLHttpRequest();\r\n request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true);\r\n request.responseType = this.responseType;\r\n request.addEventListener('loadstart', (e) => this.events.emit('loadstart', e as any));\r\n request.addEventListener('progress', (e) => this.events.emit('progress', e as any));\r\n request.addEventListener('error', (e) => this.events.emit('error', e as any));\r\n request.addEventListener('load', (e) => this.events.emit('load', e as any));\r\n request.addEventListener('load', () => {\r\n // XHR on file:// success status is 0, such as with PhantomJS\r\n if (request.status !== 0 && request.status !== 200) {\r\n this.logger.error('Failed to load resource ', this.path, ' server responded with error code', request.status);\r\n this.events.emit('error', request.response);\r\n reject(new Error(request.statusText));\r\n return;\r\n }\r\n\r\n this.data = request.response;\r\n this.events.emit('complete', this.data as any);\r\n this.logger.debug('Completed loading resource', this.path);\r\n resolve(this.data);\r\n });\r\n request.send();\r\n });\r\n }\r\n}\r\n","/**\r\n * Watch an object with a proxy, only fires if property value is different\r\n */\r\nexport function watch(type: T, change: (type: T) => any): T {\r\n if (!type) {\r\n return type;\r\n }\r\n if ((type as any).__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, {\r\n set: (obj, prop, value) => {\r\n // The default behavior to store the value\r\n if ((obj as any)[prop] !== value) {\r\n (obj as any)[prop] = value;\r\n // Avoid watching private junk\r\n if (typeof prop === 'string') {\r\n if (prop[0] !== '_') {\r\n change(obj);\r\n }\r\n }\r\n }\r\n // Indicate success\r\n return true;\r\n },\r\n get: (obj, prop) => {\r\n if (prop !== '__isProxy') {\r\n return (obj as any)[prop];\r\n }\r\n return true;\r\n }\r\n });\r\n }\r\n return type;\r\n}\r\n\r\nconst createHandler = (path: string[] = [], change: (type: T) => any, typeType: T) => ({\r\n get: (target: T, key: string): any => {\r\n if (key === '__isProxy') {\r\n return true;\r\n }\r\n if (typeof (target as any)[key] === 'object' && (target as any)[key] != null) {\r\n return new Proxy(\r\n (target as any)[key],\r\n createHandler([...path, key as string], change, typeType)\r\n );\r\n }\r\n return (target as any)[key];\r\n },\r\n set: (target: T, key: string, value: any) => {\r\n if (typeof key === 'string') {\r\n if (key[0] !== '_') {\r\n change(typeType);\r\n }\r\n }\r\n (target as any)[key] = value;\r\n return true;\r\n }\r\n});\r\n\r\n/**\r\n *\r\n */\r\nexport function watchDeep(type: T, change: (type: T) => any): T {\r\n if (!type) {\r\n return type;\r\n }\r\n if ((type as any).__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, createHandler([], change, type));\r\n }\r\n return type;\r\n}\r\n\r\n/**\r\n * Watch an object with a proxy, fires change on any property value change\r\n */\r\nexport function watchAny(type: T, change: (type: T) => any): T {\r\n if (!type) {\r\n return type;\r\n }\r\n if ((type as any).__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, {\r\n set: (obj, prop, value) => {\r\n // The default behavior to store the value\r\n (obj as any)[prop] = value;\r\n // Avoid watching private junk\r\n if (typeof prop === 'string') {\r\n if (prop[0] !== '_') {\r\n change(obj);\r\n }\r\n }\r\n\r\n // Indicate success\r\n return true;\r\n },\r\n get: (obj, prop) => {\r\n if (prop !== '__isProxy') {\r\n return (obj as any)[prop];\r\n }\r\n return true;\r\n }\r\n });\r\n }\r\n return type;\r\n}\r\n","import { Vector, vec } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { watch } from '../Util/Watch';\r\nimport { AffineMatrix } from '../Math/affine-matrix';\r\n\r\nexport interface GraphicOptions {\r\n /**\r\n * The width of the graphic\r\n */\r\n width?: number;\r\n /**\r\n * The height of the graphic\r\n */\r\n height?: number;\r\n /**\r\n * Should the graphic be flipped horizontally\r\n */\r\n flipHorizontal?: boolean;\r\n /**\r\n * Should the graphic be flipped vertically\r\n */\r\n flipVertical?: boolean;\r\n /**\r\n * The rotation of the graphic\r\n */\r\n rotation?: number;\r\n /**\r\n * The scale of the graphic\r\n */\r\n scale?: Vector;\r\n /**\r\n * The opacity of the graphic between (0 -1)\r\n */\r\n opacity?: number;\r\n /**\r\n * The tint of the graphic, this color will be multiplied by the original pixel colors\r\n */\r\n tint?: Color;\r\n /**\r\n * The origin of the drawing in pixels to use when applying transforms, by default it will be the center of the image in pixels\r\n */\r\n origin?: Vector;\r\n}\r\n\r\n/**\r\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\r\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\r\n * [[Graphic]] abstract class.\r\n *\r\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\r\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\r\n */\r\nexport abstract class Graphic {\r\n private static _ID: number = 0;\r\n readonly id = Graphic._ID++;\r\n\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public tint: Color = null;\r\n\r\n private _transformStale = true;\r\n public isStale() {\r\n return this._transformStale;\r\n }\r\n\r\n /**\r\n * Gets or sets wether to show debug information about the graphic\r\n */\r\n public showDebug: boolean = false;\r\n\r\n\r\n private _flipHorizontal = false;\r\n /**\r\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\r\n */\r\n public get flipHorizontal(): boolean {\r\n return this._flipHorizontal;\r\n }\r\n\r\n public set flipHorizontal(value: boolean) {\r\n this._flipHorizontal = value;\r\n this._transformStale = true;\r\n }\r\n\r\n private _flipVertical = false;\r\n /**\r\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\r\n */\r\n public get flipVertical(): boolean {\r\n return this._flipVertical;\r\n }\r\n\r\n public set flipVertical(value: boolean) {\r\n this._flipVertical = value;\r\n this._transformStale = true;\r\n }\r\n\r\n private _rotation = 0;\r\n /**\r\n * Gets or sets the rotation of the graphic\r\n */\r\n public get rotation(): number {\r\n return this._rotation;\r\n }\r\n\r\n public set rotation(value: number) {\r\n this._rotation = value;\r\n this._transformStale = true;\r\n }\r\n\r\n /**\r\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\r\n */\r\n public opacity: number = 1;\r\n\r\n private _scale = Vector.One;\r\n /**\r\n * Gets or sets the scale of the graphic, this affects the width and\r\n */\r\n public get scale() {\r\n return this._scale;\r\n }\r\n\r\n public set scale(value: Vector) {\r\n this._scale = watch(value, () => {\r\n this._transformStale = true;\r\n });\r\n this._transformStale = true;\r\n }\r\n\r\n private _origin: Vector | null = null;\r\n /**\r\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\r\n */\r\n public get origin(): Vector | null {\r\n return this._origin;\r\n }\r\n\r\n public set origin(value: Vector | null) {\r\n this._origin = watch(value, () => {\r\n this._transformStale = true;\r\n });\r\n this._transformStale = true;\r\n }\r\n\r\n constructor(options?: GraphicOptions) {\r\n if (options) {\r\n this.origin = options.origin ?? this.origin;\r\n this.flipHorizontal = options.flipHorizontal ?? this.flipHorizontal;\r\n this.flipVertical = options.flipVertical ?? this.flipVertical;\r\n this.rotation = options.rotation ?? this.rotation;\r\n this.opacity = options.opacity ?? this.opacity;\r\n this.scale = options.scale ?? this.scale;\r\n this.tint = options.tint ?? this.tint;\r\n }\r\n }\r\n\r\n public cloneGraphicOptions(): GraphicOptions {\r\n return {\r\n width: this.width / this.scale.x,\r\n height: this.height / this.scale.y,\r\n origin: this.origin ? this.origin.clone() : null,\r\n flipHorizontal: this.flipHorizontal,\r\n flipVertical: this.flipVertical,\r\n rotation: this.rotation,\r\n opacity: this.opacity,\r\n scale: this.scale ? this.scale.clone() : null,\r\n tint: this.tint ? this.tint.clone(): null\r\n };\r\n }\r\n\r\n private _width: number = 0;\r\n\r\n /**\r\n * Gets or sets the width of the graphic (always positive)\r\n */\r\n public get width() {\r\n return Math.abs(this._width * this.scale.x);\r\n }\r\n\r\n private _height: number = 0;\r\n\r\n /**\r\n * Gets or sets the height of the graphic (always positive)\r\n */\r\n public get height() {\r\n return Math.abs(this._height * this.scale.y);\r\n }\r\n\r\n public set width(value: number) {\r\n this._width = value;\r\n this._transformStale = true;\r\n }\r\n\r\n public set height(value: number) {\r\n this._height = value;\r\n this._transformStale = true;\r\n }\r\n\r\n /**\r\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\r\n */\r\n public get localBounds(): BoundingBox {\r\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\r\n }\r\n\r\n /**\r\n * Draw the whole graphic to the context including transform\r\n * @param ex The excalibur graphics context\r\n * @param x\r\n * @param y\r\n */\r\n public draw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0);\r\n this._postDraw(ex);\r\n }\r\n\r\n /**\r\n * Meant to be overridden by the graphic implementation to draw the underlying image (HTMLCanvasElement or HTMLImageElement)\r\n * to the graphics context without transform. Transformations like position, rotation, and scale are handled by [[Graphic._preDraw]]\r\n * and [[Graphic._postDraw]]\r\n * @param ex The excalibur graphics context\r\n * @param x\r\n * @param y\r\n */\r\n protected abstract _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number): void;\r\n\r\n /**\r\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\r\n * @param ex\r\n * @param x\r\n * @param y\r\n */\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n ex.save();\r\n ex.translate(x, y);\r\n if (this._transformStale) {\r\n this.transform.reset();\r\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\r\n this._rotate(this.transform);\r\n this._flip(this.transform);\r\n this._transformStale = false;\r\n }\r\n ex.multiply(this.transform);\r\n // it is important to multiply alphas so graphics respect the current context\r\n ex.opacity = ex.opacity * this.opacity;\r\n if (this.tint) {\r\n ex.tint = this.tint;\r\n }\r\n }\r\n\r\n protected _rotate(ex: ExcaliburGraphicsContext | AffineMatrix) {\r\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\r\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\r\n const origin = this.origin ?? vec(this.width / 2, this.height / 2);\r\n ex.translate(origin.x, origin.y);\r\n ex.rotate(this.rotation);\r\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\r\n ex.scale(scaleDirX, scaleDirY);\r\n ex.translate(-origin.x, -origin.y);\r\n }\r\n\r\n protected _flip(ex: ExcaliburGraphicsContext | AffineMatrix) {\r\n if (this.flipHorizontal) {\r\n ex.translate(this.width / this.scale.x, 0);\r\n ex.scale(-1, 1);\r\n }\r\n\r\n if (this.flipVertical) {\r\n ex.translate(0, this.height / this.scale.y);\r\n ex.scale(1, -1);\r\n }\r\n }\r\n\r\n /**\r\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\r\n * @param ex\r\n */\r\n protected _postDraw(ex: ExcaliburGraphicsContext): void {\r\n if (this.showDebug) {\r\n ex.debug.drawRect(0, 0, this.width, this.height);\r\n }\r\n ex.restore();\r\n }\r\n\r\n /**\r\n * Returns a new instance of the graphic that has the same properties\r\n */\r\n abstract clone(): Graphic;\r\n}\r\n","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ImageSource } from './ImageSource';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport type SourceView = { x: number; y: number; width: number; height: number };\r\nexport type DestinationSize = { width: number; height: number };\r\n\r\nexport interface SpriteOptions {\r\n /**\r\n * Image to create a sprite from\r\n */\r\n image: ImageSource;\r\n /**\r\n * By default the source is the entire dimension of the [[ImageSource]]\r\n */\r\n sourceView?: { x: number; y: number; width: number; height: number };\r\n /**\r\n * By default the size of the final sprite is the size of the [[ImageSource]]\r\n */\r\n destSize?: { width: number; height: number };\r\n}\r\n\r\nexport class Sprite extends Graphic {\r\n private _logger = Logger.getInstance();\r\n public image: ImageSource;\r\n public sourceView: SourceView;\r\n public destSize: DestinationSize;\r\n private _dirty = true;\r\n\r\n public static from(image: ImageSource): Sprite {\r\n return new Sprite({\r\n image: image\r\n });\r\n }\r\n\r\n constructor(options: GraphicOptions & SpriteOptions) {\r\n super(options);\r\n this.image = options.image;\r\n const { width, height } = options;\r\n this.sourceView = options.sourceView ?? { x: 0, y: 0, width: width ?? 0, height: height ?? 0 };\r\n this.destSize = options.destSize ?? { width: width ?? 0, height: height ?? 0 };\r\n this._updateSpriteDimensions();\r\n // Fire when loaded\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.image.ready.then(() => {\r\n this._updateSpriteDimensions();\r\n });\r\n }\r\n\r\n public override get width(): number {\r\n return Math.abs(this.destSize.width * this.scale.x);\r\n }\r\n\r\n public override get height(): number {\r\n return Math.abs(this.destSize.height * this.scale.y);\r\n }\r\n\r\n public override set width(newWidth: number) {\r\n newWidth /= Math.abs(this.scale.x);\r\n this.destSize.width = newWidth;\r\n super.width = Math.ceil(this.destSize.width);\r\n }\r\n\r\n public override set height(newHeight: number) {\r\n newHeight /= Math.abs(this.scale.y);\r\n this.destSize.height = newHeight;\r\n super.height = Math.ceil(this.destSize.height);\r\n }\r\n\r\n private _updateSpriteDimensions() {\r\n const { width: nativeWidth, height: nativeHeight } = this.image;\r\n // This code uses || to avoid 0's\r\n // If the source is not specified, use the native dimension\r\n this.sourceView.width = this.sourceView?.width || nativeWidth;\r\n this.sourceView.height = this.sourceView?.height || nativeHeight;\r\n\r\n // If the destination is not specified, use the source if specified, then native\r\n this.destSize.width = this.destSize?.width || this.sourceView?.width || nativeWidth;\r\n this.destSize.height = this.destSize?.height || this.sourceView?.height || nativeHeight;\r\n\r\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\r\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\r\n }\r\n\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.image.isLoaded() && this._dirty) {\r\n this._dirty = false;\r\n this._updateSpriteDimensions();\r\n }\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n public _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.image.isLoaded()) {\r\n ex.drawImage(\r\n this.image.image,\r\n this.sourceView.x,\r\n this.sourceView.y,\r\n this.sourceView.width,\r\n this.sourceView.height,\r\n x,\r\n y,\r\n this.destSize.width,\r\n this.destSize.height\r\n );\r\n } else {\r\n this._logger.warnOnce(\r\n `ImageSource ${this.image.path}` +\r\n ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` +\r\n `Read https://excaliburjs.com/docs/imagesource for more information.`\r\n );\r\n }\r\n }\r\n\r\n public clone(): Sprite {\r\n return new Sprite({\r\n image: this.image,\r\n sourceView: { ...this.sourceView },\r\n destSize: { ...this.destSize },\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n}\r\n","\r\n/**\r\n * Describes the different image filtering modes\r\n */\r\nexport enum ImageFiltering {\r\n\r\n /**\r\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\r\n *\r\n * Useful for Pixel art aesthetics.\r\n */\r\n Pixel = 'Pixel',\r\n\r\n /**\r\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\r\n */\r\n Blended = 'Blended'\r\n}","import { Logger } from '../../Util/Log';\r\nimport { ImageFiltering } from '../Filtering';\r\nimport { HTMLImageSource } from './ExcaliburGraphicsContext';\r\n\r\n/**\r\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\r\n */\r\nexport class TextureLoader {\r\n private static _LOGGER = Logger.getInstance();\r\n\r\n constructor(gl: WebGL2RenderingContext) {\r\n this._gl = gl;\r\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\r\n }\r\n\r\n public dispose() {\r\n for (const [image] of this._textureMap) {\r\n this.delete(image);\r\n }\r\n this._textureMap.clear();\r\n this._gl = null;\r\n }\r\n\r\n /**\r\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\r\n */\r\n public static filtering: ImageFiltering = ImageFiltering.Blended;\r\n\r\n private _gl: WebGL2RenderingContext;\r\n\r\n private _textureMap = new Map();\r\n\r\n private static _MAX_TEXTURE_SIZE: number = 4096;\r\n\r\n /**\r\n * Get the WebGL Texture from a source image\r\n * @param image\r\n */\r\n public get(image: HTMLImageSource): WebGLTexture {\r\n return this._textureMap.get(image);\r\n }\r\n\r\n /**\r\n * Returns whether a source image has been loaded as a texture\r\n * @param image\r\n */\r\n public has(image: HTMLImageSource): boolean {\r\n return this._textureMap.has(image);\r\n }\r\n\r\n /**\r\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\r\n * @param image Source graphic\r\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\r\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\r\n */\r\n public load(image: HTMLImageSource, filtering?: ImageFiltering, forceUpdate = false): WebGLTexture {\r\n // Ignore loading if webgl is not registered\r\n const gl = this._gl;\r\n if (!gl) {\r\n return null;\r\n }\r\n\r\n let tex: WebGLTexture = null;\r\n // If reuse the texture if it's from the same source\r\n if (this.has(image)) {\r\n tex = this.get(image);\r\n }\r\n\r\n // Update existing webgl texture and return early\r\n if (tex) {\r\n if (forceUpdate) {\r\n gl.bindTexture(gl.TEXTURE_2D, tex);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\r\n }\r\n return tex;\r\n }\r\n\r\n // No texture exists create a new one\r\n tex = gl.createTexture();\r\n\r\n // TODO implement texture gc with weakmap and timer\r\n TextureLoader.checkImageSizeSupportedAndLog(image);\r\n\r\n gl.bindTexture(gl.TEXTURE_2D, tex);\r\n\r\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\r\n // TODO make configurable\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n // NEAREST for pixel art, LINEAR for hi-res\r\n const filterMode = filtering ?? TextureLoader.filtering;\r\n\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\r\n\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\r\n\r\n this._textureMap.set(image, tex);\r\n return tex;\r\n }\r\n\r\n public delete(image: HTMLImageSource): void {\r\n // Ignore loading if webgl is not registered\r\n const gl = this._gl;\r\n if (!gl) {\r\n return null;\r\n }\r\n\r\n let tex: WebGLTexture = null;\r\n if (this.has(image)) {\r\n tex = this.get(image);\r\n gl.deleteTexture(tex);\r\n }\r\n }\r\n\r\n /**\r\n * Takes an image and returns if it meets size criteria for hardware\r\n * @param image\r\n * @returns if the image will be supported at runtime\r\n */\r\n public static checkImageSizeSupportedAndLog(image: HTMLImageSource) {\r\n const originalSrc = image.dataset.originalSrc ?? 'internal canvas bitmap';\r\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\r\n TextureLoader._LOGGER.error(\r\n `The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of `+\r\n `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image `\r\n +`for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n`+\r\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\r\n return false;\r\n } else if (image.width > 4096 || image.height > 4096) {\r\n // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\r\n TextureLoader._LOGGER.warn(\r\n `The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, `+\r\n `it is recommended you resize images to a maximum (4096x4096).\\n\\n` +\r\n `Images will likely render as black rectangles on some mobile platforms.\\n\\n` +\r\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\r\n }\r\n return true;\r\n }\r\n}\r\n","import { Resource } from '../Resources/Resource';\r\nimport { Sprite } from './Sprite';\r\nimport { Loadable } from '../Interfaces/Index';\r\nimport { Logger } from '../Util/Log';\r\nimport { ImageFiltering } from './Filtering';\r\nimport { Future } from '../Util/Future';\r\nimport { TextureLoader } from '../Graphics/Context/texture-loader';\r\n\r\nexport interface ImageSourceOptions {\r\n filtering?: ImageFiltering;\r\n bustCache?: boolean;\r\n}\r\n\r\nexport class ImageSource implements Loadable {\r\n private _logger = Logger.getInstance();\r\n private _resource: Resource;\r\n public filtering: ImageFiltering;\r\n\r\n /**\r\n * The original size of the source image in pixels\r\n */\r\n public get width() {\r\n return this.image.naturalWidth;\r\n }\r\n\r\n /**\r\n * The original height of the source image in pixels\r\n */\r\n public get height() {\r\n return this.image.naturalHeight;\r\n }\r\n\r\n private _src: string;\r\n /**\r\n * Returns true if the Texture is completely loaded and is ready\r\n * to be drawn.\r\n */\r\n public isLoaded(): boolean {\r\n if (!this._src) {\r\n // this boosts speed of access\r\n this._src = this.data.src;\r\n }\r\n return !!this._src;\r\n }\r\n\r\n /**\r\n * Access to the underlying html image element\r\n */\r\n public data: HTMLImageElement = new Image();\r\n public get image(): HTMLImageElement {\r\n return this.data;\r\n }\r\n\r\n private _readyFuture = new Future();\r\n /**\r\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\r\n */\r\n public ready: Promise = this._readyFuture.promise;\r\n\r\n /**\r\n * The path to the image, can also be a data url like 'data:image/'\r\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\r\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\r\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\r\n */\r\n constructor(public readonly path: string, bustCache: boolean = false, filtering?: ImageFiltering) {\r\n this._resource = new Resource(path, 'blob', bustCache);\r\n this.filtering = filtering;\r\n if (path.endsWith('.svg') || path.endsWith('.gif')) {\r\n this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\r\n }\r\n }\r\n\r\n /**\r\n * Create an ImageSource from and HTML tag element\r\n * @param image\r\n */\r\n static fromHtmlImageElement(image: HTMLImageElement, options?: ImageSourceOptions) {\r\n const imageSource = new ImageSource('');\r\n imageSource._src = 'image-element';\r\n imageSource.data = image;\r\n imageSource.data.setAttribute('data-original-src', 'image-element');\r\n\r\n if (options?.filtering) {\r\n imageSource.data.setAttribute('filtering', options?.filtering);\r\n } else {\r\n imageSource.data.setAttribute('filtering', ImageFiltering.Blended);\r\n }\r\n\r\n TextureLoader.checkImageSizeSupportedAndLog(image);\r\n imageSource._readyFuture.resolve(image);\r\n return imageSource;\r\n }\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n /**\r\n * Begins loading the image and returns a promise that resolves when the image is loaded\r\n */\r\n async load(): Promise {\r\n if (this.isLoaded()) {\r\n return this.data;\r\n }\r\n try {\r\n // Load base64 or blob if needed\r\n let url: string;\r\n if (!this.path.includes('data:image/')) {\r\n const blob = await this._resource.load();\r\n url = URL.createObjectURL(blob);\r\n } else {\r\n url = this.path;\r\n }\r\n\r\n // Decode the image\r\n const image = new Image();\r\n // Use Image.onload over Image.decode()\r\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\r\n // Otherwise chrome will throw still Image.decode() failures for large textures\r\n const loadedFuture = new Future();\r\n image.onload = () => loadedFuture.resolve();\r\n image.src = url;\r\n image.setAttribute('data-original-src', this.path);\r\n\r\n await loadedFuture.promise;\r\n\r\n // Set results\r\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\r\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\r\n // See image-renderer.ts draw()\r\n this.data = image;\r\n\r\n // emit warning if potentially too big\r\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\r\n } catch (error) {\r\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\r\n }\r\n // Do a bad thing to pass the filtering as an attribute\r\n this.data.setAttribute('filtering', this.filtering);\r\n\r\n // todo emit complete\r\n this._readyFuture.resolve(this.data);\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Build a sprite from this ImageSource\r\n */\r\n public toSprite(): Sprite {\r\n return Sprite.from(this);\r\n }\r\n\r\n /**\r\n * Unload images from memory\r\n */\r\n unload(): void {\r\n this.data = new Image();\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Logger } from '../Util/Log';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { FontRenderer } from './FontCommon';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Sprite } from './Sprite';\r\nimport { SpriteSheet } from './SpriteSheet';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\n\r\nexport interface SpriteFontOptions {\r\n /**\r\n * Alphabet string in spritesheet order (default is row column order)\r\n * example: 'abcdefghijklmnopqrstuvwxyz'\r\n */\r\n alphabet: string;\r\n /**\r\n * [[SpriteSheet]] to source character sprites from\r\n */\r\n spriteSheet: SpriteSheet;\r\n /**\r\n * Optionally ignore case in the supplied text;\r\n */\r\n caseInsensitive?: boolean;\r\n /**\r\n * Optionally override the text line height, useful for multiline text. If unset will use default.\r\n */\r\n lineHeight?: number | undefined;\r\n /**\r\n * Optionally adjust the spacing between character sprites\r\n */\r\n spacing?: number;\r\n /**\r\n * Optionally specify a \"shadow\"\r\n */\r\n shadow?: { offset: Vector };\r\n}\r\n\r\nexport class SpriteFont extends Graphic implements FontRenderer {\r\n private _text: string = '';\r\n public alphabet: string = '';\r\n public spriteSheet: SpriteSheet;\r\n\r\n public shadow: { offset: Vector } = null;\r\n public caseInsensitive = false;\r\n public spacing: number = 0;\r\n public lineHeight: number | undefined = undefined;\r\n\r\n private _logger = Logger.getInstance();\r\n\r\n constructor(options: SpriteFontOptions & GraphicOptions) {\r\n super(options);\r\n const { alphabet, spriteSheet, caseInsensitive, spacing, shadow, lineHeight } = options;\r\n this.alphabet = alphabet;\r\n this.spriteSheet = spriteSheet;\r\n this.caseInsensitive = caseInsensitive ?? this.caseInsensitive;\r\n this.spacing = spacing ?? this.spacing;\r\n this.shadow = shadow ?? this.shadow;\r\n this.lineHeight = lineHeight ?? this.lineHeight;\r\n }\r\n\r\n private _getCharacterSprites(text: string): Sprite[] {\r\n const results: Sprite[] = [];\r\n // handle case insensitive\r\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\r\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\r\n\r\n // for each letter in text\r\n for (let letterIndex = 0; letterIndex < textToRender.length; letterIndex++) {\r\n // find the sprite index in alphabet , if there is an error pick the first\r\n const letter = textToRender[letterIndex];\r\n let spriteIndex = alphabet.indexOf(letter);\r\n if (spriteIndex === -1) {\r\n spriteIndex = 0;\r\n this._logger.warnOnce(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\r\n this._logger.warnOnce('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\r\n }\r\n\r\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\r\n if (letterSprite) {\r\n results.push(letterSprite);\r\n } else {\r\n this._logger.warnOnce(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\r\n this._logger.warnOnce('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n public measureText(text: string, maxWidth?: number): BoundingBox {\r\n const lines = this._getLinesFromText(text, maxWidth);\r\n const maxWidthLine = lines.reduce((a, b) => {\r\n return a.length > b.length ? a : b;\r\n });\r\n const sprites = this._getCharacterSprites(maxWidthLine);\r\n let width = 0;\r\n let height = 0;\r\n for (const sprite of sprites) {\r\n width += sprite.width + this.spacing;\r\n height = Math.max(height, sprite.height);\r\n }\r\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number, maxWidth?: number): void {\r\n let xCursor = 0;\r\n let yCursor = 0;\r\n let height = 0;\r\n const lines = this._getLinesFromText(this._text, maxWidth);\r\n for (const line of lines) {\r\n for (const sprite of this._getCharacterSprites(line)) {\r\n // draw it in the right spot and increase the cursor by sprite width\r\n sprite.draw(ex, x + xCursor, y + yCursor);\r\n xCursor += sprite.width + this.spacing;\r\n height = Math.max(height, sprite.height);\r\n }\r\n xCursor = 0;\r\n yCursor += this.lineHeight ?? height;\r\n }\r\n }\r\n\r\n render(ex: ExcaliburGraphicsContext, text: string, _color: Color, x: number, y: number, maxWidth?: number) {\r\n // SpriteFont doesn't support _color, yet...\r\n this._text = text;\r\n const bounds = this.measureText(text, maxWidth);\r\n this.width = bounds.width;\r\n this.height = bounds.height;\r\n if (this.shadow) {\r\n ex.save();\r\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0, maxWidth);\r\n this._postDraw(ex);\r\n ex.restore();\r\n }\r\n\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0, maxWidth);\r\n this._postDraw(ex);\r\n }\r\n\r\n clone(): SpriteFont {\r\n return new SpriteFont({\r\n alphabet: this.alphabet,\r\n spriteSheet: this.spriteSheet,\r\n spacing: this.spacing\r\n });\r\n }\r\n\r\n /**\r\n * Return array of lines split based on the \\n character, and the maxWidth? constraint\r\n * @param text\r\n * @param maxWidth\r\n */\r\n private _cachedText: string;\r\n private _cachedLines: string[];\r\n private _cachedRenderWidth: number;\r\n private _getLinesFromText(text: string, maxWidth?: number) {\r\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\r\n return this._cachedLines;\r\n }\r\n\r\n const lines = text.split('\\n');\r\n\r\n if (maxWidth == null) {\r\n return lines;\r\n }\r\n\r\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\r\n for (let i = 0; i < lines.length; i++) {\r\n let line = lines[i];\r\n let newLine = '';\r\n // Note: we subtract the spacing to counter the initial padding on the left side.\r\n if (this.measureText(line).width > maxWidth) {\r\n while (this.measureText(line).width > maxWidth) {\r\n newLine = line[line.length - 1] + newLine;\r\n line = line.slice(0, -1); // Remove last character from line\r\n }\r\n\r\n // Update the array with our new values\r\n lines[i] = line;\r\n lines[i + 1] = newLine;\r\n }\r\n }\r\n\r\n this._cachedText = text;\r\n this._cachedLines = lines;\r\n this._cachedRenderWidth = maxWidth;\r\n\r\n return lines;\r\n }\r\n}\r\n","import { ImageSource } from './ImageSource';\r\nimport { SourceView, Sprite } from './Sprite';\r\nimport { GraphicOptions } from './Graphic';\r\n\r\n/**\r\n * Specify sprite sheet spacing options, useful if your sprites are not tightly packed\r\n * and have space between them.\r\n */\r\nexport interface SpriteSheetSpacingDimensions {\r\n /**\r\n * The starting point to offset and start slicing the sprite sheet from the top left of the image.\r\n * Default is (0, 0)\r\n */\r\n originOffset?: { x?: number, y?: number };\r\n\r\n /**\r\n * The margin between sprites.\r\n * Default is (0, 0)\r\n */\r\n margin?: {x?: number, y?: number};\r\n}\r\n\r\n/**\r\n * Sprite sheet options for slicing up images\r\n */\r\nexport interface SpriteSheetGridOptions {\r\n /**\r\n * Source image to use for each sprite\r\n */\r\n image: ImageSource;\r\n /**\r\n * Grid definition for the sprite sheet\r\n */\r\n grid: {\r\n /**\r\n * Number of rows in the sprite sheet\r\n */\r\n rows: number;\r\n /**\r\n * Number of columns in the sprite sheet\r\n */\r\n columns: number;\r\n /**\r\n * Width of each individual sprite\r\n */\r\n spriteWidth: number;\r\n /**\r\n * Height of each individual sprite\r\n */\r\n spriteHeight: number;\r\n };\r\n /**\r\n * Optionally specify any spacing information between sprites\r\n */\r\n spacing?: SpriteSheetSpacingDimensions;\r\n}\r\n\r\nexport interface SpriteSheetSparseOptions {\r\n /**\r\n * Source image to use for each sprite\r\n */\r\n image: ImageSource;\r\n /**\r\n * List of source view rectangles to create a sprite sheet from\r\n */\r\n sourceViews: SourceView[];\r\n}\r\n\r\nexport interface SpriteSheetOptions {\r\n /**\r\n * Source sprites for the sprite sheet\r\n */\r\n sprites: Sprite[];\r\n /**\r\n * Optionally specify the number of rows in a sprite sheet (default 1 row)\r\n */\r\n rows?: number;\r\n /**\r\n * Optionally specify the number of columns in a sprite sheet (default sprites.length)\r\n */\r\n columns?: number;\r\n}\r\n\r\nexport interface GetSpriteOptions extends GraphicOptions {}\r\n\r\n/**\r\n * Represents a collection of sprites from a source image with some organization in a grid\r\n */\r\nexport class SpriteSheet {\r\n public readonly sprites: Sprite[] = [];\r\n public readonly rows: number;\r\n public readonly columns: number;\r\n\r\n /**\r\n * Build a new sprite sheet from a list of sprites\r\n *\r\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n * @param options\r\n */\r\n constructor(options: SpriteSheetOptions) {\r\n const { sprites, rows, columns } = options;\r\n this.sprites = sprites;\r\n this.rows = rows ?? 1;\r\n this.columns = columns ?? this.sprites.length;\r\n }\r\n\r\n /**\r\n * Find a sprite by their x/y integer coordinates in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\r\n * and `getSprite(1, 0)` is the sprite one to the right.\r\n * @param x\r\n * @param y\r\n */\r\n public getSprite(x: number, y: number, options?: GetSpriteOptions): Sprite {\r\n if (x >= this.columns || x < 0) {\r\n throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\r\n }\r\n if (y >= this.rows || y < 0) {\r\n throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\r\n }\r\n const spriteIndex = x + y * this.columns;\r\n const sprite = this.sprites[spriteIndex];\r\n if (sprite) {\r\n if (options) {\r\n const spriteWithOptions = sprite.clone();\r\n spriteWithOptions.flipHorizontal = options.flipHorizontal ?? spriteWithOptions.flipHorizontal;\r\n spriteWithOptions.flipVertical = options.flipVertical ?? spriteWithOptions.flipVertical;\r\n spriteWithOptions.width = options.width ?? spriteWithOptions.width;\r\n spriteWithOptions.height = options.height ?? spriteWithOptions.height;\r\n spriteWithOptions.rotation = options.rotation ?? spriteWithOptions.rotation;\r\n spriteWithOptions.scale = options.scale ?? spriteWithOptions.scale;\r\n spriteWithOptions.opacity = options.opacity ?? spriteWithOptions.opacity;\r\n spriteWithOptions.tint = options.tint ?? spriteWithOptions.tint;\r\n spriteWithOptions.origin = options.origin ?? spriteWithOptions.origin;\r\n return spriteWithOptions;\r\n }\r\n return sprite;\r\n }\r\n throw Error(`Invalid sprite coordinates (${x}, ${y}`);\r\n }\r\n\r\n /**\r\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\r\n * @param options\r\n */\r\n public static fromImageSourceWithSourceViews(options: SpriteSheetSparseOptions): SpriteSheet {\r\n const sprites: Sprite[] = options.sourceViews.map(sourceView => {\r\n return new Sprite({\r\n image: options.image,\r\n sourceView\r\n });\r\n });\r\n return new SpriteSheet({sprites});\r\n }\r\n\r\n /**\r\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n *\r\n * Example:\r\n * ```\r\n * const spriteSheet = SpriteSheet.fromImageSource({\r\n * image: imageSource,\r\n * grid: {\r\n * rows: 5,\r\n * columns: 2,\r\n * spriteWidth: 32, // pixels\r\n * spriteHeight: 32 // pixels\r\n * },\r\n * // Optionally specify spacing\r\n * spacing: {\r\n * // pixels from the top left to start the sprite parsing\r\n * originOffset: {\r\n * x: 5,\r\n * y: 5\r\n * },\r\n * // pixels between each sprite while parsing\r\n * margin: {\r\n * x: 1,\r\n * y: 1\r\n * }\r\n * }\r\n * })\r\n * ```\r\n * @param options\r\n */\r\n public static fromImageSource(options: SpriteSheetGridOptions): SpriteSheet {\r\n const sprites: Sprite[] = [];\r\n options.spacing = options.spacing ?? {};\r\n const {\r\n image,\r\n grid: { rows, columns: cols, spriteWidth, spriteHeight },\r\n spacing: { originOffset, margin }\r\n } = options;\r\n const offsetDefaults = { x: 0, y: 0, ...originOffset};\r\n const marginDefaults = { x: 0, y: 0, ...margin};\r\n for (let x = 0; x < cols; x++) {\r\n for (let y = 0; y < rows; y++) {\r\n sprites[x + y * cols] = new Sprite({\r\n image: image,\r\n sourceView: {\r\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\r\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\r\n width: spriteWidth,\r\n height: spriteHeight\r\n },\r\n destSize: { height: spriteHeight, width: spriteWidth }\r\n });\r\n }\r\n }\r\n return new SpriteSheet({\r\n sprites: sprites,\r\n rows: rows,\r\n columns: cols\r\n });\r\n }\r\n\r\n public clone(): SpriteSheet {\r\n return new SpriteSheet({\r\n sprites: this.sprites.map(sprite => sprite.clone()),\r\n rows: this.rows,\r\n columns: this.columns\r\n });\r\n }\r\n}\r\n","export default \"data:image/png;base64,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\"","import { ExcaliburGraphicsContext } from '../Context/ExcaliburGraphicsContext';\r\nimport { ImageSource } from '../ImageSource';\r\nimport { SpriteFont } from '../SpriteFont';\r\nimport { SpriteSheet } from '../SpriteSheet';\r\nimport { Vector } from '../../Math/vector';\r\nimport debugFont from './debug-font.png';\r\n\r\n/**\r\n * Internal debugtext helper\r\n */\r\nexport class DebugText {\r\n constructor() {\r\n // We fire and forget, we don't care if it's loaded or not\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.load();\r\n }\r\n\r\n /**\r\n * base64 font\r\n */\r\n public readonly fontSheet = debugFont;\r\n public size: number = 16;\r\n private _imageSource: ImageSource;\r\n private _spriteSheet: SpriteSheet;\r\n private _spriteFont: SpriteFont;\r\n public load() {\r\n this._imageSource = new ImageSource(this.fontSheet);\r\n return this._imageSource.load().then(() => {\r\n this._spriteSheet = SpriteSheet.fromImageSource({\r\n image: this._imageSource,\r\n grid: {\r\n rows: 4,\r\n columns: 16,\r\n spriteWidth: 16,\r\n spriteHeight: 16\r\n }\r\n });\r\n this._spriteFont = new SpriteFont({\r\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!\\'&.\"?-()+# ',\r\n caseInsensitive: true,\r\n spriteSheet: this._spriteSheet,\r\n spacing: -6\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Writes debug text using the built in sprint font\r\n * @param ctx\r\n * @param text\r\n * @param pos\r\n */\r\n public write(ctx: ExcaliburGraphicsContext, text: string, pos: Vector) {\r\n if (this._imageSource.isLoaded()) {\r\n this._spriteFont.render(ctx, text, null, pos.x, pos.y);\r\n }\r\n }\r\n}\r\n","export class RenderSource {\r\n constructor(\r\n private _gl: WebGLRenderingContext,\r\n private _texture: WebGLTexture) {}\r\n\r\n public use() {\r\n const gl = this._gl;\r\n gl.activeTexture(gl.TEXTURE0);\r\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\r\n }\r\n\r\n public disable() {\r\n const gl = this._gl;\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n }\r\n}","import { RenderSource } from './render-source';\r\n\r\ndeclare global {\r\n interface WebGL2RenderingContext {\r\n /**\r\n * Experimental only in chrome\r\n */\r\n drawingBufferFormat?: number;\r\n }\r\n}\r\n\r\n\r\nexport interface RenderTargetOptions {\r\n gl: WebGL2RenderingContext;\r\n width: number;\r\n height: number;\r\n transparency: boolean;\r\n /**\r\n * Optionally enable render buffer multisample anti-aliasing\r\n *\r\n * By default false\r\n */\r\n antialias?: boolean;\r\n /**\r\n * Optionally specify number of anti-aliasing samples to use\r\n *\r\n * By default the max for the platform is used if antialias is on.\r\n */\r\n samples?: number;\r\n}\r\n\r\nexport class RenderTarget {\r\n width: number;\r\n height: number;\r\n transparency: boolean;\r\n antialias: boolean = false;\r\n samples: number = 1;\r\n private _gl: WebGL2RenderingContext;\r\n public readonly bufferFormat: number;\r\n constructor(options: RenderTargetOptions) {\r\n this._gl = options.gl;\r\n this.width = options.width;\r\n this.height = options.height;\r\n this.transparency = options.transparency;\r\n this.antialias = options.antialias ?? this.antialias;\r\n this.samples = options.samples ?? this._gl.getParameter(this._gl.MAX_SAMPLES);\r\n\r\n const gl = this._gl;\r\n // Determine current context format for blitting later needs to match\r\n if (gl.drawingBufferFormat) {\r\n this.bufferFormat = gl.drawingBufferFormat;\r\n } else {\r\n // Documented in webgl spec\r\n // https://registry.khronos.org/webgl/specs/latest/1.0/\r\n if (this.transparency) {\r\n this.bufferFormat = gl.RGBA8;\r\n } else {\r\n this.bufferFormat = gl.RGB8;\r\n }\r\n }\r\n\r\n this._setupRenderBuffer();\r\n this._setupFramebuffer();\r\n }\r\n\r\n setResolution(width: number, height: number) {\r\n const gl = this._gl;\r\n this.width = width;\r\n this.height = height;\r\n\r\n // update backing texture size\r\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n\r\n // update render buffer size\r\n if (this._renderBuffer) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\r\n gl.renderbufferStorageMultisample(\r\n gl.RENDERBUFFER,\r\n Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)),\r\n this.bufferFormat,\r\n this.width,\r\n this.height);\r\n }\r\n }\r\n\r\n private _renderBuffer: WebGLRenderbuffer;\r\n public get renderBuffer() {\r\n return this._renderBuffer;\r\n }\r\n private _renderFrameBuffer: WebGLFramebuffer;\r\n public get renderFrameBuffer() {\r\n return this._renderFrameBuffer;\r\n }\r\n\r\n private _frameBuffer: WebGLFramebuffer;\r\n public get frameBuffer() {\r\n return this._frameBuffer;\r\n }\r\n private _frameTexture: WebGLTexture;\r\n public get frameTexture() {\r\n return this._frameTexture;\r\n }\r\n\r\n private _setupRenderBuffer() {\r\n if (this.antialias) {\r\n const gl = this._gl;\r\n // Render buffers can be used as an input to a shader\r\n this._renderBuffer = gl.createRenderbuffer();\r\n this._renderFrameBuffer = gl.createFramebuffer();\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\r\n gl.renderbufferStorageMultisample(\r\n gl.RENDERBUFFER,\r\n Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)),\r\n this.bufferFormat,\r\n this.width,\r\n this.height);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\r\n gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._renderBuffer);\r\n }\r\n }\r\n\r\n private _setupFramebuffer() {\r\n // Allocates frame buffer\r\n const gl = this._gl;\r\n this._frameTexture = gl.createTexture();\r\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n\r\n // set the filtering so we don't need mips\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n\r\n // attach the texture as the first color attachment\r\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\r\n\r\n // After this bind all draw calls will draw to this framebuffer texture\r\n this._frameBuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\r\n\r\n // Reset after initialized\r\n this.disable();\r\n }\r\n\r\n public toRenderSource() {\r\n if (this.renderBuffer) {\r\n this.blitRenderBufferToFrameBuffer();\r\n }\r\n const source = new RenderSource(this._gl, this._frameTexture);\r\n return source;\r\n }\r\n\r\n public blitToScreen() {\r\n const gl = this._gl;\r\n // set to size of canvas's drawingBuffer\r\n if (this._renderBuffer) {\r\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\r\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\r\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\r\n gl.blitFramebuffer(\r\n 0, 0, this.width, this.height,\r\n 0, 0, this.width, this.height,\r\n gl.COLOR_BUFFER_BIT, gl.LINEAR);\r\n } else {\r\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.frameBuffer);\r\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\r\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\r\n gl.blitFramebuffer(\r\n 0, 0, this.width, this.height,\r\n 0, 0, this.width, this.height,\r\n gl.COLOR_BUFFER_BIT, gl.LINEAR);\r\n }\r\n }\r\n\r\n public blitRenderBufferToFrameBuffer() {\r\n if (this._renderBuffer) {\r\n const gl = this._gl;\r\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\r\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.frameBuffer);\r\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\r\n gl.blitFramebuffer(\r\n 0, 0, this.width, this.height,\r\n 0, 0, this.width, this.height,\r\n gl.COLOR_BUFFER_BIT, gl.LINEAR);\r\n }\r\n }\r\n\r\n public copyToTexture(texture: WebGLTexture) {\r\n const gl = this._gl;\r\n if (this._renderBuffer) {\r\n this.blitRenderBufferToFrameBuffer();\r\n }\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, this.width, this.height, 0);\r\n }\r\n\r\n /**\r\n * When called, all drawing gets redirected to this render target\r\n */\r\n public use() {\r\n const gl = this._gl;\r\n if (this.antialias) {\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\r\n } else {\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n }\r\n\r\n // very important to set the viewport to the size of the framebuffer texture\r\n gl.viewport(0, 0, this.width, this.height);\r\n }\r\n\r\n /**\r\n * When called, all drawing is sent back to the canvas\r\n */\r\n public disable() {\r\n const gl = this._gl;\r\n // passing null switches rendering back to the canvas\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n }\r\n}","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\";","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\";","/**\r\n * Return the size of the GlType in bytes\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getGlTypeSizeBytes(gl: WebGLRenderingContext, type: number): number {\r\n switch (type) {\r\n case gl.FLOAT:\r\n return 4;\r\n case gl.SHORT:\r\n return 2;\r\n case gl.UNSIGNED_SHORT:\r\n return 2;\r\n case gl.BYTE:\r\n return 1;\r\n case gl.UNSIGNED_BYTE:\r\n return 1;\r\n default:\r\n return 1;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Based on the type return the number of attribute components\r\n *\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getAttributeComponentSize(gl: WebGLRenderingContext, type: number): number {\r\n switch (type) {\r\n case gl.LOW_FLOAT:\r\n case gl.HIGH_FLOAT:\r\n case gl.FLOAT:\r\n return 1;\r\n case gl.FLOAT_VEC2:\r\n return 2;\r\n case gl.FLOAT_VEC3:\r\n return 3;\r\n case gl.FLOAT_VEC4:\r\n return 4;\r\n case gl.BYTE:\r\n return 1;\r\n case gl.UNSIGNED_BYTE:\r\n return 1;\r\n case gl.UNSIGNED_SHORT:\r\n case gl.SHORT:\r\n return 1;\r\n default:\r\n return 1;\r\n }\r\n}\r\n\r\n/**\r\n * Based on the attribute return the corresponding supported attrib pointer type\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getAttributePointerType(gl: WebGLRenderingContext, type: number) {\r\n switch (type) {\r\n case gl.LOW_FLOAT:\r\n case gl.HIGH_FLOAT:\r\n case gl.FLOAT:\r\n case gl.FLOAT_VEC2:\r\n case gl.FLOAT_VEC3:\r\n case gl.FLOAT_VEC4:\r\n return gl.FLOAT;\r\n case gl.BYTE:\r\n return gl.BYTE;\r\n case gl.UNSIGNED_BYTE:\r\n return gl.UNSIGNED_BYTE;\r\n case gl.SHORT:\r\n return gl.SHORT;\r\n case gl.UNSIGNED_SHORT:\r\n return gl.UNSIGNED_SHORT;\r\n default:\r\n return gl.FLOAT;\r\n }\r\n}","import { Color, Logger, Vector } from '../..';\r\nimport { Matrix } from '../../Math/matrix';\r\nimport { getAttributeComponentSize, getAttributePointerType } from './webgl-util';\r\n\r\n/**\r\n * List of the possible glsl uniform types\r\n */\r\nexport type UniformTypeNames =\r\n 'uniform1f' |\r\n 'uniform1i' |\r\n 'uniform2f' |\r\n 'uniform2i' |\r\n 'uniform3f' |\r\n 'uniform3i' |\r\n 'uniform4f' |\r\n 'uniform4i' |\r\n 'uniform1fv' |\r\n 'uniform1iv' |\r\n 'uniform2fv' |\r\n 'uniform2iv' |\r\n 'uniform3fv' |\r\n 'uniform3iv' |\r\n 'uniform4fv' |\r\n 'uniform4iv' |\r\n 'uniformMatrix2fv' |\r\n 'uniformMatrix3fv' |\r\n 'uniformMatrix4fv';\r\n\r\ntype RemoveFirstFromTuple =\r\n T['length'] extends 0 ? undefined :\r\n (((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : [])\r\n\r\ntype UniformParameters = RemoveFirstFromTuple>\r\n\r\nexport interface UniformDefinition {\r\n name: string;\r\n glType: number;\r\n location: WebGLUniformLocation;\r\n}\r\n\r\n\r\nexport interface VertexAttributeDefinition {\r\n /**\r\n * string name of the attribute in the shader program, commonly `a_nameofmyvariable`\r\n */\r\n name: string;\r\n /**\r\n * Number of components for a given attribute\r\n * Must be 1, 2, 3, or 4\r\n *\r\n * For example a vec4 attribute would be `4` floats, so 4\r\n */\r\n size: number;\r\n /**\r\n * Supported types in webgl 1\r\n * * gl.BYTE\r\n * * gl.SHORT\r\n * * gl.UNSIGNED_BYTE\r\n * * gl.UNSIGNED_SHORT\r\n * * gl.FLOAT\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n */\r\n glType: number;\r\n /**\r\n * Is the attribute normalized between (0-1)\r\n */\r\n normalized: boolean;\r\n /**\r\n * Location index in the shader program\r\n */\r\n location: number;\r\n}\r\n\r\nexport interface ShaderOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across webgl contexts.\r\n */\r\n gl: WebGL2RenderingContext;\r\n /**\r\n * Vertex shader source code in glsl #version 300 es\r\n */\r\n vertexSource: string;\r\n /**\r\n * Fragment shader source code in glsl #version 300 es\r\n */\r\n fragmentSource: string;\r\n}\r\n\r\nexport class Shader {\r\n private static _ACTIVE_SHADER_INSTANCE: Shader = null;\r\n private _logger = Logger.getInstance();\r\n private _gl: WebGL2RenderingContext;\r\n public program: WebGLProgram;\r\n public uniforms: { [variableName: string]: UniformDefinition } = {};\r\n public attributes: { [variableName: string]: VertexAttributeDefinition } = {};\r\n private _compiled = false;\r\n public readonly vertexSource: string;\r\n public readonly fragmentSource: string;\r\n\r\n public get compiled() {\r\n return this._compiled;\r\n }\r\n\r\n /**\r\n * Create a shader program in excalibur\r\n * @param options specify shader vertex and fragment source\r\n */\r\n constructor(options?: ShaderOptions) {\r\n const { gl, vertexSource, fragmentSource } = options;\r\n this._gl = gl;\r\n this.vertexSource = vertexSource;\r\n this.fragmentSource = fragmentSource;\r\n }\r\n\r\n dispose() {\r\n const gl = this._gl;\r\n gl.deleteProgram(this.program);\r\n this._gl = null;\r\n }\r\n\r\n /**\r\n * Binds the shader program\r\n */\r\n use() {\r\n const gl = this._gl;\r\n gl.useProgram(this.program);\r\n Shader._ACTIVE_SHADER_INSTANCE = this;\r\n }\r\n\r\n isCurrentlyBound() {\r\n return Shader._ACTIVE_SHADER_INSTANCE === this;\r\n }\r\n\r\n /**\r\n * Compile the current shader against a webgl context\r\n */\r\n compile(): WebGLProgram {\r\n const gl = this._gl;\r\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\r\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\r\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\r\n\r\n const attributes = this.getAttributes();\r\n for (const attribute of attributes) {\r\n this.attributes[attribute.name] = attribute;\r\n }\r\n const uniforms = this.getUniforms();\r\n for (const uniform of uniforms) {\r\n this.uniforms[uniform.name] = uniform;\r\n }\r\n\r\n this._compiled = true;\r\n return this.program;\r\n }\r\n\r\n getUniforms(): UniformDefinition[] {\r\n const gl = this._gl;\r\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\r\n const uniforms: UniformDefinition[] = [];\r\n for (let i = 0; i < uniformCount; i++) {\r\n const uniform = gl.getActiveUniform(this.program, i);\r\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\r\n uniforms.push({\r\n name: uniform.name,\r\n glType: uniform.type,\r\n location: uniformLocation\r\n });\r\n }\r\n return uniforms;\r\n }\r\n\r\n getAttributes(): VertexAttributeDefinition[] {\r\n const gl = this._gl;\r\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\r\n const attributes: VertexAttributeDefinition[] = [];\r\n for (let i = 0; i < attributeCount; i++) {\r\n const attribute = gl.getActiveAttrib(this.program, i);\r\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\r\n attributes.push({\r\n name: attribute.name,\r\n glType: getAttributePointerType(gl, attribute.type),\r\n size: getAttributeComponentSize(gl, attribute.type),\r\n location: attributeLocation,\r\n normalized: false\r\n });\r\n }\r\n return attributes;\r\n }\r\n\r\n /**\r\n * Set a texture in a gpu texture slot\r\n * @param slotNumber\r\n * @param texture\r\n */\r\n setTexture(slotNumber: number, texture: WebGLTexture) {\r\n const gl = this._gl;\r\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n }\r\n\r\n /**\r\n * Set an integer uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformInt(name: string, value: number) {\r\n this.setUniform('uniform1i', name, ~~value);\r\n }\r\n\r\n /**\r\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformInt(name: string, value: number): boolean {\r\n return this.trySetUniform('uniform1i', name, ~~value);\r\n }\r\n\r\n /**\r\n * Set an integer array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformIntArray(name: string, value: number[]) {\r\n this.setUniform('uniform1iv', name, value);\r\n }\r\n\r\n /**\r\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformIntArray(name: string, value: number[]): boolean {\r\n return this.trySetUniform('uniform1iv', name, value);\r\n }\r\n\r\n /**\r\n * Set a boolean uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformBoolean(name: string, value: boolean) {\r\n this.setUniform('uniform1i', name, value ? 1 : 0);\r\n }\r\n\r\n /**\r\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformBoolean(name: string, value: boolean): boolean {\r\n return this.trySetUniform('uniform1i', name, value ? 1 : 0);\r\n }\r\n\r\n /**\r\n * Set a float uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloat(name: string, value: number) {\r\n this.setUniform('uniform1f', name, value);\r\n }\r\n\r\n /**\r\n * Set a float uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloat(name: string, value: number): boolean {\r\n return this.trySetUniform('uniform1f', name, value);\r\n }\r\n\r\n /**\r\n * Set a float array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatArray(name: string, value: number[]) {\r\n this.setUniform('uniform1fv', name, value);\r\n }\r\n /**\r\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatArray(name: string, value: number[]): boolean {\r\n return this.trySetUniform('uniform1fv', name, value);\r\n }\r\n\r\n /**\r\n * Set a [[Vector]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatVector(name: string, value: Vector) {\r\n this.setUniform('uniform2f', name, value.x, value.y);\r\n }\r\n\r\n /**\r\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatVector(name: string, value: Vector): boolean {\r\n return this.trySetUniform('uniform2f', name, value.x, value.y);\r\n }\r\n\r\n /**\r\n * Set a [[Color]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatColor(name: string, value: Color) {\r\n this.setUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\r\n }\r\n\r\n /**\r\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatColor(name: string, value: Color): boolean {\r\n return this.trySetUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\r\n }\r\n\r\n /**\r\n * Set an [[Matrix]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformMatrix(name: string, value: Matrix) {\r\n this.setUniform('uniformMatrix4fv', name, false, value.data);\r\n }\r\n\r\n /**\r\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformMatrix(name: string, value: Matrix): boolean {\r\n return this.trySetUniform('uniformMatrix4fv', name, false, value.data);\r\n }\r\n\r\n /**\r\n * Set any available uniform type in webgl\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n */\r\n setUniform(uniformType: TUniformType, name: string, ...value: UniformParameters) {\r\n if (!this._compiled) {\r\n throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\r\n }\r\n if (!this.isCurrentlyBound()) {\r\n throw Error('Currently accessed shader instance is not the current active shader in WebGL,' +\r\n ' must call `shader.use()` before setting uniforms');\r\n }\r\n const gl = this._gl;\r\n const location = gl.getUniformLocation(this.program, name);\r\n if (location) {\r\n const args = [location, ...value];\r\n this._gl[uniformType].apply(this._gl, args);\r\n } else {\r\n throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,`+\r\n ' unused uniforms are optimized away by most browsers');\r\n }\r\n }\r\n\r\n /**\r\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\r\n * true if it was set.\r\n *\r\n * WILL NOT THROW on error\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n *\r\n */\r\n trySetUniform(\r\n uniformType: TUniformType,\r\n name: string,\r\n ...value: UniformParameters): boolean {\r\n if (!this._compiled) {\r\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\r\n return false;\r\n }\r\n if (!this.isCurrentlyBound()) {\r\n this._logger.warn('Currently accessed shader instance is not the current active shader in WebGL,' +\r\n ' must call `shader.use()` before setting uniforms');\r\n return false;\r\n }\r\n const gl = this._gl;\r\n const location = gl.getUniformLocation(this.program, name);\r\n if (location) {\r\n const args = [location, ...value];\r\n this._gl[uniformType].apply(this._gl, args);\r\n } else {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram {\r\n const program = gl.createProgram();\r\n if (program === null) {\r\n throw Error('Could not create graphics shader program');\r\n }\r\n\r\n // attach the shaders.\r\n gl.attachShader(program, vertexShader);\r\n gl.attachShader(program, fragmentShader);\r\n\r\n // link the program.\r\n gl.linkProgram(program);\r\n\r\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\r\n if (!success) {\r\n throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\r\n }\r\n\r\n return program;\r\n }\r\n\r\n private _compileShader(gl: WebGLRenderingContext, source: string, type: number): WebGLShader {\r\n const typeName = gl.VERTEX_SHADER === type ? 'vertex' : 'fragment';\r\n const shader = gl.createShader(type);\r\n if (shader === null) {\r\n throw Error(`Could not build shader: [${source}]`);\r\n }\r\n\r\n gl.shaderSource(shader, source);\r\n gl.compileShader(shader);\r\n\r\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\r\n if (!success) {\r\n const errorInfo = gl.getShaderInfoLog(shader);\r\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\r\n }\r\n return shader;\r\n }\r\n\r\n private _processSourceForError(source: string, errorInfo: string) {\r\n if (!source) {\r\n return errorInfo;\r\n }\r\n const lines = source.split('\\n');\r\n const errorLineStart = errorInfo.search(/\\d:\\d/);\r\n const errorLineEnd = errorInfo.indexOf(' ', errorLineStart);\r\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(':').map(v => Number(v));\r\n for (let i = 0; i < lines.length; i++) {\r\n lines[i] = `${i+1}: ${lines[i]}${error2 === (i+1)? ' <----- ERROR!' : ''}`;\r\n }\r\n\r\n return '\\n\\nSource:\\n' + lines.join('\\n');\r\n }\r\n}","export interface VertexBufferOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n */\r\n gl: WebGL2RenderingContext,\r\n /**\r\n * Size in number of floats, so [4.2, 4.0, 2.1] is size = 3\r\n *\r\n * Ignored if data is passed directly\r\n */\r\n size?: number;\r\n /**\r\n * If the vertices never change switching 'static' can be more efficient on the gpu\r\n *\r\n * Default is 'dynamic'\r\n */\r\n type?: 'static' | 'dynamic';\r\n\r\n /**\r\n * Optionally pass pre-seeded data, size parameter is ignored\r\n */\r\n data?: Float32Array\r\n}\r\n\r\n/**\r\n * Helper around vertex buffer to simplify creating and uploading geometry\r\n *\r\n * Under the hood uses Float32Array\r\n */\r\nexport class VertexBuffer {\r\n private _gl: WebGL2RenderingContext;\r\n\r\n /**\r\n * Access to the webgl buffer handle\r\n */\r\n public readonly buffer: WebGLBuffer;\r\n /**\r\n * Access to the raw data of the vertex buffer\r\n */\r\n public readonly bufferData: Float32Array;\r\n\r\n /**\r\n * If the vertices never change switching 'static' can be more efficient on the gpu\r\n *\r\n * Default is 'dynamic'\r\n */\r\n public type: 'static' | 'dynamic' = 'dynamic';\r\n\r\n constructor(options: VertexBufferOptions) {\r\n const { gl, size, type, data } = options;\r\n this._gl = gl;\r\n this.buffer = this._gl.createBuffer();\r\n if (!data && !size) {\r\n throw Error('Must either provide data or a size to the VertexBuffer');\r\n }\r\n\r\n if (!data) {\r\n this.bufferData = new Float32Array(size);\r\n } else {\r\n this.bufferData = data;\r\n }\r\n this.type = type ?? this.type;\r\n // Allocate buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\r\n }\r\n\r\n /**\r\n * Bind this vertex buffer\r\n */\r\n bind() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n\r\n }\r\n\r\n /**\r\n * Upload vertex buffer geometry to the GPU\r\n */\r\n upload(count?: number) {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n if (count) {\r\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\r\n } else {\r\n // TODO always use bufferSubData? need to perf test it\r\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\r\n }\r\n }\r\n\r\n dispose() {\r\n const gl = this._gl;\r\n gl.deleteBuffer(this.buffer);\r\n this._gl = null;\r\n }\r\n}","import { Logger } from '../..';\r\nimport { Shader, VertexAttributeDefinition } from './shader';\r\nimport { VertexBuffer } from './vertex-buffer';\r\nimport { getGlTypeSizeBytes } from './webgl-util';\r\n\r\n\r\nexport interface VertexLayoutOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n */\r\n gl: WebGL2RenderingContext,\r\n /**\r\n * Shader that this layout will be for, if null you must set a shader before using it.\r\n */\r\n shader?: Shader;\r\n /**\r\n * Vertex buffer to use for vertex data\r\n */\r\n vertexBuffer: VertexBuffer,\r\n /**\r\n * Specify the attributes that will exist in the vertex buffer\r\n *\r\n * **Important** must specify them in the order that they will be in the vertex buffer!!\r\n */\r\n attributes: [name: string, numberOfComponents: number][]\r\n}\r\n\r\n/**\r\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\r\n * the memory layout for your vertices inside a particular buffer\r\n *\r\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\r\n *\r\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\r\n */\r\nexport class VertexLayout {\r\n private _gl: WebGL2RenderingContext;\r\n private _logger = Logger.getInstance();\r\n private _shader: Shader;\r\n private _layout: VertexAttributeDefinition[] = [];\r\n private _attributes: [name: string, numberOfComponents: number][] = [];\r\n private _vertexBuffer: VertexBuffer;\r\n public get vertexBuffer() {\r\n return this._vertexBuffer;\r\n }\r\n\r\n public get attributes(): readonly [name: string, numberOfComponents: number][] {\r\n return this._attributes;\r\n }\r\n\r\n constructor(options: VertexLayoutOptions) {\r\n const {gl, shader, vertexBuffer, attributes} = options;\r\n this._gl = gl;\r\n this._vertexBuffer = vertexBuffer;\r\n this._attributes = attributes;\r\n this._shader = shader;\r\n if (shader) {\r\n this.initialize();\r\n }\r\n }\r\n\r\n private _vertexTotalSizeBytes = 0;\r\n /**\r\n * Total number of bytes that the vertex will take up\r\n */\r\n public get totalVertexSizeBytes(): number {\r\n return this._vertexTotalSizeBytes;\r\n }\r\n\r\n public set shader(shader: Shader) {\r\n if (shader && this._shader !== shader) {\r\n this._shader = shader;\r\n this.initialize();\r\n }\r\n }\r\n\r\n public get shader() {\r\n return this._shader;\r\n }\r\n\r\n /**\r\n * Layouts need shader locations and must be bound to a shader\r\n */\r\n initialize() {\r\n if (!this._shader) {\r\n return;\r\n }\r\n\r\n if (!this._shader.compiled) {\r\n throw Error('Shader not compiled, shader must be compiled before defining a vertex layout');\r\n }\r\n this._vertexTotalSizeBytes = 0;\r\n this._layout.length = 0;\r\n const shaderAttributes = this._shader.attributes;\r\n for (const attribute of this._attributes) {\r\n const attrib = shaderAttributes[attribute[0]];\r\n if (!attrib) {\r\n throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}`+\r\n ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\r\n }\r\n if (attrib.size !== attribute[1]) {\r\n throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],`\r\n +` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\r\n }\r\n this._layout.push(attrib);\r\n }\r\n\r\n // calc size\r\n let componentsPerVertex = 0;\r\n for (const vertAttribute of this._layout) {\r\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\r\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\r\n componentsPerVertex += vertAttribute.size;\r\n }\r\n\r\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) {\r\n this._logger.warn(`The vertex component size (${componentsPerVertex}) does NOT divide evenly into the specified vertex buffer`\r\n +` (${this._vertexBuffer.bufferData.length})`);\r\n }\r\n }\r\n\r\n /**\r\n * Bind this layout with it's associated vertex buffer\r\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\r\n */\r\n use(uploadBuffer = false, count?: number) {\r\n if (!this._shader) {\r\n throw Error('No shader is associated with this vertex layout, a shader must be set');\r\n }\r\n\r\n const gl = this._gl;\r\n if (!this._shader.isCurrentlyBound()) {\r\n throw Error('Shader associated with this vertex layout is not active! Call shader.use() before layout.use()');\r\n }\r\n this._vertexBuffer.bind();\r\n if (uploadBuffer) {\r\n this._vertexBuffer.upload(count);\r\n }\r\n let offset = 0;\r\n // TODO switch to VAOs if the extension is\r\n for (const vert of this._layout) {\r\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\r\n gl.enableVertexAttribArray(vert.location);\r\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\r\n }\r\n }\r\n}","export class GraphicsDiagnostics {\r\n public static DrawCallCount: number = 0;\r\n public static DrawnImagesCount: number = 0;\r\n public static clear(): void {\r\n GraphicsDiagnostics.DrawCallCount = 0;\r\n GraphicsDiagnostics.DrawnImagesCount = 0;\r\n }\r\n}\r\n","import { Vector } from '../../../Math/vector';\r\nimport { Color } from '../../../Color';\r\nimport lineVertexSource from './line-vertex.glsl';\r\nimport lineFragmentSource from './line-fragment.glsl';\r\nimport { ExcaliburGraphicsContextWebGL } from '../ExcaliburGraphicsContextWebGL';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader, VertexBuffer, VertexLayout } from '../..';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\n\r\nexport interface LineOptions {\r\n color?: Color;\r\n width?: number;\r\n}\r\n\r\nexport class LineRenderer implements RendererPlugin {\r\n public readonly type = 'ex.line';\r\n public priority: number = 0;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGL2RenderingContext;\r\n private _shader: Shader;\r\n private _maxLines: number = 10922;\r\n private _vertexBuffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _vertexIndex = 0;\r\n private _lineCount = 0;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: lineVertexSource,\r\n fragmentSource: lineFragmentSource\r\n });\r\n this._shader.compile();\r\n this._shader.use();\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n this._vertexBuffer = new VertexBuffer({\r\n gl,\r\n size: 6 * 2 * this._maxLines,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n vertexBuffer: this._vertexBuffer,\r\n shader: this._shader,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_color', 4]\r\n ]\r\n });\r\n }\r\n\r\n public dispose() {\r\n this._vertexBuffer.dispose();\r\n this._shader.dispose();\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n draw(start: Vector, end: Vector, color: Color): void {\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._lineCount++;\r\n\r\n const transform = this._context.getTransform();\r\n const finalStart = transform.multiply(start);\r\n const finalEnd = transform.multiply(end);\r\n\r\n\r\n const vertexBuffer = this._vertexBuffer.bufferData;\r\n // Start\r\n vertexBuffer[this._vertexIndex++] = finalStart.x;\r\n vertexBuffer[this._vertexIndex++] = finalStart.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n\r\n // End\r\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\r\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n }\r\n\r\n private _isFull() {\r\n if (this._lineCount >= this._maxLines) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._lineCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._lineCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use(true);\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // reset\r\n this._vertexIndex = 0;\r\n this._lineCount = 0;\r\n }\r\n}\r\n","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\";","export default \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \\\"premultiply\\\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}\";","import pointVertexSource from './point-vertex.glsl';\r\nimport pointFragmentSource from './point-fragment.glsl';\r\nimport { Vector } from '../../../Math/vector';\r\nimport { Color } from '../../../Color';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\n\r\nexport class PointRenderer implements RendererPlugin {\r\n public readonly type = 'ex.point';\r\n public priority: number = 0;\r\n private _shader: Shader;\r\n private _maxPoints: number = 10922;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _gl: WebGLRenderingContext;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _pointCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: pointVertexSource,\r\n fragmentSource: pointFragmentSource\r\n });\r\n this._shader.compile();\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 7 * this._maxPoints,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_color', 4],\r\n ['a_size', 1]\r\n ]\r\n });\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._shader.dispose();\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n draw(point: Vector, color: Color, size: number): void {\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._pointCount++;\r\n\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const finalPoint = transform.multiply(point);\r\n\r\n if (snapToPixel) {\r\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\r\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\r\n }\r\n\r\n const vertexBuffer = this._buffer.bufferData;\r\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\r\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\r\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\r\n }\r\n\r\n private _isFull() {\r\n if (this._pointCount >= this._maxPoints) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._pointCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._pointCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use(true);\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n this._pointCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n}\r\n","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\";","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\";","\r\nimport screenVertex from './screen-vertex.glsl';\r\nimport screenFragment from './screen-fragment.glsl';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport { PostProcessor } from '../../PostProcessor/PostProcessor';\r\n\r\n/**\r\n * This is responsible for painting the entire screen during the render passes\r\n */\r\nexport class ScreenPassPainter {\r\n private _gl: WebGLRenderingContext;\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n constructor(gl: WebGL2RenderingContext) {\r\n this._gl = gl;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: screenVertex,\r\n fragmentSource: screenFragment\r\n });\r\n this._shader.compile();\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n type: 'static',\r\n // clip space quad + uv since we don't need a camera\r\n data: new Float32Array([\r\n -1, -1, 0, 0,\r\n -1, 1, 0, 1,\r\n 1, -1, 1, 0,\r\n\r\n 1, -1, 1, 0,\r\n -1, 1, 0, 1,\r\n 1, 1, 1, 1\r\n ])\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_texcoord', 2]\r\n ]\r\n });\r\n this._buffer.upload();\r\n }\r\n\r\n renderWithPostProcessor(postprocessor: PostProcessor): void {\r\n const gl = this._gl;\r\n postprocessor.getShader().use();\r\n postprocessor.getLayout().use();\r\n gl.drawArrays(gl.TRIANGLES, 0, 6);\r\n }\r\n\r\n renderToScreen(): void {\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use();\r\n gl.drawArrays(gl.TRIANGLES, 0, 6);\r\n }\r\n}","import { Logger } from '../..';\r\n\r\n/**\r\n * Helper that defines and index buffer for quad geometry\r\n *\r\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\r\n * it is almost always worth it in terms of performance to use an index buffer.\r\n */\r\nexport class QuadIndexBuffer {\r\n private _gl: WebGL2RenderingContext;\r\n private _logger: Logger = Logger.getInstance();\r\n /**\r\n * Access to the webgl buffer handle\r\n */\r\n public buffer: WebGLBuffer;\r\n /**\r\n * Access to the raw data of the index buffer\r\n */\r\n public bufferData: Uint16Array | Uint32Array;\r\n /**\r\n * Depending on the browser this is either gl.UNSIGNED_SHORT or gl.UNSIGNED_INT\r\n */\r\n public bufferGlType: number;\r\n\r\n /**\r\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n * @param numberOfQuads Specify the max number of quads you want to draw\r\n * @param useUint16 Optionally force a uint16 buffer\r\n */\r\n constructor(gl: WebGL2RenderingContext, numberOfQuads: number, useUint16?: boolean) {\r\n this._gl = gl;\r\n this.buffer = gl.createBuffer();\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n\r\n const totalVertices = numberOfQuads * 6;\r\n\r\n if (!useUint16) {\r\n this.bufferData = new Uint32Array(totalVertices);\r\n } else {\r\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\r\n const maxUint16 = 65_535;\r\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\r\n\r\n this.bufferGlType = gl.UNSIGNED_SHORT;\r\n this.bufferData = new Uint16Array(totalVertices);\r\n // TODO Should we error if this happens?? maybe not might crash mid game\r\n if (numberOfQuads > maxUint16Index) {\r\n this._logger.warn(\r\n `Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\r\n }\r\n }\r\n\r\n\r\n let currentQuad = 0;\r\n for (let i = 0; i < totalVertices; i += 6) {\r\n // first triangle\r\n this.bufferData[i + 0] = currentQuad + 0;\r\n this.bufferData[i + 1] = currentQuad + 1;\r\n this.bufferData[i + 2] = currentQuad + 2;\r\n // second triangle\r\n this.bufferData[i + 3] = currentQuad + 2;\r\n this.bufferData[i + 4] = currentQuad + 1;\r\n this.bufferData[i + 5] = currentQuad + 3;\r\n currentQuad += 4;\r\n }\r\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\r\n }\r\n\r\n public get size() {\r\n return this.bufferData.length;\r\n }\r\n\r\n /**\r\n * Upload data to the GPU\r\n */\r\n public upload() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\r\n }\r\n\r\n /**\r\n * Bind this index buffer\r\n */\r\n public bind() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n }\r\n\r\n public dispose() {\r\n const gl = this._gl;\r\n gl.deleteBuffer(this.buffer);\r\n this._gl = null;\r\n }\r\n}","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\nuniform bool u_pixelart;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nin vec2 v_res;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\n// Inigo Quilez pixel art filter https://jorenjoestar.github.io/post/pixel_art_filtering/\\r\\nvec2 uv_iq(in vec2 uv, in vec2 texture_size) {\\r\\n vec2 pixel = uv * texture_size;\\r\\n \\r\\n vec2 seam=floor(pixel+.5);\\r\\n vec2 dudv=fwidth(pixel);\\r\\n pixel=seam+clamp((pixel-seam)/dudv,-.5,.5);\\r\\n \\r\\n return pixel/texture_size;\\r\\n}\\r\\n\\r\\nvoid main(){\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n \\r\\n vec4 color=vec4(1.,0,0,1.);\\r\\n \\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n \\r\\n color.rgb=color.rgb*v_opacity;\\r\\n color.a=color.a*v_opacity;\\r\\n fragColor=color*v_tint;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity\\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture res\\r\\nin vec2 a_res;\\r\\nout vec2 v_res;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main(){\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position=u_matrix*vec4(a_position,0.,1.);\\r\\n \\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity=a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord=a_texcoord;\\r\\n\\r\\n v_res = a_res;\\r\\n\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex=a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint=a_tint;\\r\\n}\";","import { sign } from '../../../Math/util';\r\nimport { vec } from '../../../Math/vector';\r\nimport { ImageFiltering } from '../../Filtering';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { HTMLImageSource } from '../ExcaliburGraphicsContext';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport frag from './image-renderer.frag.glsl';\r\nimport vert from './image-renderer.vert.glsl';\r\n\r\nexport interface ImageRendererOptions {\r\n pixelArtSampler: boolean;\r\n uvPadding: number;\r\n}\r\n\r\nexport class ImageRenderer implements RendererPlugin {\r\n public readonly type = 'ex.image';\r\n public priority: number = 0;\r\n\r\n public readonly pixelArtSampler: boolean;\r\n public readonly uvPadding: number;\r\n\r\n private _maxImages: number = 10922; // max(uint16) / 6 verts\r\n private _maxTextures: number = 0;\r\n\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGLRenderingContext;\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n\r\n // Per flush vars\r\n private _imageCount: number = 0;\r\n private _textures: WebGLTexture[] = [];\r\n private _vertexIndex: number = 0;\r\n\r\n constructor(options: ImageRendererOptions) {\r\n this.pixelArtSampler = options.pixelArtSampler;\r\n this.uvPadding = options.uvPadding;\r\n }\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n // Transform shader source\r\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\r\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\r\n const transformedFrag = this._transformFragmentSource(frag, this._maxTextures);\r\n // Compile shader\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: transformedFrag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\r\n this._shader.setUniformIntArray(\r\n 'u_textures',\r\n [...Array(this._maxTextures)].map((_, i) => i)\r\n );\r\n\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 12 * 4 * this._maxImages, // 12 components * 4 verts\r\n type: 'dynamic'\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_opacity', 1],\r\n ['a_res', 2],\r\n ['a_texcoord', 2],\r\n ['a_textureIndex', 1],\r\n ['a_tint', 4]\r\n ]\r\n });\r\n\r\n // Setup index buffer\r\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._quads.dispose();\r\n this._shader.dispose();\r\n this._textures.length = 0;\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n private _transformFragmentSource(source: string, maxTextures: number): string {\r\n let newSource = source.replace('%%count%%', maxTextures.toString());\r\n let texturePickerBuilder = '';\r\n for (let i = 0; i < maxTextures; i++) {\r\n if (i === 0) {\r\n texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\r\n } else {\r\n texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\r\n }\r\n texturePickerBuilder += ` vec2 uv = u_pixelart ? uv_iq(v_texcoord, v_res) : v_texcoord;\\n`;\r\n texturePickerBuilder += ` color = texture(u_textures[${i}], uv);\\n`;\r\n texturePickerBuilder += ` }\\n`;\r\n }\r\n newSource = newSource.replace('%%texture_picker%%', texturePickerBuilder);\r\n return newSource;\r\n }\r\n\r\n private _addImageAsTexture(image: HTMLImageSource) {\r\n const maybeFiltering = image.getAttribute('filtering');\r\n let filtering: ImageFiltering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n\r\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._context.textureLoader.load(image, filtering, force);\r\n // remove force attribute after upload\r\n image.removeAttribute('forceUpload');\r\n if (this._textures.indexOf(texture) === -1) {\r\n this._textures.push(texture);\r\n }\r\n }\r\n\r\n private _bindTextures(gl: WebGLRenderingContext) {\r\n // Bind textures in the correct order\r\n for (let i = 0; i < this._maxTextures; i++) {\r\n gl.activeTexture(gl.TEXTURE0 + i);\r\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\r\n }\r\n }\r\n\r\n private _getTextureIdForImage(image: HTMLImageSource) {\r\n if (image) {\r\n const maybeTexture = this._context.textureLoader.get(image);\r\n return this._textures.indexOf(maybeTexture);\r\n }\r\n return -1;\r\n }\r\n\r\n private _isFull() {\r\n if (this._imageCount >= this._maxImages) {\r\n return true;\r\n }\r\n if (this._textures.length >= this._maxTextures) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n\r\n draw(image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number): void {\r\n\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._imageCount++;\r\n // This creates and uploads the texture if not already done\r\n this._addImageAsTexture(image);\r\n\r\n let width = image?.width || swidth || 0;\r\n let height = image?.height || sheight || 0;\r\n let view = [0, 0, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n let dest = [sx ?? 1, sy ?? 1];\r\n // If destination is specified, update view and dest\r\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\r\n view = [sx ?? 1, sy ?? 1, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n dest = [dx, dy];\r\n width = dwidth;\r\n height = dheight;\r\n }\r\n\r\n sx = view[0];\r\n sy = view[1];\r\n const sw = view[2];\r\n const sh = view[3];\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n let topLeft = vec(dest[0], dest[1]);\r\n let topRight = vec(dest[0] + width, dest[1]);\r\n let bottomLeft = vec(dest[0], dest[1] + height);\r\n let bottomRight = vec(dest[0] + width, dest[1] + height);\r\n\r\n topLeft = transform.multiply(topLeft);\r\n topRight = transform.multiply(topRight);\r\n bottomLeft = transform.multiply(bottomLeft);\r\n bottomRight = transform.multiply(bottomRight);\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + sign(topLeft.x) * pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + sign(topLeft.y) * pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + sign(topRight.x) * pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + sign(topRight.y) * pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + sign(bottomLeft.x) * pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + sign(bottomLeft.y) * pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + sign(bottomRight.x) * pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + sign(bottomRight.y) * pixelSnapEpsilon);\r\n }\r\n\r\n const tint = this._context.tint;\r\n\r\n const textureId = this._getTextureIdForImage(image);\r\n const imageWidth = image.width || width;\r\n const imageHeight = image.height || height;\r\n\r\n const uvx0 = (sx + this.uvPadding) / imageWidth;\r\n const uvy0 = (sy + this.uvPadding) / imageHeight;\r\n const uvx1 = (sx + sw - this.uvPadding) / imageWidth;\r\n const uvy1 = (sy + sh - this.uvPadding) / imageHeight;\r\n\r\n const txWidth = image.width;\r\n const txHeight = image.height;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = txWidth;\r\n vertexBuffer[this._vertexIndex++] = txHeight;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = txWidth;\r\n vertexBuffer[this._vertexIndex++] = txHeight;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = txWidth;\r\n vertexBuffer[this._vertexIndex++] = txHeight;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = txWidth;\r\n vertexBuffer[this._vertexIndex++] = txHeight;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._imageCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._imageCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true, 4 * 12 * this._imageCount); // 4 verts * 12 components\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Turn on pixel art aa sampler\r\n this._shader.setUniformBoolean('u_pixelart', this.pixelArtSampler);\r\n\r\n // Bind textures to\r\n this._bindTextures(gl);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._imageCount = 0;\r\n this._vertexIndex = 0;\r\n this._textures.length = 0;\r\n }\r\n}","export default \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";","import { Color } from '../../../Color';\r\nimport { vec, Vector } from '../../../Math/vector';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\nimport frag from './rectangle-renderer.frag.glsl';\r\nimport vert from './rectangle-renderer.vert.glsl';\r\n\r\nexport class RectangleRenderer implements RendererPlugin {\r\n public readonly type = 'ex.rectangle';\r\n public priority: number = 0;\r\n\r\n private _maxRectangles: number = 10922; // max(uint16) / 6 verts\r\n\r\n private _shader: Shader;\r\n private _gl: WebGLRenderingContext;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n private _rectangleCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: frag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 16 * 4 * this._maxRectangles,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_size', 2],\r\n ['a_opacity', 1],\r\n ['a_color', 4],\r\n ['a_strokeColor', 4],\r\n ['a_strokeThickness', 1]\r\n ]\r\n });\r\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._quads.dispose();\r\n this._shader.dispose();\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n private _isFull() {\r\n if (this._rectangleCount >= this._maxRectangles) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n draw(...args: any[]): void {\r\n if (args[0] instanceof Vector && args[1] instanceof Vector) {\r\n this.drawLine.apply(this, args);\r\n } else {\r\n this.drawRectangle.apply(this, args);\r\n }\r\n }\r\n\r\n drawLine(start: Vector, end: Vector, color: Color, thickness: number = 1) {\r\n\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._rectangleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const dir = end.sub(start);\r\n const length = dir.size;\r\n const normal = dir.normalize().perpendicular();\r\n const halfThick = thickness / 2;\r\n\r\n /**\r\n * +---------------------^----------------------+\r\n * | | (normal) |\r\n * (startx, starty)------------------>(endx, endy)\r\n * | |\r\n * + -------------------------------------------+\r\n */\r\n const startTop = transform.multiply(normal.scale(halfThick).add(start));\r\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\r\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\r\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\r\n\r\n if (snapToPixel) {\r\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\r\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\r\n\r\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\r\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\r\n\r\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\r\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\r\n\r\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\r\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO uv could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n const stroke = Color.Transparent;\r\n const strokeThickness = 0;\r\n const width = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = startTop.x;\r\n vertexBuffer[this._vertexIndex++] = startTop.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = startBottom.x;\r\n vertexBuffer[this._vertexIndex++] = startBottom.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = endTop.x;\r\n vertexBuffer[this._vertexIndex++] = endTop.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = endBottom.x;\r\n vertexBuffer[this._vertexIndex++] = endBottom.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n }\r\n\r\n drawRectangle(\r\n pos: Vector,\r\n width: number,\r\n height: number,\r\n color: Color,\r\n stroke: Color = Color.Transparent,\r\n strokeThickness: number = 0): void {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._rectangleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\r\n const topRight = transform.multiply(pos.add(vec(width, 0)));\r\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\r\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO uv could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._rectangleCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._rectangleCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true);\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._rectangleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n\r\n}","export default \"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";","import { Color } from '../../../Color';\r\nimport { vec, Vector } from '../../../Math/vector';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\nimport frag from './circle-renderer.frag.glsl';\r\nimport vert from './circle-renderer.vert.glsl';\r\n\r\nexport class CircleRenderer implements RendererPlugin {\r\n public readonly type = 'ex.circle';\r\n public priority: number = 0;\r\n\r\n private _maxCircles: number = 10922; // max(uint16) / 6 verts\r\n\r\n private _shader: Shader;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGLRenderingContext;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n\r\n private _circleCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: frag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 14 * 4 * this._maxCircles,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_opacity', 1],\r\n ['a_color', 4],\r\n ['a_strokeColor', 4],\r\n ['a_strokeThickness', 1]\r\n ]\r\n });\r\n\r\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._quads.dispose();\r\n this._shader.dispose();\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n private _isFull() {\r\n if (this._circleCount >= this._maxCircles) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n draw(pos: Vector, radius: number, color: Color, stroke: Color = Color.Transparent, strokeThickness: number = 0): void {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._circleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\r\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\r\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\r\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO UV could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._circleCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._circleCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true);\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._circleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n\r\n}","import { Logger } from '../Util/Log';\r\nexport class Pool {\r\n public totalAllocations = 0;\r\n public index = 0;\r\n public objects: Type[] = [];\r\n public disableWarnings = false;\r\n private _logger = Logger.getInstance();\r\n\r\n constructor(\r\n public builder: (...args: any[]) => Type,\r\n public recycler: (instance: Type, ...args: any[]) => Type,\r\n public maxObjects: number = 100\r\n ) {}\r\n\r\n dispose() {\r\n this.objects.length = 0;\r\n }\r\n\r\n preallocate() {\r\n for (let i = 0; i < this.maxObjects; i++) {\r\n this.objects[i] = this.builder();\r\n }\r\n }\r\n\r\n /**\r\n * Use many instances out of the in the context and return all to the pool.\r\n *\r\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\r\n * @param context\r\n */\r\n using(context: (pool: Pool) => Type[] | void) {\r\n const result = context(this);\r\n if (result) {\r\n return this.done(...result);\r\n }\r\n return this.done();\r\n }\r\n\r\n /**\r\n * Use a single instance out of th pool and immediately return it to the pool\r\n * @param context\r\n */\r\n borrow(context: (object: Type) => void) {\r\n const object = this.get();\r\n context(object);\r\n this.index--;\r\n }\r\n\r\n /**\r\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\r\n * @param args\r\n */\r\n get(...args: any[]): Type {\r\n if (this.index === this.maxObjects) {\r\n if (!this.disableWarnings) {\r\n this._logger.warn('Max pooled objects reached, possible memory leak? Doubling');\r\n }\r\n this.maxObjects = this.maxObjects * 2;\r\n }\r\n\r\n if (this.objects[this.index]) {\r\n // Pool has an available object already constructed\r\n return this.recycler(this.objects[this.index++], ...args);\r\n } else {\r\n // New allocation\r\n this.totalAllocations++;\r\n const object = (this.objects[this.index++] = this.builder(...args));\r\n return object;\r\n }\r\n }\r\n\r\n /**\r\n * Signals we are done with the pool objects for now, Reclaims all objects in the pool.\r\n *\r\n * If a list of pooled objects is passed to done they are un-hooked from the pool and are free\r\n * to be passed to consumers\r\n * @param objects A list of object to separate from the pool\r\n */\r\n done(...objects: Type[]): Type[];\r\n done(): void;\r\n done(...objects: Type[]): Type[] | void {\r\n // All objects in pool now considered \"free\"\r\n this.index = 0;\r\n for (const object of objects) {\r\n const poolIndex = this.objects.indexOf(object);\r\n // Build a new object to take the pool place\r\n this.objects[poolIndex] = (this as any).builder(); // TODO problematic 0-arg only support\r\n this.totalAllocations++;\r\n }\r\n return objects;\r\n }\r\n}\r\n","import { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContextState } from './ExcaliburGraphicsContext';\r\n\r\nexport class DrawCall {\r\n public z: number = 0;\r\n public priority: number = 0;\r\n public renderer: string;\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public state: ExcaliburGraphicsContextState = {\r\n z: 0,\r\n opacity: 1,\r\n tint: Color.White,\r\n material: null\r\n };\r\n public args: any[];\r\n}","import { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContext } from './ExcaliburGraphicsContext';\r\nimport { ExcaliburGraphicsContextWebGL } from './ExcaliburGraphicsContextWebGL';\r\nimport { Shader } from './shader';\r\nimport { Logger } from '../../Util/Log';\r\nimport { ImageSource } from '../ImageSource';\r\nimport { ImageFiltering } from '../Filtering';\r\n\r\nexport interface MaterialOptions {\r\n /**\r\n * Name the material for debugging\r\n */\r\n name?: string;\r\n\r\n /**\r\n * Excalibur graphics context to create the material (only WebGL is supported at the moment)\r\n */\r\n graphicsContext?: ExcaliburGraphicsContext;\r\n\r\n /**\r\n * Optionally specify a vertex shader\r\n *\r\n * If none supplied the default will be used\r\n *\r\n * ```\r\n * #version 300 es\r\n * // vertex position in local space\r\n * in vec2 a_position;\r\n * in vec2 a_uv;\r\n * out vec2 v_uv;\r\n * // orthographic projection matrix\r\n * uniform mat4 u_matrix;\r\n * // world space transform matrix\r\n * uniform mat4 u_transform;\r\n * void main() {\r\n * // Set the vertex position using the ortho & transform matrix\r\n * gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n * // Pass through the UV coord to the fragment shader\r\n * v_uv = a_uv;\r\n * }\r\n * ```\r\n */\r\n vertexSource?: string,\r\n\r\n /**\r\n * Add custom fragment shader\r\n *\r\n * *Note: Excalibur image alpha's are pre-multiplied\r\n *\r\n * Pre-built varyings:\r\n *\r\n * * `in vec2 v_uv` - UV coordinate\r\n *\r\n * Pre-built uniforms:\r\n *\r\n * * `uniform sampler2D u_graphic` - The current graphic displayed by the GraphicsComponent\r\n * * `uniform vec2 u_resolution` - The current resolution of the screen\r\n * * `uniform vec2 u_size;` - The current size of the graphic\r\n * * `uniform vec4 u_color` - The current color of the material\r\n * * `uniform float u_opacity` - The current opacity of the graphics context\r\n *\r\n */\r\n fragmentSource: string,\r\n\r\n /**\r\n * Add custom color, by default ex.Color.Transparent\r\n */\r\n color?: Color,\r\n\r\n /**\r\n * Add additional images to the material, you are limited by the GPU's maximum texture slots\r\n *\r\n * Specify a dictionary of uniform sampler names to ImageSource\r\n */\r\n images?: Record\r\n}\r\n\r\nconst defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nin vec2 a_screenuv;\r\nout vec2 v_screenuv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n v_screenuv = a_screenuv;\r\n}\r\n`;\r\n\r\nexport interface MaterialImageOptions {\r\n filtering?: ImageFiltering,\r\n\r\n}\r\n\r\nexport class Material {\r\n private _logger = Logger.getInstance();\r\n private _name: string;\r\n private _shader: Shader;\r\n private _color: Color = Color.Transparent;\r\n private _initialized = false;\r\n private _fragmentSource: string;\r\n private _vertexSource: string;\r\n\r\n private _images = new Map();\r\n private _textures = new Map();\r\n private _maxTextureSlots: number;\r\n private _graphicsContext: ExcaliburGraphicsContextWebGL;\r\n\r\n constructor(options: MaterialOptions) {\r\n const { color, name, vertexSource, fragmentSource, graphicsContext, images } = options;\r\n this._name = name ?? 'anonymous material';\r\n this._vertexSource = vertexSource ?? defaultVertexSource;\r\n this._fragmentSource = fragmentSource;\r\n this._color = color ?? this._color;\r\n if (!graphicsContext) {\r\n throw Error(`Material ${name} must be provided an excalibur webgl graphics context`);\r\n }\r\n if (graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this._graphicsContext = graphicsContext;\r\n this._initialize(graphicsContext);\r\n } else {\r\n this._logger.warn(`Material ${name} was created in 2D Canvas mode, currently only WebGL is supported`);\r\n }\r\n\r\n if (images) {\r\n for (const key in images) {\r\n this.addImageSource(key, images[key]);\r\n }\r\n }\r\n }\r\n\r\n private _initialize(graphicsContextWebGL: ExcaliburGraphicsContextWebGL) {\r\n if (this._initialized) {\r\n return;\r\n }\r\n const gl = graphicsContextWebGL.__gl;\r\n // max texture slots - 2 for the graphic texture and screen texture\r\n this._maxTextureSlots = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) - 2;\r\n this._shader = graphicsContextWebGL.createShader({\r\n vertexSource: this._vertexSource,\r\n fragmentSource: this._fragmentSource\r\n });\r\n this._shader.compile();\r\n this._initialized = true;\r\n }\r\n\r\n get name() {\r\n return this._name ?? 'anonymous material';\r\n }\r\n\r\n get isUsingScreenTexture() {\r\n return this._fragmentSource.includes('u_screen_texture');\r\n }\r\n\r\n update(callback: (shader: Shader) => any) {\r\n if (this._shader) {\r\n this._shader.use();\r\n callback(this._shader);\r\n }\r\n }\r\n\r\n getShader(): Shader | null {\r\n return this._shader;\r\n }\r\n\r\n addImageSource(textureUniformName: string, image: ImageSource) {\r\n if (this._images.size < this._maxTextureSlots) {\r\n this._images.set(textureUniformName, image);\r\n } else {\r\n this._logger.warn(`Max number texture slots ${this._maxTextureSlots} have been reached for material \"${this.name}\", `+\r\n `no more textures will be uploaded due to hardware constraints.`);\r\n }\r\n }\r\n\r\n removeImageSource(textureName: string) {\r\n const image = this._images.get(textureName);\r\n this._graphicsContext.textureLoader.delete(image.image);\r\n this._images.delete(textureName);\r\n }\r\n\r\n private _loadImageSource(image: ImageSource) {\r\n const imageElement = image.image;\r\n const maybeFiltering = imageElement.getAttribute('filtering');\r\n let filtering: ImageFiltering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n\r\n const force = imageElement.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._graphicsContext.textureLoader.load(imageElement, filtering, force);\r\n // remove force attribute after upload\r\n imageElement.removeAttribute('forceUpload');\r\n if (!this._textures.has(image)) {\r\n this._textures.set(image, texture);\r\n }\r\n\r\n return texture;\r\n }\r\n\r\n uploadAndBind(gl: WebGL2RenderingContext, startingTextureSlot: number = 2) {\r\n\r\n let textureSlot = startingTextureSlot;\r\n for (const [textureName, image] of this._images.entries()) {\r\n if (!image.isLoaded()) {\r\n this._logger.warnOnce(`Image named ${textureName} in material ${this.name} not loaded, nothing will be uploaded to the shader.` +\r\n ` Did you forget to add this to a loader? https://excaliburjs.com/docs/loaders/`);\r\n continue;\r\n } // skip unloaded images, maybe warn\r\n const texture = this._loadImageSource(image);\r\n\r\n gl.activeTexture(gl.TEXTURE0 + textureSlot);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n this._shader.trySetUniformInt(textureName, textureSlot);\r\n\r\n textureSlot++;\r\n }\r\n }\r\n\r\n use() {\r\n if (this._initialized) {\r\n // bind the shader\r\n this._shader.use();\r\n // Apply standard uniforms\r\n this._shader.trySetUniformFloatColor('u_color', this._color);\r\n\r\n } else {\r\n throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\r\n }\r\n }\r\n}","import { vec } from '../../../Math/vector';\r\nimport { ImageFiltering } from '../../Filtering';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { HTMLImageSource } from '../ExcaliburGraphicsContext';\r\nimport { ExcaliburGraphicsContextWebGL } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\n\r\nexport class MaterialRenderer implements RendererPlugin {\r\n public readonly type: string = 'ex.material';\r\n public priority: number = 0;\r\n // private _maxTextures = 8;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGL2RenderingContext;\r\n private _textures: WebGLTexture[] = [];\r\n private _quads: any;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 6 * 4, // 6 components * 4 verts\r\n type: 'dynamic'\r\n });\r\n\r\n // Setup a vertex layout/buffer to the material\r\n this._layout = new VertexLayout({\r\n gl,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_screenuv', 2]\r\n ]\r\n });\r\n\r\n // Setup index buffer\r\n this._quads = new QuadIndexBuffer(gl, 1, true);\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._quads.dispose();\r\n this._textures.length = 0;\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n draw(image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number): void {\r\n const gl = this._gl;\r\n\r\n // Extract context info\r\n const material = this._context.material;\r\n\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n\r\n // material shader\r\n const shader = material.getShader();\r\n\r\n // construct geometry, or hold on to it in the material?\r\n // geometry primitive for drawing rectangles?\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n let vertexIndex = 0;\r\n\r\n let width = image?.width || swidth || 0;\r\n let height = image?.height || sheight || 0;\r\n let view = [0, 0, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n let dest = [sx ?? 1, sy ?? 1];\r\n // If destination is specified, update view and dest\r\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\r\n view = [sx ?? 1, sy ?? 1, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n dest = [dx, dy];\r\n width = dwidth;\r\n height = dheight;\r\n }\r\n\r\n sx = view[0];\r\n sy = view[1];\r\n const sw = view[2];\r\n const sh = view[3];\r\n\r\n const topLeft = vec(dest[0], dest[1]);\r\n const topRight = vec(dest[0] + width, dest[1]);\r\n const bottomLeft = vec(dest[0], dest[1] + height);\r\n const bottomRight = vec(dest[0] + width, dest[1] + height);\r\n\r\n const imageWidth = image.width || width;\r\n const imageHeight = image.height || height;\r\n\r\n const uvx0 = (sx) / imageWidth;\r\n const uvy0 = (sy) / imageHeight;\r\n const uvx1 = (sx + sw - 0.01) / imageWidth;\r\n const uvy1 = (sy + sh - 0.01) / imageHeight;\r\n\r\n const topLeftScreen = transform.getPosition();\r\n const bottomRightScreen = topLeftScreen.add(bottomRight);\r\n const screenUVX0 = topLeftScreen.x / this._context.width;\r\n const screenUVY0 = topLeftScreen.y / this._context.height;\r\n const screenUVX1 = bottomRightScreen.x / this._context.width;\r\n const screenUVY1 = bottomRightScreen.y / this._context.height;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[vertexIndex++] = topLeft.x;\r\n vertexBuffer[vertexIndex++] = topLeft.y;\r\n vertexBuffer[vertexIndex++] = uvx0;\r\n vertexBuffer[vertexIndex++] = uvy0;\r\n vertexBuffer[vertexIndex++] = screenUVX0;\r\n vertexBuffer[vertexIndex++] = screenUVY0;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[vertexIndex++] = uvx0;\r\n vertexBuffer[vertexIndex++] = uvy1;\r\n vertexBuffer[vertexIndex++] = screenUVX0;\r\n vertexBuffer[vertexIndex++] = screenUVY1;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[vertexIndex++] = topRight.x;\r\n vertexBuffer[vertexIndex++] = topRight.y;\r\n vertexBuffer[vertexIndex++] = uvx1;\r\n vertexBuffer[vertexIndex++] = uvy0;\r\n vertexBuffer[vertexIndex++] = screenUVX1;\r\n vertexBuffer[vertexIndex++] = screenUVY0;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[vertexIndex++] = bottomRight.x;\r\n vertexBuffer[vertexIndex++] = bottomRight.y;\r\n vertexBuffer[vertexIndex++] = uvx1;\r\n vertexBuffer[vertexIndex++] = uvy1;\r\n vertexBuffer[vertexIndex++] = screenUVX1;\r\n vertexBuffer[vertexIndex++] = screenUVY1;\r\n\r\n // This creates and uploads the texture if not already done\r\n const texture = this._addImageAsTexture(image);\r\n\r\n // apply material\r\n material.use();\r\n\r\n this._layout.shader = shader;\r\n // apply layout and geometry\r\n this._layout.use(true);\r\n\r\n // apply time in ms since the page (performance.now())\r\n shader.trySetUniformFloat('u_time_ms', performance.now());\r\n\r\n // apply opacity\r\n shader.trySetUniformFloat('u_opacity', opacity);\r\n\r\n // apply resolution\r\n shader.trySetUniformFloatVector('u_resolution', vec(this._context.width, this._context.height));\r\n\r\n // apply graphic resolution\r\n shader.trySetUniformFloatVector('u_graphic_resolution', vec(imageWidth, imageHeight));\r\n\r\n // apply size\r\n shader.trySetUniformFloatVector('u_size', vec(sw, sh));\r\n\r\n // apply orthographic projection\r\n shader.trySetUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // apply geometry transform\r\n shader.trySetUniformMatrix('u_transform', transform.to4x4());\r\n\r\n // bind graphic image texture 'uniform sampler2D u_graphic;'\r\n gl.activeTexture(gl.TEXTURE0 + 0);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n shader.trySetUniformInt('u_graphic', 0);\r\n\r\n // bind the screen texture\r\n gl.activeTexture(gl.TEXTURE0 + 1);\r\n gl.bindTexture(gl.TEXTURE_2D, this._context.materialScreenTexture);\r\n shader.trySetUniformInt('u_screen_texture', 1);\r\n\r\n // bind any additional textures in the material\r\n material.uploadAndBind(gl);\r\n\r\n // bind quad index buffer\r\n this._quads.bind();\r\n\r\n // Draw a single quad\r\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount++;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n }\r\n\r\n private _addImageAsTexture(image: HTMLImageSource) {\r\n const maybeFiltering = image.getAttribute('filtering');\r\n let filtering: ImageFiltering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n\r\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._context.textureLoader.load(image, filtering, force);\r\n // remove force attribute after upload\r\n image.removeAttribute('forceUpload');\r\n if (this._textures.indexOf(texture) === -1) {\r\n this._textures.push(texture);\r\n }\r\n\r\n return texture;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return false;\r\n }\r\n flush(): void {\r\n // flush does not do anything, material renderer renders immediately per draw\r\n }\r\n\r\n}","import {\r\n ExcaliburGraphicsContext,\r\n LineGraphicsOptions,\r\n RectGraphicsOptions,\r\n PointGraphicsOptions,\r\n ExcaliburGraphicsContextOptions,\r\n DebugDraw,\r\n HTMLImageSource\r\n} from './ExcaliburGraphicsContext';\r\n\r\nimport { Matrix } from '../../Math/matrix';\r\nimport { TransformStack } from './transform-stack';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Color } from '../../Color';\r\nimport { StateStack } from './state-stack';\r\nimport { Logger } from '../../Util/Log';\r\nimport { DebugText } from './debug-text';\r\nimport { ScreenDimension } from '../../Screen';\r\nimport { RenderTarget } from './render-target';\r\nimport { PostProcessor } from '../PostProcessor/PostProcessor';\r\nimport { TextureLoader } from './texture-loader';\r\nimport { RendererPlugin } from './renderer';\r\n\r\n// renderers\r\nimport { LineRenderer } from './line-renderer/line-renderer';\r\nimport { PointRenderer } from './point-renderer/point-renderer';\r\nimport { ScreenPassPainter } from './screen-pass-painter/screen-pass-painter';\r\nimport { ImageRenderer } from './image-renderer/image-renderer';\r\nimport { RectangleRenderer } from './rectangle-renderer/rectangle-renderer';\r\nimport { CircleRenderer } from './circle-renderer/circle-renderer';\r\nimport { Pool } from '../../Util/Pool';\r\nimport { DrawCall } from './draw-call';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Material, MaterialOptions } from './material';\r\nimport { MaterialRenderer } from './material-renderer/material-renderer';\r\nimport { Shader, ShaderOptions } from './shader';\r\n\r\nexport const pixelSnapEpsilon = 0.0001;\r\n\r\nclass ExcaliburGraphicsContextWebGLDebug implements DebugDraw {\r\n private _debugText = new DebugText();\r\n constructor(private _webglCtx: ExcaliburGraphicsContextWebGL) {}\r\n\r\n /**\r\n * Draw a debugging rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */\r\n drawRect(x: number, y: number, width: number, height: number, rectOptions: RectGraphicsOptions = { color: Color.Black }): void {\r\n this.drawLine(vec(x, y), vec(x + width, y), { ...rectOptions });\r\n this.drawLine(vec(x + width, y), vec(x + width, y + height), { ...rectOptions });\r\n this.drawLine(vec(x + width, y + height), vec(x, y + height), { ...rectOptions });\r\n this.drawLine(vec(x, y + height), vec(x, y), { ...rectOptions });\r\n }\r\n\r\n /**\r\n * Draw a debugging line to the context\r\n * @param start\r\n * @param end\r\n * @param lineOptions\r\n */\r\n drawLine(start: Vector, end: Vector, lineOptions: LineGraphicsOptions = { color: Color.Black }): void {\r\n this._webglCtx.draw('ex.line', start, end, lineOptions.color);\r\n }\r\n\r\n /**\r\n * Draw a debugging point to the context\r\n * @param point\r\n * @param pointOptions\r\n */\r\n drawPoint(point: Vector, pointOptions: PointGraphicsOptions = { color: Color.Black, size: 5 }): void {\r\n this._webglCtx.draw('ex.point', point, pointOptions.color, pointOptions.size);\r\n }\r\n\r\n drawText(text: string, pos: Vector) {\r\n this._debugText.write(this._webglCtx, text, pos);\r\n }\r\n}\r\n\r\nexport interface WebGLGraphicsContextInfo {\r\n transform: TransformStack;\r\n state: StateStack;\r\n ortho: Matrix;\r\n context: ExcaliburGraphicsContextWebGL;\r\n}\r\n\r\nexport interface ExcaliburGraphicsContextWebGLOptions extends ExcaliburGraphicsContextOptions {\r\n context?: WebGL2RenderingContext\r\n}\r\n\r\nexport class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext {\r\n private _logger = Logger.getInstance();\r\n private _renderers: Map = new Map();\r\n private _isDrawLifecycle = false;\r\n public useDrawSorting = true;\r\n\r\n private _drawCallPool = new Pool(\r\n () => new DrawCall(),\r\n (instance) => {\r\n instance.priority = 0;\r\n instance.z = 0;\r\n instance.renderer = undefined;\r\n instance.args = undefined;\r\n return instance;\r\n }, 4000);\r\n private _drawCalls: DrawCall[] = [];\r\n\r\n // Main render target\r\n private _renderTarget: RenderTarget;\r\n\r\n // Quad boundary MSAA\r\n private _msaaTarget: RenderTarget;\r\n\r\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\r\n private _postProcessTargets: RenderTarget[] = [];\r\n\r\n private _screenRenderer: ScreenPassPainter;\r\n\r\n private _postprocessors: PostProcessor[] = [];\r\n /**\r\n * Meant for internal use only. Access the internal context at your own risk and no guarantees this will exist in the future.\r\n * @internal\r\n */\r\n public __gl: WebGL2RenderingContext;\r\n\r\n private _transform = new TransformStack();\r\n private _state = new StateStack();\r\n private _ortho!: Matrix;\r\n\r\n /**\r\n * Snaps the drawing x/y coordinate to the nearest whole pixel\r\n */\r\n public snapToPixel: boolean = false;\r\n\r\n /**\r\n * Native context smoothing\r\n */\r\n public readonly smoothing: boolean = false;\r\n\r\n\r\n /**\r\n * Whether the pixel art sampler is enabled for smooth sub pixel anti-aliasing\r\n */\r\n public readonly pixelArtSampler: boolean = false;\r\n\r\n /**\r\n * UV padding in pixels to use in internal image rendering to prevent texture bleed\r\n *\r\n */\r\n public uvPadding = .01;\r\n\r\n public backgroundColor: Color = Color.ExcaliburBlue;\r\n\r\n public textureLoader: TextureLoader;\r\n\r\n public materialScreenTexture: WebGLTexture;\r\n\r\n public get z(): number {\r\n return this._state.current.z;\r\n }\r\n\r\n public set z(value: number) {\r\n this._state.current.z = value;\r\n }\r\n\r\n public get opacity(): number {\r\n return this._state.current.opacity;\r\n }\r\n\r\n public set opacity(value: number) {\r\n this._state.current.opacity = value;\r\n }\r\n\r\n public get tint(): Color {\r\n return this._state.current.tint;\r\n }\r\n\r\n public set tint(color: Color) {\r\n this._state.current.tint = color;\r\n }\r\n\r\n public get width() {\r\n return this.__gl.canvas.width;\r\n }\r\n\r\n public get height() {\r\n return this.__gl.canvas.height;\r\n }\r\n\r\n public get ortho(): Matrix {\r\n return this._ortho;\r\n }\r\n\r\n /**\r\n * Checks the underlying webgl implementation if the requested internal resolution is supported\r\n * @param dim\r\n */\r\n public checkIfResolutionSupported(dim: ScreenDimension): boolean {\r\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\r\n let supported = true;\r\n if (dim.width > 4096 || dim.height > 4096) {\r\n supported = false;\r\n }\r\n return supported;\r\n }\r\n\r\n public readonly multiSampleAntialiasing: boolean = true;\r\n public readonly samples?: number;\r\n public readonly transparency: boolean = true;\r\n\r\n constructor(options: ExcaliburGraphicsContextWebGLOptions) {\r\n const {\r\n canvasElement,\r\n context,\r\n enableTransparency,\r\n antialiasing,\r\n uvPadding,\r\n multiSampleAntialiasing,\r\n pixelArtSampler,\r\n powerPreference,\r\n snapToPixel,\r\n backgroundColor,\r\n useDrawSorting\r\n } = options;\r\n this.__gl = context ?? canvasElement.getContext('webgl2', {\r\n antialias: antialiasing ?? this.smoothing,\r\n premultipliedAlpha: false,\r\n alpha: enableTransparency ?? this.transparency,\r\n depth: false,\r\n powerPreference: powerPreference ?? 'high-performance'\r\n });\r\n if (!this.__gl) {\r\n throw Error('Failed to retrieve webgl context from browser');\r\n }\r\n this.textureLoader = new TextureLoader(this.__gl);\r\n this.snapToPixel = snapToPixel ?? this.snapToPixel;\r\n this.smoothing = antialiasing ?? this.smoothing;\r\n this.transparency = enableTransparency ?? this.transparency;\r\n this.pixelArtSampler = pixelArtSampler ?? this.pixelArtSampler;\r\n this.uvPadding = uvPadding ?? this.uvPadding;\r\n this.multiSampleAntialiasing = typeof multiSampleAntialiasing === 'boolean' ? multiSampleAntialiasing : this.multiSampleAntialiasing;\r\n this.samples = typeof multiSampleAntialiasing === 'object' ? multiSampleAntialiasing.samples : undefined;\r\n this.backgroundColor = backgroundColor ?? this.backgroundColor;\r\n this.useDrawSorting = useDrawSorting ?? this.useDrawSorting;\r\n this._drawCallPool.disableWarnings = true;\r\n this._drawCallPool.preallocate();\r\n this._init();\r\n }\r\n\r\n private _disposed = false;\r\n public dispose() {\r\n if (!this._disposed) {\r\n this._disposed = true;\r\n this.textureLoader.dispose();\r\n for (const renderer of this._renderers.values()) {\r\n renderer.dispose();\r\n }\r\n this._renderers.clear();\r\n this._drawCallPool.dispose();\r\n this._drawCalls.length = 0;\r\n this.__gl = null;\r\n }\r\n }\r\n\r\n private _init() {\r\n const gl = this.__gl;\r\n // Setup viewport and view matrix\r\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\r\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\r\n\r\n // Clear background\r\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\r\n gl.clear(gl.COLOR_BUFFER_BIT);\r\n\r\n // Enable alpha blending\r\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\r\n gl.enable(gl.BLEND);\r\n gl.blendEquation(gl.FUNC_ADD);\r\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\r\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n\r\n // Setup builtin renderers\r\n this.register(new ImageRenderer({\r\n uvPadding: this.uvPadding,\r\n pixelArtSampler: this.pixelArtSampler\r\n }));\r\n this.register(new MaterialRenderer());\r\n this.register(new RectangleRenderer());\r\n this.register(new CircleRenderer());\r\n this.register(new PointRenderer());\r\n this.register(new LineRenderer());\r\n\r\n\r\n this.materialScreenTexture = gl.createTexture();\r\n gl.bindTexture(gl.TEXTURE_2D, this.materialScreenTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n\r\n this._screenRenderer = new ScreenPassPainter(gl);\r\n\r\n this._renderTarget = new RenderTarget({\r\n gl,\r\n transparency: this.transparency,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n });\r\n\r\n this._postProcessTargets = [\r\n new RenderTarget({\r\n gl,\r\n transparency: this.transparency,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n }),\r\n new RenderTarget({\r\n gl,\r\n transparency: this.transparency,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n })\r\n ];\r\n\r\n this._msaaTarget = new RenderTarget({\r\n gl,\r\n transparency: this.transparency,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height,\r\n antialias: this.multiSampleAntialiasing,\r\n samples: this.samples\r\n });\r\n }\r\n\r\n public register(renderer: T) {\r\n this._renderers.set(renderer.type, renderer);\r\n renderer.initialize(this.__gl, this);\r\n }\r\n\r\n public get(rendererName: string): RendererPlugin {\r\n return this._renderers.get(rendererName);\r\n }\r\n\r\n private _currentRenderer: RendererPlugin;\r\n\r\n private _isCurrentRenderer(renderer: RendererPlugin): boolean {\r\n if (!this._currentRenderer || this._currentRenderer === renderer) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n public beginDrawLifecycle() {\r\n this._isDrawLifecycle = true;\r\n }\r\n\r\n public endDrawLifecycle() {\r\n this._isDrawLifecycle = false;\r\n }\r\n\r\n public draw(rendererName: TRenderer['type'], ...args: Parameters) {\r\n if (!this._isDrawLifecycle) {\r\n this._logger.warnOnce(\r\n `Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` +\r\n `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\r\n }\r\n\r\n const renderer = this._renderers.get(rendererName);\r\n if (renderer) {\r\n if (this.useDrawSorting) {\r\n const drawCall = this._drawCallPool.get();\r\n drawCall.z = this._state.current.z;\r\n drawCall.priority = renderer.priority;\r\n drawCall.renderer = rendererName;\r\n this.getTransform().clone(drawCall.transform);\r\n drawCall.state.z = this._state.current.z;\r\n drawCall.state.opacity = this._state.current.opacity;\r\n drawCall.state.tint = this._state.current.tint;\r\n drawCall.state.material = this._state.current.material;\r\n drawCall.args = args;\r\n this._drawCalls.push(drawCall);\r\n } else {\r\n // Set the current renderer if not defined\r\n if (!this._currentRenderer) {\r\n this._currentRenderer = renderer;\r\n }\r\n\r\n if (!this._isCurrentRenderer(renderer)) {\r\n // switching graphics means we must flush the previous\r\n this._currentRenderer.flush();\r\n }\r\n\r\n // If we are still using the same renderer we can add to the current batch\r\n renderer.draw(...args);\r\n\r\n this._currentRenderer = renderer;\r\n }\r\n } else {\r\n throw Error(`No renderer with name ${rendererName} has been registered`);\r\n }\r\n }\r\n\r\n public resetTransform(): void {\r\n this._transform.current = AffineMatrix.identity();\r\n }\r\n\r\n public updateViewport(resolution: ScreenDimension): void {\r\n const gl = this.__gl;\r\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\r\n\r\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\r\n this._msaaTarget.setResolution(gl.canvas.width, gl.canvas.height);\r\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\r\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\r\n }\r\n\r\n drawImage(image: HTMLImageSource, x: number, y: number): void;\r\n drawImage(image: HTMLImageSource, x: number, y: number, width: number, height: number): void;\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void;\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void {\r\n if (swidth === 0 || sheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (dwidth === 0 || dheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (image.width === 0 || image.height === 0) {\r\n return; // zero dimension source exit early\r\n }\r\n\r\n if (!image) {\r\n Logger.getInstance().warn('Cannot draw a null or undefined image');\r\n // tslint:disable-next-line: no-console\r\n if (console.trace) {\r\n // tslint:disable-next-line: no-console\r\n console.trace();\r\n }\r\n return;\r\n }\r\n\r\n if (this._state.current.material) {\r\n this.draw('ex.material', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\r\n } else {\r\n this.draw('ex.image', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\r\n }\r\n }\r\n\r\n public drawLine(start: Vector, end: Vector, color: Color, thickness = 1) {\r\n this.draw('ex.rectangle', start, end, color, thickness);\r\n }\r\n\r\n public drawRectangle(pos: Vector, width: number, height: number, color: Color, stroke?: Color, strokeThickness?: number) {\r\n this.draw('ex.rectangle', pos, width, height, color, stroke, strokeThickness);\r\n }\r\n\r\n public drawCircle(pos: Vector, radius: number, color: Color, stroke?: Color, thickness?: number) {\r\n this.draw('ex.circle', pos, radius, color, stroke, thickness);\r\n }\r\n\r\n debug = new ExcaliburGraphicsContextWebGLDebug(this);\r\n\r\n public save(): void {\r\n this._transform.save();\r\n this._state.save();\r\n }\r\n\r\n public restore(): void {\r\n this._transform.restore();\r\n this._state.restore();\r\n }\r\n\r\n public translate(x: number, y: number): void {\r\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\r\n }\r\n\r\n public rotate(angle: number): void {\r\n this._transform.rotate(angle);\r\n }\r\n\r\n public scale(x: number, y: number): void {\r\n this._transform.scale(x, y);\r\n }\r\n\r\n public transform(matrix: AffineMatrix) {\r\n this._transform.current = matrix;\r\n }\r\n\r\n public getTransform(): AffineMatrix {\r\n return this._transform.current;\r\n }\r\n\r\n public multiply(m: AffineMatrix) {\r\n this._transform.current.multiply(m, this._transform.current);\r\n }\r\n\r\n public addPostProcessor(postprocessor: PostProcessor) {\r\n this._postprocessors.push(postprocessor);\r\n postprocessor.initialize(this.__gl);\r\n }\r\n\r\n public removePostProcessor(postprocessor: PostProcessor) {\r\n const index = this._postprocessors.indexOf(postprocessor);\r\n if (index !== -1) {\r\n this._postprocessors.splice(index, 1);\r\n }\r\n }\r\n\r\n public clearPostProcessors() {\r\n this._postprocessors.length = 0;\r\n }\r\n\r\n private _totalPostProcessorTime = 0;\r\n public updatePostProcessors(delta: number) {\r\n for (const postprocessor of this._postprocessors) {\r\n const shader = postprocessor.getShader();\r\n shader.use();\r\n const uniforms = shader.getUniforms();\r\n this._totalPostProcessorTime += delta;\r\n\r\n if (uniforms.find(u => u.name ==='u_time_ms')) {\r\n shader.setUniformFloat('u_time_ms', this._totalPostProcessorTime);\r\n }\r\n if (uniforms.find(u => u.name ==='u_elapsed_ms')) {\r\n shader.setUniformFloat('u_elapsed_ms', delta);\r\n }\r\n if (uniforms.find(u => u.name ==='u_resolution')) {\r\n shader.setUniformFloatVector('u_resolution', vec(this.width, this.height));\r\n }\r\n\r\n if (postprocessor.onUpdate) {\r\n postprocessor.onUpdate(delta);\r\n }\r\n }\r\n }\r\n\r\n public set material(material: Material) {\r\n this._state.current.material = material;\r\n }\r\n\r\n public get material(): Material | null {\r\n return this._state.current.material;\r\n }\r\n\r\n /**\r\n * Creates and initializes the material which compiles the internal shader\r\n * @param options\r\n * @returns Material\r\n */\r\n public createMaterial(options: Omit): Material {\r\n const material = new Material({...options, graphicsContext: this});\r\n return material;\r\n }\r\n\r\n public createShader(options: Omit): Shader {\r\n const gl = this.__gl;\r\n const { vertexSource, fragmentSource } = options;\r\n const shader = new Shader({\r\n gl,\r\n vertexSource,\r\n fragmentSource\r\n });\r\n shader.compile();\r\n return shader;\r\n }\r\n\r\n clear() {\r\n const gl = this.__gl;\r\n const currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\r\n currentTarget.use();\r\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\r\n // Clear the context with the newly set color. This is\r\n // the function call that actually does the drawing.\r\n gl.clear(gl.COLOR_BUFFER_BIT);\r\n }\r\n\r\n /**\r\n * Flushes all batched rendering to the screen\r\n */\r\n flush() {\r\n // render target captures all draws and redirects to the render target\r\n let currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\r\n currentTarget.use();\r\n\r\n if (this.useDrawSorting) {\r\n // sort draw calls\r\n // Find the original order of the first instance of the draw call\r\n const originalSort = new Map();\r\n for (const [name] of this._renderers) {\r\n const firstIndex = this._drawCalls.findIndex(dc => dc.renderer === name);\r\n originalSort.set(name, firstIndex);\r\n }\r\n\r\n this._drawCalls.sort((a, b) => {\r\n const zIndex = a.z - b.z;\r\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\r\n const priority = a.priority - b.priority;\r\n if (zIndex === 0) { // sort by z first\r\n if (priority === 0) { // sort by priority\r\n return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\r\n }\r\n return priority;\r\n }\r\n return zIndex;\r\n });\r\n\r\n const oldTransform = this._transform.current;\r\n const oldState = this._state.current;\r\n\r\n if (this._drawCalls.length) {\r\n let currentRendererName = this._drawCalls[0].renderer;\r\n let currentRenderer = this._renderers.get(currentRendererName);\r\n for (let i = 0; i < this._drawCalls.length; i++) {\r\n // hydrate the state for renderers\r\n this._transform.current = this._drawCalls[i].transform;\r\n this._state.current = this._drawCalls[i].state;\r\n\r\n if (this._drawCalls[i].renderer !== currentRendererName) {\r\n // switching graphics renderer means we must flush the previous\r\n currentRenderer.flush();\r\n currentRendererName = this._drawCalls[i].renderer;\r\n currentRenderer = this._renderers.get(currentRendererName);\r\n }\r\n\r\n // ! hack to grab screen texture before materials run because they might want it\r\n if (currentRenderer instanceof MaterialRenderer && this.material.isUsingScreenTexture) {\r\n currentTarget.copyToTexture(this.materialScreenTexture);\r\n currentTarget.use();\r\n }\r\n // If we are still using the same renderer we can add to the current batch\r\n currentRenderer.draw(...this._drawCalls[i].args);\r\n }\r\n if (currentRenderer.hasPendingDraws()) {\r\n currentRenderer.flush();\r\n }\r\n }\r\n\r\n // reset state\r\n this._transform.current = oldTransform;\r\n this._state.current = oldState;\r\n\r\n // reclaim draw calls\r\n this._drawCallPool.done();\r\n this._drawCalls.length = 0;\r\n } else {\r\n // This is the final flush at the moment to draw any leftover pending draw\r\n for (const renderer of this._renderers.values()) {\r\n if (renderer.hasPendingDraws()) {\r\n renderer.flush();\r\n }\r\n }\r\n }\r\n\r\n currentTarget.disable();\r\n\r\n // post process step\r\n if (this._postprocessors.length > 0) {\r\n const source = currentTarget.toRenderSource();\r\n source.use();\r\n }\r\n\r\n // flip flop render targets for post processing\r\n for (let i = 0; i < this._postprocessors.length; i++) {\r\n currentTarget = this._postProcessTargets[i % 2];\r\n this._postProcessTargets[i % 2].use();\r\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\r\n this._postProcessTargets[i % 2].toRenderSource().use();\r\n }\r\n\r\n // Final blit to the screen\r\n currentTarget.blitToScreen();\r\n }\r\n}\r\n","import {\r\n ExcaliburGraphicsContext,\r\n LineGraphicsOptions,\r\n PointGraphicsOptions,\r\n ExcaliburGraphicsContextOptions,\r\n DebugDraw,\r\n HTMLImageSource\r\n} from './ExcaliburGraphicsContext';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Color } from '../../Color';\r\nimport { StateStack } from './state-stack';\r\nimport { GraphicsDiagnostics } from '../GraphicsDiagnostics';\r\nimport { DebugText } from './debug-text';\r\nimport { ScreenDimension } from '../../Screen';\r\nimport { PostProcessor } from '../PostProcessor/PostProcessor';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Material, MaterialOptions } from './material';\r\n\r\nconst pixelSnapEpsilon = 0.0001;\r\n\r\nclass ExcaliburGraphicsContext2DCanvasDebug implements DebugDraw {\r\n private _debugText = new DebugText();\r\n constructor(private _ex: ExcaliburGraphicsContext2DCanvas) {}\r\n /**\r\n * Draw a debug rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */\r\n drawRect(x: number, y: number, width: number, height: number): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.strokeStyle = 'red';\r\n this._ex.__ctx.strokeRect(\r\n this._ex.snapToPixel ? ~~(x + pixelSnapEpsilon) : x,\r\n this._ex.snapToPixel ? ~~(y + pixelSnapEpsilon) : y,\r\n this._ex.snapToPixel ? ~~(width + pixelSnapEpsilon) : width,\r\n this._ex.snapToPixel ? ~~(height + pixelSnapEpsilon) : height\r\n );\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawLine(start: Vector, end: Vector, lineOptions: LineGraphicsOptions = { color: Color.Black }): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.beginPath();\r\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\r\n this._ex.__ctx.moveTo(\r\n this._ex.snapToPixel ? ~~(start.x + pixelSnapEpsilon) : start.x,\r\n this._ex.snapToPixel ? ~~(start.y + pixelSnapEpsilon) : start.y\r\n );\r\n this._ex.__ctx.lineTo(\r\n this._ex.snapToPixel ? ~~(end.x + pixelSnapEpsilon) : end.x,\r\n this._ex.snapToPixel ? ~~(end.y + pixelSnapEpsilon) : end.y\r\n );\r\n this._ex.__ctx.lineWidth = 2;\r\n this._ex.__ctx.stroke();\r\n this._ex.__ctx.closePath();\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawPoint(point: Vector, pointOptions: PointGraphicsOptions = { color: Color.Black, size: 5 }): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.beginPath();\r\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\r\n this._ex.__ctx.arc(\r\n this._ex.snapToPixel ? ~~(point.x + pixelSnapEpsilon) : point.x,\r\n this._ex.snapToPixel ? ~~(point.y + pixelSnapEpsilon) : point.y,\r\n pointOptions.size,\r\n 0,\r\n Math.PI * 2\r\n );\r\n this._ex.__ctx.fill();\r\n this._ex.__ctx.closePath();\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawText(text: string, pos: Vector) {\r\n this._debugText.write(this._ex, text, pos);\r\n }\r\n}\r\n\r\nexport interface ExcaliburGraphicsContext2DOptions extends ExcaliburGraphicsContextOptions {\r\n context?: CanvasRenderingContext2D;\r\n}\r\n\r\nexport class ExcaliburGraphicsContext2DCanvas implements ExcaliburGraphicsContext {\r\n /**\r\n * Meant for internal use only. Access the internal context at your own risk and no guarantees this will exist in the future.\r\n * @internal\r\n */\r\n public __ctx: CanvasRenderingContext2D;\r\n public get width() {\r\n return this.__ctx.canvas.width;\r\n }\r\n\r\n public get height() {\r\n return this.__ctx.canvas.height;\r\n }\r\n\r\n /**\r\n * Unused in Canvas implementation\r\n */\r\n public readonly useDrawSorting: boolean = false;\r\n\r\n /**\r\n * Unused in Canvas implementation\r\n */\r\n public z: number = 0;\r\n\r\n public backgroundColor: Color = Color.ExcaliburBlue;\r\n\r\n private _state = new StateStack();\r\n\r\n public get opacity(): number {\r\n return this._state.current.opacity;\r\n }\r\n\r\n public set opacity(value: number) {\r\n this._state.current.opacity = value;\r\n }\r\n\r\n public get tint(): Color {\r\n return this._state.current.tint;\r\n }\r\n\r\n public set tint(color: Color) {\r\n this._state.current.tint = color;\r\n }\r\n\r\n public snapToPixel: boolean = false;\r\n\r\n public get smoothing(): boolean {\r\n return this.__ctx.imageSmoothingEnabled;\r\n }\r\n\r\n public set smoothing(value: boolean) {\r\n this.__ctx.imageSmoothingEnabled = value;\r\n }\r\n\r\n constructor(options: ExcaliburGraphicsContext2DOptions) {\r\n const { canvasElement, context, enableTransparency, snapToPixel, antialiasing: smoothing, backgroundColor } = options;\r\n this.__ctx = context ?? canvasElement.getContext('2d', {\r\n alpha: enableTransparency ?? true\r\n });\r\n if (!this.__ctx) {\r\n throw new Error('Cannot build new ExcaliburGraphicsContext2D for some reason!');\r\n }\r\n this.backgroundColor = backgroundColor ?? this.backgroundColor;\r\n this.snapToPixel = snapToPixel ?? this.snapToPixel;\r\n this.smoothing = smoothing ?? this.smoothing;\r\n }\r\n\r\n public resetTransform(): void {\r\n this.__ctx.resetTransform();\r\n }\r\n\r\n public updateViewport(_resolution: ScreenDimension): void {\r\n // pass\r\n }\r\n\r\n /**\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate using the images width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate with a specific width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number, width: number, height: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context specifying the source image coordinates (sx, sy, swidth, sheight)\r\n * and to a specific destination on the context (dx, dy, dwidth, dheight)\r\n */\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void;\r\n\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void {\r\n if (swidth === 0 || sheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (dwidth === 0 || dheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (image.width === 0 || image.height === 0) {\r\n return; // zero dimension source exit early\r\n }\r\n\r\n this.__ctx.globalAlpha = this.opacity;\r\n const args = [image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight]\r\n .filter((a) => a !== undefined)\r\n .map((a) => (typeof a === 'number' && this.snapToPixel ? ~~a : a));\r\n this.__ctx.drawImage.apply(this.__ctx, args);\r\n GraphicsDiagnostics.DrawCallCount++;\r\n GraphicsDiagnostics.DrawnImagesCount = 1;\r\n }\r\n\r\n public drawLine(start: Vector, end: Vector, color: Color, thickness = 1) {\r\n this.__ctx.save();\r\n this.__ctx.beginPath();\r\n this.__ctx.strokeStyle = color.toString();\r\n this.__ctx.moveTo(\r\n this.snapToPixel ? ~~ (start.x + pixelSnapEpsilon) : start.x,\r\n this.snapToPixel ? ~~(start.y + pixelSnapEpsilon) : start.y\r\n );\r\n this.__ctx.lineTo(\r\n this.snapToPixel ? ~~ (end.x + pixelSnapEpsilon) : end.x,\r\n this.snapToPixel ? ~~(end.y + pixelSnapEpsilon) : end.y\r\n );\r\n this.__ctx.lineWidth = thickness;\r\n this.__ctx.stroke();\r\n this.__ctx.closePath();\r\n this.__ctx.restore();\r\n }\r\n\r\n public drawRectangle(pos: Vector, width: number, height: number, color: Color) {\r\n this.__ctx.save();\r\n this.__ctx.fillStyle = color.toString();\r\n this.__ctx.fillRect(\r\n this.snapToPixel ? ~~(pos.x + pixelSnapEpsilon) : pos.x,\r\n this.snapToPixel ? ~~(pos.y + pixelSnapEpsilon) : pos.y,\r\n this.snapToPixel ? ~~(width + pixelSnapEpsilon) : width,\r\n this.snapToPixel ? ~~(height + pixelSnapEpsilon) : height\r\n );\r\n this.__ctx.restore();\r\n }\r\n\r\n public drawCircle(pos: Vector, radius: number, color: Color, stroke?: Color, thickness?: number) {\r\n this.__ctx.save();\r\n this.__ctx.beginPath();\r\n if (stroke) {\r\n this.__ctx.strokeStyle = stroke.toString();\r\n }\r\n if (thickness) {\r\n this.__ctx.lineWidth = thickness;\r\n }\r\n this.__ctx.fillStyle = color.toString();\r\n this.__ctx.arc(\r\n this.snapToPixel ? ~~(pos.x + pixelSnapEpsilon) : pos.x,\r\n this.snapToPixel ? ~~(pos.y + pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2\r\n );\r\n this.__ctx.fill();\r\n if (stroke) {\r\n this.__ctx.stroke();\r\n }\r\n this.__ctx.closePath();\r\n this.__ctx.restore();\r\n }\r\n\r\n debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\r\n\r\n /**\r\n * Save the current state of the canvas to the stack (transforms and opacity)\r\n */\r\n save(): void {\r\n this.__ctx.save();\r\n this._state.save();\r\n }\r\n\r\n /**\r\n * Restore the state of the canvas from the stack\r\n */\r\n restore(): void {\r\n this.__ctx.restore();\r\n this._state.restore();\r\n }\r\n\r\n /**\r\n * Translate the origin of the context by an x and y\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number): void {\r\n this.__ctx.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\r\n }\r\n\r\n /**\r\n * Rotate the context about the current origin\r\n */\r\n rotate(angle: number): void {\r\n this.__ctx.rotate(angle);\r\n }\r\n\r\n /**\r\n * Scale the context by an x and y factor\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number): void {\r\n this.__ctx.scale(x, y);\r\n }\r\n\r\n public getTransform(): AffineMatrix {\r\n throw new Error('Not implemented');\r\n }\r\n\r\n public multiply(_m: AffineMatrix): void {\r\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\r\n }\r\n\r\n public addPostProcessor(_postprocessor: PostProcessor) {\r\n // pass\r\n }\r\n\r\n public removePostProcessor(_postprocessor: PostProcessor) {\r\n // pass\r\n }\r\n\r\n public clearPostProcessors() {\r\n // pass\r\n }\r\n\r\n public updatePostProcessors(delta: number) {\r\n // pass\r\n }\r\n\r\n public beginDrawLifecycle() {\r\n // pass\r\n }\r\n\r\n public endDrawLifecycle() {\r\n // pass\r\n }\r\n\r\n public set material(material: Material | null) {\r\n this._state.current.material = material;\r\n }\r\n\r\n public get material(): Material | null {\r\n return this._state.current.material;\r\n }\r\n\r\n public createMaterial(options: Omit): Material {\r\n // pass\r\n return null;\r\n }\r\n\r\n clear(): void {\r\n // Clear frame\r\n this.__ctx.clearRect(0, 0, this.width, this.height);\r\n this.__ctx.fillStyle = this.backgroundColor.toString();\r\n this.__ctx.fillRect(0, 0, this.width, this.height);\r\n GraphicsDiagnostics.clear();\r\n }\r\n\r\n /**\r\n * Flushes the batched draw calls to the screen\r\n */\r\n flush(): void {\r\n // pass\r\n }\r\n\r\n dispose(): void {\r\n this.__ctx = null;\r\n }\r\n}\r\n","import { vec, Vector } from './Math/vector';\r\nimport { Logger } from './Util/Log';\r\nimport { Camera } from './Camera';\r\nimport { BrowserEvents } from './Util/Browser';\r\nimport { BoundingBox } from './Collision/Index';\r\nimport { ExcaliburGraphicsContext } from './Graphics/Context/ExcaliburGraphicsContext';\r\nimport { getPosition } from './Util/Util';\r\nimport { ExcaliburGraphicsContextWebGL } from './Graphics/Context/ExcaliburGraphicsContextWebGL';\r\nimport { ExcaliburGraphicsContext2DCanvas } from './Graphics/Context/ExcaliburGraphicsContext2DCanvas';\r\nimport { EventEmitter } from './EventEmitter';\r\n\r\n/**\r\n * Enum representing the different display modes available to Excalibur.\r\n */\r\nexport enum DisplayMode {\r\n /**\r\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\r\n */\r\n Fixed = 'Fixed',\r\n\r\n /**\r\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\r\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */\r\n FitContainerAndFill = 'FitContainerAndFill',\r\n\r\n /**\r\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\r\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */\r\n FitScreenAndFill = 'FitScreenAndFill',\r\n\r\n /**\r\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitContainer]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */\r\n FitContainerAndZoom = 'FitContainerAndZoom',\r\n\r\n /**\r\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitScreen]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */\r\n FitScreenAndZoom = 'FitScreenAndZoom',\r\n\r\n /**\r\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\r\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\r\n *\r\n * You may want to center your game here is an example\r\n * ```html\r\n * \r\n * \r\n *
\r\n * \r\n *
\r\n * \r\n * ```\r\n *\r\n * ```css\r\n * // css\r\n * main {\r\n * display: flex;\r\n * align-items: center;\r\n * justify-content: center;\r\n * height: 100%;\r\n * width: 100%;\r\n * }\r\n * ```\r\n */\r\n FitScreen = 'FitScreen',\r\n\r\n /**\r\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\r\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\r\n */\r\n FillScreen = 'FillScreen',\r\n\r\n /**\r\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\r\n */\r\n FitContainer = 'FitContainer',\r\n\r\n /**\r\n * Use the parent DOM container's css width/height for the game resolution dynamically\r\n */\r\n FillContainer = 'FillContainer'\r\n}\r\n\r\n/**\r\n * Convenience class for quick resolutions\r\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\r\n */\r\nexport class Resolution {\r\n /* istanbul ignore next */\r\n public static get SVGA(): ScreenDimension {\r\n return { width: 800, height: 600 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get Standard(): ScreenDimension {\r\n return { width: 1920, height: 1080 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get Atari2600(): ScreenDimension {\r\n return { width: 160, height: 192 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get GameBoy(): ScreenDimension {\r\n return { width: 160, height: 144 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get GameBoyAdvance(): ScreenDimension {\r\n return { width: 240, height: 160 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get NintendoDS(): ScreenDimension {\r\n return { width: 256, height: 192 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get NES(): ScreenDimension {\r\n return { width: 256, height: 224 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get SNES(): ScreenDimension {\r\n return { width: 256, height: 244 };\r\n }\r\n}\r\n\r\nexport interface ScreenDimension {\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface ScreenOptions {\r\n /**\r\n * Canvas element to build a screen on\r\n */\r\n canvas: HTMLCanvasElement;\r\n\r\n /**\r\n * Graphics context for the screen\r\n */\r\n context: ExcaliburGraphicsContext;\r\n\r\n /**\r\n * Browser abstraction\r\n */\r\n browser: BrowserEvents;\r\n /**\r\n * Optionally set antialiasing, defaults to true. If set to true, images will be smoothed\r\n */\r\n antialiasing?: boolean;\r\n\r\n /**\r\n * Optionally set the image rendering CSS hint on the canvas element, default is auto\r\n */\r\n canvasImageRendering?: 'auto' | 'pixelated';\r\n /**\r\n * Optionally override the pixel ratio to use for the screen, otherwise calculated automatically from the browser\r\n */\r\n pixelRatio?: number;\r\n /**\r\n * Optionally specify the actual pixel resolution in width/height pixels (also known as logical resolution), by default the\r\n * resolution will be the same as the viewport. Resolution will be overridden by [[DisplayMode.FillContainer]] and\r\n * [[DisplayMode.FillScreen]].\r\n */\r\n resolution?: ScreenDimension;\r\n /**\r\n * Visual viewport size in css pixel, if resolution is not specified it will be the same as the viewport\r\n */\r\n viewport: ScreenDimension;\r\n /**\r\n * Set the display mode of the screen, by default DisplayMode.Fixed.\r\n */\r\n displayMode?: DisplayMode;\r\n}\r\n\r\n/**\r\n * Fires when the screen resizes, useful if you have logic that needs to be aware of resolution/viewport constraints\r\n */\r\nexport interface ScreenResizeEvent {\r\n /**\r\n * Current viewport in css pixels of the screen\r\n */\r\n viewport: ScreenDimension;\r\n /**\r\n * Current resolution in world pixels of the screen\r\n */\r\n resolution: ScreenDimension;\r\n}\r\n\r\n/**\r\n * Fires when the pixel ratio changes, useful to know if you've moved to a hidpi screen or back\r\n */\r\nexport interface PixelRatioChangeEvent {\r\n /**\r\n * Current pixel ratio of the screen\r\n */\r\n pixelRatio: number;\r\n}\r\n\r\n/**\r\n * Fires when the browser fullscreen api is successfully engaged or disengaged\r\n */\r\nexport interface FullScreenChangeEvent {\r\n /**\r\n * Current fullscreen state\r\n */\r\n fullscreen: boolean;\r\n}\r\n\r\n/**\r\n * Built in events supported by all entities\r\n */\r\nexport type ScreenEvents = {\r\n /**\r\n * Fires when the screen resizes, useful if you have logic that needs to be aware of resolution/viewport constraints\r\n */\r\n 'resize': ScreenResizeEvent;\r\n /**\r\n * Fires when the pixel ratio changes, useful to know if you've moved to a hidpi screen or back\r\n */\r\n 'pixelratio': PixelRatioChangeEvent;\r\n /**\r\n * Fires when the browser fullscreen api is successfully engaged or disengaged\r\n */\r\n 'fullscreen': FullScreenChangeEvent;\r\n};\r\n\r\nexport const ScreenEvents = {\r\n ScreenResize: 'resize',\r\n PixelRatioChange: 'pixelratio',\r\n FullScreenChange: 'fullscreen'\r\n} as const;\r\n\r\n/**\r\n * The Screen handles all aspects of interacting with the screen for Excalibur.\r\n */\r\nexport class Screen {\r\n public graphicsContext: ExcaliburGraphicsContext;\r\n /**\r\n * Listen to screen events [[ScreenEvents]]\r\n */\r\n public events = new EventEmitter();\r\n private _canvas: HTMLCanvasElement;\r\n private _antialiasing: boolean = true;\r\n private _canvasImageRendering: 'auto' | 'pixelated' = 'auto';\r\n private _contentResolution: ScreenDimension;\r\n private _browser: BrowserEvents;\r\n private _camera: Camera;\r\n private _resolution: ScreenDimension;\r\n private _resolutionStack: ScreenDimension[] = [];\r\n private _viewport: ScreenDimension;\r\n private _viewportStack: ScreenDimension[] = [];\r\n private _pixelRatioOverride: number | null = null;\r\n private _displayMode: DisplayMode;\r\n private _isFullScreen = false;\r\n private _mediaQueryList: MediaQueryList;\r\n private _isDisposed = false;\r\n private _logger = Logger.getInstance();\r\n private _resizeObserver: ResizeObserver;\r\n\r\n constructor(options: ScreenOptions) {\r\n this.viewport = options.viewport;\r\n this.resolution = options.resolution ?? { ...this.viewport };\r\n this._contentResolution = this.resolution;\r\n this._displayMode = options.displayMode ?? DisplayMode.Fixed;\r\n this._canvas = options.canvas;\r\n this.graphicsContext = options.context;\r\n this._antialiasing = options.antialiasing ?? this._antialiasing;\r\n this._canvasImageRendering = options.canvasImageRendering ?? this._canvasImageRendering;\r\n this._browser = options.browser;\r\n this._pixelRatioOverride = options.pixelRatio;\r\n\r\n this._applyDisplayMode();\r\n\r\n this._listenForPixelRatio();\r\n\r\n this._canvas.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n this.applyResolutionAndViewport();\r\n }\r\n\r\n private _listenForPixelRatio() {\r\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) {\r\n // Safari <=13.1 workaround, remove any existing handlers\r\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\r\n }\r\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\r\n\r\n // Safari <=13.1 workaround\r\n if (this._mediaQueryList.addEventListener) {\r\n this._mediaQueryList.addEventListener('change', this._pixelRatioChangeHandler, { once: true });\r\n } else {\r\n this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\r\n }\r\n }\r\n\r\n public dispose(): void {\r\n if (!this._isDisposed) {\r\n // Clean up handlers\r\n this._isDisposed = true;\r\n this.events.clear();\r\n this._browser.window.off('resize', this._resizeHandler);\r\n this._browser.window.clear();\r\n if (this._resizeObserver) {\r\n this._resizeObserver.disconnect();\r\n }\r\n this.parent.removeEventListener('resize', this._resizeHandler);\r\n // Safari <=13.1 workaround\r\n if (this._mediaQueryList.removeEventListener) {\r\n this._mediaQueryList.removeEventListener('change', this._pixelRatioChangeHandler);\r\n } else {\r\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\r\n }\r\n this._canvas.removeEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n this._canvas = null;\r\n }\r\n }\r\n\r\n private _fullscreenChangeHandler = () => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._isFullScreen = !this._isFullScreen;\r\n this._logger.debug('Fullscreen Change', this._isFullScreen);\r\n this.events.emit('fullscreen', {\r\n fullscreen: this.isFullScreen\r\n } satisfies FullScreenChangeEvent);\r\n };\r\n\r\n private _pixelRatioChangeHandler = () => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._logger.debug('Pixel Ratio Change', window.devicePixelRatio);\r\n this._listenForPixelRatio();\r\n this._devicePixelRatio = this._calculateDevicePixelRatio();\r\n this.applyResolutionAndViewport();\r\n this.events.emit('pixelratio', {\r\n pixelRatio: this.pixelRatio\r\n } satisfies PixelRatioChangeEvent);\r\n };\r\n\r\n private _resizeHandler = () => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n const parent = this.parent;\r\n this._logger.debug('View port resized');\r\n this._setResolutionAndViewportByDisplayMode(parent);\r\n this.applyResolutionAndViewport();\r\n // Emit resize event\r\n this.events.emit('resize', {\r\n resolution: this.resolution,\r\n viewport: this.viewport\r\n } satisfies ScreenResizeEvent);\r\n };\r\n\r\n private _calculateDevicePixelRatio() {\r\n if (window.devicePixelRatio < 1) {\r\n return 1;\r\n }\r\n\r\n const devicePixelRatio = window.devicePixelRatio || 1;\r\n\r\n return devicePixelRatio;\r\n }\r\n\r\n // Asking the window.devicePixelRatio is expensive we do it once\r\n private _devicePixelRatio = this._calculateDevicePixelRatio();\r\n\r\n /**\r\n * Returns the computed pixel ratio, first using any override, then the device pixel ratio\r\n */\r\n public get pixelRatio(): number {\r\n if (this._pixelRatioOverride) {\r\n return this._pixelRatioOverride;\r\n }\r\n\r\n return this._devicePixelRatio;\r\n }\r\n\r\n /**\r\n * Get or set the pixel ratio override\r\n *\r\n * You will need to call applyResolutionAndViewport() affect change on the screen\r\n */\r\n public get pixelRatioOverride(): number | undefined {\r\n return this._pixelRatioOverride;\r\n }\r\n\r\n public set pixelRatioOverride(value: number | undefined) {\r\n this._pixelRatioOverride = value;\r\n }\r\n\r\n public get isHiDpi() {\r\n return this.pixelRatio !== 1;\r\n }\r\n\r\n public get displayMode(): DisplayMode {\r\n return this._displayMode;\r\n }\r\n\r\n public get canvas(): HTMLCanvasElement {\r\n return this._canvas;\r\n }\r\n\r\n public get parent(): HTMLElement | Window {\r\n switch (this.displayMode) {\r\n case DisplayMode.FillContainer:\r\n case DisplayMode.FitContainer:\r\n case DisplayMode.FitContainerAndFill:\r\n case DisplayMode.FitContainerAndZoom:\r\n return this.canvas.parentElement || document.body;\r\n default:\r\n return window;\r\n }\r\n }\r\n\r\n public get resolution(): ScreenDimension {\r\n return this._resolution;\r\n }\r\n\r\n public set resolution(resolution: ScreenDimension) {\r\n this._resolution = resolution;\r\n }\r\n\r\n public get viewport(): ScreenDimension {\r\n if (this._viewport) {\r\n return this._viewport;\r\n }\r\n return this._resolution;\r\n }\r\n\r\n public set viewport(viewport: ScreenDimension) {\r\n this._viewport = viewport;\r\n }\r\n\r\n public get aspectRatio() {\r\n return this._resolution.width / this._resolution.height;\r\n }\r\n\r\n public get scaledWidth() {\r\n return this._resolution.width * this.pixelRatio;\r\n }\r\n\r\n public get scaledHeight() {\r\n return this._resolution.height * this.pixelRatio;\r\n }\r\n\r\n public setCurrentCamera(camera: Camera) {\r\n this._camera = camera;\r\n }\r\n\r\n public pushResolutionAndViewport() {\r\n this._resolutionStack.push(this.resolution);\r\n this._viewportStack.push(this.viewport);\r\n\r\n this.resolution = { ...this.resolution };\r\n this.viewport = { ...this.viewport };\r\n }\r\n\r\n public peekViewport(): ScreenDimension {\r\n return this._viewportStack[this._viewportStack.length - 1];\r\n }\r\n\r\n public peekResolution(): ScreenDimension {\r\n return this._resolutionStack[this._resolutionStack.length - 1];\r\n }\r\n\r\n public popResolutionAndViewport() {\r\n if (this._resolutionStack.length && this._viewportStack.length) {\r\n this.resolution = this._resolutionStack.pop();\r\n this.viewport = this._viewportStack.pop();\r\n }\r\n }\r\n\r\n public applyResolutionAndViewport() {\r\n this._canvas.width = this.scaledWidth;\r\n this._canvas.height = this.scaledHeight;\r\n\r\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n const supported = this.graphicsContext.checkIfResolutionSupported({\r\n width: this.scaledWidth,\r\n height: this.scaledHeight\r\n });\r\n if (!supported) {\r\n this._logger.warnOnce(\r\n `The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` +\r\n ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' +\r\n ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' +\r\n ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).');\r\n }\r\n }\r\n\r\n if (this._canvasImageRendering === 'auto') {\r\n this._canvas.style.imageRendering = 'auto';\r\n } else {\r\n this._canvas.style.imageRendering = 'pixelated';\r\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\r\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\r\n if (this._canvas.style.imageRendering === '') {\r\n this._canvas.style.imageRendering = 'crisp-edges';\r\n }\r\n }\r\n this._canvas.style.width = this.viewport.width + 'px';\r\n this._canvas.style.height = this.viewport.height + 'px';\r\n\r\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\r\n this.graphicsContext.updateViewport(this.resolution);\r\n this.graphicsContext.resetTransform();\r\n this.graphicsContext.smoothing = this._antialiasing;\r\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) {\r\n this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\r\n }\r\n }\r\n\r\n public get antialiasing() {\r\n return this._antialiasing;\r\n }\r\n\r\n public set antialiasing(isSmooth: boolean) {\r\n this._antialiasing = isSmooth;\r\n this.graphicsContext.smoothing = this._antialiasing;\r\n }\r\n\r\n /**\r\n * Returns true if excalibur is fullscreen using the browser fullscreen api\r\n */\r\n public get isFullScreen() {\r\n return this._isFullScreen;\r\n }\r\n\r\n /**\r\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\r\n * For example, wire this to a user click handler.\r\n *\r\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\r\n * @param elementId\r\n */\r\n public goFullScreen(elementId?: string): Promise {\r\n if (elementId) {\r\n const maybeElement = document.getElementById(elementId);\r\n if (maybeElement) {\r\n if (!maybeElement.getAttribute('ex-fullscreen-listener')) {\r\n maybeElement.setAttribute('ex-fullscreen-listener', 'true');\r\n maybeElement.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n }\r\n const fullscreenPromise = maybeElement.requestFullscreen();\r\n return fullscreenPromise;\r\n }\r\n }\r\n return this._canvas.requestFullscreen();\r\n }\r\n\r\n /**\r\n * Requests to exit fullscreen using the browser fullscreen api\r\n */\r\n public exitFullScreen(): Promise {\r\n return document.exitFullscreen();\r\n }\r\n\r\n /**\r\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\r\n * Excalibur screen space.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY). When using *AndFill suffixed display modes screen space\r\n * (0, 0) is the top left of the safe content area bounding box not the viewport.\r\n * @param point\r\n */\r\n public pageToScreenCoordinates(point: Vector): Vector {\r\n let newX = point.x;\r\n let newY = point.y;\r\n\r\n if (!this._isFullScreen) {\r\n newX -= getPosition(this._canvas).x;\r\n newY -= getPosition(this._canvas).y;\r\n }\r\n\r\n // if fullscreen api on it centers with black bars\r\n // we need to adjust the screen to world coordinates in this case\r\n if (this._isFullScreen) {\r\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\r\n const screenHeight = window.innerWidth / this.aspectRatio;\r\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\r\n newY = ((newY - screenMarginY) / screenHeight) * this.viewport.height;\r\n newX = (newX / window.innerWidth) * this.viewport.width;\r\n } else {\r\n const screenWidth = window.innerHeight * this.aspectRatio;\r\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\r\n newX = ((newX - screenMarginX) / screenWidth) * this.viewport.width;\r\n newY = (newY / window.innerHeight) * this.viewport.height;\r\n }\r\n }\r\n\r\n newX = (newX / this.viewport.width) * this.resolution.width;\r\n newY = (newY / this.viewport.height) * this.resolution.height;\r\n\r\n // offset by content area\r\n newX = newX - this.contentArea.left;\r\n newY = newY - this.contentArea.top;\r\n\r\n return new Vector(newX, newY);\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\r\n * this is where html elements might live if you want to position them relative to Excalibur.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY)\r\n * @param point\r\n */\r\n public screenToPageCoordinates(point: Vector): Vector {\r\n let newX = point.x;\r\n let newY = point.y;\r\n\r\n // no need to offset by content area, drawing is already offset by this\r\n\r\n newX = (newX / this.resolution.width) * this.viewport.width;\r\n newY = (newY / this.resolution.height) * this.viewport.height;\r\n\r\n if (this._isFullScreen) {\r\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\r\n const screenHeight = window.innerWidth / this.aspectRatio;\r\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\r\n newY = (newY / this.viewport.height) * screenHeight + screenMarginY;\r\n newX = (newX / this.viewport.width) * window.innerWidth;\r\n } else {\r\n const screenWidth = window.innerHeight * this.aspectRatio;\r\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\r\n newX = (newX / this.viewport.width) * screenWidth + screenMarginX;\r\n newY = (newY / this.viewport.height) * window.innerHeight;\r\n }\r\n }\r\n\r\n if (!this._isFullScreen) {\r\n newX += getPosition(this._canvas).x;\r\n newY += getPosition(this._canvas).y;\r\n }\r\n\r\n return new Vector(newX, newY);\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\r\n *\r\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\r\n * and extends infinitely out relative from the [[Camera]].\r\n * @param point Screen coordinate to convert\r\n */\r\n public screenToWorldCoordinates(point: Vector): Vector {\r\n // offset by content area\r\n point = point.add(vec(this.contentArea.left, this.contentArea.top));\r\n\r\n // the only difference between screen & world is the camera transform\r\n if (this._camera) {\r\n return this._camera.inverse.multiply(point);\r\n }\r\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\r\n *\r\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\r\n * @param point World coordinate to convert\r\n */\r\n public worldToScreenCoordinates(point: Vector): Vector {\r\n if (this._camera) {\r\n return this._camera.transform.multiply(point);\r\n }\r\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\r\n }\r\n\r\n public pageToWorldCoordinates(point: Vector): Vector {\r\n const screen = this.pageToScreenCoordinates(point);\r\n return this.screenToWorldCoordinates(screen);\r\n }\r\n\r\n public worldToPageCoordinates(point: Vector): Vector {\r\n const screen = this.worldToScreenCoordinates(point);\r\n return this.screenToPageCoordinates(screen);\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n *\r\n * World bounds are in world coordinates, useful for culling objects offscreen that are in world space\r\n */\r\n public getWorldBounds(): BoundingBox {\r\n const bounds = BoundingBox.fromDimension(\r\n this.resolution.width,\r\n this.resolution.height,\r\n Vector.Half)\r\n .scale(vec(1/this._camera.zoom, 1/this._camera.zoom))\r\n .rotate(this._camera.rotation)\r\n .translate(this._camera.pos);\r\n return bounds;\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen and the bottom right corner of the screen.\r\n *\r\n * Screen bounds are in screen coordinates, useful for culling objects offscreen that are in screen space\r\n */\r\n public getScreenBounds(): BoundingBox {\r\n const bounds = BoundingBox.fromDimension(\r\n this.resolution.width,\r\n this.resolution.height,\r\n Vector.Zero, Vector.Zero);\r\n return bounds;\r\n }\r\n\r\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */\r\n public get canvasWidth(): number {\r\n return this.canvas.width;\r\n }\r\n\r\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */\r\n public get halfCanvasWidth(): number {\r\n return this.canvas.width / 2;\r\n }\r\n\r\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */\r\n public get canvasHeight(): number {\r\n return this.canvas.height;\r\n }\r\n\r\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */\r\n public get halfCanvasHeight(): number {\r\n return this.canvas.height / 2;\r\n }\r\n\r\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawWidth(): number {\r\n if (this._camera) {\r\n return this.resolution.width / this._camera.zoom;\r\n }\r\n return this.resolution.width;\r\n }\r\n\r\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawWidth(): number {\r\n return this.drawWidth / 2;\r\n }\r\n\r\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawHeight(): number {\r\n if (this._camera) {\r\n return this.resolution.height / this._camera.zoom;\r\n }\r\n return this.resolution.height;\r\n }\r\n\r\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawHeight(): number {\r\n return this.drawHeight / 2;\r\n }\r\n\r\n /**\r\n * Returns screen center coordinates including zoom and device pixel ratio.\r\n */\r\n public get center(): Vector {\r\n return vec(this.halfDrawWidth, this.halfDrawHeight);\r\n }\r\n\r\n /**\r\n * Returns the content area in screen space where it is safe to place content\r\n */\r\n public get contentArea(): BoundingBox {\r\n return this._contentArea;\r\n }\r\n\r\n /**\r\n * Returns the unsafe area in screen space, this is the full screen and some space may not be onscreen.\r\n */\r\n public get unsafeArea(): BoundingBox {\r\n return this._unsafeArea;\r\n }\r\n\r\n private _contentArea: BoundingBox = new BoundingBox();\r\n private _unsafeArea: BoundingBox = new BoundingBox();\r\n\r\n private _computeFit() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n if (window.innerWidth / aspect < window.innerHeight) {\r\n adjustedWidth = window.innerWidth;\r\n adjustedHeight = window.innerWidth / aspect;\r\n } else {\r\n adjustedWidth = window.innerHeight * aspect;\r\n adjustedHeight = window.innerHeight;\r\n }\r\n\r\n this.viewport = {\r\n width: adjustedWidth,\r\n height: adjustedHeight\r\n };\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n this._unsafeArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n }\r\n\r\n private _computeFitScreenAndFill() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n this._computeFitAndFill(vw, vh);\r\n }\r\n\r\n\r\n\r\n private _computeFitContainerAndFill() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const parent = this.canvas.parentElement;\r\n const vw = parent.clientWidth;\r\n const vh = parent.clientHeight;\r\n this._computeFitAndFill(vw, vh);\r\n }\r\n\r\n private _computeFitAndFill(vw: number, vh: number) {\r\n this.viewport = {\r\n width: vw,\r\n height: vh\r\n };\r\n // if the current screen aspectRatio is less than the original aspectRatio\r\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\r\n // compute new resolution to match the original aspect ratio\r\n this.resolution = {\r\n width: vw * this._contentResolution.width / vw,\r\n height: vw * this._contentResolution.width / vw * vh / vw\r\n };\r\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\r\n this._contentArea = new BoundingBox({\r\n top: clip,\r\n left: 0,\r\n right: this._contentResolution.width,\r\n bottom: this.resolution.height - clip\r\n });\r\n this._unsafeArea = new BoundingBox({\r\n top: -clip,\r\n left: 0,\r\n right: this._contentResolution.width,\r\n bottom: this.resolution.height + clip\r\n });\r\n } else {\r\n this.resolution = {\r\n width: vh * this._contentResolution.height / vh * vw / vh,\r\n height: vh * this._contentResolution.height / vh\r\n };\r\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\r\n this._contentArea = new BoundingBox({\r\n top: 0,\r\n left: clip,\r\n right: this.resolution.width - clip,\r\n bottom: this._contentResolution.height\r\n });\r\n this._unsafeArea = new BoundingBox({\r\n top: 0,\r\n left: -clip,\r\n right: this.resolution.width + clip,\r\n bottom: this._contentResolution.height\r\n });\r\n }\r\n }\r\n\r\n private _computeFitScreenAndZoom() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.canvas.style.position = 'absolute';\r\n\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n\r\n this._computeFitAndZoom(vw, vh);\r\n }\r\n\r\n private _computeFitContainerAndZoom() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.canvas.style.position = 'absolute';\r\n const parent = this.canvas.parentElement;\r\n parent.style.position = 'relative';\r\n parent.style.overflow = 'hidden';\r\n\r\n const vw = parent.clientWidth;\r\n const vh = parent.clientHeight;\r\n\r\n this._computeFitAndZoom(vw, vh);\r\n }\r\n\r\n private _computeFitAndZoom(vw: number, vh: number) {\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n if (vw / aspect < vh) {\r\n adjustedWidth = vw;\r\n adjustedHeight = vw / aspect;\r\n } else {\r\n adjustedWidth = vh * aspect;\r\n adjustedHeight = vh;\r\n }\r\n\r\n const scaleX = vw / adjustedWidth;\r\n const scaleY = vh / adjustedHeight;\r\n\r\n const maxScaleFactor = Math.max(scaleX, scaleY);\r\n\r\n const zoomedWidth = adjustedWidth * maxScaleFactor;\r\n const zoomedHeight = adjustedHeight * maxScaleFactor;\r\n\r\n // Center zoomed dimension if bigger than the screen\r\n if (zoomedWidth > vw) {\r\n this.canvas.style.left = -(zoomedWidth - vw) / 2 + 'px';\r\n } else {\r\n this.canvas.style.left = '';\r\n }\r\n\r\n if (zoomedHeight > vh) {\r\n this.canvas.style.top = -(zoomedHeight - vh) / 2 + 'px';\r\n } else {\r\n this.canvas.style.top = '';\r\n }\r\n\r\n this.viewport = {\r\n width: zoomedWidth,\r\n height: zoomedHeight\r\n };\r\n\r\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\r\n // return safe area\r\n if (this.viewport.width > vw) {\r\n const clip = (this.viewport.width - vw)/this.viewport.width * this.resolution.width;\r\n bounds.top = 0;\r\n bounds.left = clip / 2;\r\n bounds.right = this.resolution.width - clip / 2;\r\n bounds.bottom = this.resolution.height;\r\n }\r\n\r\n if (this.viewport.height > vh) {\r\n const clip = (this.viewport.height - vh)/this.viewport.height * this.resolution.height;\r\n bounds.top = clip / 2;\r\n bounds.left = 0;\r\n bounds.bottom = this.resolution.height - clip / 2;\r\n bounds.right = this.resolution.width;\r\n }\r\n this._contentArea = bounds;\r\n }\r\n\r\n private _computeFitContainer() {\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n const parent = this.canvas.parentElement;\r\n if (parent.clientWidth / aspect < parent.clientHeight) {\r\n adjustedWidth = parent.clientWidth;\r\n adjustedHeight = parent.clientWidth / aspect;\r\n } else {\r\n adjustedWidth = parent.clientHeight * aspect;\r\n adjustedHeight = parent.clientHeight;\r\n }\r\n\r\n this.viewport = {\r\n width: adjustedWidth,\r\n height: adjustedHeight\r\n };\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n }\r\n\r\n private _applyDisplayMode() {\r\n this._setResolutionAndViewportByDisplayMode(this.parent);\r\n\r\n // watch resizing\r\n if (this.parent instanceof Window) {\r\n this._browser.window.on('resize', this._resizeHandler);\r\n } else {\r\n this._resizeObserver = new ResizeObserver(() => {\r\n this._resizeHandler();\r\n });\r\n this._resizeObserver.observe(this.parent);\r\n }\r\n this.parent.addEventListener('resize', this._resizeHandler);\r\n }\r\n\r\n /**\r\n * Sets the resolution and viewport based on the selected display mode.\r\n */\r\n private _setResolutionAndViewportByDisplayMode(parent: HTMLElement | Window) {\r\n if (this.displayMode === DisplayMode.FillContainer) {\r\n this.resolution = {\r\n width: ( parent).clientWidth,\r\n height: ( parent).clientHeight\r\n };\r\n\r\n this.viewport = this.resolution;\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FillScreen) {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.resolution = {\r\n width: ( parent).innerWidth,\r\n height: ( parent).innerHeight\r\n };\r\n\r\n this.viewport = this.resolution;\r\n }\r\n\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n\r\n if (this.displayMode === DisplayMode.FitScreen) {\r\n this._computeFit();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainer) {\r\n this._computeFitContainer();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitScreenAndFill) {\r\n this._computeFitScreenAndFill();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainerAndFill){\r\n this._computeFitContainerAndFill();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitScreenAndZoom) {\r\n this._computeFitScreenAndZoom();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainerAndZoom){\r\n this._computeFitContainerAndZoom();\r\n }\r\n }\r\n}\r\n","/**\r\n * Internal class used to build instances of AudioContext\r\n */\r\n/* istanbul ignore next */\r\nexport class AudioContextFactory {\r\n private static _INSTANCE: AudioContext = null;\r\n\r\n public static create(): AudioContext {\r\n if (!this._INSTANCE) {\r\n if ((window).AudioContext || (window).webkitAudioContext) {\r\n this._INSTANCE = new AudioContext();\r\n }\r\n }\r\n\r\n return this._INSTANCE;\r\n }\r\n}\r\n","import { AudioContextFactory } from '../Resources/Sound/AudioContext';\r\nimport { Logger } from './Log';\r\n\r\nexport interface LegacyWebAudioSource {\r\n playbackState: string;\r\n PLAYING_STATE: 'playing';\r\n FINISHED_STATE: 'finished';\r\n}\r\n\r\n/**\r\n * Patch for detecting legacy web audio in browsers\r\n * @internal\r\n * @param source\r\n */\r\nfunction isLegacyWebAudioSource(source: any): source is LegacyWebAudioSource {\r\n return !!source.playbackState;\r\n}\r\n\r\nexport class WebAudio {\r\n private static _UNLOCKED: boolean = false;\r\n\r\n /**\r\n * Play an empty sound to unlock Safari WebAudio context. Call this function\r\n * right after a user interaction event.\r\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\r\n */\r\n static unlock(): Promise {\r\n const promise = new Promise((resolve, reject) => {\r\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) {\r\n return resolve(true);\r\n }\r\n const unlockTimeoutTimer = setTimeout(() => {\r\n Logger.getInstance().warn('Excalibur was unable to unlock the audio context, audio probably will not play in this browser.');\r\n resolve(false);\r\n }, 200);\r\n\r\n const audioContext = AudioContextFactory.create();\r\n audioContext.resume().then(\r\n () => {\r\n // create empty buffer and play it\r\n const buffer = audioContext.createBuffer(1, 1, 22050);\r\n const source = audioContext.createBufferSource();\r\n let ended = false;\r\n\r\n source.buffer = buffer;\r\n source.connect(audioContext.destination);\r\n source.onended = () => (ended = true);\r\n\r\n source.start(0);\r\n\r\n // by checking the play state after some time, we know if we're really unlocked\r\n setTimeout(() => {\r\n if (isLegacyWebAudioSource(source)) {\r\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) {\r\n WebAudio._UNLOCKED = true;\r\n }\r\n } else {\r\n if (audioContext.currentTime > 0 || ended) {\r\n WebAudio._UNLOCKED = true;\r\n }\r\n }\r\n }, 0);\r\n\r\n clearTimeout(unlockTimeoutTimer);\r\n resolve(true);\r\n },\r\n () => {\r\n reject();\r\n }\r\n );\r\n });\r\n\r\n return promise;\r\n }\r\n\r\n static isUnlocked() {\r\n return this._UNLOCKED;\r\n }\r\n}\r\n","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { watch } from '../Util/Watch';\r\nimport { ImageFiltering } from './Filtering';\r\nimport { omit } from '../Util/Util';\r\n\r\nexport interface RasterOptions {\r\n /**\r\n * Optionally specify a quality number, which is how much to scale the internal Raster. Default is 1.\r\n *\r\n * For example if the quality is set to 2, it doubles the internal raster bitmap in memory.\r\n *\r\n * Adjusting this value can be useful if you are working with small rasters.\r\n */\r\n quality?: number;\r\n /**\r\n * Optionally specify \"smoothing\" if you want antialiasing to apply to the raster's bitmap context, by default `false`\r\n */\r\n smoothing?: boolean;\r\n\r\n /**\r\n * Optionally specify the color of the raster's bitmap context, by default [[Color.Black]]\r\n */\r\n color?: Color;\r\n\r\n /**\r\n * Optionally specify the stroke color of the raster's bitmap context, by default undefined\r\n */\r\n strokeColor?: Color;\r\n\r\n /**\r\n * Optionally specify the line width of the raster's bitmap, by default 1 pixel\r\n */\r\n lineWidth?: number;\r\n\r\n /**\r\n * Optionally specify the line dash of the raster's bitmap, by default `[]` which means none\r\n */\r\n lineDash?: number[];\r\n\r\n /**\r\n * Optionally specify the line end style, default is \"butt\".\r\n */\r\n lineCap?: 'butt' | 'round' | 'square';\r\n\r\n /**\r\n * Optionally specify the padding to apply to the bitmap\r\n */\r\n padding?: number;\r\n\r\n /**\r\n * Optionally specify what image filtering mode should be used, [[ImageFiltering.Pixel]] for pixel art,\r\n * [[ImageFiltering.Blended]] for hi-res art\r\n *\r\n * By default unset, rasters defer to the engine antialiasing setting\r\n */\r\n filtering?: ImageFiltering;\r\n}\r\n\r\n/**\r\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\r\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\r\n *\r\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\r\n */\r\nexport abstract class Raster extends Graphic {\r\n public filtering: ImageFiltering = null;\r\n public lineCap: 'butt' | 'round' | 'square' = 'butt';\r\n public quality: number = 1;\r\n\r\n public _bitmap: HTMLCanvasElement;\r\n protected _ctx: CanvasRenderingContext2D;\r\n private _dirty: boolean = true;\r\n\r\n constructor(options?: GraphicOptions & RasterOptions) {\r\n super(omit(options, ['width', 'height'])); // rasters do some special sauce with width/height\r\n if (options) {\r\n this.quality = options.quality ?? this.quality;\r\n this.color = options.color ?? Color.Black;\r\n this.strokeColor = options?.strokeColor;\r\n this.smoothing = options.smoothing ?? this.smoothing;\r\n this.lineWidth = options.lineWidth ?? this.lineWidth;\r\n this.lineDash = options.lineDash ?? this.lineDash;\r\n this.lineCap = options.lineCap ?? this.lineCap;\r\n this.padding = options.padding ?? this.padding;\r\n this.filtering = options.filtering ?? this.filtering;\r\n }\r\n this._bitmap = document.createElement('canvas');\r\n // get the default canvas width/height as a fallback\r\n const bitmapWidth = options?.width ?? this._bitmap.width;\r\n const bitmapHeight = options?.height ?? this._bitmap.height;\r\n this.width = bitmapWidth;\r\n this.height = bitmapHeight;\r\n const maybeCtx = this._bitmap.getContext('2d');\r\n if (!maybeCtx) {\r\n /* istanbul ignore next */\r\n throw new Error('Browser does not support 2d canvas drawing, cannot create Raster graphic');\r\n } else {\r\n this._ctx = maybeCtx;\r\n }\r\n }\r\n\r\n public cloneRasterOptions(): RasterOptions {\r\n return {\r\n color: this.color ? this.color.clone() : null,\r\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\r\n smoothing: this.smoothing,\r\n lineWidth: this.lineWidth,\r\n lineDash: this.lineDash,\r\n lineCap: this.lineCap,\r\n quality: this.quality,\r\n padding: this.padding\r\n };\r\n }\r\n\r\n /**\r\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\r\n */\r\n public get dirty() {\r\n return this._dirty;\r\n }\r\n\r\n /**\r\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\r\n * This should be called any time the graphics state changes such that it affects the outputted drawing\r\n */\r\n public flagDirty() {\r\n this._dirty = true;\r\n }\r\n\r\n private _originalWidth: number;\r\n /**\r\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding`s or `quality` set will be factored into the width\r\n */\r\n public get width() {\r\n return Math.abs(this._getTotalWidth() * this.scale.x);\r\n }\r\n public set width(value: number) {\r\n value /= Math.abs(this.scale.x);\r\n this._bitmap.width = value;\r\n this._originalWidth = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _originalHeight: number;\r\n /**\r\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding` or `quality` set will be factored into the height\r\n */\r\n public get height() {\r\n return Math.abs(this._getTotalHeight() * this.scale.y);\r\n }\r\n\r\n public set height(value: number) {\r\n value /= Math.abs(this.scale.y);\r\n this._bitmap.height = value;\r\n this._originalHeight = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _getTotalWidth() {\r\n return ((this._originalWidth ?? this._bitmap.width) + this.padding * 2) * 1;\r\n }\r\n\r\n private _getTotalHeight() {\r\n return ((this._originalHeight ?? this._bitmap.height) + this.padding * 2) * 1;\r\n }\r\n\r\n /**\r\n * Returns the local bounds of the Raster including the padding\r\n */\r\n public get localBounds() {\r\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\r\n }\r\n\r\n private _smoothing: boolean = false;\r\n /**\r\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get smoothing() {\r\n return this._smoothing;\r\n }\r\n public set smoothing(value: boolean) {\r\n this._smoothing = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _color: Color = watch(Color.Black, () => this.flagDirty());\r\n /**\r\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get color() {\r\n return this._color;\r\n }\r\n public set color(value) {\r\n this.flagDirty();\r\n this._color = watch(value, () => this.flagDirty());\r\n }\r\n\r\n private _strokeColor: Color;\r\n /**\r\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get strokeColor() {\r\n return this._strokeColor;\r\n }\r\n public set strokeColor(value) {\r\n this.flagDirty();\r\n this._strokeColor = watch(value, () => this.flagDirty());\r\n }\r\n\r\n private _lineWidth: number = 1;\r\n /**\r\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get lineWidth() {\r\n return this._lineWidth;\r\n }\r\n public set lineWidth(value) {\r\n this._lineWidth = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _lineDash: number[] = [];\r\n public get lineDash() {\r\n return this._lineDash;\r\n }\r\n\r\n public set lineDash(value) {\r\n this._lineDash = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _padding: number = 0;\r\n public get padding() {\r\n return this._padding;\r\n }\r\n\r\n public set padding(value: number) {\r\n this._padding = value;\r\n this.flagDirty();\r\n }\r\n\r\n /**\r\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\r\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\r\n */\r\n public rasterize(): void {\r\n this._dirty = false;\r\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\r\n this._ctx.save();\r\n this._applyRasterProperties(this._ctx);\r\n this.execute(this._ctx);\r\n this._ctx.restore();\r\n }\r\n\r\n protected _applyRasterProperties(ctx: CanvasRenderingContext2D) {\r\n this._bitmap.width = this._getTotalWidth() * this.quality;\r\n this._bitmap.height = this._getTotalHeight() * this.quality;\r\n // Do a bad thing to pass the filtering as an attribute\r\n this._bitmap.setAttribute('filtering', this.filtering);\r\n this._bitmap.setAttribute('forceUpload', 'true');\r\n ctx.scale(this.quality, this.quality);\r\n ctx.translate(this.padding, this.padding);\r\n ctx.imageSmoothingEnabled = this.smoothing;\r\n ctx.lineWidth = this.lineWidth;\r\n ctx.setLineDash(this.lineDash ?? ctx.getLineDash());\r\n ctx.lineCap = this.lineCap;\r\n ctx.strokeStyle = this.strokeColor?.toString();\r\n ctx.fillStyle = this.color?.toString();\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n if (this._dirty) {\r\n this.rasterize();\r\n }\r\n ex.scale(1 / this.quality, 1 / this.quality);\r\n ex.drawImage(this._bitmap, x, y);\r\n }\r\n\r\n /**\r\n * Executes drawing implementation of the graphic, this is where the specific drawing code for the graphic\r\n * should be implemented. Once `rasterize()` the graphic can be drawn to the [[ExcaliburGraphicsContext]] via `draw(...)`\r\n * @param ctx Canvas to draw the graphic to\r\n */\r\n abstract execute(ctx: CanvasRenderingContext2D): void;\r\n}\r\n","import { GraphicOptions } from './Graphic';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface CanvasOptions {\r\n draw?: (ctx: CanvasRenderingContext2D) => void;\r\n cache?: boolean;\r\n}\r\n\r\n/**\r\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\r\n *\r\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\r\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\r\n *\r\n * **Low performance API**\r\n */\r\nexport class Canvas extends Raster {\r\n /**\r\n * Return the 2D graphics context of this canvas\r\n */\r\n public get ctx() {\r\n return this._ctx;\r\n }\r\n\r\n constructor(private _options: GraphicOptions & RasterOptions & CanvasOptions) {\r\n super(_options);\r\n }\r\n\r\n public clone(): Canvas {\r\n return new Canvas({\r\n ...this._options,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this._options?.draw) {\r\n this._options?.draw(ctx);\r\n }\r\n if (!this._options.cache) {\r\n this.flagDirty();\r\n }\r\n }\r\n}\r\n","import { Audio } from './Audio';\r\n\r\nexport type ExResponseType = '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';\r\n\r\nexport interface ExResponseTypesLookup {\r\n [name: string]: ExResponseType;\r\n}\r\n\r\nexport class ExResponse {\r\n public static type: ExResponseTypesLookup = {\r\n any: '',\r\n blob: 'blob',\r\n json: 'json',\r\n text: 'text',\r\n document: 'document',\r\n arraybuffer: 'arraybuffer'\r\n };\r\n}\r\n\r\n/**\r\n * Represents an audio implementation like [[WebAudioInstance]]\r\n */\r\nexport interface AudioImplementation {\r\n /**\r\n * XHR response type\r\n */\r\n responseType: ExResponseType;\r\n\r\n /**\r\n * Processes raw data and transforms into sound data\r\n */\r\n processData(data: Blob | ArrayBuffer): Promise;\r\n\r\n /**\r\n * Factory method that returns an instance of a played audio track\r\n */\r\n createInstance(data: string | AudioBuffer): Audio;\r\n}\r\n","\r\nexport interface State {\r\n name?: string;\r\n transitions: string[];\r\n onEnter?: (context: {from: string, eventData?: any, data: any}) => boolean | void;\r\n onState?: () => any;\r\n onExit?: (context: {to: string, data: any}) => boolean | void;\r\n onUpdate?: (data: any, elapsedMs: number) => any;\r\n}\r\n\r\nexport interface StateMachineDescription {\r\n start: string,\r\n states: { [name: string]: State }\r\n}\r\n\r\nexport type PossibleStates = TMachine extends StateMachineDescription ? Extract : never;\r\n\r\nexport interface StateMachineState {\r\n data: any;\r\n currentState: string;\r\n}\r\n\r\nexport class StateMachine {\r\n public startState: State;\r\n private _currentState: State;\r\n public get currentState(): State {\r\n return this._currentState;\r\n }\r\n public set currentState(state: State) {\r\n this._currentState = state;\r\n }\r\n public states = new Map();\r\n public data: TData;\r\n\r\n static create(\r\n machineDescription: TMachine, data?: TData): StateMachine, TData> {\r\n const machine = new StateMachine, TData>();\r\n machine.data = data;\r\n for (const stateName in machineDescription.states) {\r\n machine.states.set(stateName as PossibleStates, {\r\n name: stateName,\r\n ...machineDescription.states[stateName]\r\n });\r\n }\r\n\r\n // validate transitions are states\r\n for (const state of machine.states.values()) {\r\n for (const transitionState of state.transitions) {\r\n if (transitionState === '*') {\r\n continue;\r\n }\r\n if (!machine.states.has(transitionState)) {\r\n throw Error(\r\n `Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`\r\n );\r\n }\r\n }\r\n }\r\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\r\n return machine;\r\n }\r\n\r\n in(state: TPossibleStates): boolean {\r\n return this.currentState.name === state;\r\n }\r\n\r\n go(stateName: TPossibleStates, eventData?: any): boolean {\r\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes('*')) {\r\n const potentialNewState = this.states.get(stateName);\r\n if (this.currentState.onExit) {\r\n const canExit = this.currentState?.onExit({to: potentialNewState.name, data: this.data});\r\n if (canExit === false) {\r\n return false;\r\n }\r\n }\r\n\r\n if (potentialNewState?.onEnter) {\r\n const canEnter = potentialNewState?.onEnter({from: this.currentState.name, eventData, data: this.data});\r\n if (canEnter === false) {\r\n return false;\r\n }\r\n }\r\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\r\n this.currentState = potentialNewState;\r\n if (this.currentState?.onState) {\r\n this.currentState.onState();\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n update(elapsedMs: number) {\r\n if (this.currentState.onUpdate) {\r\n this.currentState.onUpdate(this.data, elapsedMs);\r\n }\r\n }\r\n\r\n save(saveKey: string) {\r\n localStorage.setItem(saveKey, JSON.stringify({\r\n currentState: this.currentState.name,\r\n data: this.data\r\n }));\r\n }\r\n\r\n restore(saveKey: string) {\r\n const state: StateMachineState = JSON.parse(localStorage.getItem(saveKey));\r\n this.currentState = this.states.get(state.currentState);\r\n this.data = state.data;\r\n }\r\n}\r\n\r\n","import { StateMachine } from '../../Util/StateMachine';\r\nimport { Audio } from '../../Interfaces/Audio';\r\nimport { clamp } from '../../Math/util';\r\nimport { AudioContextFactory } from './AudioContext';\r\nimport { Future } from '../../Util/Future';\r\n\r\ninterface SoundState {\r\n startedAt: number;\r\n pausedAt: number;\r\n}\r\n\r\n/**\r\n * Internal class representing a Web Audio AudioBufferSourceNode instance\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\r\n */\r\nexport class WebAudioInstance implements Audio {\r\n private _instance: AudioBufferSourceNode;\r\n private _audioContext: AudioContext = AudioContextFactory.create();\r\n private _volumeNode = this._audioContext.createGain();\r\n\r\n private _playingFuture = new Future();\r\n private _stateMachine = StateMachine.create({\r\n start: 'STOPPED',\r\n states: {\r\n PLAYING: {\r\n onEnter: ({data}: {from: string, data: SoundState}) => {\r\n\r\n // Buffer nodes are single use\r\n this._createNewBufferSource();\r\n this._handleEnd();\r\n if (this.loop) {\r\n // when looping don't set a duration\r\n this._instance.start(0, data.pausedAt * this._playbackRate);\r\n } else {\r\n this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\r\n }\r\n data.startedAt = (this._audioContext.currentTime - data.pausedAt);\r\n data.pausedAt = 0;\r\n },\r\n onState: () => this._playStarted(),\r\n onExit: ({to}) => {\r\n // If you've exited early only resolve if explicitly STOPPED\r\n if (to === 'STOPPED') {\r\n this._playingFuture.resolve(true);\r\n }\r\n // Whenever you're not playing... you stop!\r\n this._instance.onended = null; // disconnect the wired on-end handler\r\n this._instance.disconnect();\r\n this._instance.stop(0);\r\n this._instance = null;\r\n },\r\n transitions: ['STOPPED', 'PAUSED', 'SEEK']\r\n },\r\n SEEK: {\r\n onEnter: ({ eventData: position, data }: {eventData?: number, data: SoundState}) => {\r\n data.pausedAt = (position ?? 0) / this._playbackRate;\r\n data.startedAt = 0;\r\n },\r\n transitions: ['*']\r\n },\r\n STOPPED: {\r\n onEnter: ({data}: {from: string, data: SoundState}) => {\r\n data.pausedAt = 0;\r\n data.startedAt = 0;\r\n this._playingFuture.resolve(true);\r\n },\r\n transitions: ['PLAYING', 'PAUSED', 'SEEK']\r\n },\r\n PAUSED: {\r\n onEnter: ({data}: {data: SoundState}) => {\r\n // Playback rate will be a scale factor of how fast/slow the audio is being played\r\n // default is 1.0\r\n // we need to invert it to get the time scale\r\n data.pausedAt = (this._audioContext.currentTime - data.startedAt);\r\n },\r\n transitions: ['PLAYING', 'STOPPED', 'SEEK']\r\n }\r\n }\r\n }, {\r\n startedAt: 0,\r\n pausedAt: 0\r\n } as SoundState);\r\n\r\n private _createNewBufferSource() {\r\n this._instance = this._audioContext.createBufferSource();\r\n this._instance.buffer = this._src;\r\n this._instance.loop = this.loop;\r\n this._instance.playbackRate.value = this._playbackRate;\r\n this._instance.connect(this._volumeNode);\r\n this._volumeNode.connect(this._audioContext.destination);\r\n }\r\n\r\n private _handleEnd() {\r\n if (!this.loop) {\r\n this._instance.onended = () => {\r\n this._playingFuture.resolve(true);\r\n };\r\n }\r\n }\r\n\r\n private _volume = 1;\r\n private _loop = false;\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n private _playStarted: () => any = () => {};\r\n public set loop(value: boolean) {\r\n this._loop = value;\r\n\r\n if (this._instance) {\r\n this._instance.loop = value;\r\n if (!this.loop) {\r\n this._instance.onended = () => {\r\n this._playingFuture.resolve(true);\r\n };\r\n }\r\n }\r\n }\r\n public get loop(): boolean {\r\n return this._loop;\r\n }\r\n\r\n public set volume(value: number) {\r\n value = clamp(value, 0, 1.0);\r\n\r\n this._volume = value;\r\n\r\n if (this._stateMachine.in('PLAYING') && this._volumeNode.gain.setTargetAtTime) {\r\n // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\r\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\r\n // This exponential ramp provides a more pleasant transition in gain\r\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\r\n } else {\r\n this._volumeNode.gain.value = value;\r\n }\r\n }\r\n public get volume(): number {\r\n return this._volume;\r\n }\r\n\r\n private _duration: number | undefined;\r\n /**\r\n * Returns the set duration to play, otherwise returns the total duration if unset\r\n */\r\n public get duration() {\r\n return this._duration ?? this.getTotalPlaybackDuration();\r\n }\r\n\r\n /**\r\n * Set the duration that this audio should play.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */\r\n public set duration(duration: number) {\r\n this._duration = duration;\r\n }\r\n\r\n constructor(private _src: AudioBuffer) {\r\n this._createNewBufferSource();\r\n }\r\n\r\n public isPlaying() {\r\n return this._stateMachine.in('PLAYING');\r\n }\r\n\r\n public isPaused() {\r\n return this._stateMachine.in('PAUSED') || this._stateMachine.in('SEEK');\r\n }\r\n\r\n public isStopped() {\r\n return this._stateMachine.in('STOPPED');\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n public play(playStarted: () => any = () => {}) {\r\n this._playStarted = playStarted;\r\n this._stateMachine.go('PLAYING');\r\n return this._playingFuture.promise;\r\n }\r\n\r\n public pause() {\r\n this._stateMachine.go('PAUSED');\r\n }\r\n\r\n public stop() {\r\n this._stateMachine.go('STOPPED');\r\n }\r\n\r\n public seek(position: number) {\r\n this._stateMachine.go('PAUSED');\r\n this._stateMachine.go('SEEK', position);\r\n }\r\n\r\n public getTotalPlaybackDuration() {\r\n return this._src.duration;\r\n }\r\n\r\n public getPlaybackPosition() {\r\n const {pausedAt, startedAt} = this._stateMachine.data;\r\n if (pausedAt) {\r\n return pausedAt * this._playbackRate;\r\n }\r\n if (startedAt) {\r\n return (this._audioContext.currentTime - startedAt) * this._playbackRate;\r\n }\r\n return 0;\r\n }\r\n\r\n private _playbackRate = 1.0;\r\n public set playbackRate(playbackRate: number) {\r\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\r\n }\r\n\r\n public get playbackRate() {\r\n return this._instance.playbackRate.value;\r\n }\r\n}\r\n","import { Scene } from './Scene';\r\nimport { Vector } from './Math/vector';\r\nimport { Actor } from './Actor';\r\nimport { Trigger } from './Trigger';\r\nimport { FrameStats } from './Debug';\r\nimport { Engine } from './Engine';\r\nimport { TileMap } from './TileMap';\r\nimport { Side } from './Collision/Side';\r\nimport { CollisionContact } from './Collision/Detection/CollisionContact';\r\nimport { Collider } from './Collision/Colliders/Collider';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { OnInitialize, OnPreUpdate, OnPostUpdate, SceneActivationContext } from './Interfaces/LifecycleEvents';\r\nimport { BodyComponent } from './Collision/BodyComponent';\r\nimport { ExcaliburGraphicsContext } from './Graphics';\r\nimport { Axes, Buttons, Gamepad } from './Input/Gamepad';\r\nimport { Action } from './Actions/Action';\r\n\r\nexport enum EventTypes {\r\n Kill = 'kill',\r\n PreKill = 'prekill',\r\n PostKill = 'postkill',\r\n\r\n PreDraw = 'predraw',\r\n PostDraw = 'postdraw',\r\n\r\n PreDebugDraw = 'predebugdraw',\r\n PostDebugDraw = 'postdebugdraw',\r\n\r\n PreUpdate = 'preupdate',\r\n PostUpdate = 'postupdate',\r\n\r\n PreFrame = 'preframe',\r\n PostFrame = 'postframe',\r\n\r\n PreCollision = 'precollision',\r\n CollisionStart = 'collisionstart',\r\n CollisionEnd = 'collisionend',\r\n PostCollision = 'postcollision',\r\n\r\n Initialize = 'initialize',\r\n Activate = 'activate',\r\n Deactivate = 'deactivate',\r\n\r\n ExitViewport = 'exitviewport',\r\n EnterViewport = 'enterviewport',\r\n\r\n ExitTrigger = 'exit',\r\n EnterTrigger = 'enter',\r\n\r\n Connect = 'connect',\r\n Disconnect = 'disconnect',\r\n Button = 'button',\r\n Axis = 'axis',\r\n\r\n Visible = 'visible',\r\n Hidden = 'hidden',\r\n Start = 'start',\r\n Stop = 'stop',\r\n\r\n PointerUp = 'pointerup',\r\n PointerDown = 'pointerdown',\r\n PointerMove = 'pointermove',\r\n PointerEnter = 'pointerenter',\r\n PointerLeave = 'pointerleave',\r\n PointerCancel = 'pointercancel',\r\n PointerWheel = 'pointerwheel',\r\n\r\n Up = 'up',\r\n Down = 'down',\r\n Move = 'move',\r\n Enter = 'enter',\r\n Leave = 'leave',\r\n Cancel = 'cancel',\r\n Wheel = 'wheel',\r\n\r\n Press = 'press',\r\n Release = 'release',\r\n Hold = 'hold',\r\n\r\n PointerDragStart = 'pointerdragstart',\r\n PointerDragEnd = 'pointerdragend',\r\n PointerDragEnter = 'pointerdragenter',\r\n PointerDragLeave = 'pointerdragleave',\r\n PointerDragMove = 'pointerdragmove',\r\n\r\n ActionStart = 'actionstart',\r\n ActionComplete = 'actioncomplete'\r\n}\r\n\r\n/* istanbul ignore next */\r\n/* compiler only: these are internal to lib */\r\nexport type kill = 'kill';\r\nexport type prekill = 'prekill';\r\nexport type postkill = 'postkill';\r\n\r\nexport type predraw = 'predraw';\r\nexport type postdraw = 'postdraw';\r\n\r\nexport type predebugdraw = 'predebugdraw';\r\nexport type postdebugdraw = 'postdebugdraw';\r\n\r\nexport type preupdate = 'preupdate';\r\nexport type postupdate = 'postupdate';\r\n\r\nexport type preframe = 'preframe';\r\nexport type postframe = 'postframe';\r\n\r\nexport type precollision = 'precollision';\r\nexport type collisionstart = 'collisionstart';\r\nexport type collisionend = 'collisionend';\r\nexport type postcollision = 'postcollision';\r\n\r\nexport type initialize = 'initialize';\r\nexport type activate = 'activate';\r\nexport type deactivate = 'deactivate';\r\n\r\nexport type exitviewport = 'exitviewport';\r\nexport type enterviewport = 'enterviewport';\r\n\r\nexport type exittrigger = 'exit';\r\nexport type entertrigger = 'enter';\r\n\r\nexport type connect = 'connect';\r\nexport type disconnect = 'disconnect';\r\nexport type button = 'button';\r\nexport type axis = 'axis';\r\n\r\nexport type subscribe = 'subscribe';\r\nexport type unsubscribe = 'unsubscribe';\r\n\r\nexport type visible = 'visible';\r\nexport type hidden = 'hidden';\r\nexport type start = 'start';\r\nexport type stop = 'stop';\r\n\r\nexport type pointerup = 'pointerup';\r\nexport type pointerdown = 'pointerdown';\r\nexport type pointermove = 'pointermove';\r\nexport type pointerenter = 'pointerenter';\r\nexport type pointerleave = 'pointerleave';\r\nexport type pointercancel = 'pointercancel';\r\nexport type pointerwheel = 'pointerwheel';\r\n\r\nexport type up = 'up';\r\nexport type down = 'down';\r\nexport type move = 'move';\r\nexport type enter = 'enter';\r\nexport type leave = 'leave';\r\nexport type cancel = 'cancel';\r\nexport type wheel = 'wheel';\r\n\r\nexport type press = 'press';\r\nexport type release = 'release';\r\nexport type hold = 'hold';\r\n\r\nexport type pointerdragstart = 'pointerdragstart';\r\nexport type pointerdragend = 'pointerdragend';\r\nexport type pointerdragenter = 'pointerdragenter';\r\nexport type pointerdragleave = 'pointerdragleave';\r\nexport type pointerdragmove = 'pointerdragmove';\r\n\r\n/**\r\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\r\n * some events are unique to a type, others are not.\r\n *\r\n */\r\nexport class GameEvent {\r\n /**\r\n * Target object for this event.\r\n */\r\n public target: T;\r\n\r\n /**\r\n * Other target object for this event\r\n */\r\n public other: U | null;\r\n\r\n /**\r\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\r\n * to all actors that apply.\r\n */\r\n public get bubbles(): boolean {\r\n return this._bubbles;\r\n }\r\n\r\n public set bubbles(value: boolean) {\r\n this._bubbles = value;\r\n }\r\n\r\n private _bubbles: boolean = true;\r\n /**\r\n * Prevents event from bubbling\r\n */\r\n public stopPropagation() {\r\n this.bubbles = false;\r\n }\r\n}\r\n\r\n/**\r\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\r\n */\r\nexport class KillEvent extends GameEvent {\r\n constructor(public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'prekill' event is emitted directly before an actor is killed.\r\n */\r\nexport class PreKillEvent extends GameEvent {\r\n constructor(public target: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postkill' event is emitted directly after the actor is killed.\r\n */\r\nexport class PostKillEvent extends GameEvent {\r\n constructor(public target: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'start' event is emitted on engine when has started and is ready for interaction.\r\n */\r\nexport class GameStartEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\r\n */\r\nexport class GameStopEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */\r\nexport class PreDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity | Scene | Engine | TileMap) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */\r\nexport class PostDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity | Scene | Engine | TileMap) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'pretransformdraw' event is emitted on actors/entities before any graphics transforms have taken place.\r\n * Useful if you need to completely customize the draw or modify the transform before drawing in the draw step (for example needing\r\n * latest camera positions)\r\n *\r\n */\r\nexport class PreTransformDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'posttransformdraw' event is emitted on actors/entities after all graphics have been draw and transforms reset.\r\n * Useful if you need to completely custom the draw after everything is done.\r\n *\r\n */\r\nexport class PostTransformDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\r\n */\r\nexport class PreDebugDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public target: Entity | Actor | Scene | Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\r\n */\r\nexport class PostDebugDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public target: Entity | Actor | Scene | Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\r\n */\r\nexport class PreUpdateEvent extends GameEvent {\r\n constructor(public engine: Engine, public delta: number, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\r\n */\r\nexport class PostUpdateEvent extends GameEvent {\r\n constructor(public engine: Engine, public delta: number, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'preframe' event is emitted on the engine, before the frame begins.\r\n */\r\nexport class PreFrameEvent extends GameEvent {\r\n constructor(public engine: Engine, public prevStats: FrameStats) {\r\n super();\r\n this.target = engine;\r\n }\r\n}\r\n\r\n/**\r\n * The 'postframe' event is emitted on the engine, after a frame ends.\r\n */\r\nexport class PostFrameEvent extends GameEvent {\r\n constructor(public engine: Engine, public stats: FrameStats) {\r\n super();\r\n this.target = engine;\r\n }\r\n}\r\n\r\n/**\r\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\r\n */\r\nexport class GamepadConnectEvent extends GameEvent {\r\n constructor(public index: number, public gamepad: Gamepad) {\r\n super();\r\n this.target = gamepad;\r\n }\r\n}\r\n\r\n/**\r\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\r\n */\r\nexport class GamepadDisconnectEvent extends GameEvent {\r\n constructor(public index: number, public gamepad: Gamepad) {\r\n super();\r\n this.target = gamepad;\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */\r\nexport class GamepadButtonEvent extends GameEvent {\r\n /**\r\n * @param button The Gamepad button\r\n * @param value A numeric value between 0 and 1\r\n */\r\n constructor(public button: Buttons, public value: number, public target: Gamepad) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */\r\nexport class GamepadAxisEvent extends GameEvent {\r\n /**\r\n * @param axis The Gamepad axis\r\n * @param value A numeric value between -1 and 1\r\n */\r\n constructor(public axis: Axes, public value: number, public target: Gamepad) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event received by the [[Engine]] when the browser window is visible on a screen.\r\n */\r\nexport class VisibleEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\r\n */\r\nexport class HiddenEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\r\n */\r\nexport class PreCollisionEvent extends GameEvent {\r\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that will collided with the current actor\r\n * @param side The side that will be collided with the current actor\r\n * @param intersection Intersection vector\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\r\n */\r\nexport class PostCollisionEvent extends GameEvent {\r\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that did collide with the current actor\r\n * @param side The side that did collide with the current actor\r\n * @param intersection Intersection vector\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\nexport class ContactStartEvent {\r\n constructor(public target: T, public other: T, public side: Side, public contact: CollisionContact) {}\r\n}\r\n\r\nexport class ContactEndEvent {\r\n constructor(public target: T, public other: T, public side: Side, public lastContact: CollisionContact) {}\r\n}\r\n\r\nexport class CollisionPreSolveEvent {\r\n constructor(public target: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {}\r\n}\r\n\r\nexport class CollisionPostSolveEvent {\r\n constructor(public target: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {}\r\n}\r\n\r\n/**\r\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\r\n */\r\nexport class CollisionStartEvent extends GameEvent {\r\n /**\r\n *\r\n * @param actor\r\n * @param other\r\n * @param side\r\n * @param contact\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public contact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\r\n */\r\nexport class CollisionEndEvent extends GameEvent {\r\n /**\r\n *\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public lastContact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\r\n */\r\nexport class InitializeEvent extends GameEvent {\r\n /**\r\n * @param engine The reference to the current engine\r\n */\r\n constructor(public engine: Engine, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on a [[Scene]] on activation\r\n */\r\nexport class ActivateEvent extends GameEvent {\r\n /**\r\n * @param context The context for the scene activation\r\n */\r\n constructor(public context: SceneActivationContext, public target: Scene) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on a [[Scene]] on deactivation\r\n */\r\nexport class DeactivateEvent extends GameEvent {\r\n /**\r\n * @param context The context for the scene deactivation\r\n */\r\n constructor(public context: SceneActivationContext, public target: Scene) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when the graphics bounds completely leaves the screen.\r\n */\r\nexport class ExitViewPortEvent extends GameEvent {\r\n constructor(public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when any part of the graphics bounds are on screen.\r\n */\r\nexport class EnterViewPortEvent extends GameEvent {\r\n constructor(public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\nexport class EnterTriggerEvent extends GameEvent {\r\n constructor(public target: Trigger, public actor: Actor) {\r\n super();\r\n }\r\n}\r\n\r\nexport class ExitTriggerEvent extends GameEvent {\r\n constructor(public target: Trigger, public actor: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when an action starts.\r\n */\r\nexport class ActionStartEvent extends GameEvent {\r\n constructor(public action: Action, public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when an action completes.\r\n */\r\nexport class ActionCompleteEvent extends GameEvent {\r\n constructor(public action: Action, public target: Entity) {\r\n super();\r\n }\r\n}\r\n","import { GameEvent } from '../Events';\r\nimport { Sound } from '../Resources/Sound/Sound';\r\nimport { Actor } from '../Actor';\r\nimport { WebAudioInstance } from '../Resources/Sound/WebAudioInstance';\r\n\r\nexport class MediaEvent extends GameEvent {\r\n /**\r\n * Media event cannot bubble\r\n */\r\n public set bubbles(_value: boolean) {\r\n // stubbed\r\n }\r\n /**\r\n * Media event cannot bubble\r\n */\r\n public get bubbles(): boolean {\r\n return false;\r\n }\r\n /**\r\n * Media event cannot bubble, so they have no path\r\n */\r\n protected get _path(): Actor[] {\r\n return null;\r\n }\r\n /**\r\n * Media event cannot bubble, so they have no path\r\n */\r\n protected set _path(_val: Actor[]) {\r\n // stubbed\r\n }\r\n\r\n constructor(public target: Sound, protected _name: string = 'MediaEvent') {\r\n super();\r\n }\r\n\r\n /**\r\n * Prevents event from bubbling\r\n */\r\n public stopPropagation(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n /**\r\n * Action, that calls when event happens\r\n */\r\n public action(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n /**\r\n * Propagate event further through event path\r\n */\r\n public propagate(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n\r\n public layPath(_actor: Actor): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n}\r\n\r\nexport class NativeSoundEvent extends MediaEvent {\r\n constructor(target: Sound, public track?: WebAudioInstance) {\r\n super(target, 'NativeSoundEvent');\r\n }\r\n}\r\n\r\nexport class NativeSoundProcessedEvent extends MediaEvent {\r\n public data: string | AudioBuffer;\r\n\r\n constructor(target: Sound, private _processedData: string | AudioBuffer) {\r\n super(target, 'NativeSoundProcessedEvent');\r\n\r\n this.data = this._processedData;\r\n }\r\n}\r\n","import { Logger } from './Log';\r\n\r\n/**\r\n * Whether or not the browser can play this file as HTML5 Audio\r\n */\r\nexport function canPlayFile(file: string): boolean {\r\n try {\r\n const a = new Audio();\r\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\r\n const type = file.match(filetype)[1];\r\n if (a.canPlayType('audio/' + type)) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n } catch (e) {\r\n Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e);\r\n return false;\r\n }\r\n}\r\n","import { ExResponse } from '../../Interfaces/AudioImplementation';\r\nimport { Audio } from '../../Interfaces/Audio';\r\nimport { Engine } from '../../Engine';\r\nimport { Resource } from '../Resource';\r\nimport { WebAudioInstance } from './WebAudioInstance';\r\nimport { AudioContextFactory } from './AudioContext';\r\nimport { NativeSoundEvent, NativeSoundProcessedEvent } from '../../Events/MediaEvents';\r\nimport { canPlayFile } from '../../Util/Sound';\r\nimport { Loadable } from '../../Interfaces/Index';\r\nimport { Logger } from '../../Util/Log';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../../EventEmitter';\r\n\r\nexport type SoundEvents = {\r\n volumechange: NativeSoundEvent,\r\n processed: NativeSoundProcessedEvent,\r\n pause: NativeSoundEvent,\r\n stop: NativeSoundEvent,\r\n playbackend: NativeSoundEvent,\r\n resume: NativeSoundEvent,\r\n playbackstart: NativeSoundEvent\r\n}\r\n\r\nexport const SoundEvents = {\r\n VolumeChange: 'volumechange',\r\n Processed: 'processed',\r\n Pause: 'pause',\r\n Stop: 'stop',\r\n PlaybackEnd: 'playbackend',\r\n Resume: 'resume',\r\n PlaybackStart: 'playbackstart'\r\n};\r\n\r\n/**\r\n * The [[Sound]] object allows games built in Excalibur to load audio\r\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\r\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\r\n */\r\nexport class Sound implements Audio, Loadable {\r\n public events = new EventEmitter();\r\n public logger: Logger = Logger.getInstance();\r\n public data: AudioBuffer;\r\n private _resource: Resource;\r\n /**\r\n * Indicates whether the clip should loop when complete\r\n * @param value Set the looping flag\r\n */\r\n public set loop(value: boolean) {\r\n this._loop = value;\r\n\r\n for (const track of this._tracks) {\r\n track.loop = this._loop;\r\n }\r\n\r\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._loop);\r\n }\r\n public get loop(): boolean {\r\n return this._loop;\r\n }\r\n\r\n public set volume(value: number) {\r\n this._volume = value;\r\n\r\n for (const track of this._tracks) {\r\n track.volume = this._volume;\r\n }\r\n\r\n this.events.emit('volumechange', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._volume);\r\n }\r\n public get volume(): number {\r\n return this._volume;\r\n }\r\n\r\n private _duration: number | undefined;\r\n /**\r\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\r\n */\r\n public get duration(): number | undefined {\r\n return this._duration;\r\n }\r\n /**\r\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */\r\n public set duration(duration: number | undefined){\r\n this._duration = duration;\r\n }\r\n\r\n /**\r\n * Return array of Current AudioInstances playing or being paused\r\n */\r\n public get instances(): Audio[] {\r\n return this._tracks;\r\n }\r\n\r\n public get path() {\r\n return this._resource.path;\r\n }\r\n\r\n public set path(val: string) {\r\n this._resource.path = val;\r\n }\r\n\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n private _loop = false;\r\n private _volume = 1;\r\n private _isStopped = false;\r\n // private _isPaused = false;\r\n private _tracks: Audio[] = [];\r\n private _engine: Engine;\r\n private _wasPlayingOnHidden: boolean = false;\r\n private _playbackRate = 1.0;\r\n private _audioContext = AudioContextFactory.create();\r\n\r\n /**\r\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\r\n */\r\n constructor(...paths: string[]) {\r\n this._resource = new Resource('', ExResponse.type.arraybuffer);\r\n /**\r\n * Chrome : MP3, WAV, Ogg\r\n * Firefox : WAV, Ogg,\r\n * IE : MP3, WAV coming soon\r\n * Safari MP3, WAV, Ogg\r\n */\r\n for (const path of paths) {\r\n if (canPlayFile(path)) {\r\n this.path = path;\r\n break;\r\n }\r\n }\r\n\r\n if (!this.path) {\r\n this.logger.warn('This browser does not support any of the audio files specified:', paths.join(', '));\r\n this.logger.warn('Attempting to use', paths[0]);\r\n this.path = paths[0]; // select the first specified\r\n }\r\n }\r\n\r\n public isLoaded() {\r\n return !!this.data;\r\n }\r\n\r\n public async load(): Promise {\r\n if (this.data) {\r\n return this.data;\r\n }\r\n const arraybuffer = await this._resource.load();\r\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\r\n this._duration = this._duration ?? audiobuffer?.duration ?? undefined;\r\n this.events.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer));\r\n return this.data = audiobuffer;\r\n }\r\n\r\n public async decodeAudio(data: ArrayBuffer): Promise {\r\n try {\r\n return await this._audioContext.decodeAudioData(data.slice(0));\r\n } catch (e) {\r\n this.logger.error(\r\n 'Unable to decode ' +\r\n ' this browser may not fully support this format, or the file may be corrupt, ' +\r\n 'if this is an mp3 try removing id3 tags and album art from the file.'\r\n );\r\n return await Promise.reject();\r\n }\r\n }\r\n\r\n public wireEngine(engine: Engine) {\r\n if (engine) {\r\n this._engine = engine;\r\n\r\n this._engine.on('hidden', () => {\r\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\r\n this._wasPlayingOnHidden = true;\r\n this.pause();\r\n }\r\n });\r\n\r\n this._engine.on('visible', () => {\r\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.play();\r\n this._wasPlayingOnHidden = false;\r\n }\r\n });\r\n\r\n this._engine.on('start', () => {\r\n this._isStopped = false;\r\n });\r\n\r\n this._engine.on('stop', () => {\r\n this.stop();\r\n this._isStopped = true;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Returns how many instances of the sound are currently playing\r\n */\r\n public instanceCount(): number {\r\n return this._tracks.length;\r\n }\r\n\r\n /**\r\n * Whether or not the sound is playing right now\r\n */\r\n public isPlaying(): boolean {\r\n return this._tracks.some((t) => t.isPlaying());\r\n }\r\n\r\n public isPaused(): boolean {\r\n return this._tracks.some(t => t.isPaused());\r\n }\r\n\r\n public isStopped(): boolean {\r\n return this._tracks.some(t => t.isStopped());\r\n }\r\n\r\n /**\r\n * Play the sound, returns a promise that resolves when the sound is done playing\r\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\r\n */\r\n public play(volume?: number): Promise {\r\n if (!this.isLoaded()) {\r\n this.logger.warn('Cannot start playing. Resource', this.path, 'is not loaded yet');\r\n\r\n return Promise.resolve(true);\r\n }\r\n\r\n if (this._isStopped) {\r\n this.logger.warn('Cannot start playing. Engine is in a stopped state.');\r\n return Promise.resolve(false);\r\n }\r\n\r\n this.volume = volume || this.volume;\r\n\r\n if (this.isPaused()) {\r\n return this._resumePlayback();\r\n } else {\r\n return this._startPlayback();\r\n }\r\n }\r\n\r\n /**\r\n * Stop the sound, and do not rewind\r\n */\r\n public pause() {\r\n if (!this.isPlaying()) {\r\n return;\r\n }\r\n\r\n for (const track of this._tracks) {\r\n track.pause();\r\n }\r\n\r\n this.events.emit('pause', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Paused all instances of sound', this.path);\r\n }\r\n\r\n /**\r\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\r\n */\r\n public stop() {\r\n for (const track of this._tracks) {\r\n track.stop();\r\n }\r\n\r\n this.events.emit('stop', new NativeSoundEvent(this));\r\n\r\n this._tracks.length = 0;\r\n this.logger.debug('Stopped all instances of sound', this.path);\r\n }\r\n\r\n public get playbackRate(): number {\r\n return this._playbackRate;\r\n }\r\n\r\n public set playbackRate(playbackRate: number) {\r\n this._playbackRate = playbackRate;\r\n this._tracks.forEach(t => {\r\n t.playbackRate = this._playbackRate;\r\n });\r\n }\r\n\r\n public seek(position: number, trackId = 0) {\r\n if (this._tracks.length === 0) {\r\n this._getTrackInstance(this.data);\r\n }\r\n\r\n this._tracks[trackId].seek(position);\r\n }\r\n\r\n public getTotalPlaybackDuration() {\r\n if (!this.isLoaded()) {\r\n this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.` +\r\n `Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`);\r\n return 0;\r\n }\r\n return this.data.duration;\r\n }\r\n\r\n /**\r\n * Return the current playback time of the playing track in seconds from the start.\r\n *\r\n * Optionally specify the track to query if multiple are playing at once.\r\n * @param trackId\r\n */\r\n public getPlaybackPosition(trackId = 0) {\r\n if (this._tracks.length) {\r\n return this._tracks[trackId].getPlaybackPosition();\r\n }\r\n return 0;\r\n }\r\n\r\n\r\n\r\n /**\r\n * Get Id of provided AudioInstance in current trackList\r\n * @param track [[Audio]] which Id is to be given\r\n */\r\n public getTrackId(track: Audio): number {\r\n return this._tracks.indexOf(track);\r\n }\r\n\r\n private async _resumePlayback(): Promise {\r\n if (this.isPaused) {\r\n const resumed: Promise[] = [];\r\n // ensure we resume *current* tracks (if paused)\r\n for (const track of this._tracks) {\r\n resumed.push(track.play().then(() => {\r\n this._tracks.splice(this.getTrackId(track), 1);\r\n return true;\r\n }));\r\n }\r\n\r\n this.events.emit('resume', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Resuming paused instances for sound', this.path, this._tracks);\r\n // resolve when resumed tracks are done\r\n await Promise.all(resumed);\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Starts playback, returns a promise that resolves when playback is complete\r\n */\r\n private async _startPlayback(): Promise {\r\n const track = this._getTrackInstance(this.data);\r\n\r\n const complete = await track.play(() => {\r\n this.events.emit('playbackstart', new NativeSoundEvent(this, track));\r\n this.logger.debug('Playing new instance for sound', this.path);\r\n });\r\n\r\n this.events.emit('playbackend', new NativeSoundEvent(this, track));\r\n\r\n // cleanup any done tracks\r\n const trackId = this.getTrackId(track);\r\n if (trackId !== -1) {\r\n this._tracks.splice(trackId, 1);\r\n }\r\n\r\n return complete;\r\n }\r\n\r\n private _getTrackInstance(data: AudioBuffer): WebAudioInstance {\r\n const newTrack = new WebAudioInstance(data);\r\n\r\n newTrack.loop = this.loop;\r\n newTrack.volume = this.volume;\r\n newTrack.duration = this.duration;\r\n newTrack.playbackRate = this._playbackRate;\r\n\r\n this._tracks.push(newTrack);\r\n\r\n return newTrack;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: SoundEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n","import { WebAudio } from '../Util/WebAudio';\r\nimport { Engine } from '../Engine';\r\nimport { Loadable } from '../Interfaces/Loadable';\r\nimport { Canvas } from '../Graphics/Canvas';\r\nimport { ImageFiltering } from '../Graphics/Filtering';\r\nimport { clamp } from '../Math/util';\r\nimport { Sound } from '../Resources/Sound/Sound';\r\nimport { Future } from '../Util/Future';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { Color } from '../Color';\r\nimport { delay } from '../Util/Util';\r\n\r\nexport interface DefaultLoaderOptions {\r\n /**\r\n * List of loadables\r\n */\r\n loadables?: Loadable[];\r\n}\r\n\r\nexport type LoaderEvents = {\r\n // Add event types here\r\n beforeload: void,\r\n afterload: void,\r\n useraction: void,\r\n loadresourcestart: Loadable,\r\n loadresourceend: Loadable,\r\n}\r\n\r\nexport const LoaderEvents = {\r\n // Add event types here\r\n BeforeLoad: 'beforeload',\r\n AfterLoad: 'afterload',\r\n UserAction: 'useraction',\r\n LoadResourceStart: 'loadresourcestart',\r\n LoadResourceEnd: 'loadresourceend'\r\n};\r\n\r\nexport type LoaderConstructor = new (...args: any[]) => DefaultLoader;\r\n/**\r\n * Returns true if the constructor is for an Excalibur Loader\r\n */\r\nexport function isLoaderConstructor(x: any): x is LoaderConstructor {\r\n return !!x?.prototype && !!x?.prototype?.constructor?.name;\r\n}\r\n\r\nexport class DefaultLoader implements Loadable[]> {\r\n public data: Loadable[];\r\n public events = new EventEmitter();\r\n public canvas: Canvas = new Canvas({\r\n filtering: ImageFiltering.Blended,\r\n smoothing: true,\r\n cache: false,\r\n draw: this.onDraw.bind(this)\r\n });\r\n private _resources: Loadable[] = [];\r\n public get resources(): readonly Loadable[] {\r\n return this._resources;\r\n }\r\n private _numLoaded: number = 0;\r\n public engine: Engine;\r\n\r\n\r\n /**\r\n * @param options Optionally provide the list of resources you want to load at constructor time\r\n */\r\n constructor(options?: DefaultLoaderOptions) {\r\n if (options && options.loadables?.length) {\r\n this.addResources(options.loadables);\r\n }\r\n }\r\n\r\n /**\r\n * Called by the engine before loading\r\n * @param engine\r\n */\r\n public onInitialize(engine: Engine) {\r\n this.engine = engine;\r\n this.canvas.width = this.engine.screen.resolution.width;\r\n this.canvas.height = this.engine.screen.resolution.height;\r\n }\r\n\r\n /**\r\n * Return a promise that resolves when the user interacts with the loading screen in some way, usually a click.\r\n *\r\n * It's important to implement this in order to unlock the audio context in the browser. Browsers automatically prevent\r\n * audio from playing until the user performs an action.\r\n *\r\n */\r\n public async onUserAction(): Promise {\r\n\r\n return await Promise.resolve();\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called directly before loading starts\r\n */\r\n public async onBeforeLoad() {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called after loading has completed\r\n */\r\n public async onAfterLoad() {\r\n // override me\r\n await delay(500, this.engine.clock); // avoid a flicker\r\n }\r\n\r\n /**\r\n * Add a resource to the loader to load\r\n * @param loadable Resource to add\r\n */\r\n public addResource(loadable: Loadable) {\r\n this._resources.push(loadable);\r\n }\r\n\r\n /**\r\n * Add a list of resources to the loader to load\r\n * @param loadables The list of resources to load\r\n */\r\n public addResources(loadables: Loadable[]) {\r\n let i = 0;\r\n const len = loadables.length;\r\n\r\n for (i; i < len; i++) {\r\n this.addResource(loadables[i]);\r\n }\r\n }\r\n\r\n public markResourceComplete(): void {\r\n this._numLoaded++;\r\n }\r\n\r\n /**\r\n * Returns the progress of the loader as a number between [0, 1] inclusive.\r\n */\r\n public get progress(): number {\r\n const total = this._resources.length;\r\n return total > 0 ? clamp(this._numLoaded, 0, total) / total : 1;\r\n }\r\n\r\n /**\r\n * Returns true if the loader has completely loaded all resources\r\n */\r\n public isLoaded() {\r\n return this._numLoaded === this._resources.length;\r\n }\r\n\r\n private _totalTimeMs = 0;\r\n\r\n /**\r\n * Optionally override the onUpdate\r\n * @param engine\r\n * @param elapsedMilliseconds\r\n */\r\n onUpdate(engine: Engine, elapsedMilliseconds: number): void {\r\n this._totalTimeMs += elapsedMilliseconds;\r\n // override me\r\n }\r\n\r\n /**\r\n * Optionally override the onDraw\r\n */\r\n onDraw(ctx: CanvasRenderingContext2D) {\r\n const seconds = this._totalTimeMs / 1000;\r\n\r\n ctx.fillStyle = Color.Black.toRGBA();\r\n ctx.fillRect(0, 0, this.engine.screen.resolution.width, this.engine.screen.resolution.height);\r\n\r\n ctx.save();\r\n ctx.translate(this.engine.screen.resolution.width / 2, this.engine.screen.resolution.height / 2);\r\n const speed = seconds * 10;\r\n ctx.strokeStyle = 'white';\r\n ctx.lineWidth = 10;\r\n ctx.lineCap = 'round';\r\n ctx.arc(0, 0, 40, speed, speed + (Math.PI * 3 / 2));\r\n ctx.stroke();\r\n\r\n ctx.fillStyle = 'white';\r\n ctx.font = '16px sans-serif';\r\n const text = (this.progress * 100).toFixed(0) + '%';\r\n const textbox = ctx.measureText(text);\r\n const width = Math.abs(textbox.actualBoundingBoxLeft) + Math.abs(textbox.actualBoundingBoxRight);\r\n const height = Math.abs(textbox.actualBoundingBoxAscent) + Math.abs(textbox.actualBoundingBoxDescent);\r\n ctx.fillText(text, -width / 2, height / 2); // center\r\n ctx.restore();\r\n }\r\n\r\n\r\n private _loadingFuture = new Future();\r\n public areResourcesLoaded() {\r\n return this._loadingFuture.promise;\r\n }\r\n\r\n /**\r\n * Not meant to be overridden\r\n *\r\n * Begin loading all of the supplied resources, returning a promise\r\n * that resolves when loading of all is complete AND the user has interacted with the loading screen\r\n */\r\n public async load(): Promise[]> {\r\n await this.onBeforeLoad();\r\n this.events.emit('beforeload');\r\n this.canvas.flagDirty();\r\n\r\n await Promise.all(\r\n this._resources.map(async (r) => {\r\n this.events.emit('loadresourcestart', r);\r\n await r.load().finally(() => {\r\n // capture progress\r\n this._numLoaded++;\r\n this.canvas.flagDirty();\r\n this.events.emit('loadresourceend', r);\r\n });\r\n })\r\n );\r\n\r\n // Wire all sound to the engine\r\n for (const resource of this._resources) {\r\n if (resource instanceof Sound) {\r\n resource.wireEngine(this.engine);\r\n }\r\n }\r\n\r\n this._loadingFuture.resolve();\r\n this.canvas.flagDirty();\r\n // Unlock browser AudioContext in after user gesture\r\n // See: https://github.com/excaliburjs/Excalibur/issues/262\r\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\r\n await this.onUserAction();\r\n this.events.emit('useraction');\r\n await WebAudio.unlock();\r\n\r\n await this.onAfterLoad();\r\n this.events.emit('afterload');\r\n return (this.data = this._resources);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: LoaderEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n","import { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\n\r\n/**\r\n * A canvas linecap style. \"butt\" is the default flush style, \"round\" is a semi-circle cap with a radius half the width of\r\n * the line, and \"square\" is a rectangle that is an equal width and half height cap.\r\n */\r\nexport type LineCapStyle = 'butt' | 'round' | 'square';\r\n\r\n/* istanbul ignore next */\r\n/**\r\n * Draw a line on canvas context\r\n * @param ctx The canvas context\r\n * @param color The color of the line\r\n * @param x1 The start x coordinate\r\n * @param y1 The start y coordinate\r\n * @param x2 The ending x coordinate\r\n * @param y2 The ending y coordinate\r\n * @param thickness The line thickness\r\n * @param cap The [[LineCapStyle]] (butt, round, or square)\r\n */\r\nexport function line(\r\n ctx: CanvasRenderingContext2D,\r\n color: Color = Color.Red,\r\n x1: number,\r\n y1: number,\r\n x2: number,\r\n y2: number,\r\n thickness: number = 1,\r\n cap: LineCapStyle = 'butt'\r\n) {\r\n ctx.save();\r\n ctx.beginPath();\r\n ctx.lineWidth = thickness;\r\n ctx.lineCap = cap;\r\n ctx.strokeStyle = color.toString();\r\n ctx.moveTo(x1, y1);\r\n ctx.lineTo(x2, y2);\r\n ctx.closePath();\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n\r\n/* istanbul ignore next */\r\n/**\r\n * Draw the vector as a point onto the canvas.\r\n */\r\nexport function point(ctx: CanvasRenderingContext2D, color: Color = Color.Red, point: Vector): void {\r\n ctx.beginPath();\r\n ctx.strokeStyle = color.toString();\r\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\r\n ctx.closePath();\r\n ctx.stroke();\r\n}\r\n\r\n/**\r\n * Draw the vector as a line onto the canvas starting a origin point.\r\n */\r\n/* istanbul ignore next */\r\n/**\r\n *\r\n */\r\nexport function vector(ctx: CanvasRenderingContext2D, color: Color, origin: Vector, vector: Vector, scale: number = 1.0): void {\r\n const c = color ? color.toString() : 'blue';\r\n const v = vector.scale(scale);\r\n ctx.beginPath();\r\n ctx.strokeStyle = c;\r\n ctx.moveTo(origin.x, origin.y);\r\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\r\n ctx.closePath();\r\n ctx.stroke();\r\n}\r\n\r\n/**\r\n * Represents border radius values\r\n */\r\nexport interface BorderRadius {\r\n /**\r\n * Top-left\r\n */\r\n tl: number;\r\n /**\r\n * Top-right\r\n */\r\n tr: number;\r\n /**\r\n * Bottom-right\r\n */\r\n br: number;\r\n /**\r\n * Bottom-left\r\n */\r\n bl: number;\r\n}\r\n\r\n/**\r\n * Draw a round rectangle on a canvas context\r\n * @param ctx The canvas context\r\n * @param x The top-left x coordinate\r\n * @param y The top-left y coordinate\r\n * @param width The width of the rectangle\r\n * @param height The height of the rectangle\r\n * @param radius The border radius of the rectangle\r\n * @param stroke The [[Color]] to stroke rectangle with\r\n * @param fill The [[Color]] to fill rectangle with\r\n */\r\nexport function roundRect(\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n width: number,\r\n height: number,\r\n radius: number | BorderRadius = 5,\r\n stroke: Color = Color.White,\r\n fill: Color = null\r\n) {\r\n let br: BorderRadius;\r\n\r\n if (typeof radius === 'number') {\r\n br = { tl: radius, tr: radius, br: radius, bl: radius };\r\n } else {\r\n const defaultRadius: BorderRadius = { tl: 0, tr: 0, br: 0, bl: 0 };\r\n\r\n for (const prop in defaultRadius) {\r\n if (defaultRadius.hasOwnProperty(prop)) {\r\n const side = prop;\r\n br[side] = radius[side] || defaultRadius[side];\r\n }\r\n }\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(x + br.tl, y);\r\n ctx.lineTo(x + width - br.tr, y);\r\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\r\n ctx.lineTo(x + width, y + height - br.br);\r\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\r\n ctx.lineTo(x + br.bl, y + height);\r\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\r\n ctx.lineTo(x, y + br.tl);\r\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\r\n ctx.closePath();\r\n\r\n if (fill) {\r\n ctx.fillStyle = fill.toString();\r\n ctx.fill();\r\n }\r\n\r\n if (stroke) {\r\n ctx.strokeStyle = stroke.toString();\r\n ctx.stroke();\r\n }\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function circle(\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n radius: number,\r\n stroke: Color = Color.White,\r\n fill: Color = null\r\n) {\r\n ctx.beginPath();\r\n ctx.arc(x, y, radius, 0, Math.PI * 2);\r\n ctx.closePath();\r\n\r\n if (fill) {\r\n ctx.fillStyle = fill.toString();\r\n ctx.fill();\r\n }\r\n\r\n if (stroke) {\r\n ctx.strokeStyle = stroke.toString();\r\n ctx.stroke();\r\n }\r\n}\r\n","export default \"data:image/png;base64,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\"","import { Color } from '../Color';\r\nimport { Loadable } from '../Interfaces/Loadable';\r\nimport * as DrawUtil from '../Util/DrawUtil';\r\n\r\nimport logoImg from './Loader.logo.png';\r\nimport loaderCss from './Loader.css';\r\nimport { Vector } from '../Math/vector';\r\nimport { delay } from '../Util/Util';\r\nimport { EventEmitter } from '../EventEmitter';\r\nimport { DefaultLoader, DefaultLoaderOptions } from './DefaultLoader';\r\nimport { Engine } from '../Engine';\r\nimport { Screen } from '../Screen';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport interface LoaderOptions extends DefaultLoaderOptions {\r\n /**\r\n * Go fullscreen after loading and clicking play\r\n */\r\n fullscreenAfterLoad?: boolean;\r\n /**\r\n * Fullscreen container element or id\r\n */\r\n fullscreenContainer?: HTMLElement | string;\r\n}\r\n\r\n/**\r\n * Pre-loading assets\r\n *\r\n * The loader provides a mechanism to preload multiple resources at\r\n * one time. The loader must be passed to the engine in order to\r\n * trigger the loading progress bar.\r\n *\r\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\r\n *\r\n * ## Example: Pre-loading resources for a game\r\n *\r\n * ```js\r\n * // create a loader\r\n * var loader = new ex.Loader();\r\n *\r\n * // create a resource dictionary (best practice is to keep a separate file)\r\n * var resources = {\r\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\r\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\r\n * };\r\n *\r\n * // loop through dictionary and add to loader\r\n * for (var loadable in resources) {\r\n * if (resources.hasOwnProperty(loadable)) {\r\n * loader.addResource(resources[loadable]);\r\n * }\r\n * }\r\n *\r\n * // start game\r\n * game.start(loader).then(function () {\r\n * console.log(\"Game started!\");\r\n * });\r\n * ```\r\n *\r\n * ## Customize the Loader\r\n *\r\n * The loader can be customized to show different, text, logo, background color, and button.\r\n *\r\n * ```typescript\r\n * const loader = new ex.Loader([playerTexture]);\r\n *\r\n * // The loaders button text can simply modified using this\r\n * loader.playButtonText = 'Start the best game ever';\r\n *\r\n * // The logo can be changed by inserting a base64 image string here\r\n *\r\n * loader.logo = 'data:image/png;base64,iVBORw...';\r\n * loader.logoWidth = 15;\r\n * loader.logoHeight = 14;\r\n *\r\n * // The background color can be changed like so by supplying a valid CSS color string\r\n *\r\n * loader.backgroundColor = 'red'\r\n * loader.backgroundColor = '#176BAA'\r\n *\r\n * // To build a completely new button\r\n * loader.startButtonFactory = () => {\r\n * let myButton = document.createElement('button');\r\n * myButton.textContent = 'The best button';\r\n * return myButton;\r\n * };\r\n *\r\n * engine.start(loader).then(() => {});\r\n * ```\r\n */\r\nexport class Loader extends DefaultLoader {\r\n private _logger = Logger.getInstance();\r\n private static _DEFAULT_LOADER_OPTIONS: LoaderOptions = {\r\n loadables: [],\r\n fullscreenAfterLoad: false,\r\n fullscreenContainer: undefined\r\n };\r\n private _originalOptions: LoaderOptions = {loadables:[]};\r\n public events = new EventEmitter();\r\n public screen: Screen;\r\n private _playButtonShown: boolean = false;\r\n\r\n // logo drawing stuff\r\n\r\n // base64 string encoding of the excalibur logo (logo-white.png)\r\n public logo = logoImg;\r\n public logoWidth = 468;\r\n public logoHeight = 118;\r\n /**\r\n * Positions the top left corner of the logo image\r\n * If not set, the loader automatically positions the logo\r\n */\r\n public logoPosition: Vector | null;\r\n /**\r\n * Positions the top left corner of the play button.\r\n * If not set, the loader automatically positions the play button\r\n */\r\n public playButtonPosition: Vector | null;\r\n /**\r\n * Positions the top left corner of the loading bar\r\n * If not set, the loader automatically positions the loading bar\r\n */\r\n public loadingBarPosition: Vector | null;\r\n\r\n /**\r\n * Gets or sets the color of the loading bar, default is [[Color.White]]\r\n */\r\n public loadingBarColor: Color = Color.White;\r\n\r\n /**\r\n * Gets or sets the background color of the loader as a hex string\r\n */\r\n public backgroundColor: string = '#176BAA';\r\n\r\n protected _imageElement: HTMLImageElement;\r\n protected get _image() {\r\n if (!this._imageElement) {\r\n this._imageElement = new Image();\r\n this._imageElement.src = this.logo;\r\n }\r\n\r\n return this._imageElement;\r\n }\r\n\r\n public suppressPlayButton: boolean = false;\r\n public get playButtonRootElement(): HTMLElement | null {\r\n return this._playButtonRootElement;\r\n }\r\n public get playButtonElement(): HTMLButtonElement | null {\r\n return this._playButtonElement;\r\n }\r\n protected _playButtonRootElement: HTMLElement;\r\n protected _playButtonElement: HTMLButtonElement;\r\n protected _styleBlock: HTMLStyleElement;\r\n /** Loads the css from Loader.css */\r\n protected _playButtonStyles: string = loaderCss.toString();\r\n protected get _playButton() {\r\n const existingRoot = document.getElementById('excalibur-play-root');\r\n if (existingRoot) {\r\n this._playButtonRootElement = existingRoot;\r\n }\r\n if (!this._playButtonRootElement) {\r\n this._playButtonRootElement = document.createElement('div');\r\n this._playButtonRootElement.id = 'excalibur-play-root';\r\n this._playButtonRootElement.style.position = 'absolute';\r\n document.body.appendChild(this._playButtonRootElement);\r\n }\r\n if (!this._styleBlock) {\r\n this._styleBlock = document.createElement('style');\r\n this._styleBlock.textContent = this._playButtonStyles;\r\n document.head.appendChild(this._styleBlock);\r\n }\r\n if (!this._playButtonElement) {\r\n this._playButtonElement = this.startButtonFactory();\r\n this._playButtonRootElement.appendChild(this._playButtonElement);\r\n }\r\n return this._playButtonElement;\r\n }\r\n\r\n /**\r\n * Get/set play button text\r\n */\r\n public playButtonText: string = 'Play game';\r\n\r\n /**\r\n * Return a html button element for excalibur to use as a play button\r\n */\r\n public startButtonFactory = () => {\r\n let buttonElement: HTMLButtonElement = document.getElementById('excalibur-play') as HTMLButtonElement;\r\n if (!buttonElement) {\r\n buttonElement = document.createElement('button');\r\n }\r\n\r\n buttonElement.id = 'excalibur-play';\r\n buttonElement.textContent = this.playButtonText;\r\n buttonElement.style.display = 'none';\r\n return buttonElement;\r\n };\r\n\r\n /**\r\n * @param options Optionally provide options to loader\r\n */\r\n constructor(options?: LoaderOptions);\r\n /**\r\n * @param loadables Optionally provide the list of resources you want to load at constructor time\r\n */\r\n constructor(loadables?: Loadable[]);\r\n constructor(loadablesOrOptions?: Loadable[] | LoaderOptions) {\r\n const options = Array.isArray(loadablesOrOptions) ? {\r\n loadables: loadablesOrOptions\r\n } : loadablesOrOptions;\r\n super(options);\r\n this._originalOptions = { ...Loader._DEFAULT_LOADER_OPTIONS, ...options };\r\n }\r\n\r\n public override onInitialize(engine: Engine): void {\r\n this.engine = engine;\r\n this.screen = engine.screen;\r\n this.canvas.width = this.engine.canvas.width;\r\n this.canvas.height = this.engine.canvas.height;\r\n }\r\n\r\n /**\r\n * Shows the play button and returns a promise that resolves when clicked\r\n */\r\n public async showPlayButton(): Promise {\r\n if (this.suppressPlayButton) {\r\n this.hidePlayButton();\r\n // Delay is to give the logo a chance to show, otherwise don't delay\r\n await delay(500, this.engine?.clock);\r\n } else {\r\n const resizeHandler = () => {\r\n try {\r\n this._positionPlayButton();\r\n } catch {\r\n // swallow if can't position\r\n };\r\n };\r\n if (this.engine?.browser) {\r\n this.engine.browser.window.on('resize', resizeHandler);\r\n }\r\n this._playButtonShown = true;\r\n this._playButton.style.display = 'block';\r\n document.body.addEventListener('keyup', (evt: KeyboardEvent) => {\r\n if (evt.key === 'Enter') {\r\n this._playButton.click();\r\n }\r\n });\r\n this._positionPlayButton();\r\n const playButtonClicked = new Promise(resolve => {\r\n const startButtonHandler = (e: Event) => {\r\n // We want to stop propagation to keep bubbling to the engine pointer handlers\r\n e.stopPropagation();\r\n // Hide Button after click\r\n this.hidePlayButton();\r\n if (this.engine?.browser) {\r\n this.engine.browser.window.off('resize', resizeHandler);\r\n }\r\n\r\n if (this._originalOptions.fullscreenAfterLoad) {\r\n try {\r\n this._logger.info('requesting fullscreen');\r\n if (this._originalOptions.fullscreenContainer instanceof HTMLElement) {\r\n this._originalOptions.fullscreenContainer.requestFullscreen();\r\n } else {\r\n this.engine.screen.goFullScreen(this._originalOptions.fullscreenContainer);\r\n }\r\n } catch (error) {\r\n this._logger.error('could not go fullscreen', error);\r\n }\r\n }\r\n\r\n resolve();\r\n };\r\n this._playButton.addEventListener('click', startButtonHandler);\r\n this._playButton.addEventListener('touchend', startButtonHandler);\r\n this._playButton.addEventListener('pointerup', startButtonHandler);\r\n });\r\n\r\n return await playButtonClicked;\r\n }\r\n }\r\n\r\n public hidePlayButton() {\r\n this._playButtonShown = false;\r\n this._playButton.style.display = 'none';\r\n }\r\n\r\n /**\r\n * Clean up generated elements for the loader\r\n */\r\n public dispose() {\r\n if (this._playButtonRootElement.parentElement) {\r\n this._playButtonRootElement.removeChild(this._playButtonElement);\r\n document.body.removeChild(this._playButtonRootElement);\r\n document.head.removeChild(this._styleBlock);\r\n this._playButtonRootElement = null;\r\n this._playButtonElement = null;\r\n this._styleBlock = null;\r\n }\r\n }\r\n\r\n data: Loadable[];\r\n\r\n public override async onUserAction(): Promise {\r\n // short delay in showing the button for aesthetics\r\n await delay(200, this.engine?.clock);\r\n this.canvas.flagDirty();\r\n // show play button\r\n await this.showPlayButton();\r\n }\r\n\r\n private _configuredPixelRatio: number | null = null;\r\n public override async onBeforeLoad(): Promise {\r\n this._configuredPixelRatio = this.screen.pixelRatioOverride;\r\n // Push the current user entered resolution/viewport\r\n this.screen.pushResolutionAndViewport();\r\n // Configure resolution for loader, it expects resolution === viewport\r\n this.screen.resolution = this.screen.viewport;\r\n this.screen.pixelRatioOverride = 1;\r\n this.screen.applyResolutionAndViewport();\r\n\r\n this.canvas.width = this.engine.canvas.width;\r\n this.canvas.height = this.engine.canvas.height;\r\n\r\n await this._image?.decode(); // decode logo if it exists\r\n }\r\n\r\n // eslint-disable-next-line require-await\r\n public override async onAfterLoad(): Promise {\r\n this.screen.pixelRatioOverride = this._configuredPixelRatio;\r\n this.screen.popResolutionAndViewport();\r\n this.screen.applyResolutionAndViewport();\r\n this.dispose();\r\n }\r\n\r\n private _positionPlayButton() {\r\n if (this.engine) {\r\n const screenHeight = this.engine.screen.viewport.height;\r\n const screenWidth = this.engine.screen.viewport.width;\r\n if (this._playButtonRootElement) {\r\n const left = this.engine.canvas.offsetLeft;\r\n const top = this.engine.canvas.offsetTop;\r\n const buttonWidth = this._playButton.clientWidth;\r\n const buttonHeight = this._playButton.clientHeight;\r\n if (this.playButtonPosition) {\r\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\r\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\r\n } else {\r\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\r\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Loader draw function. Draws the default Excalibur loading screen.\r\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\r\n * to customize the drawing, or just override entire method.\r\n */\r\n public override onDraw(ctx: CanvasRenderingContext2D) {\r\n const canvasHeight = this.engine.canvasHeight / this.engine.pixelRatio;\r\n const canvasWidth = this.engine.canvasWidth / this.engine.pixelRatio;\r\n\r\n this._positionPlayButton();\r\n\r\n ctx.fillStyle = this.backgroundColor;\r\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\r\n\r\n let logoY = canvasHeight / 2;\r\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\r\n let logoX = canvasWidth / 2 - width / 2;\r\n\r\n if (this.logoPosition) {\r\n logoX = this.logoPosition.x;\r\n logoY = this.logoPosition.y;\r\n }\r\n\r\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\r\n const oldAntialias = this.engine.getAntialiasing();\r\n this.engine.setAntialiasing(true);\r\n if (!this.logoPosition) {\r\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\r\n } else {\r\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\r\n }\r\n\r\n // loading box\r\n if (!this.suppressPlayButton && this._playButtonShown) {\r\n this.engine.setAntialiasing(oldAntialias);\r\n return;\r\n }\r\n\r\n let loadingX = logoX;\r\n let loadingY = logoY;\r\n if (this.loadingBarPosition) {\r\n loadingX = this.loadingBarPosition.x;\r\n loadingY = this.loadingBarPosition.y;\r\n }\r\n\r\n ctx.lineWidth = 2;\r\n DrawUtil.roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\r\n const progress = width * this.progress;\r\n const margin = 5;\r\n const progressWidth = progress - margin * 2;\r\n const height = 20 - margin * 2;\r\n DrawUtil.roundRect(\r\n ctx,\r\n loadingX + margin,\r\n loadingY + margin,\r\n progressWidth > 10 ? progressWidth : 10,\r\n height,\r\n 5,\r\n null,\r\n this.loadingBarColor\r\n );\r\n this.engine.setAntialiasing(oldAntialias);\r\n }\r\n}\r\n","import { Logger } from './Log';\r\n/**\r\n * This is the list of features that will be used to log the supported\r\n * features to the console when Detector.logBrowserFeatures() is called.\r\n */\r\n\r\nconst REPORTED_FEATURES: { [key: string]: string } = {\r\n webgl: 'WebGL',\r\n webaudio: 'WebAudio',\r\n gamepadapi: 'Gamepad API'\r\n};\r\n\r\n/**\r\n * Interface for detected browser features matrix\r\n */\r\nexport interface DetectedFeatures {\r\n readonly canvas: boolean;\r\n readonly arraybuffer: boolean;\r\n readonly dataurl: boolean;\r\n readonly objecturl: boolean;\r\n readonly rgba: boolean;\r\n readonly webaudio: boolean;\r\n readonly webgl: boolean;\r\n readonly gamepadapi: boolean;\r\n}\r\n\r\ninterface CriticalTests {\r\n canvasSupport(): boolean;\r\n arrayBufferSupport(): boolean;\r\n dataUrlSupport(): boolean;\r\n objectUrlSupport(): boolean;\r\n rgbaSupport(): boolean;\r\n}\r\n\r\ninterface WarningTests {\r\n webAudioSupport(): boolean;\r\n webglSupport(): boolean;\r\n}\r\n\r\n/**\r\n * Excalibur internal feature detection helper class\r\n */\r\nexport class Detector {\r\n private _features: DetectedFeatures = null;\r\n\r\n public failedTests: string[] = [];\r\n\r\n public constructor() {\r\n this._features = this._loadBrowserFeatures();\r\n }\r\n\r\n /**\r\n * Returns a map of currently supported browser features. This method\r\n * treats the features as a singleton and will only calculate feature\r\n * support if it has not previously been done.\r\n */\r\n public getBrowserFeatures(): DetectedFeatures {\r\n if (this._features === null) {\r\n this._features = this._loadBrowserFeatures();\r\n }\r\n return this._features;\r\n }\r\n\r\n /**\r\n * Report on non-critical browser support for debugging purposes.\r\n * Use native browser console colors for visibility.\r\n */\r\n public logBrowserFeatures(): void {\r\n let msg = '%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n';\r\n const args = ['font-weight: bold; color: navy', 'font-weight: normal; color: inherit'];\r\n\r\n const supported: any = this.getBrowserFeatures();\r\n for (const feature of Object.keys(REPORTED_FEATURES)) {\r\n if (supported[feature]) {\r\n msg += '(%c\\u2713%c)'; // (✓)\r\n args.push('font-weight: bold; color: green');\r\n args.push('font-weight: normal; color: inherit');\r\n } else {\r\n msg += '(%c\\u2717%c)'; // (✗)\r\n args.push('font-weight: bold; color: red');\r\n args.push('font-weight: normal; color: inherit');\r\n }\r\n\r\n msg += ' ' + REPORTED_FEATURES[feature] + '\\n';\r\n }\r\n\r\n args.unshift(msg);\r\n // eslint-disable-next-line no-console\r\n console.log.apply(console, args);\r\n }\r\n\r\n /**\r\n * Executes several IIFE's to get a constant reference to supported\r\n * features within the current execution context.\r\n */\r\n private _loadBrowserFeatures(): DetectedFeatures {\r\n return {\r\n // IIFE to check canvas support\r\n canvas: (() => {\r\n return this._criticalTests.canvasSupport();\r\n })(),\r\n\r\n // IIFE to check arraybuffer support\r\n arraybuffer: (() => {\r\n return this._criticalTests.arrayBufferSupport();\r\n })(),\r\n\r\n // IIFE to check dataurl support\r\n dataurl: (() => {\r\n return this._criticalTests.dataUrlSupport();\r\n })(),\r\n\r\n // IIFE to check objecturl support\r\n objecturl: (() => {\r\n return this._criticalTests.objectUrlSupport();\r\n })(),\r\n\r\n // IIFE to check rgba support\r\n rgba: (() => {\r\n return this._criticalTests.rgbaSupport();\r\n })(),\r\n\r\n // IIFE to check webaudio support\r\n webaudio: (() => {\r\n return this._warningTest.webAudioSupport();\r\n })(),\r\n\r\n // IIFE to check webgl support\r\n webgl: (() => {\r\n return this._warningTest.webglSupport();\r\n })(),\r\n\r\n // IIFE to check gamepadapi support\r\n gamepadapi: (() => {\r\n return !!(navigator).getGamepads;\r\n })()\r\n };\r\n }\r\n\r\n // critical browser features required for ex to run\r\n private _criticalTests: CriticalTests = {\r\n // Test canvas/2d context support\r\n canvasSupport: function() {\r\n const elem = document.createElement('canvas');\r\n return !!(elem.getContext && elem.getContext('2d'));\r\n },\r\n\r\n // Test array buffer support ex uses for downloading binary data\r\n arrayBufferSupport: function() {\r\n const xhr = new XMLHttpRequest();\r\n xhr.open('GET', '/');\r\n try {\r\n xhr.responseType = 'arraybuffer';\r\n } catch (e) {\r\n return false;\r\n }\r\n return xhr.responseType === 'arraybuffer';\r\n },\r\n\r\n // Test data urls ex uses for sprites\r\n dataUrlSupport: function() {\r\n const canvas = document.createElement('canvas');\r\n return canvas.toDataURL('image/png').indexOf('data:image/png') === 0;\r\n },\r\n\r\n // Test object url support for loading\r\n objectUrlSupport: function() {\r\n return 'URL' in window && 'revokeObjectURL' in URL && 'createObjectURL' in URL;\r\n },\r\n\r\n // RGBA support for colors\r\n rgbaSupport: function() {\r\n const style = document.createElement('a').style;\r\n style.cssText = 'background-color:rgba(150,255,150,.5)';\r\n return ('' + style.backgroundColor).indexOf('rgba') > -1;\r\n }\r\n };\r\n\r\n // warnings excalibur performance will be degraded\r\n private _warningTest: WarningTests = {\r\n webAudioSupport: function() {\r\n return !!(\r\n (window).AudioContext ||\r\n (window).webkitAudioContext ||\r\n (window).mozAudioContext ||\r\n (window).msAudioContext ||\r\n (window).oAudioContext\r\n );\r\n },\r\n webglSupport: function() {\r\n const elem = document.createElement('canvas');\r\n return !!(elem.getContext && elem.getContext('webgl'));\r\n }\r\n };\r\n\r\n public test(): boolean {\r\n // Critical test will for ex not to run\r\n let failedCritical = false;\r\n for (const test in this._criticalTests) {\r\n if (!this._criticalTests[test].call(this)) {\r\n this.failedTests.push(test);\r\n Logger.getInstance().error('Critical browser feature missing, Excalibur requires:', test);\r\n failedCritical = true;\r\n }\r\n }\r\n if (failedCritical) {\r\n return false;\r\n }\r\n\r\n // Warning tests do not for ex to return false to compatibility\r\n for (const warning in this._warningTest) {\r\n if (!this._warningTest[warning]()) {\r\n Logger.getInstance().warn('Warning browser feature missing, Excalibur will have reduced performance:', warning);\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n","/**\r\n * An enum that describes the types of collisions bodies can participate in\r\n */\r\nexport enum CollisionType {\r\n /**\r\n * Bodies with the `PreventCollision` setting do not participate in any\r\n * collisions and do not raise collision events.\r\n */\r\n PreventCollision = 'PreventCollision',\r\n /**\r\n * Bodies with the `Passive` setting only raise collision events, but are not\r\n * influenced or moved by other bodies and do not influence or move other bodies.\r\n * This is useful for use in trigger type behavior.\r\n */\r\n Passive = 'Passive',\r\n /**\r\n * Bodies with the `Active` setting raise collision events and participate\r\n * in collisions with other bodies and will be push or moved by bodies sharing\r\n * the `Active` or `Fixed` setting.\r\n */\r\n Active = 'Active',\r\n /**\r\n * Bodies with the `Fixed` setting raise collision events and participate in\r\n * collisions with other bodies. Actors with the `Fixed` setting will not be\r\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\r\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\r\n * not be pushed or moved by each other, they will not interact except to throw\r\n * collision events.\r\n */\r\n Fixed = 'Fixed'\r\n}\r\n","/**\r\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\r\n */\r\nexport enum CoordPlane {\r\n /**\r\n * The world coordinate plane (default) represents world space, any entities drawn with world\r\n * space move when the camera moves.\r\n */\r\n World = 'world',\r\n /**\r\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\r\n * to screen coordinates ignoring the camera.\r\n */\r\n Screen = 'screen'\r\n}","import { Vector } from './vector';\r\n\r\nexport interface VectorViewOptions {\r\n getX: () => number;\r\n getY: () => number;\r\n setX: (x: number) => void;\r\n setY: (y: number) => void;\r\n}\r\nexport class VectorView extends Vector {\r\n private _getX: () => number;\r\n private _getY: () => number;\r\n private _setX: (x: number) => void;\r\n private _setY: (y: number) => void;\r\n constructor(options: VectorViewOptions) {\r\n super(0, 0);\r\n this._getX = options.getX;\r\n this._getY = options.getY;\r\n this._setX = options.setX;\r\n this._setY = options.setY;\r\n }\r\n public get x() {\r\n return (this._x = this._getX());\r\n }\r\n\r\n public set x(val) {\r\n this._setX(val);\r\n this._x = val;\r\n }\r\n\r\n public get y() {\r\n return (this._y = this._getY());\r\n }\r\n public set y(val) {\r\n this._setY(val);\r\n this._y = val;\r\n }\r\n}\r\n","import { Vector } from './vector';\r\n\r\n/**\r\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\r\n */\r\nexport class WatchVector extends Vector {\r\n constructor(public original: Vector, public change: (x: number, y: number) => any) {\r\n super(original.x, original.y);\r\n }\r\n public get x() {\r\n return this._x = this.original.x;\r\n }\r\n\r\n public set x(newX: number) {\r\n this.change(newX, this._y);\r\n this._x = this.original.x = newX;\r\n }\r\n\r\n public get y() {\r\n return this._y = this.original.y;\r\n }\r\n\r\n public set y(newY: number) {\r\n this.change(this._x, newY);\r\n this._y = this.original.y = newY;\r\n }\r\n}","import { AffineMatrix } from './affine-matrix';\r\nimport { canonicalizeAngle } from './util';\r\nimport { vec, Vector } from './vector';\r\nimport { VectorView } from './vector-view';\r\nimport { WatchVector } from './watch-vector';\r\n\r\nexport class Transform {\r\n private _parent: Transform | null = null;\r\n get parent() {\r\n return this._parent;\r\n }\r\n set parent(transform: Transform | null) {\r\n if (this._parent) {\r\n const index = this._parent._children.indexOf(this);\r\n if (index > -1) {\r\n this._parent._children.splice(index, 1);\r\n }\r\n }\r\n this._parent = transform;\r\n if (this._parent) {\r\n this._parent._children.push(this);\r\n }\r\n this.flagDirty();\r\n }\r\n get children(): readonly Transform[] {\r\n return this._children;\r\n }\r\n private _children: Transform[] = [];\r\n\r\n private _pos: Vector = vec(0, 0);\r\n set pos(v: Vector) {\r\n if (!v.equals(this._pos)) {\r\n this._pos.x = v.x;\r\n this._pos.y = v.y;\r\n this.flagDirty();\r\n }\r\n }\r\n get pos() {\r\n return new WatchVector(this._pos, (x, y) => {\r\n if (x !== this._pos.x || y !== this._pos.y) {\r\n this.flagDirty();\r\n }\r\n });\r\n }\r\n\r\n set globalPos(v: Vector) {\r\n let localPos = v.clone();\r\n if (this.parent) {\r\n localPos = this.parent.inverse.multiply(v);\r\n }\r\n if (!localPos.equals(this._pos)) {\r\n this._pos = localPos;\r\n this.flagDirty();\r\n }\r\n }\r\n get globalPos() {\r\n return new VectorView({\r\n getX: () => this.matrix.data[4],\r\n getY: () => this.matrix.data[5],\r\n setX: (x) => {\r\n if (this.parent) {\r\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\r\n this.pos.x = newX;\r\n } else {\r\n this.pos.x = x;\r\n }\r\n if (x !== this.matrix.data[4]) {\r\n this.flagDirty();\r\n }\r\n },\r\n setY: (y) => {\r\n if (this.parent) {\r\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\r\n this.pos.y = newY;\r\n } else {\r\n this.pos.y = y;\r\n }\r\n if (y !== this.matrix.data[5]) {\r\n this.flagDirty();\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _rotation: number = 0;\r\n set rotation(rotation: number) {\r\n const canonRotation = canonicalizeAngle(rotation);\r\n if (canonRotation !== this._rotation) {\r\n this.flagDirty();\r\n }\r\n this._rotation = canonRotation;\r\n }\r\n get rotation() {\r\n return this._rotation;\r\n }\r\n\r\n set globalRotation(rotation: number) {\r\n let inverseRotation = 0;\r\n if (this.parent) {\r\n inverseRotation = this.parent.globalRotation;\r\n }\r\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\r\n if (canonRotation !== this._rotation) {\r\n this.flagDirty();\r\n }\r\n this._rotation = canonRotation;\r\n }\r\n\r\n get globalRotation() {\r\n if (this.parent) {\r\n return this.matrix.getRotation();\r\n }\r\n return this.rotation;\r\n }\r\n\r\n private _scale: Vector = vec(1, 1);\r\n set scale(v: Vector) {\r\n if (!v.equals(this._scale)) {\r\n this._scale.x = v.x;\r\n this._scale.y = v.y;\r\n this.flagDirty();\r\n }\r\n }\r\n get scale() {\r\n return new WatchVector(this._scale, (x, y) => {\r\n if (x !== this._scale.x || y !== this._scale.y) {\r\n this.flagDirty();\r\n }\r\n });\r\n }\r\n\r\n set globalScale(v: Vector) {\r\n let inverseScale = vec(1, 1);\r\n if (this.parent) {\r\n inverseScale = this.parent.globalScale;\r\n }\r\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\r\n }\r\n\r\n get globalScale() {\r\n return new VectorView({\r\n getX: () => this.parent ? this.matrix.getScaleX() : this.scale.x,\r\n getY: () => this.parent ? this.matrix.getScaleY() : this.scale.y,\r\n setX: (x) => {\r\n if (this.parent) {\r\n const globalScaleX = this.parent.globalScale.x;\r\n this.scale.x = x / globalScaleX;\r\n } else {\r\n this.scale.x = x;\r\n }\r\n },\r\n setY: (y) => {\r\n if (this.parent) {\r\n const globalScaleY = this.parent.globalScale.y;\r\n this.scale.y = y / globalScaleY;\r\n } else {\r\n this.scale.y = y;\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _isDirty = false;\r\n private _isInverseDirty = false;\r\n private _matrix = AffineMatrix.identity();\r\n private _inverse = AffineMatrix.identity();\r\n\r\n public get matrix() {\r\n if (this._isDirty) {\r\n if (this.parent === null) {\r\n this._matrix = this._calculateMatrix();\r\n } else {\r\n this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\r\n }\r\n this._isDirty = false;\r\n }\r\n return this._matrix;\r\n }\r\n\r\n public get inverse() {\r\n if (this._isInverseDirty) {\r\n this._inverse = this.matrix.inverse();\r\n this._isInverseDirty = false;\r\n }\r\n return this._inverse;\r\n }\r\n\r\n private _calculateMatrix(): AffineMatrix {\r\n const matrix = AffineMatrix.identity()\r\n .translate(this.pos.x, this.pos.y)\r\n .rotate(this.rotation)\r\n .scale(this.scale.x, this.scale.y);\r\n return matrix;\r\n }\r\n\r\n\r\n public flagDirty() {\r\n this._isDirty = true;\r\n this._isInverseDirty = true;\r\n for (let i = 0; i < this._children.length; i ++) {\r\n this._children[i].flagDirty();\r\n }\r\n }\r\n\r\n public apply(point: Vector): Vector {\r\n return this.matrix.multiply(point);\r\n }\r\n\r\n public applyInverse(point: Vector): Vector {\r\n return this.inverse.multiply(point);\r\n }\r\n\r\n public setTransform(pos: Vector, rotation: number, scale: Vector) {\r\n this._pos.x = pos.x;\r\n this._pos.y = pos.y;\r\n this._rotation = canonicalizeAngle(rotation);\r\n this._scale.x = scale.x;\r\n this._scale.y = scale.y;\r\n this.flagDirty();\r\n }\r\n\r\n /**\r\n * Clones the current transform\r\n * **Warning does not clone the parent**\r\n * @param dest\r\n */\r\n public clone(dest?: Transform) {\r\n const target = dest ?? new Transform();\r\n this._pos.clone(target._pos);\r\n target._rotation = this._rotation;\r\n this._scale.clone(target._scale);\r\n target.flagDirty();\r\n return target;\r\n }\r\n}","import { Entity } from './Entity';\r\n\r\n/**\r\n * Component Constructor Types\r\n */\r\nexport declare type ComponentCtor = new (...args:any[]) => TComponent;\r\n\r\n/**\r\n *\r\n */\r\nexport function isComponentCtor(value: any): value is ComponentCtor {\r\n return !!value && !!value.prototype && !!value.prototype.constructor;\r\n}\r\n\r\n/**\r\n * Type guard to check if a component implements clone\r\n * @param x\r\n */\r\nfunction hasClone(x: any): x is { clone(): any } {\r\n return !!x?.clone;\r\n}\r\n\r\n/**\r\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\r\n *\r\n * Implementations of Component must have a zero-arg constructor to support dependencies\r\n *\r\n * ```typescript\r\n * class MyComponent extends ex.Component {\r\n * // zero arg support required if you want to use component dependencies\r\n * constructor(public optionalPos?: ex.Vector) {}\r\n * }\r\n * ```\r\n */\r\nexport abstract class Component {\r\n // TODO maybe generate a unique id?\r\n\r\n /**\r\n * Optionally list any component types this component depends on\r\n * If the owner entity does not have these components, new components will be added to the entity\r\n *\r\n * Only components with zero-arg constructors are supported as automatic component dependencies\r\n */\r\n readonly dependencies?: ComponentCtor[];\r\n\r\n /**\r\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\r\n */\r\n owner?: Entity = undefined;\r\n\r\n /**\r\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\r\n */\r\n clone(): Component {\r\n const newComponent = new (this.constructor as any)();\r\n for (const prop in this) {\r\n if (this.hasOwnProperty(prop)) {\r\n const val = this[prop];\r\n if (hasClone(val) && prop !== 'owner' && prop !== 'clone') {\r\n newComponent[prop] = val.clone();\r\n } else {\r\n newComponent[prop] = val;\r\n }\r\n }\r\n }\r\n return newComponent;\r\n }\r\n\r\n /**\r\n * Optional callback called when a component is added to an entity\r\n */\r\n onAdd?(owner: Entity): void;\r\n\r\n /**\r\n * Optional callback called when a component is removed from an entity\r\n */\r\n onRemove?(previousOwner: Entity): void;\r\n}","/**\r\n * Defines a generic message that can contain any data\r\n * @template T is the typescript Type of the data\r\n */\r\nexport interface Message {\r\n type: string;\r\n data: T;\r\n}\r\n\r\n/**\r\n * Defines an interface for an observer to receive a message via a notify() method\r\n */\r\nexport interface Observer {\r\n notify(message: T): void;\r\n}\r\n\r\n/**\r\n * Defines an interface for something that might be an observer if a notify() is present\r\n */\r\nexport type MaybeObserver = Partial>;\r\n\r\n/**\r\n * Simple Observable implementation\r\n * @template T is the typescript Type that defines the data being observed\r\n */\r\nexport class Observable {\r\n public observers: Observer[] = [];\r\n public subscriptions: ((val: T) => any)[] = [];\r\n\r\n /**\r\n * Register an observer to listen to this observable\r\n * @param observer\r\n */\r\n register(observer: Observer) {\r\n this.observers.push(observer);\r\n }\r\n\r\n /**\r\n * Register a callback to listen to this observable\r\n * @param func\r\n */\r\n subscribe(func: (val: T) => any) {\r\n this.subscriptions.push(func);\r\n }\r\n\r\n /**\r\n * Remove an observer from the observable\r\n * @param observer\r\n */\r\n unregister(observer: Observer) {\r\n const i = this.observers.indexOf(observer);\r\n if (i !== -1) {\r\n this.observers.splice(i, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Remove a callback that is listening to this observable\r\n * @param func\r\n */\r\n unsubscribe(func: (val: T) => any) {\r\n const i = this.subscriptions.indexOf(func);\r\n if (i !== -1) {\r\n this.subscriptions.splice(i, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Broadcasts a message to all observers and callbacks\r\n * @param message\r\n */\r\n notifyAll(message: T) {\r\n const observersLength = this.observers.length;\r\n for (let i = 0; i < observersLength; i++) {\r\n this.observers[i].notify(message);\r\n }\r\n const subscriptionsLength = this.subscriptions.length;\r\n for (let i = 0; i < subscriptionsLength; i++) {\r\n this.subscriptions[i](message);\r\n }\r\n }\r\n\r\n /**\r\n * Removes all observers and callbacks\r\n */\r\n clear() {\r\n this.observers.length = 0;\r\n this.subscriptions.length = 0;\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { CoordPlane } from '../../Math/coord-plane';\r\nimport { Transform } from '../../Math/transform';\r\nimport { Component } from '../Component';\r\nimport { Entity } from '../Entity';\r\nimport { Observable } from '../../Util/Observable';\r\nimport { Logger } from '../../Util/Log';\r\n\r\n\r\nexport class TransformComponent extends Component {\r\n private _logger = Logger.getInstance();\r\n private _parentComponent: TransformComponent | null = null;\r\n private _transform = new Transform();\r\n public get() {\r\n return this._transform;\r\n }\r\n\r\n private _addChildTransform = (child: Entity) => {\r\n const childTxComponent = child.get(TransformComponent);\r\n if (childTxComponent) {\r\n childTxComponent._transform.parent = this._transform;\r\n childTxComponent._parentComponent = this;\r\n }\r\n };\r\n onAdd(owner: Entity): void {\r\n for (const child of owner.children) {\r\n this._addChildTransform(child);\r\n }\r\n owner.childrenAdded$.subscribe(child => this._addChildTransform(child));\r\n owner.childrenRemoved$.subscribe(child => {\r\n const childTxComponent = child.get(TransformComponent);\r\n if (childTxComponent) {\r\n childTxComponent._transform.parent = null;\r\n childTxComponent._parentComponent = null;\r\n }\r\n });\r\n }\r\n onRemove(_previousOwner: Entity): void {\r\n this._transform.parent = null;\r\n this._parentComponent = null;\r\n }\r\n\r\n /**\r\n * Observable that emits when the z index changes on this component\r\n */\r\n public zIndexChanged$ = new Observable();\r\n private _z = 0;\r\n\r\n /**\r\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\r\n * For example z=99 would be drawn on top of z=0.\r\n */\r\n public get z(): number {\r\n return this._z;\r\n }\r\n\r\n public set z(val: number) {\r\n const oldz = this._z;\r\n this._z = val;\r\n if (oldz !== val) {\r\n this.zIndexChanged$.notifyAll(val);\r\n }\r\n }\r\n\r\n private _coordPlane = CoordPlane.World;\r\n /**\r\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\r\n */\r\n public get coordPlane() {\r\n if (this._parentComponent) {\r\n return this._parentComponent.coordPlane;\r\n }\r\n return this._coordPlane;\r\n }\r\n\r\n public set coordPlane(value: CoordPlane) {\r\n if (!this._parentComponent) {\r\n this._coordPlane = value;\r\n } else {\r\n this._logger.warn(\r\n `Cannot set coordinate plane on child entity ${this.owner?.name}, children inherit their coordinate plane from their parents.`);\r\n }\r\n }\r\n\r\n get pos() {\r\n return this._transform.pos;\r\n }\r\n set pos(v: Vector) {\r\n this._transform.pos = v;\r\n }\r\n\r\n get globalPos() {\r\n return this._transform.globalPos;\r\n }\r\n set globalPos(v: Vector) {\r\n this._transform.globalPos = v;\r\n }\r\n\r\n get rotation() {\r\n return this._transform.rotation;\r\n }\r\n set rotation(rotation) {\r\n this._transform.rotation = rotation;\r\n }\r\n\r\n get globalRotation() {\r\n return this._transform.globalRotation;\r\n }\r\n set globalRotation(rotation) {\r\n this._transform.globalRotation = rotation;\r\n }\r\n\r\n get scale() {\r\n return this._transform.scale;\r\n }\r\n set scale(v: Vector) {\r\n this._transform.scale = v;\r\n }\r\n\r\n get globalScale() {\r\n return this._transform.globalScale;\r\n }\r\n set globalScale(v: Vector) {\r\n this._transform.globalScale = v;\r\n }\r\n\r\n applyInverse(v: Vector) {\r\n return this._transform.applyInverse(v);\r\n }\r\n\r\n apply(v: Vector) {\r\n return this._transform.apply(v);\r\n }\r\n\r\n clone(): TransformComponent {\r\n const component = new TransformComponent();\r\n component._transform = this._transform.clone();\r\n component._z = this._z;\r\n return component;\r\n }\r\n}","import { Vector } from '../../Math/vector';\r\nimport { Component } from '../Component';\r\n\r\nexport interface Motion {\r\n /**\r\n * The velocity of an entity in pixels per second\r\n */\r\n vel: Vector;\r\n\r\n /**\r\n * The acceleration of entity in pixels per second^2\r\n */\r\n acc: Vector;\r\n\r\n /**\r\n * The scale rate of change in scale units per second\r\n */\r\n scaleFactor: Vector;\r\n\r\n /**\r\n * The angular velocity which is how quickly the entity is rotating in radians per second\r\n */\r\n angularVelocity: number;\r\n\r\n /**\r\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\r\n */\r\n torque: number;\r\n\r\n /**\r\n * Inertia can be thought of as the resistance to motion\r\n */\r\n inertia: number;\r\n}\r\n\r\nexport class MotionComponent extends Component {\r\n\r\n /**\r\n * The velocity of an entity in pixels per second\r\n */\r\n public vel: Vector = Vector.Zero;\r\n\r\n /**\r\n * The acceleration of entity in pixels per second^2\r\n */\r\n public acc: Vector = Vector.Zero;\r\n\r\n /**\r\n * The scale rate of change in scale units per second\r\n */\r\n public scaleFactor: Vector = Vector.Zero;\r\n\r\n /**\r\n * The angular velocity which is how quickly the entity is rotating in radians per second\r\n */\r\n public angularVelocity = 0;\r\n\r\n /**\r\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\r\n */\r\n public torque: number = 0;\r\n\r\n /**\r\n * Inertia can be thought of as the resistance to motion\r\n */\r\n public inertia: number = 1;\r\n}\r\n","import { CollisionGroup } from './CollisionGroup';\r\n\r\n/**\r\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\r\n */\r\nexport class CollisionGroupManager {\r\n // using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\r\n private static _STARTING_BIT = 0b1 | 0;\r\n private static _MAX_GROUPS = 32;\r\n private static _CURRENT_GROUP = 1;\r\n private static _CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\r\n private static _GROUPS: Map = new Map();\r\n\r\n /**\r\n * Create a new named collision group up to a max of 32.\r\n * @param name Name for the collision group\r\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\r\n */\r\n public static create(name: string, mask?: number) {\r\n if (this._CURRENT_GROUP > this._MAX_GROUPS) {\r\n throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\r\n }\r\n if (this._GROUPS.get(name)) {\r\n const existingGroup = this._GROUPS.get(name);\r\n if (existingGroup.mask === mask) {\r\n return existingGroup;\r\n }\r\n throw new Error(`Collision group ${name} already exists with a different mask!`);\r\n }\r\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\r\n this._CURRENT_BIT = (this._CURRENT_BIT << 1) | 0;\r\n this._CURRENT_GROUP++;\r\n this._GROUPS.set(name, group);\r\n return group;\r\n }\r\n\r\n /**\r\n * Get all collision groups currently tracked by excalibur\r\n */\r\n public static get groups(): CollisionGroup[] {\r\n return Array.from(this._GROUPS.values());\r\n }\r\n\r\n /**\r\n * Get a collision group by it's name\r\n * @param name\r\n */\r\n public static groupByName(name: string) {\r\n return this._GROUPS.get(name);\r\n }\r\n\r\n /**\r\n * Resets the managers internal group management state\r\n */\r\n public static reset() {\r\n this._GROUPS = new Map();\r\n this._CURRENT_BIT = this._STARTING_BIT;\r\n this._CURRENT_GROUP = 1;\r\n }\r\n}\r\n","import { CollisionGroupManager } from './CollisionGroupManager';\r\n\r\n/**\r\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\r\n *\r\n * For example:\r\n *\r\n * Players have collision group \"player\"\r\n *\r\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\r\n *\r\n * Enemies have collision group \"enemy\"\r\n *\r\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\r\n *\r\n * Blocks have collision group \"ground\"\r\n *\r\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\r\n *\r\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\r\n * with players and blocks.\r\n *\r\n * This is done with bitmasking, see the following pseudo-code\r\n *\r\n * PlayerGroup = `0b001`\r\n * PlayerGroupMask = `0b110`\r\n *\r\n * EnemyGroup = `0b010`\r\n * EnemyGroupMask = `0b101`\r\n *\r\n * BlockGroup = `0b100`\r\n * BlockGroupMask = `0b011`\r\n *\r\n * Should Players collide? No because the bitwise mask evaluates to 0\r\n * `(player1.group & player2.mask) === 0`\r\n * `(0b001 & 0b110) === 0`\r\n *\r\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & enemy1.mask) === 1`\r\n * `(0b001 & 0b101) === 1`\r\n *\r\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & blocks1.mask) === 1`\r\n * `(0b001 & 0b011) === 1`\r\n */\r\nexport class CollisionGroup {\r\n /**\r\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\r\n * it is the default collision group on colliders.\r\n */\r\n public static All = new CollisionGroup('Collide with all groups', -1, -1);\r\n\r\n private _name: string;\r\n private _category: number;\r\n private _mask: number;\r\n\r\n /**\r\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\r\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\r\n * @param name Name of the collision group\r\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\r\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\r\n */\r\n constructor(name: string, category: number, mask: number) {\r\n this._name = name;\r\n this._category = category;\r\n this._mask = mask;\r\n }\r\n\r\n /**\r\n * Get the name of the collision group\r\n */\r\n public get name() {\r\n return this._name;\r\n }\r\n\r\n /**\r\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\r\n */\r\n public get category() {\r\n return this._category;\r\n }\r\n\r\n /**\r\n * Get the mask for this collision group\r\n */\r\n public get mask() {\r\n return this._mask;\r\n }\r\n\r\n /**\r\n * Evaluates whether 2 collision groups can collide\r\n *\r\n * This means the mask has the same bit set the other category and vice versa\r\n * @param other CollisionGroup\r\n */\r\n public canCollide(other: CollisionGroup): boolean {\r\n const overlap1 = this.category & other.mask;\r\n const overlap2 = this.mask & other.category;\r\n return (overlap1 !== 0) && (overlap2 !== 0);\r\n }\r\n\r\n /**\r\n * Inverts the collision group. For example, if before the group specified \"players\",\r\n * inverting would specify all groups except players\r\n * @returns CollisionGroup\r\n */\r\n public invert(): CollisionGroup {\r\n const group = CollisionGroupManager.create('~(' + this.name + ')', ~this.mask | 0);\r\n group._category = ~this.category;\r\n return group;\r\n }\r\n\r\n /**\r\n * Combine collision groups with each other. The new group includes all of the previous groups.\r\n * @param collisionGroups\r\n */\r\n public static combine(collisionGroups: CollisionGroup[]) {\r\n const combinedName = collisionGroups.map((c) => c.name).join('+');\r\n const combinedCategory = collisionGroups.reduce((current, g) => g.category | current, 0b0);\r\n const combinedMask = ~combinedCategory;\r\n\r\n return CollisionGroupManager.create(combinedName, combinedMask);\r\n }\r\n\r\n /**\r\n * Creates a collision group that collides with the listed groups\r\n * @param collisionGroups\r\n */\r\n public static collidesWith(collisionGroups: CollisionGroup[]) {\r\n const combinedName = `collidesWith(${collisionGroups.map((c) => c.name).join('+')})`;\r\n const combinedMask = collisionGroups.reduce((current, g) => g.category | current, 0b0);\r\n return CollisionGroupManager.create(combinedName, combinedMask);\r\n }\r\n\r\n public toString() {\r\n return `\r\ncategory: ${this.category.toString(2).padStart(32, '0')}\r\nmask: ${(this.mask>>>0).toString(2).padStart(32, '0')}\r\n `;\r\n }\r\n}\r\n","import { CollisionContact } from './CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { Id } from '../../Id';\r\nimport { Collider } from '../Colliders/Collider';\r\n\r\n/**\r\n * Models a potential collision between 2 colliders\r\n */\r\nexport class Pair {\r\n public id: string = null;\r\n constructor(public colliderA: Collider, public colliderB: Collider) {\r\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n }\r\n\r\n /**\r\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\r\n * @param colliderA\r\n * @param colliderB\r\n */\r\n public static canCollide(colliderA: Collider, colliderB: Collider) {\r\n const bodyA = colliderA?.owner?.get(BodyComponent);\r\n const bodyB = colliderB?.owner?.get(BodyComponent);\r\n\r\n // Prevent self collision\r\n if (colliderA.id === colliderB.id) {\r\n return false;\r\n }\r\n\r\n // Colliders with the same owner do not collide (composite colliders)\r\n if (colliderA.owner &&\r\n colliderB.owner &&\r\n colliderA.owner.id === colliderB.owner.id) {\r\n return false;\r\n }\r\n\r\n // if the pair has a member with zero dimension don't collide\r\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) {\r\n return false;\r\n }\r\n\r\n // Body's needed for collision in the current state\r\n // TODO can we collide without a body?\r\n if (!bodyA || !bodyB) {\r\n return false;\r\n }\r\n\r\n // If both are in the same collision group short circuit\r\n if (!bodyA.group.canCollide(bodyB.group)) {\r\n return false;\r\n }\r\n\r\n // if both are fixed short circuit\r\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) {\r\n return false;\r\n }\r\n\r\n // if the either is prevent collision short circuit\r\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) {\r\n return false;\r\n }\r\n\r\n // if either is dead short circuit\r\n if (!bodyA.active || !bodyB.active) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns whether or not it is possible for the pairs to collide\r\n */\r\n public get canCollide(): boolean {\r\n const colliderA = this.colliderA;\r\n const colliderB = this.colliderB;\r\n return Pair.canCollide(colliderA, colliderB);\r\n }\r\n\r\n /**\r\n * Runs the collision intersection logic on the members of this pair\r\n */\r\n public collide(): CollisionContact[] {\r\n return this.colliderA.collide(this.colliderB);\r\n }\r\n\r\n /**\r\n * Check if the collider is part of the pair\r\n * @param collider\r\n */\r\n public hasCollider(collider: Collider) {\r\n return collider === this.colliderA || collider === this.colliderB;\r\n }\r\n\r\n /**\r\n * Calculates the unique pair hash id for this collision pair (owning id)\r\n */\r\n public static calculatePairHash(idA: Id<'collider'>, idB: Id<'collider'>): string {\r\n if (idA.value < idB.value) {\r\n return `#${idA.value}+${idB.value}`;\r\n } else {\r\n return `#${idB.value}+${idA.value}`;\r\n }\r\n }\r\n}\r\n","/**\r\n * A 1 dimensional projection on an axis, used to test overlaps\r\n */\r\n\r\nexport class Projection {\r\n constructor(public min: number, public max: number) {}\r\n public overlaps(projection: Projection): boolean {\r\n return this.max > projection.min && projection.max > this.min;\r\n }\r\n\r\n public getOverlap(projection: Projection): number {\r\n if (this.overlaps(projection)) {\r\n if (this.max > projection.max) {\r\n return projection.max - this.min;\r\n } else {\r\n return this.max - projection.min;\r\n }\r\n }\r\n return 0;\r\n }\r\n}\r\n","import { BoundingBox } from '../BoundingBox';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Id } from '../../Id';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { Color, ExcaliburGraphicsContext } from '../..';\r\nimport { PhysicsConfig } from '../PhysicsConfig';\r\n\r\n/**\r\n * Dynamic Tree Node used for tracking bounds within the tree\r\n */\r\nexport class TreeNode {\r\n public left: TreeNode;\r\n public right: TreeNode;\r\n public bounds: BoundingBox;\r\n public height: number;\r\n public data: T;\r\n constructor(public parent?: TreeNode) {\r\n this.parent = parent || null;\r\n this.data = null;\r\n this.bounds = new BoundingBox();\r\n this.left = null;\r\n this.right = null;\r\n this.height = 0;\r\n }\r\n\r\n public isLeaf(): boolean {\r\n return !this.left && !this.right;\r\n }\r\n}\r\n\r\nexport interface ColliderProxy {\r\n id: Id<'collider'>;\r\n owner: T;\r\n bounds: BoundingBox;\r\n}\r\n\r\n/**\r\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\r\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\r\n *\r\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\r\n * Every non-leaf node is a bounding box that contains child bounding boxes.\r\n */\r\nexport class DynamicTree> {\r\n public root: TreeNode;\r\n public nodes: { [key: number]: TreeNode };\r\n constructor(\r\n private _config: Required['dynamicTree']>,\r\n public worldBounds: BoundingBox = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)) {\r\n this.root = null;\r\n this.nodes = {};\r\n }\r\n\r\n /**\r\n * Inserts a node into the dynamic tree\r\n */\r\n private _insert(leaf: TreeNode): void {\r\n // If there are no nodes in the tree, make this the root leaf\r\n if (this.root === null) {\r\n this.root = leaf;\r\n this.root.parent = null;\r\n return;\r\n }\r\n\r\n // Search the tree for a node that is not a leaf and find the best place to insert\r\n const leafAABB = leaf.bounds;\r\n let currentRoot = this.root;\r\n while (!currentRoot.isLeaf()) {\r\n const left = currentRoot.left;\r\n const right = currentRoot.right;\r\n\r\n const area = currentRoot.bounds.getPerimeter();\r\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\r\n const combinedArea = combinedAABB.getPerimeter();\r\n\r\n // Calculate cost heuristic for creating a new parent and leaf\r\n const cost = 2 * combinedArea;\r\n\r\n // Minimum cost of pushing the leaf down the tree\r\n const inheritanceCost = 2 * (combinedArea - area);\r\n\r\n // Cost of descending\r\n let leftCost = 0;\r\n const leftCombined = leafAABB.combine(left.bounds);\r\n let newArea;\r\n let oldArea;\r\n if (left.isLeaf()) {\r\n leftCost = leftCombined.getPerimeter() + inheritanceCost;\r\n } else {\r\n oldArea = left.bounds.getPerimeter();\r\n newArea = leftCombined.getPerimeter();\r\n leftCost = newArea - oldArea + inheritanceCost;\r\n }\r\n\r\n let rightCost = 0;\r\n const rightCombined = leafAABB.combine(right.bounds);\r\n if (right.isLeaf()) {\r\n rightCost = rightCombined.getPerimeter() + inheritanceCost;\r\n } else {\r\n oldArea = right.bounds.getPerimeter();\r\n newArea = rightCombined.getPerimeter();\r\n rightCost = newArea - oldArea + inheritanceCost;\r\n }\r\n\r\n // cost is acceptable\r\n if (cost < leftCost && cost < rightCost) {\r\n break;\r\n }\r\n\r\n // Descend to the depths\r\n if (leftCost < rightCost) {\r\n currentRoot = left;\r\n } else {\r\n currentRoot = right;\r\n }\r\n }\r\n\r\n // Create the new parent node and insert into the tree\r\n const oldParent = currentRoot.parent;\r\n const newParent = new TreeNode(oldParent);\r\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\r\n newParent.height = currentRoot.height + 1;\r\n\r\n if (oldParent !== null) {\r\n // The sibling node was not the root\r\n if (oldParent.left === currentRoot) {\r\n oldParent.left = newParent;\r\n } else {\r\n oldParent.right = newParent;\r\n }\r\n\r\n newParent.left = currentRoot;\r\n newParent.right = leaf;\r\n\r\n currentRoot.parent = newParent;\r\n leaf.parent = newParent;\r\n } else {\r\n // The sibling node was the root\r\n newParent.left = currentRoot;\r\n newParent.right = leaf;\r\n\r\n currentRoot.parent = newParent;\r\n leaf.parent = newParent;\r\n this.root = newParent;\r\n }\r\n\r\n // Walk up the tree fixing heights and AABBs\r\n let currentNode = leaf.parent;\r\n while (currentNode) {\r\n currentNode = this._balance(currentNode);\r\n\r\n if (!currentNode.left) {\r\n throw new Error('Parent of current leaf cannot have a null left child' + currentNode);\r\n }\r\n if (!currentNode.right) {\r\n throw new Error('Parent of current leaf cannot have a null right child' + currentNode);\r\n }\r\n\r\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\r\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\r\n\r\n currentNode = currentNode.parent;\r\n }\r\n }\r\n\r\n /**\r\n * Removes a node from the dynamic tree\r\n */\r\n private _remove(leaf: TreeNode) {\r\n if (leaf === this.root) {\r\n this.root = null;\r\n return;\r\n }\r\n\r\n const parent = leaf.parent;\r\n const grandParent = parent.parent;\r\n let sibling: TreeNode;\r\n if (parent.left === leaf) {\r\n sibling = parent.right;\r\n } else {\r\n sibling = parent.left;\r\n }\r\n\r\n if (grandParent) {\r\n if (grandParent.left === parent) {\r\n grandParent.left = sibling;\r\n } else {\r\n grandParent.right = sibling;\r\n }\r\n sibling.parent = grandParent;\r\n\r\n let currentNode = grandParent;\r\n while (currentNode) {\r\n currentNode = this._balance(currentNode);\r\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\r\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\r\n\r\n currentNode = currentNode.parent;\r\n }\r\n } else {\r\n this.root = sibling;\r\n sibling.parent = null;\r\n }\r\n }\r\n\r\n /**\r\n * Tracks a body in the dynamic tree\r\n */\r\n public trackCollider(collider: T) {\r\n const node = new TreeNode();\r\n node.data = collider;\r\n node.bounds = collider.bounds;\r\n node.bounds.left -= 2;\r\n node.bounds.top -= 2;\r\n node.bounds.right += 2;\r\n node.bounds.bottom += 2;\r\n this.nodes[collider.id.value] = node;\r\n this._insert(node);\r\n }\r\n\r\n /**\r\n * Updates the dynamic tree given the current bounds of each body being tracked\r\n */\r\n public updateCollider(collider: T) {\r\n const node = this.nodes[collider.id.value];\r\n if (!node) {\r\n return false;\r\n }\r\n const b = collider.bounds;\r\n\r\n // if the body is outside the world no longer update it\r\n if (!this.worldBounds.contains(b)) {\r\n Logger.getInstance().warn(\r\n 'Collider with id ' + collider.id.value + ' is outside the world bounds and will no longer be tracked for physics'\r\n );\r\n this.untrackCollider(collider);\r\n return false;\r\n }\r\n\r\n if (node.bounds.contains(b)) {\r\n return false;\r\n }\r\n\r\n this._remove(node);\r\n b.left -= this._config.boundsPadding;\r\n b.top -= this._config.boundsPadding;\r\n b.right += this._config.boundsPadding;\r\n b.bottom += this._config.boundsPadding;\r\n\r\n // THIS IS CAUSING UNNECESSARY CHECKS\r\n if (collider.owner) {\r\n const body = collider.owner?.get(BodyComponent);\r\n if (body) {\r\n const multdx = ((body.vel.x * 32) / 1000) * this._config.velocityMultiplier;\r\n const multdy = ((body.vel.y * 32) / 1000) * this._config.velocityMultiplier;\r\n\r\n if (multdx < 0) {\r\n b.left += multdx;\r\n } else {\r\n b.right += multdx;\r\n }\r\n\r\n if (multdy < 0) {\r\n b.top += multdy;\r\n } else {\r\n b.bottom += multdy;\r\n }\r\n }\r\n }\r\n\r\n node.bounds = b;\r\n this._insert(node);\r\n return true;\r\n }\r\n\r\n /**\r\n * Untracks a body from the dynamic tree\r\n */\r\n public untrackCollider(collider: T) {\r\n const node = this.nodes[collider.id.value];\r\n if (!node) {\r\n return;\r\n }\r\n this._remove(node);\r\n this.nodes[collider.id.value] = null;\r\n delete this.nodes[collider.id.value];\r\n }\r\n\r\n /**\r\n * Balances the tree about a node\r\n */\r\n private _balance(node: TreeNode) {\r\n if (node === null) {\r\n throw new Error('Cannot balance at null node');\r\n }\r\n\r\n if (node.isLeaf() || node.height < 2) {\r\n return node;\r\n }\r\n\r\n const left = node.left;\r\n const right = node.right;\r\n\r\n const a = node;\r\n const b = left;\r\n const c = right;\r\n const d = left.left;\r\n const e = left.right;\r\n const f = right.left;\r\n const g = right.right;\r\n\r\n const balance = c.height - b.height;\r\n // Rotate c node up\r\n if (balance > 1) {\r\n // Swap the right node with it's parent\r\n c.left = a;\r\n c.parent = a.parent;\r\n a.parent = c;\r\n\r\n // The original node's old parent should point to the right node\r\n // this is mega confusing\r\n if (c.parent) {\r\n if (c.parent.left === a) {\r\n c.parent.left = c;\r\n } else {\r\n c.parent.right = c;\r\n }\r\n } else {\r\n this.root = c;\r\n }\r\n\r\n // Rotate\r\n if (f.height > g.height) {\r\n c.right = f;\r\n a.right = g;\r\n g.parent = a;\r\n\r\n a.bounds = b.bounds.combine(g.bounds);\r\n c.bounds = a.bounds.combine(f.bounds);\r\n\r\n a.height = 1 + Math.max(b.height, g.height);\r\n c.height = 1 + Math.max(a.height, f.height);\r\n } else {\r\n c.right = g;\r\n a.right = f;\r\n f.parent = a;\r\n\r\n a.bounds = b.bounds.combine(f.bounds);\r\n c.bounds = a.bounds.combine(g.bounds);\r\n\r\n a.height = 1 + Math.max(b.height, f.height);\r\n c.height = 1 + Math.max(a.height, g.height);\r\n }\r\n\r\n return c;\r\n }\r\n // Rotate left node up\r\n if (balance < -1) {\r\n // swap\r\n b.left = a;\r\n b.parent = a.parent;\r\n a.parent = b;\r\n\r\n // node's old parent should point to b\r\n if (b.parent) {\r\n if (b.parent.left === a) {\r\n b.parent.left = b;\r\n } else {\r\n if (b.parent.right !== a) {\r\n throw 'Error rotating Dynamic Tree';\r\n }\r\n b.parent.right = b;\r\n }\r\n } else {\r\n this.root = b;\r\n }\r\n\r\n // rotate\r\n if (d.height > e.height) {\r\n b.right = d;\r\n a.left = e;\r\n e.parent = a;\r\n\r\n a.bounds = c.bounds.combine(e.bounds);\r\n b.bounds = a.bounds.combine(d.bounds);\r\n\r\n a.height = 1 + Math.max(c.height, e.height);\r\n b.height = 1 + Math.max(a.height, d.height);\r\n } else {\r\n b.right = e;\r\n a.left = d;\r\n d.parent = a;\r\n\r\n a.bounds = c.bounds.combine(d.bounds);\r\n b.bounds = a.bounds.combine(e.bounds);\r\n\r\n a.height = 1 + Math.max(c.height, d.height);\r\n b.height = 1 + Math.max(a.height, e.height);\r\n }\r\n return b;\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /**\r\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\r\n */\r\n public getHeight(): number {\r\n if (this.root === null) {\r\n return 0;\r\n }\r\n return this.root.height;\r\n }\r\n\r\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\r\n *\r\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\r\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\r\n * the tree until all possible colliders have been returned.\r\n */\r\n public query(collider: T, callback: (other: T) => boolean): void {\r\n const bounds = collider.bounds;\r\n const helper = (currentNode: TreeNode): boolean => {\r\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\r\n if (currentNode.isLeaf() && currentNode.data !== collider) {\r\n if (callback.call(collider, currentNode.data)) {\r\n return true;\r\n }\r\n } else {\r\n return helper(currentNode.left) || helper(currentNode.right);\r\n }\r\n }\r\n return false;\r\n };\r\n helper(this.root);\r\n }\r\n\r\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\r\n * long ray to test the tree specified by `max`.\r\n *\r\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\r\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\r\n * the tree until all possible bodies that would intersect with the ray have been returned.\r\n */\r\n public rayCastQuery(ray: Ray, max: number = Infinity, callback: (other: T) => boolean): void {\r\n const helper = (currentNode: TreeNode): boolean => {\r\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\r\n if (currentNode.isLeaf()) {\r\n if (callback.call(ray, currentNode.data)) {\r\n // ray hit a leaf! return the body\r\n return true;\r\n }\r\n } else {\r\n // ray hit but not at a leaf, recurse deeper\r\n return helper(currentNode.left) || helper(currentNode.right);\r\n }\r\n }\r\n return false; // ray missed\r\n };\r\n helper(this.root);\r\n }\r\n\r\n public getNodes(): TreeNode[] {\r\n const helper = (currentNode: TreeNode): TreeNode[] => {\r\n if (currentNode) {\r\n return [currentNode].concat(helper(currentNode.left), helper(currentNode.right));\r\n } else {\r\n return [];\r\n }\r\n };\r\n return helper(this.root);\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext) {\r\n // draw all the nodes in the Dynamic Tree\r\n const helper = (currentNode: TreeNode) => {\r\n if (currentNode) {\r\n if (currentNode.isLeaf()) {\r\n currentNode.bounds.draw(ex, Color.Green);\r\n } else {\r\n currentNode.bounds.draw(ex, Color.White);\r\n }\r\n\r\n if (currentNode.left) {\r\n helper(currentNode.left);\r\n }\r\n if (currentNode.right) {\r\n helper(currentNode.right);\r\n }\r\n }\r\n };\r\n\r\n helper(this.root);\r\n }\r\n}\r\n","import { LineSegment } from './line-segment';\r\nimport { Vector } from './vector';\r\n\r\n/**\r\n * A 2D ray that can be cast into the scene to do collision detection\r\n */\r\n\r\nexport class Ray {\r\n public pos: Vector;\r\n public dir: Vector;\r\n\r\n /**\r\n * @param pos The starting position for the ray\r\n * @param dir The vector indicating the direction of the ray\r\n */\r\n constructor(pos: Vector, dir: Vector) {\r\n this.pos = pos;\r\n this.dir = dir.normalize();\r\n }\r\n\r\n /**\r\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\r\n * This number indicates the mathematical intersection time.\r\n * @param line The line to test\r\n */\r\n public intersect(line: LineSegment): number {\r\n const numerator = line.begin.sub(this.pos);\r\n\r\n // Test is line and ray are parallel and non intersecting\r\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) {\r\n return -1;\r\n }\r\n\r\n // Lines are parallel\r\n const divisor = this.dir.cross(line.getSlope());\r\n if (divisor === 0) {\r\n return -1;\r\n }\r\n\r\n const t = numerator.cross(line.getSlope()) / divisor;\r\n\r\n if (t >= 0) {\r\n const u = numerator.cross(this.dir) / divisor / line.getLength();\r\n if (u >= 0 && u <= 1) {\r\n return t;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n public intersectPoint(line: LineSegment): Vector {\r\n const time = this.intersect(line);\r\n if (time < 0) {\r\n return null;\r\n }\r\n return this.getPoint(time);\r\n }\r\n\r\n /**\r\n * Returns the point of intersection given the intersection time\r\n */\r\n public getPoint(time: number): Vector {\r\n return this.pos.add(this.dir.scale(time));\r\n }\r\n}\r\n","import { CollisionProcessor } from './CollisionProcessor';\r\nimport { DynamicTree } from './DynamicTree';\r\nimport { Pair } from './Pair';\r\n\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { FrameStats } from '../../Debug';\r\nimport { Logger } from '../../Util/Log';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Collider } from '../Colliders/Collider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { CompositeCollider } from '../Colliders/CompositeCollider';\r\nimport { CollisionGroup } from '../Group/CollisionGroup';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { RayCastHit } from './RayCastHit';\r\nimport { DeepRequired } from '../../Util/Required';\r\nimport { PhysicsConfig } from '../PhysicsConfig';\r\n\r\nexport interface RayCastOptions {\r\n /**\r\n * Optionally specify the maximum distance in pixels to ray cast, default is Infinity\r\n */\r\n maxDistance?: number;\r\n /**\r\n * Optionally specify a collision group to target in the ray cast, default is All.\r\n */\r\n collisionGroup?: CollisionGroup;\r\n /**\r\n * Optionally specify a collision mask to target multiple collision categories\r\n */\r\n collisionMask?: number;\r\n /**\r\n * Optionally specify to search for all colliders that intersect the ray cast, not just the first which is the default\r\n */\r\n searchAllColliders?: boolean;\r\n /**\r\n * Optionally ignore things with CollisionGroup.All and only test against things with an explicit group\r\n *\r\n * Default false\r\n */\r\n ignoreCollisionGroupAll?: boolean;\r\n\r\n /**\r\n * Optionally provide a any filter function to filter on arbitrary qualities of a ray cast hit\r\n *\r\n * Filters run after any collision mask/collision group filtering, it is the last decision\r\n *\r\n * Returning true means you want to include the collider in your results, false means exclude it\r\n */\r\n filter?: (hit: RayCastHit) => boolean;\r\n}\r\n\r\n/**\r\n * Responsible for performing the collision broadphase (locating potential collisions) and\r\n * the narrowphase (actual collision contacts)\r\n */\r\nexport class DynamicTreeCollisionProcessor implements CollisionProcessor {\r\n private _dynamicCollisionTree: DynamicTree;\r\n private _pairs = new Set();\r\n\r\n private _collisionPairCache: Pair[] = [];\r\n private _colliders: Collider[] = [];\r\n\r\n constructor(private _config: DeepRequired) {\r\n this._dynamicCollisionTree = new DynamicTree(_config.dynamicTree);\r\n }\r\n\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n public rayCast(ray: Ray, options?: RayCastOptions): RayCastHit[] {\r\n const results: RayCastHit[] = [];\r\n const maxDistance = options?.maxDistance ?? Infinity;\r\n const collisionGroup = options?.collisionGroup;\r\n const collisionMask = !collisionGroup ? options?.collisionMask ?? CollisionGroup.All.category : collisionGroup.category;\r\n const searchAllColliders = options?.searchAllColliders ?? false;\r\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider) => {\r\n const owner = collider.owner;\r\n const maybeBody = owner.get(BodyComponent);\r\n\r\n if (options?.ignoreCollisionGroupAll && maybeBody.group === CollisionGroup.All) {\r\n return false;\r\n }\r\n\r\n const canCollide = (collisionMask & maybeBody.group.category) !== 0;\r\n\r\n // Early exit if not the right group\r\n if (maybeBody?.group && !canCollide) {\r\n return false;\r\n }\r\n\r\n const hit = collider.rayCast(ray, maxDistance);\r\n\r\n if (hit) {\r\n if (options?.filter) {\r\n if (options.filter(hit)) {\r\n results.push(hit);\r\n if (!searchAllColliders) {\r\n // returning true exits the search\r\n return true;\r\n }\r\n }\r\n } else {\r\n results.push(hit);\r\n if (!searchAllColliders) {\r\n // returning true exits the search\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n return results;\r\n }\r\n\r\n /**\r\n * Tracks a physics body for collisions\r\n */\r\n public track(target: Collider): void {\r\n if (!target) {\r\n Logger.getInstance().warn('Cannot track null collider');\r\n return;\r\n }\r\n if (target instanceof CompositeCollider) {\r\n const colliders = target.getColliders();\r\n for (const c of colliders) {\r\n c.owner = target.owner;\r\n this._colliders.push(c);\r\n this._dynamicCollisionTree.trackCollider(c);\r\n }\r\n } else {\r\n this._colliders.push(target);\r\n this._dynamicCollisionTree.trackCollider(target);\r\n }\r\n }\r\n\r\n /**\r\n * Untracks a physics body\r\n */\r\n public untrack(target: Collider): void {\r\n if (!target) {\r\n Logger.getInstance().warn('Cannot untrack a null collider');\r\n return;\r\n }\r\n\r\n if (target instanceof CompositeCollider) {\r\n const colliders = target.getColliders();\r\n for (const c of colliders) {\r\n const index = this._colliders.indexOf(c);\r\n if (index !== -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this._dynamicCollisionTree.untrackCollider(c);\r\n }\r\n } else {\r\n const index = this._colliders.indexOf(target);\r\n if (index !== -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this._dynamicCollisionTree.untrackCollider(target);\r\n }\r\n }\r\n\r\n private _pairExists(colliderA: Collider, colliderB: Collider) {\r\n // if the collision pair has been calculated already short circuit\r\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n return this._pairs.has(hash);\r\n }\r\n\r\n /**\r\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\r\n */\r\n public broadphase(targets: Collider[], delta: number, stats?: FrameStats): Pair[] {\r\n const seconds = delta / 1000;\r\n\r\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\r\n const potentialColliders = targets.filter((other) => {\r\n const body = other.owner?.get(BodyComponent);\r\n return other.owner?.active && body.collisionType !== CollisionType.PreventCollision;\r\n });\r\n\r\n // clear old list of collision pairs\r\n this._collisionPairCache = [];\r\n this._pairs.clear();\r\n\r\n // check for normal collision pairs\r\n let collider: Collider;\r\n for (let j = 0, l = potentialColliders.length; j < l; j++) {\r\n collider = potentialColliders[j];\r\n // Query the collision tree for potential colliders\r\n this._dynamicCollisionTree.query(collider, (other: Collider) => {\r\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\r\n const pair = new Pair(collider, other);\r\n this._pairs.add(pair.id);\r\n this._collisionPairCache.push(pair);\r\n }\r\n // Always return false, to query whole tree. Returning true in the query method stops searching\r\n return false;\r\n });\r\n }\r\n if (stats) {\r\n stats.physics.pairs = this._collisionPairCache.length;\r\n }\r\n\r\n // Check dynamic tree for fast moving objects\r\n // Fast moving objects are those moving at least there smallest bound per frame\r\n if (this._config.continuous.checkForFastBodies) {\r\n for (const collider of potentialColliders) {\r\n const body = collider.owner.get(BodyComponent);\r\n // Skip non-active objects. Does not make sense on other collision types\r\n if (body.collisionType !== CollisionType.Active) {\r\n continue;\r\n }\r\n\r\n // Maximum travel distance next frame\r\n const updateDistance =\r\n body.vel.size * seconds + // velocity term\r\n body.acc.size * 0.5 * seconds * seconds; // acc term\r\n\r\n // Find the minimum dimension\r\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\r\n if (this._config.continuous.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\r\n if (stats) {\r\n stats.physics.fastBodies++;\r\n }\r\n\r\n // start with the oldPos because the integration for actors has already happened\r\n // objects resting on a surface may be slightly penetrating in the current position\r\n const updateVec = body.globalPos.sub(body.oldPos);\r\n const centerPoint = collider.center;\r\n const furthestPoint = collider.getFurthestPoint(body.vel);\r\n const origin: Vector = furthestPoint.sub(updateVec);\r\n\r\n const ray: Ray = new Ray(origin, body.vel);\r\n\r\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\r\n ray.pos = ray.pos.add(ray.dir.scale(-2 * this._config.continuous.surfaceEpsilon));\r\n let minCollider: Collider;\r\n let minTranslate: Vector = new Vector(Infinity, Infinity);\r\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + this._config.continuous.surfaceEpsilon * 2, (other: Collider) => {\r\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\r\n const hit = other.rayCast(ray, updateDistance + this._config.continuous.surfaceEpsilon * 10);\r\n if (hit) {\r\n const translate = hit.point.sub(origin);\r\n if (translate.size < minTranslate.size) {\r\n minTranslate = translate;\r\n minCollider = other;\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n\r\n if (minCollider && Vector.isValid(minTranslate)) {\r\n const pair = new Pair(collider, minCollider);\r\n if (!this._pairs.has(pair.id)) {\r\n this._pairs.add(pair.id);\r\n this._collisionPairCache.push(pair);\r\n }\r\n // move the fast moving object to the other body\r\n // need to push into the surface by ex.Physics.surfaceEpsilon\r\n const shift = centerPoint.sub(furthestPoint);\r\n body.globalPos = origin\r\n .add(shift)\r\n .add(minTranslate)\r\n .add(ray.dir.scale(10 * this._config.continuous.surfaceEpsilon)); // needed to push the shape slightly into contact\r\n collider.update(body.transform.get());\r\n\r\n if (stats) {\r\n stats.physics.fastBodyCollisions++;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n // return cache\r\n return this._collisionPairCache;\r\n }\r\n\r\n /**\r\n * Applies narrow phase on collision pairs to find actual area intersections\r\n * Adds actual colliding pairs to stats' Frame data\r\n */\r\n public narrowphase(pairs: Pair[], stats?: FrameStats): CollisionContact[] {\r\n let contacts: CollisionContact[] = [];\r\n for (let i = 0; i < pairs.length; i++) {\r\n const newContacts = pairs[i].collide();\r\n contacts = contacts.concat(newContacts);\r\n if (stats && newContacts.length > 0) {\r\n for (const c of newContacts) {\r\n stats.physics.contacts.set(c.id, c);\r\n }\r\n }\r\n }\r\n if (stats) {\r\n stats.physics.collisions += contacts.length;\r\n }\r\n return contacts;\r\n }\r\n\r\n /**\r\n * Update the dynamic tree positions\r\n */\r\n public update(targets: Collider[]): number {\r\n let updated = 0;\r\n const len = targets.length;\r\n\r\n for (let i = 0; i < len; i++) {\r\n if (this._dynamicCollisionTree.updateCollider(targets[i])) {\r\n updated++;\r\n }\r\n }\r\n return updated;\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext) {\r\n this._dynamicCollisionTree.debug(ex);\r\n }\r\n}\r\n","import { Color } from '../../Color';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Clonable } from '../../Interfaces/Clonable';\r\nimport { Entity } from '../../EntityComponentSystem';\r\nimport { createId, Id } from '../../Id';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { EventEmitter } from '../../EventEmitter';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\nimport { CompositeCollider } from './CompositeCollider';\r\n\r\n/**\r\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\r\n * for the purposes of colliding 2 objects in excalibur.\r\n */\r\nexport abstract class Collider implements Clonable {\r\n private static _ID = 0;\r\n public readonly id: Id<'collider'> = createId('collider', Collider._ID++);\r\n /**\r\n * Composite collider if any this collider is attached to\r\n *\r\n * **WARNING** do not tamper with this property\r\n */\r\n public composite: CompositeCollider | null = null;\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Returns a boolean indicating whether this body collided with\r\n * or was in stationary contact with\r\n * the body of the other [[Collider]]\r\n */\r\n public touching(other: Collider): boolean {\r\n const contact = this.collide(other);\r\n\r\n if (contact) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n public owner: Entity;\r\n\r\n /**\r\n * Pixel offset of the collision collider relative to the collider, by default (0, 0) meaning the collider is positioned\r\n * on top of the collider.\r\n */\r\n offset: Vector = Vector.Zero;\r\n\r\n /**\r\n * Position of the collision collider in world coordinates\r\n */\r\n abstract get worldPos(): Vector;\r\n\r\n /**\r\n * The center point of the collision collider, for example if the collider is a circle it would be the center.\r\n */\r\n abstract get center(): Vector;\r\n\r\n /**\r\n * Return the axis-aligned bounding box of the collision collider in world coordinates\r\n */\r\n abstract get bounds(): BoundingBox;\r\n\r\n /**\r\n * Return the axis-aligned bounding box of the collision collider in local coordinates\r\n */\r\n abstract get localBounds(): BoundingBox;\r\n\r\n /**\r\n * Return the axes of this particular collider\r\n */\r\n abstract get axes(): Vector[];\r\n /**\r\n * Find the furthest point on the convex hull of this particular collider in a certain direction.\r\n */\r\n abstract getFurthestPoint(direction: Vector): Vector;\r\n\r\n abstract getInertia(mass: number): number;\r\n\r\n // All new CollisionShape need to do the following\r\n // Create a new collision function in the CollisionJumpTable against all the primitives\r\n // Currently there are 3 primitive collision collider 3! = 6 jump functions\r\n abstract collide(collider: Collider): CollisionContact[];\r\n\r\n /**\r\n * Returns the closest line between the surfaces this collider and another\r\n * @param collider\r\n */\r\n abstract getClosestLineBetween(collider: Collider): LineSegment;\r\n\r\n /**\r\n * Return wether the collider contains a point inclusive to it's border\r\n */\r\n abstract contains(point: Vector): boolean;\r\n\r\n /**\r\n * Return the point on the border of the collision collider that intersects with a ray (if any).\r\n */\r\n abstract rayCast(ray: Ray, max?: number): RayCastHit | null;\r\n\r\n /**\r\n * Create a projection of this collider along an axis. Think of this as casting a \"shadow\" along an axis\r\n */\r\n abstract project(axis: Vector): Projection;\r\n\r\n /**\r\n * Updates collider world space geometry\r\n */\r\n abstract update(transform: Transform): void;\r\n\r\n\r\n abstract debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }): void;\r\n\r\n abstract clone(): Collider;\r\n}\r\n","/**\r\n * Possible collision resolution strategies\r\n *\r\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\r\n * like platformers or top down games.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n */\r\nexport enum SolverStrategy {\r\n Arcade = 'arcade',\r\n Realistic = 'realistic'\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { SolverStrategy } from './SolverStrategy';\r\n\r\n/**\r\n * Possible broadphase collision pair identification strategies\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n * @deprecated Unused in Excalibur, will be removed in v0.30\r\n */\r\nexport enum BroadphaseStrategy {\r\n DynamicAABBTree\r\n}\r\n\r\n/**\r\n * Possible numerical integrators for position and velocity\r\n * @deprecated Unused in Excalibur, will be removed in v0.30\r\n */\r\nexport enum Integrator {\r\n Euler\r\n}\r\n\r\n/**\r\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n/* istanbul ignore next */\r\nexport class Physics {\r\n /**\r\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\r\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\r\n *\r\n * This is a great way to globally simulate effects like gravity.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static acc = new Vector(0, 0);\r\n /**\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static get gravity() {\r\n return Physics.acc;\r\n }\r\n public static set gravity(v: Vector) {\r\n Physics.acc = v;\r\n }\r\n\r\n /**\r\n * Globally switches all Excalibur physics behavior on or off.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static enabled = true;\r\n\r\n /**\r\n * Gets or sets the broadphase pair identification strategy.\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static broadphaseStrategy: BroadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\r\n\r\n /**\r\n * Gets or sets the global collision resolution strategy (narrowphase).\r\n *\r\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static collisionResolutionStrategy: SolverStrategy = SolverStrategy.Arcade;\r\n /**\r\n * The default mass to use if none is specified\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static defaultMass: number = 10;\r\n /**\r\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static integrator: Integrator = Integrator.Euler;\r\n\r\n /**\r\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static useArcadePhysics(): void {\r\n Physics.collisionResolutionStrategy = SolverStrategy.Arcade;\r\n }\r\n\r\n /**\r\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\r\n * simulated physical interactions.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static useRealisticPhysics(): void {\r\n Physics.collisionResolutionStrategy = SolverStrategy.Realistic;\r\n }\r\n\r\n /**\r\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static dynamicTreeVelocityMultiplier = 2;\r\n\r\n /**\r\n * Pad RigidBody BoundingBox by a constant amount\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static boundsPadding = 5;\r\n\r\n /**\r\n * Number of position iterations (overlap) to run in the solver\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static positionIterations = 3;\r\n\r\n /**\r\n * Number of velocity iteration (response) to run in the solver\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static velocityIterations = 8;\r\n\r\n /**\r\n * Amount of overlap to tolerate in pixels\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static slop = 1;\r\n\r\n /**\r\n * Amount of positional overlap correction to apply each position iteration of the solver\r\n * O - meaning no correction, 1 - meaning correct all overlap\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static steeringFactor = 0.2;\r\n\r\n /**\r\n * Warm start set to true re-uses impulses from previous frames back in the solver\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static warmStart = true;\r\n\r\n /**\r\n * By default bodies do not sleep\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static bodiesCanSleepByDefault = false;\r\n\r\n /**\r\n * Surface epsilon is used to help deal with surface penetration\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static surfaceEpsilon = 0.1;\r\n\r\n /**\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static sleepEpsilon = 0.07;\r\n\r\n /**\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static wakeThreshold = Physics.sleepEpsilon * 3;\r\n\r\n /**\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static sleepBias = 0.9;\r\n\r\n /**\r\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\r\n * bodies from tunneling through one another.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static checkForFastBodies = true;\r\n\r\n /**\r\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\r\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\r\n * Excalibur will always perform the fast body raycast regardless of speed.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static disableMinimumSpeedForFastBody = false;\r\n}\r\n","\r\n/**\r\n * Tells the Arcade collision solver to prefer certain contacts over others\r\n */\r\nexport enum ContactSolveBias {\r\n None = 'none',\r\n VerticalFirst = 'vertical-first',\r\n HorizontalFirst = 'horizontal-first'\r\n}\r\n\r\n/**\r\n * Contact bias values\r\n */\r\nexport interface ContactBias {\r\n vertical: number;\r\n horizontal: number;\r\n}\r\n\r\n/**\r\n * Vertical First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\r\n */\r\nexport const VerticalFirst: ContactBias = {\r\n 'vertical': 1,\r\n 'horizontal': 2\r\n} as const;\r\n\r\n/**\r\n * Horizontal First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\r\n */\r\nexport const HorizontalFirst: ContactBias = {\r\n 'horizontal': 1,\r\n 'vertical': 2\r\n} as const;\r\n\r\n/**\r\n * None value, [[ArcadeSolver]] sorts contacts using distance by default\r\n */\r\nexport const None: ContactBias = {\r\n 'horizontal': 0,\r\n 'vertical': 0\r\n} as const;","import { Vector, vec } from '../Math/vector';\r\nimport { DeepRequired } from '../Util/Required';\r\nimport { SolverStrategy } from './SolverStrategy';\r\nimport { Physics } from './Physics';\r\nimport { ContactSolveBias } from './Solver/ContactBias';\r\n\r\n\r\nexport interface PhysicsConfig {\r\n /**\r\n * Excalibur physics simulation is enabled\r\n */\r\n enabled?: boolean;\r\n /**\r\n * Configure gravity that applies to all [[CollisionType.Active]] bodies.\r\n *\r\n * This is acceleration in pixels/sec^2\r\n *\r\n * Default vec(0, 0)\r\n *\r\n * [[BodyComponent.useGravity]] to opt out\r\n */\r\n gravity?: Vector;\r\n /**\r\n * Configure the type of physics simulation you would like\r\n *\r\n * * [[SolverStrategy.Arcade]] is suitable for games where you might be doing platforming or top down movement.\r\n * * [[SolverStrategy.Realistic]] is where you need objects to bounce off each other and respond like real world objects.\r\n *\r\n * Default is Arcade\r\n */\r\n solver?: SolverStrategy;\r\n\r\n /**\r\n * Configure colliders\r\n */\r\n colliders?: {\r\n /**\r\n * Treat composite collider's member colliders as either separate colliders for the purposes of onCollisionStart/onCollision\r\n * or as a single collider together.\r\n *\r\n * This property can be overridden on individual [[CompositeColliders]].\r\n *\r\n * For composites without gaps or small groups of colliders, you probably want 'together'\r\n *\r\n * For composites with deliberate gaps, like a platforming level layout, you probably want 'separate'\r\n *\r\n * Default is 'together' if unset\r\n */\r\n compositeStrategy?: 'separate' | 'together'\r\n }\r\n\r\n /**\r\n * Configure excalibur continuous collision (WIP)\r\n */\r\n continuous?: {\r\n\r\n /**\r\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\r\n * bodies from tunneling through one another.\r\n *\r\n * Default true\r\n */\r\n checkForFastBodies?: boolean;\r\n\r\n /**\r\n * Disable minimum fast moving body raycast, by default if checkForFastBodies = true Excalibur will only check if the\r\n * body is moving at least half of its minimum dimension in an update. If disableMinimumSpeedForFastBody is set to true,\r\n * Excalibur will always perform the fast body raycast regardless of speed.\r\n *\r\n * Default false\r\n */\r\n disableMinimumSpeedForFastBody?: boolean;\r\n\r\n /**\r\n * Surface epsilon is used to help deal with predicting collisions by applying a slop\r\n *\r\n * Default 0.1\r\n */\r\n surfaceEpsilon?: number;\r\n }\r\n\r\n /**\r\n * Configure body defaults\r\n */\r\n bodies?: {\r\n /**\r\n * Configure default mass that bodies have\r\n *\r\n * Default 10 mass units\r\n */\r\n defaultMass?: number;\r\n\r\n /**\r\n * Sleep epsilon\r\n *\r\n * Default 0.07\r\n */\r\n sleepEpsilon?: number;\r\n\r\n /**\r\n * Wake Threshold, the amount of \"motion\" need to wake a body from sleep\r\n *\r\n * Default 0.07 * 3;\r\n */\r\n wakeThreshold?: number;\r\n\r\n /**\r\n * Sleep bias\r\n *\r\n * Default 0.9\r\n */\r\n sleepBias?: number;\r\n\r\n /**\r\n * By default bodies do not sleep, this can be turned on to improve perf if you have a lot of bodies.\r\n *\r\n * Default false\r\n */\r\n canSleepByDefault?: boolean;\r\n }\r\n\r\n /**\r\n * Configure the dynamic tree spatial data structure for locating pairs and raycasts\r\n */\r\n dynamicTree?: {\r\n /**\r\n * Pad collider BoundingBox by a constant amount for purposes of potential pairs\r\n *\r\n * Default 5 pixels\r\n */\r\n boundsPadding?: number;\r\n\r\n /**\r\n * Factor to add to the collider BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\r\n *\r\n * Default 2\r\n */\r\n velocityMultiplier?: number;\r\n }\r\n\r\n /**\r\n * Configure the [[ArcadeSolver]]\r\n */\r\n arcade?: {\r\n /**\r\n * Hints the [[ArcadeSolver]] to preferentially solve certain contact directions first.\r\n *\r\n * Options:\r\n * * Solve [[ContactSolveBias.VerticalFirst]] which will do vertical contact resolution first (useful for platformers\r\n * with up/down gravity)\r\n * * Solve [[ContactSolveBias.HorizontalFirst]] which will do horizontal contact resolution first (useful for games with\r\n * left/right forces)\r\n * * By default [[ContactSolveBias.None]] which sorts by distance\r\n */\r\n contactSolveBias?: ContactSolveBias;\r\n }\r\n\r\n /**\r\n * Configure the [[RealisticSolver]]\r\n */\r\n realistic?: {\r\n /**\r\n * Number of position iterations (overlap) to run in the solver\r\n *\r\n * Default 3 iterations\r\n */\r\n positionIterations?: number;\r\n\r\n /**\r\n * Number of velocity iteration (response) to run in the solver\r\n *\r\n * Default 8 iterations\r\n */\r\n velocityIterations?: number;\r\n\r\n /**\r\n * Amount of overlap to tolerate in pixels\r\n *\r\n * Default 1 pixel\r\n */\r\n slop?: number;\r\n\r\n /**\r\n * Amount of positional overlap correction to apply each position iteration of the solver\r\n * 0 - meaning no correction, 1 - meaning correct all overlap. Generally values 0 < .5 look nice.\r\n *\r\n * Default 0.2\r\n */\r\n steeringFactor?: number;\r\n\r\n /**\r\n * Warm start set to true re-uses impulses from previous frames back in the solver. Re-using impulses helps\r\n * the solver converge quicker\r\n *\r\n * Default true\r\n */\r\n warmStart?: boolean;\r\n }\r\n}\r\n\r\nexport const DefaultPhysicsConfig: DeepRequired = {\r\n enabled: true,\r\n gravity: vec(0, 0),\r\n solver: SolverStrategy.Arcade,\r\n colliders: {\r\n compositeStrategy: 'together'\r\n },\r\n continuous: {\r\n checkForFastBodies: true,\r\n disableMinimumSpeedForFastBody: false,\r\n surfaceEpsilon: 0.1\r\n },\r\n bodies: {\r\n canSleepByDefault: false,\r\n sleepEpsilon: 0.07,\r\n wakeThreshold: 0.07 * 3,\r\n sleepBias: 0.9,\r\n defaultMass: 10\r\n },\r\n dynamicTree: {\r\n boundsPadding: 5,\r\n velocityMultiplier: 2\r\n },\r\n arcade: {\r\n contactSolveBias: ContactSolveBias.None\r\n },\r\n realistic: {\r\n positionIterations: 3,\r\n velocityIterations: 8,\r\n slop: 1,\r\n steeringFactor: 0.2,\r\n warmStart: true\r\n }\r\n};\r\n\r\n/**\r\n * @deprecated will be removed in v0.30\r\n */\r\nexport function DeprecatedStaticToConfig(): DeepRequired {\r\n return {\r\n enabled: Physics.enabled,\r\n gravity: Physics.gravity,\r\n solver: Physics.collisionResolutionStrategy,\r\n continuous: {\r\n checkForFastBodies: Physics.checkForFastBodies,\r\n disableMinimumSpeedForFastBody: Physics.disableMinimumSpeedForFastBody,\r\n surfaceEpsilon: Physics.surfaceEpsilon\r\n },\r\n colliders: {\r\n compositeStrategy: 'together'\r\n },\r\n bodies: {\r\n canSleepByDefault: Physics.bodiesCanSleepByDefault,\r\n sleepEpsilon: Physics.sleepEpsilon,\r\n wakeThreshold: Physics.wakeThreshold,\r\n sleepBias: Physics.sleepBias,\r\n defaultMass: Physics.defaultMass\r\n },\r\n dynamicTree: {\r\n boundsPadding: Physics.boundsPadding,\r\n velocityMultiplier: Physics.dynamicTreeVelocityMultiplier\r\n },\r\n arcade: {\r\n contactSolveBias: ContactSolveBias.None\r\n },\r\n realistic: {\r\n positionIterations: Physics.positionIterations,\r\n velocityIterations: Physics.velocityIterations,\r\n slop: Physics.slop,\r\n steeringFactor: Physics.steeringFactor,\r\n warmStart: Physics.warmStart\r\n }\r\n };\r\n}","import { Util } from '../..';\r\nimport { Pair } from '../Detection/Pair';\r\nimport { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Projection } from '../../Math/projection';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Vector } from '../../Math/vector';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { DynamicTree } from '../Detection/DynamicTree';\r\nimport { DynamicTreeCollisionProcessor } from '../Detection/DynamicTreeCollisionProcessor';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\nimport { Collider } from './Collider';\r\nimport { Transform } from '../../Math/transform';\r\nimport { DefaultPhysicsConfig } from '../PhysicsConfig';\r\n\r\nexport class CompositeCollider extends Collider {\r\n private _transform: Transform;\r\n private _collisionProcessor = new DynamicTreeCollisionProcessor(DefaultPhysicsConfig);\r\n private _dynamicAABBTree = new DynamicTree(DefaultPhysicsConfig.dynamicTree);\r\n private _colliders: Collider[] = [];\r\n\r\n private _compositeStrategy?: 'separate' | 'together';\r\n /**\r\n * Treat composite collider's member colliders as either separate colliders for the purposes of onCollisionStart/onCollision\r\n * or as a single collider together.\r\n *\r\n * This property can be overridden on individual [[CompositeColliders]].\r\n *\r\n * For composites without gaps or small groups of colliders, you probably want 'together'\r\n *\r\n * For composites with deliberate gaps, like a platforming level layout, you probably want 'separate'\r\n *\r\n * Default is 'together' if unset\r\n */\r\n public set compositeStrategy(value: 'separate' | 'together') {\r\n this._compositeStrategy = value;\r\n }\r\n public get compositeStrategy() {\r\n return this._compositeStrategy;\r\n }\r\n\r\n constructor(colliders: Collider[]) {\r\n super();\r\n for (const c of colliders) {\r\n this.addCollider(c);\r\n }\r\n }\r\n\r\n clearColliders() {\r\n this._colliders = [];\r\n }\r\n\r\n addCollider(collider: Collider) {\r\n let colliders: Collider[];\r\n if (collider instanceof CompositeCollider) {\r\n colliders = collider.getColliders();\r\n colliders.forEach(c => c.offset.addEqual(collider.offset));\r\n } else {\r\n colliders = [collider];\r\n }\r\n // Flatten composites\r\n for (const c of colliders) {\r\n c.events.pipe(this.events);\r\n c.composite = this;\r\n this._colliders.push(c);\r\n this._collisionProcessor.track(c);\r\n this._dynamicAABBTree.trackCollider(c);\r\n }\r\n }\r\n\r\n removeCollider(collider: Collider) {\r\n collider.events.pipe(this.events);\r\n collider.composite = null;\r\n Util.removeItemFromArray(collider, this._colliders);\r\n this._collisionProcessor.untrack(collider);\r\n this._dynamicAABBTree.untrackCollider(collider);\r\n }\r\n\r\n getColliders(): Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n get worldPos(): Vector {\r\n return (this._transform?.pos ?? Vector.Zero).add(this.offset);\r\n }\r\n\r\n get center(): Vector {\r\n return (this._transform?.pos ?? Vector.Zero).add(this.offset);\r\n }\r\n\r\n get bounds(): BoundingBox {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n const results = colliders.reduce(\r\n (acc, collider) => acc.combine(collider.bounds),\r\n colliders[0]?.bounds ?? new BoundingBox().translate(this.worldPos)\r\n );\r\n\r\n return results.translate(this.offset);\r\n }\r\n\r\n get localBounds(): BoundingBox {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n const results = colliders.reduce((acc, collider) => acc.combine(collider.localBounds), colliders[0]?.localBounds ?? new BoundingBox());\r\n\r\n return results;\r\n }\r\n\r\n get axes(): Vector[] {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n let axes: Vector[] = [];\r\n for (const collider of colliders) {\r\n axes = axes.concat(collider.axes);\r\n }\r\n return axes;\r\n }\r\n\r\n getFurthestPoint(direction: Vector): Vector {\r\n const colliders = this.getColliders();\r\n const furthestPoints: Vector[] = [];\r\n for (const collider of colliders) {\r\n furthestPoints.push(collider.getFurthestPoint(direction));\r\n }\r\n // Pick best point from all colliders\r\n let bestPoint = furthestPoints[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (const point of furthestPoints) {\r\n const distance = point.dot(direction);\r\n if (distance > maxDistance) {\r\n bestPoint = point;\r\n maxDistance = distance;\r\n }\r\n }\r\n return bestPoint;\r\n }\r\n\r\n getInertia(mass: number): number {\r\n const colliders = this.getColliders();\r\n let totalInertia = 0;\r\n for (const collider of colliders) {\r\n totalInertia += collider.getInertia(mass);\r\n }\r\n return totalInertia;\r\n }\r\n\r\n collide(other: Collider): CollisionContact[] {\r\n let otherColliders = [other];\r\n if (other instanceof CompositeCollider) {\r\n otherColliders = other.getColliders();\r\n }\r\n\r\n const pairs: Pair[] = [];\r\n for (const c of otherColliders) {\r\n this._dynamicAABBTree.query(c, (potentialCollider: Collider) => {\r\n pairs.push(new Pair(c, potentialCollider));\r\n return false;\r\n });\r\n }\r\n\r\n let contacts: CollisionContact[] = [];\r\n for (const p of pairs) {\r\n contacts = contacts.concat(p.collide());\r\n }\r\n return contacts;\r\n }\r\n\r\n getClosestLineBetween(other: Collider): LineSegment {\r\n const colliders = this.getColliders();\r\n const lines: LineSegment[] = [];\r\n if (other instanceof CompositeCollider) {\r\n const otherColliders = other.getColliders();\r\n for (const colliderA of colliders) {\r\n for (const colliderB of otherColliders) {\r\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\r\n if (maybeLine) {\r\n lines.push(maybeLine);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const collider of colliders) {\r\n const maybeLine = other.getClosestLineBetween(collider);\r\n if (maybeLine) {\r\n lines.push(maybeLine);\r\n }\r\n }\r\n }\r\n\r\n if (lines.length) {\r\n let minLength = lines[0].getLength();\r\n let minLine = lines[0];\r\n for (const line of lines) {\r\n const length = line.getLength();\r\n if (length < minLength) {\r\n minLength = length;\r\n minLine = line;\r\n }\r\n }\r\n return minLine;\r\n }\r\n return null;\r\n }\r\n contains(point: Vector): boolean {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n if (collider.contains(point)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n rayCast(ray: Ray, max?: number): RayCastHit | null {\r\n const colliders = this.getColliders();\r\n const hits: RayCastHit[] = [];\r\n for (const collider of colliders) {\r\n const hit = collider.rayCast(ray, max);\r\n if (hit) {\r\n hits.push(hit);\r\n }\r\n }\r\n if (hits.length) {\r\n let minHit = hits[0];\r\n let minDistance = minHit.point.dot(ray.dir);\r\n for (const hit of hits) {\r\n const distance = ray.dir.dot(hit.point);\r\n if (distance < minDistance) {\r\n minHit = hit;\r\n minDistance = distance;\r\n }\r\n }\r\n return minHit;\r\n }\r\n return null;\r\n }\r\n project(axis: Vector): Projection {\r\n const colliders = this.getColliders();\r\n const projections: Projection[] = [];\r\n for (const collider of colliders) {\r\n const proj = collider.project(axis);\r\n if (proj) {\r\n projections.push(proj);\r\n }\r\n }\r\n // Merge all proj's on the same axis\r\n if (projections.length) {\r\n const newProjection = new Projection(projections[0].min, projections[0].max);\r\n for (const proj of projections) {\r\n newProjection.min = Math.min(proj.min, newProjection.min);\r\n newProjection.max = Math.max(proj.max, newProjection.max);\r\n }\r\n return newProjection;\r\n }\r\n return null;\r\n }\r\n\r\n update(transform: Transform): void {\r\n if (transform) {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n collider.owner = this.owner;\r\n collider.update(transform);\r\n }\r\n }\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }) {\r\n const colliders = this.getColliders();\r\n ex.save();\r\n ex.translate(this.offset.x, this.offset.y);\r\n for (const collider of colliders) {\r\n collider.debug(ex, color, options);\r\n }\r\n ex.restore();\r\n }\r\n\r\n clone(): Collider {\r\n const result = new CompositeCollider(this._colliders.map((c) => c.clone()));\r\n result.offset = this.offset.clone();\r\n return result;\r\n }\r\n}\r\n","import { Vector } from './vector';\r\n\r\n/**\r\n * A 2D line segment\r\n */\r\n\r\nexport class LineSegment {\r\n\r\n /**\r\n * @param begin The starting point of the line segment\r\n * @param end The ending point of the line segment\r\n */\r\n constructor(public readonly begin: Vector, public readonly end: Vector) {}\r\n\r\n /**\r\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\r\n */\r\n public get slope() {\r\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\r\n }\r\n\r\n /**\r\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\r\n */\r\n public get intercept() {\r\n return this.begin.y - this.slope * this.begin.x;\r\n }\r\n\r\n private _normal: Vector;\r\n /**\r\n * Gets the normal of the line\r\n */\r\n public normal(): Vector {\r\n if (this._normal) {\r\n return this._normal;\r\n }\r\n return this._normal = this.end.sub(this.begin).normal();\r\n }\r\n\r\n private _dir: Vector;\r\n public dir(): Vector {\r\n if (this._dir) {\r\n return this._dir;\r\n }\r\n return this._dir = this.end.sub(this.begin);\r\n }\r\n\r\n public getPoints(): Vector[] {\r\n return [this.begin, this.end];\r\n }\r\n\r\n private _slope: Vector;\r\n /**\r\n * Returns the slope of the line in the form of a vector of length 1\r\n */\r\n public getSlope(): Vector {\r\n if (this._slope) {\r\n return this._slope;\r\n }\r\n const begin = this.begin;\r\n const end = this.end;\r\n const distance = begin.distance(end);\r\n return this._slope = end.sub(begin).scale(1 / distance);\r\n }\r\n\r\n /**\r\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\r\n */\r\n public getEdge(): Vector {\r\n const begin = this.begin;\r\n const end = this.end;\r\n return end.sub(begin);\r\n }\r\n\r\n private _length: number;\r\n /**\r\n * Returns the length of the line segment in pixels\r\n */\r\n public getLength(): number {\r\n if (this._length) {\r\n return this._length;\r\n }\r\n const begin = this.begin;\r\n const end = this.end;\r\n const distance = begin.distance(end);\r\n return this._length = distance;\r\n }\r\n\r\n /**\r\n * Returns the midpoint of the edge\r\n */\r\n public get midpoint(): Vector {\r\n return this.begin.add(this.end).scale(0.5);\r\n }\r\n\r\n /**\r\n * Flips the direction of the line segment\r\n */\r\n public flip(): LineSegment {\r\n return new LineSegment(this.end, this.begin);\r\n }\r\n\r\n /**\r\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\r\n * @param point\r\n */\r\n public below(point: Vector): boolean {\r\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\r\n return above2 >= 0;\r\n }\r\n\r\n /**\r\n * Returns the clip point\r\n * @param sideVector Vector that traces the line\r\n * @param length Length to clip along side\r\n */\r\n public clip(sideVector: Vector, length: number): LineSegment {\r\n let dir = sideVector;\r\n dir = dir.normalize();\r\n\r\n const near = dir.dot(this.begin) - length;\r\n const far = dir.dot(this.end) - length;\r\n\r\n const results = [];\r\n if (near <= 0) {\r\n results.push(this.begin);\r\n }\r\n if (far <= 0) {\r\n results.push(this.end);\r\n }\r\n\r\n if (near * far < 0) {\r\n const clipTime = near / (near - far);\r\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\r\n }\r\n if (results.length !== 2) {\r\n return null;\r\n }\r\n\r\n return new LineSegment(results[0], results[1]);\r\n }\r\n\r\n /**\r\n * Find the perpendicular distance from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * @param point\r\n */\r\n public distanceToPoint(point: Vector, signed: boolean = false) {\r\n const x0 = point.x;\r\n const y0 = point.y;\r\n\r\n const l = this.getLength();\r\n\r\n const dy = this.end.y - this.begin.y;\r\n const dx = this.end.x - this.begin.x;\r\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\r\n return signed ? distance : Math.abs(distance);\r\n }\r\n\r\n /**\r\n * Find the perpendicular line from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * (a - p) - ((a - p) * n)n\r\n * a is a point on the line\r\n * p is the arbitrary point above the line\r\n * n is a unit vector in direction of the line\r\n * @param point\r\n */\r\n public findVectorToPoint(point: Vector): Vector {\r\n const aMinusP = this.begin.sub(point);\r\n const n = this.getSlope();\r\n\r\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\r\n }\r\n\r\n /**\r\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\r\n * a new point with the calculated Y value and vice-versa.\r\n * @param x The known X value of the target point\r\n * @param y The known Y value of the target point\r\n * @returns A new point with the other calculated axis value\r\n */\r\n public findPoint(x: number = null, y: number = null): Vector {\r\n const m = this.slope;\r\n const b = this.intercept;\r\n\r\n if (x !== null) {\r\n return new Vector(x, m * x + b);\r\n } else if (y !== null) {\r\n return new Vector((y - b) / m, y);\r\n } else {\r\n throw new Error('You must provide an X or a Y value');\r\n }\r\n }\r\n\r\n /**\r\n * Whether or not the given point lies on this line. This method is precise by default\r\n * meaning the point must lie exactly on the line. Adjust threshold to\r\n * loosen the strictness of the check for floating-point calculations.\r\n */\r\n public hasPoint(x: number, y: number, threshold?: number): boolean;\r\n\r\n /**\r\n * Whether or not the given point lies on this line. This method is precise by default\r\n * meaning the point must lie exactly on the line. Adjust threshold to\r\n * loosen the strictness of the check for floating-point calculations.\r\n */\r\n public hasPoint(v: Vector, threshold?: number): boolean;\r\n\r\n /**\r\n * @see http://stackoverflow.com/a/11908158/109458\r\n */\r\n public hasPoint(): boolean {\r\n let currPoint: Vector;\r\n let threshold = 0;\r\n\r\n if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') {\r\n currPoint = new Vector(arguments[0], arguments[1]);\r\n threshold = arguments[2] || 0;\r\n } else if (arguments[0] instanceof Vector) {\r\n currPoint = arguments[0];\r\n threshold = arguments[1] || 0;\r\n } else {\r\n throw 'Could not determine the arguments for Vector.hasPoint';\r\n }\r\n\r\n const dxc = currPoint.x - this.begin.x;\r\n const dyc = currPoint.y - this.begin.y;\r\n\r\n const dx1 = this.end.x - this.begin.x;\r\n const dy1 = this.end.y - this.begin.y;\r\n\r\n const cross = dxc * dy1 - dyc * dx1;\r\n\r\n // check whether point lines on the line\r\n if (Math.abs(cross) > threshold) {\r\n return false;\r\n }\r\n\r\n // check whether point lies in-between start and end\r\n if (Math.abs(dx1) >= Math.abs(dy1)) {\r\n return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\r\n } else {\r\n return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\r\n }\r\n }\r\n}\r\n","import { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { CircleCollider } from './CircleCollider';\r\n\r\n/**\r\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\r\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n * @param p0 Point where L1 begins\r\n * @param u Direction and length of L1\r\n * @param q0 Point were L2 begins\r\n * @param v Direction and length of L2\r\n */\r\nexport function ClosestLine(p0: Vector, u: Vector, q0: Vector, v: Vector) {\r\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\r\n\r\n // w(s, t) = P(s) - Q(t)\r\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\r\n //\r\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\r\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\r\n //\r\n // The closest point between 2 lines then satisfies this pair of equations\r\n // 1: u * wClosest = 0\r\n // 2: v * wClosest = 0\r\n //\r\n // Substituting wClosest into the equations we get\r\n //\r\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\r\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\r\n\r\n // simplify w0\r\n const w0 = p0.sub(q0);\r\n\r\n // simplify (u * u);\r\n const a = u.dot(u);\r\n // simplify (u * v);\r\n const b = u.dot(v);\r\n // simplify (v * v)\r\n const c = v.dot(v);\r\n // simplify (u * w0)\r\n const d = u.dot(w0);\r\n // simplify (v * w0)\r\n const e = v.dot(w0);\r\n\r\n // denominator ac - b^2\r\n const denom = a * c - b * b;\r\n let sDenom = denom;\r\n let tDenom = denom;\r\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\r\n if (denom === 0 || denom <= 0.01) {\r\n const tClosestParallel = d / b;\r\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\r\n }\r\n\r\n // Solve for sClosest for infinite line\r\n let sClosest = b * e - c * d; // / denom;\r\n\r\n // Solve for tClosest for infinite line\r\n let tClosest = a * e - b * d; // / denom;\r\n\r\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\r\n if (sClosest < 0) {\r\n sClosest = 0;\r\n tClosest = e;\r\n tDenom = c;\r\n } else if (sClosest > sDenom) {\r\n sClosest = sDenom;\r\n tClosest = e + b;\r\n tDenom = c;\r\n }\r\n\r\n if (tClosest < 0) {\r\n tClosest = 0;\r\n if (-d < 0) {\r\n sClosest = 0;\r\n } else if (-d > a) {\r\n sClosest = sDenom;\r\n } else {\r\n sClosest = -d;\r\n sDenom = a;\r\n }\r\n } else if (tClosest > tDenom) {\r\n tClosest = tDenom;\r\n if (-d + b < 0) {\r\n sClosest = 0;\r\n } else if (-d + b > a) {\r\n sClosest = sDenom;\r\n } else {\r\n sClosest = -d + b;\r\n sDenom = a;\r\n }\r\n }\r\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\r\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\r\n\r\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\r\n}\r\n\r\nexport const ClosestLineJumpTable = {\r\n PolygonPolygonClosestLine(polygonA: PolygonCollider, polygonB: PolygonCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = polygonB.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\r\n const thisDirection = otherDirection.negate();\r\n\r\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\r\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\r\n\r\n const thisPoint = polygonA.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\r\n const otherPoint = polygonB.rayCast(rayTowardsThis).point.add(rayTowardsThis.dir.scale(0.1));\r\n\r\n const thisFace = polygonA.getClosestFace(thisPoint);\r\n const otherFace = polygonB.getClosestFace(otherPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const q0 = otherFace.face.begin;\r\n const v = otherFace.face.getEdge();\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n },\r\n\r\n PolygonEdgeClosestLine(polygon: PolygonCollider, edge: EdgeCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = edge.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\r\n\r\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\r\n\r\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\r\n\r\n const thisFace = polygon.getClosestFace(thisPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const edgeLine = edge.asLine();\r\n const edgeStart = edgeLine.begin;\r\n const edgeVector = edgeLine.getEdge();\r\n const q0 = edgeStart;\r\n const v = edgeVector;\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n },\r\n\r\n PolygonCircleClosestLine(polygon: PolygonCollider, circle: CircleCollider) {\r\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = circle.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\r\n\r\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\r\n\r\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\r\n\r\n const thisFace = polygon.getClosestFace(thisPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // Time of minimum distance\r\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\r\n\r\n // If time of minimum is past the edge clamp\r\n if (t > 1) {\r\n t = 1;\r\n } else if (t < 0) {\r\n t = 0;\r\n }\r\n\r\n // Minimum distance\r\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\r\n\r\n const circlex = ((p0.x + u.x * t - otherWorldPos.x) * circle.radius) / (circle.radius + d);\r\n const circley = ((p0.y + u.y * t - otherWorldPos.y) * circle.radius) / (circle.radius + d);\r\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\r\n },\r\n\r\n CircleCircleClosestLine(circleA: CircleCollider, circleB: CircleCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = circleB.worldPos;\r\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\r\n\r\n const thisWorldPos = circleA.worldPos;\r\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\r\n\r\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\r\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\r\n\r\n const thisPoint = circleA.rayCast(rayTowardsOther);\r\n const otherPoint = circleB.rayCast(rayTowardsThis);\r\n\r\n return new LineSegment(thisPoint.point, otherPoint.point);\r\n },\r\n\r\n CircleEdgeClosestLine(circle: CircleCollider, edge: EdgeCollider) {\r\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\r\n const circleWorldPos = circle.worldPos;\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const edgeLine = edge.asLine();\r\n const edgeStart = edgeLine.begin;\r\n const edgeVector = edgeLine.getEdge();\r\n const p0 = edgeStart;\r\n const u = edgeVector;\r\n\r\n // Time of minimum distance\r\n let t = (u.x * (circleWorldPos.x - p0.x) + u.y * (circleWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\r\n\r\n // If time of minimum is past the edge clamp to edge\r\n if (t > 1) {\r\n t = 1;\r\n } else if (t < 0) {\r\n t = 0;\r\n }\r\n\r\n // Minimum distance\r\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorldPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorldPos.y, 2)) - circle.radius;\r\n\r\n const circlex = ((p0.x + u.x * t - circleWorldPos.x) * circle.radius) / (circle.radius + d);\r\n const circley = ((p0.y + u.y * t - circleWorldPos.y) * circle.radius) / (circle.radius + d);\r\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorldPos.x + circlex, circleWorldPos.y + circley));\r\n },\r\n\r\n EdgeEdgeClosestLine(edgeA: EdgeCollider, edgeB: EdgeCollider) {\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const edgeLineA = edgeA.asLine();\r\n const edgeStartA = edgeLineA.begin;\r\n const edgeVectorA = edgeLineA.getEdge();\r\n const p0 = edgeStartA;\r\n const u = edgeVectorA;\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const edgeLineB = edgeB.asLine();\r\n const edgeStartB = edgeLineB.begin;\r\n const edgeVectorB = edgeLineB.getEdge();\r\n const q0 = edgeStartB;\r\n const v = edgeVectorB;\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n }\r\n};\r\n","import { BoundingBox } from '../BoundingBox';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\n\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Color } from '../../Color';\r\nimport { Collider } from './Collider';\r\n\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { BodyComponent } from '../Index';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\n\r\nexport interface CircleColliderOptions {\r\n /**\r\n * Optional pixel offset to shift the circle relative to the collider, by default (0, 0).\r\n */\r\n offset?: Vector;\r\n /**\r\n * Required radius of the circle\r\n */\r\n radius: number;\r\n}\r\n\r\n/**\r\n * This is a circle collider for the excalibur rigid body physics simulation\r\n */\r\nexport class CircleCollider extends Collider {\r\n /**\r\n * Position of the circle relative to the collider, by default (0, 0).\r\n */\r\n public offset: Vector = Vector.Zero;\r\n\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n public get worldPos(): Vector {\r\n return this._globalMatrix.getPosition();\r\n }\r\n\r\n private _naturalRadius: number;\r\n /**\r\n * Get the radius of the circle\r\n */\r\n public get radius(): number {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\r\n return this._naturalRadius * Math.min(scale.x, scale.y);\r\n }\r\n\r\n /**\r\n * Set the radius of the circle\r\n */\r\n public set radius(val: number) {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\r\n this._naturalRadius = val / Math.min(scale.x, scale.y);\r\n }\r\n\r\n private _transform: Transform;\r\n\r\n constructor(options: CircleColliderOptions) {\r\n super();\r\n this.offset = options.offset || Vector.Zero;\r\n this.radius = options.radius || 0;\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Returns a clone of this shape, not associated with any collider\r\n */\r\n public clone(): CircleCollider {\r\n return new CircleCollider({\r\n offset: this.offset.clone(),\r\n radius: this.radius\r\n });\r\n }\r\n\r\n /**\r\n * Get the center of the collider in world coordinates\r\n */\r\n public get center(): Vector {\r\n return this._globalMatrix.getPosition();\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collider\r\n */\r\n public contains(point: Vector): boolean {\r\n const pos = this._transform?.pos ?? this.offset;\r\n const distance = pos.distance(point);\r\n if (distance <= this.radius) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Casts a ray at the Circle collider and returns the nearest point of collision\r\n * @param ray\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity): RayCastHit | null {\r\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\r\n const c = this.center;\r\n const dir = ray.dir;\r\n const orig = ray.pos;\r\n\r\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\r\n\r\n if (discriminant < 0) {\r\n // no intersection\r\n return null;\r\n } else {\r\n let toi = 0;\r\n // tangent case\r\n if (discriminant === 0) {\r\n toi = -dir.dot(orig.sub(c));\r\n if (toi > 0 && toi < max) {\r\n const point = ray.getPoint(toi);\r\n return {\r\n point,\r\n normal: point.sub(c).normalize(),\r\n collider: this,\r\n body: this.owner?.get(BodyComponent),\r\n distance: toi\r\n } satisfies RayCastHit;\r\n }\r\n return null;\r\n } else { // two point\r\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\r\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\r\n\r\n const positiveToi: number[] = [];\r\n if (toi1 >= 0) {\r\n positiveToi.push(toi1);\r\n }\r\n\r\n if (toi2 >= 0) {\r\n positiveToi.push(toi2);\r\n }\r\n\r\n const minToi = Math.min(...positiveToi);\r\n if (minToi <= max) {\r\n const point = ray.getPoint(minToi);\r\n return {\r\n point,\r\n normal: point.sub(c).normalize(),\r\n collider: this,\r\n body: this.owner?.get(BodyComponent),\r\n distance: minToi\r\n } satisfies RayCastHit;\r\n }\r\n return null;\r\n }\r\n }\r\n }\r\n\r\n public getClosestLineBetween(shape: Collider): LineSegment {\r\n if (shape instanceof CircleCollider) {\r\n return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\r\n } else if (shape instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\r\n } else if (shape instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public collide(collider: Collider): CollisionContact[] {\r\n if (collider instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCircleCircle(this, collider);\r\n } else if (collider instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollideCirclePolygon(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollideCircleEdge(this, collider);\r\n } else {\r\n throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n return this.center.add(direction.normalize().scale(this.radius));\r\n }\r\n\r\n /**\r\n * Find the local point on the shape in the direction specified\r\n * @param direction\r\n */\r\n public getFurthestLocalPoint(direction: Vector): Vector {\r\n const dir = direction.normalize();\r\n return dir.scale(this.radius);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the circle collider in world coordinates\r\n */\r\n public get bounds(): BoundingBox {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n const rotation = tx?.globalRotation ?? 0;\r\n const pos = (tx?.globalPos ?? Vector.Zero);\r\n return new BoundingBox(\r\n this.offset.x - this._naturalRadius,\r\n this.offset.y - this._naturalRadius,\r\n this.offset.x + this._naturalRadius,\r\n this.offset.y + this._naturalRadius\r\n ).rotate(rotation).scale(scale).translate(pos);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the circle collider in local coordinates\r\n */\r\n public get localBounds(): BoundingBox {\r\n return new BoundingBox(\r\n this.offset.x - this._naturalRadius,\r\n this.offset.y - this._naturalRadius,\r\n this.offset.x + this._naturalRadius,\r\n this.offset.y + this._naturalRadius\r\n );\r\n }\r\n\r\n /**\r\n * Get axis not implemented on circles, since there are infinite axis in a circle\r\n */\r\n public get axes(): Vector[] {\r\n return [];\r\n }\r\n\r\n /**\r\n * Returns the moment of inertia of a circle given it's mass\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n return (mass * this.radius * this.radius) / 2;\r\n }\r\n\r\n /* istanbul ignore next */\r\n public update(transform: Transform): void {\r\n this._transform = transform;\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Project the circle along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const scalars = [];\r\n const point = this.center;\r\n const dotProduct = point.dot(axis);\r\n scalars.push(dotProduct);\r\n scalars.push(dotProduct + this.radius);\r\n scalars.push(dotProduct - this.radius);\r\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number }) {\r\n const { lineWidth } = { ...{ lineWidth: 1 }, ...options };\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n const rotation = tx?.globalRotation ?? 0;\r\n const pos = (tx?.globalPos ?? Vector.Zero);\r\n ex.save();\r\n ex.translate(pos.x, pos.y);\r\n ex.rotate(rotation);\r\n ex.scale(scale.x, scale.y);\r\n ex.drawCircle((this.offset ?? Vector.Zero), this._naturalRadius, Color.Transparent, color, lineWidth);\r\n ex.restore();\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { Collider } from '../Colliders/Collider';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Pair } from './Pair';\r\nimport { SeparationInfo } from '../Colliders/SeparatingAxis';\r\nimport { BodyComponent } from '../BodyComponent';\r\n\r\n/**\r\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\r\n * Pair prevents collisions from being evaluated more than one time\r\n */\r\nexport class CollisionContact {\r\n private _canceled = false;\r\n\r\n /**\r\n * Currently the ids between colliders\r\n */\r\n readonly id: string;\r\n\r\n /**\r\n * The first collider in the collision\r\n */\r\n colliderA: Collider;\r\n\r\n /**\r\n * The second collider in the collision\r\n */\r\n colliderB: Collider;\r\n\r\n /**\r\n * The minimum translation vector to resolve overlap, pointing away from colliderA\r\n */\r\n mtv: Vector;\r\n\r\n /**\r\n * World space contact points between colliderA and colliderB\r\n */\r\n points: Vector[];\r\n\r\n /**\r\n * Local space contact points between colliderA and colliderB\r\n */\r\n localPoints: Vector[];\r\n\r\n /**\r\n * The collision normal, pointing away from colliderA\r\n */\r\n normal: Vector;\r\n\r\n /**\r\n * The collision tangent\r\n */\r\n tangent: Vector;\r\n\r\n /**\r\n * Information about the specifics of the collision contact separation\r\n */\r\n info: SeparationInfo;\r\n\r\n constructor(\r\n colliderA: Collider,\r\n colliderB: Collider,\r\n mtv: Vector,\r\n normal: Vector,\r\n tangent: Vector,\r\n points: Vector[],\r\n localPoints: Vector[],\r\n info: SeparationInfo\r\n ) {\r\n this.colliderA = colliderA;\r\n this.colliderB = colliderB;\r\n this.mtv = mtv;\r\n this.normal = normal;\r\n this.tangent = tangent;\r\n this.points = points;\r\n this.localPoints = localPoints;\r\n this.info = info;\r\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n if (colliderA.composite || colliderB.composite) {\r\n // Add on the parent composite pair for start/end contact if 'together\r\n const colliderAId = colliderA.composite?.compositeStrategy === 'separate' ? colliderA.id : colliderA.composite?.id ?? colliderA.id;\r\n const colliderBId = colliderB.composite?.compositeStrategy === 'separate' ? colliderB.id : colliderB.composite?.id ?? colliderB.id;\r\n this.id += '|' + Pair.calculatePairHash(colliderAId, colliderBId);\r\n }\r\n }\r\n\r\n /**\r\n * Match contact awake state, except if body's are Fixed\r\n */\r\n public matchAwake(): void {\r\n const bodyA = this.colliderA.owner.get(BodyComponent);\r\n const bodyB = this.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.sleeping !== bodyB.sleeping) {\r\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= bodyA.wakeThreshold) {\r\n bodyA.setSleeping(false);\r\n }\r\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= bodyB.wakeThreshold) {\r\n bodyB.setSleeping(false);\r\n }\r\n }\r\n }\r\n }\r\n\r\n public isCanceled() {\r\n return this._canceled;\r\n }\r\n\r\n public cancel(): void {\r\n this._canceled = true;\r\n }\r\n}\r\n","import { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Collider } from './Collider';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { PolygonCollider } from './PolygonCollider';\r\n\r\n/**\r\n * Specific information about a contact and it's separation\r\n */\r\nexport interface SeparationInfo {\r\n /**\r\n * Collider A\r\n */\r\n collider: Collider;\r\n\r\n /**\r\n * Signed value (negative means overlap, positive no overlap)\r\n */\r\n separation: number;\r\n\r\n /**\r\n * Axis of separation from the collider's perspective\r\n */\r\n axis: Vector;\r\n\r\n /**\r\n * Side of separation (reference) from the collider's perspective\r\n */\r\n\r\n side?: LineSegment;\r\n\r\n /**\r\n * Local side of separation (reference) from the collider's perspective\r\n */\r\n localSide?: LineSegment;\r\n\r\n /**\r\n * Index of the separation side (reference) from the collider's perspective\r\n */\r\n sideId?: number;\r\n\r\n /**\r\n * Point on collider B (incident point)\r\n */\r\n point: Vector;\r\n\r\n /**\r\n * Local point on collider B (incident point)\r\n */\r\n localPoint?: Vector;\r\n}\r\n\r\nexport class SeparatingAxis {\r\n static findPolygonPolygonSeparation(polyA: PolygonCollider, polyB: PolygonCollider): SeparationInfo {\r\n let bestSeparation = -Number.MAX_VALUE;\r\n let bestSide: LineSegment | null = null;\r\n let bestAxis: Vector | null = null;\r\n let bestSideIndex: number = -1;\r\n let bestOtherPoint: Vector | null = null;\r\n const sides = polyA.getSides();\r\n const localSides = polyA.getLocalSides();\r\n for (let i = 0; i < sides.length; i++) {\r\n const side = sides[i];\r\n const axis = side.normal();\r\n const vertB = polyB.getFurthestPoint(axis.negate());\r\n // Separation on side i's axis\r\n // We are looking for the largest separation between poly A's sides\r\n const vertSeparation = side.distanceToPoint(vertB, true);\r\n if (vertSeparation > bestSeparation) {\r\n bestSeparation = vertSeparation;\r\n bestSide = side;\r\n bestAxis = axis;\r\n bestSideIndex = i;\r\n bestOtherPoint = vertB;\r\n }\r\n }\r\n\r\n return {\r\n collider: polyA,\r\n separation: bestAxis ? bestSeparation : 99,\r\n axis: bestAxis as Vector,\r\n side: bestSide,\r\n localSide: localSides[bestSideIndex],\r\n sideId: bestSideIndex,\r\n point: bestOtherPoint as Vector,\r\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis!.negate()) : null\r\n };\r\n }\r\n\r\n static findCirclePolygonSeparation(circle: CircleCollider, polygon: PolygonCollider): Vector | null {\r\n const axes = polygon.axes;\r\n const pc = polygon.center;\r\n // Special SAT with circles\r\n const polyDir = pc.sub(circle.worldPos);\r\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\r\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\r\n\r\n let minOverlap = Number.MAX_VALUE;\r\n let minAxis = null;\r\n let minIndex = -1;\r\n for (let i = 0; i < axes.length; i++) {\r\n const proj1 = polygon.project(axes[i]);\r\n const proj2 = circle.project(axes[i]);\r\n const overlap = proj1.getOverlap(proj2);\r\n if (overlap <= 0) {\r\n return null;\r\n } else {\r\n if (overlap < minOverlap) {\r\n minOverlap = overlap;\r\n minAxis = axes[i];\r\n minIndex = i;\r\n }\r\n }\r\n }\r\n if (minIndex < 0) {\r\n return null;\r\n }\r\n return minAxis.normalize().scale(minOverlap);\r\n }\r\n}\r\n","import { CircleCollider } from './CircleCollider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { SeparatingAxis, SeparationInfo } from './SeparatingAxis';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { TransformComponent } from '../../EntityComponentSystem';\r\nimport { Pair } from '../Detection/Pair';\r\n\r\nexport const CollisionJumpTable = {\r\n CollideCircleCircle(circleA: CircleCollider, circleB: CircleCollider): CollisionContact[] {\r\n const circleAPos = circleA.worldPos;\r\n const circleBPos = circleB.worldPos;\r\n const combinedRadius = circleA.radius + circleB.radius;\r\n const distance = circleAPos.distance(circleBPos);\r\n\r\n if (distance > combinedRadius) {\r\n return [];\r\n }\r\n\r\n // negative means overlap\r\n const separation = combinedRadius - distance;\r\n\r\n // Normal points from A -> B\r\n const normal = circleBPos.sub(circleAPos).normalize();\r\n const tangent = normal.perpendicular();\r\n const mvt = normal.scale(separation);\r\n\r\n const point = circleA.getFurthestPoint(normal);\r\n const local = circleA.getFurthestLocalPoint(normal);\r\n\r\n const info: SeparationInfo = {\r\n collider: circleA,\r\n separation,\r\n axis: normal,\r\n point: point\r\n };\r\n\r\n return [new CollisionContact(circleA, circleB, mvt, normal, tangent, [point], [local], info)];\r\n },\r\n\r\n CollideCirclePolygon(circle: CircleCollider, polygon: PolygonCollider): CollisionContact[] {\r\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\r\n if (!minAxis) {\r\n return [];\r\n }\r\n\r\n // make sure that the minAxis is pointing away from circle\r\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\r\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\r\n\r\n const point = circle.getFurthestPoint(minAxis);\r\n const xf = circle.owner?.get(TransformComponent) ?? new TransformComponent();\r\n const local = xf.applyInverse(point);\r\n const normal = minAxis.normalize();\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: -minAxis.size,\r\n axis: normal,\r\n point: point,\r\n localPoint: local,\r\n side: polygon.findSide(normal.negate()),\r\n localSide: polygon.findLocalSide(normal.negate())\r\n };\r\n\r\n return [new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [point], [local], info)];\r\n },\r\n\r\n CollideCircleEdge(circle: CircleCollider, edge: EdgeCollider): CollisionContact[] {\r\n // TODO not sure this actually abides by local/world collisions\r\n // Are edge.begin and edge.end local space or world space? I think they should be local\r\n\r\n // center of the circle in world pos\r\n const cc = circle.center;\r\n // vector in the direction of the edge\r\n const edgeWorld = edge.asLine();\r\n const e = edgeWorld.end.sub(edgeWorld.begin);\r\n\r\n // amount of overlap with the circle's center along the edge direction\r\n const u = e.dot(edgeWorld.end.sub(cc));\r\n const v = e.dot(cc.sub(edgeWorld.begin));\r\n const side = edge.asLine();\r\n const localSide = edge.asLocalLine();\r\n\r\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\r\n if (v <= 0) {\r\n const da = edgeWorld.begin.sub(cc);\r\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\r\n // save some sqrts\r\n if (dda > circle.radius * circle.radius) {\r\n return []; // no collision\r\n }\r\n\r\n const normal = da.normalize();\r\n const separation = circle.radius - Math.sqrt(dda);\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: side.begin,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.begin], [localSide.begin], info)\r\n ];\r\n }\r\n\r\n // Potential region B collision (circle is on the right side of the edge, after the end)\r\n if (u <= 0) {\r\n const db = edgeWorld.end.sub(cc);\r\n const ddb = db.dot(db);\r\n if (ddb > circle.radius * circle.radius) {\r\n return [];\r\n }\r\n\r\n const normal = db.normalize();\r\n const separation = circle.radius - Math.sqrt(ddb);\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: side.end,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.end], [localSide.end], info)\r\n ];\r\n }\r\n\r\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\r\n const den = e.dot(e);\r\n const pointOnEdge = edgeWorld.begin\r\n .scale(u)\r\n .add(edgeWorld.end.scale(v))\r\n .scale(1 / den);\r\n const d = cc.sub(pointOnEdge);\r\n\r\n const dd = d.dot(d);\r\n if (dd > circle.radius * circle.radius) {\r\n return []; // no collision\r\n }\r\n\r\n let normal = e.perpendicular();\r\n // flip correct direction\r\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\r\n normal.x = -normal.x;\r\n normal.y = -normal.y;\r\n }\r\n\r\n normal = normal.normalize();\r\n const separation = circle.radius - Math.sqrt(dd);\r\n\r\n const mvt = normal.scale(separation);\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: pointOnEdge,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(\r\n circle,\r\n edge,\r\n mvt,\r\n normal.negate(),\r\n normal.negate().perpendicular(),\r\n [pointOnEdge],\r\n [pointOnEdge.sub(edge.worldPos)],\r\n info\r\n )\r\n ];\r\n },\r\n\r\n CollideEdgeEdge(): CollisionContact[] {\r\n // Edge-edge collision doesn't make sense\r\n return [];\r\n },\r\n\r\n CollidePolygonEdge(polygon: PolygonCollider, edge: EdgeCollider): CollisionContact[] {\r\n const pc = polygon.center;\r\n const ec = edge.center;\r\n const dir = ec.sub(pc).normalize();\r\n\r\n // build a temporary polygon from the edge to use SAT\r\n const linePoly = new PolygonCollider({\r\n points: [edge.begin, edge.end, edge.end.add(dir.scale(100)), edge.begin.add(dir.scale(100))],\r\n offset: edge.offset\r\n });\r\n linePoly.owner = edge.owner;\r\n const tx = edge.owner?.get(TransformComponent);\r\n if (tx) {\r\n linePoly.update(edge.owner.get(TransformComponent).get());\r\n }\r\n // Gross hack but poly-poly works well\r\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\r\n if (contact.length) {\r\n // Fudge the contact back to edge\r\n contact[0].colliderB = edge;\r\n (contact[0].id as any) = Pair.calculatePairHash(polygon.id, edge.id);\r\n }\r\n return contact;\r\n },\r\n\r\n CollidePolygonPolygon(polyA: PolygonCollider, polyB: PolygonCollider): CollisionContact[] {\r\n // Multi contact from SAT\r\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\r\n // do a SAT test to find a min axis if it exists\r\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\r\n // If there is no overlap from boxA's perspective we can end early\r\n if (separationA.separation > 0) {\r\n return [];\r\n }\r\n\r\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\r\n // If there is no overlap from boxB's perspective exit now\r\n if (separationB.separation > 0) {\r\n return [];\r\n }\r\n\r\n // Separations are both negative, we want to pick the least negative (minimal movement)\r\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\r\n\r\n // The incident side is the most opposite from the axes of collision on the other collider\r\n const other = separation.collider === polyA ? polyB : polyA;\r\n const incident = other.findSide(separation.axis.negate()) as LineSegment;\r\n\r\n // Clip incident side by the perpendicular lines at each end of the reference side\r\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\r\n const reference = separation.side;\r\n const refDir = reference.dir().normalize();\r\n\r\n // Find our contact points by clipping the incident by the collision side\r\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\r\n let clipLeft: LineSegment | null = null;\r\n if (clipRight) {\r\n clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\r\n }\r\n\r\n // If there is no left there is no collision\r\n if (clipLeft) {\r\n // We only want clip points below the reference edge, discard the others\r\n const points = clipLeft.getPoints().filter((p) => {\r\n return reference.below(p);\r\n });\r\n\r\n let normal = separation.axis;\r\n let tangent = normal.perpendicular();\r\n // Point Contact A -> B\r\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\r\n normal = normal.negate();\r\n tangent = normal.perpendicular();\r\n }\r\n // Points are clipped from incident which is the other collider\r\n // Store those as locals\r\n let localPoints: Vector[] = [];\r\n if (separation.collider === polyA) {\r\n const xf = polyB.owner?.get(TransformComponent) ?? new TransformComponent();\r\n localPoints = points.map((p) => xf.applyInverse(p));\r\n } else {\r\n const xf = polyA.owner?.get(TransformComponent) ?? new TransformComponent();\r\n localPoints = points.map((p) => xf.applyInverse(p));\r\n }\r\n return [new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)];\r\n }\r\n return [];\r\n },\r\n\r\n FindContactSeparation(contact: CollisionContact, localPoint: Vector) {\r\n const shapeA = contact.colliderA;\r\n const txA = contact.colliderA.owner?.get(TransformComponent) ?? new TransformComponent();\r\n const shapeB = contact.colliderB;\r\n const txB = contact.colliderB.owner?.get(TransformComponent) ?? new TransformComponent();\r\n\r\n // both are circles\r\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\r\n const combinedRadius = shapeA.radius + shapeB.radius;\r\n const distance = txA.pos.distance(txB.pos);\r\n const separation = combinedRadius - distance;\r\n return -separation;\r\n }\r\n\r\n // both are polygons\r\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\r\n if (contact.info.localSide) {\r\n let side: LineSegment;\r\n let worldPoint: Vector;\r\n if (contact.info.collider === shapeA) {\r\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\r\n worldPoint = txB.apply(localPoint);\r\n } else {\r\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\r\n worldPoint = txA.apply(localPoint);\r\n }\r\n\r\n return side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // polygon v circle\r\n if (\r\n (shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider) ||\r\n (shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider)\r\n ) {\r\n const worldPoint = txA.apply(localPoint);\r\n if (contact.info.side) {\r\n return contact.info.side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // polygon v edge\r\n if (\r\n (shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider) ||\r\n (shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider)\r\n ) {\r\n let worldPoint: Vector;\r\n if (contact.info.collider === shapeA) {\r\n worldPoint = txB.apply(localPoint);\r\n } else {\r\n worldPoint = txA.apply(localPoint);\r\n }\r\n if (contact.info.side) {\r\n return contact.info.side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // circle v edge\r\n if (\r\n (shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider) ||\r\n (shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider)\r\n ) {\r\n // Local point is always on the edge which is always shapeB\r\n const worldPoint = txB.apply(localPoint);\r\n\r\n let circlePoint: Vector;\r\n if (shapeA instanceof CircleCollider) {\r\n circlePoint = shapeA.getFurthestPoint(contact.normal);\r\n }\r\n\r\n const dist = worldPoint.distance(circlePoint);\r\n\r\n if (contact.info.side) {\r\n return dist > 0 ? -dist : 0;\r\n }\r\n }\r\n\r\n return 0;\r\n }\r\n};\r\n","import { BoundingBox } from '../BoundingBox';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { PolygonCollider } from './PolygonCollider';\r\n\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Color } from '../../Color';\r\nimport { Collider } from './Collider';\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { BodyComponent } from '../Index';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\n\r\nexport interface EdgeColliderOptions {\r\n /**\r\n * The beginning of the edge defined in local coordinates to the collider\r\n */\r\n begin: Vector;\r\n /**\r\n * The ending of the edge defined in local coordinates to the collider\r\n */\r\n end: Vector;\r\n /**\r\n * Optionally specify an offset\r\n */\r\n offset?: Vector;\r\n}\r\n\r\n/**\r\n * Edge is a single line collider to create collisions with a single line.\r\n */\r\nexport class EdgeCollider extends Collider {\r\n offset: Vector;\r\n begin: Vector;\r\n end: Vector;\r\n\r\n private _transform: Transform;\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n constructor(options: EdgeColliderOptions) {\r\n super();\r\n this.begin = options.begin || Vector.Zero;\r\n this.end = options.end || Vector.Zero;\r\n this.offset = options.offset ?? Vector.Zero;\r\n }\r\n\r\n /**\r\n * Returns a clone of this Edge, not associated with any collider\r\n */\r\n public clone(): EdgeCollider {\r\n return new EdgeCollider({\r\n begin: this.begin.clone(),\r\n end: this.end.clone()\r\n });\r\n }\r\n\r\n public get worldPos(): Vector {\r\n const tx = this._transform;\r\n return tx?.globalPos.add(this.offset) ?? this.offset;\r\n }\r\n\r\n /**\r\n * Get the center of the collision area in world coordinates\r\n */\r\n public get center(): Vector {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const pos = begin.average(end);\r\n return pos;\r\n }\r\n\r\n private _getTransformedBegin(): Vector {\r\n return this._globalMatrix.multiply(this.begin);\r\n }\r\n\r\n private _getTransformedEnd(): Vector {\r\n return this._globalMatrix.multiply(this.end);\r\n }\r\n\r\n /**\r\n * Returns the slope of the line in the form of a vector\r\n */\r\n public getSlope(): Vector {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const distance = begin.distance(end);\r\n return end.sub(begin).scale(1 / distance);\r\n }\r\n\r\n /**\r\n * Returns the length of the line segment in pixels\r\n */\r\n public getLength(): number {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const distance = begin.distance(end);\r\n return distance;\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collision area\r\n */\r\n public contains(): boolean {\r\n return false;\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity): RayCastHit | null {\r\n const numerator = this._getTransformedBegin().sub(ray.pos);\r\n\r\n // Test is line and ray are parallel and non intersecting\r\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) {\r\n return null;\r\n }\r\n\r\n // Lines are parallel\r\n const divisor = ray.dir.cross(this.getSlope());\r\n if (divisor === 0) {\r\n return null;\r\n }\r\n\r\n const t = numerator.cross(this.getSlope()) / divisor;\r\n\r\n if (t >= 0 && t <= max) {\r\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\r\n if (u >= 0 && u <= 1) {\r\n return {\r\n distance: t,\r\n normal: this.asLine().normal(),\r\n collider: this,\r\n body: this.owner?.get(BodyComponent),\r\n point: ray.getPoint(t)\r\n } satisfies RayCastHit;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns the closes line between this and another collider, from this -> collider\r\n * @param shape\r\n */\r\n public getClosestLineBetween(shape: Collider): LineSegment {\r\n if (shape instanceof CircleCollider) {\r\n return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\r\n } else if (shape instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\r\n } else if (shape instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public collide(shape: Collider): CollisionContact[] {\r\n if (shape instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCircleEdge(shape, this);\r\n } else if (shape instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollidePolygonEdge(shape, this);\r\n } else if (shape instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollideEdgeEdge();\r\n } else {\r\n throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n const transformedBegin = this._getTransformedBegin();\r\n const transformedEnd = this._getTransformedEnd();\r\n if (direction.dot(transformedBegin) > 0) {\r\n return transformedBegin;\r\n } else {\r\n return transformedEnd;\r\n }\r\n }\r\n\r\n private _boundsFromBeginEnd(begin: Vector, end: Vector, padding = 10) {\r\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\r\n // this causes problems for the collision system so we give them some padding\r\n return new BoundingBox(\r\n Math.min(begin.x, end.x) - padding,\r\n Math.min(begin.y, end.y) - padding,\r\n Math.max(begin.x, end.x) + padding,\r\n Math.max(begin.y, end.y) + padding\r\n );\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the edge collider in world space\r\n */\r\n public get bounds(): BoundingBox {\r\n const transformedBegin = this._getTransformedBegin();\r\n const transformedEnd = this._getTransformedEnd();\r\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the edge collider in local space\r\n */\r\n public get localBounds(): BoundingBox {\r\n return this._boundsFromBeginEnd(this.begin, this.end);\r\n }\r\n\r\n /**\r\n * Returns this edge represented as a line in world coordinates\r\n */\r\n public asLine(): LineSegment {\r\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\r\n }\r\n\r\n /**\r\n * Return this edge as a line in local line coordinates (relative to the position)\r\n */\r\n public asLocalLine(): LineSegment {\r\n return new LineSegment(this.begin, this.end);\r\n }\r\n\r\n /**\r\n * Get the axis associated with the edge\r\n */\r\n public get axes(): Vector[] {\r\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\r\n const edgeNormal = e.normal();\r\n\r\n const axes = [];\r\n axes.push(edgeNormal);\r\n axes.push(edgeNormal.negate());\r\n axes.push(edgeNormal.normal());\r\n axes.push(edgeNormal.normal().negate());\r\n return axes;\r\n }\r\n\r\n /**\r\n * Get the moment of inertia for an edge\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n const length = this.end.sub(this.begin).distance() / 2;\r\n return mass * length * length;\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public update(transform: Transform): void {\r\n this._transform = transform;\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Project the edge along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const scalars = [];\r\n\r\n const points = [this._getTransformedBegin(), this._getTransformedEnd()];\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n scalars.push(points[i].dot(axis));\r\n }\r\n\r\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color) {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n ex.drawLine(begin, end, color, 2);\r\n ex.drawCircle(begin, 2, color);\r\n ex.drawCircle(end, 2, color);\r\n }\r\n\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext, LineGraphicsOptions, PointGraphicsOptions } from './Context/ExcaliburGraphicsContext';\r\nimport { Color } from '../Color';\r\nimport { Ray } from '../Math/ray';\r\nimport { BoundingBox } from '../excalibur';\r\n\r\nexport class Debug {\r\n static _drawCalls: ((ctx: ExcaliburGraphicsContext) => void)[] = [];\r\n static _ctx: ExcaliburGraphicsContext;\r\n static z: number = Infinity;\r\n static registerGraphicsContext(ctx: ExcaliburGraphicsContext) {\r\n Debug._ctx = ctx;\r\n }\r\n static draw(debugDrawCall: (ctx: ExcaliburGraphicsContext) => void) {\r\n this._drawCalls.push(debugDrawCall);\r\n }\r\n\r\n static drawPoint(point: Vector, options?: PointGraphicsOptions) {\r\n Debug.draw(ctx => {\r\n ctx.debug.drawPoint(point, options);\r\n });\r\n }\r\n\r\n static drawLine(start: Vector, end: Vector, options?: LineGraphicsOptions) {\r\n Debug.draw(ctx => {\r\n ctx.debug.drawLine(start, end, options);\r\n });\r\n }\r\n\r\n static drawLines(points: Vector[], options?: LineGraphicsOptions) {\r\n if (points.length > 1) {\r\n Debug.draw(ctx => {\r\n for (let i = 0; i < points.length - 1; i++) {\r\n ctx.debug.drawLine(points[i], points[i + 1], options);\r\n }\r\n });\r\n }\r\n }\r\n\r\n static drawText(text: string, pos: Vector) {\r\n Debug.draw(ctx => {\r\n ctx.debug.drawText(text, pos);\r\n });\r\n }\r\n\r\n static drawPolygon(points: Vector[], options?: { color?: Color }) {\r\n if (points.length > 1) {\r\n Debug.draw(ctx => {\r\n const firstPoint = points[0];\r\n const polygon = [...points, firstPoint];\r\n for (let i = 0; i < polygon.length - 1; i++) {\r\n ctx.debug.drawLine(polygon[i], polygon[i + 1], options);\r\n }\r\n });\r\n }\r\n }\r\n\r\n static drawCircle(center: Vector, radius: number, options?: {\r\n color?: Color,\r\n strokeColor?: Color,\r\n width?: number\r\n }) {\r\n const { color, strokeColor, width} = {\r\n color: Color.Black,\r\n strokeColor: undefined,\r\n width: undefined,\r\n ...options\r\n };\r\n Debug.draw(ctx => {\r\n ctx.drawCircle(center, radius, color, strokeColor, width);\r\n });\r\n }\r\n\r\n static drawBounds(boundingBox: BoundingBox, options?: { color?: Color }): void {\r\n Debug.draw(ctx => {\r\n ctx.debug.drawRect(boundingBox.left, boundingBox.top, boundingBox.width, boundingBox.height, options);\r\n });\r\n }\r\n\r\n static drawRay(ray: Ray, options?: { distance?: number, color?: Color }) {\r\n const { distance, color } = {\r\n color: Color.Blue,\r\n distance: 10,\r\n ...options\r\n };\r\n Debug.draw((ctx) => {\r\n const start = ray.pos;\r\n const end = ray.pos.add(ray.dir.scale(distance));\r\n\r\n ctx.debug.drawLine(start, end, { color });\r\n });\r\n }\r\n\r\n static flush(ctx: ExcaliburGraphicsContext) {\r\n ctx.save();\r\n ctx.z = Debug.z;\r\n for (const drawCall of Debug._drawCalls) {\r\n drawCall(ctx);\r\n }\r\n ctx.restore();\r\n Debug.clear();\r\n }\r\n\r\n static clear() {\r\n Debug._drawCalls.length = 0;\r\n }\r\n}","import { Color } from '../../Color';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Ray } from '../../Math/ray';\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { Collider } from './Collider';\r\nimport { BodyComponent, Debug, ExcaliburGraphicsContext, Logger } from '../..';\r\nimport { CompositeCollider } from './CompositeCollider';\r\nimport { Shape } from './Shape';\r\nimport { Transform } from '../../Math/transform';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\n\r\nexport interface PolygonColliderOptions {\r\n /**\r\n * Pixel offset relative to a collider's body transform position.\r\n */\r\n offset?: Vector;\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n */\r\n points: Vector[];\r\n\r\n /**\r\n * Suppresses convexity warning\r\n */\r\n suppressConvexWarning?: boolean;\r\n}\r\n\r\n/**\r\n * Polygon collider for detecting collisions\r\n */\r\nexport class PolygonCollider extends Collider {\r\n private _logger = Logger.getInstance();\r\n /**\r\n * Pixel offset relative to a collider's body transform position.\r\n */\r\n public offset: Vector;\r\n\r\n public flagDirty() {\r\n this._localBoundsDirty = true;\r\n this._localSidesDirty = true;\r\n this._transformedPointsDirty = true;\r\n this._sidesDirty = true;\r\n }\r\n\r\n private _points: Vector[];\r\n\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */\r\n public set points(points: Vector[]) {\r\n this._points = points;\r\n this.flagDirty();\r\n }\r\n\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */\r\n public get points(): Vector[] {\r\n return this._points;\r\n }\r\n\r\n private _transform: Transform;\r\n\r\n private _transformedPoints: Vector[] = [];\r\n private _sides: LineSegment[] = [];\r\n private _localSides: LineSegment[] = [];\r\n\r\n constructor(options: PolygonColliderOptions) {\r\n super();\r\n this.offset = options.offset ?? Vector.Zero;\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n this.points = options.points ?? [];\r\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\r\n if (!counterClockwise) {\r\n this.points.reverse();\r\n }\r\n\r\n if (!this.isConvex()) {\r\n if (!options.suppressConvexWarning) {\r\n this._logger.warn(\r\n 'Excalibur only supports convex polygon colliders and will not behave properly.' +\r\n 'Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles');\r\n }\r\n }\r\n\r\n // calculate initial transformation\r\n this._calculateTransformation();\r\n }\r\n\r\n private _isCounterClockwiseWinding(points: Vector[]): boolean {\r\n // https://stackoverflow.com/a/1165943\r\n let sum = 0;\r\n for (let i = 0; i < points.length; i++) {\r\n sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\r\n }\r\n return sum < 0;\r\n }\r\n\r\n /**\r\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\r\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\r\n */\r\n public isConvex(): boolean {\r\n // From SO: https://stackoverflow.com/a/45372025\r\n if (this.points.length < 3) {\r\n return false;\r\n }\r\n let oldPoint = this.points[this.points.length - 2];\r\n let newPoint = this.points[this.points.length - 1];\r\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\r\n let oldDirection = 0;\r\n let orientation = 0;\r\n let angleSum = 0;\r\n for (const [i, point] of this.points.entries()) {\r\n oldPoint = newPoint;\r\n oldDirection = direction;\r\n newPoint = point;\r\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\r\n if (oldPoint.equals(newPoint)) {\r\n return false; // repeat point\r\n }\r\n let angle = direction - oldDirection;\r\n if (angle <= -Math.PI) {\r\n angle += Math.PI * 2;\r\n } else if (angle > Math.PI) {\r\n angle -= Math.PI * 2;\r\n }\r\n if (i === 0) {\r\n if (angle === 0.0) {\r\n return false;\r\n }\r\n orientation = angle > 0 ? 1 : -1;\r\n } else {\r\n if (orientation * angle <= 0) {\r\n return false;\r\n }\r\n }\r\n angleSum += angle;\r\n }\r\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\r\n }\r\n\r\n /**\r\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\r\n */\r\n public tessellate(): CompositeCollider {\r\n const polygons: Vector[][] = [];\r\n for (let i = 1; i < this.points.length - 2; i++) {\r\n polygons.push([this.points[0], this.points[i + 1], this.points[i + 2]]);\r\n }\r\n polygons.push([this.points[0], this.points[1], this.points[2]]);\r\n\r\n return new CompositeCollider(polygons.map(points => Shape.Polygon(points)));\r\n }\r\n\r\n /**\r\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\r\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\r\n */\r\n public triangulate(): CompositeCollider {\r\n // https://www.youtube.com/watch?v=hTJFcHutls8\r\n if (this.points.length < 3) {\r\n throw Error('Invalid polygon');\r\n }\r\n\r\n const triangles: [Vector, Vector, Vector][] = [];\r\n // algorithm likes clockwise\r\n const vertices = [...this.points].reverse();\r\n let vertexCount = vertices.length;\r\n\r\n /**\r\n * Returns the previous index based on the current vertex\r\n */\r\n function getPrevIndex(index: number) {\r\n return index === 0 ? vertexCount - 1 : index - 1;\r\n }\r\n\r\n /**\r\n * Retrieves the next index based on the current vertex\r\n */\r\n function getNextIndex(index: number) {\r\n return index === vertexCount - 1 ? 0 : index + 1;\r\n }\r\n\r\n /**\r\n * Whether or not the angle at this vertex index is convex\r\n */\r\n function isConvex(index: number) {\r\n const prev = getPrevIndex(index);\r\n const next = getNextIndex(index);\r\n\r\n const va = vertices[prev];\r\n const vb = vertices[index];\r\n const vc = vertices[next];\r\n\r\n // Check convexity\r\n const leftArm = va.sub(vb);\r\n const rightArm = vc.sub(vb);\r\n // Positive cross product is convex\r\n if (leftArm.cross(rightArm) < 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n const convexVertices = vertices.map((_,i) => isConvex(i));\r\n\r\n /**\r\n * Quick test for point in triangle\r\n */\r\n function isPointInTriangle(point: Vector, a: Vector, b: Vector, c: Vector) {\r\n const ab = b.sub(a);\r\n const bc = c.sub(b);\r\n const ca = a.sub(c);\r\n\r\n const ap = point.sub(a);\r\n const bp = point.sub(b);\r\n const cp = point.sub(c);\r\n\r\n const cross1 = ab.cross(ap);\r\n const cross2 = bc.cross(bp);\r\n const cross3 = ca.cross(cp);\r\n\r\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Calculate the area of the triangle\r\n */\r\n // function triangleArea(a: Vector, b: Vector, c: Vector) {\r\n // return Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - c.y))/2;\r\n // }\r\n\r\n /**\r\n * Find the next suitable ear tip\r\n */\r\n function findEarTip() {\r\n for (let i = 0; i < vertexCount; i++) {\r\n if (convexVertices[i]) {\r\n\r\n const prev = getPrevIndex(i);\r\n const next = getNextIndex(i);\r\n\r\n const va = vertices[prev];\r\n const vb = vertices[i];\r\n const vc = vertices[next];\r\n\r\n let isEar = true;\r\n // Check that if any vertices are in the triangle a, b, c\r\n for (let j = 0; j < vertexCount; j++) {\r\n // We can skip these verts because they are the triangle we are testing\r\n if (j === i || j === prev || j === next) {\r\n continue;\r\n }\r\n const point = vertices[j];\r\n if (isPointInTriangle(point, va, vb, vc)) {\r\n isEar = false;\r\n break;\r\n }\r\n }\r\n\r\n // Add ear to polygon list and remove from list\r\n if (isEar) {\r\n return i;\r\n }\r\n }\r\n }\r\n\r\n // Fall back to any convex vertex\r\n for (let i = 0; i < vertexCount; i++) {\r\n if (convexVertices[i]) {\r\n return i;\r\n }\r\n }\r\n\r\n // bail and return the first one?\r\n return 0;\r\n }\r\n\r\n /**\r\n * Cut the ear and produce a triangle, update internal state\r\n */\r\n function cutEarTip(index: number) {\r\n const prev = getPrevIndex(index);\r\n const next = getNextIndex(index);\r\n\r\n const va = vertices[prev];\r\n const vb = vertices[index];\r\n const vc = vertices[next];\r\n\r\n // Clockwise winding\r\n // if (triangleArea(va, vb, vc) > 0) {\r\n triangles.push([va, vb, vc]);\r\n // }\r\n vertices.splice(index, 1);\r\n convexVertices.splice(index, 1);\r\n vertexCount--;\r\n }\r\n\r\n // Loop over all the vertices finding ears\r\n while (vertexCount > 3) {\r\n const earIndex = findEarTip();\r\n cutEarTip(earIndex);\r\n\r\n // reclassify vertices\r\n for (let i = 0; i < vertexCount; i++) {\r\n convexVertices[i] = isConvex(i);\r\n }\r\n }\r\n\r\n // Last triangle after the loop\r\n triangles.push([vertices[0], vertices[1], vertices[2]]);\r\n\r\n // FIXME: there is a colinear triangle that sneaks in here sometimes\r\n return new CompositeCollider(\r\n triangles.map(points => Shape.Polygon(points, Vector.Zero, true)));\r\n }\r\n\r\n /**\r\n * Returns a clone of this ConvexPolygon, not associated with any collider\r\n */\r\n public clone(): PolygonCollider {\r\n return new PolygonCollider({\r\n offset: this.offset.clone(),\r\n points: this.points.map((p) => p.clone())\r\n });\r\n }\r\n\r\n /**\r\n * Returns the world position of the collider, which is the current body transform plus any defined offset\r\n */\r\n public get worldPos(): Vector {\r\n if (this._transform) {\r\n return this._transform.pos.add(this.offset);\r\n }\r\n return this.offset;\r\n }\r\n\r\n /**\r\n * Get the center of the collider in world coordinates\r\n */\r\n public get center(): Vector {\r\n return this.bounds.center;\r\n }\r\n\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n private _transformedPointsDirty = true;\r\n /**\r\n * Calculates the underlying transformation from the body relative space to world space\r\n */\r\n private _calculateTransformation() {\r\n const points = this.points;\r\n const len = points.length;\r\n this._transformedPoints.length = 0; // clear out old transform\r\n for (let i = 0; i < len; i++) {\r\n this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\r\n }\r\n }\r\n\r\n /**\r\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\r\n */\r\n public getTransformedPoints(): Vector[] {\r\n if (this._transformedPointsDirty) {\r\n this._calculateTransformation();\r\n this._transformedPointsDirty = false;\r\n }\r\n return this._transformedPoints;\r\n }\r\n\r\n private _sidesDirty = true;\r\n /**\r\n * Gets the sides of the polygon in world space\r\n */\r\n public getSides(): LineSegment[] {\r\n if (this._sidesDirty) {\r\n const lines = [];\r\n const points = this.getTransformedPoints();\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n // This winding is important\r\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\r\n }\r\n this._sides = lines;\r\n this._sidesDirty = false;\r\n }\r\n return this._sides;\r\n }\r\n\r\n private _localSidesDirty = true;\r\n /**\r\n * Returns the local coordinate space sides\r\n */\r\n public getLocalSides(): LineSegment[] {\r\n if (this._localSidesDirty) {\r\n const lines = [];\r\n const points = this.points;\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n // This winding is important\r\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\r\n }\r\n this._localSides = lines;\r\n this._localSidesDirty = false;\r\n }\r\n\r\n return this._localSides;\r\n }\r\n\r\n /**\r\n * Given a direction vector find the world space side that is most in that direction\r\n * @param direction\r\n */\r\n public findSide(direction: Vector): LineSegment {\r\n const sides = this.getSides();\r\n let bestSide = sides[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let side = 0; side < sides.length; side++) {\r\n const currentSide = sides[side];\r\n const sideNormal = currentSide.normal();\r\n const mostDirection = sideNormal.dot(direction);\r\n if (mostDirection > maxDistance) {\r\n bestSide = currentSide;\r\n maxDistance = mostDirection;\r\n }\r\n }\r\n return bestSide;\r\n }\r\n\r\n /**\r\n * Given a direction vector find the local space side that is most in that direction\r\n * @param direction\r\n */\r\n public findLocalSide(direction: Vector): LineSegment {\r\n const sides = this.getLocalSides();\r\n let bestSide = sides[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let side = 0; side < sides.length; side++) {\r\n const currentSide = sides[side];\r\n const sideNormal = currentSide.normal();\r\n const mostDirection = sideNormal.dot(direction);\r\n if (mostDirection > maxDistance) {\r\n bestSide = currentSide;\r\n maxDistance = mostDirection;\r\n }\r\n }\r\n return bestSide;\r\n }\r\n\r\n /**\r\n * Get the axis associated with the convex polygon\r\n */\r\n public get axes(): Vector[] {\r\n const axes: Vector[] = [];\r\n const sides = this.getSides();\r\n for (let i = 0; i < sides.length; i++) {\r\n axes.push(sides[i].normal());\r\n }\r\n return axes;\r\n }\r\n\r\n /**\r\n * Updates the transform for the collision geometry\r\n *\r\n * Collision geometry (points/bounds) will not change until this is called.\r\n * @param transform\r\n */\r\n public update(transform: Transform): void {\r\n if (transform) {\r\n this._transform = transform;\r\n this._transformedPointsDirty = true;\r\n this._sidesDirty = true;\r\n // This change means an update must be performed in order for geometry to update\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collider in world space\r\n */\r\n public contains(point: Vector): boolean {\r\n // Always cast to the right, as long as we cast in a consistent fixed direction we\r\n // will be fine\r\n const testRay = new Ray(point, new Vector(1, 0));\r\n const intersectCount = this.getSides().reduce(function (accum, side) {\r\n if (testRay.intersect(side) >= 0) {\r\n return accum + 1;\r\n }\r\n return accum;\r\n }, 0);\r\n\r\n if (intersectCount % 2 === 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public getClosestLineBetween(collider: Collider): LineSegment {\r\n if (collider instanceof CircleCollider) {\r\n return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\r\n } else if (collider instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\r\n * return null.\r\n * @param collider\r\n */\r\n public collide(collider: Collider): CollisionContact[] {\r\n if (collider instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCirclePolygon(collider, this);\r\n } else if (collider instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollidePolygonPolygon(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollidePolygonEdge(this, collider);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n const pts = this.getTransformedPoints();\r\n let furthestPoint = null;\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let i = 0; i < pts.length; i++) {\r\n const distance = direction.dot(pts[i]);\r\n if (distance > maxDistance) {\r\n maxDistance = distance;\r\n furthestPoint = pts[i];\r\n }\r\n }\r\n return furthestPoint;\r\n }\r\n\r\n /**\r\n * Find the local point on the collider furthest in the direction specified\r\n * @param direction\r\n */\r\n public getFurthestLocalPoint(direction: Vector): Vector {\r\n const pts = this.points;\r\n let furthestPoint = pts[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let i = 0; i < pts.length; i++) {\r\n const distance = direction.dot(pts[i]);\r\n if (distance > maxDistance) {\r\n maxDistance = distance;\r\n furthestPoint = pts[i];\r\n }\r\n }\r\n return furthestPoint;\r\n }\r\n\r\n /**\r\n * Finds the closes face to the point using perpendicular distance\r\n * @param point point to test against polygon\r\n */\r\n public getClosestFace(point: Vector): { distance: Vector; face: LineSegment } {\r\n const sides = this.getSides();\r\n let min = Number.POSITIVE_INFINITY;\r\n let faceIndex = -1;\r\n let distance = -1;\r\n for (let i = 0; i < sides.length; i++) {\r\n const dist = sides[i].distanceToPoint(point);\r\n if (dist < min) {\r\n min = dist;\r\n faceIndex = i;\r\n distance = dist;\r\n }\r\n }\r\n\r\n if (faceIndex !== -1) {\r\n return {\r\n distance: sides[faceIndex].normal().scale(distance),\r\n face: sides[faceIndex]\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the polygon collider in world coordinates\r\n */\r\n public get bounds(): BoundingBox {\r\n return this.localBounds.transform(this._globalMatrix);\r\n }\r\n\r\n private _localBoundsDirty = true;\r\n private _localBounds: BoundingBox;\r\n /**\r\n * Get the axis aligned bounding box for the polygon collider in local coordinates\r\n */\r\n public get localBounds(): BoundingBox {\r\n if (this._localBoundsDirty) {\r\n this._localBounds = BoundingBox.fromPoints(this.points);\r\n this._localBoundsDirty = false;\r\n }\r\n\r\n return this._localBounds;\r\n }\r\n\r\n private _cachedMass: number;\r\n private _cachedInertia: number;\r\n /**\r\n * Get the moment of inertia for an arbitrary polygon\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n if (this._cachedMass === mass && this._cachedInertia) {\r\n return this._cachedInertia;\r\n }\r\n let numerator = 0;\r\n let denominator = 0;\r\n const points = this.points;\r\n for (let i = 0; i < points.length; i++) {\r\n const iplusone = (i + 1) % points.length;\r\n const crossTerm = points[iplusone].cross(points[i]);\r\n numerator +=\r\n crossTerm *\r\n (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\r\n denominator += crossTerm;\r\n }\r\n this._cachedMass = mass;\r\n return this._cachedInertia = (mass / 6) * (numerator / denominator);\r\n }\r\n\r\n /**\r\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity): RayCastHit | null {\r\n // find the minimum contact time greater than 0\r\n // contact times less than 0 are behind the ray and we don't want those\r\n const sides = this.getSides();\r\n const len = sides.length;\r\n let minContactTime = Number.MAX_VALUE;\r\n let contactSide: LineSegment;\r\n let contactIndex = -1;\r\n for (let i = 0; i < len; i++) {\r\n const contactTime = ray.intersect(sides[i]);\r\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\r\n minContactTime = contactTime;\r\n contactSide = sides[i];\r\n contactIndex = i;\r\n }\r\n }\r\n\r\n // contact was found\r\n if (contactIndex >= 0) {\r\n return {\r\n collider: this,\r\n distance: minContactTime,\r\n body: this.owner?.get(BodyComponent),\r\n point: ray.getPoint(minContactTime),\r\n normal: contactSide.normal()\r\n } satisfies RayCastHit;\r\n }\r\n\r\n // no contact found\r\n return null;\r\n }\r\n\r\n /**\r\n * Project the edges of the polygon along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const points = this.getTransformedPoints();\r\n const len = points.length;\r\n let min = Number.MAX_VALUE;\r\n let max = -Number.MAX_VALUE;\r\n for (let i = 0; i < len; i++) {\r\n const scalar = points[i].dot(axis);\r\n min = Math.min(min, scalar);\r\n max = Math.max(max, scalar);\r\n }\r\n\r\n return new Projection(min, max);\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }) {\r\n const points = this.getTransformedPoints();\r\n Debug.drawPolygon(points, { color });\r\n }\r\n}\r\n","import { PolygonCollider } from './PolygonCollider';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { CompositeCollider } from './CompositeCollider';\r\nimport { Logger } from '../..';\r\n\r\n/**\r\n * Excalibur helper for defining colliders quickly\r\n */\r\nexport class Shape {\r\n /**\r\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\r\n * @param width Width of the box\r\n * @param height Height of the box\r\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Box(width: number, height: number, anchor: Vector = Vector.Half, offset: Vector = Vector.Zero): PolygonCollider {\r\n return new PolygonCollider({\r\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\r\n offset: offset\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\r\n *\r\n * PolygonColliders are useful for creating convex polygon shapes\r\n * @param points Points specified in counter clockwise\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Polygon(points: Vector[], offset: Vector = Vector.Zero, suppressConvexWarning = false): PolygonCollider {\r\n return new PolygonCollider({\r\n points: points,\r\n offset: offset,\r\n suppressConvexWarning\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[CircleCollider|circle]] collider\r\n *\r\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\r\n * @param radius Radius of the circle collider\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Circle(radius: number, offset: Vector = Vector.Zero): CircleCollider {\r\n return new CircleCollider({\r\n radius: radius,\r\n offset: offset\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[EdgeCollider|edge]] collider\r\n *\r\n * Edge colliders are useful for floors, walls, and other barriers\r\n * @param begin Beginning of the edge in local coordinates to the collider\r\n * @param end Ending of the edge in local coordinates to the collider\r\n */\r\n static Edge(begin: Vector, end: Vector): EdgeCollider {\r\n return new EdgeCollider({\r\n begin: begin,\r\n end: end\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\r\n *\r\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\r\n * player experience.\r\n * @param width\r\n * @param height\r\n * @param offset Optional offset\r\n */\r\n static Capsule(width: number, height: number, offset = Vector.Zero): CompositeCollider {\r\n const logger = Logger.getInstance();\r\n if (width === height) {\r\n logger.warn('A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider');\r\n }\r\n\r\n const vertical = height >= width;\r\n\r\n if (vertical) {\r\n // height > width, if equal maybe use a circle\r\n const capsule = new CompositeCollider([\r\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\r\n Shape.Box(width, height - width, Vector.Half, offset),\r\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\r\n ]);\r\n return capsule;\r\n } else {\r\n // width > height, if equal maybe use a circle\r\n const capsule = new CompositeCollider([\r\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\r\n Shape.Box(width - height, height, Vector.Half, offset),\r\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\r\n ]);\r\n return capsule;\r\n }\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { CollisionEndEvent, CollisionStartEvent, PostCollisionEvent, PreCollisionEvent } from '../Events';\r\nimport { Observable } from '../Util/Observable';\r\nimport { BoundingBox } from './BoundingBox';\r\nimport { CollisionContact } from './Detection/CollisionContact';\r\nimport { CircleCollider } from './Colliders/CircleCollider';\r\nimport { Collider } from './Colliders/Collider';\r\nimport { CompositeCollider } from './Colliders/CompositeCollider';\r\nimport { PolygonCollider } from './Colliders/PolygonCollider';\r\nimport { EdgeCollider } from './Colliders/EdgeCollider';\r\nimport { Shape } from './Colliders/Shape';\r\nimport { EventEmitter } from '../EventEmitter';\r\nimport { Actor } from '../Actor';\r\n\r\nexport class ColliderComponent extends Component {\r\n\r\n public events = new EventEmitter();\r\n /**\r\n * Observable that notifies when a collider is added to the body\r\n */\r\n public $colliderAdded = new Observable();\r\n\r\n /**\r\n * Observable that notifies when a collider is removed from the body\r\n */\r\n public $colliderRemoved = new Observable();\r\n\r\n constructor(collider?: Collider) {\r\n super();\r\n this.set(collider);\r\n }\r\n\r\n private _collider: Collider;\r\n /**\r\n * Get the current collider geometry\r\n */\r\n public get() {\r\n return this._collider;\r\n }\r\n\r\n /**\r\n * Set the collider geometry\r\n * @param collider\r\n * @returns the collider you set\r\n */\r\n public set(collider: T): T {\r\n this.clear();\r\n if (collider) {\r\n this._collider = collider;\r\n this._collider.owner = this.owner;\r\n collider.events.pipe(this.events);\r\n this.$colliderAdded.notifyAll(collider);\r\n this.update();\r\n }\r\n return collider;\r\n }\r\n\r\n private _collidersToRemove: Collider[] = [];\r\n /**\r\n * Remove collider geometry from collider component\r\n */\r\n public clear() {\r\n if (this._collider) {\r\n this._collidersToRemove.push(this._collider);\r\n this._collider = null;\r\n }\r\n }\r\n\r\n public processColliderRemoval() {\r\n for (const collider of this._collidersToRemove) {\r\n collider.events.unpipe(this.events);\r\n this.$colliderRemoved.notifyAll(collider);\r\n collider.owner = null;\r\n }\r\n }\r\n\r\n public clone(): ColliderComponent {\r\n const clone = new ColliderComponent(this._collider.clone());\r\n\r\n return clone;\r\n }\r\n\r\n /**\r\n * Return world space bounds\r\n */\r\n public get bounds() {\r\n return this._collider?.bounds ?? new BoundingBox();\r\n }\r\n\r\n /**\r\n * Return local space bounds\r\n */\r\n public get localBounds() {\r\n return this._collider?.localBounds ?? new BoundingBox();\r\n }\r\n\r\n /**\r\n * Update the collider's transformed geometry\r\n */\r\n public update() {\r\n const tx = this.owner?.get(TransformComponent);\r\n if (this._collider) {\r\n this._collider.owner = this.owner;\r\n if (tx) {\r\n this._collider.update(tx.get());\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Collide component with another\r\n * @param other\r\n */\r\n collide(other: ColliderComponent): CollisionContact[] {\r\n let colliderA = this._collider;\r\n let colliderB = other._collider;\r\n if (!colliderA || !colliderB) {\r\n return [];\r\n }\r\n\r\n // If we have a composite left hand side :(\r\n // Might bite us, but to avoid updating all the handlers make composite always left side\r\n let flipped = false;\r\n if (colliderB instanceof CompositeCollider) {\r\n colliderA = colliderB;\r\n colliderB = this._collider;\r\n flipped = true;\r\n }\r\n\r\n if (this._collider) {\r\n const contacts = colliderA.collide(colliderB);\r\n if (contacts) {\r\n if (flipped) {\r\n contacts.forEach((contact) => {\r\n contact.mtv = contact.mtv.negate();\r\n contact.normal = contact.normal.negate();\r\n contact.tangent = contact.normal.perpendicular();\r\n contact.colliderA = this._collider;\r\n contact.colliderB = other._collider;\r\n });\r\n }\r\n return contacts;\r\n }\r\n return [];\r\n }\r\n return [];\r\n }\r\n\r\n onAdd(entity: Entity) {\r\n if (this._collider) {\r\n this.update();\r\n }\r\n // Wire up the collider events to the owning entity\r\n this.events.on('precollision', (evt: any) => {\r\n const precollision = evt as PreCollisionEvent;\r\n entity.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(\r\n precollision.target.owner,\r\n precollision.other.owner,\r\n precollision.side,\r\n precollision.intersection,\r\n precollision.contact\r\n )\r\n );\r\n if (entity instanceof Actor) {\r\n entity.onPreCollisionResolve(precollision.target, precollision.other, precollision.side, precollision.contact);\r\n }\r\n });\r\n this.events.on('postcollision', (evt: any) => {\r\n const postcollision = evt as PostCollisionEvent;\r\n entity.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(\r\n postcollision.target.owner,\r\n postcollision.other.owner,\r\n postcollision.side,\r\n postcollision.intersection,\r\n postcollision.contact)\r\n );\r\n if (entity instanceof Actor) {\r\n entity.onPostCollisionResolve(postcollision.target, postcollision.other, postcollision.side, postcollision.contact);\r\n }\r\n });\r\n this.events.on('collisionstart', (evt: any) => {\r\n const start = evt as CollisionStartEvent;\r\n entity.events.emit('collisionstart', new CollisionStartEvent(start.target.owner, start.other.owner, start.side, start.contact));\r\n if (entity instanceof Actor) {\r\n entity.onCollisionStart(start.target, start.other, start.side, start.contact);\r\n }\r\n });\r\n this.events.on('collisionend', (evt: any) => {\r\n const end = evt as CollisionEndEvent;\r\n entity.events.emit('collisionend', new CollisionEndEvent(end.target.owner, end.other.owner, end.side, end.lastContact));\r\n if (entity instanceof Actor) {\r\n entity.onCollisionEnd(end.target, end.other, end.side, end.lastContact);\r\n }\r\n });\r\n }\r\n\r\n onRemove() {\r\n this.events.clear();\r\n this.$colliderRemoved.notifyAll(this._collider);\r\n }\r\n\r\n /**\r\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\r\n *\r\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useBoxCollider(width: number, height: number, anchor: Vector = Vector.Half, center: Vector = Vector.Zero): PolygonCollider {\r\n const collider = Shape.Box(width, height, anchor, center);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\r\n * to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n usePolygonCollider(points: Vector[], center: Vector = Vector.Zero): PolygonCollider {\r\n const poly = Shape.Polygon(points, center);\r\n return (this.set(poly));\r\n }\r\n\r\n /**\r\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useCircleCollider(radius: number, center: Vector = Vector.Zero): CircleCollider {\r\n const collider = Shape.Circle(radius, center);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useEdgeCollider(begin: Vector, end: Vector): EdgeCollider {\r\n const collider = Shape.Edge(begin, end);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\r\n * @param colliders\r\n */\r\n useCompositeCollider(colliders: Collider[]): CompositeCollider {\r\n return (this.set(new CompositeCollider(colliders)));\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { CollisionType } from './CollisionType';\r\nimport { Clonable } from '../Interfaces/Clonable';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { CollisionGroup } from './Group/CollisionGroup';\r\nimport { createId, Id } from '../Id';\r\nimport { clamp } from '../Math/util';\r\nimport { ColliderComponent } from './ColliderComponent';\r\nimport { Transform } from '../Math/transform';\r\nimport { EventEmitter } from '../EventEmitter';\r\nimport { DefaultPhysicsConfig, PhysicsConfig } from './PhysicsConfig';\r\nimport { DeepRequired } from '../Util/Required';\r\n\r\nexport interface BodyComponentOptions {\r\n type?: CollisionType;\r\n group?: CollisionGroup;\r\n useGravity?: boolean;\r\n config?: Pick['bodies']\r\n}\r\n\r\nexport enum DegreeOfFreedom {\r\n Rotation = 'rotation',\r\n X = 'x',\r\n Y = 'y'\r\n}\r\n\r\n/**\r\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\r\n * of physics simulation.\r\n */\r\nexport class BodyComponent extends Component implements Clonable {\r\n public dependencies = [TransformComponent, MotionComponent];\r\n public static _ID = 0;\r\n public readonly id: Id<'body'> = createId('body', BodyComponent._ID++);\r\n public events = new EventEmitter();\r\n\r\n public oldTransform = new Transform();\r\n\r\n /**\r\n * Indicates whether the old transform has been captured at least once for interpolation\r\n * @internal\r\n */\r\n public __oldTransformCaptured: boolean = false;\r\n\r\n /**\r\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\r\n */\r\n public enableFixedUpdateInterpolate = true;\r\n\r\n private _bodyConfig: DeepRequired['bodies']>;\r\n private static _DEFAULT_CONFIG: DeepRequired['bodies']> = {\r\n ...DefaultPhysicsConfig.bodies\r\n };\r\n public wakeThreshold: number;\r\n\r\n constructor(options?: BodyComponentOptions) {\r\n super();\r\n if (options) {\r\n this.collisionType = options.type ?? this.collisionType;\r\n this.group = options.group ?? this.group;\r\n this.useGravity = options.useGravity ?? this.useGravity;\r\n this._bodyConfig = {\r\n ...DefaultPhysicsConfig.bodies,\r\n ...options.config\r\n };\r\n } else {\r\n this._bodyConfig = {\r\n ...DefaultPhysicsConfig.bodies\r\n };\r\n }\r\n this.updatePhysicsConfig(this._bodyConfig);\r\n this._mass = BodyComponent._DEFAULT_CONFIG.defaultMass;\r\n }\r\n\r\n public get matrix() {\r\n return this.transform.get().matrix;\r\n }\r\n\r\n /**\r\n * Called by excalibur to update physics config defaults if they change\r\n * @param config\r\n */\r\n public updatePhysicsConfig(config: DeepRequired['bodies']>) {\r\n this._bodyConfig = {\r\n ...DefaultPhysicsConfig.bodies,\r\n ...config\r\n };\r\n this.canSleep = this._bodyConfig.canSleepByDefault;\r\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\r\n this.wakeThreshold = this._bodyConfig.wakeThreshold;\r\n }\r\n /**\r\n * Called by excalibur to update defaults\r\n * @param config\r\n */\r\n public static updateDefaultPhysicsConfig(config: DeepRequired['bodies']>) {\r\n BodyComponent._DEFAULT_CONFIG = config;\r\n }\r\n\r\n /**\r\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\r\n */\r\n public collisionType: CollisionType = CollisionType.PreventCollision;\r\n\r\n /**\r\n * The collision group for the body's colliders, by default body colliders collide with everything\r\n */\r\n public group: CollisionGroup = CollisionGroup.All;\r\n\r\n /**\r\n * The amount of mass the body has\r\n */\r\n private _mass: number;\r\n public get mass(): number {\r\n return this._mass;\r\n }\r\n\r\n public set mass(newMass: number) {\r\n this._mass = newMass;\r\n this._cachedInertia = undefined;\r\n this._cachedInverseInertia = undefined;\r\n }\r\n\r\n /**\r\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */\r\n public get inverseMass(): number {\r\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\r\n }\r\n\r\n /**\r\n * Amount of \"motion\" the body has before sleeping. If below [[Physics.sleepEpsilon]] it goes to \"sleep\"\r\n */\r\n public sleepMotion: number;\r\n\r\n /**\r\n * Can this body sleep, by default bodies do not sleep\r\n */\r\n public canSleep: boolean;;\r\n\r\n private _sleeping = false;\r\n /**\r\n * Whether this body is sleeping or not\r\n */\r\n public get sleeping(): boolean {\r\n return this._sleeping;\r\n }\r\n\r\n /**\r\n * Set the sleep state of the body\r\n * @param sleeping\r\n */\r\n public setSleeping(sleeping: boolean) {\r\n this._sleeping = sleeping;\r\n if (!sleeping) {\r\n // Give it a kick to keep it from falling asleep immediately\r\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\r\n } else {\r\n this.vel = Vector.Zero;\r\n this.acc = Vector.Zero;\r\n this.angularVelocity = 0;\r\n this.sleepMotion = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\r\n */\r\n public updateMotion() {\r\n if (this._sleeping) {\r\n this.setSleeping(true);\r\n }\r\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\r\n const bias = this._bodyConfig.sleepBias;\r\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\r\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * this._bodyConfig.sleepEpsilon);\r\n if (this.canSleep && this.sleepMotion < this._bodyConfig.sleepEpsilon) {\r\n this.setSleeping(true);\r\n }\r\n }\r\n\r\n private _cachedInertia: number;\r\n /**\r\n * Get the moment of inertia from the [[ColliderComponent]]\r\n */\r\n public get inertia() {\r\n if (this._cachedInertia) {\r\n return this._cachedInertia;\r\n }\r\n\r\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\r\n const collider = this.owner.get(ColliderComponent);\r\n if (collider) {\r\n collider.$colliderAdded.subscribe(() => {\r\n this._cachedInertia = null;\r\n });\r\n collider.$colliderRemoved.subscribe(() => {\r\n this._cachedInertia = null;\r\n });\r\n const maybeCollider = collider.get();\r\n if (maybeCollider) {\r\n return this._cachedInertia = maybeCollider.getInertia(this.mass);\r\n }\r\n }\r\n return 0;\r\n }\r\n\r\n private _cachedInverseInertia: number;\r\n /**\r\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */\r\n public get inverseInertia() {\r\n if (this._cachedInverseInertia) {\r\n return this._cachedInverseInertia;\r\n }\r\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\r\n }\r\n\r\n /**\r\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\r\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\r\n */\r\n public bounciness: number = 0.2;\r\n\r\n /**\r\n * The coefficient of friction on this actor\r\n */\r\n public friction: number = 0.99;\r\n\r\n /**\r\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\r\n */\r\n public useGravity: boolean = true;\r\n\r\n /**\r\n * Degrees of freedom to limit\r\n *\r\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\r\n */\r\n public limitDegreeOfFreedom: DegreeOfFreedom[] = [];\r\n\r\n /**\r\n * Returns if the owner is active\r\n */\r\n public get active() {\r\n return !!this.owner?.active;\r\n }\r\n\r\n /**\r\n * @deprecated Use globalP0s\r\n */\r\n public get center() {\r\n return this.globalPos;\r\n }\r\n\r\n public get transform(): TransformComponent {\r\n return this.owner?.get(TransformComponent);\r\n }\r\n\r\n public get motion(): MotionComponent {\r\n return this.owner?.get(MotionComponent);\r\n }\r\n\r\n public get pos(): Vector {\r\n return this.transform.pos;\r\n }\r\n\r\n public set pos(val: Vector) {\r\n this.transform.pos = val;\r\n }\r\n\r\n /**\r\n * The (x, y) position of the actor this will be in the middle of the actor if the\r\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\r\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\r\n */\r\n public get globalPos(): Vector {\r\n return this.transform.globalPos;\r\n }\r\n\r\n public set globalPos(val: Vector) {\r\n this.transform.globalPos = val;\r\n }\r\n\r\n /**\r\n * The position of the actor last frame (x, y) in pixels\r\n */\r\n public get oldPos(): Vector {\r\n return this.oldTransform.pos;\r\n }\r\n\r\n /**\r\n * The current velocity vector (vx, vy) of the actor in pixels/second\r\n */\r\n public get vel(): Vector {\r\n return this.motion.vel;\r\n }\r\n\r\n public set vel(val: Vector) {\r\n this.motion.vel = val;\r\n }\r\n\r\n /**\r\n * The velocity of the actor last frame (vx, vy) in pixels/second\r\n */\r\n public oldVel: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\r\n * be useful to simulate a gravitational effect.\r\n */\r\n public get acc(): Vector {\r\n return this.motion.acc;\r\n }\r\n\r\n public set acc(val: Vector) {\r\n this.motion.acc = val;\r\n }\r\n\r\n /**\r\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public oldAcc: Vector = Vector.Zero;\r\n\r\n /**\r\n * The current torque applied to the actor\r\n */\r\n public get torque(): number {\r\n return this.motion.torque;\r\n }\r\n\r\n public set torque(val: number) {\r\n this.motion.torque = val;\r\n }\r\n\r\n /**\r\n * Gets/sets the rotation of the body from the last frame.\r\n */\r\n public get oldRotation(): number {\r\n return this.oldTransform.rotation;\r\n }\r\n\r\n /**\r\n * The rotation of the body in radians\r\n */\r\n public get rotation() {\r\n return this.transform.globalRotation;\r\n }\r\n\r\n public set rotation(val: number) {\r\n this.transform.globalRotation = val;\r\n }\r\n\r\n /**\r\n * The scale vector of the actor\r\n */\r\n public get scale(): Vector {\r\n return this.transform.globalScale;\r\n }\r\n\r\n public set scale(val: Vector) {\r\n this.transform.globalScale = val;\r\n }\r\n\r\n /**\r\n * The scale of the actor last frame\r\n */\r\n public get oldScale(): Vector {\r\n return this.oldTransform.scale;\r\n }\r\n\r\n /**\r\n * The scale rate of change of the actor in scale/second\r\n */\r\n public get scaleFactor(): Vector {\r\n return this.motion.scaleFactor;\r\n }\r\n\r\n public set scaleFactor(scaleFactor: Vector) {\r\n this.motion.scaleFactor = scaleFactor;\r\n }\r\n\r\n /**\r\n * Get the angular velocity in radians/second\r\n */\r\n public get angularVelocity(): number {\r\n return this.motion.angularVelocity;\r\n }\r\n\r\n /**\r\n * Set the angular velocity in radians/second\r\n */\r\n public set angularVelocity(value: number) {\r\n this.motion.angularVelocity = value;\r\n }\r\n\r\n /**\r\n * Apply a specific impulse to the body\r\n * @param point\r\n * @param impulse\r\n */\r\n public applyImpulse(point: Vector, impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n const finalImpulse = impulse.scale(this.inverseMass);\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n finalImpulse.x = 0;\r\n }\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n finalImpulse.y = 0;\r\n }\r\n\r\n this.vel.addEqual(finalImpulse);\r\n\r\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n const distanceFromCenter = point.sub(this.globalPos);\r\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\r\n }\r\n }\r\n\r\n /**\r\n * Apply only linear impulse to the body\r\n * @param impulse\r\n */\r\n public applyLinearImpulse(impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n const finalImpulse = impulse.scale(this.inverseMass);\r\n\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n finalImpulse.x = 0;\r\n }\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n finalImpulse.y = 0;\r\n }\r\n\r\n this.vel = this.vel.add(finalImpulse);\r\n }\r\n\r\n /**\r\n * Apply only angular impulse to the body\r\n * @param point\r\n * @param impulse\r\n */\r\n public applyAngularImpulse(point: Vector, impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n const distanceFromCenter = point.sub(this.globalPos);\r\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\r\n }\r\n }\r\n\r\n /**\r\n * Sets the old versions of pos, vel, acc, and scale.\r\n */\r\n public captureOldTransform() {\r\n // Capture old values before integration step updates them\r\n this.__oldTransformCaptured = true;\r\n const tx = this.transform.get();\r\n tx.clone(this.oldTransform);\r\n this.oldTransform.parent = tx.parent; // also grab parent\r\n this.oldVel.setTo(this.vel.x, this.vel.y);\r\n this.oldAcc.setTo(this.acc.x, this.acc.y);\r\n }\r\n\r\n public clone(): BodyComponent {\r\n const component = super.clone() as BodyComponent;\r\n return component;\r\n }\r\n}\r\n","import { Component, ComponentCtor, isComponentCtor } from './Component';\r\n\r\nimport { Observable, Message } from '../Util/Observable';\r\nimport { OnInitialize, OnPreUpdate, OnPostUpdate } from '../Interfaces/LifecycleEvents';\r\nimport { Engine } from '../Engine';\r\nimport { InitializeEvent, PreUpdateEvent, PostUpdateEvent } from '../Events';\r\nimport { KillEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { Scene } from '../Scene';\r\nimport { removeItemFromArray } from '../Util/Util';\r\nimport { MaybeKnownComponent } from './Types';\r\n\r\n/**\r\n * Interface holding an entity component pair\r\n */\r\nexport interface EntityComponent {\r\n component: Component;\r\n entity: Entity;\r\n}\r\n\r\n/**\r\n * AddedComponent message\r\n */\r\nexport class AddedComponent implements Message {\r\n readonly type: 'Component Added' = 'Component Added';\r\n constructor(public data: EntityComponent) { }\r\n}\r\n\r\n/**\r\n * Type guard to know if message is f an Added Component\r\n */\r\nexport function isAddedComponent(x: Message): x is AddedComponent {\r\n return !!x && x.type === 'Component Added';\r\n}\r\n\r\n/**\r\n * RemovedComponent message\r\n */\r\nexport class RemovedComponent implements Message {\r\n readonly type: 'Component Removed' = 'Component Removed';\r\n constructor(public data: EntityComponent) { }\r\n}\r\n\r\n/**\r\n * Type guard to know if message is for a Removed Component\r\n */\r\nexport function isRemovedComponent(x: Message): x is RemovedComponent {\r\n return !!x && x.type === 'Component Removed';\r\n}\r\n\r\n/**\r\n * Built in events supported by all entities\r\n */\r\nexport type EntityEvents = {\r\n 'initialize': InitializeEvent;\r\n 'preupdate': PreUpdateEvent;\r\n 'postupdate': PostUpdateEvent;\r\n 'kill': KillEvent\r\n};\r\n\r\nexport const EntityEvents = {\r\n Initialize: 'initialize',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n Kill: 'kill'\r\n} as const;\r\n\r\nexport interface EntityOptions {\r\n name?: string;\r\n components: TComponents[];\r\n}\r\n\r\n/**\r\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\r\n *\r\n * Entities can be strongly typed with the components they contain\r\n *\r\n * ```typescript\r\n * const entity = new Entity();\r\n * entity.components.a; // Type ComponentA\r\n * entity.components.b; // Type ComponentB\r\n * ```\r\n */\r\nexport class Entity implements OnInitialize, OnPreUpdate, OnPostUpdate {\r\n private static _ID = 0;\r\n /**\r\n * The unique identifier for the entity\r\n */\r\n public id: number = Entity._ID++;\r\n\r\n public name = `Entity#${this.id}`;\r\n\r\n /**\r\n * Listen to or emit events for an entity\r\n */\r\n public events = new EventEmitter();\r\n private _tags = new Set();\r\n public componentAdded$ = new Observable;\r\n public componentRemoved$ = new Observable;\r\n public tagAdded$ = new Observable;\r\n public tagRemoved$ = new Observable;\r\n /**\r\n * Current components on the entity\r\n *\r\n * **Do not modify**\r\n *\r\n * Use addComponent/removeComponent otherwise the ECS will not be notified of changes.\r\n */\r\n public readonly components = new Map();\r\n private _componentsToRemove: ComponentCtor[] = [];\r\n\r\n private _instanceOfComponentCacheDirty = true;\r\n private _instanceOfComponentCache = new Map();\r\n\r\n constructor(options: EntityOptions);\r\n constructor(components?: TKnownComponents[], name?: string);\r\n constructor(componentsOrOptions?: TKnownComponents[] | EntityOptions, name?: string) {\r\n let componentsToAdd!: TKnownComponents[];\r\n let nameToAdd: string | undefined;\r\n if (Array.isArray(componentsOrOptions)) {\r\n componentsToAdd = componentsOrOptions;\r\n nameToAdd = name;\r\n } else if (componentsOrOptions && typeof componentsOrOptions === 'object') {\r\n const { components, name } = componentsOrOptions;\r\n componentsToAdd = components;\r\n nameToAdd = name;\r\n }\r\n if (nameToAdd) {\r\n this.name = nameToAdd;\r\n }\r\n if (componentsToAdd) {\r\n for (const component of componentsToAdd) {\r\n this.addComponent(component);\r\n }\r\n }\r\n // this.addComponent(this.tagsComponent);\r\n }\r\n\r\n /**\r\n * The current scene that the entity is in, if any\r\n */\r\n public scene: Scene | null = null;\r\n\r\n /**\r\n * Whether this entity is active, if set to false it will be reclaimed\r\n */\r\n public active: boolean = true;\r\n\r\n /**\r\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\r\n * If parented it will be removed from the parent when killed.\r\n */\r\n public kill() {\r\n if (this.active) {\r\n this.active = false;\r\n this.unparent();\r\n }\r\n this.emit('kill', new KillEvent(this));\r\n }\r\n\r\n public isKilled() {\r\n return !this.active;\r\n }\r\n\r\n /**\r\n * Specifically get the tags on the entity from [[TagsComponent]]\r\n */\r\n public get tags(): Set {\r\n return this._tags;\r\n }\r\n\r\n /**\r\n * Check if a tag exists on the entity\r\n * @param tag name to check for\r\n */\r\n public hasTag(tag: string): boolean {\r\n return this._tags.has(tag);\r\n }\r\n\r\n /**\r\n * Adds a tag to an entity\r\n * @param tag\r\n */\r\n public addTag(tag: string) {\r\n this._tags.add(tag);\r\n this.tagAdded$.notifyAll(tag);\r\n }\r\n\r\n /**\r\n * Removes a tag on the entity\r\n *\r\n * Removals are deferred until the end of update\r\n * @param tag\r\n */\r\n public removeTag(tag: string) {\r\n this._tags.delete(tag);\r\n this.tagRemoved$.notifyAll(tag);\r\n }\r\n\r\n /**\r\n * The types of the components on the Entity\r\n */\r\n public get types(): ComponentCtor[] {\r\n return Array.from(this.components.keys()) as ComponentCtor[];\r\n }\r\n\r\n /**\r\n * Returns all component instances on entity\r\n */\r\n public getComponents(): Component[] {\r\n return Array.from(this.components.values());\r\n }\r\n\r\n /**\r\n * Verifies that an entity has all the required types\r\n * @param requiredTypes\r\n */\r\n hasAll(requiredTypes: ComponentCtor[]): boolean {\r\n for (let i = 0; i < requiredTypes.length; i++) {\r\n if (!this.components.has(requiredTypes[i])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Verifies that an entity has all the required tags\r\n * @param requiredTags\r\n */\r\n hasAllTags(requiredTags: string[]): boolean {\r\n for (let i = 0; i < requiredTags.length; i++) {\r\n if (!this.tags.has(requiredTags[i])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n private _getCachedInstanceOfType(\r\n type: ComponentCtor): MaybeKnownComponent | undefined {\r\n if (this._instanceOfComponentCacheDirty) {\r\n this._instanceOfComponentCacheDirty = false;\r\n this._instanceOfComponentCache.clear();\r\n }\r\n\r\n if (this._instanceOfComponentCache.has(type)) {\r\n return this._instanceOfComponentCache.get(type) as MaybeKnownComponent;\r\n }\r\n\r\n for (const instance of this.components.values()) {\r\n if (instance instanceof type) {\r\n this._instanceOfComponentCache.set(type, instance);\r\n return instance as MaybeKnownComponent;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n get(type: ComponentCtor): MaybeKnownComponent {\r\n const maybeComponent = this._getCachedInstanceOfType(type);\r\n return maybeComponent ?? this.components.get(type) as MaybeKnownComponent;\r\n }\r\n\r\n private _parent: Entity | null = null;\r\n public get parent(): Entity | null {\r\n return this._parent;\r\n }\r\n\r\n public childrenAdded$ = new Observable();\r\n public childrenRemoved$ = new Observable();\r\n\r\n private _children: Entity[] = [];\r\n /**\r\n * Get the direct children of this entity\r\n */\r\n public get children(): readonly Entity[] {\r\n return this._children;\r\n }\r\n\r\n /**\r\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\r\n */\r\n public unparent() {\r\n if (this._parent) {\r\n this._parent.removeChild(this);\r\n this._parent = null;\r\n }\r\n }\r\n\r\n /**\r\n * Adds an entity to be a child of this entity\r\n * @param entity\r\n */\r\n public addChild(entity: Entity): Entity {\r\n if (entity.parent === null) {\r\n if (this.getAncestors().includes(entity)) {\r\n throw new Error('Cycle detected, cannot add entity');\r\n }\r\n this._children.push(entity);\r\n entity._parent = this;\r\n this.childrenAdded$.notifyAll(entity);\r\n } else {\r\n throw new Error('Entity already has a parent, cannot add without unparenting');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove an entity from children if it exists\r\n * @param entity\r\n */\r\n public removeChild(entity: Entity): Entity {\r\n if (entity.parent === this) {\r\n removeItemFromArray(entity, this._children);\r\n entity._parent = null;\r\n this.childrenRemoved$.notifyAll(entity);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes all children from this entity\r\n */\r\n public removeAllChildren(): Entity {\r\n // Avoid modifying the array issue by walking backwards\r\n for (let i = this.children.length - 1; i >= 0; i--) {\r\n this.removeChild(this.children[i]);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\r\n */\r\n public getAncestors(): Entity[] {\r\n const result: Entity[] = [this];\r\n let current = this.parent;\r\n while (current) {\r\n result.push(current);\r\n current = current.parent;\r\n }\r\n return result.reverse();\r\n }\r\n\r\n /**\r\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\r\n */\r\n public getDescendants(): Entity[] {\r\n let result: Entity[] = [this];\r\n let queue: Entity[] = [this];\r\n while (queue.length > 0) {\r\n const curr = queue.pop();\r\n if (curr) {\r\n queue = queue.concat(curr.children);\r\n result = result.concat(curr.children);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a deep copy of the entity and a copy of all its components\r\n */\r\n public clone(): Entity {\r\n const newEntity = new Entity();\r\n for (const c of this.types) {\r\n const componentInstance = this.get(c);\r\n if (componentInstance) {\r\n newEntity.addComponent(componentInstance.clone());\r\n }\r\n }\r\n for (const child of this.children) {\r\n newEntity.addChild(child.clone());\r\n }\r\n return newEntity;\r\n }\r\n\r\n /**\r\n * Adds a copy of all the components from another template entity as a \"prefab\"\r\n * @param templateEntity Entity to use as a template\r\n * @param force Force component replacement if it already exists on the target entity\r\n */\r\n public addTemplate(templateEntity: Entity, force: boolean = false): Entity {\r\n for (const c of templateEntity.getComponents()) {\r\n this.addComponent(c.clone(), force);\r\n }\r\n for (const child of templateEntity.children) {\r\n this.addChild(child.clone().addTemplate(child));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds a component to the entity\r\n * @param component Component or Entity to add copy of components from\r\n * @param force Optionally overwrite any existing components of the same type\r\n */\r\n public addComponent(component: TComponent, force: boolean = false): Entity {\r\n this._instanceOfComponentCacheDirty = true;\r\n // if component already exists, skip if not forced\r\n if (this.has(component.constructor as ComponentCtor)) {\r\n if (force) {\r\n // Remove existing component type if exists when forced\r\n this.removeComponent(component.constructor as ComponentCtor, true);\r\n } else {\r\n // early exit component exits\r\n return this as Entity;\r\n }\r\n }\r\n\r\n // TODO circular dependencies will be a problem\r\n if (component.dependencies && component.dependencies.length) {\r\n for (const ctor of component.dependencies) {\r\n this.addComponent(new ctor());\r\n }\r\n }\r\n\r\n component.owner = this;\r\n this.components.set(component.constructor, component);\r\n if (component.onAdd) {\r\n component.onAdd(this);\r\n }\r\n\r\n this.componentAdded$.notifyAll(component);\r\n return this as Entity;\r\n }\r\n\r\n /**\r\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\r\n *\r\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\r\n * @param typeOrInstance\r\n * @param force\r\n */\r\n public removeComponent(\r\n typeOrInstance: ComponentCtor | TComponent, force = false): Entity> {\r\n\r\n let type: ComponentCtor;\r\n if (isComponentCtor(typeOrInstance)) {\r\n type = typeOrInstance;\r\n } else {\r\n type = typeOrInstance.constructor as ComponentCtor;\r\n }\r\n\r\n if (force) {\r\n const componentToRemove = this.components.get(type);\r\n if (componentToRemove) {\r\n this.componentRemoved$.notifyAll(componentToRemove);\r\n componentToRemove.owner = undefined;\r\n if (componentToRemove.onRemove) {\r\n componentToRemove.onRemove(this);\r\n }\r\n }\r\n this.components.delete(type); // remove after the notify to preserve typing\r\n this._instanceOfComponentCacheDirty = true;\r\n } else {\r\n this._componentsToRemove.push(type);\r\n }\r\n\r\n return this as any;\r\n }\r\n\r\n public clearComponents() {\r\n const components = this.types;\r\n for (const c of components) {\r\n this.removeComponent(c);\r\n }\r\n }\r\n\r\n /**\r\n * @hidden\r\n * @internal\r\n */\r\n public processComponentRemoval() {\r\n for (const type of this._componentsToRemove) {\r\n this.removeComponent(type, true);\r\n }\r\n this._componentsToRemove.length = 0;\r\n }\r\n\r\n /**\r\n * Check if a component type exists\r\n * @param type\r\n */\r\n public has(type: ComponentCtor): boolean {\r\n return this.components.has(type);\r\n }\r\n\r\n private _isInitialized = false;\r\n\r\n /**\r\n * Gets whether the actor is Initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n /**\r\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n * @internal\r\n */\r\n public _initialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * `onInitialize` is called before the first update of the entity. This method is meant to be\r\n * overridden.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */\r\n public onInitialize(engine: Engine): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an entity is updated.\r\n */\r\n public onPreUpdate(engine: Engine, delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an entity is updated.\r\n */\r\n public onPostUpdate(engine: Engine, delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n *\r\n * Entity update lifecycle, called internally\r\n * @internal\r\n * @param engine\r\n * @param delta\r\n */\r\n public update(engine: Engine, delta: number): void {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n for (const child of this.children) {\r\n child.update(engine, delta);\r\n }\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: EntityEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n if (handler) {\r\n this.events.off(eventName, handler);\r\n } else {\r\n this.events.off(eventName);\r\n }\r\n }\r\n}\r\n","import { Vector, vec } from '../Math/vector';\r\nimport { Graphic } from './Graphic';\r\nimport { HasTick } from './Animation';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/Index';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Material } from './Context/material';\r\nimport { Logger } from '../Util/Log';\r\nimport { WatchVector } from '../Math/watch-vector';\r\n\r\n/**\r\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\r\n * @param graphic\r\n */\r\nexport function hasGraphicsTick(graphic: Graphic): graphic is Graphic & HasTick {\r\n return !!(graphic as unknown as HasTick).tick;\r\n}\r\nexport interface GraphicsShowOptions {\r\n offset?: Vector;\r\n anchor?: Vector;\r\n}\r\n\r\nexport interface GraphicsComponentOptions {\r\n onPostDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n onPreDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n onPreTransformDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n onPostTransformDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n\r\n /**\r\n * Name of current graphic to use\r\n */\r\n current?: string;\r\n\r\n /**\r\n * Optionally set a material to use on the graphic\r\n */\r\n material?: Material;\r\n\r\n /**\r\n * Optionally copy instances of graphics by calling .clone(), you may set this to false to avoid sharing graphics when added to the\r\n * component for performance reasons. By default graphics are not copied and are shared when added to the component.\r\n */\r\n copyGraphics?: boolean;\r\n\r\n /**\r\n * Optional visible flag, if the graphics component is not visible it will not be displayed\r\n */\r\n visible?: boolean;\r\n\r\n /**\r\n * Optional opacity\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * List of graphics and optionally the options per graphic\r\n */\r\n graphics?: { [graphicName: string]: Graphic | { graphic: Graphic, options: GraphicsShowOptions } };\r\n\r\n /**\r\n * Optional offset in absolute pixels to shift all graphics in this component from each graphic's anchor (default is top left corner)\r\n */\r\n offset?: Vector;\r\n\r\n /**\r\n * Optional anchor\r\n */\r\n anchor?: Vector;\r\n}\r\n\r\n/**\r\n * Component to manage drawings, using with the position component\r\n */\r\nexport class GraphicsComponent extends Component {\r\n private _logger = Logger.getInstance();\r\n\r\n private _current: string = 'default';\r\n private _graphics: Record = {};\r\n private _options: Record = {};\r\n\r\n public material: Material | null = null;\r\n\r\n /**\r\n * Draws after the entity transform has been applied, but before graphics component graphics have been drawn\r\n */\r\n public onPreDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Draws after the entity transform has been applied, and after graphics component graphics has been drawn\r\n */\r\n public onPostDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Draws before the entity transform has been applied before any any graphics component drawing\r\n */\r\n public onPreTransformDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Draws after the entity transform has been applied, and after all graphics component drawing\r\n */\r\n public onPostTransformDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Sets or gets wether any drawing should be visible in this component\r\n */\r\n public visible: boolean = true;\r\n\r\n /**\r\n * Sets or gets wither all drawings should have an opacity applied\r\n */\r\n public opacity: number = 1;\r\n\r\n\r\n private _offset: Vector = Vector.Zero;\r\n\r\n /**\r\n * Offset to apply to graphics by default\r\n */\r\n public get offset(): Vector {\r\n return new WatchVector(this._offset, () => {\r\n this.recalculateBounds();\r\n });\r\n }\r\n public set offset(value: Vector) {\r\n this._offset = value;\r\n this.recalculateBounds();\r\n }\r\n\r\n private _anchor: Vector = Vector.Half;\r\n\r\n /**\r\n * Anchor to apply to graphics by default\r\n */\r\n public get anchor(): Vector {\r\n return new WatchVector(this._anchor, () => {\r\n this.recalculateBounds();\r\n });\r\n }\r\n public set anchor(value: Vector) {\r\n this._anchor = value;\r\n this.recalculateBounds();\r\n }\r\n\r\n /**\r\n * Flip all graphics horizontally along the y-axis\r\n */\r\n public flipHorizontal: boolean = false;\r\n\r\n /**\r\n * Flip all graphics vertically along the x-axis\r\n */\r\n public flipVertical: boolean = false;\r\n\r\n /**\r\n * If set to true graphics added to the component will be copied. This can effect performance, but is useful if you don't want\r\n * changes to a graphic to effect all the places it is used.\r\n */\r\n public copyGraphics: boolean = false;\r\n\r\n constructor(options?: GraphicsComponentOptions) {\r\n super();\r\n // Defaults\r\n options = {\r\n visible: this.visible,\r\n graphics: {},\r\n ...options\r\n };\r\n\r\n const {\r\n current,\r\n anchor,\r\n opacity,\r\n visible,\r\n graphics,\r\n offset,\r\n copyGraphics,\r\n onPreDraw,\r\n onPostDraw,\r\n onPreTransformDraw,\r\n onPostTransformDraw\r\n } = options;\r\n\r\n for (const [key, graphicOrOptions] of Object.entries(graphics)) {\r\n if (graphicOrOptions instanceof Graphic) {\r\n this._graphics[key] = graphicOrOptions;\r\n } else {\r\n this._graphics[key] = graphicOrOptions.graphic;\r\n this._options[key] = graphicOrOptions.options;\r\n }\r\n }\r\n\r\n this.offset = offset ?? this.offset;\r\n this.opacity = opacity ?? this.opacity;\r\n this.anchor = anchor ?? this.anchor;\r\n this.copyGraphics = copyGraphics ?? this.copyGraphics;\r\n this.onPreDraw = onPreDraw ?? this.onPreDraw;\r\n this.onPostDraw = onPostDraw ?? this.onPostDraw;\r\n this.onPreDraw = onPreTransformDraw ?? this.onPreTransformDraw;\r\n this.onPostTransformDraw = onPostTransformDraw ?? this.onPostTransformDraw;\r\n this.visible = !!visible;\r\n this._current = current ?? this._current;\r\n if (current && this._graphics[current]) {\r\n this.use(current);\r\n }\r\n }\r\n\r\n public getGraphic(name: string): Graphic | undefined {\r\n return this._graphics[name];\r\n }\r\n public getOptions(name: string): GraphicsShowOptions | undefined {\r\n return this._options[name];\r\n }\r\n\r\n /**\r\n * Get registered graphics names\r\n */\r\n public getNames(): string[] {\r\n return Object.keys(this._graphics);\r\n }\r\n\r\n /**\r\n * Returns the currently displayed graphic\r\n */\r\n public get current(): Graphic | undefined {\r\n return this._graphics[this._current];\r\n }\r\n\r\n /**\r\n * Returns the currently displayed graphic offsets\r\n */\r\n public get currentOptions(): GraphicsShowOptions | undefined {\r\n return this._options[this._current];\r\n }\r\n\r\n /**\r\n * Returns all graphics associated with this component\r\n */\r\n public get graphics(): { [graphicName: string]: Graphic } {\r\n return this._graphics;\r\n }\r\n\r\n /**\r\n * Returns all graphics options associated with this component\r\n */\r\n public get options(): { [graphicName: string]: GraphicsShowOptions } {\r\n return this._options;\r\n }\r\n\r\n /**\r\n * Adds a named graphic to this component, if the name is \"default\" or not specified, it will be shown by default without needing to call\r\n * @param graphic\r\n */\r\n public add(graphic: Graphic, options?: GraphicsShowOptions): Graphic;\r\n public add(name: string, graphic: Graphic, options?: GraphicsShowOptions): Graphic;\r\n public add(nameOrGraphic: string | Graphic, graphicOrOptions?: Graphic | GraphicsShowOptions, options?: GraphicsShowOptions): Graphic {\r\n let name = 'default';\r\n let graphicToSet: Graphic = null;\r\n let optionsToSet: GraphicsShowOptions | undefined = undefined;\r\n if (typeof nameOrGraphic === 'string' && graphicOrOptions instanceof Graphic) {\r\n name = nameOrGraphic;\r\n graphicToSet = graphicOrOptions;\r\n optionsToSet = options;\r\n }\r\n if (nameOrGraphic instanceof Graphic && !(graphicOrOptions instanceof Graphic)) {\r\n graphicToSet = nameOrGraphic;\r\n optionsToSet = graphicOrOptions;\r\n }\r\n\r\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\r\n this._options[name] = this.copyGraphics ? {...optionsToSet} : optionsToSet;\r\n if (name === 'default') {\r\n this.use('default');\r\n }\r\n return graphicToSet;\r\n }\r\n\r\n /**\r\n * Removes a registered graphic, if the removed graphic is the current it will switch to the default\r\n * @param name\r\n */\r\n public remove(name: string) {\r\n delete this._graphics[name];\r\n delete this._options[name];\r\n if (this._current === name) {\r\n this._current = 'default';\r\n this.recalculateBounds();\r\n }\r\n }\r\n\r\n /**\r\n * Shows a graphic, will be removed\r\n * @param nameOrGraphic\r\n * @param options\r\n * @deprecated will be removed in v0.30.0, use `graphics.use(...)`\r\n */\r\n public show(nameOrGraphic: string | T, options?: GraphicsShowOptions): T {\r\n return this.use(nameOrGraphic, options);\r\n }\r\n\r\n /**\r\n * Use a graphic only, will set the default graphic. Returns the new [[Graphic]]\r\n *\r\n * Optionally override the stored options\r\n * @param nameOrGraphic\r\n * @param options\r\n */\r\n public use(nameOrGraphic: string | T, options?: GraphicsShowOptions): T {\r\n if (nameOrGraphic instanceof Graphic) {\r\n let graphic = nameOrGraphic as Graphic;\r\n if (this.copyGraphics) {\r\n graphic = nameOrGraphic.clone();\r\n }\r\n this._current = 'default';\r\n this._graphics[this._current] = graphic;\r\n this._options[this._current] = options;\r\n } else {\r\n this._current = nameOrGraphic;\r\n this._options[this._current] = options;\r\n if (!(this._current in this._graphics)) {\r\n this._logger.warn(\r\n `Graphic ${this._current} is not registered with the graphics component owned by ${this.owner?.name}. Nothing will be drawn.`);\r\n }\r\n }\r\n this.recalculateBounds();\r\n return this.current as T;\r\n }\r\n\r\n /**\r\n * Hide currently shown graphic\r\n */\r\n public hide(): void {\r\n this._current = 'ex.none';\r\n }\r\n\r\n private _localBounds: BoundingBox = null;\r\n public set localBounds(bounds: BoundingBox) {\r\n this._localBounds = bounds;\r\n }\r\n\r\n public recalculateBounds() {\r\n let bb = new BoundingBox();\r\n const graphic = this._graphics[this._current];\r\n const options = this._options[this._current];\r\n\r\n if (!graphic) {\r\n this._localBounds = bb;\r\n return;\r\n }\r\n\r\n let anchor = this.anchor;\r\n let offset = this.offset;\r\n if (options?.anchor) {\r\n anchor = options.anchor;\r\n }\r\n if (options?.offset) {\r\n offset = options.offset;\r\n }\r\n const bounds = graphic.localBounds;\r\n const offsetX = -bounds.width * anchor.x + offset.x;\r\n const offsetY = -bounds.height * anchor.y + offset.y;\r\n bb = graphic?.localBounds.translate(vec(offsetX, offsetY)).combine(bb);\r\n this._localBounds = bb;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) {\r\n this.recalculateBounds();\r\n }\r\n return this._localBounds;\r\n }\r\n\r\n /**\r\n * Update underlying graphics if necessary, called internally\r\n * @param elapsed\r\n * @internal\r\n */\r\n public update(elapsed: number, idempotencyToken: number = 0) {\r\n const graphic = this.current;\r\n if (graphic && hasGraphicsTick(graphic)) {\r\n graphic.tick(elapsed, idempotencyToken);\r\n }\r\n }\r\n\r\n\r\n public clone(): GraphicsComponent {\r\n const graphics = new GraphicsComponent();\r\n graphics._graphics = { ...this._graphics };\r\n graphics._options = {... this._options};\r\n graphics.offset = this.offset.clone();\r\n graphics.opacity = this.opacity;\r\n graphics.anchor = this.anchor.clone();\r\n graphics.copyGraphics = this.copyGraphics;\r\n graphics.onPreDraw = this.onPreDraw;\r\n graphics.onPostDraw = this.onPostDraw;\r\n graphics.visible = this.visible;\r\n\r\n return graphics;\r\n }\r\n}\r\n","import { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface RectangleOptions {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/**\r\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\r\n */\r\nexport class Rectangle extends Raster {\r\n constructor(options: RasterOptions & RectangleOptions) {\r\n super(options);\r\n this.width = options.width;\r\n this.height = options.height;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Rectangle {\r\n return new Rectangle({\r\n width: this.width,\r\n height: this.height,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.color) {\r\n ctx.fillRect(0, 0, this.width, this.height);\r\n }\r\n if (this.strokeColor) {\r\n ctx.strokeRect(0, 0, this.width, this.height);\r\n }\r\n }\r\n}\r\n","import { ImageFiltering } from './Filtering';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface CircleOptions {\r\n radius: number;\r\n}\r\n\r\n/**\r\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Circles default to [[ImageFiltering.Blended]]\r\n */\r\nexport class Circle extends Raster {\r\n private _radius: number = 0;\r\n public get radius() {\r\n return this._radius;\r\n }\r\n public set radius(value: number) {\r\n this._radius = value;\r\n this.width = this._radius * 2;\r\n this.height = this._radius * 2;\r\n this.flagDirty();\r\n }\r\n constructor(options: RasterOptions & CircleOptions) {\r\n super(options);\r\n const lineWidth = options.lineWidth ?? (options.strokeColor ? 1 : 0); // default lineWidth in canvas is 1px\r\n this.padding = options.padding ?? 2 + (lineWidth / 2); // default 2 padding for circles looks nice\r\n this.radius = options.radius;\r\n this.filtering = options.filtering ?? ImageFiltering.Blended;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Circle {\r\n return new Circle({\r\n radius: this.radius,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.radius > 0) {\r\n ctx.beginPath();\r\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\r\n\r\n if (this.color) {\r\n ctx.fill();\r\n }\r\n\r\n if (this.strokeColor) {\r\n ctx.stroke();\r\n }\r\n }\r\n }\r\n}\r\n","import { Component } from '../EntityComponentSystem/Component';\r\n\r\n/**\r\n * Add this component to optionally configure how the pointer\r\n * system detects pointer events.\r\n *\r\n * By default the collider shape is used and graphics bounds is not.\r\n *\r\n * If both collider shape and graphics bounds are enabled it will fire events if either or\r\n * are intersecting the pointer.\r\n */\r\nexport class PointerComponent extends Component {\r\n /**\r\n * Use any existing Collider component geometry for pointer events. This is useful if you want\r\n * user pointer events only to trigger on the same collision geometry used in the collider component\r\n * for collision resolution. Default is `true`.\r\n */\r\n public useColliderShape = true;\r\n /**\r\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\r\n * bounds around the graphic to trigger pointer events. Default is `true`.\r\n */\r\n public useGraphicsBounds = true;\r\n}","import { Vector } from '../Math/vector';\r\n\r\n/**\r\n * A definition of an EasingFunction. See [[EasingFunctions]].\r\n */\r\n// tslint:disable-next-line\r\nexport interface EasingFunction {\r\n (currentTime: number, startValue: number, endValue: number, duration: number): number;\r\n}\r\n\r\n/**\r\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\r\n * Given a time, the function will return a value from positive startValue to positive endValue.\r\n *\r\n * ```js\r\n * function Linear (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInQuad (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutQuad (t) {\r\n * return t * (2 - t);\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutQuad (t) {\r\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInCubic (t) {\r\n * return t * t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutCubic (t) {\r\n * return (--t) * t * t + 1;\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutCubic (t) {\r\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\r\n * }\r\n * ```\r\n */\r\nexport class EasingFunctions {\r\n public static CreateReversibleEasingFunction(easing: EasingFunction) {\r\n return (time: number, start: number, end: number, duration: number) => {\r\n if (end < start) {\r\n return start - (easing(time, end, start, duration) - end);\r\n } else {\r\n return easing(time, start, end, duration);\r\n }\r\n };\r\n }\r\n\r\n public static CreateVectorEasingFunction(easing: EasingFunction) {\r\n return (time: number, start: Vector, end: Vector, duration: number) => {\r\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\r\n };\r\n }\r\n\r\n public static Linear: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n return (endValue * currentTime) / duration + startValue;\r\n }\r\n );\r\n\r\n public static EaseInQuad = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n\r\n return endValue * currentTime * currentTime + startValue;\r\n }\r\n );\r\n\r\n public static EaseOutQuad: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return -endValue * currentTime * (currentTime - 2) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInOutQuad: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration / 2;\r\n\r\n if (currentTime < 1) {\r\n return (endValue / 2) * currentTime * currentTime + startValue;\r\n }\r\n currentTime--;\r\n\r\n return (-endValue / 2) * (currentTime * (currentTime - 2) - 1) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return endValue * currentTime * currentTime * currentTime + startValue;\r\n }\r\n );\r\n\r\n public static EaseOutCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n currentTime--;\r\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInOutCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration / 2;\r\n if (currentTime < 1) {\r\n return (endValue / 2) * currentTime * currentTime * currentTime + startValue;\r\n }\r\n currentTime -= 2;\r\n return (endValue / 2) * (currentTime * currentTime * currentTime + 2) + startValue;\r\n }\r\n );\r\n}\r\n","import { ActionCompleteEvent, ActionStartEvent } from '../Events';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Action } from './Action';\r\n\r\n/**\r\n * Action Queues represent an ordered sequence of actions\r\n *\r\n * Action queues are part of the [[ActionContext|Action API]] and\r\n * store the list of actions to be executed for an [[Actor]].\r\n *\r\n * Actors implement [[Actor.actions]] which can be manipulated by\r\n * advanced users to adjust the actions currently being executed in the\r\n * queue.\r\n */\r\nexport class ActionQueue {\r\n private _entity: Entity;\r\n private _actions: Action[] = [];\r\n private _currentAction: Action | null = null;\r\n private _completedActions: Action[] = [];\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n }\r\n\r\n /**\r\n * Add an action to the sequence\r\n * @param action\r\n */\r\n public add(action: Action) {\r\n this._actions.push(action);\r\n }\r\n\r\n /**\r\n * Remove an action by reference from the sequence\r\n * @param action\r\n */\r\n public remove(action: Action) {\r\n const index = this._actions.indexOf(action);\r\n this._actions.splice(index, 1);\r\n }\r\n\r\n /**\r\n * Removes all actions from this sequence\r\n */\r\n public clearActions(): void {\r\n this._actions.length = 0;\r\n this._completedActions.length = 0;\r\n if (this._currentAction) {\r\n this._currentAction.stop();\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @returns The total list of actions in this sequence complete or not\r\n */\r\n public getActions(): Action[] {\r\n return this._actions.concat(this._completedActions);\r\n }\r\n\r\n /**\r\n *\r\n * @returns `true` if there are more actions to process in the sequence\r\n */\r\n public hasNext(): boolean {\r\n return this._actions.length > 0;\r\n }\r\n\r\n /**\r\n * @returns `true` if the current sequence of actions is done\r\n */\r\n public isComplete(): boolean {\r\n return this._actions.length === 0;\r\n }\r\n\r\n /**\r\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\r\n */\r\n public reset(): void {\r\n this._actions = this.getActions();\r\n\r\n const len = this._actions.length;\r\n for (let i = 0; i < len; i++) {\r\n this._actions[i].reset();\r\n }\r\n this._completedActions = [];\r\n }\r\n\r\n /**\r\n * Update the queue which updates actions and handles completing actions\r\n * @param elapsedMs\r\n */\r\n public update(elapsedMs: number) {\r\n if (this._actions.length > 0) {\r\n if (this._currentAction !== this._actions[0]) {\r\n this._currentAction = this._actions[0];\r\n this._entity.emit('actionstart', new ActionStartEvent(this._currentAction, this._entity));\r\n }\r\n\r\n this._currentAction.update(elapsedMs);\r\n\r\n if (this._currentAction.isComplete(this._entity)) {\r\n this._entity.emit('actioncomplete', new ActionCompleteEvent(this._currentAction, this._entity));\r\n const complete = this._actions.shift();\r\n if (complete) {\r\n this._completedActions.push(complete);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\nexport class Repeat implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _repeat: number;\r\n private _originalRepeat: number;\r\n private _stopped: boolean = false;\r\n private _repeatContext: ActionContext;\r\n private _repeatBuilder: (repeatContext: ActionContext) => any;\r\n constructor(entity: Entity, repeatBuilder: (repeatContext: ActionContext) => any, repeat: number) {\r\n this._repeatBuilder = repeatBuilder;\r\n this._repeatContext = new ActionContext(entity);\r\n this._actionQueue = this._repeatContext.getQueue();\r\n\r\n this._repeat = repeat;\r\n this._originalRepeat = repeat;\r\n\r\n this._repeatBuilder(this._repeatContext);\r\n this._repeat--; // current execution is the first repeat\r\n }\r\n\r\n public update(delta: number): void {\r\n if (this._actionQueue.isComplete()) {\r\n this._actionQueue.clearActions();\r\n this._repeatBuilder(this._repeatContext);\r\n this._repeat--;\r\n }\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || (this._repeat <= 0 && this._actionQueue.isComplete());\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._repeat = this._originalRepeat;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\n/**\r\n * RepeatForever Action implementation, it is recommended you use the fluent action\r\n * context API.\r\n *\r\n *\r\n */\r\nexport class RepeatForever implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _stopped: boolean = false;\r\n private _repeatContext: ActionContext;\r\n private _repeatBuilder: (repeatContext: ActionContext) => any;\r\n constructor(entity: Entity, repeatBuilder: (repeatContext: ActionContext) => any) {\r\n this._repeatBuilder = repeatBuilder;\r\n this._repeatContext = new ActionContext(entity);\r\n this._actionQueue = this._repeatContext.getQueue();\r\n\r\n this._repeatBuilder(this._repeatContext);\r\n }\r\n\r\n public update(delta: number): void {\r\n if (this._stopped) {\r\n return;\r\n }\r\n\r\n if (this._actionQueue.isComplete()) {\r\n this._actionQueue.clearActions();\r\n this._repeatBuilder(this._repeatContext);\r\n }\r\n\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n this._actionQueue.clearActions();\r\n }\r\n\r\n public reset(): void {\r\n return;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Action } from '../Action';\r\n\r\nexport class MoveBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _entity: Entity;\r\n public x: number;\r\n public y: number;\r\n private _distance: number;\r\n private _speed: number;\r\n\r\n private _start: Vector;\r\n private _offset: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, offsetX: number, offsetY: number, speed: number) {\r\n this._entity = entity;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._speed = speed;\r\n this._offset = new Vector(offsetX, offsetY);\r\n if (speed <= 0) {\r\n Logger.getInstance().error('Attempted to moveBy with speed less than or equal to zero : ' + speed);\r\n throw new Error('Speed must be greater than 0 pixels per second');\r\n }\r\n }\r\n\r\n public update(_delta: number) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = this._start.add(this._offset);\r\n this._distance = this._offset.size;\r\n this._dir = this._end.sub(this._start).normalize();\r\n }\r\n\r\n if (this.isComplete(this._entity)) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n } else {\r\n this._motion.vel = this._dir.scale(this._speed);\r\n }\r\n }\r\n\r\n public isComplete(entity: Entity): boolean {\r\n const tx = entity.get(TransformComponent);\r\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class MoveTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _distance: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(public entity: Entity, destx: number, desty: number, speed: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._end = new Vector(destx, desty);\r\n this._speed = speed;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._distance = this._start.distance(this._end);\r\n this._dir = this._end.sub(this._start).normalize();\r\n }\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n\r\n if (this.isComplete(this.entity)) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public isComplete(entity: Entity): boolean {\r\n const tx = entity.get(TransformComponent);\r\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","/**\r\n * An enum that describes the strategies that rotation actions can use\r\n */\r\nexport enum RotationType {\r\n /**\r\n * Rotation via `ShortestPath` will use the smallest angle\r\n * between the starting and ending points. This strategy is the default behavior.\r\n */\r\n ShortestPath = 0,\r\n /**\r\n * Rotation via `LongestPath` will use the largest angle\r\n * between the starting and ending points.\r\n */\r\n LongestPath = 1,\r\n /**\r\n * Rotation via `Clockwise` will travel in a clockwise direction,\r\n * regardless of the starting and ending points.\r\n */\r\n Clockwise = 2,\r\n /**\r\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\r\n * regardless of the starting and ending points.\r\n */\r\n CounterClockwise = 3\r\n}\r\n","import { Action } from '../Action';\r\nimport { RotationType } from '../RotationType';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { TwoPI } from '../../Math/util';\r\n\r\nexport class RotateTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: number;\r\n private _end: number;\r\n private _speed: number;\r\n private _rotationType: RotationType;\r\n private _direction: number;\r\n private _distance: number;\r\n private _shortDistance: number;\r\n private _longDistance: number;\r\n private _shortestPathIsPositive: boolean;\r\n private _currentNonCannonAngle: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, angleRadians: number, speed: number, rotationType?: RotationType) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._end = angleRadians;\r\n this._speed = speed;\r\n this._rotationType = rotationType || RotationType.ShortestPath;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = this._tx.rotation;\r\n this._currentNonCannonAngle = this._tx.rotation;\r\n const distance1 = Math.abs(this._end - this._start);\r\n const distance2 = TwoPI - distance1;\r\n if (distance1 > distance2) {\r\n this._shortDistance = distance2;\r\n this._longDistance = distance1;\r\n } else {\r\n this._shortDistance = distance1;\r\n this._longDistance = distance2;\r\n }\r\n\r\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\r\n\r\n switch (this._rotationType) {\r\n case RotationType.ShortestPath:\r\n this._distance = this._shortDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = 1;\r\n } else {\r\n this._direction = -1;\r\n }\r\n break;\r\n case RotationType.LongestPath:\r\n this._distance = this._longDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = -1;\r\n } else {\r\n this._direction = 1;\r\n }\r\n break;\r\n case RotationType.Clockwise:\r\n this._direction = 1;\r\n if (this._shortestPathIsPositive) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n case RotationType.CounterClockwise:\r\n this._direction = -1;\r\n if (!this._shortestPathIsPositive) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n this._motion.angularVelocity = this._direction * this._speed;\r\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\r\n\r\n if (this.isComplete()) {\r\n this._tx.rotation = this._end;\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\r\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\r\n }\r\n\r\n public stop(): void {\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\nimport { RotationType } from '../RotationType';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { TwoPI } from '../../Math/util';\r\n\r\nexport class RotateBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: number;\r\n private _end: number;\r\n private _speed: number;\r\n private _offset: number;\r\n\r\n private _rotationType: RotationType;\r\n private _direction: number;\r\n private _distance: number;\r\n private _shortDistance: number;\r\n private _longDistance: number;\r\n private _shortestPathIsPositive: boolean;\r\n private _currentNonCannonAngle: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, angleRadiansOffset: number, speed: number, rotationType?: RotationType) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._speed = speed;\r\n this._offset = angleRadiansOffset;\r\n this._rotationType = rotationType || RotationType.ShortestPath;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = this._tx.rotation;\r\n this._currentNonCannonAngle = this._tx.rotation;\r\n this._end = this._start + this._offset;\r\n\r\n const distance1 = Math.abs(this._end - this._start);\r\n const distance2 = TwoPI - distance1;\r\n if (distance1 > distance2) {\r\n this._shortDistance = distance2;\r\n this._longDistance = distance1;\r\n } else {\r\n this._shortDistance = distance1;\r\n this._longDistance = distance2;\r\n }\r\n\r\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\r\n\r\n switch (this._rotationType) {\r\n case RotationType.ShortestPath:\r\n this._distance = this._shortDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = 1;\r\n } else {\r\n this._direction = -1;\r\n }\r\n break;\r\n case RotationType.LongestPath:\r\n this._distance = this._longDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = -1;\r\n } else {\r\n this._direction = 1;\r\n }\r\n break;\r\n case RotationType.Clockwise:\r\n this._direction = 1;\r\n if (this._shortDistance >= 0) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n case RotationType.CounterClockwise:\r\n this._direction = -1;\r\n if (this._shortDistance <= 0) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n this._motion.angularVelocity = this._direction * this._speed;\r\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\r\n\r\n if (this.isComplete()) {\r\n this._tx.rotation = this._end;\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\r\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\r\n }\r\n\r\n public stop(): void {\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n this._start = undefined;\r\n this._currentNonCannonAngle = undefined;\r\n this._distance = undefined;\r\n }\r\n}\r\n","import { vec } from '../../Math/vector';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Action } from '../Action';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\n\r\nexport class ScaleTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _startX: number;\r\n private _startY: number;\r\n private _endX: number;\r\n private _endY: number;\r\n private _speedX: number;\r\n private _speedY: number;\r\n private _distanceX: number;\r\n private _distanceY: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, scaleX: number, scaleY: number, speedX: number, speedY: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._endX = scaleX;\r\n this._endY = scaleY;\r\n this._speedX = speedX;\r\n this._speedY = speedY;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._startX = this._tx.scale.x;\r\n this._startY = this._tx.scale.y;\r\n this._distanceX = Math.abs(this._endX - this._startX);\r\n this._distanceY = Math.abs(this._endY - this._startY);\r\n }\r\n\r\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\r\n const directionX = this._endY < this._startY ? -1 : 1;\r\n this._motion.scaleFactor.x = this._speedX * directionX;\r\n } else {\r\n this._motion.scaleFactor.x = 0;\r\n }\r\n\r\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\r\n const directionY = this._endY < this._startY ? -1 : 1;\r\n this._motion.scaleFactor.y = this._speedY * directionY;\r\n } else {\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._tx.scale = vec(this._endX, this._endY);\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return (\r\n this._stopped ||\r\n (Math.abs(this._tx.scale.x - this._startX) >= (this._distanceX - 0.01) &&\r\n Math.abs(this._tx.scale.y - this._startY) >= (this._distanceY - 0.01))\r\n );\r\n }\r\n\r\n public stop(): void {\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Action } from '../Action';\r\n\r\nexport class ScaleBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _startScale: Vector;\r\n private _endScale: Vector;\r\n private _offset: Vector;\r\n private _distanceX: number;\r\n private _distanceY: number;\r\n private _directionX: number;\r\n private _directionY: number;\r\n private _started = false;\r\n private _stopped = false;\r\n private _speedX: number;\r\n private _speedY: number;\r\n constructor(entity: Entity, scaleOffsetX: number, scaleOffsetY: number, speed: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\r\n this._speedX = this._speedY = speed;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._startScale = this._tx.scale.clone();\r\n this._endScale = this._startScale.add(this._offset);\r\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\r\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\r\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\r\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\r\n }\r\n\r\n this._motion.scaleFactor.x = this._speedX * this._directionX;\r\n this._motion.scaleFactor.y = this._speedY * this._directionY;\r\n\r\n if (this.isComplete()) {\r\n this._tx.scale = this._endScale;\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return (\r\n this._stopped ||\r\n (Math.abs(this._tx.scale.x - this._startScale.x) >= (this._distanceX - 0.01) &&\r\n Math.abs(this._tx.scale.y - this._startScale.y) >= (this._distanceY - 0.01))\r\n );\r\n }\r\n\r\n public stop(): void {\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\n\r\nexport class CallMethod implements Action {\r\n private _method: () => any = null;\r\n private _hasBeenCalled: boolean = false;\r\n constructor(method: () => any) {\r\n this._method = method;\r\n }\r\n\r\n public update(_delta: number) {\r\n this._method();\r\n this._hasBeenCalled = true;\r\n }\r\n public isComplete() {\r\n return this._hasBeenCalled;\r\n }\r\n public reset() {\r\n this._hasBeenCalled = false;\r\n }\r\n public stop() {\r\n this._hasBeenCalled = true;\r\n }\r\n}\r\n","import { Entity} from '../../EntityComponentSystem/Entity';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class EaseTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1 * 1000; // 1 second\r\n private _lerpStart: Vector = new Vector(0, 0);\r\n private _lerpEnd: Vector = new Vector(0, 0);\r\n private _initialized: boolean = false;\r\n private _stopped: boolean = false;\r\n constructor(\r\n entity: Entity,\r\n x: number,\r\n y: number,\r\n duration: number,\r\n public easingFcn: (currentTime: number, startValue: number, endValue: number, duration: number) => number\r\n ) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._lerpDuration = duration;\r\n this._lerpEnd = new Vector(x, y);\r\n }\r\n private _initialize() {\r\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._currentLerpTime = 0;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._initialized) {\r\n this._initialize();\r\n this._initialized = true;\r\n }\r\n\r\n // Need to update lerp time first, otherwise the first update will always be zero\r\n this._currentLerpTime += delta;\r\n let newX = this._tx.pos.x;\r\n let newY = this._tx.pos.y;\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n if (this._lerpEnd.x < this._lerpStart.x) {\r\n newX =\r\n this._lerpStart.x -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\r\n } else {\r\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\r\n }\r\n\r\n if (this._lerpEnd.y < this._lerpStart.y) {\r\n newY =\r\n this._lerpStart.y -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\r\n } else {\r\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\r\n }\r\n // Given the lerp position figure out the velocity in pixels per second\r\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\r\n } else {\r\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\r\n this._motion.vel = Vector.Zero;\r\n }\r\n }\r\n public isComplete(): boolean {\r\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\r\n }\r\n\r\n public reset(): void {\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._currentLerpTime = 0;\r\n }\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class EaseBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1 * 1000; // 1 second\r\n private _lerpStart: Vector = new Vector(0, 0);\r\n private _lerpEnd: Vector = new Vector(0, 0);\r\n private _offset: Vector;\r\n private _initialized: boolean = false;\r\n private _stopped: boolean = false;\r\n constructor(\r\n entity: Entity,\r\n offsetX: number,\r\n offsetY: number,\r\n duration: number,\r\n public easingFcn: (currentTime: number, startValue: number, endValue: number, duration: number) => number\r\n ) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._lerpDuration = duration;\r\n this._offset = new Vector(offsetX, offsetY);\r\n }\r\n private _initialize() {\r\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._currentLerpTime = 0;\r\n this._lerpEnd = this._lerpStart.add(this._offset);\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._initialized) {\r\n this._initialize();\r\n this._initialized = true;\r\n }\r\n\r\n // Need to update lerp time first, otherwise the first update will always be zero\r\n this._currentLerpTime += delta;\r\n let newX = this._tx.pos.x;\r\n let newY = this._tx.pos.y;\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n if (this._lerpEnd.x < this._lerpStart.x) {\r\n newX =\r\n this._lerpStart.x -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\r\n } else {\r\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\r\n }\r\n\r\n if (this._lerpEnd.y < this._lerpStart.y) {\r\n newY =\r\n this._lerpStart.y -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\r\n } else {\r\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\r\n }\r\n // Given the lerp position figure out the velocity in pixels per second\r\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\r\n } else {\r\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\r\n this._motion.vel = Vector.Zero;\r\n }\r\n }\r\n public isComplete(): boolean {\r\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\r\n }\r\n\r\n public reset(): void {\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._currentLerpTime = 0;\r\n }\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n}","import { GraphicsComponent } from '../../Graphics/GraphicsComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\n\r\nexport class Blink implements Action {\r\n private _graphics: GraphicsComponent;\r\n private _timeVisible: number = 0;\r\n private _timeNotVisible: number = 0;\r\n private _elapsedTime: number = 0;\r\n private _totalTime: number = 0;\r\n private _duration: number;\r\n private _stopped: boolean = false;\r\n private _started: boolean = false;\r\n constructor(entity: Entity, timeVisible: number, timeNotVisible: number, numBlinks: number = 1) {\r\n this._graphics = entity.get(GraphicsComponent);\r\n this._timeVisible = timeVisible;\r\n this._timeNotVisible = timeNotVisible;\r\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n }\r\n if (!this._graphics) {\r\n return;\r\n }\r\n\r\n this._elapsedTime += delta;\r\n this._totalTime += delta;\r\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\r\n this._graphics.visible = false;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\r\n this._graphics.visible = true;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._graphics.visible = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._totalTime >= this._duration;\r\n }\r\n\r\n public stop(): void {\r\n if (this._graphics) {\r\n this._graphics.visible = true;\r\n }\r\n this._stopped = true;\r\n }\r\n\r\n public reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { GraphicsComponent } from '../../Graphics/GraphicsComponent';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Action } from '../Action';\r\n\r\nexport class Fade implements Action {\r\n private _graphics: GraphicsComponent;\r\n public x: number;\r\n public y: number;\r\n\r\n private _endOpacity: number;\r\n private _speed: number;\r\n private _ogspeed: number;\r\n private _multiplier: number = 1;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, endOpacity: number, speed: number) {\r\n this._graphics = entity.get(GraphicsComponent);\r\n this._endOpacity = endOpacity;\r\n this._speed = this._ogspeed = speed;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._graphics) {\r\n return;\r\n }\r\n\r\n if (!this._started) {\r\n this._started = true;\r\n this._speed = this._ogspeed;\r\n\r\n // determine direction when we start\r\n if (this._endOpacity < this._graphics.opacity) {\r\n this._multiplier = -1;\r\n } else {\r\n this._multiplier = 1;\r\n }\r\n }\r\n\r\n if (this._speed > 0) {\r\n this._graphics.opacity += (this._multiplier *\r\n (Math.abs(this._graphics.opacity - this._endOpacity) * delta)) / this._speed;\r\n }\r\n\r\n this._speed -= delta;\r\n\r\n if (this.isComplete()) {\r\n this._graphics.opacity = this._endOpacity;\r\n }\r\n\r\n Logger.getInstance().debug('[Action fade] Actor opacity:', this._graphics.opacity);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\n\r\nexport class Delay implements Action {\r\n private _elapsedTime: number = 0;\r\n private _delay: number;\r\n private _started: boolean = false;\r\n private _stopped = false;\r\n constructor(delay: number) {\r\n this._delay = delay;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n }\r\n\r\n this._elapsedTime += delta;\r\n }\r\n\r\n isComplete(): boolean {\r\n return this._stopped || this._elapsedTime >= this._delay;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n reset(): void {\r\n this._elapsedTime = 0;\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionsComponent } from '../ActionsComponent';\r\n\r\nexport class Die implements Action {\r\n private _entity: Entity;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n }\r\n\r\n public update(_delta: number): void {\r\n this._entity.get(ActionsComponent).clearActions();\r\n this._entity.kill();\r\n this._stopped = true;\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped;\r\n }\r\n\r\n public stop(): void {\r\n return;\r\n }\r\n\r\n public reset(): void {\r\n return;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class Follow implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _followTx: TransformComponent;\r\n private _followMotion: MotionComponent;\r\n\r\n public x: number;\r\n public y: number;\r\n private _current: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _maximumDistance: number;\r\n private _distanceBetween: number;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, entityToFollow: Entity, followDistance?: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._followTx = entityToFollow.get(TransformComponent);\r\n this._followMotion = entityToFollow.get(MotionComponent);\r\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\r\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\r\n this._speed = 0;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n }\r\n\r\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\r\n if (actorToFollowSpeed !== 0) {\r\n this._speed = actorToFollowSpeed;\r\n }\r\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\r\n\r\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n\r\n if (this._distanceBetween >= this._maximumDistance) {\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n } else {\r\n this._motion.vel = vec(0, 0);\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public isComplete(): boolean {\r\n // the actor following should never stop unless specified to do so\r\n return this._stopped;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class Meet implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _meetTx: TransformComponent;\r\n private _meetMotion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _current: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _distanceBetween: number;\r\n private _started = false;\r\n private _stopped = false;\r\n private _speedWasSpecified = false;\r\n\r\n constructor(actor: Entity, actorToMeet: Entity, speed?: number) {\r\n this._tx = actor.get(TransformComponent);\r\n this._motion = actor.get(MotionComponent);\r\n this._meetTx = actorToMeet.get(TransformComponent);\r\n this._meetMotion = actorToMeet.get(MotionComponent);\r\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\r\n this._speed = speed || 0;\r\n\r\n if (speed !== undefined) {\r\n this._speedWasSpecified = true;\r\n }\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n }\r\n\r\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\r\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) {\r\n this._speed = actorToMeetSpeed;\r\n }\r\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\r\n\r\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n\r\n if (this.isComplete()) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._distanceBetween <= 1;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n this._distanceBetween = undefined;\r\n }\r\n}\r\n","import { RotationType } from './RotationType';\r\n\r\nimport { EasingFunction, EasingFunctions } from '../Util/EasingFunctions';\r\nimport { ActionQueue } from './ActionQueue';\r\nimport { Repeat } from './Action/Repeat';\r\nimport { RepeatForever } from './Action/RepeatForever';\r\nimport { MoveBy } from './Action/MoveBy';\r\nimport { MoveTo } from './Action/MoveTo';\r\nimport { RotateTo } from './Action/RotateTo';\r\nimport { RotateBy } from './Action/RotateBy';\r\nimport { ScaleTo } from './Action/ScaleTo';\r\nimport { ScaleBy } from './Action/ScaleBy';\r\nimport { CallMethod } from './Action/CallMethod';\r\nimport { EaseTo } from './Action/EaseTo';\r\nimport { EaseBy } from './Action/EaseBy';\r\nimport { Blink } from './Action/Blink';\r\nimport { Fade } from './Action/Fade';\r\nimport { Delay } from './Action/Delay';\r\nimport { Die } from './Action/Die';\r\nimport { Follow } from './Action/Follow';\r\nimport { Meet } from './Action/Meet';\r\nimport { Vector } from '../Math/vector';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Action } from './Action';\r\n\r\n/**\r\n * The fluent Action API allows you to perform \"actions\" on\r\n * [[Actor|Actors]] such as following, moving, rotating, and\r\n * more. You can implement your own actions by implementing\r\n * the [[Action]] interface.\r\n */\r\nexport class ActionContext {\r\n private _entity: Entity;\r\n private _queue: ActionQueue;\r\n\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n this._queue = new ActionQueue(entity);\r\n }\r\n\r\n public getQueue(): ActionQueue {\r\n return this._queue;\r\n }\r\n\r\n public update(elapsedMs: number) {\r\n this._queue.update(elapsedMs);\r\n }\r\n\r\n /**\r\n * Clears all queued actions from the Actor\r\n */\r\n public clearActions(): void {\r\n this._queue.clearActions();\r\n }\r\n\r\n public runAction(action: Action) {\r\n action.reset();\r\n this._queue.add(action);\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(pos: Vector, duration: number, easingFcn?: EasingFunction): ActionContext\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(x: number, y: number, duration: number, easingFcn?: EasingFunction): ActionContext\r\n public easeTo(...args: any[]): ActionContext {\r\n let x = 0;\r\n let y = 0;\r\n let duration = 0;\r\n let easingFcn = EasingFunctions.Linear;\r\n if (args[0] instanceof Vector) {\r\n x = args[0].x;\r\n y = args[0].y;\r\n duration = args[1];\r\n easingFcn = args[2] ?? easingFcn;\r\n } else {\r\n x = args[0];\r\n y = args[1];\r\n duration = args[2];\r\n easingFcn = args[3] ?? easingFcn;\r\n }\r\n\r\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor by a specified vector offset relative to the current position given\r\n * a duration and a [[EasingFunction]]. This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset Vector offset relative to the current position\r\n * @param duration The duration in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeBy(offset: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n /**\r\n * This method will move an actor by a specified x and y offset relative to the current position given\r\n * a duration and a [[EasingFunction]]. This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset Vector offset relative to the current position\r\n * @param duration The duration in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeBy(offsetX: number, offsetY: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(...args: any[]): ActionContext {\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n let duration = 0;\r\n let easingFcn = EasingFunctions.Linear;\r\n if (args[0] instanceof Vector) {\r\n offsetX = args[0].x;\r\n offsetY = args[0].y;\r\n duration = args[1];\r\n easingFcn = args[2] ?? easingFcn;\r\n } else {\r\n offsetX = args[0];\r\n offsetY = args[1];\r\n duration = args[2];\r\n easingFcn = args[3] ?? easingFcn;\r\n }\r\n\r\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(pos: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(x: number, y: number, speed: number): ActionContext;\r\n public moveTo(xOrPos: number | Vector, yOrSpeed: number, speedOrUndefined?: number | undefined): ActionContext {\r\n let x = 0;\r\n let y = 0;\r\n let speed = 0;\r\n if (xOrPos instanceof Vector) {\r\n x = xOrPos.x;\r\n y = xOrPos.y;\r\n speed = yOrSpeed;\r\n } else {\r\n x = xOrPos;\r\n y = yOrSpeed;\r\n speed = speedOrUndefined;\r\n }\r\n this._queue.add(new MoveTo(this._entity, x, y, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param xOffset The x offset to apply to this actor\r\n * @param yOffset The y location to move the actor to\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(offset: Vector, speed: number): ActionContext;\r\n public moveBy(xOffset: number, yOffset: number, speed: number): ActionContext;\r\n public moveBy(xOffsetOrVector: number | Vector, yOffsetOrSpeed: number, speedOrUndefined?: number | undefined): ActionContext {\r\n let xOffset = 0;\r\n let yOffset = 0;\r\n let speed = 0;\r\n if (xOffsetOrVector instanceof Vector) {\r\n xOffset = xOffsetOrVector.x;\r\n yOffset = xOffsetOrVector.y;\r\n speed = yOffsetOrSpeed;\r\n } else {\r\n xOffset = xOffsetOrVector;\r\n yOffset = yOffsetOrSpeed;\r\n speed = speedOrUndefined;\r\n }\r\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */\r\n public rotateTo(angleRadians: number, speed: number, rotationType?: RotationType): ActionContext {\r\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */\r\n public rotateBy(angleRadiansOffset: number, speed: number, rotationType?: RotationType): ActionContext {\r\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param size The scale to adjust the actor to over time\r\n * @param speed The speed of scaling specified in magnitude increase per second\r\n */\r\n public scaleTo(size: Vector, speed: Vector): ActionContext;\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param sizeX The scaling factor to apply on X axis\r\n * @param sizeY The scaling factor to apply on Y axis\r\n * @param speedX The speed of scaling specified in magnitude increase per second on X axis\r\n * @param speedY The speed of scaling specified in magnitude increase per second on Y axis\r\n */\r\n public scaleTo(sizeX: number, sizeY: number, speedX: number, speedY: number): ActionContext;\r\n public scaleTo(sizeXOrVector: number | Vector,\r\n sizeYOrSpeed: number | Vector,\r\n speedXOrUndefined?: number | undefined,\r\n speedYOrUndefined?: number | undefined): ActionContext {\r\n\r\n let sizeX = 1;\r\n let sizeY = 1;\r\n let speedX = 0;\r\n let speedY = 0;\r\n\r\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\r\n sizeX = sizeXOrVector.x;\r\n sizeY = sizeXOrVector.y;\r\n\r\n speedX = sizeYOrSpeed.x;\r\n speedY = sizeYOrSpeed.y;\r\n }\r\n if (typeof sizeXOrVector === 'number' && typeof sizeYOrSpeed === 'number') {\r\n sizeX = sizeXOrVector;\r\n sizeY = sizeYOrSpeed;\r\n\r\n speedX = speedXOrUndefined;\r\n speedY = speedYOrUndefined;\r\n }\r\n\r\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param offset The scaling factor to apply to the actor\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param sizeOffsetX The scaling factor to apply on X axis\r\n * @param sizeOffsetY The scaling factor to apply on Y axis\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(sizeOffsetX: number, sizeOffsetY: number, speed: number): ActionContext;\r\n public scaleBy(sizeOffsetXOrVector: number | Vector, sizeOffsetYOrSpeed: number, speed?: number | undefined): ActionContext {\r\n let sizeOffsetX = 1;\r\n let sizeOffsetY = 1;\r\n\r\n if (sizeOffsetXOrVector instanceof Vector) {\r\n sizeOffsetX = sizeOffsetXOrVector.x;\r\n sizeOffsetY = sizeOffsetXOrVector.y;\r\n\r\n speed = sizeOffsetYOrSpeed;\r\n }\r\n if (typeof sizeOffsetXOrVector === 'number' && typeof sizeOffsetYOrSpeed === 'number') {\r\n sizeOffsetX = sizeOffsetXOrVector;\r\n sizeOffsetY = sizeOffsetYOrSpeed;\r\n }\r\n\r\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */\r\n public blink(timeVisible: number, timeNotVisible: number, numBlinks: number = 1): ActionContext {\r\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */\r\n public fade(opacity: number, time: number): ActionContext {\r\n this._queue.add(new Fade(this._entity, opacity, time));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */\r\n public delay(time: number): ActionContext {\r\n this._queue.add(new Delay(time));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */\r\n public die(): ActionContext {\r\n this._queue.add(new Die(this._entity));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */\r\n public callMethod(method: () => any): ActionContext {\r\n this._queue.add(new CallMethod(method));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */\r\n public repeat(repeatBuilder: (repeatContext: ActionContext) => any, times?: number): ActionContext {\r\n if (!times) {\r\n this.repeatForever(repeatBuilder);\r\n return this;\r\n }\r\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */\r\n public repeatForever(repeatBuilder: (repeatContext: ActionContext) => any): ActionContext {\r\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */\r\n public follow(entity: Entity, followDistance?: number): ActionContext {\r\n if (followDistance === undefined) {\r\n this._queue.add(new Follow(this._entity, entity));\r\n } else {\r\n this._queue.add(new Follow(this._entity, entity, followDistance));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */\r\n public meet(entity: Entity, speed?: number): ActionContext {\r\n if (speed === undefined) {\r\n this._queue.add(new Meet(this._entity, entity));\r\n } else {\r\n this._queue.add(new Meet(this._entity, entity, speed));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */\r\n public toPromise(): Promise {\r\n const temp = new Promise((resolve) => {\r\n this._queue.add(\r\n new CallMethod(() => {\r\n resolve();\r\n })\r\n );\r\n });\r\n return temp;\r\n }\r\n}\r\n","import { ActionContext } from './ActionContext';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Actor } from '../Actor';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Vector } from '../Math/vector';\r\nimport { EasingFunction } from '../Util/EasingFunctions';\r\nimport { ActionQueue } from './ActionQueue';\r\nimport { RotationType } from './RotationType';\r\nimport { Action } from './Action';\r\n\r\nexport interface ActionContextMethods extends Pick { };\r\n\r\nexport class ActionsComponent extends Component implements ActionContextMethods {\r\n dependencies = [TransformComponent, MotionComponent];\r\n private _ctx: ActionContext | null = null;\r\n\r\n onAdd(entity: Entity) {\r\n this._ctx = new ActionContext(entity);\r\n }\r\n\r\n onRemove() {\r\n this._ctx = null;\r\n }\r\n\r\n private _getCtx() {\r\n if (!this._ctx) {\r\n throw new Error('Actions component not attached to an entity, no context available');\r\n }\r\n return this._ctx;\r\n }\r\n\r\n /**\r\n * Returns the internal action queue\r\n * @returns action queue\r\n */\r\n public getQueue(): ActionQueue {\r\n if (!this._ctx) {\r\n throw new Error('Actions component not attached to an entity, no queue available');\r\n }\r\n return this._ctx.getQueue();\r\n }\r\n\r\n public runAction(action: Action): ActionContext {\r\n if (!this._ctx) {\r\n throw new Error('Actions component not attached to an entity, cannot run action');\r\n }\r\n return this._ctx.runAction(action);\r\n }\r\n\r\n /**\r\n * Updates the internal action context, performing action and moving through the internal queue\r\n * @param elapsedMs\r\n */\r\n public update(elapsedMs: number): void {\r\n return this._ctx?.update(elapsedMs);\r\n }\r\n\r\n /**\r\n * Clears all queued actions from the Actor\r\n */\r\n public clearActions(): void {\r\n this._ctx?.clearActions();\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunctions]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(pos: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunctions]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(x: number, y: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeTo(...args: any[]): ActionContext {\r\n return this._getCtx().easeTo.apply(this._ctx, args as any);\r\n }\r\n\r\n public easeBy(offset: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(offsetX: number, offsetY: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(...args: any[]): ActionContext {\r\n return this._getCtx().easeBy.apply(this._ctx, args as any);\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(pos: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(x: number, y: number, speed: number): ActionContext;\r\n public moveTo(xOrPos: number | Vector, yOrSpeed: number, speedOrUndefined?: number): ActionContext {\r\n return this._getCtx().moveTo.apply(this._ctx, [xOrPos, yOrSpeed, speedOrUndefined] as any);\r\n }\r\n\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset The (x, y) offset to apply to this actor\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param xOffset The x offset to apply to this actor\r\n * @param yOffset The y location to move the actor to\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(xOffset: number, yOffset: number, speed: number): ActionContext;\r\n public moveBy(xOffsetOrVector: number | Vector, yOffsetOrSpeed: number, speedOrUndefined?: number): ActionContext {\r\n return this._getCtx().moveBy.apply(this._ctx, [xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined] as any);\r\n }\r\n\r\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */\r\n public rotateTo(angleRadians: number, speed: number, rotationType?: RotationType): ActionContext {\r\n return this._getCtx().rotateTo(angleRadians, speed, rotationType);\r\n }\r\n\r\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */\r\n public rotateBy(angleRadiansOffset: number, speed: number, rotationType?: RotationType): ActionContext {\r\n return this._getCtx().rotateBy(angleRadiansOffset, speed, rotationType);\r\n }\r\n\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param size The scale to adjust the actor to over time\r\n * @param speed The speed of scaling specified in magnitude increase per second\r\n */\r\n public scaleTo(size: Vector, speed: Vector): ActionContext;\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param sizeX The scaling factor to apply on X axis\r\n * @param sizeY The scaling factor to apply on Y axis\r\n * @param speedX The speed of scaling specified in magnitude increase per second on X axis\r\n * @param speedY The speed of scaling specified in magnitude increase per second on Y axis\r\n */\r\n public scaleTo(sizeX: number, sizeY: number, speedX: number, speedY: number): ActionContext;\r\n public scaleTo(\r\n sizeXOrVector: number | Vector,\r\n sizeYOrSpeed: number | Vector,\r\n speedXOrUndefined?: number,\r\n speedYOrUndefined?: number): ActionContext {\r\n return this._getCtx().scaleTo.apply(this._ctx, [sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined] as any);\r\n }\r\n\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param offset The scaling factor to apply to the actor\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param sizeOffsetX The scaling factor to apply on X axis\r\n * @param sizeOffsetY The scaling factor to apply on Y axis\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(sizeOffsetX: number, sizeOffsetY: number, speed: number): ActionContext;\r\n public scaleBy(sizeOffsetXOrVector: number | Vector, sizeOffsetYOrSpeed: number, speed?: number): ActionContext {\r\n return this._getCtx().scaleBy.apply(this._ctx, [sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed] as any);\r\n }\r\n\r\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */\r\n public blink(timeVisible: number, timeNotVisible: number, numBlinks?: number): ActionContext {\r\n return this._getCtx().blink(timeVisible, timeNotVisible, numBlinks);\r\n }\r\n\r\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */\r\n public fade(opacity: number, time: number): ActionContext {\r\n return this._getCtx().fade(opacity, time);\r\n }\r\n\r\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */\r\n public delay(time: number): ActionContext {\r\n return this._getCtx().delay(time);\r\n }\r\n\r\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */\r\n public die(): ActionContext {\r\n return this._getCtx().die();\r\n }\r\n\r\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */\r\n public callMethod(method: () => any): ActionContext {\r\n return this._getCtx().callMethod(method);\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */\r\n public repeat(repeatBuilder: (repeatContext: ActionContext) => any, times?: number): ActionContext {\r\n return this._getCtx().repeat(repeatBuilder, times);\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */\r\n public repeatForever(repeatBuilder: (repeatContext: ActionContext) => any): ActionContext {\r\n return this._getCtx().repeatForever(repeatBuilder);\r\n }\r\n\r\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */\r\n public follow(entity: Actor, followDistance?: number): ActionContext {\r\n return this._getCtx().follow(entity, followDistance);\r\n }\r\n\r\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */\r\n public meet(entity: Actor, speed?: number): ActionContext {\r\n return this._getCtx().meet(entity, speed);\r\n }\r\n\r\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */\r\n public toPromise(): Promise {\r\n return this._getCtx().toPromise();\r\n }\r\n}","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\n\r\n/**\r\n * Enum representing the different font size units\r\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\r\n */\r\nexport enum FontUnit {\r\n /**\r\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\r\n */\r\n Em = 'em',\r\n /**\r\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\r\n */\r\n Rem = 'rem',\r\n /**\r\n * Pixel is a unit of length in screen pixels\r\n */\r\n Px = 'px',\r\n /**\r\n * Point is a physical unit length (1/72 of an inch)\r\n */\r\n Pt = 'pt',\r\n /**\r\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\r\n */\r\n Percent = '%'\r\n}\r\n\r\n/**\r\n * Enum representing the different horizontal text alignments\r\n */\r\nexport enum TextAlign {\r\n /**\r\n * The text is left-aligned.\r\n */\r\n Left = 'left',\r\n /**\r\n * The text is right-aligned.\r\n */\r\n Right = 'right',\r\n /**\r\n * The text is centered.\r\n */\r\n Center = 'center',\r\n /**\r\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\r\n * right-aligned for right-to-left locales).\r\n */\r\n Start = 'start',\r\n /**\r\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\r\n * left-aligned for right-to-left locales).\r\n */\r\n End = 'end'\r\n}\r\n\r\n/**\r\n * Enum representing the different baseline text alignments\r\n */\r\nexport enum BaseAlign {\r\n /**\r\n * The text baseline is the top of the em square.\r\n */\r\n Top = 'top',\r\n /**\r\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\r\n * alphabetic.\r\n */\r\n Hanging = 'hanging',\r\n /**\r\n * The text baseline is the middle of the em square.\r\n */\r\n Middle = 'middle',\r\n /**\r\n * The text baseline is the normal alphabetic baseline.\r\n */\r\n Alphabetic = 'alphabetic',\r\n /**\r\n * The text baseline is the ideographic baseline; this is the bottom of\r\n * the body of the characters, if the main body of characters protrudes\r\n * beneath the alphabetic baseline. Currently unsupported; this will\r\n * act like alphabetic.\r\n */\r\n Ideographic = 'ideographic',\r\n /**\r\n * The text baseline is the bottom of the bounding box. This differs\r\n * from the ideographic baseline in that the ideographic baseline\r\n * doesn't consider descenders.\r\n */\r\n Bottom = 'bottom'\r\n}\r\n\r\n/**\r\n * Enum representing the different possible font styles\r\n */\r\nexport enum FontStyle {\r\n Normal = 'normal',\r\n Italic = 'italic',\r\n Oblique = 'oblique'\r\n}\r\n\r\n/**\r\n * Enum representing the text direction, useful for other languages, or writing text in reverse\r\n */\r\nexport enum Direction {\r\n LeftToRight = 'ltr',\r\n RightToLeft = 'rtl'\r\n}\r\n\r\n/**\r\n * Font rendering option\r\n */\r\nexport interface FontOptions {\r\n /**\r\n * Optionally the size of the font in the specified [[FontUnit]] by default 10.\r\n */\r\n size?: number;\r\n /**\r\n * Optionally specify unit to measure fonts in, by default Pixels\r\n */\r\n unit?: FontUnit;\r\n /**\r\n * Optionally specify the font family, by default 'sans-serif'\r\n */\r\n family?: string;\r\n /**\r\n * Optionally specify the font style, by default Normal\r\n */\r\n style?: FontStyle;\r\n /**\r\n * Optionally set whether the font is bold, by default false\r\n */\r\n bold?: boolean;\r\n /**\r\n * Optionally specify the text align, by default Left\r\n */\r\n textAlign?: TextAlign;\r\n /**\r\n * Optionally specify the text base align, by default Alphabetic\r\n */\r\n baseAlign?: BaseAlign;\r\n /**\r\n * Optionally specify the text direction, by default LeftToRight\r\n */\r\n direction?: Direction;\r\n /**\r\n * Optionally override the text line height in pixels, useful for multiline text. If unset will use default.\r\n */\r\n lineHeight?: number | undefined;\r\n /**\r\n * Optionally specify the quality of the text bitmap, it is a multiplier on the size size, by default 2.\r\n * Higher quality text has a higher memory impact\r\n */\r\n quality?: number;\r\n /**\r\n * Optionally specify a text shadow, by default none is specified\r\n */\r\n shadow?: {\r\n blur?: number;\r\n offset?: Vector;\r\n color?: Color;\r\n };\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface FontRenderer {\r\n measureText(text: string): BoundingBox;\r\n render(ex: ExcaliburGraphicsContext, text: string, color: Color, x: number, y: number): void;\r\n}\r\n","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { line } from '../Util/DrawUtil';\r\nimport { ExcaliburGraphicsContextWebGL } from './Context/ExcaliburGraphicsContextWebGL';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Font } from './Font';\r\n\r\nexport class FontTextInstance {\r\n public canvas: HTMLCanvasElement;\r\n public ctx: CanvasRenderingContext2D;\r\n private _textFragments: { x: number; y: number; canvas: HTMLCanvasElement }[] = [];\r\n public dimensions: BoundingBox;\r\n public disposed: boolean = false;\r\n private _lastHashCode: string;\r\n\r\n constructor(public readonly font: Font, public readonly text: string, public readonly color: Color, public readonly maxWidth?: number) {\r\n this.canvas = document.createElement('canvas');\r\n this.ctx = this.canvas.getContext('2d');\r\n this.dimensions = this.measureText(text);\r\n this._setDimension(this.dimensions, this.ctx);\r\n this._lastHashCode = this.getHashCode();\r\n }\r\n\r\n measureText(text: string, maxWidth?: number): BoundingBox {\r\n if (this.disposed) {\r\n throw Error('Accessing disposed text instance! ' + this.text);\r\n }\r\n let lines = null;\r\n if (maxWidth != null) {\r\n lines = this._getLinesFromText(text, maxWidth);\r\n } else {\r\n lines = text.split('\\n');\r\n }\r\n\r\n const maxWidthLine = lines.reduce((a, b) => {\r\n return a.length > b.length ? a : b;\r\n });\r\n\r\n this._applyFont(this.ctx); // font must be applied to the context to measure it\r\n const metrics = this.ctx.measureText(maxWidthLine);\r\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\r\n\r\n // TODO lineheight makes the text bounds wonky\r\n const lineAdjustedHeight = textHeight * lines.length;\r\n textHeight = lineAdjustedHeight;\r\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\r\n const x = 0;\r\n const y = 0;\r\n const measurement = new BoundingBox({\r\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\r\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\r\n bottom: y + bottomBounds + this.font.padding,\r\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\r\n });\r\n\r\n return measurement;\r\n }\r\n\r\n private _setDimension(textBounds: BoundingBox, bitmap: CanvasRenderingContext2D) {\r\n let lineHeightRatio = 1;\r\n if (this.font.lineHeight) {\r\n lineHeightRatio = (this.font.lineHeight/this.font.size);\r\n }\r\n // Changing the width and height clears the context properties\r\n // We double the bitmap width to account for all possible alignment\r\n // We scale by \"quality\" so we render text without jaggies\r\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\r\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality * lineHeightRatio;\r\n }\r\n\r\n public static getHashCode(font: Font, text: string, color?: Color) {\r\n const hash =\r\n text +\r\n '__hashcode__' +\r\n font.fontString +\r\n font.showDebug +\r\n font.textAlign +\r\n font.baseAlign +\r\n font.direction +\r\n font.lineHeight +\r\n JSON.stringify(font.shadow) +\r\n (font.padding.toString() +\r\n font.smoothing.toString() +\r\n font.lineWidth.toString() +\r\n font.lineDash.toString() +\r\n font.strokeColor?.toString() +\r\n (color ? color.toString() : font.color.toString()));\r\n return hash;\r\n }\r\n\r\n getHashCode(includeColor: boolean = true) {\r\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\r\n }\r\n\r\n protected _applyRasterProperties(ctx: CanvasRenderingContext2D) {\r\n ctx.translate(this.font.padding, this.font.padding);\r\n ctx.imageSmoothingEnabled = this.font.smoothing;\r\n ctx.lineWidth = this.font.lineWidth;\r\n ctx.setLineDash(this.font.lineDash ?? ctx.getLineDash());\r\n ctx.strokeStyle = this.font.strokeColor?.toString();\r\n ctx.fillStyle = this.color.toString();\r\n }\r\n\r\n private _applyFont(ctx: CanvasRenderingContext2D) {\r\n ctx.resetTransform();\r\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\r\n ctx.scale(this.font.quality, this.font.quality);\r\n ctx.textAlign = this.font.textAlign;\r\n ctx.textBaseline = this.font.baseAlign;\r\n ctx.font = this.font.fontString;\r\n ctx.direction = this.font.direction;\r\n\r\n if (this.font.shadow) {\r\n ctx.shadowColor = this.font.shadow.color.toString();\r\n ctx.shadowBlur = this.font.shadow.blur;\r\n ctx.shadowOffsetX = this.font.shadow.offset.x;\r\n ctx.shadowOffsetY = this.font.shadow.offset.y;\r\n }\r\n }\r\n\r\n private _drawText(ctx: CanvasRenderingContext2D, lines: string[], lineHeight: number): void {\r\n this._applyRasterProperties(ctx);\r\n this._applyFont(ctx);\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (this.color) {\r\n ctx.fillText(line, 0, i * lineHeight);\r\n }\r\n\r\n if (this.font.strokeColor) {\r\n ctx.strokeText(line, 0, i * lineHeight);\r\n }\r\n }\r\n\r\n if (this.font.showDebug) {\r\n // Horizontal line\r\n /* istanbul ignore next */\r\n line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\r\n // Vertical line\r\n /* istanbul ignore next */\r\n line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\r\n }\r\n }\r\n\r\n private _splitTextBitmap(bitmap: CanvasRenderingContext2D) {\r\n const textImages: { x: number; y: number; canvas: HTMLCanvasElement }[] = [];\r\n let currentX = 0;\r\n let currentY = 0;\r\n // 4k is the max for mobile devices\r\n const width = Math.min(4096, bitmap.canvas.width);\r\n const height = Math.min(4096, bitmap.canvas.height);\r\n\r\n // Splits the original bitmap into 4k max chunks\r\n while (currentX < bitmap.canvas.width) {\r\n while (currentY < bitmap.canvas.height) {\r\n // create new bitmap\r\n const canvas = document.createElement('canvas');\r\n canvas.width = width;\r\n canvas.height = height;\r\n const ctx = canvas.getContext('2d');\r\n\r\n // draw current slice to new bitmap in < 4k chunks\r\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\r\n\r\n textImages.push({ x: currentX, y: currentY, canvas });\r\n currentY += height;\r\n }\r\n currentX += width;\r\n currentY = 0;\r\n }\r\n return textImages;\r\n }\r\n\r\n public flagDirty() {\r\n this._dirty = true;\r\n }\r\n private _dirty = true;\r\n private _ex: ExcaliburGraphicsContext;\r\n public render(ex: ExcaliburGraphicsContext, x: number, y: number, maxWidth?: number) {\r\n if (this.disposed) {\r\n throw Error('Accessing disposed text instance! ' + this.text);\r\n }\r\n this._ex = ex;\r\n const hashCode = this.getHashCode();\r\n if (this._lastHashCode !== hashCode) {\r\n this._dirty = true;\r\n }\r\n\r\n // Calculate image chunks\r\n if (this._dirty) {\r\n this.dimensions = this.measureText(this.text, maxWidth);\r\n this._setDimension(this.dimensions, this.ctx);\r\n const lines = this._getLinesFromText(this.text, maxWidth);\r\n const lineHeight = this.font.lineHeight ?? this.dimensions.height / lines.length;\r\n\r\n // draws the text to the main bitmap\r\n this._drawText(this.ctx, lines, lineHeight);\r\n\r\n // clear any out old fragments\r\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n ex.textureLoader.delete(frag.canvas);\r\n }\r\n }\r\n\r\n // splits to < 4k fragments for large text\r\n this._textFragments = this._splitTextBitmap(this.ctx);\r\n\r\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n ex.textureLoader.load(frag.canvas, this.font.filtering, true);\r\n }\r\n }\r\n this._lastHashCode = hashCode;\r\n this._dirty = false;\r\n }\r\n\r\n // draws the bitmap fragments to excalibur graphics context\r\n for (const frag of this._textFragments) {\r\n ex.drawImage(\r\n frag.canvas,\r\n 0,\r\n 0,\r\n frag.canvas.width,\r\n frag.canvas.height,\r\n frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2,\r\n frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2,\r\n frag.canvas.width / this.font.quality,\r\n frag.canvas.height / this.font.quality\r\n );\r\n }\r\n }\r\n\r\n dispose() {\r\n this.disposed = true;\r\n this.dimensions = undefined;\r\n this.canvas = undefined;\r\n this.ctx = undefined;\r\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n this._ex.textureLoader.delete(frag.canvas);\r\n }\r\n }\r\n this._textFragments.length = 0;\r\n }\r\n\r\n /**\r\n * Return array of lines split based on the \\n character, and the maxWidth? constraint\r\n * @param text\r\n * @param maxWidth\r\n */\r\n private _cachedText: string;\r\n private _cachedLines: string[];\r\n private _cachedRenderWidth: number;\r\n private _getLinesFromText(text: string, maxWidth?: number) {\r\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\r\n return this._cachedLines;\r\n }\r\n\r\n const lines = text.split('\\n');\r\n\r\n if (maxWidth == null) {\r\n return lines;\r\n }\r\n\r\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\r\n for (let i = 0; i < lines.length; i++) {\r\n let line = lines[i];\r\n let newLine = '';\r\n if (this.measureText(line).width > maxWidth) {\r\n while (this.measureText(line).width > maxWidth) {\r\n newLine = line[line.length - 1] + newLine;\r\n line = line.slice(0, -1); // Remove last character from line\r\n }\r\n\r\n // Update the array with our new values\r\n lines[i] = line;\r\n lines[i + 1] = newLine;\r\n }\r\n }\r\n\r\n this._cachedText = text;\r\n this._cachedLines = lines;\r\n this._cachedRenderWidth = maxWidth;\r\n\r\n return lines;\r\n }\r\n}\r\n","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Logger } from '../Util/Log';\r\nimport { Font } from './Font';\r\nimport { FontTextInstance } from './FontTextInstance';\r\n\r\nexport class FontCache {\r\n public static FONT_TIMEOUT = 500;\r\n private static _LOGGER = Logger.getInstance();\r\n private static _TEXT_USAGE = new Map();\r\n private static _TEXT_CACHE = new Map();\r\n private static _MEASURE_CACHE = new Map();\r\n\r\n static measureText(text: string, font: Font, maxWidth?: number) {\r\n const hash = FontTextInstance.getHashCode(font, text);\r\n if (FontCache._MEASURE_CACHE.has(hash)) {\r\n return FontCache._MEASURE_CACHE.get(hash);\r\n }\r\n FontCache._LOGGER.debug('Font text measurement cache miss');\r\n const measurement = font.measureTextWithoutCache(text, maxWidth);\r\n FontCache._MEASURE_CACHE.set(hash, measurement);\r\n return measurement;\r\n }\r\n\r\n static getTextInstance(text: string, font: Font, color: Color) {\r\n const hash = FontTextInstance.getHashCode(font, text, color);\r\n let textInstance = FontCache._TEXT_CACHE.get(hash);\r\n if (!textInstance) {\r\n textInstance = new FontTextInstance(font, text, color);\r\n FontCache._TEXT_CACHE.set(hash, textInstance);\r\n FontCache._LOGGER.debug('Font text instance cache miss');\r\n }\r\n\r\n // Cache the bitmap for certain amount of time\r\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\r\n\r\n return textInstance;\r\n }\r\n\r\n static checkAndClearCache() {\r\n const deferred: FontTextInstance[] = [];\r\n const currentHashCodes = new Set();\r\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries()) {\r\n // if bitmap hasn't been used in 100 ms clear it\r\n if (time + FontCache.FONT_TIMEOUT < performance.now()) {\r\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\r\n deferred.push(textInstance);\r\n textInstance.dispose();\r\n } else {\r\n const hash = textInstance.getHashCode(false);\r\n currentHashCodes.add(hash);\r\n }\r\n }\r\n // Deferred removal of text instances\r\n deferred.forEach((t) => {\r\n FontCache._TEXT_USAGE.delete(t);\r\n });\r\n\r\n // Regenerate text instance cache\r\n this._TEXT_CACHE.clear();\r\n for (const [textInstance] of this._TEXT_USAGE.entries()) {\r\n this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\r\n }\r\n\r\n // Regenerated measurement cache\r\n const newTextMeasurementCache = new Map();\r\n for (const current of currentHashCodes) {\r\n if (FontCache._MEASURE_CACHE.has(current)) {\r\n newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\r\n }\r\n }\r\n this._MEASURE_CACHE.clear();\r\n this._MEASURE_CACHE = newTextMeasurementCache;\r\n }\r\n\r\n public static get cacheSize() {\r\n return FontCache._TEXT_USAGE.size;\r\n }\r\n\r\n /**\r\n * Force clear all cached text bitmaps\r\n */\r\n public static clearCache() {\r\n for (const [textInstance] of FontCache._TEXT_USAGE.entries()) {\r\n textInstance.dispose();\r\n }\r\n FontCache._TEXT_USAGE.clear();\r\n FontCache._TEXT_CACHE.clear();\r\n FontCache._MEASURE_CACHE.clear();\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { BoundingBox } from '../Collision/Index';\r\nimport { Color } from '../Color';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BaseAlign, Direction, FontOptions, FontStyle, FontUnit, TextAlign, FontRenderer } from './FontCommon';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { RasterOptions } from './Raster';\r\nimport { ImageFiltering } from './Filtering';\r\nimport { FontTextInstance } from './FontTextInstance';\r\nimport { FontCache } from './FontCache';\r\n/**\r\n * Represents a system or web font in Excalibur\r\n *\r\n * If no options specified, the system sans-serif 10 pixel is used\r\n *\r\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\r\n */\r\nexport class Font extends Graphic implements FontRenderer {\r\n /**\r\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\r\n *\r\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\r\n */\r\n public filtering: ImageFiltering = ImageFiltering.Blended;\r\n constructor(options: FontOptions & GraphicOptions & RasterOptions = {}) {\r\n super(options); // <- Graphics properties\r\n\r\n // Raster properties\r\n this.smoothing = options?.smoothing ?? this.smoothing;\r\n this.padding = options?.padding ?? this.padding;\r\n this.color = options?.color ?? this.color;\r\n this.strokeColor = options?.strokeColor ?? this.strokeColor;\r\n this.lineDash = options?.lineDash ?? this.lineDash;\r\n this.lineWidth = options?.lineWidth ?? this.lineWidth;\r\n this.filtering = options?.filtering ?? this.filtering;\r\n\r\n // Font specific properties\r\n this.family = options?.family ?? this.family;\r\n this.style = options?.style ?? this.style;\r\n this.bold = options?.bold ?? this.bold;\r\n this.size = options?.size ?? this.size;\r\n this.unit = options?.unit ?? this.unit;\r\n this.textAlign = options?.textAlign ?? this.textAlign;\r\n this.baseAlign = options?.baseAlign ?? this.baseAlign;\r\n this.direction = options?.direction ?? this.direction;\r\n this.lineHeight = options?.lineHeight ?? this.lineHeight;\r\n this.quality = options?.quality ?? this.quality;\r\n if (options?.shadow) {\r\n this.shadow = {};\r\n this.shadow.blur = options.shadow.blur ?? this.shadow.blur;\r\n this.shadow.offset = options.shadow.offset ?? this.shadow.offset;\r\n this.shadow.color = options.shadow.color ?? this.shadow.color;\r\n }\r\n }\r\n\r\n public clone() {\r\n return new Font({\r\n ...this.cloneGraphicOptions(),\r\n size: this.size,\r\n unit: this.unit,\r\n family: this.family,\r\n style: this.style,\r\n bold: this.bold,\r\n textAlign: this.textAlign,\r\n baseAlign: this.baseAlign,\r\n direction: this.direction,\r\n shadow: this.shadow\r\n ? {\r\n blur: this.shadow.blur,\r\n offset: this.shadow.offset,\r\n color: this.shadow.color\r\n }\r\n : null\r\n });\r\n }\r\n\r\n /**\r\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\r\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\r\n *\r\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\r\n *\r\n * (Default 2)\r\n */\r\n public quality = 2;\r\n\r\n // Raster properties for fonts\r\n public padding = 2;\r\n public smoothing = false;\r\n public lineWidth = 1;\r\n public lineDash: number[] = [];\r\n public color: Color = Color.Black;\r\n public strokeColor: Color;\r\n\r\n public family: string = 'sans-serif';\r\n public style: FontStyle = FontStyle.Normal;\r\n public bold: boolean = false;\r\n public unit: FontUnit = FontUnit.Px;\r\n public textAlign: TextAlign = TextAlign.Left;\r\n public baseAlign: BaseAlign = BaseAlign.Top;\r\n public direction: Direction = Direction.LeftToRight;\r\n /**\r\n * Font line height in pixels, default line height if unset\r\n */\r\n public lineHeight: number | undefined = undefined;\r\n public size: number = 10;\r\n public shadow: { blur?: number; offset?: Vector; color?: Color } = null;\r\n\r\n public get fontString() {\r\n return `${this.style} ${this.bold ? 'bold' : ''} ${this.size}${this.unit} ${this.family}`;\r\n }\r\n\r\n private _textBounds: BoundingBox = new BoundingBox();\r\n\r\n public get localBounds(): BoundingBox {\r\n return this._textBounds;\r\n }\r\n\r\n protected _drawImage(_ex: ExcaliburGraphicsContext, _x: number, _y: number) {\r\n // TODO weird vestigial drawimage\r\n }\r\n\r\n protected _rotate(ex: ExcaliburGraphicsContext) {\r\n // TODO this needs to change depending on the bounding box...\r\n const origin = this.origin ?? this._textBounds.center;\r\n ex.translate(origin.x, origin.y);\r\n ex.rotate(this.rotation);\r\n ex.translate(-origin.x, -origin.y);\r\n }\r\n\r\n protected _flip(ex: ExcaliburGraphicsContext) {\r\n if (this.flipHorizontal) {\r\n ex.translate(this._textBounds.width / this.scale.x, 0);\r\n ex.scale(-1, 1);\r\n }\r\n\r\n if (this.flipVertical) {\r\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\r\n ex.scale(1, -1);\r\n }\r\n }\r\n\r\n private _textMeasurement = new FontTextInstance(this, '', Color.Black);\r\n\r\n public measureTextWithoutCache(text: string, maxWidth?: number) {\r\n return this._textMeasurement.measureText(text, maxWidth);\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox that is the total size of the text including multiple lines\r\n *\r\n * Does not include any padding or adjustment\r\n * @param text\r\n * @returns BoundingBox\r\n */\r\n public measureText(text: string, maxWidth?: number): BoundingBox {\r\n return FontCache.measureText(text, this, maxWidth);\r\n }\r\n\r\n protected _postDraw(ex: ExcaliburGraphicsContext): void {\r\n ex.restore();\r\n }\r\n\r\n public render(ex: ExcaliburGraphicsContext, text: string, colorOverride: Color, x: number, y: number, maxWidth?: number) {\r\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\r\n\r\n // Apply affine transformations\r\n this._textBounds = textInstance.dimensions;\r\n this._preDraw(ex, x, y);\r\n\r\n textInstance.render(ex, x, y, maxWidth);\r\n\r\n this._postDraw(ex);\r\n }\r\n}\r\n","import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { SpriteFont } from './SpriteFont';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Color } from '../Color';\r\nimport { Font } from './Font';\r\n\r\nexport interface TextOptions {\r\n /**\r\n * Text to draw\r\n */\r\n text: string;\r\n\r\n /**\r\n * Optionally override the font color, currently unsupported by SpriteFont\r\n */\r\n color?: Color;\r\n\r\n /**\r\n * Optionally specify a font, if none specified a default font is used (System sans-serif 10 pixel)\r\n */\r\n font?: Font | SpriteFont;\r\n\r\n /**\r\n * Optionally specify a maximum width in pixels for our text, and wrap to the next line if needed.\r\n */\r\n maxWidth?: number;\r\n}\r\n\r\n/**\r\n * Represent Text graphics in excalibur\r\n *\r\n * Useful for in game labels, ui, or overlays\r\n */\r\nexport class Text extends Graphic {\r\n public color?: Color;\r\n public maxWidth?: number;\r\n constructor(options: TextOptions & GraphicOptions) {\r\n super(options);\r\n // This order is important font, color, then text\r\n this.font = options.font ?? new Font();\r\n this.color = options.color ?? this.color;\r\n this.text = options.text;\r\n this.maxWidth = options.maxWidth;\r\n }\r\n\r\n public clone(): Text {\r\n return new Text({\r\n text: this.text.slice(),\r\n color: this.color?.clone() ?? Color.Black,\r\n font: this.font.clone(),\r\n maxWidth: this.maxWidth\r\n });\r\n }\r\n\r\n private _text: string = '';\r\n public get text() {\r\n return this._text;\r\n }\r\n\r\n public set text(value: string) {\r\n this._text = value;\r\n this._calculateDimension();\r\n }\r\n\r\n private _font: Font | SpriteFont;\r\n public get font(): Font | SpriteFont {\r\n return this._font;\r\n }\r\n public set font(font: Font | SpriteFont) {\r\n this._font = font;\r\n }\r\n\r\n private _textWidth: number = 0;\r\n\r\n public get width() {\r\n if (this._textWidth === 0) {\r\n this._calculateDimension();\r\n }\r\n return this._textWidth * this.scale.x;\r\n }\r\n\r\n private _textHeight: number = 0;\r\n public get height() {\r\n if (this._textHeight === 0) {\r\n this._calculateDimension();\r\n }\r\n return this._textHeight * this.scale.y;\r\n }\r\n\r\n private _calculateDimension() {\r\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\r\n this._textWidth = width;\r\n this._textHeight = height;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\r\n }\r\n\r\n protected override _rotate(_ex: ExcaliburGraphicsContext) {\r\n // None this is delegated to font\r\n // This override erases the default behavior\r\n }\r\n\r\n protected override _flip(_ex: ExcaliburGraphicsContext) {\r\n // None this is delegated to font\r\n // This override erases the default behavior\r\n }\r\n\r\n protected override _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.isStale() || this.font.isStale()) {\r\n this.font.flipHorizontal = this.flipHorizontal;\r\n this.font.flipVertical = this.flipVertical;\r\n this.font.rotation = this.rotation;\r\n this.font.origin = this.origin;\r\n this.font.opacity = this.opacity;\r\n }\r\n this.font.tint = this.tint;\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n protected override _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n let color = Color.Black;\r\n if (this.font instanceof Font) {\r\n color = this.color ?? this.font.color;\r\n }\r\n\r\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\r\n this._textWidth = width;\r\n this._textHeight = height;\r\n\r\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\r\n\r\n if (this.font.showDebug) {\r\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\r\n if (this.maxWidth != null) {\r\n ex.debug.drawRect(x, y, this.maxWidth, this.height, {\r\n color: Color.Yellow\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n KillEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PostCollisionEvent,\r\n PreCollisionEvent,\r\n CollisionStartEvent,\r\n CollisionEndEvent,\r\n PostKillEvent,\r\n PreKillEvent,\r\n EnterViewPortEvent,\r\n ExitViewPortEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n PreDebugDrawEvent,\r\n PostDebugDrawEvent,\r\n ActionStartEvent,\r\n ActionCompleteEvent\r\n} from './Events';\r\nimport { Engine } from './Engine';\r\nimport { Color } from './Color';\r\nimport { CanInitialize, CanUpdate, CanBeKilled } from './Interfaces/LifecycleEvents';\r\nimport { Scene } from './Scene';\r\nimport { Logger } from './Util/Log';\r\nimport { Vector, vec } from './Math/vector';\r\nimport { BodyComponent } from './Collision/BodyComponent';\r\nimport { Eventable } from './Interfaces/Evented';\r\nimport { PointerEvents } from './Interfaces/PointerEventHandlers';\r\nimport { CollisionType } from './Collision/CollisionType';\r\n\r\nimport { Entity, EntityEvents } from './EntityComponentSystem/Entity';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from './EntityComponentSystem/Components/MotionComponent';\r\nimport { GraphicsComponent } from './Graphics/GraphicsComponent';\r\nimport { Rectangle } from './Graphics/Rectangle';\r\nimport { ColliderComponent } from './Collision/ColliderComponent';\r\nimport { Shape } from './Collision/Colliders/Shape';\r\nimport { watch } from './Util/Watch';\r\nimport { Collider, CollisionContact, CollisionGroup, Side } from './Collision/Index';\r\nimport { Circle } from './Graphics/Circle';\r\nimport { PointerEvent } from './Input/PointerEvent';\r\nimport { WheelEvent } from './Input/WheelEvent';\r\nimport { PointerComponent } from './Input/PointerComponent';\r\nimport { ActionsComponent } from './Actions/ActionsComponent';\r\nimport { Raster } from './Graphics/Raster';\r\nimport { Text } from './Graphics/Text';\r\nimport { CoordPlane } from './Math/coord-plane';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { Component } from './EntityComponentSystem';\r\n\r\n/**\r\n * Type guard for checking if something is an Actor\r\n * @param x\r\n */\r\nexport function isActor(x: any): x is Actor {\r\n return x instanceof Actor;\r\n}\r\n\r\n/**\r\n * Actor constructor options\r\n */\r\nexport interface ActorArgs {\r\n /**\r\n * Optionally set the name of the actor, default is 'anonymous'\r\n */\r\n name?: string;\r\n /**\r\n * Optionally set the x position of the actor, default is 0\r\n */\r\n x?: number;\r\n /**\r\n * Optionally set the y position of the actor, default is 0\r\n */\r\n y?: number;\r\n /**\r\n * Optionally set the (x, y) position of the actor as a vector, default is (0, 0)\r\n */\r\n pos?: Vector;\r\n /**\r\n * Optionally set the coordinate plane of the actor, default is [[CoordPlane.World]] meaning actor is subject to camera positioning\r\n */\r\n coordPlane?: CoordPlane;\r\n /**\r\n * Optionally set the width of a box collider for the actor\r\n */\r\n width?: number;\r\n /**\r\n * Optionally set the height of a box collider for the actor\r\n */\r\n height?: number;\r\n /**\r\n * Optionally set the radius of the circle collider for the actor\r\n */\r\n radius?: number;\r\n /**\r\n * Optionally set the velocity of the actor in pixels/sec\r\n */\r\n vel?: Vector;\r\n /**\r\n * Optionally set the acceleration of the actor in pixels/sec^2\r\n */\r\n acc?: Vector;\r\n /**\r\n * Optionally se the rotation in radians (180 degrees = Math.PI radians)\r\n */\r\n rotation?: number;\r\n /**\r\n * Optionally set the angular velocity of the actor in radians/sec (180 degrees = Math.PI radians)\r\n */\r\n angularVelocity?: number;\r\n /**\r\n * Optionally set the scale of the actor's transform\r\n */\r\n scale?: Vector;\r\n /**\r\n * Optionally set the z index of the actor, default is 0\r\n */\r\n z?: number;\r\n /**\r\n * Optionally set the color of an actor, only used if no graphics are present\r\n * If a width/height or a radius was set a default graphic will be added\r\n */\r\n color?: Color;\r\n /**\r\n * Optionally set the color of an actor, only used if no graphics are present\r\n * If a width/height or a radius was set a default graphic will be added\r\n */\r\n opacity?: number;\r\n /**\r\n * Optionally set the visibility of the actor\r\n */\r\n visible?: boolean;\r\n /**\r\n * Optionally set the anchor for graphics in the actor\r\n */\r\n anchor?: Vector;\r\n /**\r\n * Optionally set the anchor for graphics in the actor\r\n */\r\n offset?: Vector;\r\n /**\r\n * Optionally set the collision type\r\n */\r\n collisionType?: CollisionType;\r\n /**\r\n * Optionally supply a collider for an actor, if supplied ignores any supplied width/height\r\n */\r\n collider?: Collider;\r\n /**\r\n * Optionally supply a [[CollisionGroup]]\r\n */\r\n collisionGroup?: CollisionGroup;\r\n}\r\n\r\nexport type ActorEvents = EntityEvents & {\r\n collisionstart: CollisionStartEvent;\r\n collisionend: CollisionEndEvent;\r\n precollision: PreCollisionEvent;\r\n postcollision: PostCollisionEvent;\r\n kill: KillEvent;\r\n prekill: PreKillEvent;\r\n postkill: PostKillEvent;\r\n predraw: PreDrawEvent;\r\n postdraw: PostDrawEvent;\r\n pretransformdraw: PreDrawEvent;\r\n posttransformdraw: PostDrawEvent;\r\n predebugdraw: PreDebugDrawEvent;\r\n postdebugdraw: PostDebugDrawEvent;\r\n pointerup: PointerEvent;\r\n pointerdown: PointerEvent;\r\n pointerenter: PointerEvent;\r\n pointerleave: PointerEvent;\r\n pointermove: PointerEvent;\r\n pointercancel: PointerEvent;\r\n pointerwheel: WheelEvent;\r\n pointerdragstart: PointerEvent;\r\n pointerdragend: PointerEvent;\r\n pointerdragenter: PointerEvent;\r\n pointerdragleave: PointerEvent;\r\n pointerdragmove: PointerEvent;\r\n enterviewport: EnterViewPortEvent;\r\n exitviewport: ExitViewPortEvent;\r\n actionstart: ActionStartEvent;\r\n actioncomplete: ActionCompleteEvent;\r\n}\r\n\r\nexport const ActorEvents = {\r\n CollisionStart: 'collisionstart',\r\n CollisionEnd: 'collisionend',\r\n PreCollision: 'precollision',\r\n PostCollision: 'postcollision',\r\n Kill: 'kill',\r\n PreKill: 'prekill',\r\n PostKill: 'postkill',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw',\r\n PreTransformDraw: 'pretransformdraw',\r\n PostTransformDraw: 'posttransformdraw',\r\n PreDebugDraw: 'predebugdraw',\r\n PostDebugDraw: 'postdebugdraw',\r\n PointerUp: 'pointerup',\r\n PointerDown: 'pointerdown',\r\n PointerEnter: 'pointerenter',\r\n PointerLeave: 'pointerleave',\r\n PointerMove: 'pointermove',\r\n PointerCancel: 'pointercancel',\r\n Wheel: 'pointerwheel',\r\n PointerDrag: 'pointerdragstart',\r\n PointerDragEnd: 'pointerdragend',\r\n PointerDragEnter: 'pointerdragenter',\r\n PointerDragLeave: 'pointerdragleave',\r\n PointerDragMove: 'pointerdragmove',\r\n EnterViewPort: 'enterviewport',\r\n ExitViewPort: 'exitviewport',\r\n ActionStart: 'actionstart',\r\n ActionComplete: 'actioncomplete'\r\n};\r\n\r\n/**\r\n * The most important primitive in Excalibur is an `Actor`. Anything that\r\n * can move on the screen, collide with another `Actor`, respond to events,\r\n * or interact with the current scene, must be an actor. An `Actor` **must**\r\n * be part of a [[Scene]] for it to be drawn to the screen.\r\n */\r\nexport class Actor extends Entity implements Eventable, PointerEvents, CanInitialize, CanUpdate, CanBeKilled {\r\n public events = new EventEmitter();\r\n // #region Properties\r\n\r\n /**\r\n * Set defaults for all Actors\r\n */\r\n public static defaults = {\r\n anchor: Vector.Half\r\n };\r\n\r\n /**\r\n * The physics body the is associated with this actor. The body is the container for all physical properties, like position, velocity,\r\n * acceleration, mass, inertia, etc.\r\n */\r\n public body: BodyComponent;\r\n\r\n /**\r\n * Access the Actor's built in [[TransformComponent]]\r\n */\r\n public transform: TransformComponent;\r\n\r\n /**\r\n * Access the Actor's built in [[MotionComponent]]\r\n */\r\n public motion: MotionComponent;\r\n\r\n /**\r\n * Access to the Actor's built in [[GraphicsComponent]]\r\n */\r\n public graphics: GraphicsComponent;\r\n\r\n /**\r\n * Access to the Actor's built in [[ColliderComponent]]\r\n */\r\n public collider: ColliderComponent;\r\n\r\n /**\r\n * Access to the Actor's built in [[PointerComponent]] config\r\n */\r\n public pointer: PointerComponent;\r\n\r\n /**\r\n * Useful for quickly scripting actor behavior, like moving to a place, patrolling back and forth, blinking, etc.\r\n *\r\n * Access to the Actor's built in [[ActionsComponent]] which forwards to the\r\n * [[ActionContext|Action context]] of the actor.\r\n */\r\n public actions: ActionsComponent;\r\n\r\n /**\r\n * Gets the position vector of the actor in pixels\r\n */\r\n public get pos(): Vector {\r\n return this.transform.pos;\r\n }\r\n\r\n /**\r\n * Sets the position vector of the actor in pixels\r\n */\r\n public set pos(thePos: Vector) {\r\n this.transform.pos = thePos.clone();\r\n }\r\n\r\n /**\r\n * Gets the position vector of the actor from the last frame\r\n */\r\n public get oldPos(): Vector {\r\n return this.body.oldPos;\r\n }\r\n\r\n /**\r\n * Sets the position vector of the actor in the last frame\r\n */\r\n public set oldPos(thePos: Vector) {\r\n this.body.oldPos.setTo(thePos.x, thePos.y);\r\n }\r\n\r\n /**\r\n * Gets the velocity vector of the actor in pixels/sec\r\n */\r\n public get vel(): Vector {\r\n return this.motion.vel;\r\n }\r\n\r\n /**\r\n * Sets the velocity vector of the actor in pixels/sec\r\n */\r\n public set vel(theVel: Vector) {\r\n this.motion.vel = theVel.clone();\r\n }\r\n\r\n /**\r\n * Gets the velocity vector of the actor from the last frame\r\n */\r\n public get oldVel(): Vector {\r\n return this.body.oldVel;\r\n }\r\n\r\n /**\r\n * Sets the velocity vector of the actor from the last frame\r\n */\r\n public set oldVel(theVel: Vector) {\r\n this.body.oldVel.setTo(theVel.x, theVel.y);\r\n }\r\n\r\n /**\r\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\r\n * useful to simulate a gravitational effect.\r\n */\r\n public get acc(): Vector {\r\n return this.motion.acc;\r\n }\r\n\r\n /**\r\n * Sets the acceleration vector of teh actor in pixels/second/second\r\n */\r\n public set acc(theAcc: Vector) {\r\n this.motion.acc = theAcc.clone();\r\n }\r\n\r\n /**\r\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public set oldAcc(theAcc: Vector) {\r\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\r\n }\r\n\r\n /**\r\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public get oldAcc(): Vector {\r\n return this.body.oldAcc;\r\n }\r\n\r\n /**\r\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */\r\n public get rotation(): number {\r\n return this.transform.rotation;\r\n }\r\n\r\n /**\r\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */\r\n public set rotation(theAngle: number) {\r\n this.transform.rotation = theAngle;\r\n }\r\n\r\n /**\r\n * Gets the rotational velocity of the actor in radians/second\r\n */\r\n public get angularVelocity(): number {\r\n return this.motion.angularVelocity;\r\n }\r\n\r\n /**\r\n * Sets the rotational velocity of the actor in radians/sec\r\n */\r\n public set angularVelocity(angularVelocity: number) {\r\n this.motion.angularVelocity = angularVelocity;\r\n }\r\n\r\n public get scale(): Vector {\r\n return this.get(TransformComponent).scale;\r\n }\r\n\r\n public set scale(scale: Vector) {\r\n this.get(TransformComponent).scale = scale;\r\n }\r\n\r\n private _anchor: Vector = watch(Vector.Half, (v) => this._handleAnchorChange(v));\r\n /**\r\n * The anchor to apply all actor related transformations like rotation,\r\n * translation, and scaling. By default the anchor is in the center of\r\n * the actor. By default it is set to the center of the actor (.5, .5)\r\n *\r\n * An anchor of (.5, .5) will ensure that drawings are centered.\r\n *\r\n * Use `anchor.setTo` to set the anchor to a different point using\r\n * values between 0 and 1. For example, anchoring to the top-left would be\r\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\r\n */\r\n public get anchor(): Vector {\r\n return this._anchor;\r\n }\r\n\r\n public set anchor(vec: Vector) {\r\n this._anchor = watch(vec, (v) => this._handleAnchorChange(v));\r\n this._handleAnchorChange(vec);\r\n }\r\n\r\n private _handleAnchorChange(v: Vector) {\r\n if (this.graphics) {\r\n this.graphics.anchor = v;\r\n }\r\n }\r\n\r\n private _offset: Vector = watch(Vector.Zero, (v) => this._handleOffsetChange(v));\r\n /**\r\n * The offset in pixels to apply to all actor graphics\r\n *\r\n * Default offset of (0, 0)\r\n */\r\n public get offset(): Vector {\r\n return this._offset;\r\n }\r\n\r\n public set offset(vec: Vector) {\r\n this._offset = watch(vec, (v) => this._handleOffsetChange(v));\r\n this._handleOffsetChange(vec);\r\n }\r\n\r\n private _handleOffsetChange(v: Vector) {\r\n if (this.graphics) {\r\n this.graphics.offset = v;\r\n }\r\n }\r\n\r\n /**\r\n * Indicates whether the actor is physically in the viewport\r\n */\r\n public get isOffScreen(): boolean {\r\n return this.hasTag('ex.offscreen');\r\n }\r\n\r\n /**\r\n * Convenience reference to the global logger\r\n */\r\n public logger: Logger = Logger.getInstance();\r\n\r\n /**\r\n * Draggable helper\r\n */\r\n private _draggable: boolean = false;\r\n private _dragging: boolean = false;\r\n\r\n private _pointerDragStartHandler = () => {\r\n this._dragging = true;\r\n };\r\n\r\n private _pointerDragEndHandler = () => {\r\n this._dragging = false;\r\n };\r\n\r\n private _pointerDragMoveHandler = (pe: PointerEvent) => {\r\n if (this._dragging) {\r\n this.pos = pe.worldPos;\r\n }\r\n };\r\n\r\n private _pointerDragLeaveHandler = (pe: PointerEvent) => {\r\n if (this._dragging) {\r\n this.pos = pe.worldPos;\r\n }\r\n };\r\n\r\n public get draggable(): boolean {\r\n return this._draggable;\r\n }\r\n\r\n public set draggable(isDraggable: boolean) {\r\n if (isDraggable) {\r\n if (isDraggable && !this._draggable) {\r\n this.events.on('pointerdragstart', this._pointerDragStartHandler);\r\n this.events.on('pointerdragend', this._pointerDragEndHandler);\r\n this.events.on('pointerdragmove', this._pointerDragMoveHandler);\r\n this.events.on('pointerdragleave', this._pointerDragLeaveHandler);\r\n } else if (!isDraggable && this._draggable) {\r\n this.events.off('pointerdragstart', this._pointerDragStartHandler);\r\n this.events.off('pointerdragend', this._pointerDragEndHandler);\r\n this.events.off('pointerdragmove', this._pointerDragMoveHandler);\r\n this.events.off('pointerdragleave', this._pointerDragLeaveHandler);\r\n }\r\n\r\n this._draggable = isDraggable;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the color of the actor's current graphic\r\n */\r\n public get color(): Color {\r\n return this._color;\r\n }\r\n public set color(v: Color) {\r\n this._color = v.clone();\r\n const currentGraphic = this.graphics.current;\r\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) {\r\n currentGraphic.color = this._color;\r\n }\r\n }\r\n private _color: Color;\r\n\r\n // #endregion\r\n\r\n /**\r\n *\r\n * @param config\r\n */\r\n constructor(config?: ActorArgs) {\r\n super();\r\n\r\n const {\r\n name,\r\n x,\r\n y,\r\n pos,\r\n coordPlane,\r\n scale,\r\n width,\r\n height,\r\n radius,\r\n collider,\r\n vel,\r\n acc,\r\n rotation,\r\n angularVelocity,\r\n z,\r\n color,\r\n visible,\r\n opacity,\r\n anchor,\r\n offset,\r\n collisionType,\r\n collisionGroup\r\n } = {\r\n ...config\r\n };\r\n\r\n this.name = name ?? this.name;\r\n this.anchor = anchor ?? Actor.defaults.anchor.clone();\r\n this.offset = offset ?? Vector.Zero;\r\n this.transform = new TransformComponent();\r\n this.addComponent(this.transform);\r\n this.pos = pos ?? vec(x ?? 0, y ?? 0);\r\n this.rotation = rotation ?? 0;\r\n this.scale = scale ?? vec(1, 1);\r\n this.z = z ?? 0;\r\n this.transform.coordPlane = coordPlane ?? CoordPlane.World;\r\n\r\n this.pointer = new PointerComponent;\r\n this.addComponent(this.pointer);\r\n\r\n this.graphics = new GraphicsComponent({\r\n anchor: this.anchor,\r\n offset: this.offset,\r\n opacity: opacity\r\n });\r\n this.addComponent(this.graphics);\r\n\r\n this.motion = new MotionComponent;\r\n this.addComponent(this.motion);\r\n this.vel = vel ?? Vector.Zero;\r\n this.acc = acc ?? Vector.Zero;\r\n this.angularVelocity = angularVelocity ?? 0;\r\n\r\n this.actions = new ActionsComponent;\r\n this.addComponent(this.actions);\r\n\r\n this.body = new BodyComponent;\r\n this.addComponent(this.body);\r\n this.body.collisionType = collisionType ?? CollisionType.Passive;\r\n if (collisionGroup) {\r\n this.body.group = collisionGroup;\r\n }\r\n\r\n if (collider) {\r\n this.collider = new ColliderComponent(collider);\r\n this.addComponent(this.collider);\r\n } else if (radius) {\r\n this.collider = new ColliderComponent(Shape.Circle(radius));\r\n this.addComponent(this.collider);\r\n } else {\r\n if (width > 0 && height > 0) {\r\n this.collider = new ColliderComponent(Shape.Box(width, height, this.anchor));\r\n this.addComponent(this.collider);\r\n } else {\r\n this.collider = new ColliderComponent();\r\n this.addComponent(this.collider); // no collider\r\n }\r\n }\r\n\r\n this.graphics.visible = visible ?? true;\r\n\r\n if (color) {\r\n this.color = color;\r\n if (width && height) {\r\n this.graphics.add(\r\n new Rectangle({\r\n color: color,\r\n width,\r\n height\r\n })\r\n );\r\n } else if (radius) {\r\n this.graphics.add(\r\n new Circle({\r\n color: color,\r\n radius\r\n })\r\n );\r\n }\r\n }\r\n }\r\n\r\n public clone(): Actor {\r\n const clone = new Actor({\r\n color: this.color.clone(),\r\n anchor: this.anchor.clone(),\r\n offset: this.offset.clone()\r\n });\r\n clone.clearComponents();\r\n clone.processComponentRemoval();\r\n\r\n // Clone builtins, order is important, same as ctor\r\n clone.addComponent(clone.transform = this.transform.clone() as TransformComponent, true);\r\n clone.addComponent(clone.pointer = this.pointer.clone() as PointerComponent, true);\r\n clone.addComponent(clone.graphics = this.graphics.clone() as GraphicsComponent, true);\r\n clone.addComponent(clone.motion = this.motion.clone() as MotionComponent, true);\r\n clone.addComponent(clone.actions = this.actions.clone() as ActionsComponent, true);\r\n clone.addComponent(clone.body = this.body.clone() as BodyComponent, true);\r\n clone.addComponent(clone.collider = this.collider.clone() as ColliderComponent, true);\r\n\r\n const builtInComponents: Component[] = [\r\n this.transform,\r\n this.pointer,\r\n this.graphics,\r\n this.motion,\r\n this.actions,\r\n this.body,\r\n this.collider\r\n ];\r\n\r\n // Clone non-builtin the current actors components\r\n const components = this.getComponents();\r\n for (const c of components) {\r\n if (!builtInComponents.includes(c)) {\r\n clone.addComponent(c.clone(), true);\r\n }\r\n }\r\n return clone;\r\n }\r\n\r\n /**\r\n * `onInitialize` is called before the first update of the actor. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */\r\n public onInitialize(engine: Engine): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n * @internal\r\n */\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n for (const child of this.children) {\r\n child._initialize(engine);\r\n }\r\n }\r\n\r\n // #region Events\r\n public emit>(eventName: TEventName, event: ActorEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n // #endregion\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPreKill]] lifecycle event\r\n * @internal\r\n */\r\n public _prekill(scene: Scene) {\r\n this.events.emit('prekill', new PreKillEvent(this));\r\n this.onPreKill(scene);\r\n }\r\n\r\n /**\r\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\r\n *\r\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\r\n */\r\n public onPreKill(scene: Scene) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPostKill]] lifecycle event\r\n * @internal\r\n */\r\n public _postkill(scene: Scene) {\r\n this.events.emit('postkill', new PostKillEvent(this));\r\n this.onPostKill(scene);\r\n }\r\n\r\n /**\r\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\r\n *\r\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\r\n */\r\n public onPostKill(scene: Scene) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * If the current actor is a member of the scene, this will remove\r\n * it from the scene graph. It will no longer be drawn or updated.\r\n */\r\n public kill() {\r\n if (this.scene) {\r\n this._prekill(this.scene);\r\n this.events.emit('kill', new KillEvent(this));\r\n super.kill();\r\n this._postkill(this.scene);\r\n } else {\r\n this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\r\n }\r\n }\r\n\r\n /**\r\n * If the current actor is killed, it will now not be killed.\r\n */\r\n public unkill() {\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Indicates wether the actor has been killed.\r\n */\r\n public isKilled(): boolean {\r\n return !this.active;\r\n }\r\n\r\n /**\r\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n */\r\n public get z(): number {\r\n return this.get(TransformComponent).z;\r\n }\r\n\r\n\r\n /**\r\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\r\n * The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n * @param newZ new z-index to assign\r\n */\r\n public set z(newZ: number) {\r\n this.get(TransformComponent).z = newZ;\r\n }\r\n\r\n /**\r\n * Get the center point of an actor (global position)\r\n */\r\n public get center(): Vector {\r\n const globalPos = this.getGlobalPos();\r\n return new Vector(\r\n globalPos.x + this.width / 2 - this.anchor.x * this.width,\r\n globalPos.y + this.height / 2 - this.anchor.y * this.height);\r\n }\r\n\r\n /**\r\n * Get the local center point of an actor\r\n */\r\n public get localCenter(): Vector {\r\n return new Vector(\r\n this.pos.x + this.width / 2 - this.anchor.x * this.width,\r\n this.pos.y + this.height / 2 - this.anchor.y * this.height);\r\n }\r\n\r\n public get width() {\r\n return this.collider.localBounds.width * this.getGlobalScale().x;\r\n }\r\n\r\n public get height() {\r\n return this.collider.localBounds.height * this.getGlobalScale().y;\r\n }\r\n\r\n /**\r\n * Gets this actor's rotation taking into account any parent relationships\r\n * @returns Rotation angle in radians\r\n */\r\n public getGlobalRotation(): number {\r\n return this.get(TransformComponent).globalRotation;\r\n }\r\n\r\n /**\r\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\r\n * @returns Position in world coordinates\r\n */\r\n public getGlobalPos(): Vector {\r\n return this.get(TransformComponent).globalPos;\r\n }\r\n\r\n /**\r\n * Gets the global scale of the Actor\r\n */\r\n public getGlobalScale(): Vector {\r\n return this.get(TransformComponent).globalScale;\r\n }\r\n\r\n // #region Collision\r\n\r\n /**\r\n * Tests whether the x/y specified are contained in the actor\r\n * @param x X coordinate to test (in world coordinates)\r\n * @param y Y coordinate to test (in world coordinates)\r\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\r\n */\r\n public contains(x: number, y: number, recurse: boolean = false): boolean {\r\n const point = vec(x, y);\r\n const collider = this.get(ColliderComponent);\r\n collider.update();\r\n const geom = collider.get();\r\n if (!geom) {\r\n return false;\r\n }\r\n const containment = geom.contains(point);\r\n\r\n if (recurse) {\r\n return (\r\n containment ||\r\n this.children.some((child: Actor) => {\r\n return child.contains(x, y, true);\r\n })\r\n );\r\n }\r\n\r\n return containment;\r\n }\r\n\r\n /**\r\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\r\n * @param actor Actor to test\r\n * @param distance Distance in pixels to test\r\n */\r\n public within(actor: Actor, distance: number): boolean {\r\n const collider = this.get(ColliderComponent);\r\n const otherCollider = actor.get(ColliderComponent);\r\n const me = collider.get();\r\n const other = otherCollider.get();\r\n if (me && other) {\r\n return me.getClosestLineBetween(other).getLength() <= distance;\r\n }\r\n return false;\r\n }\r\n\r\n // #endregion\r\n\r\n // #region Update\r\n\r\n /**\r\n * Called by the Engine, updates the state of the actor\r\n * @internal\r\n * @param engine The reference to the current game engine\r\n * @param delta The time elapsed since the last update in milliseconds\r\n */\r\n public update(engine: Engine, delta: number) {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an actor is updated.\r\n */\r\n public onPreUpdate(engine: Engine, delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an actor is updated.\r\n */\r\n public onPostUpdate(engine: Engine, delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Fires before every collision resolution for a confirmed contact\r\n * @param self\r\n * @param other\r\n * @param side\r\n * @param contact\r\n */\r\n public onPreCollisionResolve(self: Collider, other: Collider, side: Side, contact: CollisionContact) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Fires after every resolution for a confirmed contact.\r\n * @param self\r\n * @param other\r\n * @param side\r\n * @param contact\r\n */\r\n public onPostCollisionResolve(self: Collider, other: Collider, side: Side, contact: CollisionContact) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Fires once when 2 entities with a ColliderComponent first start colliding or touching, if the Colliders stay in contact this\r\n * does not continue firing until they separate and re-collide.\r\n * @param self\r\n * @param other\r\n * @param side\r\n * @param contact\r\n */\r\n public onCollisionStart(self: Collider, other: Collider, side: Side, contact: CollisionContact) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Fires once when 2 entities with a ColliderComponent separate after having been in contact.\r\n * @param self\r\n * @param other\r\n * @param side\r\n * @param lastContact\r\n */\r\n public onCollisionEnd(self: Collider, other: Collider, side: Side, lastContact: CollisionContact) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n // endregion\r\n}\r\n","import { Vector, vec } from './Math/vector';\r\nimport { Engine } from './Engine';\r\nimport { Actor, ActorArgs } from './Actor';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { CoordPlane } from './Math/coord-plane';\r\n\r\n/**\r\n * Type guard to detect a screen element\r\n */\r\nexport function isScreenElement(actor: Actor) {\r\n return actor instanceof ScreenElement;\r\n}\r\n\r\n/**\r\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\r\n * not participate in collisions. Drawn on top of all other actors.\r\n */\r\nexport class ScreenElement extends Actor {\r\n protected _engine: Engine;\r\n\r\n constructor();\r\n constructor(config?: ActorArgs);\r\n\r\n constructor(config?: ActorArgs) {\r\n super({ ...config });\r\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\r\n this.anchor = config?.anchor ?? vec(0, 0);\r\n this.body.collisionType = config?.collisionType ?? CollisionType.PreventCollision;\r\n this.pointer.useGraphicsBounds = true;\r\n this.pointer.useColliderShape = false;\r\n if (!config?.collider &&\r\n config?.width > 0 &&\r\n config?.height > 0) {\r\n this.collider.useBoxCollider(this.width, this.height, this.anchor);\r\n }\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n this._engine = engine;\r\n super._initialize(engine);\r\n }\r\n\r\n public contains(x: number, y: number, useWorld: boolean = true) {\r\n if (useWorld) {\r\n return super.contains(x, y);\r\n }\r\n\r\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\r\n return super.contains(coords.x, coords.y);\r\n }\r\n}\r\n","import { Scene } from './Scene';\r\nimport { Logger } from './Util/Log';\r\nimport * as ex from './index';\r\nimport { Random } from './Math/Random';\r\n\r\n\r\nexport interface TimerOptions {\r\n repeats?: boolean;\r\n numberOfRepeats?: number;\r\n fcn?: () => void;\r\n interval: number;\r\n randomRange?: [number, number];\r\n random?: ex.Random;\r\n}\r\n\r\n/**\r\n * The Excalibur timer hooks into the internal timer and fires callbacks,\r\n * after a certain interval, optionally repeating.\r\n */\r\nexport class Timer {\r\n private _logger = Logger.getInstance();\r\n private static _MAX_ID: number = 0;\r\n public id: number = 0;\r\n\r\n private _elapsedTime: number = 0;\r\n private _totalTimeAlive: number = 0;\r\n\r\n private _running = false;\r\n\r\n private _numberOfTicks: number = 0;\r\n private _callbacks: Array<() => void>;\r\n\r\n public interval: number = 10;\r\n public repeats: boolean = false;\r\n public maxNumberOfRepeats: number = -1;\r\n public randomRange: [number, number] = [0,0];\r\n public random: ex.Random;\r\n private _baseInterval = 10;\r\n private _generateRandomInterval = () => {\r\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\r\n };\r\n\r\n private _complete = false;\r\n public get complete() {\r\n return this._complete;\r\n }\r\n\r\n public scene: Scene = null;\r\n\r\n /**\r\n * @param options Options - repeats, numberOfRepeats, fcn, interval\r\n * @param repeats Indicates whether this call back should be fired only once, or repeat after every interval as completed.\r\n * @param numberOfRepeats Specifies a maximum number of times that this timer will execute.\r\n * @param fcn The callback to be fired after the interval is complete.\r\n * @param randomRange Indicates a range to select a random number to be added onto the interval\r\n */\r\n constructor(options: TimerOptions);\r\n constructor(fcn: TimerOptions | (() => void), interval?: number,\r\n repeats?: boolean, numberOfRepeats?: number, randomRange?: [number, number], random?: ex.Random) {\r\n if (typeof fcn !== 'function') {\r\n const options = fcn;\r\n fcn = options.fcn;\r\n interval = options.interval;\r\n repeats = options.repeats;\r\n numberOfRepeats = options.numberOfRepeats;\r\n randomRange = options.randomRange;\r\n random= options.random;\r\n }\r\n\r\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\r\n this.maxNumberOfRepeats = numberOfRepeats;\r\n if (!repeats) {\r\n throw new Error('repeats must be set to true if numberOfRepeats is set');\r\n }\r\n }\r\n\r\n this.id = Timer._MAX_ID++;\r\n this._callbacks = [];\r\n this._baseInterval = this.interval = interval;\r\n if (!!randomRange){\r\n if (randomRange[0] > randomRange[1]) {\r\n throw new Error('min value must be lower than max value for range');\r\n }\r\n //We use the instance of ex.Random to generate the range\r\n this.random = random ?? new Random();\r\n this.randomRange = randomRange;\r\n\r\n this.interval = this._generateRandomInterval();\r\n this.on(() => {\r\n this.interval = this._generateRandomInterval();\r\n });\r\n };\r\n this.repeats = repeats || this.repeats;\r\n if (fcn) {\r\n this.on(fcn);\r\n }\r\n }\r\n\r\n /**\r\n * Adds a new callback to be fired after the interval is complete\r\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\r\n */\r\n public on(fcn: () => void) {\r\n this._callbacks.push(fcn);\r\n }\r\n\r\n /**\r\n * Removes a callback from the callback list to be fired after the interval is complete.\r\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\r\n */\r\n public off(fcn: () => void) {\r\n const index = this._callbacks.indexOf(fcn);\r\n this._callbacks.splice(index, 1);\r\n }\r\n /**\r\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\r\n * @param delta Number of elapsed milliseconds since the last update.\r\n */\r\n public update(delta: number) {\r\n if (this._running) {\r\n this._totalTimeAlive += delta;\r\n this._elapsedTime += delta;\r\n\r\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\r\n this._complete = true;\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (!this.complete && this._elapsedTime >= this.interval) {\r\n this._callbacks.forEach((c) => {\r\n c.call(this);\r\n });\r\n this._numberOfTicks++;\r\n if (this.repeats) {\r\n this._elapsedTime = 0;\r\n } else {\r\n this._complete = true;\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\r\n *\r\n * Warning** you may need to call `timer.start()` again if the timer had completed\r\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\r\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\r\n */\r\n public reset(newInterval?: number, newNumberOfRepeats?: number) {\r\n if (!!newInterval && newInterval >= 0) {\r\n this._baseInterval = this.interval= newInterval;\r\n }\r\n\r\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\r\n this.maxNumberOfRepeats = newNumberOfRepeats;\r\n if (!this.repeats) {\r\n throw new Error('repeats must be set to true if numberOfRepeats is set');\r\n }\r\n }\r\n\r\n this._complete = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n }\r\n\r\n public get timesRepeated(): number {\r\n return this._numberOfTicks;\r\n }\r\n\r\n public getTimeRunning(): number {\r\n return this._totalTimeAlive;\r\n }\r\n\r\n /**\r\n * @returns milliseconds until the next action callback, if complete will return 0\r\n */\r\n public get timeToNextAction() {\r\n if (this.complete) {\r\n return 0;\r\n }\r\n return this.interval - this._elapsedTime;\r\n }\r\n\r\n /**\r\n * @returns milliseconds elapsed toward the next action\r\n */\r\n public get timeElapsedTowardNextAction() {\r\n return this._elapsedTime;\r\n }\r\n\r\n public get isRunning() {\r\n return this._running;\r\n }\r\n\r\n /**\r\n * Pauses the timer, time will no longer increment towards the next call\r\n */\r\n public pause(): Timer {\r\n this._running = false;\r\n return this;\r\n }\r\n\r\n /**\r\n * Resumes the timer, time will now increment towards the next call.\r\n */\r\n public resume(): Timer {\r\n this._running = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\r\n */\r\n public start(): Timer {\r\n if (!this.scene) {\r\n this._logger.warn('Cannot start a timer not part of a scene, timer wont start until added');\r\n }\r\n\r\n this._running = true;\r\n if (this.complete) {\r\n this._complete = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Stops the timer and resets the elapsed time counter towards the next action invocation\r\n */\r\n public stop(): Timer {\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n return this;\r\n }\r\n\r\n /**\r\n * Cancels the timer, preventing any further executions.\r\n */\r\n public cancel() {\r\n this.pause();\r\n if (this.scene) {\r\n this.scene.cancelTimer(this);\r\n }\r\n }\r\n}\r\n\r\n","import { Component } from '../EntityComponentSystem/Component';\r\nimport { vec, Vector } from '../Math/vector';\r\n\r\nexport class ParallaxComponent extends Component {\r\n\r\n parallaxFactor = vec(1.0, 1.0);\r\n\r\n constructor(parallaxFactor?: Vector) {\r\n super();\r\n this.parallaxFactor = parallaxFactor ?? this.parallaxFactor;\r\n }\r\n}","import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { DebugConfig } from '../Debug';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\n\r\n\r\n/**\r\n * Provide arbitrary drawing for the purposes of debugging your game\r\n *\r\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\r\n *\r\n */\r\nexport class DebugGraphicsComponent extends Component {\r\n constructor(\r\n public draw: (ctx: ExcaliburGraphicsContext, debugFlags: DebugConfig) => void,\r\n public useTransform = true) {\r\n super();\r\n }\r\n}","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Engine } from '../Engine';\r\nimport { Vector, vec } from '../Math/vector';\r\nimport { Logger } from '../Util/Log';\r\nimport { Entity, EntityEvents } from '../EntityComponentSystem/Entity';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { BodyComponent } from '../Collision/BodyComponent';\r\nimport { CollisionType } from '../Collision/CollisionType';\r\nimport { Shape } from '../Collision/Colliders/Shape';\r\nimport { ExcaliburGraphicsContext, Graphic, GraphicsComponent, hasGraphicsTick, ParallaxComponent } from '../Graphics';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { CompositeCollider } from '../Collision/Colliders/CompositeCollider';\r\nimport { DebugGraphicsComponent } from '../Graphics/DebugGraphicsComponent';\r\nimport { Collider } from '../Collision/Colliders/Collider';\r\nimport { PostDrawEvent, PostUpdateEvent, PreDrawEvent, PreUpdateEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { DebugConfig } from '../Debug';\r\nimport { clamp } from '../Math/util';\r\n\r\nexport interface TileMapOptions {\r\n /**\r\n * Optionally name the tile map\r\n */\r\n name?: string;\r\n /**\r\n * Optionally specify the position of the tile map\r\n */\r\n pos?: Vector;\r\n /**\r\n * Width of an individual tile in pixels\r\n */\r\n tileWidth: number;\r\n /**\r\n * Height of an individual tile in pixels\r\n */\r\n tileHeight: number;\r\n /**\r\n * The number of tile columns, or the number of tiles wide\r\n */\r\n columns: number;\r\n /**\r\n * The number of tile rows, or the number of tiles high\r\n */\r\n rows: number;\r\n\r\n /**\r\n * Optionally render from the top of the graphic, by default tiles are rendered from the bottom\r\n */\r\n renderFromTopOfGraphic?: boolean;\r\n\r\n /**\r\n * Optionally configure the meshing lookbehind for Tilemap, Tilemaps combine solid tiles into optimal\r\n * geometry and the lookbehind configures how far back the Tilemap to look for geometry when combining. Meshing\r\n * is an expensive operation, so when the Tilemap geometry is invalidated it must be recalculated.\r\n *\r\n * Default is 10 slots, but if your Tilemap does not change positions or solid tiles often you can increase this to\r\n * Infinity.\r\n */\r\n meshingLookBehind?: number;\r\n}\r\n\r\nexport type TileMapEvents = EntityEvents & {\r\n preupdate: PreUpdateEvent;\r\n postupdate: PostUpdateEvent;\r\n predraw: PreDrawEvent;\r\n postdraw: PostDrawEvent\r\n}\r\n\r\nexport const TileMapEvents = {\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw'\r\n};\r\n\r\n/**\r\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\r\n *\r\n * TileMaps are useful for top down or side scrolling grid oriented games.\r\n */\r\nexport class TileMap extends Entity {\r\n public events = new EventEmitter();\r\n private _token = 0;\r\n private _engine: Engine;\r\n\r\n public logger: Logger = Logger.getInstance();\r\n public readonly tiles: Tile[] = [];\r\n private _rows: Tile[][] = [];\r\n private _cols: Tile[][] = [];\r\n\r\n public readonly tileWidth: number;\r\n public readonly tileHeight: number;\r\n public readonly rows: number;\r\n public readonly columns: number;\r\n\r\n public renderFromTopOfGraphic = false;\r\n public meshingLookBehind = 10;\r\n\r\n private _collidersDirty = true;\r\n public flagCollidersDirty() {\r\n this._collidersDirty = true;\r\n }\r\n\r\n public flagTilesDirty() {\r\n for (let i = 0; i < this.tiles.length; i++) {\r\n if (this.tiles[i]) {\r\n this.tiles[i].flagDirty();\r\n }\r\n }\r\n }\r\n\r\n public transform: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _graphics: GraphicsComponent;\r\n public collider: ColliderComponent;\r\n private _composite: CompositeCollider;\r\n\r\n public get x(): number {\r\n return this.transform.pos.x ?? 0;\r\n }\r\n\r\n public set x(val: number) {\r\n if (this.transform?.pos) {\r\n this.get(TransformComponent).pos = vec(val, this.y);\r\n }\r\n }\r\n\r\n public get y(): number {\r\n return this.transform?.pos.y ?? 0;\r\n }\r\n\r\n public set y(val: number) {\r\n if (this.transform?.pos) {\r\n this.transform.pos = vec(this.x, val);\r\n }\r\n }\r\n\r\n public get z(): number {\r\n return this.transform.z ?? 0;\r\n }\r\n\r\n public set z(val: number) {\r\n if (this.transform) {\r\n this.transform.z = val;\r\n }\r\n }\r\n\r\n private _oldRotation: number;\r\n public get rotation(): number {\r\n return this.transform?.rotation ?? 0;\r\n }\r\n\r\n public set rotation(val: number) {\r\n if (this.transform) {\r\n this.transform.rotation = val;\r\n }\r\n }\r\n\r\n private _oldScale: Vector;\r\n public get scale(): Vector {\r\n return this.transform?.scale ?? Vector.One;\r\n }\r\n\r\n public set scale(val: Vector) {\r\n if (this.transform?.scale) {\r\n this.transform.scale = val;\r\n }\r\n }\r\n\r\n private _oldPos: Vector;\r\n public get pos(): Vector {\r\n return this.transform.pos;\r\n }\r\n\r\n public set pos(val: Vector) {\r\n this.transform.pos = val;\r\n }\r\n\r\n public get vel(): Vector {\r\n return this._motion.vel;\r\n }\r\n\r\n public set vel(val: Vector) {\r\n this._motion.vel = val;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: TileMapEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n\r\n /**\r\n * @param options\r\n */\r\n constructor(options: TileMapOptions) {\r\n super([], options.name);\r\n this.meshingLookBehind = options.meshingLookBehind ?? this.meshingLookBehind;\r\n this.addComponent(new TransformComponent());\r\n this.addComponent(new MotionComponent());\r\n this.addComponent(\r\n new BodyComponent({\r\n type: CollisionType.Fixed\r\n })\r\n );\r\n this.addComponent(\r\n new GraphicsComponent({\r\n onPostDraw: (ctx, delta) => this.draw(ctx, delta)\r\n })\r\n );\r\n this.addComponent(new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false));\r\n this.addComponent(new ColliderComponent());\r\n this._graphics = this.get(GraphicsComponent);\r\n this.transform = this.get(TransformComponent);\r\n this._motion = this.get(MotionComponent);\r\n this.collider = this.get(ColliderComponent);\r\n this._composite = this.collider.useCompositeCollider([]);\r\n\r\n this.transform.pos = options.pos ?? Vector.Zero;\r\n this._oldPos = this.transform.pos.clone();\r\n this._oldScale = this.transform.scale.clone();\r\n this.renderFromTopOfGraphic = options.renderFromTopOfGraphic ?? this.renderFromTopOfGraphic;\r\n this.tileWidth = options.tileWidth;\r\n this.tileHeight = options.tileHeight;\r\n this.rows = options.rows;\r\n this.columns = options.columns;\r\n\r\n this.tiles = new Array(this.rows * this.columns);\r\n this._rows = new Array(this.rows);\r\n this._cols = new Array(this.columns);\r\n let currentCol: Tile[] = [];\r\n for (let i = 0; i < this.columns; i++) {\r\n for (let j = 0; j < this.rows; j++) {\r\n const tile = new Tile({\r\n x: i,\r\n y: j,\r\n map: this\r\n });\r\n tile.map = this;\r\n this.tiles[i + j * this.columns] = tile;\r\n currentCol.push(tile);\r\n if (!this._rows[j]) {\r\n this._rows[j] = [];\r\n }\r\n this._rows[j].push(tile);\r\n }\r\n this._cols[i] = currentCol;\r\n currentCol = [];\r\n }\r\n\r\n this._graphics.localBounds = new BoundingBox({\r\n left: 0,\r\n top: 0,\r\n right: this.columns * this.tileWidth * this.scale.x,\r\n bottom: this.rows * this.tileHeight * this.scale.y\r\n });\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n this._engine = engine;\r\n }\r\n\r\n\r\n private _originalOffsets = new WeakMap();\r\n private _getOrSetColliderOriginalOffset(collider: Collider): Vector {\r\n if (!this._originalOffsets.has(collider)) {\r\n const originalOffset = collider.offset;\r\n this._originalOffsets.set(collider, originalOffset);\r\n return originalOffset;\r\n } else {\r\n return this._originalOffsets.get(collider);\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Tiles colliders based on the solid tiles in the tilemap.\r\n */\r\n private _updateColliders(): void {\r\n this.collider.$colliderRemoved.notifyAll(this._composite);\r\n this._composite.clearColliders();\r\n const colliders: BoundingBox[] = [];\r\n this._composite = this.collider.useCompositeCollider([]);\r\n let current: BoundingBox;\r\n\r\n /**\r\n * Returns wether or not the 2 boxes share an edge and are the same height\r\n * @param prev\r\n * @param next\r\n * @returns true if they share and edge, false if not\r\n */\r\n const shareEdges = (prev: BoundingBox, next: BoundingBox) => {\r\n if (prev && next) {\r\n // same top/bottom\r\n return prev.top === next.top &&\r\n prev.bottom === next.bottom &&\r\n // Shared right/left edge\r\n prev.right === next.left;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Potentially merges the current collider into a list of previous ones, mutating the list\r\n * If checkAndCombine returns true, the collider was successfully merged and should be thrown away\r\n * @param current current collider to test\r\n * @param colliders List of colliders to consider merging with\r\n * @param maxLookBack The amount of colliders to look back for combination\r\n * @returns false when no combination found, true when successfully combined\r\n */\r\n const checkAndCombine = (current: BoundingBox, colliders: BoundingBox[], maxLookBack = this.meshingLookBehind) => {\r\n if (!current) {\r\n return false;\r\n }\r\n // walk backwards through the list of colliders and combine with the first that shares an edge\r\n for (let i = colliders.length - 1; i >= 0; i--) {\r\n if (maxLookBack-- < 0) {\r\n // blunt the O(n^2) algorithm a bit\r\n return false;\r\n }\r\n const prev = colliders[i];\r\n if (shareEdges(prev, current)) {\r\n colliders[i] = prev.combine(current);\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n\r\n // ? configurable bias perhaps, horizontal strips vs. vertical ones\r\n // Bad tile collider packing algorithm\r\n for (let i = 0; i < this.columns; i++) {\r\n // Scan column for colliders\r\n for (let j = 0; j < this.rows; j++) {\r\n const tile = this.tiles[i + j * this.columns];\r\n // Current tile in column is solid build up current collider\r\n if (tile.solid) {\r\n // Use custom collider otherwise bounding box\r\n if (tile.getColliders().length > 0) {\r\n // tile with custom collider interrupting the current run\r\n for (const collider of tile.getColliders()) {\r\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\r\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n //we push any current collider before nulling the current run\r\n if (current && !checkAndCombine(current, colliders)) {\r\n colliders.push(current);\r\n }\r\n current = null;\r\n // Use the bounding box\r\n } else {\r\n if (!current) {\r\n // no current run, start one\r\n current = tile.defaultGeometry;\r\n } else {\r\n // combine with current run\r\n current = current.combine(tile.defaultGeometry);\r\n }\r\n }\r\n } else {\r\n // Not solid skip and cut off the current collider\r\n // End of run check and combine\r\n if (current && !checkAndCombine(current, colliders)) {\r\n colliders.push(current);\r\n }\r\n current = null;\r\n }\r\n }\r\n // After a column is complete check to see if it can be merged into the last one\r\n // Eno of run check and combine\r\n if (current && !checkAndCombine(current, colliders)) {\r\n // else new collider if no combination\r\n colliders.push(current);\r\n }\r\n current = null;\r\n }\r\n\r\n for (const c of colliders) {\r\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n this.collider.update();\r\n // Notify that colliders have been updated\r\n this.collider.$colliderAdded.notifyAll(this._composite);\r\n }\r\n\r\n /**\r\n * Returns the [[Tile]] by index (row major order)\r\n */\r\n public getTileByIndex(index: number): Tile {\r\n return this.tiles[index];\r\n }\r\n /**\r\n * Returns the [[Tile]] by its x and y integer coordinates\r\n *\r\n * For example, if I want the tile in fifth column (x), and second row (y):\r\n * `getTile(4, 1)` 0 based, so 0 is the first in row/column\r\n */\r\n public getTile(x: number, y: number): Tile {\r\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\r\n return null;\r\n }\r\n return this.tiles[x + y * this.columns];\r\n }\r\n /**\r\n * Returns the [[Tile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */\r\n public getTileByPoint(point: Vector): Tile | null {\r\n const {x, y} = this._getTileCoordinates(point);\r\n const tile = this.getTile(x, y);\r\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) {\r\n return tile;\r\n }\r\n return null;\r\n }\r\n\r\n private _getTileCoordinates(point: Vector): {x: number, y: number} {\r\n // Convert to Tile Space point\r\n point = this.transform.applyInverse(point);\r\n\r\n const x = Math.floor(point.x / this.tileWidth);\r\n const y = Math.floor(point.y / this.tileHeight);\r\n return {x, y};\r\n }\r\n\r\n public getRows(): readonly Tile[][] {\r\n return this._rows;\r\n }\r\n\r\n public getColumns(): readonly Tile[][] {\r\n return this._cols;\r\n }\r\n\r\n /**\r\n * Returns the on screen tiles for a tilemap, this will overshoot by a small amount because of the internal quad tree data structure.\r\n *\r\n * Useful if you need to perform specific logic on onscreen tiles\r\n */\r\n public getOnScreenTiles(): readonly Tile[] {\r\n let worldBounds = this._engine.screen.getWorldBounds();\r\n const maybeParallax = this.get(ParallaxComponent);\r\n if (maybeParallax && this.isInitialized) {\r\n let pos = this.pos;\r\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\r\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\r\n pos = pos.sub(parallaxOffset);\r\n // adjust world bounds by parallax factor\r\n worldBounds = worldBounds.translate(pos);\r\n }\r\n\r\n const bounds = this.transform.coordPlane === CoordPlane.Screen ?\r\n this._engine.screen.getScreenBounds() :\r\n worldBounds;\r\n const topLeft = this._getTileCoordinates(bounds.topLeft);\r\n const topRight = this._getTileCoordinates(bounds.topRight);\r\n const bottomRight = this._getTileCoordinates(bounds.bottomRight);\r\n const bottomLeft = this._getTileCoordinates(bounds.bottomLeft);\r\n\r\n const tileStartX = Math.min(\r\n clamp(topLeft.x, 0, this.columns - 1),\r\n clamp(topRight.x, 0, this.columns - 1)\r\n );\r\n const tileStartY = Math.min(\r\n clamp(topLeft.y, 0, this.rows - 1),\r\n clamp(topRight.y, 0, this.rows - 1)\r\n );\r\n const tileEndX = Math.max(\r\n clamp(bottomRight.x, 0, this.columns - 1),\r\n clamp(bottomLeft.x, 0, this.columns - 1)\r\n );\r\n const tileEndY = Math.max(\r\n clamp(bottomRight.y, 0, this.rows - 1),\r\n clamp(bottomLeft.y, 0, this.rows - 1)\r\n );\r\n\r\n const tiles: Tile[] = [];\r\n for (let x = tileStartX; x <= tileEndX; x++) {\r\n for (let y = tileStartY; y <= tileEndY; y++) {\r\n tiles.push(this.getTile(x, y));\r\n }\r\n }\r\n return tiles;\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n this._initialize(engine);\r\n this.onPreUpdate(engine, delta);\r\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n if (!this._oldPos.equals(this.pos) ||\r\n this._oldRotation !== this.rotation ||\r\n !this._oldScale.equals(this.scale)) {\r\n this.flagCollidersDirty();\r\n this.flagTilesDirty();\r\n }\r\n if (this._collidersDirty) {\r\n this._collidersDirty = false;\r\n this._updateColliders();\r\n }\r\n\r\n this._token++;\r\n\r\n this.pos.clone(this._oldPos);\r\n this._oldRotation = this.rotation;\r\n this.scale.clone(this._oldScale);\r\n this.transform.pos = this.pos;\r\n this.onPostUpdate(engine, delta);\r\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n }\r\n\r\n /**\r\n * Draws the tile map to the screen. Called by the [[Scene]].\r\n * @param ctx ExcaliburGraphicsContext\r\n * @param delta The number of milliseconds since the last draw\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n if (!this.isInitialized) {\n return;\n }\r\n this.emit('predraw', new PreDrawEvent(ctx as any, delta, this)); // TODO fix event\r\n\r\n let graphics: readonly Graphic[], graphicsIndex: number, graphicsLen: number;\r\n\r\n const tiles = this.getOnScreenTiles();\r\n for (let i = 0; i < tiles.length; i++) {\r\n const tile = tiles[i];\r\n // get non-negative tile sprites\r\n const offsets = tile.getGraphicsOffsets();\r\n graphics = tile.getGraphics();\r\n\r\n for (graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++) {\r\n // draw sprite, warning if sprite doesn't exist\r\n const graphic = graphics[graphicsIndex];\r\n const offset = offsets[graphicsIndex];\r\n if (graphic) {\r\n if (hasGraphicsTick(graphic)) {\r\n graphic?.tick(delta, this._token);\r\n }\r\n const offsetY = this.renderFromTopOfGraphic ? 0 : (graphic.height - this.tileHeight);\r\n graphic.draw(ctx, tile.x * this.tileWidth + offset.x, tile.y * this.tileHeight - offsetY + offset.y);\r\n }\r\n }\r\n }\r\n this.emit('postdraw', new PostDrawEvent(ctx as any, delta, this));\r\n }\r\n\r\n public debug(gfx: ExcaliburGraphicsContext, debugFlags: DebugConfig) {\r\n const {\r\n showAll,\r\n showGrid,\r\n gridColor,\r\n gridWidth,\r\n showSolidBounds: showColliderBounds,\r\n solidBoundsColor: colliderBoundsColor,\r\n showColliderGeometry\r\n } = debugFlags.tilemap;\r\n const {\r\n geometryColor,\r\n geometryLineWidth,\r\n geometryPointSize\r\n } = debugFlags.collider;\r\n const width = this.tileWidth * this.columns * this.scale.x;\r\n const height = this.tileHeight * this.rows * this.scale.y;\r\n const pos = this.pos;\r\n if (showGrid || showAll) {\r\n for (let r = 0; r < this.rows + 1; r++) {\r\n const yOffset = vec(0, r * this.tileHeight * this.scale.y);\r\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), gridColor, gridWidth);\r\n }\r\n\r\n for (let c = 0; c < this.columns + 1; c++) {\r\n const xOffset = vec(c * this.tileWidth * this.scale.x, 0);\r\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), gridColor, gridWidth);\r\n }\r\n }\r\n\r\n if (showAll || showColliderBounds || showColliderGeometry) {\r\n const colliders = this._composite.getColliders();\r\n gfx.save();\r\n gfx.translate(this.pos.x, this.pos.y);\r\n gfx.scale(this.scale.x, this.scale.y);\r\n for (const collider of colliders) {\r\n const bounds = collider.localBounds;\r\n const pos = collider.worldPos.sub(this.pos);\r\n if (showColliderBounds) {\r\n gfx.drawRectangle(pos, bounds.width, bounds.height, colliderBoundsColor);\r\n }\r\n }\r\n gfx.restore();\r\n if (showColliderGeometry) {\r\n for (const collider of colliders) {\r\n collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize });\r\n }\r\n }\r\n }\r\n\r\n if (showAll || showColliderBounds) {\r\n gfx.save();\r\n gfx.z = 999;\r\n if (showColliderBounds) {\r\n for (let i = 0; i < this.tiles.length; i++) {\r\n this.tiles[i].bounds.draw(gfx);\r\n }\r\n }\r\n gfx.restore();\r\n }\r\n }\r\n}\r\n\r\nexport interface TileOptions {\r\n /**\r\n * Integer tile x coordinate\r\n */\r\n x: number;\r\n /**\r\n * Integer tile y coordinate\r\n */\r\n y: number;\r\n map: TileMap;\r\n solid?: boolean;\r\n graphics?: Graphic[];\r\n}\r\n\r\n/**\r\n * TileMap Tile\r\n *\r\n * A light-weight object that occupies a space in a collision map. Generally\r\n * created by a [[TileMap]].\r\n *\r\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\r\n * of the sprites in the array so the last one will be drawn on top. You can\r\n * use transparency to create layers this way.\r\n */\r\nexport class Tile extends Entity {\r\n private _bounds: BoundingBox;\r\n private _geometry: BoundingBox;\r\n private _pos: Vector;\r\n private _posDirty = false;\r\n\r\n /**\r\n * Return the world position of the top left corner of the tile\r\n */\r\n public get pos() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n this._posDirty = false;\r\n }\r\n return this._pos;\r\n }\r\n\r\n /**\r\n * Integer x coordinate of the tile\r\n */\r\n public readonly x: number;\r\n\r\n /**\r\n * Integer y coordinate of the tile\r\n */\r\n public readonly y: number;\r\n\r\n private _width: number;\r\n /**\r\n * Width of the tile in pixels\r\n */\r\n public get width(): number {\r\n return this._width;\r\n }\r\n\r\n private _height: number;\r\n /**\r\n * Height of the tile in pixels\r\n */\r\n public get height(): number {\r\n return this._height;\r\n }\r\n\r\n /**\r\n * Reference to the TileMap this tile is associated with\r\n */\r\n public map: TileMap;\r\n\r\n private _solid = false;\r\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */\r\n public get solid(): boolean {\r\n return this._solid;\r\n }\r\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */\r\n public set solid(val: boolean) {\r\n this.map?.flagCollidersDirty();\r\n this._solid = val;\r\n }\r\n\r\n private _graphics: Graphic[] = [];\r\n private _offsets: Vector[] = [];\r\n\r\n /**\r\n * Current list of graphics for this tile\r\n */\r\n public getGraphics(): readonly Graphic[] {\r\n return this._graphics;\r\n }\r\n\r\n /**\r\n * Current list of offsets for this tile's graphics\r\n */\r\n public getGraphicsOffsets(): readonly Vector[] {\r\n return this._offsets;\r\n }\r\n\r\n /**\r\n * Add another [[Graphic]] to this TileMap tile\r\n * @param graphic\r\n */\r\n public addGraphic(graphic: Graphic, options?: { offset?: Vector }) {\r\n this._graphics.push(graphic);\r\n if (options?.offset) {\r\n this._offsets.push(options.offset);\r\n } else {\r\n this._offsets.push(Vector.Zero);\r\n }\r\n }\r\n\r\n /**\r\n * Remove an instance of a [[Graphic]] from this tile\r\n */\r\n public removeGraphic(graphic: Graphic) {\r\n const index = this._graphics.indexOf(graphic);\r\n if (index > -1) {\r\n this._graphics.splice(index, 1);\r\n this._offsets.splice(index, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Clear all graphics from this tile\r\n */\r\n public clearGraphics() {\r\n this._graphics.length = 0;\r\n this._offsets.length = 0;\r\n }\r\n\r\n /**\r\n * Current list of colliders for this tile\r\n */\r\n private _colliders: Collider[] = [];\r\n\r\n /**\r\n * Returns the list of colliders\r\n */\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n /**\r\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\r\n *\r\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */\r\n public addCollider(collider: Collider) {\r\n this._colliders.push(collider);\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Removes a collider from the [[Tile]]\r\n * @param collider\r\n */\r\n public removeCollider(collider: Collider) {\r\n const index = this._colliders.indexOf(collider);\r\n if (index > -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Clears all colliders from the [[Tile]]\r\n */\r\n public clearColliders() {\r\n this._colliders.length = 0;\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Arbitrary data storage per tile, useful for any game specific data\r\n */\r\n public data = new Map();\r\n\r\n constructor(options: TileOptions) {\r\n super();\r\n this.x = options.x;\r\n this.y = options.y;\r\n this.map = options.map;\r\n this._width = options.map.tileWidth * this.map.scale.x;\r\n this._height = options.map.tileHeight * this.map.scale.y;\r\n this.solid = options.solid ?? this.solid;\r\n this._graphics = options.graphics ?? [];\r\n this._recalculate();\r\n }\r\n\r\n public flagDirty() {\r\n return this._posDirty = true;\r\n }\r\n\r\n private _recalculate() {\r\n const geometryPos = this.map.pos.add(vec(this.x * this.map.tileWidth, this.y * this.map.tileHeight));\r\n this._geometry = new BoundingBox(geometryPos.x, geometryPos.y, geometryPos.x + this.map.tileWidth, geometryPos.y + this.map.tileHeight);\r\n\r\n this._width = this.map.tileWidth * this.map.scale.x;\r\n this._height = this.map.tileHeight * this.map.scale.y;\r\n\r\n this._pos = this.map.pos.add(\r\n vec(\r\n this.x * this._width,\r\n this.y * this._height));\r\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\r\n\r\n if (this.map.rotation) {\r\n this._bounds = this._bounds.rotate(this.map.rotation, this.map.pos);\r\n }\r\n this._posDirty = false;\r\n }\r\n\r\n /**\r\n * Tile bounds in world space\r\n */\r\n public get bounds() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n }\r\n return this._bounds;\r\n }\r\n\r\n public get defaultGeometry() {\r\n return this._geometry;\r\n }\r\n\r\n /**\r\n * Tile position in world space\r\n */\r\n public get center(): Vector {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n }\r\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\r\n }\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Screen } from './Screen';\r\nimport { EasingFunction, EasingFunctions } from './Util/EasingFunctions';\r\nimport { Vector, vec } from './Math/vector';\r\nimport { Actor } from './Actor';\r\nimport { removeItemFromArray } from './Util/Util';\r\nimport { CanUpdate, CanInitialize } from './Interfaces/LifecycleEvents';\r\nimport { PreUpdateEvent, PostUpdateEvent, InitializeEvent } from './Events';\r\nimport { BoundingBox } from './Collision/BoundingBox';\r\nimport { Logger } from './Util/Log';\r\nimport { ExcaliburGraphicsContext } from './Graphics/Context/ExcaliburGraphicsContext';\r\nimport { watchAny } from './Util/Watch';\r\nimport { AffineMatrix } from './Math/affine-matrix';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { pixelSnapEpsilon } from './Graphics';\r\nimport { sign } from './Math/util';\r\n\r\n/**\r\n * Interface that describes a custom camera strategy for tracking targets\r\n */\r\nexport interface CameraStrategy {\r\n /**\r\n * Target of the camera strategy that will be passed to the action\r\n */\r\n target: T;\r\n\r\n /**\r\n * Camera strategies perform an action to calculate a new focus returned out of the strategy\r\n * @param target The target object to apply this camera strategy (if any)\r\n * @param camera The current camera implementation in excalibur running the game\r\n * @param engine The current engine running the game\r\n * @param delta The elapsed time in milliseconds since the last frame\r\n */\r\n action: (target: T, camera: Camera, engine: Engine, delta: number) => Vector;\r\n}\r\n\r\n/**\r\n * Container to house convenience strategy methods\r\n * @internal\r\n */\r\nexport class StrategyContainer {\r\n constructor(public camera: Camera) {}\r\n\r\n /**\r\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\r\n * @param actor The actor to lock the camera to\r\n */\r\n public lockToActor(actor: Actor) {\r\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\r\n * @param actor The actor to lock the camera to\r\n * @param axis The axis to follow the actor on\r\n */\r\n public lockToActorAxis(actor: Actor, axis: Axis) {\r\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n * @param actor Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */\r\n public elasticToActor(actor: Actor, cameraElasticity: number, cameraFriction: number) {\r\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\r\n * @param actor Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */\r\n public radiusAroundActor(actor: Actor, radius: number) {\r\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\r\n * @param box The bounding box to limit the camera to.\r\n */\r\n public limitCameraBounds(box: BoundingBox) {\r\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\r\n }\r\n}\r\n\r\n/**\r\n * Camera axis enum\r\n */\r\nexport enum Axis {\r\n X,\r\n Y\r\n}\r\n\r\n/**\r\n * Lock a camera to the exact x/y position of an actor.\r\n */\r\nexport class LockCameraToActorStrategy implements CameraStrategy {\r\n constructor(public target: Actor) {}\r\n public action = (target: Actor, camera: Camera, engine: Engine, delta: number) => {\r\n const center = target.center;\r\n return center;\r\n };\r\n}\r\n\r\n/**\r\n * Lock a camera to a specific axis around an actor.\r\n */\r\nexport class LockCameraToActorAxisStrategy implements CameraStrategy {\r\n constructor(public target: Actor, public axis: Axis) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const center = target.center;\r\n const currentFocus = cam.getFocus();\r\n if (this.axis === Axis.X) {\r\n return new Vector(center.x, currentFocus.y);\r\n } else {\r\n return new Vector(currentFocus.x, center.y);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\r\n */\r\nexport class ElasticToActorStrategy implements CameraStrategy {\r\n /**\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n * @param target Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */\r\n constructor(public target: Actor, public cameraElasticity: number, public cameraFriction: number) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const position = target.center;\r\n let focus = cam.getFocus();\r\n let cameraVel = cam.vel.clone();\r\n\r\n // Calculate the stretch vector, using the spring equation\r\n // F = kX\r\n // https://en.wikipedia.org/wiki/Hooke's_law\r\n // Apply to the current camera velocity\r\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\r\n cameraVel = cameraVel.add(stretch);\r\n\r\n // Calculate the friction (-1 to apply a force in the opposition of motion)\r\n // Apply to the current camera velocity\r\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\r\n cameraVel = cameraVel.add(friction);\r\n\r\n // Update position by velocity deltas\r\n focus = focus.add(cameraVel);\r\n\r\n return focus;\r\n };\r\n}\r\n\r\nexport class RadiusAroundActorStrategy implements CameraStrategy {\r\n /**\r\n *\r\n * @param target Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */\r\n constructor(public target: Actor, public radius: number) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const position = target.center;\r\n const focus = cam.getFocus();\r\n\r\n const direction = position.sub(focus);\r\n const distance = direction.size;\r\n if (distance >= this.radius) {\r\n const offset = distance - this.radius;\r\n return focus.add(direction.normalize().scale(offset));\r\n }\r\n return focus;\r\n };\r\n}\r\n\r\n/**\r\n * Prevent a camera from going beyond the given camera dimensions.\r\n */\r\nexport class LimitCameraBoundsStrategy implements CameraStrategy {\r\n /**\r\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\r\n *\r\n * Note that this strategy does not perform any movement by itself.\r\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\r\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\r\n *\r\n * Make sure that the camera bounds are at least as large as the viewport size.\r\n * @param target The bounding box to limit the camera to\r\n */\r\n\r\n boundSizeChecked: boolean = false; // Check and warn only once\r\n\r\n constructor(public target: BoundingBox) {}\r\n\r\n public action = (target: BoundingBox, cam: Camera, _eng: Engine, _delta: number) => {\r\n const focus = cam.getFocus();\r\n\r\n if (!this.boundSizeChecked) {\r\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) {\r\n Logger.getInstance().warn('Camera bounds should not be smaller than the engine viewport');\r\n }\r\n this.boundSizeChecked = true;\r\n }\r\n\r\n let focusX = focus.x;\r\n let focusY = focus.y;\r\n if (focus.x < target.left + _eng.halfDrawWidth) {\r\n focusX = target.left + _eng.halfDrawWidth;\r\n } else if (focus.x > target.right - _eng.halfDrawWidth) {\r\n focusX = target.right - _eng.halfDrawWidth;\r\n }\r\n\r\n if (focus.y < target.top + _eng.halfDrawHeight) {\r\n focusY = target.top + _eng.halfDrawHeight;\r\n } else if (focus.y > target.bottom - _eng.halfDrawHeight) {\r\n focusY = target.bottom - _eng.halfDrawHeight;\r\n }\r\n\r\n return vec(focusX, focusY);\r\n };\r\n}\r\n\r\nexport type CameraEvents = {\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n initialize: InitializeEvent,\r\n\r\n}\r\n\r\nexport const CameraEvents = {\r\n Initialize: 'initialize',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate'\r\n};\r\n\r\n/**\r\n * Cameras\r\n *\r\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\r\n * to move around your game and set focus. They are used to determine\r\n * what is \"off screen\" and can be used to scale the game.\r\n *\r\n */\r\nexport class Camera implements CanUpdate, CanInitialize {\r\n public events = new EventEmitter();\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public inverse: AffineMatrix = AffineMatrix.identity();\r\n\r\n\r\n protected _follow: Actor;\r\n\r\n private _cameraStrategies: CameraStrategy[] = [];\r\n\r\n public strategy: StrategyContainer = new StrategyContainer(this);\r\n\r\n /**\r\n * Get or set current zoom of the camera, defaults to 1\r\n */\r\n private _z = 1;\r\n public get zoom(): number {\r\n return this._z;\r\n }\r\n\r\n public set zoom(val: number) {\r\n this._z = val;\r\n if (this._engine) {\r\n this._halfWidth = this._engine.halfDrawWidth;\r\n this._halfHeight = this._engine.halfDrawHeight;\r\n }\r\n }\r\n /**\r\n * Get or set rate of change in zoom, defaults to 0\r\n */\r\n public dz: number = 0;\r\n /**\r\n * Get or set zoom acceleration\r\n */\r\n public az: number = 0;\r\n\r\n /**\r\n * Current rotation of the camera\r\n */\r\n public rotation: number = 0;\r\n\r\n private _angularVelocity: number = 0;\r\n\r\n /**\r\n * Get or set the camera's angular velocity\r\n */\r\n public get angularVelocity(): number {\r\n return this._angularVelocity;\r\n }\r\n\r\n public set angularVelocity(value: number) {\r\n this._angularVelocity = value;\r\n }\r\n\r\n /**\r\n * Get or set the camera's position\r\n */\r\n private _posChanged = false;\r\n private _pos: Vector = watchAny(Vector.Zero, () => (this._posChanged = true));\r\n public get pos(): Vector {\r\n return this._pos;\r\n }\r\n public set pos(vec: Vector) {\r\n this._pos = watchAny(vec, () => (this._posChanged = true));\r\n this._posChanged = true;\r\n }\r\n /**\r\n * Interpolated camera position if more draws are running than updates\r\n *\r\n * Enabled when `Engine.fixedUpdateFps` is enabled, in all other cases this will be the same as pos\r\n */\r\n public drawPos: Vector = this.pos.clone();\r\n\r\n private _oldPos = this.pos.clone();\r\n\r\n /**\r\n * Get or set the camera's velocity\r\n */\r\n public vel: Vector = Vector.Zero;\r\n\r\n /**\r\n * Get or set the camera's acceleration\r\n */\r\n public acc: Vector = Vector.Zero;\r\n\r\n private _cameraMoving: boolean = false;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1000; // 1 second\r\n private _lerpStart: Vector = null;\r\n private _lerpEnd: Vector = null;\r\n private _lerpResolve: (value: Vector) => void;\r\n private _lerpPromise: Promise;\r\n\r\n //camera effects\r\n protected _isShaking: boolean = false;\r\n private _shakeMagnitudeX: number = 0;\r\n private _shakeMagnitudeY: number = 0;\r\n private _shakeDuration: number = 0;\r\n private _elapsedShakeTime: number = 0;\r\n private _xShake: number = 0;\r\n private _yShake: number = 0;\r\n\r\n protected _isZooming: boolean = false;\r\n private _zoomStart: number = 1;\r\n private _zoomEnd: number = 1;\r\n private _currentZoomTime: number = 0;\r\n private _zoomDuration: number = 0;\r\n\r\n private _zoomResolve: (val: boolean) => void;\r\n private _zoomPromise: Promise;\r\n private _zoomEasing: EasingFunction = EasingFunctions.EaseInOutCubic;\r\n private _easing: EasingFunction = EasingFunctions.EaseInOutCubic;\r\n\r\n private _halfWidth: number = 0;\r\n private _halfHeight: number = 0;\r\n\r\n /**\r\n * Get the camera's x position\r\n */\r\n public get x() {\r\n return this.pos.x;\r\n }\r\n\r\n /**\r\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\r\n */\r\n public set x(value: number) {\r\n if (!this._follow && !this._cameraMoving) {\r\n this.pos = vec(value, this.pos.y);\r\n }\r\n }\r\n\r\n /**\r\n * Get the camera's y position\r\n */\r\n public get y() {\r\n return this.pos.y;\r\n }\r\n\r\n /**\r\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\r\n */\r\n public set y(value: number) {\r\n if (!this._follow && !this._cameraMoving) {\r\n this.pos = vec(this.pos.x, value);\r\n }\r\n }\r\n\r\n /**\r\n * Get or set the camera's x velocity\r\n */\r\n public get dx() {\r\n return this.vel.x;\r\n }\r\n\r\n public set dx(value: number) {\r\n this.vel = vec(value, this.vel.y);\r\n }\r\n\r\n /**\r\n * Get or set the camera's y velocity\r\n */\r\n public get dy() {\r\n return this.vel.y;\r\n }\r\n\r\n public set dy(value: number) {\r\n this.vel = vec(this.vel.x, value);\r\n }\r\n\r\n /**\r\n * Get or set the camera's x acceleration\r\n */\r\n public get ax() {\r\n return this.acc.x;\r\n }\r\n\r\n public set ax(value: number) {\r\n this.acc = vec(value, this.acc.y);\r\n }\r\n\r\n /**\r\n * Get or set the camera's y acceleration\r\n */\r\n public get ay() {\r\n return this.acc.y;\r\n }\r\n\r\n public set ay(value: number) {\r\n this.acc = vec(this.acc.x, value);\r\n }\r\n\r\n /**\r\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\r\n */\r\n public getFocus() {\r\n return this.pos;\r\n }\r\n\r\n /**\r\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\r\n * @param pos The target position to move to\r\n * @param duration The duration in milliseconds the move should last\r\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\r\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\r\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\r\n */\r\n public move(pos: Vector, duration: number, easingFn: EasingFunction = EasingFunctions.EaseInOutCubic): Promise {\r\n if (typeof easingFn !== 'function') {\r\n throw 'Please specify an EasingFunction';\r\n }\r\n\r\n // cannot move when following an actor\r\n if (this._follow) {\r\n return Promise.reject(pos);\r\n }\r\n\r\n // resolve existing promise, if any\r\n if (this._lerpPromise && this._lerpResolve) {\r\n this._lerpResolve(pos);\r\n }\r\n\r\n this._lerpPromise = new Promise((resolve) => {\r\n this._lerpResolve = resolve;\r\n });\r\n this._lerpStart = this.getFocus().clone();\r\n this._lerpDuration = duration;\r\n this._lerpEnd = pos;\r\n this._currentLerpTime = 0;\r\n this._cameraMoving = true;\r\n this._easing = easingFn;\r\n\r\n return this._lerpPromise;\r\n }\r\n\r\n /**\r\n * Sets the camera to shake at the specified magnitudes for the specified duration\r\n * @param magnitudeX The x magnitude of the shake\r\n * @param magnitudeY The y magnitude of the shake\r\n * @param duration The duration of the shake in milliseconds\r\n */\r\n public shake(magnitudeX: number, magnitudeY: number, duration: number) {\r\n this._isShaking = true;\r\n this._shakeMagnitudeX = magnitudeX;\r\n this._shakeMagnitudeY = magnitudeY;\r\n this._shakeDuration = duration;\r\n }\r\n\r\n /**\r\n * Zooms the camera in or out by the specified scale over the specified duration.\r\n * If no duration is specified, it take effect immediately.\r\n * @param scale The scale of the zoom\r\n * @param duration The duration of the zoom in milliseconds\r\n */\r\n public zoomOverTime(scale: number, duration: number = 0, easingFn: EasingFunction = EasingFunctions.EaseInOutCubic): Promise {\r\n this._zoomPromise = new Promise((resolve) => {\r\n this._zoomResolve = resolve;\r\n });\r\n\r\n if (duration) {\r\n this._isZooming = true;\r\n this._zoomEasing = easingFn;\r\n this._currentZoomTime = 0;\r\n this._zoomDuration = duration;\r\n this._zoomStart = this.zoom;\r\n this._zoomEnd = scale;\r\n } else {\r\n this._isZooming = false;\r\n this.zoom = scale;\r\n return Promise.resolve(true);\r\n }\r\n\r\n return this._zoomPromise;\r\n }\r\n\r\n private _viewport: BoundingBox = null;\r\n /**\r\n * Gets the bounding box of the viewport of this camera in world coordinates\r\n */\r\n public get viewport(): BoundingBox {\r\n if (this._viewport) {\r\n return this._viewport;\r\n }\r\n\r\n return new BoundingBox(0, 0, 0, 0);\r\n }\r\n\r\n /**\r\n * Adds a new camera strategy to this camera\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */\r\n public addStrategy(cameraStrategy: CameraStrategy) {\r\n this._cameraStrategies.push(cameraStrategy);\r\n }\r\n\r\n /**\r\n * Removes a camera strategy by reference\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */\r\n public removeStrategy(cameraStrategy: CameraStrategy) {\r\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\r\n }\r\n\r\n /**\r\n * Clears all camera strategies from the camera\r\n */\r\n public clearAllStrategies() {\r\n this._cameraStrategies.length = 0;\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */\r\n public onPreUpdate(engine: Engine, delta: number): void {\r\n // Overridable\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onPostUpdate(engine: Engine, delta: number): void {\r\n // Overridable\r\n }\r\n\r\n private _engine: Engine;\r\n private _screen: Screen;\r\n private _isInitialized = false;\r\n public get isInitialized() {\r\n return this._isInitialized;\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n this._engine = engine;\r\n this._screen = engine.screen;\r\n\r\n const currentRes = this._screen.contentArea;\r\n let center = vec(currentRes.width / 2, currentRes.height / 2);\r\n if (!this._engine.loadingComplete) {\r\n // If there was a loading screen, we peek the configured resolution\r\n const res = this._screen.peekResolution();\r\n if (res) {\r\n center = vec(res.width / 2, res.height / 2);\r\n }\r\n }\r\n this._halfWidth = center.x;\r\n this._halfHeight = center.y;\r\n\r\n // If the user has not set the camera pos, apply default center screen position\r\n if (!this._posChanged) {\r\n this.pos = center;\r\n }\r\n this.pos.clone(this.drawPos);\r\n // First frame bootstrap\r\n\r\n // Ensure camera tx is correct\r\n // Run update twice to ensure properties are init'd\r\n this.updateTransform(this.pos);\r\n\r\n // Run strategies for first frame\r\n this.runStrategies(engine, engine.clock.elapsed());\r\n\r\n // Setup the first frame viewport\r\n this.updateViewport();\r\n\r\n // It's important to update the camera after strategies\r\n // This prevents jitter\r\n this.updateTransform(this.pos);\r\n this.pos.clone(this._oldPos);\r\n\r\n this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onInitialize(engine: Engine) {\r\n // Overridable\r\n }\r\n\r\n public emit>(eventName: TEventName, event: CameraEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n public runStrategies(engine: Engine, delta: number) {\r\n for (const s of this._cameraStrategies) {\r\n this.pos = s.action.call(s, s.target, this, engine, delta);\r\n }\r\n }\r\n\r\n public updateViewport() {\r\n // recalculate viewport\r\n this._viewport = new BoundingBox(\r\n this.x - this._halfWidth,\r\n this.y - this._halfHeight,\r\n this.x + this._halfWidth,\r\n this.y + this._halfHeight\r\n );\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n this.pos.clone(this._oldPos);\r\n\r\n // Update placements based on linear algebra\r\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\r\n this.zoom += (this.dz * delta) / 1000;\r\n\r\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\r\n this.dz += (this.az * delta) / 1000;\r\n\r\n this.rotation += (this.angularVelocity * delta) / 1000;\r\n\r\n if (this._isZooming) {\r\n if (this._currentZoomTime < this._zoomDuration) {\r\n const zoomEasing = this._zoomEasing;\r\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\r\n\r\n this.zoom = newZoom;\r\n this._currentZoomTime += delta;\r\n } else {\r\n this._isZooming = false;\r\n this.zoom = this._zoomEnd;\r\n this._currentZoomTime = 0;\r\n this._zoomResolve(true);\r\n }\r\n }\r\n\r\n if (this._cameraMoving) {\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\r\n\r\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\r\n\r\n this.pos = lerpPoint;\r\n\r\n this._currentLerpTime += delta;\r\n } else {\r\n this.pos = this._lerpEnd;\r\n const end = this._lerpEnd.clone();\r\n\r\n this._lerpStart = null;\r\n this._lerpEnd = null;\r\n this._currentLerpTime = 0;\r\n this._cameraMoving = false;\r\n // Order matters here, resolve should be last so any chain promises have a clean slate\r\n this._lerpResolve(end);\r\n }\r\n }\r\n\r\n if (this._isDoneShaking()) {\r\n this._isShaking = false;\r\n this._elapsedShakeTime = 0;\r\n this._shakeMagnitudeX = 0;\r\n this._shakeMagnitudeY = 0;\r\n this._shakeDuration = 0;\r\n this._xShake = 0;\r\n this._yShake = 0;\r\n } else {\r\n this._elapsedShakeTime += delta;\r\n this._xShake = ((Math.random() * this._shakeMagnitudeX) | 0) + 1;\r\n this._yShake = ((Math.random() * this._shakeMagnitudeY) | 0) + 1;\r\n }\r\n\r\n this.runStrategies(engine, delta);\r\n\r\n this.updateViewport();\r\n\r\n // It's important to update the camera after strategies\r\n // This prevents jitter\r\n this.updateTransform(this.pos);\r\n\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n private _snapPos = vec(0, 0);\r\n /**\r\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\r\n * @param ctx Canvas context to apply transformations\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext): void {\r\n // default to the current position\r\n this.pos.clone(this.drawPos);\r\n\r\n // interpolation if fixed update is on\r\n // must happen on the draw, because more draws are potentially happening than updates\r\n if (this._engine.fixedUpdateFps) {\r\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\r\n const interpolatedPos = this.pos.scale(blend).add(\r\n this._oldPos.scale(1.0 - blend)\r\n );\r\n interpolatedPos.clone(this.drawPos);\r\n this.updateTransform(interpolatedPos);\r\n }\r\n // Snap camera to pixel\r\n if (ctx.snapToPixel) {\r\n const snapPos = this.drawPos.clone(this._snapPos);\r\n snapPos.x = ~~(snapPos.x + pixelSnapEpsilon * sign(snapPos.x));\r\n snapPos.y = ~~(snapPos.y + pixelSnapEpsilon * sign(snapPos.y));\r\n snapPos.clone(this.drawPos);\r\n this.updateTransform(snapPos);\r\n }\r\n ctx.multiply(this.transform);\r\n }\r\n\r\n public updateTransform(pos: Vector) {\r\n // center the camera\r\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\r\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\r\n const cameraPos = vec(-pos.x + newCanvasWidth / 2 + this._xShake, -pos.y + newCanvasHeight / 2 + this._yShake);\r\n\r\n // Calculate camera transform\r\n this.transform.reset();\r\n\r\n this.transform.scale(this.zoom, this.zoom);\r\n\r\n // rotate about the focus\r\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\r\n this.transform.rotate(this.rotation);\r\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\r\n\r\n this.transform.translate(cameraPos.x, cameraPos.y);\r\n this.transform.inverse(this.inverse);\r\n }\r\n\r\n private _isDoneShaking(): boolean {\r\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\r\n }\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Vector } from './Math/vector';\r\nimport { ExitTriggerEvent, EnterTriggerEvent, CollisionEndEvent, CollisionStartEvent } from './Events';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { Entity } from './EntityComponentSystem';\r\nimport { Actor, ActorEvents } from './Actor';\r\nimport { EventEmitter } from './EventEmitter';\r\n\r\nexport type TriggerEvents = ActorEvents & {\r\n exit: ExitTriggerEvent,\r\n enter: EnterTriggerEvent\r\n}\r\n\r\nexport const TriggerEvents = {\r\n ExitTrigger: 'exit',\r\n EnterTrigger: 'enter'\r\n};\r\n\r\n/**\r\n * TriggerOptions\r\n */\r\nexport interface TriggerOptions {\r\n // position of the trigger\r\n pos: Vector;\r\n // width of the trigger\r\n width: number;\r\n // height of the trigger\r\n height: number;\r\n // whether the trigger is visible or not\r\n visible: boolean;\r\n // action to take when triggered\r\n action: () => void;\r\n // if specified the trigger will only fire on a specific actor and overrides any filter\r\n target: Entity;\r\n // Returns true if the triggers should fire on the collided actor\r\n filter: (actor: Entity) => boolean;\r\n // -1 if it should repeat forever\r\n repeat: number;\r\n}\r\n\r\nconst triggerDefaults: Partial = {\r\n pos: Vector.Zero,\r\n width: 10,\r\n height: 10,\r\n visible: false,\r\n action: () => {\r\n return;\r\n },\r\n filter: () => true,\r\n repeat: -1\r\n};\r\n\r\n/**\r\n * Triggers are a method of firing arbitrary code on collision. These are useful\r\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\r\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\r\n */\r\nexport class Trigger extends Actor {\r\n public events = new EventEmitter();\r\n private _target: Entity;\r\n /**\r\n * Action to fire when triggered by collision\r\n */\r\n public action: () => void = () => {\r\n return;\r\n };\r\n /**\r\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\r\n * filter return true for the collided actor.\r\n */\r\n public filter: (actor: Entity) => boolean = () => true;\r\n /**\r\n * Number of times to repeat before killing the trigger,\r\n */\r\n public repeat: number = -1;\r\n\r\n /**\r\n *\r\n * @param opts Trigger options\r\n */\r\n constructor(opts: Partial) {\r\n super({ x: opts.pos.x, y: opts.pos.y, width: opts.width, height: opts.height });\r\n opts = {\r\n ...triggerDefaults,\r\n ...opts\r\n };\r\n\r\n this.filter = opts.filter || this.filter;\r\n this.repeat = opts.repeat || this.repeat;\r\n this.action = opts.action || this.action;\r\n if (opts.target) {\r\n this.target = opts.target;\r\n }\r\n\r\n this.graphics.visible = opts.visible;\r\n this.body.collisionType = CollisionType.Passive;\r\n\r\n this.events.on('collisionstart', (evt: CollisionStartEvent) => {\r\n if (this.filter(evt.other)) {\r\n this.events.emit('enter', new EnterTriggerEvent(this, evt.other));\r\n this._dispatchAction();\r\n // remove trigger if its done, -1 repeat forever\r\n if (this.repeat === 0) {\r\n this.kill();\r\n }\r\n }\r\n });\r\n\r\n this.events.on('collisionend', (evt: CollisionEndEvent) => {\r\n if (this.filter(evt.other)) {\r\n this.events.emit('exit', new ExitTriggerEvent(this, evt.other));\r\n }\r\n });\r\n }\r\n\r\n public set target(target: Entity) {\r\n this._target = target;\r\n this.filter = (actor: Entity) => actor === target;\r\n }\r\n\r\n public get target() {\r\n return this._target;\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n }\r\n\r\n private _dispatchAction() {\r\n if (this.repeat !== 0) {\r\n this.action.call(this);\r\n this.repeat--;\r\n }\r\n }\r\n}\r\n","/**\r\n * Higher priorities run earlier than others in the system update\r\n */\r\nexport const SystemPriority = {\r\n Highest: -Infinity,\r\n Higher: -5,\r\n Average: 0,\r\n Lower: 5,\r\n Lowest: Infinity\r\n} as const;","import { Scene } from '../Scene';\r\nimport { SystemPriority } from './Priority';\r\nimport { World } from './World';\r\n\r\n/**\r\n * Enum that determines whether to run the system in the update or draw phase\r\n */\r\nexport enum SystemType {\r\n Update = 'update',\r\n Draw = 'draw'\r\n}\r\n\r\n/**\r\n * An Excalibur [[System]] that updates entities of certain types.\r\n * Systems are scene specific\r\n *\r\n *\r\n *\r\n * Excalibur Systems currently require at least 1 Component type to operated\r\n *\r\n * Multiple types are declared as a type union\r\n * For example:\r\n *\r\n * ```typescript\r\n * class MySystem extends System {\r\n * public readonly types = ['a', 'b'] as const;\r\n * public readonly systemType = SystemType.Update;\r\n * public update(entities: Entity) {\r\n * ...\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport abstract class System {\r\n\r\n /**\r\n * Determine whether the system is called in the [[SystemType.Update]] or the [[SystemType.Draw]] phase. Update is first, then Draw.\r\n */\r\n abstract readonly systemType: SystemType;\r\n\r\n /**\r\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\r\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\r\n * For a system to execute after all other a higher priority value (10 for example) must be set.\r\n */\r\n public priority: number = SystemPriority.Average;\r\n\r\n /**\r\n * Optionally specify an initialize handler\r\n * @param scene\r\n */\r\n initialize?(world: World, scene: Scene): void;\r\n\r\n /**\r\n * Update all entities that match this system's types\r\n * @param entities Entities to update that match this system's types\r\n * @param elapsedMs Time in milliseconds\r\n */\r\n abstract update(elapsedMs: number): void;\r\n\r\n /**\r\n * Optionally run a preupdate before the system processes matching entities\r\n * @param scene\r\n * @param elapsedMs Time in milliseconds since the last frame\r\n */\r\n preupdate?(scene: Scene, elapsedMs: number): void;\r\n\r\n /**\r\n * Optionally run a postupdate after the system processes matching entities\r\n * @param scene\r\n * @param elapsedMs Time in milliseconds since the last frame\r\n */\r\n postupdate?(scene: Scene, elapsedMs: number): void;\r\n}\r\n","import { Entity } from './Entity';\r\nimport { World } from './World';\r\nimport { removeItemFromArray } from '../Util/Util';\r\nimport { Scene } from '../Scene';\r\n\r\n// Add/Remove entities and components\r\n\r\nexport class EntityManager {\r\n public entities: Entity[] = [];\r\n public _entityIndex: { [entityId: string]: Entity } = {};\r\n\r\n constructor(private _world: World) {}\r\n\r\n /**\r\n * Runs the entity lifecycle\r\n * @param scene\r\n * @param elapsed\r\n */\r\n public updateEntities(scene: Scene, elapsed: number) {\r\n for (const entity of this.entities) {\r\n entity.update(scene.engine, elapsed);\r\n if (!entity.active) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n }\r\n\r\n public findEntitiesForRemoval() {\r\n for (const entity of this.entities) {\r\n if (!entity.active) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Adds an entity to be tracked by the EntityManager\r\n * @param entity\r\n */\r\n public addEntity(entity: Entity): void {\r\n entity.active = true;\r\n entity.scene = this._world.scene;\r\n if (entity && !this._entityIndex[entity.id]) {\r\n this._entityIndex[entity.id] = entity;\r\n this.entities.push(entity);\r\n this._world.queryManager.addEntity(entity);\r\n\r\n // if entity has children\r\n entity.children.forEach((c) => {\r\n c.scene = entity.scene;\r\n this.addEntity(c);\r\n });\r\n entity.childrenAdded$.register({\r\n notify: (e) => {\r\n this.addEntity(e);\r\n }\r\n });\r\n entity.childrenRemoved$.register({\r\n notify: (e) => {\r\n this.removeEntity(e, false);\r\n }\r\n });\r\n }\r\n }\r\n\r\n public removeEntity(entity: Entity, deferred?: boolean): void;\r\n public removeEntity(id: number, deferred?: boolean): void;\r\n public removeEntity(idOrEntity: number | Entity, deferred = true): void {\r\n let id = 0;\r\n if (idOrEntity instanceof Entity) {\r\n id = idOrEntity.id;\r\n } else {\r\n id = idOrEntity;\r\n }\r\n const entity = this._entityIndex[id];\r\n if (entity && entity.active) {\r\n entity.active = false;\r\n }\r\n\r\n if (entity && deferred) {\r\n this._entitiesToRemove.push(entity);\r\n return;\r\n }\r\n\r\n delete this._entityIndex[id];\r\n if (entity) {\r\n entity.scene = null;\r\n removeItemFromArray(entity, this.entities);\r\n this._world.queryManager.removeEntity(entity);\r\n\r\n // if entity has children\r\n entity.children.forEach((c) => {\r\n c.scene = null;\r\n this.removeEntity(c, deferred);\r\n });\r\n entity.childrenAdded$.clear();\r\n entity.childrenRemoved$.clear();\r\n\r\n // stats\r\n if (this._world?.scene?.engine) {\r\n this._world.scene.engine.stats.currFrame.actors.killed++;\r\n }\r\n }\r\n }\r\n\r\n private _entitiesToRemove: Entity[] = [];\r\n public processEntityRemovals(): void {\r\n for (const entity of this._entitiesToRemove) {\r\n if (entity.active) {\r\n continue;\r\n }\r\n this.removeEntity(entity, false);\r\n }\r\n this._entitiesToRemove.length = 0;\r\n }\r\n\r\n public processComponentRemovals(): void {\r\n for (const entity of this.entities) {\r\n entity.processComponentRemoval();\r\n }\r\n }\r\n\r\n public getById(id: number): Entity {\r\n return this._entityIndex[id];\r\n }\r\n\r\n public getByName(name: string): Entity[]{\r\n return this.entities.filter(e => e.name === name);\r\n }\r\n\r\n public clear(): void {\r\n for (let i = this.entities.length - 1; i >= 0; i--) {\r\n this.removeEntity(this.entities[i]);\r\n }\r\n }\r\n}\r\n","import { Entity } from './Entity';\r\nimport { Observable } from '../Util/Observable';\r\nimport { Component, ComponentCtor } from '../EntityComponentSystem/Component';\r\n\r\nexport type ComponentInstance = T extends ComponentCtor ? R : never;\r\n\r\n/**\r\n * Represents query for entities that match a list of types that is cached and observable\r\n *\r\n * Queries can be strongly typed by supplying a type union in the optional type parameter\r\n * ```typescript\r\n * const queryAB = new ex.Query(['A', 'B']);\r\n * ```\r\n */\r\nexport class Query = never> {\r\n public readonly id: string;\r\n public components = new Set();\r\n public entities: Entity>[] = [];\r\n /**\r\n * This fires right after the component is added\r\n */\r\n public entityAdded$ = new Observable>>();\r\n /**\r\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\r\n */\r\n public entityRemoved$ = new Observable>>();\r\n\r\n constructor(public readonly requiredComponents: TKnownComponentCtors[]) {\r\n if (requiredComponents.length === 0) {\r\n throw new Error('Cannot create query without components');\r\n }\r\n for (const type of requiredComponents) {\r\n this.components.add(type);\r\n }\r\n\r\n this.id = Query.createId(requiredComponents);\r\n }\r\n\r\n static createId(requiredComponents: Function[]) {\r\n // TODO what happens if a user defines the same type name as a built in type\r\n // ! TODO this could be dangerous depending on the bundler's settings for names\r\n // Maybe some kind of hash function is better here?\r\n return requiredComponents.slice().map(c => c.name).sort().join('-');\r\n }\r\n\r\n /**\r\n * Potentially adds an entity to a query index, returns true if added, false if not\r\n * @param entity\r\n */\r\n checkAndAdd(entity: Entity) {\r\n if (!this.entities.includes(entity) && entity.hasAll(Array.from(this.components))) {\r\n this.entities.push(entity);\r\n this.entityAdded$.notifyAll(entity);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n removeEntity(entity: Entity) {\r\n const index = this.entities.indexOf(entity);\r\n if (index > -1) {\r\n this.entities.splice(index, 1);\r\n this.entityRemoved$.notifyAll(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a list of entities that match the query\r\n * @param sort Optional sorting function to sort entities returned from the query\r\n */\r\n public getEntities(sort?: (a: Entity, b: Entity) => number): Entity>[] {\r\n if (sort) {\r\n this.entities.sort(sort);\r\n }\r\n return this.entities;\r\n }\r\n}","import { Observable } from '../Util/Observable';\r\nimport { Entity } from './Entity';\r\n\r\n\r\nexport class TagQuery {\r\n public readonly id: string;\r\n public tags = new Set();\r\n public entities: Entity[] = [];\r\n /**\r\n * This fires right after the component is added\r\n */\r\n public entityAdded$ = new Observable>();\r\n /**\r\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\r\n */\r\n public entityRemoved$ = new Observable>();\r\n\r\n constructor(public readonly requiredTags: TKnownTags[]) {\r\n if (requiredTags.length === 0) {\r\n throw new Error('Cannot create tag query without tags');\r\n }\r\n for (const tag of requiredTags) {\r\n this.tags.add(tag);\r\n }\r\n\r\n this.id = TagQuery.createId(requiredTags);\r\n }\r\n\r\n static createId(requiredComponents: string[]) {\r\n return requiredComponents.slice().sort().join('-');\r\n }\r\n\r\n checkAndAdd(entity: Entity) {\r\n if (!this.entities.includes(entity) && entity.hasAllTags(Array.from(this.tags))) {\r\n this.entities.push(entity);\r\n this.entityAdded$.notifyAll(entity);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n removeEntity(entity: Entity) {\r\n const index = this.entities.indexOf(entity);\r\n if (index > -1) {\r\n this.entities.splice(index, 1);\r\n this.entityRemoved$.notifyAll(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a list of entities that match the query\r\n * @param sort Optional sorting function to sort entities returned from the query\r\n */\r\n public getEntities(sort?: (a: Entity, b: Entity) => number): Entity[] {\r\n if (sort) {\r\n this.entities.sort(sort);\r\n }\r\n return this.entities;\r\n }\r\n}","import { Entity } from './Entity';\r\nimport { Query } from './Query';\r\nimport { Component, ComponentCtor } from './Component';\r\nimport { World } from './World';\r\nimport { TagQuery } from './TagQuery';\r\n\r\n/**\r\n * The query manager is responsible for updating all queries when entities/components change\r\n */\r\nexport class QueryManager {\r\n private _queries = new Map>();\r\n private _addComponentHandlers = new Map any>();\r\n private _removeComponentHandlers = new Map any>();\r\n private _componentToQueriesIndex = new Map, Query[]>();\r\n\r\n private _tagQueries = new Map>();\r\n private _addTagHandlers = new Map any>();\r\n private _removeTagHandlers = new Map any>();\r\n private _tagToQueriesIndex = new Map[]>();\r\n\r\n constructor(private _world: World) {}\r\n\r\n public createQuery>(\r\n requiredComponents: TKnownComponentCtors[]): Query {\r\n const id = Query.createId(requiredComponents);\r\n if (this._queries.has(id)) {\r\n // short circuit if query is already created\r\n return this._queries.get(id) as Query;\r\n }\r\n\r\n const query = new Query(requiredComponents);\r\n\r\n this._queries.set(query.id, query);\r\n\r\n // index maintenance\r\n for (const component of requiredComponents) {\r\n const queries = this._componentToQueriesIndex.get(component);\r\n if (!queries) {\r\n this._componentToQueriesIndex.set(component, [query]);\r\n } else {\r\n queries.push(query);\r\n }\r\n }\r\n\r\n for (const entity of this._world.entities) {\r\n this.addEntity(entity);\r\n }\r\n\r\n return query;\r\n }\r\n\r\n public createTagQuery(requiredTags: TKnownTags[]): TagQuery {\r\n const id = TagQuery.createId(requiredTags);\r\n if (this._tagQueries.has(id)) {\r\n // short circuit if query is already created\r\n return this._tagQueries.get(id) as TagQuery;\r\n }\r\n\r\n const query = new TagQuery(requiredTags);\r\n\r\n this._tagQueries.set(query.id, query);\r\n\r\n // index maintenance\r\n for (const tag of requiredTags) {\r\n const queries = this._tagToQueriesIndex.get(tag);\r\n if (!queries) {\r\n this._tagToQueriesIndex.set(tag, [query]);\r\n } else {\r\n queries.push(query);\r\n }\r\n }\r\n\r\n for (const entity of this._world.entities) {\r\n this.addEntity(entity);\r\n }\r\n\r\n return query;\r\n }\r\n\r\n private _createAddComponentHandler = (entity: Entity) => (c: Component) => {\r\n this.addComponent(entity, c);\r\n };\r\n\r\n private _createRemoveComponentHandler = (entity: Entity) => (c: Component) => {\r\n this.removeComponent(entity, c);\r\n };\r\n\r\n private _createAddTagHandler = (entity: Entity) => (tag: string) => {\r\n this.addTag(entity, tag);\r\n };\r\n\r\n private _createRemoveTagHandler = (entity: Entity) => (tag: string) => {\r\n this.removeTag(entity, tag);\r\n };\r\n\r\n /**\r\n * Scans queries and locates any that need this entity added\r\n * @param entity\r\n */\r\n addEntity(entity: Entity) {\r\n const maybeAddComponent = this._addComponentHandlers.get(entity);\r\n const maybeRemoveComponent = this._removeComponentHandlers.get(entity);\r\n const addComponent = maybeAddComponent ?? this._createAddComponentHandler(entity);\r\n const removeComponent = maybeRemoveComponent ?? this._createRemoveComponentHandler(entity);\r\n this._addComponentHandlers.set(entity, addComponent);\r\n this._removeComponentHandlers.set(entity, removeComponent);\r\n\r\n const maybeAddTag = this._addTagHandlers.get(entity);\r\n const maybeRemoveTag = this._removeTagHandlers.get(entity);\r\n const addTag = maybeAddTag ?? this._createAddTagHandler(entity);\r\n const removeTag = maybeRemoveTag ?? this._createRemoveTagHandler(entity);\r\n this._addTagHandlers.set(entity, addTag);\r\n this._removeTagHandlers.set(entity, removeTag);\r\n\r\n for (const query of this._queries.values()) {\r\n query.checkAndAdd(entity);\r\n }\r\n for (const tagQuery of this._tagQueries.values()) {\r\n tagQuery.checkAndAdd(entity);\r\n }\r\n entity.componentAdded$.subscribe(addComponent);\r\n entity.componentRemoved$.subscribe(removeComponent);\r\n entity.tagAdded$.subscribe(addTag);\r\n entity.tagRemoved$.subscribe(removeTag);\r\n }\r\n\r\n /**\r\n * Scans queries and locates any that need this entity removed\r\n * @param entity\r\n */\r\n removeEntity(entity: Entity) {\r\n // Handle components\r\n const addComponent = this._addComponentHandlers.get(entity);\r\n const removeComponent = this._removeComponentHandlers.get(entity);\r\n for (const query of this._queries.values()) {\r\n query.removeEntity(entity);\r\n }\r\n if (addComponent) {\r\n entity.componentAdded$.unsubscribe(addComponent);\r\n }\r\n if (removeComponent) {\r\n entity.componentRemoved$.unsubscribe(removeComponent);\r\n }\r\n\r\n // Handle tags\r\n const addTag = this._addTagHandlers.get(entity);\r\n const removeTag = this._removeTagHandlers.get(entity);\r\n for (const tagQuery of this._tagQueries.values()) {\r\n tagQuery.removeEntity(entity);\r\n }\r\n\r\n if (addTag) {\r\n entity.tagAdded$.unsubscribe(addTag);\r\n }\r\n if (removeTag) {\r\n entity.tagRemoved$.unsubscribe(removeTag);\r\n }\r\n }\r\n\r\n /**\r\n * Updates any queries when a component is added to an entity\r\n * @param entity\r\n * @param component\r\n */\r\n addComponent(entity: Entity, component: Component) {\r\n const queries = this._componentToQueriesIndex.get(component.constructor as ComponentCtor) ?? [];\r\n for (const query of queries) {\r\n query.checkAndAdd(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Updates any queries when a component is removed from an entity\r\n * @param entity\r\n * @param component\r\n */\r\n removeComponent(entity: Entity, component: Component) {\r\n const queries = this._componentToQueriesIndex.get(component.constructor as ComponentCtor) ?? [];\r\n for (const query of queries) {\r\n query.removeEntity(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Updates any queries when a tag is added to an entity\r\n * @param entity\r\n * @param tag\r\n */\r\n addTag(entity: Entity, tag: string) {\r\n const queries = this._tagToQueriesIndex.get(tag) ?? [];\r\n for (const query of queries) {\r\n query.checkAndAdd(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Updates any queries when a component is removed from an entity\r\n * @param entity\r\n * @param tag\r\n */\r\n removeTag(entity: Entity, tag: string) {\r\n const queries = this._tagToQueriesIndex.get(tag) ?? [];\r\n for (const query of queries) {\r\n query.removeEntity(entity);\r\n }\r\n }\r\n\r\n\r\n}\r\n","import { System, SystemType } from './System';\r\nimport { Scene } from '../Scene';\r\nimport { World } from './World';\r\nimport { removeItemFromArray } from '../Util/Util';\r\n\r\nexport interface SystemCtor {\r\n new (...args: any[]): T;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function isSystemConstructor(x: any): x is SystemCtor {\r\n return !!x?.prototype && !!x?.prototype?.constructor?.name;\r\n}\r\n\r\n/**\r\n * The SystemManager is responsible for keeping track of all systems in a scene.\r\n * Systems are scene specific\r\n */\r\nexport class SystemManager {\r\n /**\r\n * List of systems, to add a new system call [[SystemManager.addSystem]]\r\n */\r\n public systems: System[] = [];\r\n public initialized = false;\r\n constructor(private _world: World) {}\r\n\r\n /**\r\n * Get a system registered in the manager by type\r\n * @param systemType\r\n */\r\n public get(systemType: SystemCtor): T | null {\r\n return this.systems.find((s) => s instanceof systemType) as unknown as T;\r\n }\r\n\r\n /**\r\n * Adds a system to the manager, it will now be updated every frame\r\n * @param systemOrCtor\r\n */\r\n public addSystem(systemOrCtor: SystemCtor | System): void {\r\n let system: System;\r\n if (systemOrCtor instanceof System) {\r\n system = systemOrCtor;\r\n } else {\r\n system = new systemOrCtor(this._world);\r\n }\r\n\r\n this.systems.push(system);\r\n this.systems.sort((a, b) => a.priority - b.priority);\r\n // If systems are added and the manager has already been init'd\r\n // then immediately init the system\r\n if (this.initialized && system.initialize) {\r\n system.initialize(this._world, this._world.scene);\r\n }\r\n }\r\n\r\n /**\r\n * Removes a system from the manager, it will no longer be updated\r\n * @param system\r\n */\r\n public removeSystem(system: System) {\r\n removeItemFromArray(system, this.systems);\r\n }\r\n\r\n /**\r\n * Initialize all systems in the manager\r\n *\r\n * Systems added after initialize() will be initialized on add\r\n */\r\n public initialize() {\r\n if (!this.initialized) {\r\n this.initialized = true;\r\n for (const s of this.systems) {\r\n if (s.initialize) {\r\n s.initialize(this._world, this._world.scene);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates all systems\r\n * @param type whether this is an update or draw system\r\n * @param scene context reference\r\n * @param delta time in milliseconds\r\n */\r\n public updateSystems(type: SystemType, scene: Scene, delta: number) {\r\n const systems = this.systems.filter((s) => s.systemType === type);\r\n for (const s of systems) {\r\n if (s.preupdate) {\r\n s.preupdate(scene, delta);\r\n }\r\n }\r\n\r\n for (const s of systems) {\r\n s.update(delta);\r\n }\r\n\r\n for (const s of systems) {\r\n if (s.postupdate) {\r\n s.postupdate(scene, delta);\r\n }\r\n }\r\n }\r\n\r\n public clear(): void {\r\n for (let i = this.systems.length - 1; i >= 0; i--) {\r\n this.removeSystem(this.systems[i]);\r\n }\r\n }\r\n}\r\n","import { Scene } from '../Scene';\r\nimport { Component, ComponentCtor } from './Component';\r\nimport { Entity } from './Entity';\r\nimport { EntityManager } from './EntityManager';\r\nimport { Query } from './Query';\r\nimport { QueryManager } from './QueryManager';\r\nimport { System, SystemType } from './System';\r\nimport { SystemCtor, SystemManager, isSystemConstructor } from './SystemManager';\r\nimport { TagQuery } from './TagQuery';\r\n\r\n/**\r\n * The World is a self-contained entity component system for a particular context.\r\n */\r\nexport class World {\r\n public queryManager: QueryManager = new QueryManager(this);\r\n public entityManager: EntityManager = new EntityManager(this);\r\n public systemManager: SystemManager = new SystemManager(this);\r\n\r\n /**\r\n * The context type is passed to the system updates\r\n * @param scene\r\n */\r\n constructor(public scene: Scene) {}\r\n\r\n /**\r\n * Query the ECS world for entities that match your components\r\n * @param requiredTypes\r\n */\r\n query>(\r\n requiredTypes: TKnownComponentCtors[]): Query {\r\n return this.queryManager.createQuery(requiredTypes);\r\n }\r\n\r\n queryTags(requiredTags: TKnownTags[]): TagQuery {\r\n return this.queryManager.createTagQuery(requiredTags);\r\n }\r\n\r\n /**\r\n * Update systems by type and time elapsed in milliseconds\r\n */\r\n update(type: SystemType, delta: number) {\r\n if (type === SystemType.Update) {\r\n this.entityManager.updateEntities(this.scene, delta);\r\n }\r\n this.systemManager.updateSystems(type, this.scene, delta);\r\n this.entityManager.findEntitiesForRemoval();\r\n this.entityManager.processComponentRemovals();\r\n this.entityManager.processEntityRemovals();\r\n }\r\n\r\n /**\r\n * Add an entity to the ECS world\r\n * @param entity\r\n */\r\n add(entity: Entity): void;\r\n /**\r\n * Add a system to the ECS world\r\n * @param system\r\n */\r\n add(system: System): void;\r\n add(system: SystemCtor): void;\r\n add(entityOrSystem: Entity | System | SystemCtor): void {\r\n if (entityOrSystem instanceof Entity) {\r\n this.entityManager.addEntity(entityOrSystem);\r\n }\r\n\r\n if (entityOrSystem instanceof System || isSystemConstructor(entityOrSystem)) {\r\n this.systemManager.addSystem(entityOrSystem);\r\n }\r\n }\r\n\r\n /**\r\n * Get a system out of the ECS world\r\n */\r\n get(system: SystemCtor) {\r\n return this.systemManager.get(system);\r\n }\r\n\r\n /**\r\n * Remove an entity from the ECS world\r\n * @param entity\r\n */\r\n remove(entity: Entity, deferred?: boolean): void;\r\n /**\r\n * Remove a system from the ECS world\r\n * @param system\r\n */\r\n remove(system: System): void;\r\n remove(entityOrSystem: Entity | System, deferred = true): void {\r\n if (entityOrSystem instanceof Entity) {\r\n this.entityManager.removeEntity(entityOrSystem, deferred);\r\n }\r\n\r\n if (entityOrSystem instanceof System) {\r\n this.systemManager.removeSystem(entityOrSystem);\r\n }\r\n }\r\n\r\n get entities() {\r\n return this.entityManager.entities;\r\n }\r\n\r\n clearEntities(): void {\r\n this.entityManager.clear();\r\n }\r\n\r\n clearSystems(): void {\r\n this.systemManager.clear();\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\n\r\nexport class EulerIntegrator {\r\n // Scratch vectors to avoid allocation\r\n private static _POS = new Vector(0, 0);\r\n private static _SCALE = new Vector(1, 1);\r\n\r\n private static _ACC = new Vector(0, 0);\r\n private static _VEL = new Vector(0, 0);\r\n private static _VEL_ACC = new Vector(0, 0);\r\n private static _SCALE_FACTOR = new Vector(0, 0);\r\n\r\n static integrate(transform: TransformComponent, motion: MotionComponent, totalAcc: Vector, elapsedMs: number): void {\r\n const seconds = elapsedMs / 1000;\r\n // This code looks a little wild, but it's to avoid creating any new Vector instances\r\n // integration is done in a tight loop so this is key to avoid GC'ing\r\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\r\n transform.pos\r\n .add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS)\r\n .addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\r\n\r\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\r\n const rotation = transform.rotation + motion.angularVelocity * seconds;\r\n\r\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\r\n const tx = transform.get();\r\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\r\n }\r\n}\r\n","import { Query, SystemPriority, World } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { BodyComponent } from './BodyComponent';\r\nimport { CollisionType } from './CollisionType';\r\nimport { EulerIntegrator } from './Integrator';\r\nimport { PhysicsWorld } from './PhysicsWorld';\r\n\r\nexport class MotionSystem extends System {\r\n public systemType = SystemType.Update;\r\n public priority = SystemPriority.Higher;\r\n private _physicsConfigDirty = false;\r\n query: Query;\r\n constructor(public world: World, public physics: PhysicsWorld) {\r\n super();\r\n physics.$configUpdate.subscribe(() => this._physicsConfigDirty = true);\r\n this.query = this.world.query([TransformComponent, MotionComponent]);\r\n }\r\n\r\n update(elapsedMs: number): void {\r\n let transform: TransformComponent;\r\n let motion: MotionComponent;\r\n const entities = this.query.entities;\r\n for (let i = 0; i < entities.length; i++) {\r\n transform = entities[i].get(TransformComponent);\r\n motion = entities[i].get(MotionComponent);\r\n\r\n const optionalBody = entities[i].get(BodyComponent);\r\n if (this._physicsConfigDirty && optionalBody) {\r\n optionalBody.updatePhysicsConfig(this.physics.config.bodies);\r\n }\r\n\r\n if (optionalBody?.sleeping) {\r\n continue;\r\n }\r\n\r\n const totalAcc = motion.acc.clone();\r\n if (optionalBody?.collisionType === CollisionType.Active && optionalBody?.useGravity) {\r\n totalAcc.addEqual(this.physics.config.gravity);\r\n }\r\n optionalBody?.captureOldTransform();\r\n\r\n // Update transform and motion based on Euler linear algebra\r\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\r\n }\r\n }\r\n}\r\n","import { PostCollisionEvent, PreCollisionEvent } from '../../Events';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Side } from '../Side';\r\nimport { CollisionSolver } from './Solver';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { ContactBias, ContactSolveBias, HorizontalFirst, None, VerticalFirst } from './ContactBias';\r\nimport { PhysicsConfig } from '../PhysicsConfig';\r\nimport { DeepRequired } from '../../Util/Required';\r\n\r\n/**\r\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\r\n * and negates velocity along the collision normal.\r\n *\r\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\r\n *\r\n */\r\nexport class ArcadeSolver implements CollisionSolver {\r\n directionMap = new Map();\r\n distanceMap = new Map();\r\n\r\n constructor(public config: DeepRequired['arcade']>) {}\r\n\r\n public solve(contacts: CollisionContact[]): CollisionContact[] {\r\n // Events and init\r\n this.preSolve(contacts);\r\n\r\n // Remove any canceled contacts\r\n contacts = contacts.filter(c => !c.isCanceled());\r\n\r\n // Locate collision bias order\r\n let bias: ContactBias;\r\n switch (this.config.contactSolveBias) {\r\n case ContactSolveBias.HorizontalFirst: {\r\n bias = HorizontalFirst;\r\n break;\r\n }\r\n case ContactSolveBias.VerticalFirst: {\r\n bias = VerticalFirst;\r\n break;\r\n }\r\n default: {\r\n bias = None;\r\n }\r\n }\r\n\r\n // Sort by bias (None, VerticalFirst, HorizontalFirst) to avoid artifacts with seams\r\n // Sort contacts by distance to avoid artifacts with seams\r\n // It's important to solve in a specific order\r\n contacts.sort((a, b) => {\r\n const aDir = this.directionMap.get(a.id);\r\n const bDir = this.directionMap.get(b.id);\r\n const aDist = this.distanceMap.get(a.id);\r\n const bDist = this.distanceMap.get(b.id);\r\n return (bias[aDir] - bias[bDir]) || (aDist - bDist);\r\n });\r\n\r\n for (const contact of contacts) {\r\n // Solve position first in arcade\r\n this.solvePosition(contact);\r\n\r\n // Solve velocity second in arcade\r\n this.solveVelocity(contact);\r\n }\r\n\r\n // Events and any contact house-keeping the solver needs\r\n this.postSolve(contacts);\r\n\r\n return contacts;\r\n }\r\n\r\n public preSolve(contacts: CollisionContact[]) {\r\n const epsilon = .0001;\r\n for (const contact of contacts) {\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n continue;\r\n }\r\n const side = Side.fromDirection(contact.mtv);\r\n const mtv = contact.mtv.negate();\r\n\r\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\r\n this.distanceMap.set(contact.id, distance);\r\n\r\n this.directionMap.set(contact.id, side === Side.Left || side === Side.Right ? 'horizontal' : 'vertical');\r\n\r\n // Publish collision events on both participants\r\n contact.colliderA.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\r\n contact.colliderB.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact)\r\n );\r\n }\r\n }\r\n\r\n public postSolve(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n if (contact.isCanceled()) {\r\n continue;\r\n }\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n }\r\n\r\n const side = Side.fromDirection(contact.mtv);\r\n const mtv = contact.mtv.negate();\r\n // Publish collision events on both participants\r\n contact.colliderA.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\r\n contact.colliderB.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact)\r\n );\r\n }\r\n }\r\n\r\n public solvePosition(contact: CollisionContact) {\r\n const epsilon = .0001;\r\n // if bounds no longer intersect skip to the next\r\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\r\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\r\n // Cancel the contact to prevent and solving\r\n contact.cancel();\r\n return;\r\n }\r\n\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n return;\r\n }\r\n\r\n let mtv = contact.mtv;\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n return;\r\n }\r\n\r\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) {\r\n // split overlaps if both are Active\r\n mtv = mtv.scale(0.5);\r\n }\r\n\r\n // Resolve overlaps\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n bodyA.globalPos.x -= mtv.x;\r\n bodyA.globalPos.y -= mtv.y;\r\n colliderA.update(bodyA.transform.get());\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n bodyB.globalPos.x += mtv.x;\r\n bodyB.globalPos.y += mtv.y;\r\n colliderB.update(bodyB.transform.get());\r\n }\r\n }\r\n }\r\n\r\n\r\n public solveVelocity(contact: CollisionContact) {\r\n if (contact.isCanceled()) {\r\n return;\r\n }\r\n\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n return;\r\n }\r\n\r\n const normal = contact.normal;\r\n const opposite = normal.negate();\r\n\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n // only adjust velocity if the contact normal is opposite to the current velocity\r\n // this avoids catching edges on a platform when sliding off\r\n if (bodyA.vel.normalize().dot(opposite) < 0) {\r\n // Cancel out velocity opposite direction of collision normal\r\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\r\n bodyA.vel = bodyA.vel.add(velAdj);\r\n }\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n // only adjust velocity if the contact normal is opposite to the current velocity\r\n // this avoids catching edges on a platform\r\n if (bodyB.vel.normalize().dot(normal) < 0) {\r\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\r\n bodyB.vel = bodyB.vel.add(velAdj);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\n\r\n/**\r\n * Holds information about contact points, meant to be reused over multiple frames of contact\r\n */\r\nexport class ContactConstraintPoint {\r\n constructor(public point: Vector, public local: Vector, public contact: CollisionContact) {\r\n this.update();\r\n }\r\n\r\n /**\r\n * Updates the contact information\r\n */\r\n update() {\r\n const bodyA = this.contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = this.contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n const normal = this.contact.normal;\r\n const tangent = this.contact.tangent;\r\n\r\n this.aToContact = this.point.sub(bodyA.globalPos);\r\n this.bToContact = this.point.sub(bodyB.globalPos);\r\n\r\n const aToContactNormal = this.aToContact.cross(normal);\r\n const bToContactNormal = this.bToContact.cross(normal);\r\n\r\n this.normalMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\r\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\r\n\r\n const aToContactTangent = this.aToContact.cross(tangent);\r\n const bToContactTangent = this.bToContact.cross(tangent);\r\n\r\n this.tangentMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\r\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns the relative velocity between bodyA and bodyB\r\n */\r\n public getRelativeVelocity() {\r\n const bodyA = this.contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = this.contact.colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n // Relative velocity in linear terms\r\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\r\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\r\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\r\n return velB.sub(velA);\r\n }\r\n return Vector.Zero;\r\n }\r\n\r\n /**\r\n * Impulse accumulated over time in normal direction\r\n */\r\n public normalImpulse: number = 0;\r\n\r\n /**\r\n * Impulse accumulated over time in the tangent direction\r\n */\r\n public tangentImpulse: number = 0;\r\n\r\n /**\r\n * Effective mass seen in the normal direction\r\n */\r\n public normalMass: number = 0;\r\n\r\n /**\r\n * Effective mass seen in the tangent direction\r\n */\r\n public tangentMass: number = 0;\r\n\r\n /**\r\n * Direction from center of mass of bodyA to contact point\r\n */\r\n public aToContact: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Direction from center of mass of bodyB to contact point\r\n */\r\n public bToContact: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Original contact velocity combined with bounciness\r\n */\r\n public originalVelocityAndRestitution: number = 0;\r\n}\r\n","import { CollisionPostSolveEvent, CollisionPreSolveEvent, PostCollisionEvent, PreCollisionEvent } from '../../Events';\r\nimport { clamp } from '../../Math/util';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { ContactConstraintPoint } from './ContactConstraintPoint';\r\nimport { Side } from '../Side';\r\nimport { CollisionSolver } from './Solver';\r\nimport { BodyComponent, DegreeOfFreedom } from '../BodyComponent';\r\nimport { CollisionJumpTable } from '../Colliders/CollisionJumpTable';\r\nimport { DeepRequired } from '../../Util/Required';\r\nimport { PhysicsConfig } from '../PhysicsConfig';\r\n\r\nexport class RealisticSolver implements CollisionSolver {\r\n constructor(public config: DeepRequired['realistic']>) {}\r\n lastFrameContacts: Map = new Map();\r\n\r\n // map contact id to contact points\r\n idToContactConstraint: Map = new Map();\r\n\r\n getContactConstraints(id: string) {\r\n return this.idToContactConstraint.get(id) ?? [];\r\n }\r\n\r\n public solve(contacts: CollisionContact[]): CollisionContact[] {\r\n // Events and init\r\n this.preSolve(contacts);\r\n\r\n // Remove any canceled contacts\r\n contacts = contacts.filter(c => !c.isCanceled());\r\n\r\n // Solve velocity first\r\n this.solveVelocity(contacts);\r\n\r\n // Solve position last because non-overlap is the most important\r\n this.solvePosition(contacts);\r\n\r\n // Events and any contact house-keeping the solver needs\r\n this.postSolve(contacts);\r\n\r\n return contacts;\r\n }\r\n\r\n preSolve(contacts: CollisionContact[]) {\r\n const epsilon = .0001;\r\n for (const contact of contacts) {\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n continue;\r\n }\r\n // Publish collision events on both participants\r\n const side = Side.fromDirection(contact.mtv);\r\n contact.colliderA.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\r\n contact.colliderA.events.emit(\r\n 'beforecollisionresolve',\r\n new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact) as any\r\n );\r\n contact.colliderB.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact)\r\n );\r\n contact.colliderB.events.emit(\r\n 'beforecollisionresolve',\r\n new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact) as any\r\n );\r\n\r\n // Match awake state for sleeping\r\n contact.matchAwake();\r\n }\r\n\r\n // Keep track of contacts that done\r\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\r\n for (const contact of contacts) {\r\n // Remove all current contacts that are not done\r\n const index = finishedContactIds.indexOf(contact.id);\r\n if (index > -1) {\r\n finishedContactIds.splice(index, 1);\r\n }\r\n const contactPoints = this.idToContactConstraint.get(contact.id) ?? [];\r\n\r\n let pointIndex = 0;\r\n const bodyA = contact.colliderA.owner.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n for (const point of contact.points) {\r\n const normal = contact.normal;\r\n const tangent = contact.tangent;\r\n\r\n const aToContact = point.sub(bodyA.globalPos);\r\n const bToContact = point.sub(bodyB.globalPos);\r\n\r\n const aToContactNormal = aToContact.cross(normal);\r\n const bToContactNormal = bToContact.cross(normal);\r\n\r\n const normalMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\r\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\r\n\r\n const aToContactTangent = aToContact.cross(tangent);\r\n const bToContactTangent = bToContact.cross(tangent);\r\n\r\n const tangentMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\r\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\r\n\r\n // Preserve normal/tangent impulse by re-using the contact point if it's close\r\n if (contactPoints[pointIndex] && contactPoints[pointIndex]?.point?.squareDistance(point) < 4) {\r\n contactPoints[pointIndex].point = point;\r\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\r\n } else {\r\n // new contact if it's not close or doesn't exist\r\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\r\n }\r\n\r\n // Update contact point calculations\r\n contactPoints[pointIndex].aToContact = aToContact;\r\n contactPoints[pointIndex].bToContact = bToContact;\r\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\r\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\r\n\r\n // Calculate relative velocity before solving to accurately do restitution\r\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\r\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\r\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\r\n if (relativeVelocity < -0.1) { // TODO what's a good threshold here?\r\n contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\r\n }\r\n pointIndex++;\r\n }\r\n }\r\n this.idToContactConstraint.set(contact.id, contactPoints);\r\n }\r\n\r\n // Clean up any contacts that did not occur last frame\r\n for (const id of finishedContactIds) {\r\n this.idToContactConstraint.delete(id);\r\n }\r\n\r\n // Warm contacts with accumulated impulse\r\n // Useful for tall stacks\r\n if (this.config.warmStart) {\r\n this.warmStart(contacts);\r\n } else {\r\n for (const contact of contacts) {\r\n const contactPoints = this.getContactConstraints(contact.id);\r\n for (const point of contactPoints) {\r\n point.normalImpulse = 0;\r\n point.tangentImpulse = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n postSolve(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip post solve for active+passive collisions\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n // Update motion values for sleeping\r\n bodyA.updateMotion();\r\n bodyB.updateMotion();\r\n }\r\n\r\n // Publish collision events on both participants\r\n const side = Side.fromDirection(contact.mtv);\r\n contact.colliderA.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact)\r\n );\r\n contact.colliderA.events.emit(\r\n 'aftercollisionresolve',\r\n new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact) as any\r\n );\r\n contact.colliderB.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact)\r\n );\r\n contact.colliderB.events.emit(\r\n 'aftercollisionresolve',\r\n new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact) as any\r\n );\r\n }\r\n\r\n // Store contacts\r\n this.lastFrameContacts.clear();\r\n for (const c of contacts) {\r\n this.lastFrameContacts.set(c.id, c);\r\n }\r\n }\r\n\r\n /**\r\n * Warm up body's based on previous frame contact points\r\n * @param contacts\r\n */\r\n warmStart(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n const contactPoints = this.idToContactConstraint.get(contact.id) ?? [];\r\n for (const point of contactPoints) {\r\n if (this.config.warmStart) {\r\n const normalImpulse = contact.normal.scale(point.normalImpulse);\r\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\r\n const impulse = normalImpulse.add(tangentImpulse);\r\n\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n } else {\r\n point.normalImpulse = 0;\r\n point.tangentImpulse = 0;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Iteratively solve the position overlap constraint\r\n * @param contacts\r\n */\r\n solvePosition(contacts: CollisionContact[]) {\r\n for (let i = 0; i < this.config.positionIterations; i++) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip solving active+passive\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n const constraints = this.idToContactConstraint.get(contact.id) ?? [];\r\n for (const point of constraints) {\r\n const normal = contact.normal;\r\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\r\n\r\n const steeringConstant = this.config.steeringFactor; //0.2;\r\n const maxCorrection = -5;\r\n const slop = this.config.slop; //1;\r\n\r\n // Clamp to avoid over-correction\r\n // Remember that we are shooting for 0 overlap in the end\r\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\r\n const impulse = normal.scale(-steeringForce * point.normalMass);\r\n\r\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\r\n // We adjust position and rotation instead of doing the velocity\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n // TODO make applyPseudoImpulse function?\r\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\r\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n impulseForce.x = 0;\r\n }\r\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n impulseForce.y = 0;\r\n }\r\n\r\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\r\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\r\n }\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n const impulseForce = impulse.scale(bodyB.inverseMass);\r\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n impulseForce.x = 0;\r\n }\r\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n impulseForce.y = 0;\r\n }\r\n\r\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\r\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n solveVelocity(contacts: CollisionContact[]) {\r\n for (let i = 0; i < this.config.velocityIterations; i++) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip solving active+passive\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n const friction = Math.min(bodyA.friction, bodyB.friction);\r\n\r\n const constraints = this.idToContactConstraint.get(contact.id) ?? [];\r\n\r\n // Friction constraint\r\n for (const point of constraints) {\r\n const relativeVelocity = point.getRelativeVelocity();\r\n\r\n // Negate velocity in tangent direction to simulate friction\r\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\r\n let impulseDelta = tangentVelocity * point.tangentMass;\r\n\r\n // Clamping based in Erin Catto's GDC 2006 talk\r\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\r\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\r\n // But deltas can vary\r\n const maxFriction = friction * point.normalImpulse;\r\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\r\n impulseDelta = newImpulse - point.tangentImpulse;\r\n point.tangentImpulse = newImpulse;\r\n\r\n const impulse = contact.tangent.scale(impulseDelta);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n\r\n // Bounce constraint\r\n for (const point of constraints) {\r\n // Need to recalc relative velocity because the previous step could have changed vel\r\n const relativeVelocity = point.getRelativeVelocity();\r\n\r\n // Compute impulse in normal direction\r\n const normalVelocity = relativeVelocity.dot(contact.normal);\r\n\r\n // Per Erin it is a mistake to apply the restitution inside the iteration\r\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\r\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\r\n\r\n // Clamping based in Erin Catto's GDC 2014 talk\r\n // Accumulated impulse stored in the contact is always positive (dV > 0)\r\n // But deltas can be negative\r\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\r\n impulseDelta = newImpulse - point.normalImpulse;\r\n point.normalImpulse = newImpulse;\r\n\r\n const impulse = contact.normal.scale(impulseDelta);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { ComponentCtor, Query, SystemPriority, World } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { CollisionEndEvent, CollisionStartEvent, ContactEndEvent, ContactStartEvent } from '../Events';\r\nimport { SolverStrategy } from './SolverStrategy';\r\nimport { ArcadeSolver } from './Solver/ArcadeSolver';\r\nimport { Collider } from './Colliders/Collider';\r\nimport { CollisionContact } from './Detection/CollisionContact';\r\nimport { RealisticSolver } from './Solver/RealisticSolver';\r\nimport { CollisionSolver } from './Solver/Solver';\r\nimport { ColliderComponent } from './ColliderComponent';\r\nimport { CompositeCollider } from './Colliders/CompositeCollider';\r\nimport { Engine } from '../Engine';\r\nimport { ExcaliburGraphicsContext } from '../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Scene } from '../Scene';\r\nimport { Side } from '../Collision/Side';\r\nimport { DynamicTreeCollisionProcessor } from './Detection/DynamicTreeCollisionProcessor';\r\nimport { PhysicsWorld } from './PhysicsWorld';\r\nexport class CollisionSystem extends System {\r\n public systemType = SystemType.Update;\r\n public priority = SystemPriority.Higher;\r\n public query: Query | ComponentCtor | ComponentCtor>;\r\n\r\n private _engine: Engine;\r\n private _configDirty = false;\r\n private _realisticSolver: RealisticSolver;\r\n private _arcadeSolver: ArcadeSolver;\r\n private _lastFrameContacts = new Map();\r\n private _currentFrameContacts = new Map();\r\n private get _processor(): DynamicTreeCollisionProcessor {\r\n return this._physics.collisionProcessor;\r\n };\r\n\r\n private _trackCollider: (c: Collider) => void;\r\n private _untrackCollider: (c: Collider) => void;\r\n\r\n constructor(world: World, private _physics: PhysicsWorld) {\r\n super();\r\n this._arcadeSolver = new ArcadeSolver(_physics.config.arcade);\r\n this._realisticSolver = new RealisticSolver(_physics.config.realistic);\r\n this._physics.$configUpdate.subscribe(() => this._configDirty = true);\r\n this._trackCollider = (c: Collider) => this._processor.track(c);\r\n this._untrackCollider = (c: Collider) => this._processor.untrack(c);\r\n this.query = world.query([TransformComponent, MotionComponent, ColliderComponent]);\r\n this.query.entityAdded$.subscribe(e => {\r\n const colliderComponent = e.get(ColliderComponent);\r\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\r\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\r\n const collider = colliderComponent.get();\r\n if (collider) {\r\n this._processor.track(collider);\r\n }\r\n });\r\n this.query.entityRemoved$.subscribe(e => {\r\n const colliderComponent = e.get(ColliderComponent);\r\n const collider = colliderComponent.get();\r\n if (colliderComponent && collider) {\r\n this._processor.untrack(collider);\r\n }\r\n });\r\n }\r\n\r\n initialize(world: World, scene: Scene) {\r\n this._engine = scene.engine;\r\n }\r\n\r\n update(elapsedMs: number): void {\r\n if (!this._physics.config.enabled) {\r\n return;\r\n }\r\n\r\n // Collect up all the colliders and update them\r\n let colliders: Collider[] = [];\r\n for (const entity of this.query.entities) {\r\n const colliderComp = entity.get(ColliderComponent);\r\n const collider = colliderComp?.get();\r\n if (colliderComp && colliderComp.owner?.active && collider) {\r\n colliderComp.update();\r\n if (collider instanceof CompositeCollider) {\r\n const compositeColliders = collider.getColliders();\r\n if (!collider.compositeStrategy) {\r\n collider.compositeStrategy = this._physics.config.colliders.compositeStrategy;\r\n }\r\n colliders = colliders.concat(compositeColliders);\r\n } else {\r\n colliders.push(collider);\r\n }\r\n }\r\n }\r\n\r\n // Update the spatial partitioning data structures\r\n // TODO if collider invalid it will break the processor\r\n // TODO rename \"update\" to something more specific\r\n this._processor.update(colliders);\r\n\r\n // Run broadphase on all colliders and locates potential collisions\r\n const pairs = this._processor.broadphase(colliders, elapsedMs);\r\n\r\n this._currentFrameContacts.clear();\r\n\r\n // Given possible pairs find actual contacts\r\n let contacts = this._processor.narrowphase(pairs, this._engine?.debug?.stats?.currFrame);\r\n\r\n const solver: CollisionSolver = this.getSolver();\r\n\r\n // Solve, this resolves the position/velocity so entities aren't overlapping\r\n contacts = solver.solve(contacts);\r\n\r\n // Record contacts for start/end\r\n for (const contact of contacts) {\r\n if (contact.isCanceled()) {\r\n continue;\r\n }\r\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\r\n const index = contact.id.indexOf('|');\r\n if (index > 0) {\r\n const compositeId = contact.id.substring(index + 1);\r\n this._currentFrameContacts.set(compositeId, contact);\r\n } else {\r\n this._currentFrameContacts.set(contact.id, contact);\r\n }\r\n }\r\n\r\n // Emit contact start/end events\r\n this.runContactStartEnd();\r\n\r\n // reset the last frame cache\r\n this._lastFrameContacts.clear();\r\n\r\n // Keep track of collisions contacts that have started or ended\r\n this._lastFrameContacts = new Map(this._currentFrameContacts);\r\n\r\n // Process deferred collider removals\r\n for (const entity of this.query.entities) {\r\n const collider = entity.get(ColliderComponent);\r\n if (collider) {\r\n collider.processColliderRemoval();\r\n }\r\n }\r\n }\r\n\r\n getSolver(): CollisionSolver {\r\n if (this._configDirty) {\r\n this._configDirty = false;\r\n this._arcadeSolver = new ArcadeSolver(this._physics.config.arcade);\r\n this._realisticSolver = new RealisticSolver(this._physics.config.realistic);\r\n }\r\n return this._physics.config.solver === SolverStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\r\n }\r\n\r\n debug(ex: ExcaliburGraphicsContext) {\r\n this._processor.debug(ex);\r\n }\r\n\r\n public runContactStartEnd() {\r\n // If composite colliders are 'together' collisions may have a duplicate id because we want to treat those as a singular start/end\r\n for (const [id, c] of this._currentFrameContacts) {\r\n // find all new contacts\r\n if (!this._lastFrameContacts.has(id)) {\r\n const colliderA = c.colliderA;\r\n const colliderB = c.colliderB;\r\n const side = Side.fromDirection(c.mtv);\r\n const opposite = Side.getOpposite(side);\r\n colliderA.events.emit('collisionstart', new CollisionStartEvent(colliderA, colliderB, side, c));\r\n colliderA.events.emit('contactstart', new ContactStartEvent(colliderA, colliderB, side, c) as any);\r\n colliderB.events.emit('collisionstart', new CollisionStartEvent(colliderB, colliderA, opposite, c));\r\n colliderB.events.emit('contactstart', new ContactStartEvent(colliderB, colliderA, opposite, c) as any);\r\n }\r\n }\r\n\r\n // find all contacts that have ceased\r\n for (const [id, c] of this._lastFrameContacts) {\r\n if (!this._currentFrameContacts.has(id)) {\r\n const colliderA = c.colliderA;\r\n const colliderB = c.colliderB;\r\n const side = Side.fromDirection(c.mtv);\r\n const opposite = Side.getOpposite(side);\r\n colliderA.events.emit('collisionend', new CollisionEndEvent(colliderA, colliderB, side, c));\r\n colliderA.events.emit('contactend', new ContactEndEvent(colliderA, colliderB, side, c) as any);\r\n colliderB.events.emit('collisionend', new CollisionEndEvent(colliderB, colliderA, opposite, c));\r\n colliderB.events.emit('contactend', new ContactEndEvent(colliderB, colliderA, opposite, c) as any);\r\n }\r\n }\r\n }\r\n}\r\n","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { GetSpriteOptions, SpriteSheet } from './SpriteSheet';\r\nimport { Logger } from '../Util/Log';\r\nimport { clamp } from '../Math/util';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport interface HasTick {\r\n /**\r\n *\r\n * @param elapsedMilliseconds The amount of real world time in milliseconds that has elapsed that must be updated in the animation\r\n * @param idempotencyToken Optional idempotencyToken prevents a ticking animation from updating twice per frame\r\n */\r\n tick(elapsedMilliseconds: number, idempotencyToken?: number): void;\r\n}\r\n\r\nexport enum AnimationDirection {\r\n /**\r\n * Animation is playing forwards\r\n */\r\n Forward = 'forward',\r\n /**\r\n * Animation is playing backwards\r\n */\r\n Backward = 'backward'\r\n}\r\n\r\nexport enum AnimationStrategy {\r\n /**\r\n * Animation ends without displaying anything\r\n */\r\n End = 'end',\r\n /**\r\n * Animation loops to the first frame after the last frame\r\n */\r\n Loop = 'loop',\r\n /**\r\n * Animation plays to the last frame, then backwards to the first frame, then repeats\r\n */\r\n PingPong = 'pingpong',\r\n /**\r\n * Animation ends stopping on the last frame\r\n */\r\n Freeze = 'freeze'\r\n}\r\n\r\n/**\r\n * Frame of animation\r\n */\r\nexport interface Frame {\r\n /**\r\n * Optionally specify a graphic to show, no graphic shows an empty frame\r\n */\r\n graphic?: Graphic;\r\n /**\r\n * Optionally specify the number of ms the frame should be visible, overrides the animation duration (default 100 ms)\r\n */\r\n duration?: number;\r\n}\r\n\r\nexport interface FrameEvent extends Frame {\r\n frameIndex: number;\r\n}\r\n\r\n/**\r\n * Animation options for building an animation via constructor.\r\n */\r\nexport interface AnimationOptions {\r\n /**\r\n * List of frames in the order you wish to play them\r\n */\r\n frames: Frame[];\r\n /**\r\n * Optionally set a positive speed multiplier on the animation.\r\n *\r\n * By default 1, meaning 1x speed. If set to 2, it will play the animation twice as fast.\r\n */\r\n speed?: number;\r\n /**\r\n * Optionally reverse the direction of play\r\n */\r\n reverse?: boolean;\r\n /**\r\n * Optionally specify a default frame duration in ms (Default is 100)\r\n */\r\n frameDuration?: number;\r\n /**\r\n * Optionally specify a total duration of the animation in ms to calculate each frame's duration\r\n */\r\n totalDuration?: number;\r\n /**\r\n * Optionally specify the [[AnimationStrategy]] for the Animation\r\n */\r\n strategy?: AnimationStrategy;\r\n}\r\n\r\nexport type AnimationEvents = {\r\n frame: FrameEvent;\r\n loop: Animation;\r\n end: Animation;\r\n};\r\n\r\nexport const AnimationEvents = {\r\n Frame: 'frame',\r\n Loop: 'loop',\r\n End: 'end'\r\n};\r\n\r\nexport interface FromSpriteSheetOptions {\r\n /**\r\n * [[SpriteSheet]] to source the animation frames from\r\n */\r\n spriteSheet: SpriteSheet;\r\n /**\r\n * The list of (x, y) positions of sprites in the [[SpriteSheet]] of each frame, for example (0, 0)\r\n * is the the top left sprite, (0, 1) is the sprite directly below that, and so on.\r\n *\r\n * You may optionally specify a duration for the frame in milliseconds as well, this will override\r\n * the default duration.\r\n */\r\n frameCoordinates: {x: number, y: number, duration?: number, options?: GetSpriteOptions}[];\r\n /**\r\n * Optionally specify a default duration for frames in milliseconds\r\n */\r\n durationPerFrameMs?: number;\r\n /**\r\n * Optionally set a positive speed multiplier on the animation.\r\n *\r\n * By default 1, meaning 1x speed. If set to 2, it will play the animation twice as fast.\r\n */\r\n speed?: number;\r\n /**\r\n * Optionally specify the animation strategy for this animation, by default animations loop [[AnimationStrategy.Loop]]\r\n */\r\n strategy?: AnimationStrategy\r\n /**\r\n * Optionally specify the animation should be reversed\r\n */\r\n reverse?: boolean;\r\n}\r\n\r\n/**\r\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\r\n *\r\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\r\n */\r\nexport class Animation extends Graphic implements HasTick {\r\n private static _LOGGER = Logger.getInstance();\r\n public events = new EventEmitter();\r\n public frames: Frame[] = [];\r\n public strategy: AnimationStrategy = AnimationStrategy.Loop;\r\n public frameDuration: number = 100;\r\n\r\n private _idempotencyToken = -1;\r\n\r\n private _firstTick = true;\r\n private _currentFrame = 0;\r\n private _timeLeftInFrame = 0;\r\n private _pingPongDirection = 1;\r\n private _done = false;\r\n private _playing = true;\r\n private _speed = 1;\r\n\r\n constructor(options: GraphicOptions & AnimationOptions) {\r\n super(options);\r\n this.frames = options.frames;\r\n this.speed = options.speed ?? this.speed;\r\n this.strategy = options.strategy ?? this.strategy;\r\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : options.frameDuration ?? this.frameDuration;\r\n if (options.reverse) {\r\n this.reverse();\r\n }\r\n this.goToFrame(0);\r\n }\r\n\r\n public clone(): Animation {\r\n return new Animation({\r\n frames: this.frames.map((f) => ({ ...f })),\r\n frameDuration: this.frameDuration,\r\n speed: this.speed,\r\n reverse: this._reversed,\r\n strategy: this.strategy,\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n\r\n public override get width(): number {\r\n const maybeFrame = this.currentFrame;\r\n if (maybeFrame) {\r\n return Math.abs(maybeFrame.graphic.width * this.scale.x);\r\n }\r\n return 0;\r\n }\r\n\r\n public override get height(): number {\r\n const maybeFrame = this.currentFrame;\r\n if (maybeFrame) {\r\n return Math.abs(maybeFrame.graphic.height * this.scale.y);\r\n }\r\n return 0;\r\n }\r\n\r\n\r\n /**\r\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\r\n * and optional [[AnimationStrategy]]\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\r\n * ```\r\n * @param spriteSheet\r\n * @param frameIndices\r\n * @param durationPerFrameMs\r\n * @param strategy\r\n */\r\n public static fromSpriteSheet(\r\n spriteSheet: SpriteSheet,\r\n frameIndices: number[],\r\n durationPerFrameMs: number,\r\n strategy: AnimationStrategy = AnimationStrategy.Loop\r\n ): Animation {\r\n const maxIndex = spriteSheet.sprites.length - 1;\r\n const invalidIndices = frameIndices.filter((index) => index < 0 || index > maxIndex);\r\n if (invalidIndices.length) {\r\n Animation._LOGGER.warn(\r\n `Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(',')} no frame will be shown`\r\n );\r\n }\r\n return new Animation({\r\n frames: spriteSheet.sprites\r\n .filter((_, index) => frameIndices.indexOf(index) > -1)\r\n .map((f) => ({\r\n graphic: f,\r\n duration: durationPerFrameMs\r\n })),\r\n strategy: strategy\r\n });\r\n }\r\n\r\n /**\r\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheetCoordinates({\r\n * spriteSheet,\r\n * frameCoordinates: [\r\n * {x: 0, y: 5, duration: 100, options { flipHorizontal: true }},\r\n * {x: 1, y: 5, duration: 200},\r\n * {x: 2, y: 5, duration: 100},\r\n * {x: 3, y: 5, duration: 500}\r\n * ],\r\n * strategy: AnimationStrategy.PingPong\r\n * });\r\n * ```\r\n * @param options\r\n * @returns Animation\r\n */\r\n public static fromSpriteSheetCoordinates(options: FromSpriteSheetOptions): Animation {\r\n const { spriteSheet, frameCoordinates, durationPerFrameMs, speed, strategy, reverse } = options;\r\n const defaultDuration = durationPerFrameMs ?? 100;\r\n const frames: Frame[] = [];\r\n for (const coord of frameCoordinates) {\r\n const {x, y, duration, options } = coord;\r\n const sprite = spriteSheet.getSprite(x, y, options);\r\n if (sprite) {\r\n frames.push({\r\n graphic: sprite,\r\n duration: duration ?? defaultDuration\r\n });\r\n } else {\r\n Animation._LOGGER.warn(\r\n `Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`\r\n );\r\n }\r\n }\r\n\r\n return new Animation({\r\n frames,\r\n strategy,\r\n speed,\r\n reverse\r\n });\r\n }\r\n\r\n /**\r\n * Current animation speed\r\n *\r\n * 1 meaning normal 1x speed.\r\n * 2 meaning 2x speed and so on.\r\n */\r\n public get speed(): number {\r\n return this._speed;\r\n }\r\n\r\n /**\r\n * Current animation speed\r\n *\r\n * 1 meaning normal 1x speed.\r\n * 2 meaning 2x speed and so on.\r\n */\r\n public set speed(val: number) {\r\n this._speed = clamp(Math.abs(val), 0, Infinity);\r\n }\r\n\r\n /**\r\n * Returns the current Frame of the animation\r\n *\r\n * Use [[Animation.currentFrameIndex]] to get the frame number and\r\n * [[Animation.goToFrame]] to set the current frame index\r\n */\r\n public get currentFrame(): Frame | null {\r\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) {\r\n return this.frames[this._currentFrame];\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns the current frame index of the animation\r\n *\r\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\r\n */\r\n public get currentFrameIndex(): number {\r\n return this._currentFrame;\r\n }\r\n\r\n /**\r\n * Returns the amount of time in milliseconds left in the current frame\r\n */\r\n public get currentFrameTimeLeft(): number {\r\n return this._timeLeftInFrame;\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation is playing\r\n */\r\n public get isPlaying(): boolean {\r\n return this._playing;\r\n }\r\n\r\n private _reversed = false;\r\n /**\r\n * Reverses the play direction of the Animation, this preserves the current frame\r\n */\r\n public reverse(): void {\r\n // Don't mutate with the original frame list, create a copy\r\n this.frames = this.frames.slice().reverse();\r\n this._reversed = !this._reversed;\r\n }\r\n\r\n /**\r\n * Returns the current play direction of the animation\r\n */\r\n public get direction(): AnimationDirection {\r\n // Keep logically consistent with ping-pong direction\r\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\r\n const reversed = (this._reversed && this._pingPongDirection === 1) ? true : false;\r\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\r\n }\r\n\r\n /**\r\n * Plays or resumes the animation from the current frame\r\n */\r\n public play(): void {\r\n this._playing = true;\r\n }\r\n\r\n /**\r\n * Pauses the animation on the current frame\r\n */\r\n public pause(): void {\r\n this._playing = false;\r\n this._firstTick = true; // firstTick must be set to emit the proper frame event\r\n }\r\n\r\n /**\r\n * Reset the animation back to the beginning, including if the animation were done\r\n */\r\n public reset(): void {\r\n this._done = false;\r\n this._firstTick = true;\r\n this._currentFrame = 0;\r\n this._timeLeftInFrame = this.frameDuration;\r\n const maybeFrame = this.frames[this._currentFrame];\r\n if (maybeFrame) {\r\n this._timeLeftInFrame = (maybeFrame?.duration || this.frameDuration);\r\n }\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation can end\r\n */\r\n public get canFinish(): boolean {\r\n switch (this.strategy) {\r\n case AnimationStrategy.End:\r\n case AnimationStrategy.Freeze: {\r\n return true;\r\n }\r\n default: {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation is done, for looping type animations\r\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\r\n *\r\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\r\n */\r\n public get done(): boolean {\r\n return this._done;\r\n }\r\n\r\n /**\r\n * Jump the animation immediately to a specific frame if it exists\r\n *\r\n * Optionally specify an override for the duration of the frame, useful for\r\n * keeping multiple animations in sync with one another.\r\n * @param frameNumber\r\n * @param duration\r\n */\r\n public goToFrame(frameNumber: number, duration?: number) {\r\n this._currentFrame = frameNumber;\r\n this._timeLeftInFrame = duration ?? this.frameDuration;\r\n const maybeFrame = this.frames[this._currentFrame];\r\n if (maybeFrame && !this._done) {\r\n this._timeLeftInFrame = duration ?? (maybeFrame?.duration || this.frameDuration);\r\n this.events.emit('frame', {...maybeFrame, frameIndex: this.currentFrameIndex });\r\n }\r\n }\r\n\r\n private _nextFrame(): number {\r\n const currentFrame = this._currentFrame;\r\n if (this._done) {\r\n return currentFrame;\r\n }\r\n let next = -1;\r\n\r\n switch (this.strategy) {\r\n case AnimationStrategy.Loop: {\r\n next = (currentFrame + 1) % this.frames.length;\r\n if (next === 0) {\r\n this.events.emit('loop', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.End: {\r\n next = currentFrame + 1;\r\n if (next >= this.frames.length) {\r\n this._done = true;\r\n this._currentFrame = this.frames.length;\r\n this.events.emit('end', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.Freeze: {\r\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\r\n if (next >= this.frames.length - 1) {\r\n this._done = true;\r\n this.events.emit('end', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.PingPong: {\r\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\r\n this._pingPongDirection = -1;\r\n this.events.emit('loop', this);\r\n }\r\n\r\n if (currentFrame + this._pingPongDirection < 0) {\r\n this._pingPongDirection = 1;\r\n this.events.emit('loop', this);\r\n }\r\n\r\n next = currentFrame + (this._pingPongDirection % this.frames.length);\r\n break;\r\n }\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Called internally by Excalibur to update the state of the animation potential update the current frame\r\n * @param elapsedMilliseconds Milliseconds elapsed\r\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\r\n */\r\n public tick(elapsedMilliseconds: number, idempotencyToken: number = 0): void {\r\n if (this._idempotencyToken === idempotencyToken) {\r\n return;\r\n }\r\n this._idempotencyToken = idempotencyToken;\r\n if (!this._playing) {\r\n return;\r\n }\r\n\r\n // if it's the first frame emit frame event\r\n if (this._firstTick) {\r\n this._firstTick = false;\r\n this.events.emit('frame', {...this.currentFrame, frameIndex: this.currentFrameIndex });\r\n }\r\n\r\n this._timeLeftInFrame -= elapsedMilliseconds * this._speed;\r\n if (this._timeLeftInFrame <= 0) {\r\n this.goToFrame(this._nextFrame());\r\n }\r\n }\r\n\r\n protected _drawImage(ctx: ExcaliburGraphicsContext, x: number, y: number) {\r\n if (this.currentFrame) {\r\n this.currentFrame.graphic.draw(ctx, x, y);\r\n }\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Animation, HasTick } from './Animation';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/Index';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport interface GraphicsGroupingOptions {\r\n members: (GraphicsGrouping | Graphic)[];\r\n}\r\n\r\nexport interface GraphicsGrouping {\r\n offset: Vector;\r\n graphic: Graphic;\r\n /**\r\n * Optionally disable this graphics bounds as part of group calculation, default true\r\n * if unspecified\r\n *\r\n * You may want to do this if you're using text because their bounds will affect\r\n * the centering of the whole group\r\n */\r\n useBounds?: boolean;\r\n}\r\n\r\nexport class GraphicsGroup extends Graphic implements HasTick {\r\n private _logger = Logger.getInstance();\r\n public members: (GraphicsGrouping | Graphic)[] = [];\r\n\r\n constructor(options: GraphicsGroupingOptions & GraphicOptions) {\r\n super(options);\r\n this.members = options.members;\r\n this._updateDimensions();\r\n }\r\n\r\n public clone(): GraphicsGroup {\r\n return new GraphicsGroup({\r\n members: [...this.members],\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n\r\n private _updateDimensions(): BoundingBox {\r\n const bb = this.localBounds;\r\n this.width = bb.width;\r\n this.height = bb.height;\r\n return bb;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n let bb = new BoundingBox();\r\n for (const member of this.members) {\r\n if (member instanceof Graphic) {\r\n bb = member.localBounds.combine(bb);\r\n } else {\r\n const { graphic, offset: pos, useBounds } = member;\r\n const shouldUseBounds = useBounds === undefined ? true : useBounds;\r\n if (graphic) {\r\n if (shouldUseBounds) {\r\n bb = graphic.localBounds.translate(pos).combine(bb);\r\n }\r\n } else {\r\n this._logger.warnOnce(`Graphics group member has an null or undefined graphic, member definition: ${JSON.stringify(member)}.`);\r\n }\r\n }\r\n }\r\n return bb;\r\n }\r\n\r\n private _isAnimationOrGroup(graphic: Graphic): graphic is Animation | GraphicsGroup {\r\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\r\n }\r\n\r\n public tick(elapsedMilliseconds: number, idempotencyToken?: number) {\r\n for (const member of this.members) {\r\n let graphic: Graphic;\r\n if (member instanceof Graphic) {\r\n graphic = member;\r\n } else {\r\n graphic = member.graphic;\r\n }\r\n if (this._isAnimationOrGroup(graphic)) {\r\n graphic.tick(elapsedMilliseconds, idempotencyToken);\r\n }\r\n }\r\n }\r\n\r\n public reset() {\r\n for (const member of this.members) {\r\n let graphic: Graphic;\r\n if (member instanceof Graphic) {\r\n graphic = member;\r\n } else {\r\n graphic = member.graphic;\r\n }\r\n if (this._isAnimationOrGroup(graphic)) {\r\n graphic.reset();\r\n }\r\n }\r\n }\r\n\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n this._updateDimensions();\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n const pos = Vector.Zero;\r\n for (const member of this.members) {\r\n let graphic: Graphic;\r\n if (member instanceof Graphic) {\r\n graphic = member;\r\n } else {\r\n graphic = member.graphic;\r\n member.offset.clone(pos);\r\n }\r\n if (!graphic) {\r\n continue;\r\n }\r\n ex.save();\r\n ex.translate(x, y);\r\n graphic.draw(ex, pos.x, pos.y);\r\n if (this.showDebug) {\r\n /* istanbul ignore next */\r\n ex.debug.drawRect(0, 0, this.width, this.height);\r\n }\r\n ex.restore();\r\n }\r\n }\r\n}\r\n","export type Constructor = {\r\n new (...args: any[]): T;\r\n};\r\n/**\r\n * Configurable helper extends base type and makes all properties available as option bag arguments\r\n * @internal\r\n * @param base\r\n */\r\nexport function Configurable>(base: T): T {\r\n return class extends base {\r\n public assign(props: Partial) {\r\n //set the value of every property that was passed in,\r\n //if the constructor previously set this value, it will be overridden here\r\n for (const k in props) {\r\n // eslint-disable-next-line\r\n if (typeof (this)[k] !== 'function') {\r\n // eslint-disable-next-line\r\n (this)[k] = (props)[k];\r\n }\r\n }\r\n }\r\n\r\n constructor(...args: any[]) {\r\n super(...args);\r\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\r\n //of whatever ctor is the implementation, so args.length doesn't work here.\r\n const size = args.filter(function(value) {\r\n return value !== undefined;\r\n }).length;\r\n if (size === 1 && args[0] && typeof args[0] === 'object' && !(args[0] instanceof Array)) {\r\n this.assign(args[0]);\r\n }\r\n }\r\n };\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Actor } from './Actor';\r\nimport { Color } from './Color';\r\nimport { Vector, vec } from './Math/vector';\r\nimport * as Util from './Util/Util';\r\nimport { Configurable } from './Configurable';\r\nimport { Random } from './Math/Random';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { GraphicsComponent } from './Graphics/GraphicsComponent';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { BoundingBox } from './Collision/BoundingBox';\r\nimport { clamp, randomInRange } from './Math/util';\r\nimport { Graphic } from './Graphics';\r\n\r\n/**\r\n * An enum that represents the types of emitter nozzles\r\n */\r\nexport enum EmitterType {\r\n /**\r\n * Constant for the circular emitter type\r\n */\r\n Circle,\r\n /**\r\n * Constant for the rectangular emitter type\r\n */\r\n Rectangle\r\n}\r\n\r\n/**\r\n * @hidden\r\n */\r\nexport class ParticleImpl extends Entity {\r\n public position: Vector = new Vector(0, 0);\r\n public velocity: Vector = new Vector(0, 0);\r\n public acceleration: Vector = new Vector(0, 0);\r\n public particleRotationalVelocity: number = 0;\r\n public currentRotation: number = 0;\r\n\r\n public focus: Vector = null;\r\n public focusAccel: number = 0;\r\n public opacity: number = 1;\r\n public beginColor: Color = Color.White;\r\n public endColor: Color = Color.White;\r\n\r\n // Life is counted in ms\r\n public life: number = 300;\r\n public fadeFlag: boolean = false;\r\n\r\n // Color transitions\r\n private _rRate: number = 1;\r\n private _gRate: number = 1;\r\n private _bRate: number = 1;\r\n private _aRate: number = 0;\r\n private _currentColor: Color = Color.White;\r\n\r\n public emitter: ParticleEmitter = null;\r\n public particleSize: number = 5;\r\n public particleSprite: Graphic = null;\r\n\r\n public startSize: number;\r\n public endSize: number;\r\n public sizeRate: number = 0;\r\n public elapsedMultiplier: number = 0;\r\n\r\n public visible = true;\r\n public isOffscreen = false;\r\n\r\n public transform: TransformComponent;\r\n public graphics: GraphicsComponent;\r\n\r\n constructor(\r\n emitterOrConfig: ParticleEmitter | ParticleArgs,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number,\r\n particleSprite?: Graphic\r\n ) {\r\n super();\r\n let emitter = emitterOrConfig;\r\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\r\n const config = emitterOrConfig;\r\n emitter = config.emitter;\r\n life = config.life;\r\n opacity = config.opacity;\r\n endColor = config.endColor;\r\n beginColor = config.beginColor;\r\n position = config.position;\r\n velocity = config.velocity;\r\n acceleration = config.acceleration;\r\n startSize = config.startSize;\r\n endSize = config.endSize;\r\n particleSprite = config.particleSprite;\r\n }\r\n this.emitter = emitter;\r\n this.life = life || this.life;\r\n this.opacity = opacity || this.opacity;\r\n this.endColor = endColor || this.endColor.clone();\r\n this.beginColor = beginColor || this.beginColor.clone();\r\n this._currentColor = this.beginColor.clone();\r\n this.particleSprite = particleSprite;\r\n\r\n if (this.emitter.particleTransform === ParticleTransform.Global) {\r\n const globalPos = this.emitter.transform.globalPos;\r\n this.position = (position || this.position).add(globalPos);\r\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\r\n } else {\r\n this.velocity = velocity || this.velocity;\r\n this.position = (position || this.position);\r\n }\r\n this.acceleration = acceleration || this.acceleration;\r\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\r\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\r\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\r\n this._aRate = this.opacity / this.life;\r\n\r\n this.startSize = startSize || 0;\r\n this.endSize = endSize || 0;\r\n\r\n if (this.endSize > 0 && this.startSize > 0) {\r\n this.sizeRate = (this.endSize - this.startSize) / this.life;\r\n this.particleSize = this.startSize;\r\n }\r\n\r\n this.addComponent((this.transform = new TransformComponent()));\r\n this.addComponent((this.graphics = new GraphicsComponent()));\r\n\r\n this.transform.pos = this.position;\r\n this.transform.rotation = this.currentRotation;\r\n this.transform.scale = vec(1, 1); // TODO wut\r\n if (this.particleSprite) {\r\n this.graphics.opacity = this.opacity;\r\n this.graphics.use(this.particleSprite);\r\n } else {\r\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\r\n this.graphics.onPostDraw = (ctx) => {\r\n ctx.save();\r\n this.graphics.opacity = this.opacity;\r\n const tmpColor = this._currentColor.clone();\r\n tmpColor.a = 1;\r\n ctx.debug.drawPoint(vec(0, 0), { color: tmpColor, size: this.particleSize });\r\n ctx.restore();\r\n };\r\n }\r\n }\r\n\r\n public kill() {\r\n this.emitter.removeParticle(this);\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n this.life = this.life - delta;\r\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\r\n\r\n if (this.life < 0) {\r\n this.kill();\r\n }\r\n\r\n if (this.fadeFlag) {\r\n this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\r\n }\r\n\r\n if (this.startSize > 0 && this.endSize > 0) {\r\n this.particleSize = clamp(\r\n this.sizeRate * delta + this.particleSize,\r\n Math.min(this.startSize, this.endSize),\r\n Math.max(this.startSize, this.endSize)\r\n );\r\n }\r\n\r\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\r\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\r\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\r\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\r\n\r\n if (this.focus) {\r\n const accel = this.focus\r\n .sub(this.position)\r\n .normalize()\r\n .scale(this.focusAccel)\r\n .scale(delta / 1000);\r\n this.velocity = this.velocity.add(accel);\r\n } else {\r\n this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\r\n }\r\n this.position = this.position.add(this.velocity.scale(delta / 1000));\r\n\r\n if (this.particleRotationalVelocity) {\r\n this.currentRotation = (this.currentRotation + (this.particleRotationalVelocity * delta) / 1000) % (2 * Math.PI);\r\n }\r\n\r\n this.transform.pos = this.position;\r\n this.transform.rotation = this.currentRotation;\r\n this.transform.scale = vec(1, 1); // todo wut\r\n this.graphics.opacity = this.opacity;\r\n }\r\n}\r\n\r\nexport interface ParticleArgs extends Partial {\r\n emitter: ParticleEmitter;\r\n position?: Vector;\r\n velocity?: Vector;\r\n acceleration?: Vector;\r\n particleRotationalVelocity?: number;\r\n currentRotation?: number;\r\n particleSize?: number;\r\n particleSprite?: Graphic;\r\n}\r\n\r\n/**\r\n * Particle is used in a [[ParticleEmitter]]\r\n */\r\nexport class Particle extends Configurable(ParticleImpl) {\r\n constructor(config: ParticleArgs);\r\n constructor(\r\n emitter: ParticleEmitter,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number,\r\n particleSprite?: Graphic\r\n );\r\n constructor(\r\n emitterOrConfig: ParticleEmitter | ParticleArgs,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number,\r\n particleSprite?: Graphic\r\n ) {\r\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite);\r\n }\r\n}\r\n\r\nexport enum ParticleTransform {\r\n /**\r\n * [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n */\r\n Global = 'global',\r\n /**\r\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n Local = 'local'\r\n}\r\n\r\nexport interface ParticleEmitterArgs {\r\n x?: number;\r\n y?: number;\r\n pos?: Vector;\r\n width?: number;\r\n height?: number;\r\n isEmitting?: boolean;\r\n minVel?: number;\r\n maxVel?: number;\r\n acceleration?: Vector;\r\n minAngle?: number;\r\n maxAngle?: number;\r\n emitRate?: number;\r\n particleLife?: number;\r\n /**\r\n * Optionally set the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n *\r\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n particleTransform?: ParticleTransform;\r\n opacity?: number;\r\n fadeFlag?: boolean;\r\n focus?: Vector;\r\n focusAccel?: number;\r\n startSize?: number;\r\n endSize?: number;\r\n minSize?: number;\r\n maxSize?: number;\r\n beginColor?: Color;\r\n endColor?: Color;\r\n particleSprite?: Graphic;\r\n emitterType?: EmitterType;\r\n radius?: number;\r\n particleRotationalVelocity?: number;\r\n randomRotation?: boolean;\r\n random?: Random;\r\n}\r\n\r\n/**\r\n * Using a particle emitter is a great way to create interesting effects\r\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\r\n * extend [[Actor]] allowing you to use all of the features that come with.\r\n */\r\nexport class ParticleEmitter extends Actor {\r\n private _particlesToEmit: number = 0;\r\n\r\n public numParticles: number = 0;\r\n\r\n /**\r\n * Random number generator\r\n */\r\n public random: Random;\r\n\r\n /**\r\n * Gets or sets the isEmitting flag\r\n */\r\n public isEmitting: boolean = true;\r\n /**\r\n * Gets or sets the backing particle collection\r\n */\r\n public particles: Particle[] = [];\r\n\r\n /**\r\n * Gets or sets the backing deadParticle collection\r\n */\r\n public deadParticles: Particle[] = [];\r\n\r\n /**\r\n * Gets or sets the minimum particle velocity\r\n */\r\n public minVel: number = 0;\r\n /**\r\n * Gets or sets the maximum particle velocity\r\n */\r\n public maxVel: number = 0;\r\n\r\n /**\r\n * Gets or sets the acceleration vector for all particles\r\n */\r\n public acceleration: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Gets or sets the minimum angle in radians\r\n */\r\n public minAngle: number = 0;\r\n /**\r\n * Gets or sets the maximum angle in radians\r\n */\r\n public maxAngle: number = 0;\r\n\r\n /**\r\n * Gets or sets the emission rate for particles (particles/sec)\r\n */\r\n public emitRate: number = 1; //particles/sec\r\n /**\r\n * Gets or sets the life of each particle in milliseconds\r\n */\r\n public particleLife: number = 2000;\r\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */\r\n public get opacity(): number {\r\n return this.graphics.opacity;\r\n }\r\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */\r\n public set opacity(opacity: number) {\r\n this.graphics.opacity = opacity;\r\n }\r\n /**\r\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\r\n */\r\n public fadeFlag: boolean = false;\r\n\r\n /**\r\n * Gets or sets the optional focus where all particles should accelerate towards\r\n */\r\n public focus: Vector = null;\r\n /**\r\n * Gets or sets the acceleration for focusing particles if a focus has been specified\r\n */\r\n public focusAccel: number = null;\r\n /**\r\n * Gets or sets the optional starting size for the particles\r\n */\r\n public startSize: number = null;\r\n /**\r\n * Gets or sets the optional ending size for the particles\r\n */\r\n public endSize: number = null;\r\n\r\n /**\r\n * Gets or sets the minimum size of all particles\r\n */\r\n public minSize: number = 5;\r\n /**\r\n * Gets or sets the maximum size of all particles\r\n */\r\n public maxSize: number = 5;\r\n\r\n /**\r\n * Gets or sets the beginning color of all particles\r\n */\r\n public beginColor: Color = Color.White;\r\n /**\r\n * Gets or sets the ending color of all particles\r\n */\r\n public endColor: Color = Color.White;\r\n\r\n private _sprite: Graphic = null;\r\n /**\r\n * Gets or sets the sprite that a particle should use\r\n */\r\n public get particleSprite(): Graphic {\r\n return this._sprite;\r\n }\r\n\r\n public set particleSprite(val: Graphic) {\r\n if (val) {\r\n this._sprite = val;\r\n }\r\n }\r\n\r\n /**\r\n * Gets or sets the emitter type for the particle emitter\r\n */\r\n public emitterType: EmitterType = EmitterType.Rectangle;\r\n\r\n /**\r\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\r\n */\r\n public radius: number = 0;\r\n\r\n /**\r\n * Gets or sets the particle rotational speed velocity\r\n */\r\n public particleRotationalVelocity: number = 0;\r\n\r\n /**\r\n * Indicates whether particles should start with a random rotation\r\n */\r\n public randomRotation: boolean = false;\r\n\r\n /**\r\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n *\r\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n public particleTransform: ParticleTransform = ParticleTransform.Global;\r\n\r\n /**\r\n * @param config particle emitter options bag\r\n */\r\n constructor(config: ParticleEmitterArgs) {\r\n super({ width: config.width ?? 0, height: config.height ?? 0 });\r\n\r\n const {\r\n x,\r\n y,\r\n pos,\r\n isEmitting,\r\n minVel,\r\n maxVel,\r\n acceleration,\r\n minAngle,\r\n maxAngle,\r\n emitRate,\r\n particleLife,\r\n opacity,\r\n fadeFlag,\r\n focus,\r\n focusAccel,\r\n startSize,\r\n endSize,\r\n minSize,\r\n maxSize,\r\n beginColor,\r\n endColor,\r\n particleSprite,\r\n emitterType,\r\n radius,\r\n particleRotationalVelocity,\r\n particleTransform,\r\n randomRotation,\r\n random\r\n } = { ...config };\r\n\r\n this.pos = pos ?? vec(x ?? 0, y ?? 0);\r\n this.isEmitting = isEmitting ?? this.isEmitting;\r\n this.minVel = minVel ?? this.minVel;\r\n this.maxVel = maxVel ?? this.maxVel;\r\n this.acceleration = acceleration ?? this.acceleration;\r\n this.minAngle = minAngle ?? this.minAngle;\r\n this.maxAngle = maxAngle ?? this.maxAngle;\r\n this.emitRate = emitRate ?? this.emitRate;\r\n this.particleLife = particleLife ?? this.particleLife;\r\n this.opacity = opacity ?? this.opacity;\r\n this.fadeFlag = fadeFlag ?? this.fadeFlag;\r\n this.focus = focus ?? this.focus;\r\n this.focusAccel = focusAccel ?? this.focusAccel;\r\n this.startSize = startSize ?? this.startSize;\r\n this.endSize = endSize ?? this.endSize;\r\n this.minSize = minSize ?? this.minSize;\r\n this.maxSize = maxSize ?? this.maxSize;\r\n this.beginColor = beginColor ?? this.beginColor;\r\n this.endColor = endColor ?? this.endColor;\r\n this.particleSprite = particleSprite ?? this.particleSprite;\r\n this.emitterType = emitterType ?? this.emitterType;\r\n this.radius = radius ?? this.radius;\r\n this.particleRotationalVelocity = particleRotationalVelocity ?? this.particleRotationalVelocity;\r\n this.randomRotation = randomRotation ?? this.randomRotation;\r\n this.particleTransform = particleTransform ?? this.particleTransform;\r\n\r\n this.body.collisionType = CollisionType.PreventCollision;\r\n\r\n this.random = random ?? new Random();\r\n }\r\n\r\n public removeParticle(particle: Particle) {\r\n this.deadParticles.push(particle);\r\n }\r\n\r\n /**\r\n * Causes the emitter to emit particles\r\n * @param particleCount Number of particles to emit right now\r\n */\r\n public emitParticles(particleCount: number) {\r\n for (let i = 0; i < particleCount; i++) {\r\n const p = this._createParticle();\r\n this.particles.push(p);\r\n if (this?.scene?.world) {\r\n if (this.particleTransform === ParticleTransform.Global) {\r\n this.scene.world.add(p);\r\n } else {\r\n this.addChild(p);\r\n }\r\n }\r\n }\r\n }\r\n\r\n public clearParticles() {\r\n this.particles.length = 0;\r\n }\r\n\r\n // Creates a new particle given the constraints of the emitter\r\n private _createParticle(): Particle {\r\n // todo implement emitter constraints;\r\n let ranX = 0;\r\n let ranY = 0;\r\n\r\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\r\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\r\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\r\n const dx = vel * Math.cos(angle);\r\n const dy = vel * Math.sin(angle);\r\n\r\n if (this.emitterType === EmitterType.Rectangle) {\r\n ranX = randomInRange(0, this.width, this.random);\r\n ranY = randomInRange(0, this.height, this.random);\r\n } else if (this.emitterType === EmitterType.Circle) {\r\n const radius = randomInRange(0, this.radius, this.random);\r\n ranX = radius * Math.cos(angle);\r\n ranY = radius * Math.sin(angle);\r\n }\r\n\r\n const p = new Particle(\r\n this,\r\n this.particleLife,\r\n this.opacity,\r\n this.beginColor,\r\n this.endColor,\r\n new Vector(ranX, ranY),\r\n new Vector(dx, dy),\r\n this.acceleration,\r\n this.startSize,\r\n this.endSize,\r\n this.particleSprite\r\n );\r\n p.fadeFlag = this.fadeFlag;\r\n p.particleSize = size;\r\n p.particleRotationalVelocity = this.particleRotationalVelocity;\r\n if (this.randomRotation) {\r\n p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\r\n }\r\n if (this.focus) {\r\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\r\n p.focusAccel = this.focusAccel;\r\n }\r\n return p;\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n super.update(engine, delta);\r\n\r\n if (this.isEmitting) {\r\n this._particlesToEmit += this.emitRate * (delta / 1000);\r\n if (this._particlesToEmit > 1.0) {\r\n this.emitParticles(Math.floor(this._particlesToEmit));\r\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\r\n }\r\n }\r\n\r\n // deferred removal\r\n for (let i = 0; i < this.deadParticles.length; i++) {\r\n Util.removeItemFromArray(this.deadParticles[i], this.particles);\r\n if (this?.scene?.world) {\r\n this.scene.world.remove(this.deadParticles[i], false);\r\n }\r\n }\r\n this.deadParticles.length = 0;\r\n }\r\n}\r\n","import { Transform } from '../Math/transform';\r\n\r\n/**\r\n * Blend 2 transforms for interpolation, will interpolate from the context of newTx's parent if it exists\r\n */\r\nexport function blendTransform(oldTx: Transform, newTx: Transform, blend: number, target?: Transform): Transform {\r\n if (oldTx.parent !== newTx.parent) {\r\n // Caller expects a local transform\r\n // Adjust old tx to be local to the new parent whatever that is\r\n const oldTxWithNewParent = oldTx.clone();\r\n const oldGlobalPos = oldTx.globalPos.clone();\r\n const oldGlobalScale = oldTx.globalScale.clone();\r\n const oldGlobalRotation = oldTx.globalRotation;\r\n oldTxWithNewParent.parent = newTx.parent;\r\n oldTxWithNewParent.globalPos = oldGlobalPos;\r\n oldTxWithNewParent.globalScale = oldGlobalScale;\r\n oldTxWithNewParent.globalRotation = oldGlobalRotation;\r\n oldTx = oldTxWithNewParent;\r\n }\r\n let interpolatedPos = newTx.pos;\r\n let interpolatedScale = newTx.scale;\r\n let interpolatedRotation = newTx.rotation;\r\n\r\n interpolatedPos = newTx.pos.scale(blend).add(\r\n oldTx.pos.scale(1.0 - blend)\r\n );\r\n interpolatedScale = newTx.scale.scale(blend).add(\r\n oldTx.scale.scale(1.0 - blend)\r\n );\r\n // Rotational lerp https://stackoverflow.com/a/30129248\r\n const cosine = (1.0 - blend) * Math.cos(oldTx.rotation) + blend * Math.cos(newTx.rotation);\r\n const sine = (1.0 - blend) * Math.sin(oldTx.rotation) + blend * Math.sin(newTx.rotation);\r\n interpolatedRotation = Math.atan2(sine, cosine);\r\n\r\n const tx = target ?? new Transform();\r\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\r\n return tx;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function blendGlobalTransform(oldTx: Transform, newTx: Transform, blend: number, target?: Transform): Transform {\r\n let interpolatedPos = newTx.globalPos;\r\n let interpolatedScale = newTx.globalScale;\r\n let interpolatedRotation = newTx.globalRotation;\r\n\r\n interpolatedPos = newTx.globalPos.scale(blend).add(\r\n oldTx.globalPos.scale(1.0 - blend)\r\n );\r\n interpolatedScale = newTx.globalScale.scale(blend).add(\r\n oldTx.globalScale.scale(1.0 - blend)\r\n );\r\n // Rotational lerp https://stackoverflow.com/a/30129248\r\n const cosine = (1.0 - blend) * Math.cos(oldTx.globalRotation) + blend * Math.cos(newTx.globalRotation);\r\n const sine = (1.0 - blend) * Math.sin(oldTx.globalRotation) + blend * Math.sin(newTx.globalRotation);\r\n interpolatedRotation = Math.atan2(sine, cosine);\r\n\r\n const tx = target ?? new Transform();\r\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\r\n return tx;\r\n}","import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Scene } from '../Scene';\r\nimport { GraphicsComponent } from './GraphicsComponent';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Camera } from '../Camera';\r\nimport { Query, System, SystemPriority, SystemType, World } from '../EntityComponentSystem';\r\nimport { Engine } from '../Engine';\r\nimport { GraphicsGroup } from './GraphicsGroup';\r\nimport { Particle } from '../Particles'; // this import seems to bomb wallaby\r\nimport { ParallaxComponent } from './ParallaxComponent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { BodyComponent } from '../Collision/BodyComponent';\r\nimport { FontCache } from './FontCache';\r\nimport { PostDrawEvent, PostTransformDrawEvent, PreDrawEvent, PreTransformDrawEvent } from '../Events';\r\nimport { Transform } from '../Math/transform';\r\nimport { blendTransform } from './TransformInterpolation';\r\nimport { Graphic } from './Graphic';\r\n\r\nexport class GraphicsSystem extends System {\r\n public readonly systemType = SystemType.Draw;\r\n public priority = SystemPriority.Average;\r\n private _token = 0;\r\n private _graphicsContext: ExcaliburGraphicsContext;\r\n private _camera: Camera;\r\n private _engine: Engine;\r\n private _sortedTransforms: TransformComponent[] = [];\r\n query: Query;\r\n public get sortedTransforms() {\r\n return this._sortedTransforms;\r\n }\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent, GraphicsComponent]);\r\n this.query.entityAdded$.subscribe(e => {\r\n const tx = e.get(TransformComponent);\r\n this._sortedTransforms.push(tx);\r\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\r\n this._zHasChanged = true;\r\n });\r\n this.query.entityRemoved$.subscribe(e => {\r\n const tx = e.get(TransformComponent);\r\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\r\n const index = this._sortedTransforms.indexOf(tx);\r\n if (index > -1) {\r\n this._sortedTransforms.splice(index, 1);\r\n }\r\n });\r\n }\r\n\r\n public initialize(world: World, scene: Scene): void {\r\n this._camera = scene.camera;\r\n this._engine = scene.engine;\r\n }\r\n\r\n private _zHasChanged = false;\r\n private _zIndexUpdate = () => {\r\n this._zHasChanged = true;\r\n };\r\n\r\n public preupdate(): void {\r\n // Graphics context could be switched to fallback in a new frame\r\n this._graphicsContext = this._engine.graphicsContext;\r\n if (this._zHasChanged) {\r\n this._sortedTransforms.sort((a, b) => {\r\n return a.z - b.z;\r\n });\r\n this._zHasChanged = false;\r\n }\r\n }\r\n\r\n public update(delta: number): void {\r\n this._token++;\r\n let graphics: GraphicsComponent;\r\n FontCache.checkAndClearCache();\r\n\r\n // This is a performance enhancement, most things are in world space\r\n // so if we can only do this once saves a ton of transform updates\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n for (const transform of this._sortedTransforms) {\r\n const entity = transform.owner as Entity;\r\n\r\n // If the entity is offscreen skip\r\n if (entity.hasTag('ex.offscreen')) {\r\n continue;\r\n }\r\n\r\n graphics = entity.get(GraphicsComponent);\r\n // Exit if graphics set to not visible\r\n if (!graphics.visible) {\r\n continue;\r\n }\r\n\r\n // Optionally run the onPreTransformDraw graphics lifecycle draw\r\n if (graphics.onPreTransformDraw) {\r\n graphics.onPreTransformDraw(this._graphicsContext, delta);\r\n }\r\n entity.events.emit('pretransformdraw', new PreTransformDrawEvent(this._graphicsContext, delta, entity));\r\n\r\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.restore();\r\n }\r\n\r\n this._graphicsContext.save();\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\r\n }\r\n\r\n // Tick any graphics state (but only once) for animations and graphics groups\r\n graphics.update(delta, this._token);\r\n\r\n // Apply parallax\r\n const parallax = entity.get(ParallaxComponent);\r\n if (parallax) {\r\n // We use the Tiled formula\r\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\r\n // cameraPos * (1 - parallaxFactor)\r\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\r\n const parallaxOffset = this._camera.drawPos.scale(oneMinusFactor);\r\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\r\n }\r\n\r\n // Position the entity + estimate lag\r\n this._applyTransform(entity);\r\n\r\n // If there is a material enable it on the context\r\n if (graphics.material) {\r\n this._graphicsContext.material = graphics.material;\r\n }\r\n\r\n // Optionally run the onPreDraw graphics lifecycle draw\r\n if (graphics.onPreDraw) {\r\n graphics.onPreDraw(this._graphicsContext, delta);\r\n }\r\n entity.events.emit('predraw', new PreDrawEvent(this._graphicsContext, delta, entity));\r\n\r\n // TODO remove this hack on the particle redo\r\n // Remove this line after removing the wallaby import\r\n const particleOpacity = (entity instanceof Particle) ? entity.opacity : 1;\r\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\r\n\r\n // Draw the graphics component\r\n this._drawGraphicsComponent(graphics, transform);\r\n\r\n // Optionally run the onPostDraw graphics lifecycle draw\r\n if (graphics.onPostDraw) {\r\n graphics.onPostDraw(this._graphicsContext, delta);\r\n }\r\n entity.events.emit('postdraw', new PostDrawEvent(this._graphicsContext, delta, entity));\r\n\r\n this._graphicsContext.restore();\r\n\r\n // Reset the transform back to the original world space\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n }\r\n\r\n // Optionally run the onPreTransformDraw graphics lifecycle draw\r\n if (graphics.onPostTransformDraw) {\r\n graphics.onPostTransformDraw(this._graphicsContext, delta);\r\n }\r\n entity.events.emit('posttransformdraw', new PostTransformDrawEvent(this._graphicsContext, delta, entity));\r\n }\r\n this._graphicsContext.restore();\r\n }\r\n\r\n private _drawGraphicsComponent(graphicsComponent: GraphicsComponent, transformComponent: TransformComponent) {\r\n if (graphicsComponent.visible) {\r\n const flipHorizontal = graphicsComponent.flipHorizontal;\r\n const flipVertical = graphicsComponent.flipVertical;\r\n\r\n const graphic = graphicsComponent.current;\r\n const options = graphicsComponent.currentOptions ?? {};\r\n\r\n if (graphic) {\r\n let anchor = graphicsComponent.anchor;\r\n let offset = graphicsComponent.offset;\r\n let scaleX = 1;\r\n let scaleY = 1;\r\n // handle specific overrides\r\n if (options?.anchor) {\r\n anchor = options.anchor;\r\n }\r\n if (options?.offset) {\r\n offset = options.offset;\r\n }\r\n const globalScale = transformComponent.globalScale;\r\n scaleX *= graphic.scale.x * globalScale.x;\r\n scaleY *= graphic.scale.y * globalScale.y;\r\n\r\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\r\n const offsetX = -graphic.width * anchor.x + offset.x * scaleX;\r\n const offsetY = -graphic.height * anchor.y + offset.y * scaleY;\r\n\r\n const oldFlipHorizontal = graphic.flipHorizontal;\r\n const oldFlipVertical = graphic.flipVertical;\r\n if (flipHorizontal || flipVertical) {\r\n // flip any currently flipped graphics\r\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\r\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\r\n }\r\n\r\n graphic?.draw(\r\n this._graphicsContext,\r\n offsetX,\r\n offsetY);\r\n\r\n if (flipHorizontal || flipVertical) {\r\n graphic.flipHorizontal = oldFlipHorizontal;\r\n graphic.flipVertical = oldFlipVertical;\r\n }\r\n\r\n // TODO move debug code out?\r\n if (this._engine?.isDebug && this._engine.debug.graphics.showBounds) {\r\n const offset = vec(offsetX, offsetY);\r\n if (graphic instanceof GraphicsGroup) {\r\n for (const member of graphic.members) {\r\n let g: Graphic;\r\n let pos: Vector = Vector.Zero;\r\n if (member instanceof Graphic) {\r\n g = member;\r\n } else {\r\n g = member.graphic;\r\n pos = member.offset;\r\n }\r\n g?.localBounds.translate(offset.add(pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\r\n }\r\n } else {\r\n /* istanbul ignore next */\r\n graphic?.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _targetInterpolationTransform = new Transform();\r\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */\r\n private _applyTransform(entity: Entity): void {\r\n const ancestors = entity.getAncestors();\r\n for (const ancestor of ancestors) {\r\n const transform = ancestor?.get(TransformComponent);\r\n const optionalBody = ancestor?.get(BodyComponent);\r\n let tx = transform.get();\r\n if (optionalBody) {\r\n if (this._engine.fixedUpdateFps &&\r\n optionalBody.__oldTransformCaptured &&\r\n optionalBody.enableFixedUpdateInterpolate) {\r\n // Interpolate graphics if needed\r\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\r\n tx = blendTransform(optionalBody.oldTransform, transform.get(), blend, this._targetInterpolationTransform);\r\n }\r\n }\r\n\r\n if (transform) {\r\n this._graphicsContext.z = transform.z;\r\n this._graphicsContext.translate(tx.pos.x, tx.pos.y);\r\n this._graphicsContext.scale(tx.scale.x, tx.scale.y);\r\n this._graphicsContext.rotate(tx.rotation);\r\n }\r\n }\r\n }\r\n}\r\n","import { Engine } from '../Engine';\r\nimport { Scene } from '../Scene';\r\nimport { Camera } from '../Camera';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { Entity, Query, SystemPriority, TransformComponent, World } from '../EntityComponentSystem';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ExcaliburGraphicsContext } from '../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { toDegrees } from '../Math/util';\r\nimport { BodyComponent } from '../Collision/BodyComponent';\r\nimport { CollisionSystem } from '../Collision/CollisionSystem';\r\nimport { CompositeCollider } from '../Collision/Colliders/CompositeCollider';\r\nimport { GraphicsComponent } from '../Graphics/GraphicsComponent';\r\nimport { Particle } from '../Particles';\r\nimport { DebugGraphicsComponent } from '../Graphics/DebugGraphicsComponent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { Debug } from '../Graphics/Debug';\r\n\r\nexport class DebugSystem extends System {\r\n public readonly systemType = SystemType.Draw;\r\n public priority = SystemPriority.Lowest;\r\n private _graphicsContext: ExcaliburGraphicsContext;\r\n private _collisionSystem: CollisionSystem;\r\n private _camera: Camera;\r\n private _engine: Engine;\r\n query: Query;\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent]);\r\n }\r\n\r\n public initialize(world: World, scene: Scene): void {\r\n this._graphicsContext = scene.engine.graphicsContext;\r\n this._camera = scene.camera;\r\n this._engine = scene.engine;\r\n this._collisionSystem = world.systemManager.get(CollisionSystem);\r\n }\r\n\r\n update(): void {\r\n if (!this._engine.isDebug) {\r\n return;\r\n }\r\n\r\n const filterSettings = this._engine.debug.filter;\r\n\r\n let id: number;\r\n let name: string;\r\n const entitySettings = this._engine.debug.entity;\r\n\r\n let tx: TransformComponent;\r\n const txSettings = this._engine.debug.transform;\r\n\r\n let motion: MotionComponent;\r\n const motionSettings = this._engine.debug.motion;\r\n\r\n let colliderComp: ColliderComponent;\r\n const colliderSettings = this._engine.debug.collider;\r\n\r\n const physicsSettings = this._engine.debug.physics;\r\n\r\n let graphics: GraphicsComponent;\r\n const graphicsSettings = this._engine.debug.graphics;\r\n\r\n let debugDraw: DebugGraphicsComponent;\r\n\r\n let body: BodyComponent;\r\n const bodySettings = this._engine.debug.body;\r\n\r\n const cameraSettings = this._engine.debug.camera;\r\n for (const entity of this.query.entities) {\r\n if (entity.hasTag('offscreen')) {\r\n // skip offscreen entities\r\n continue;\r\n }\r\n if (entity instanceof Particle) {\r\n // Particles crush the renderer :(\r\n continue;\r\n }\r\n if (filterSettings.useFilter) {\r\n const allIds = filterSettings.ids.length === 0;\r\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\r\n if (!idMatch) {\r\n continue;\r\n }\r\n const allNames = filterSettings.nameQuery === '';\r\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\r\n if (!nameMatch) {\r\n continue;\r\n }\r\n }\r\n\r\n let cursor = Vector.Zero;\r\n const lineHeight = vec(0, 16);\r\n id = entity.id;\r\n name = entity.name;\r\n tx = entity.get(TransformComponent);\r\n\r\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\r\n this._pushCameraTransform(tx);\r\n\r\n this._graphicsContext.save();\r\n if (tx.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\r\n }\r\n this._graphicsContext.z = txSettings.debugZIndex;\r\n\r\n this._applyTransform(entity);\r\n if (tx) {\r\n if (txSettings.showAll || txSettings.showPosition) {\r\n this._graphicsContext.debug.drawPoint(Vector.Zero, { size: 4, color: txSettings.positionColor });\r\n }\r\n if (txSettings.showAll || txSettings.showPositionLabel) {\r\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (txSettings.showAll || txSettings.showZIndex) {\r\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (entitySettings.showAll || entitySettings.showId) {\r\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? 'child of id(' + entity.parent?.id + ')' : ''}`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (entitySettings.showAll || entitySettings.showName) {\r\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (txSettings.showAll || txSettings.showRotation) {\r\n this._graphicsContext.drawLine(\r\n Vector.Zero,\r\n Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero),\r\n txSettings.rotationColor,\r\n 2\r\n );\r\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (txSettings.showAll || txSettings.showScale) {\r\n this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\r\n }\r\n }\r\n\r\n graphics = entity.get(GraphicsComponent);\r\n if (graphics) {\r\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\r\n const bounds = graphics.localBounds;\r\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\r\n }\r\n }\r\n\r\n debugDraw = entity.get(DebugGraphicsComponent);\r\n if (debugDraw) {\r\n if (!debugDraw.useTransform) {\r\n this._graphicsContext.restore();\r\n }\r\n debugDraw.draw(this._graphicsContext, this._engine.debug);\r\n if (!debugDraw.useTransform) {\r\n this._graphicsContext.save();\r\n this._applyTransform(entity);\r\n }\r\n }\r\n\r\n body = entity.get(BodyComponent);\r\n if (body) {\r\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\r\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showCollisionType) {\r\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showMass) {\r\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showMotion) {\r\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showSleeping) {\r\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping: 'cant sleep'})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n }\r\n\r\n this._graphicsContext.restore();\r\n\r\n // World space\r\n this._graphicsContext.save();\r\n if (tx.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\r\n }\r\n this._graphicsContext.z = txSettings.debugZIndex;\r\n motion = entity.get(MotionComponent);\r\n if (motion) {\r\n if (motionSettings.showAll || motionSettings.showVelocity) {\r\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\r\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (motionSettings.showAll || motionSettings.showAcceleration) {\r\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\r\n }\r\n }\r\n\r\n // Colliders live in world space already so after the restore()\r\n colliderComp = entity.get(ColliderComponent);\r\n if (colliderComp) {\r\n const collider = colliderComp.get();\r\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) {\r\n collider.debug(this._graphicsContext, colliderSettings.geometryColor, {\r\n lineWidth: colliderSettings.geometryLineWidth,\r\n pointSize: colliderSettings.geometryPointSize\r\n });\r\n }\r\n if (colliderSettings.showAll || colliderSettings.showBounds) {\r\n if (collider instanceof CompositeCollider) {\r\n const colliders = collider.getColliders();\r\n for (const collider of colliders) {\r\n const bounds = collider.bounds;\r\n const pos = vec(bounds.left, bounds.top);\r\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\r\n if (colliderSettings.showAll || colliderSettings.showOwner) {\r\n this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\r\n }\r\n }\r\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\r\n } else if (collider) {\r\n const bounds = colliderComp.bounds;\r\n const pos = vec(bounds.left, bounds.top);\r\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\r\n if (colliderSettings.showAll || colliderSettings.showOwner) {\r\n this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\r\n }\r\n }\r\n }\r\n }\r\n\r\n this._graphicsContext.restore();\r\n this._popCameraTransform(tx);\r\n }\r\n\r\n this._graphicsContext.save();\r\n this._camera.draw(this._graphicsContext);\r\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) {\r\n this._collisionSystem.debug(this._graphicsContext);\r\n }\r\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) {\r\n for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts) {\r\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) {\r\n for (const point of contact.points) {\r\n this._graphicsContext.debug.drawPoint(point, {\r\n size: physicsSettings.contactSize,\r\n color: physicsSettings.collisionContactColor\r\n });\r\n }\r\n }\r\n\r\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) {\r\n for (const point of contact.points) {\r\n this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\r\n color: physicsSettings.collisionNormalColor\r\n });\r\n }\r\n }\r\n }\r\n }\r\n this._graphicsContext.restore();\r\n\r\n if (cameraSettings) {\r\n this._graphicsContext.save();\r\n this._camera.draw(this._graphicsContext);\r\n if (cameraSettings.showAll || cameraSettings.showFocus) {\r\n this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\r\n }\r\n if (cameraSettings.showAll || cameraSettings.showZoom) {\r\n this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\r\n }\r\n this._graphicsContext.restore();\r\n }\r\n\r\n this._graphicsContext.flush();\r\n }\r\n\r\n postupdate(engine: Scene, elapsedMs: number): void {\r\n if (this._engine.isDebug) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n Debug.flush(this._graphicsContext);\r\n this._graphicsContext.restore();\r\n }\r\n }\r\n\r\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */\r\n private _applyTransform(entity: Entity): void {\r\n const ancestors = entity.getAncestors();\r\n for (const ancestor of ancestors) {\r\n const transform = ancestor?.get(TransformComponent);\r\n if (transform) {\r\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\r\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\r\n this._graphicsContext.rotate(transform.rotation);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Applies the current camera transform if in world coordinates\r\n * @param transform\r\n */\r\n private _pushCameraTransform(transform: TransformComponent) {\r\n // Establish camera offset per entity\r\n if (transform.coordPlane === CoordPlane.World) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resets the current camera transform if in world coordinates\r\n * @param transform\r\n */\r\n private _popCameraTransform(transform: TransformComponent) {\r\n if (transform.coordPlane === CoordPlane.World) {\r\n // Apply camera world offset\r\n this._graphicsContext.restore();\r\n }\r\n }\r\n}\r\n","import { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { Engine } from '../Engine';\r\nimport {\r\n System,\r\n TransformComponent,\r\n SystemType,\r\n Entity,\r\n World,\r\n Query,\r\n SystemPriority\r\n} from '../EntityComponentSystem';\r\nimport { GraphicsComponent } from '../Graphics/GraphicsComponent';\r\nimport { Scene } from '../Scene';\r\nimport { PointerComponent } from './PointerComponent';\r\nimport { PointerEventReceiver } from './PointerEventReceiver';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\n\r\n/**\r\n * The PointerSystem is responsible for dispatching pointer events to entities\r\n * that need them.\r\n *\r\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\r\n * the [[Collider]]'s shape for pointer events.\r\n */\r\nexport class PointerSystem extends System {\r\n public readonly systemType = SystemType.Update;\r\n public priority = SystemPriority.Higher;\r\n\r\n private _engine: Engine;\r\n private _receivers: PointerEventReceiver[];\r\n private _engineReceiver: PointerEventReceiver;\r\n query: Query;\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent, PointerComponent]);\r\n this.query.entityAdded$.subscribe(e => {\r\n const tx = e.get(TransformComponent);\r\n this._sortedTransforms.push(tx);\r\n this._sortedEntities.push(tx.owner);\r\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\r\n this._zHasChanged = true;\r\n });\r\n\r\n this.query.entityRemoved$.subscribe(e => {\r\n const tx = e.get(TransformComponent);\r\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\r\n const index = this._sortedTransforms.indexOf(tx);\r\n if (index > -1) {\r\n this._sortedTransforms.splice(index, 1);\r\n this._sortedEntities.splice(index, 1);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Optionally override component configuration for all entities\r\n */\r\n public overrideUseColliderShape = false;\r\n /**\r\n * Optionally override component configuration for all entities\r\n */\r\n public overrideUseGraphicsBounds = false;\r\n\r\n public lastFrameEntityToPointers = new Map();\r\n public currentFrameEntityToPointers = new Map();\r\n private _scene: Scene;\r\n\r\n public initialize(world: World, scene: Scene): void {\r\n this._engine = scene.engine;\r\n this._scene = scene;\r\n }\r\n\r\n private _sortedTransforms: TransformComponent[] = [];\r\n private _sortedEntities: Entity[] = [];\r\n\r\n private _zHasChanged = false;\r\n private _zIndexUpdate = () => {\r\n this._zHasChanged = true;\r\n };\r\n\r\n public preupdate(): void {\r\n // event receiver might change per frame\r\n this._receivers = [this._engine.input.pointers, this._scene.input.pointers];\r\n this._engineReceiver = this._engine.input.pointers;\r\n if (this._zHasChanged) {\r\n this._sortedTransforms.sort((a, b) => {\r\n return b.z - a.z;\r\n });\r\n this._sortedEntities = this._sortedTransforms.map(t => t.owner);\r\n this._zHasChanged = false;\r\n }\r\n }\r\n\r\n\r\n\r\n public entityCurrentlyUnderPointer(entity: Entity, pointerId: number) {\r\n return this.currentFrameEntityToPointers.has(entity.id) &&\r\n this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\r\n }\r\n\r\n public entityWasUnderPointer(entity: Entity, pointerId: number) {\r\n return this.lastFrameEntityToPointers.has(entity.id) &&\r\n this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\r\n }\r\n\r\n public entered(entity: Entity, pointerId: number) {\r\n return this.entityCurrentlyUnderPointer(entity, pointerId) &&\r\n !this.lastFrameEntityToPointers.has(entity.id);\r\n }\r\n\r\n public left(entity: Entity, pointerId: number) {\r\n return !this.currentFrameEntityToPointers.has(entity.id) &&\r\n this.entityWasUnderPointer(entity, pointerId);\r\n }\r\n\r\n public addPointerToEntity(entity: Entity, pointerId: number) {\r\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\r\n this.currentFrameEntityToPointers.set(entity.id, [pointerId]);\r\n return;\r\n }\r\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\r\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\r\n }\r\n\r\n public update(): void {\r\n // Locate all the pointer/entity mappings\r\n this._processPointerToEntity(this._sortedEntities);\r\n\r\n // Dispatch pointer events on entities\r\n this._dispatchEvents(this._sortedEntities);\r\n\r\n // Clear last frame's events\r\n this._receivers.forEach(r => r.update());\r\n this.lastFrameEntityToPointers.clear();\r\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\r\n this.currentFrameEntityToPointers.clear();\r\n this._receivers.forEach(r => r.clear());\r\n }\r\n\r\n private _processPointerToEntity(entities: Entity[]) {\r\n let transform: TransformComponent;\r\n let collider: ColliderComponent;\r\n let graphics: GraphicsComponent;\r\n let pointer: PointerComponent;\r\n const receiver = this._engineReceiver;\r\n\r\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\r\n // doesn't seem to cause issues tho for perf\r\n\r\n // Pre-process find entities under pointers\r\n for (const entity of entities) {\r\n transform = entity.get(TransformComponent);\r\n pointer = entity.get(PointerComponent) ?? new PointerComponent;\r\n // Check collider contains pointer\r\n collider = entity.get(ColliderComponent);\r\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\r\n collider.update();\r\n const geom = collider.get();\r\n if (geom) {\r\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries()) {\r\n if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\r\n this.addPointerToEntity(entity, pointerId);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Check graphics contains pointer\r\n graphics = entity.get(GraphicsComponent);\r\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\r\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\r\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries()) {\r\n if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\r\n this.addPointerToEntity(entity, pointerId);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _processDownAndEmit(entity: Entity): Map {\r\n const receiver = this._engineReceiver;\r\n const lastDownPerPointer = new Map(); // TODO will this get confused between receivers?\r\n // Loop through down and dispatch to entities\r\n for (const event of receiver.currentFrameDown) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointerdown', event as any);\r\n if (receiver.isDragStart(event.pointerId)) {\r\n entity.events.emit('pointerdragstart', event as any);\r\n }\r\n }\r\n lastDownPerPointer.set(event.pointerId, event);\r\n }\r\n return lastDownPerPointer;\r\n }\r\n\r\n private _processUpAndEmit(entity: Entity): Map {\r\n const receiver = this._engineReceiver;\r\n const lastUpPerPointer = new Map();\r\n // Loop through up and dispatch to entities\r\n for (const event of receiver.currentFrameUp) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointerup', event as any);\r\n if (receiver.isDragEnd(event.pointerId)) {\r\n entity.events.emit('pointerdragend', event as any);\r\n }\r\n }\r\n lastUpPerPointer.set(event.pointerId, event);\r\n }\r\n return lastUpPerPointer;\r\n }\r\n\r\n private _processMoveAndEmit(entity: Entity): Map {\r\n const receiver = this._engineReceiver;\r\n const lastMovePerPointer = new Map();\r\n // Loop through move and dispatch to entities\r\n for (const event of receiver.currentFrameMove) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n // move\r\n entity.events.emit('pointermove', event as any);\r\n\r\n if (receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragmove', event as any);\r\n }\r\n }\r\n lastMovePerPointer.set(event.pointerId, event);\r\n }\r\n return lastMovePerPointer;\r\n }\r\n\r\n private _processEnterLeaveAndEmit(entity: Entity, lastUpDownMoveEvents: PointerEvent[]) {\r\n const receiver = this._engineReceiver;\r\n // up, down, and move are considered for enter and leave\r\n for (const event of lastUpDownMoveEvents) {\r\n // enter\r\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\r\n entity.events.emit('pointerenter', event as any);\r\n if (receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragenter', event as any);\r\n }\r\n break;\r\n }\r\n if (event.active && entity.active &&\r\n // leave can happen on move\r\n (this.left(entity, event.pointerId) ||\r\n // or leave can happen on pointer up\r\n (this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === 'up'))) {\r\n entity.events.emit('pointerleave', event as any);\r\n if (receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragleave', event as any);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private _processCancelAndEmit(entity: Entity) {\r\n const receiver = this._engineReceiver;\r\n // cancel\r\n for (const event of receiver.currentFrameCancel) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)){\r\n entity.events.emit('pointercancel', event as any);\r\n }\r\n }\r\n }\r\n\r\n private _processWheelAndEmit(entity: Entity) {\r\n const receiver = this._engineReceiver;\r\n // wheel\r\n for (const event of receiver.currentFrameWheel) {\r\n // Currently the wheel only fires under the primary pointer '0'\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) {\r\n entity.events.emit('pointerwheel', event as any);\r\n }\r\n }\r\n }\r\n\r\n private _dispatchEvents(entities: Entity[]) {\r\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\r\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\r\n // Filter preserves z order\r\n const entitiesWithEvents = entities.filter(e => lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\r\n let lastMovePerPointer: Map;\r\n let lastUpPerPointer: Map;\r\n let lastDownPerPointer: Map;\r\n // Dispatch events in entity z order\r\n for (const entity of entitiesWithEvents) {\r\n lastDownPerPointer = this._processDownAndEmit(entity);\r\n\r\n lastUpPerPointer = this._processUpAndEmit(entity);\r\n\r\n lastMovePerPointer = this._processMoveAndEmit(entity);\r\n\r\n const lastUpDownMoveEvents = [\r\n ...lastMovePerPointer.values(),\r\n ...lastDownPerPointer.values(),\r\n ...lastUpPerPointer.values()\r\n ];\r\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\r\n\r\n this._processCancelAndEmit(entity);\r\n\r\n this._processWheelAndEmit(entity);\r\n }\r\n }\r\n}","import { Query, SystemPriority, World } from '../EntityComponentSystem';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ActionsComponent } from './ActionsComponent';\r\n\r\nexport class ActionsSystem extends System {\r\n systemType = SystemType.Update;\r\n priority = SystemPriority.Higher;\r\n private _actions: ActionsComponent[] = [];\r\n query: Query;\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([ActionsComponent]);\r\n\r\n this.query.entityAdded$.subscribe(e => this._actions.push(e.get(ActionsComponent)));\r\n this.query.entityRemoved$.subscribe(e => {\r\n const action = e.get(ActionsComponent);\r\n const index = this._actions.indexOf(action);\r\n if (index > -1) {\r\n this._actions.splice(index, 1);\r\n }\r\n });\r\n }\r\n update(delta: number): void {\r\n for (const actions of this._actions) {\r\n actions.update(delta);\r\n }\r\n }\r\n}","import { Component } from '../EntityComponentSystem/Component';\r\nimport { IsometricMap } from './IsometricMap';\r\n\r\nexport interface IsometricEntityComponentOptions {\r\n columns: number;\r\n rows: number;\r\n tileWidth: number;\r\n tileHeight: number;\r\n}\r\n\r\nexport class IsometricEntityComponent extends Component {\r\n /**\r\n * Vertical \"height\" in the isometric world\r\n */\r\n public elevation: number = 0;\r\n\r\n public readonly columns: number;\r\n public readonly rows: number;\r\n public readonly tileWidth: number;\r\n public readonly tileHeight: number;\r\n\r\n /**\r\n * Specify the isometric map to use to position this entity's z-index\r\n * @param mapOrOptions\r\n */\r\n constructor(mapOrOptions: IsometricMap | IsometricEntityComponentOptions) {\r\n super();\r\n this.columns = mapOrOptions.columns;\r\n this.rows = mapOrOptions.rows;\r\n this.tileWidth = mapOrOptions.tileWidth;\r\n this.tileHeight = mapOrOptions.tileHeight;\r\n }\r\n}","import { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { IsometricEntityComponent } from './IsometricEntityComponent';\r\nimport { Query, SystemPriority, World } from '../EntityComponentSystem';\r\n\r\n\r\nexport class IsometricEntitySystem extends System {\r\n public readonly systemType = SystemType.Update;\r\n priority: number = SystemPriority.Lower;\r\n query: Query;\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent, IsometricEntityComponent]);\r\n }\r\n\r\n update(): void {\r\n let transform: TransformComponent;\r\n let iso: IsometricEntityComponent;\r\n for (const entity of this.query.entities) {\r\n transform = entity.get(TransformComponent);\r\n iso = entity.get(IsometricEntityComponent);\r\n\r\n const maxZindexPerElevation = Math.max(iso.columns * iso.tileWidth, iso.rows * iso.tileHeight);\r\n\r\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\r\n transform.z = newZ;\r\n }\r\n }\r\n}","import { GraphicsComponent } from './GraphicsComponent';\r\nimport { EnterViewPortEvent, ExitViewPortEvent } from '../Events';\r\nimport { Scene } from '../Scene';\r\nimport { Screen } from '../Screen';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Camera } from '../Camera';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ParallaxComponent } from './ParallaxComponent';\r\nimport { Vector } from '../Math/vector';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Query, SystemPriority, World } from '../EntityComponentSystem';\r\n\r\nexport class OffscreenSystem extends System {\r\n public systemType = SystemType.Draw;\r\n priority: number = SystemPriority.Higher;\r\n private _camera: Camera;\r\n private _screen: Screen;\r\n private _worldBounds: BoundingBox;\r\n query: Query;\r\n\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent, GraphicsComponent]);\r\n }\r\n\r\n public initialize(world: World, scene: Scene): void {\r\n this._camera = scene.camera;\r\n this._screen = scene.engine.screen;\r\n }\r\n\r\n update(): void {\r\n this._worldBounds = this._screen.getWorldBounds();\r\n let transform: TransformComponent;\r\n let graphics: GraphicsComponent;\r\n let maybeParallax: ParallaxComponent;\r\n\r\n for (const entity of this.query.entities) {\r\n graphics = entity.get(GraphicsComponent);\r\n transform = entity.get(TransformComponent);\r\n maybeParallax = entity.get(ParallaxComponent);\r\n\r\n let parallaxOffset: Vector;\r\n if (maybeParallax) {\r\n // We use the Tiled formula\r\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\r\n // cameraPos * (1 - parallaxFactor)\r\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\r\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\r\n }\r\n\r\n // Figure out if entities are offscreen\r\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\r\n if (entityOffscreen && !entity.hasTag('ex.offscreen')) {\r\n entity.events.emit('exitviewport', new ExitViewPortEvent(entity));\r\n entity.addTag('ex.offscreen');\r\n }\r\n\r\n if (!entityOffscreen && entity.hasTag('ex.offscreen')) {\r\n entity.events.emit('enterviewport', new EnterViewPortEvent(entity));\r\n entity.removeTag('ex.offscreen');\r\n }\r\n }\r\n }\r\n\r\n private _isOffscreen(transform: TransformComponent, graphics: GraphicsComponent, parallaxOffset: Vector) {\r\n if (transform.coordPlane === CoordPlane.World) {\r\n let bounds = graphics.localBounds;\r\n if (parallaxOffset) {\r\n bounds = bounds.translate(parallaxOffset);\r\n }\r\n const transformedBounds = bounds.transform(transform.get().matrix);\r\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\r\n return graphicsOffscreen;\r\n } else {\r\n // TODO screen coordinates\r\n return false;\r\n }\r\n }\r\n\r\n}","import { Ray } from '../Math/ray';\r\nimport { DeepRequired } from '../Util/Required';\r\nimport { Observable } from '../Util/Observable';\r\nimport { DynamicTreeCollisionProcessor, RayCastHit, RayCastOptions } from './Index';\r\nimport { BodyComponent } from './BodyComponent';\r\nimport { PhysicsConfig } from './PhysicsConfig';\r\nimport { watchDeep } from '../Util/Watch';\r\n\r\nexport class PhysicsWorld {\r\n\r\n $configUpdate = new Observable>;\r\n\r\n private _configDirty = false;\r\n private _config: DeepRequired;\r\n get config(): DeepRequired {\r\n return watchDeep(this._config, change => {\r\n this.$configUpdate.notifyAll(change);\r\n });\r\n }\r\n set config(newConfig: DeepRequired) {\r\n this._config = newConfig;\r\n this.$configUpdate.notifyAll(newConfig);\r\n }\r\n\r\n private _collisionProcessor: DynamicTreeCollisionProcessor;\r\n /**\r\n * Spatial data structure for locating potential collision pairs and ray casts\r\n */\r\n public get collisionProcessor(): DynamicTreeCollisionProcessor {\r\n if (this._configDirty) {\r\n this._configDirty = false;\r\n // preserve tracked colliders if config updates\r\n const colliders = this._collisionProcessor.getColliders();\r\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this._config);\r\n for (const collider of colliders) {\r\n this._collisionProcessor.track(collider);\r\n }\r\n }\r\n return this._collisionProcessor;\r\n }\r\n constructor(config: DeepRequired) {\r\n this.config = config;\r\n this.$configUpdate.subscribe((config) => {\r\n this._configDirty = true;\r\n BodyComponent.updateDefaultPhysicsConfig(config.bodies);\r\n });\r\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this.config);\r\n }\r\n\r\n /**\r\n * Raycast into the scene's physics world\r\n * @param ray\r\n * @param options\r\n */\r\n public rayCast(ray: Ray, options?: RayCastOptions): RayCastHit[] {\r\n return this.collisionProcessor.rayCast(ray, options);\r\n }\r\n}","import { GamepadConnectEvent, GamepadDisconnectEvent, GamepadButtonEvent, GamepadAxisEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\nexport type GamepadEvents = {\r\n connect: GamepadConnectEvent,\r\n disconnect: GamepadDisconnectEvent,\r\n button: GamepadButtonEvent,\r\n axis: GamepadAxisEvent\r\n}\r\n\r\nexport const GamepadEvents = {\r\n GamepadConnect: 'connect',\r\n GamepadDisconnect: 'disconnect',\r\n GamepadButton: 'button',\r\n GamepadAxis: 'axis'\r\n};\r\n\r\n/**\r\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\r\n * to provide controller support for your games.\r\n */\r\nexport class Gamepads {\r\n public events = new EventEmitter();\r\n /**\r\n * Whether or not to poll for Gamepad input (default: `false`)\r\n */\r\n public enabled = false;\r\n\r\n /**\r\n * Whether or not Gamepad API is supported\r\n */\r\n public supported = !!(navigator).getGamepads;\r\n\r\n /**\r\n * The minimum value an axis has to move before considering it a change\r\n */\r\n public static MinAxisMoveThreshold = 0.05;\r\n\r\n private _gamePadTimeStamps = [0, 0, 0, 0];\r\n private _oldPads: Gamepad[] = [];\r\n private _pads: Gamepad[] = [];\r\n private _initSuccess: boolean = false;\r\n private _navigator: NavigatorGamepads = navigator;\r\n private _minimumConfiguration: GamepadConfiguration = null;\r\n private _enabled = true;\r\n\r\n public init() {\r\n if (!this.supported) {\r\n return;\r\n }\r\n if (this._initSuccess) {\r\n return;\r\n }\r\n\r\n // In Chrome, this will return 4 undefined items until a button is pressed\r\n // In FF, this will not return any items until a button is pressed\r\n this._oldPads = this._clonePads(this._navigator.getGamepads());\r\n if (this._oldPads.length && this._oldPads[0]) {\r\n this._initSuccess = true;\r\n }\r\n }\r\n\r\n public toggleEnabled(enabled: boolean) {\r\n this._enabled = enabled;\r\n }\r\n\r\n /**\r\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\r\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\r\n * all other controllers with more axis or buttons are valid as well. If no minimum\r\n * configuration is set all pads are valid.\r\n */\r\n public setMinimumGamepadConfiguration(config: GamepadConfiguration): void {\r\n this._enableAndUpdate(); // if config is used, implicitly enable\r\n this._minimumConfiguration = config;\r\n }\r\n\r\n /**\r\n * When implicitly enabled, set the enabled flag and run an update so information is updated\r\n */\r\n private _enableAndUpdate() {\r\n if (!this.enabled) {\r\n this.enabled = true;\r\n this.update();\r\n }\r\n }\r\n\r\n /**\r\n * Checks a navigator gamepad against the minimum configuration if present.\r\n */\r\n private _isGamepadValid(pad: NavigatorGamepad): boolean {\r\n if (!this._minimumConfiguration) {\r\n return true;\r\n }\r\n if (!pad) {\r\n return false;\r\n }\r\n const axesLength = pad.axes.filter((value) => {\r\n return typeof value !== undefined;\r\n }).length;\r\n\r\n const buttonLength = pad.buttons.filter((value) => {\r\n return typeof value !== undefined;\r\n }).length;\r\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: GamepadEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._enableAndUpdate(); // implicitly enable\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this._enableAndUpdate(); // implicitly enable\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Updates Gamepad state and publishes Gamepad events\r\n */\r\n public update() {\r\n if (!this.enabled || !this.supported) {\r\n return;\r\n }\r\n if (!this._enabled) {\r\n return;\r\n }\r\n this.init();\r\n\r\n const gamepads = this._navigator.getGamepads();\r\n\r\n for (let i = 0; i < gamepads.length; i++) {\r\n if (!gamepads[i]) {\r\n const gamepad = this.at(i);\r\n // If was connected, but now isn't emit the disconnect event\r\n if (gamepad.connected) {\r\n this.events.emit('disconnect', new GamepadDisconnectEvent(i, gamepad));\r\n }\r\n // Reset connection status\r\n gamepad.connected = false;\r\n continue;\r\n } else {\r\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) {\r\n this.events.emit('connect', new GamepadConnectEvent(i, this.at(i)));\r\n }\r\n // Set connection status\r\n this.at(i).connected = true;\r\n }\r\n\r\n this.at(i).update();\r\n\r\n // Only supported in Chrome\r\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) {\r\n continue;\r\n }\r\n\r\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\r\n\r\n // Add reference to navigator gamepad\r\n this.at(i).navigatorGamepad = gamepads[i];\r\n\r\n // Buttons\r\n let b: string, bi: number, a: string, ai: number, value: number;\r\n\r\n for (b in Buttons) {\r\n bi = Buttons[b];\r\n if (typeof bi === 'number') {\r\n if (gamepads[i].buttons[bi]) {\r\n value = gamepads[i].buttons[bi].value;\r\n if (value !== this._oldPads[i].getButton(bi)) {\r\n if (gamepads[i].buttons[bi].pressed) {\r\n this.at(i).updateButton(bi, value);\r\n this.at(i).events.emit('button', new GamepadButtonEvent(bi, value, this.at(i)));\r\n } else {\r\n this.at(i).updateButton(bi, 0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Axes\r\n for (a in Axes) {\r\n ai = Axes[a];\r\n if (typeof ai === 'number') {\r\n value = gamepads[i].axes[ai];\r\n if (value !== this._oldPads[i].getAxes(ai)) {\r\n this.at(i).updateAxes(ai, value);\r\n this.at(i).events.emit('axis', new GamepadAxisEvent(ai, value, this.at(i)));\r\n }\r\n }\r\n }\r\n\r\n this._oldPads[i] = this._clonePad(gamepads[i]);\r\n }\r\n }\r\n\r\n /**\r\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\r\n */\r\n public at(index: number): Gamepad {\r\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\r\n if (index >= this._pads.length) {\r\n // Ensure there is a pad to retrieve\r\n for (let i = this._pads.length - 1, max = index; i < max; i++) {\r\n this._pads.push(new Gamepad());\r\n this._oldPads.push(new Gamepad());\r\n }\r\n }\r\n\r\n return this._pads[index];\r\n }\r\n\r\n /**\r\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\r\n */\r\n public getValidGamepads(): Gamepad[] {\r\n this._enableAndUpdate();\r\n const result: Gamepad[] = [];\r\n for (let i = 0; i < this._pads.length; i++) {\r\n if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) {\r\n result.push(this.at(i));\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets the number of connected gamepads\r\n */\r\n public count() {\r\n return this._pads.filter((p) => p.connected).length;\r\n }\r\n\r\n private _clonePads(pads: NavigatorGamepad[]): Gamepad[] {\r\n const arr = [];\r\n for (let i = 0, len = pads.length; i < len; i++) {\r\n arr.push(this._clonePad(pads[i]));\r\n }\r\n return arr;\r\n }\r\n\r\n /**\r\n * Fastest way to clone a known object is to do it yourself\r\n */\r\n private _clonePad(pad: NavigatorGamepad): Gamepad {\r\n let i, len;\r\n const clonedPad = new Gamepad();\r\n\r\n if (!pad) {\r\n return clonedPad;\r\n }\r\n\r\n for (i = 0, len = pad.buttons.length; i < len; i++) {\r\n if (pad.buttons[i]) {\r\n clonedPad.updateButton(i, pad.buttons[i].value);\r\n }\r\n }\r\n for (i = 0, len = pad.axes.length; i < len; i++) {\r\n clonedPad.updateAxes(i, pad.axes[i]);\r\n }\r\n\r\n\r\n return clonedPad;\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\r\n * for more information on handling controller input.\r\n */\r\nexport class Gamepad {\r\n public events = new EventEmitter();\r\n public connected = false;\r\n public navigatorGamepad: NavigatorGamepad;\r\n private _axes: number[] = new Array(4);\r\n private _buttons: number[] = new Array(16);\r\n private _buttonsUp: number[] = new Array(16);\r\n private _buttonsDown: number[] = new Array(16);\r\n\r\n constructor() {\r\n for (let i = 0; i < this._buttons.length; i++) {\r\n this._buttons[i] = 0;\r\n }\r\n for (let i = 0; i < this._axes.length; i++) {\r\n this._axes[i] = 0;\r\n }\r\n }\r\n\r\n public update() {\r\n // Reset buttonsDown and buttonsUp after update is complete\r\n this._buttonsDown = new Array(16);\r\n this._buttonsUp = new Array(16);\r\n }\r\n\r\n /**\r\n * Whether or not the given button is pressed\r\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public isButtonPressed(button: Buttons, threshold: number = 1) {\r\n return this._buttons[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button is held down. This is persisted between frames.\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public isButtonHeld(button: Buttons, threshold: number = 1) {\r\n return this._buttons[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\r\n * @param button Test whether a button was just pressed\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public wasButtonPressed(button: Buttons, threshold: number = 1) {\r\n return this._buttonsDown[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\r\n * @param button Test whether a button was just released\r\n */\r\n public wasButtonReleased(button: Buttons) {\r\n return Boolean(this._buttonsUp[button]);\r\n }\r\n\r\n /**\r\n * Gets the given button value between 0 and 1\r\n */\r\n public getButton(button: Buttons) {\r\n return this._buttons[button];\r\n }\r\n\r\n /**\r\n * Gets the given axis value between -1 and 1. Values below\r\n * [[MinAxisMoveThreshold]] are considered 0.\r\n */\r\n public getAxes(axes: Axes) {\r\n const value = this._axes[axes];\r\n\r\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) {\r\n return 0;\r\n } else {\r\n return value;\r\n }\r\n }\r\n\r\n public updateButton(buttonIndex: number, value: number) {\r\n // button was just released\r\n if (value === 0 && this._buttons[buttonIndex]) {\r\n this._buttonsUp[buttonIndex] = 1;\r\n\r\n // button was just pressed\r\n } else {\r\n this._buttonsDown[buttonIndex] = value;\r\n }\r\n\r\n this._buttons[buttonIndex] = value;\r\n }\r\n\r\n public updateAxes(axesIndex: number, value: number) {\r\n this._axes[axesIndex] = value;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: GamepadEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad Buttons enumeration\r\n */\r\nexport enum Buttons {\r\n /**\r\n * Face 1 button (e.g. A)\r\n */\r\n Face1 = 0,\r\n /**\r\n * Face 2 button (e.g. B)\r\n */\r\n Face2 = 1,\r\n /**\r\n * Face 3 button (e.g. X)\r\n */\r\n Face3 = 2,\r\n /**\r\n * Face 4 button (e.g. Y)\r\n */\r\n Face4 = 3,\r\n /**\r\n * Left bumper button\r\n */\r\n LeftBumper = 4,\r\n /**\r\n * Right bumper button\r\n */\r\n RightBumper = 5,\r\n /**\r\n * Left trigger button\r\n */\r\n LeftTrigger = 6,\r\n /**\r\n * Right trigger button\r\n */\r\n RightTrigger = 7,\r\n /**\r\n * Select button\r\n */\r\n Select = 8,\r\n /**\r\n * Start button\r\n */\r\n Start = 9,\r\n /**\r\n * Left analog stick press (e.g. L3)\r\n */\r\n LeftStick = 10,\r\n /**\r\n * Right analog stick press (e.g. R3)\r\n */\r\n RightStick = 11,\r\n /**\r\n * D-pad up\r\n */\r\n DpadUp = 12,\r\n /**\r\n * D-pad down\r\n */\r\n DpadDown = 13,\r\n /**\r\n * D-pad left\r\n */\r\n DpadLeft = 14,\r\n /**\r\n * D-pad right\r\n */\r\n DpadRight = 15\r\n}\r\n\r\n/**\r\n * Gamepad Axes enumeration\r\n */\r\nexport enum Axes {\r\n /**\r\n * Left analogue stick X direction\r\n */\r\n LeftStickX = 0,\r\n /**\r\n * Left analogue stick Y direction\r\n */\r\n LeftStickY = 1,\r\n /**\r\n * Right analogue stick X direction\r\n */\r\n RightStickX = 2,\r\n /**\r\n * Right analogue stick Y direction\r\n */\r\n RightStickY = 3\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepads {\r\n getGamepads(): NavigatorGamepad[];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepad {\r\n axes: number[];\r\n buttons: NavigatorGamepadButton[];\r\n connected: boolean;\r\n id: string;\r\n index: number;\r\n mapping: string;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepadButton {\r\n pressed: boolean;\r\n value: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepadEvent {\r\n gamepad: NavigatorGamepad;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface GamepadConfiguration {\r\n axis: number;\r\n buttons: number;\r\n}\r\n","import { Gamepads } from './Gamepad';\r\nimport { Keyboard } from './Keyboard';\r\nimport { PointerEventReceiver } from './PointerEventReceiver';\r\n\r\nexport interface InputsOptions {\r\n keyboard: Keyboard;\r\n gamepads: Gamepads;\r\n pointers: PointerEventReceiver;\r\n}\r\n\r\n/**\r\n * This allows you to map multiple inputs to specific commands! This is especially useful when\r\n * you need to allow multiple input sources to control a specific action.\r\n */\r\nexport class InputMapper {\r\n\r\n private _handlers = new Map();\r\n constructor(public inputs: InputsOptions) {}\r\n\r\n /**\r\n * Executes the input map, called internally by Excalibur\r\n */\r\n execute() {\r\n for (const [input, command] of this._handlers.entries()) {\r\n const results = input(this.inputs);\r\n if (results) {\r\n command(results);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * This allows you to map multiple inputs to specific commands! This is useful\r\n *\r\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\r\n *\r\n * Example:\r\n * ```typescript\r\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\r\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\r\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\r\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\r\n *\r\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\r\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\r\n * ```\r\n * @param inputHandler\r\n * @param commandHandler\r\n */\r\n on(\r\n inputHandler: (inputs: InputsOptions) => TInputHandlerData | false,\r\n commandHandler: (data: TInputHandlerData) => any) {\r\n this._handlers.set(inputHandler, commandHandler);\r\n }\r\n}","\r\n\r\n/**\r\n * Checks if excalibur is in a x-origin iframe\r\n */\r\nexport function isCrossOriginIframe() {\r\n try {\r\n // Try and listen to events on top window frame if within an iframe.\r\n //\r\n // See https://github.com/excaliburjs/Excalibur/issues/1294\r\n //\r\n // Attempt to add an event listener, which triggers a DOMException on\r\n // cross-origin iframes\r\n const noop = () => {\r\n return;\r\n };\r\n window.top.addEventListener('blur', noop);\r\n window.top.removeEventListener('blur', noop);\r\n } catch {\r\n return true;\r\n }\r\n return false;\r\n}","import { Logger } from '../Util/Log';\r\nimport * as Events from '../Events';\r\nimport { isCrossOriginIframe } from '../Util/IFrame';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\n/**\r\n * Enum representing physical input key codes\r\n */\r\nexport enum Keys {\r\n // NUMPAD\r\n Num0 = 'Numpad0',\r\n Num1 = 'Numpad1',\r\n Num2 = 'Numpad2',\r\n Num3 = 'Numpad3',\r\n Num4 = 'Numpad4',\r\n Num5 = 'Numpad5',\r\n Num6 = 'Numpad6',\r\n Num7 = 'Numpad7',\r\n Num8 = 'Numpad8',\r\n Num9 = 'Numpad9',\r\n NumAdd = 'NumpadAdd',\r\n NumSubtract = 'NumpadSubtract',\r\n NumMultiply = 'NumpadMultiply',\r\n NumDivide = 'NumpadDivide',\r\n // NumComma = 'NumpadComma', // not x-browser\r\n NumDecimal = 'NumpadDecimal',\r\n Numpad0 = 'Numpad0',\r\n Numpad1 = 'Numpad1',\r\n Numpad2 = 'Numpad2',\r\n Numpad3 = 'Numpad3',\r\n Numpad4 = 'Numpad4',\r\n Numpad5 = 'Numpad5',\r\n Numpad6 = 'Numpad6',\r\n Numpad7 = 'Numpad7',\r\n Numpad8 = 'Numpad8',\r\n Numpad9 = 'Numpad9',\r\n NumpadAdd = 'NumpadAdd',\r\n NumpadSubtract = 'NumpadSubtract',\r\n NumpadMultiply = 'NumpadMultiply',\r\n NumpadDivide = 'NumpadDivide',\r\n // NumpadComma = 'NumpadComma', // not x-browser\r\n NumpadDecimal = 'NumpadDecimal',\r\n\r\n // MODIFIERS\r\n NumLock = 'NumLock',\r\n ShiftLeft = 'ShiftLeft',\r\n ShiftRight = 'ShiftRight',\r\n AltLeft = 'AltLeft',\r\n AltRight = 'AltRight',\r\n ControlLeft = 'ControlLeft',\r\n ControlRight = 'ControlRight',\r\n MetaLeft = 'MetaLeft',\r\n MetaRight = 'MetaRight',\r\n\r\n // NUMBERS\r\n Key0 = 'Digit0',\r\n Key1 = 'Digit1',\r\n Key2 = 'Digit2',\r\n Key3 = 'Digit3',\r\n Key4 = 'Digit4',\r\n Key5 = 'Digit5',\r\n Key6 = 'Digit6',\r\n Key7 = 'Digit7',\r\n Key8 = 'Digit8',\r\n Key9 = 'Digit9',\r\n Digit0 = 'Digit0',\r\n Digit1 = 'Digit1',\r\n Digit2 = 'Digit2',\r\n Digit3 = 'Digit3',\r\n Digit4 = 'Digit4',\r\n Digit5 = 'Digit5',\r\n Digit6 = 'Digit6',\r\n Digit7 = 'Digit7',\r\n Digit8 = 'Digit8',\r\n Digit9 = 'Digit9',\r\n\r\n // FUNCTION KEYS\r\n F1 = 'F1',\r\n F2 = 'F2',\r\n F3 = 'F3',\r\n F4 = 'F4',\r\n F5 = 'F5',\r\n F6 = 'F6',\r\n F7 = 'F7',\r\n F8 = 'F8',\r\n F9 = 'F9',\r\n F10 = 'F10',\r\n F11 = 'F11',\r\n F12 = 'F12',\r\n\r\n // LETTERS\r\n A = 'KeyA',\r\n B = 'KeyB',\r\n C = 'KeyC',\r\n D = 'KeyD',\r\n E = 'KeyE',\r\n F = 'KeyF',\r\n G = 'KeyG',\r\n H = 'KeyH',\r\n I = 'KeyI',\r\n J = 'KeyJ',\r\n K = 'KeyK',\r\n L = 'KeyL',\r\n M = 'KeyM',\r\n N = 'KeyN',\r\n O = 'KeyO',\r\n P = 'KeyP',\r\n Q = 'KeyQ',\r\n R = 'KeyR',\r\n S = 'KeyS',\r\n T = 'KeyT',\r\n U = 'KeyU',\r\n V = 'KeyV',\r\n W = 'KeyW',\r\n X = 'KeyX',\r\n Y = 'KeyY',\r\n Z = 'KeyZ',\r\n KeyA = 'KeyA',\r\n KeyB = 'KeyB',\r\n KeyC = 'KeyC',\r\n KeyD = 'KeyD',\r\n KeyE = 'KeyE',\r\n KeyF = 'KeyF',\r\n KeyG = 'KeyG',\r\n KeyH = 'KeyH',\r\n KeyI = 'KeyI',\r\n KeyJ = 'KeyJ',\r\n KeyK = 'KeyK',\r\n KeyL = 'KeyL',\r\n KeyM = 'KeyM',\r\n KeyN = 'KeyN',\r\n KeyO = 'KeyO',\r\n KeyP = 'KeyP',\r\n KeyQ = 'KeyQ',\r\n KeyR = 'KeyR',\r\n KeyS = 'KeyS',\r\n KeyT = 'KeyT',\r\n KeyU = 'KeyU',\r\n KeyV = 'KeyV',\r\n KeyW = 'KeyW',\r\n KeyX = 'KeyX',\r\n KeyY = 'KeyY',\r\n KeyZ = 'KeyZ',\r\n\r\n // SYMBOLS\r\n Semicolon = 'Semicolon',\r\n Quote = 'Quote',\r\n Comma = 'Comma',\r\n Minus = 'Minus',\r\n Period = 'Period',\r\n Slash = 'Slash',\r\n Equal = 'Equal',\r\n BracketLeft = 'BracketLeft',\r\n Backslash = 'Backslash',\r\n BracketRight = 'BracketRight',\r\n Backquote = 'Backquote',\r\n\r\n // DIRECTIONS\r\n Up = 'ArrowUp',\r\n Down = 'ArrowDown',\r\n Left = 'ArrowLeft',\r\n Right = 'ArrowRight',\r\n ArrowUp = 'ArrowUp',\r\n ArrowDown = 'ArrowDown',\r\n ArrowLeft = 'ArrowLeft',\r\n ArrowRight = 'ArrowRight',\r\n\r\n // OTHER\r\n Space = 'Space',\r\n Backspace = 'Backspace',\r\n Delete = 'Delete',\r\n Esc = 'Escape',\r\n Escape = 'Escape',\r\n Enter = 'Enter',\r\n NumpadEnter = 'NumpadEnter',\r\n ContextMenu = 'ContextMenu'\r\n}\r\n\r\n/**\r\n * Event thrown on a game object for a key event\r\n */\r\nexport class KeyEvent extends Events.GameEvent {\r\n /**\r\n * @param key The key responsible for throwing the event\r\n * @param value The key's typed value the browser detected\r\n * @param originalEvent The original keyboard event that Excalibur handled\r\n */\r\n constructor(public key: Keys, public value?: string, public originalEvent?: KeyboardEvent) {\r\n super();\r\n }\r\n}\r\n\r\nexport interface KeyboardInitOptions {\r\n global?: GlobalEventHandlers,\r\n grabWindowFocus?: boolean\r\n}\r\n\r\nexport type KeyEvents = {\r\n press: KeyEvent,\r\n hold: KeyEvent,\r\n release: KeyEvent\r\n};\r\n\r\nexport const KeyEvents = {\r\n Press: 'press',\r\n Hold: 'hold',\r\n Release: 'release'\r\n};\r\n\r\n/**\r\n * Provides keyboard support for Excalibur.\r\n */\r\nexport class Keyboard {\r\n public events = new EventEmitter();\r\n private _enabled = true;\r\n /**\r\n * Keys that are currently held down\r\n */\r\n private _keys: Keys[] = [];\r\n /**\r\n * Keys up in the current frame\r\n */\r\n private _keysUp: Keys[] = [];\r\n /**\r\n * Keys down in the current frame\r\n */\r\n private _keysDown: Keys[] = [];\r\n\r\n public emit>(eventName: TEventName, event: KeyEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Initialize Keyboard event listeners\r\n */\r\n init(keyboardOptions?: KeyboardInitOptions): void {\r\n let { global } = keyboardOptions;\r\n const { grabWindowFocus } = keyboardOptions;\r\n if (!global) {\r\n if (isCrossOriginIframe()) {\r\n global = window;\r\n // Workaround for iframes like for itch.io or codesandbox\r\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\r\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\r\n if (grabWindowFocus) {\r\n window.focus();\r\n }\r\n\r\n Logger.getInstance().warn('Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus');\r\n } else {\r\n global = window.top;\r\n }\r\n }\r\n\r\n global.addEventListener('blur', () => {\r\n this._keys.length = 0; // empties array efficiently\r\n });\r\n\r\n // key up is on window because canvas cannot have focus\r\n global.addEventListener('keyup', this._handleKeyUp);\r\n\r\n // key down is on window because canvas cannot have focus\r\n global.addEventListener('keydown', this._handleKeyDown);\r\n }\r\n\r\n toggleEnabled(enabled: boolean) {\r\n this._enabled = enabled;\r\n }\r\n\r\n private _releaseAllKeys = (ev: KeyboardEvent) => {\r\n for (const code of this._keys) {\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n this.events.emit('up', keyEvent);\r\n this.events.emit('release', keyEvent);\r\n }\r\n this._keysUp = Array.from((new Set(this._keys.concat(this._keysUp))));\r\n this._keys.length = 0;\r\n };\r\n\r\n private _handleKeyDown = (ev: KeyboardEvent) => {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n\r\n // handle macos meta key issue\r\n // https://github.com/excaliburjs/Excalibur/issues/2608\r\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) {\r\n this._releaseAllKeys(ev);\r\n }\r\n\r\n const code = ev.code as Keys;\r\n if (this._keys.indexOf(code) === -1) {\r\n this._keys.push(code);\r\n this._keysDown.push(code);\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n this.events.emit('down', keyEvent);\r\n this.events.emit('press', keyEvent);\r\n }\r\n };\r\n\r\n private _handleKeyUp = (ev: KeyboardEvent) => {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n const code = ev.code as Keys;\r\n const key = this._keys.indexOf(code);\r\n this._keys.splice(key, 1);\r\n this._keysUp.push(code);\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n\r\n // alias the old api, we may want to deprecate this in the future\r\n this.events.emit('up', keyEvent);\r\n this.events.emit('release', keyEvent);\r\n\r\n // handle macos meta key issue\r\n // https://github.com/excaliburjs/Excalibur/issues/2608\r\n if (ev.key === 'Meta') {\r\n this._releaseAllKeys(ev);\r\n }\r\n };\r\n\r\n public update() {\r\n // Reset keysDown and keysUp after update is complete\r\n this._keysDown.length = 0;\r\n this._keysUp.length = 0;\r\n\r\n // Emit synthetic \"hold\" event\r\n for (let i = 0; i < this._keys.length; i++) {\r\n this.events.emit('hold', new KeyEvent(this._keys[i]));\r\n }\r\n }\r\n\r\n /**\r\n * Gets list of keys being pressed down\r\n */\r\n public getKeys(): Keys[] {\r\n return this._keys;\r\n }\r\n\r\n /**\r\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just pressed\r\n */\r\n public wasPressed(key: Keys): boolean {\r\n return this._keysDown.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Tests if a certain key is held down. This is persisted between frames.\r\n * @param key Test whether a key is held down\r\n */\r\n public isHeld(key: Keys): boolean {\r\n return this._keys.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just released\r\n */\r\n public wasReleased(key: Keys): boolean {\r\n return this._keysUp.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Trigger a manual key event\r\n * @param type\r\n * @param key\r\n * @param character\r\n */\r\n public triggerEvent(type: 'down' | 'up', key: Keys, character?: string) {\r\n if (type === 'down') {\r\n this._handleKeyDown(new KeyboardEvent('keydown', {\r\n code: key,\r\n key: character ?? null\r\n }));\r\n }\r\n if (type === 'up') {\r\n this._handleKeyUp(new KeyboardEvent('keyup', {\r\n code: key,\r\n key: character ?? null\r\n }));\r\n }\r\n }\r\n}\r\n","import { Engine } from '../Engine';\r\nimport { Vector } from './vector';\r\n\r\nexport class GlobalCoordinates {\r\n public static fromPagePosition(x: number, y: number, engine: Engine): GlobalCoordinates;\r\n public static fromPagePosition(pos: Vector, engine: Engine): GlobalCoordinates;\r\n public static fromPagePosition(xOrPos: number | Vector, yOrEngine: number | Engine, engineOrUndefined?: Engine): GlobalCoordinates {\r\n let pageX: number;\r\n let pageY: number;\r\n let pagePos: Vector;\r\n let engine: Engine;\r\n\r\n if (arguments.length === 3) {\r\n pageX = xOrPos;\r\n pageY = yOrEngine;\r\n pagePos = new Vector(pageX, pageY);\r\n engine = engineOrUndefined;\r\n } else {\r\n pagePos = xOrPos;\r\n pageX = pagePos.x;\r\n pageY = pagePos.y;\r\n engine = yOrEngine;\r\n }\r\n\r\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\r\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\r\n\r\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\r\n }\r\n\r\n constructor(public worldPos: Vector, public pagePos: Vector, public screenPos: Vector) {}\r\n}\r\n","import { GlobalCoordinates } from '../Math/global-coordinates';\r\nimport { Vector } from '../Math/vector';\r\nimport { PointerButton } from './PointerButton';\r\nimport { PointerType } from './PointerType';\r\n\r\nexport class PointerEvent {\r\n public active = true;\r\n public cancel() {\r\n this.active = false;\r\n }\r\n\r\n get pagePos(): Vector {\r\n return this.coordinates.pagePos;\r\n }\r\n\r\n get screenPos(): Vector {\r\n return this.coordinates.screenPos;\r\n }\r\n\r\n get worldPos(): Vector {\r\n return this.coordinates.worldPos;\r\n }\r\n\r\n constructor(\r\n public type: 'down' | 'up' | 'move' | 'cancel',\r\n public pointerId: number,\r\n public button: PointerButton,\r\n public pointerType: PointerType,\r\n public coordinates: GlobalCoordinates,\r\n public nativeEvent: Event) { };\r\n}\r\n","import { WheelDeltaMode } from './WheelDeltaMode';\r\n\r\n\r\nexport class WheelEvent {\r\n public active = true;\r\n public cancel() {\r\n this.active = false;\r\n }\r\n constructor(\r\n public x: number,\r\n public y: number,\r\n public pageX: number,\r\n public pageY: number,\r\n public screenX: number,\r\n public screenY: number,\r\n public index: number,\r\n public deltaX: number,\r\n public deltaY: number,\r\n public deltaZ: number,\r\n public deltaMode: WheelDeltaMode,\r\n public ev: Event\r\n ) { }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { PointerEvents } from './PointerEventReceiver';\r\n\r\nexport class PointerAbstraction {\r\n public events = new EventEmitter();\r\n /**\r\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastPagePos: Vector = Vector.Zero;\r\n\r\n /**\r\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastScreenPos: Vector = Vector.Zero;\r\n\r\n /**\r\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastWorldPos: Vector = Vector.Zero;\r\n\r\n constructor() {\r\n this.on('move', this._onPointerMove);\r\n this.on('down', this._onPointerDown);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: PointerEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n private _onPointerMove = (ev: PointerEvent): void => {\r\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\r\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\r\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\r\n };\r\n\r\n private _onPointerDown = (ev: PointerEvent): void => {\r\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\r\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\r\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\r\n };\r\n}\r\n","\r\nexport enum WheelDeltaMode {\r\n Pixel = 'Pixel',\r\n Line = 'Line',\r\n Page = 'Page'\r\n}\r\n","/**\r\n * Native browser button enumeration\r\n */\r\nexport enum NativePointerButton {\r\n NoButton = -1,\r\n Left = 0,\r\n Middle = 1,\r\n Right = 2,\r\n Unknown = 3\r\n}\r\n","/**\r\n * The mouse button being pressed.\r\n */\r\nexport enum PointerButton {\r\n Left = 'Left',\r\n Middle = 'Middle',\r\n Right = 'Right',\r\n Unknown = 'Unknown',\r\n NoButton = 'NoButton'\r\n}\r\n","/**\r\n * The type of pointer for a [[PointerEvent]].\r\n */\r\nexport enum PointerType {\r\n Touch = 'Touch',\r\n Mouse = 'Mouse',\r\n Pen = 'Pen',\r\n Unknown = 'Unknown'\r\n}\r\n","import { Engine, ScrollPreventionMode } from '../Engine';\r\nimport { GlobalCoordinates } from '../Math/global-coordinates';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { WheelEvent } from './WheelEvent';\r\nimport { PointerAbstraction } from './PointerAbstraction';\r\n\r\nimport { WheelDeltaMode } from './WheelDeltaMode';\r\nimport { PointerSystem } from './PointerSystem';\r\nimport { NativePointerButton } from './NativePointerButton';\r\nimport { PointerButton } from './PointerButton';\r\nimport { fail } from '../Util/Util';\r\nimport { PointerType } from './PointerType';\r\nimport { isCrossOriginIframe } from '../Util/IFrame';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\n\r\nexport type NativePointerEvent = globalThis.PointerEvent;\r\nexport type NativeMouseEvent = globalThis.MouseEvent;\r\nexport type NativeTouchEvent = globalThis.TouchEvent;\r\nexport type NativeWheelEvent = globalThis.WheelEvent;\r\n\r\nexport type PointerEvents = {\r\n move: PointerEvent,\r\n down: PointerEvent,\r\n up: PointerEvent,\r\n wheel: WheelEvent\r\n}\r\n\r\nexport const PointerEvents = {\r\n Move: 'move',\r\n Down: 'down',\r\n Up: 'up',\r\n Wheel: 'wheel'\r\n};\r\n\r\n/**\r\n * Is this event a native touch event?\r\n */\r\nfunction isTouchEvent(value: any): value is NativeTouchEvent {\r\n // Guard for Safari <= 13.1\r\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\r\n}\r\n\r\n/**\r\n * Is this event a native pointer event\r\n */\r\nfunction isPointerEvent(value: any): value is NativePointerEvent {\r\n // Guard for Safari <= 13.1\r\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\r\n}\r\n\r\nexport interface PointerInitOptions {\r\n grabWindowFocus?: boolean;\r\n}\r\n\r\n/**\r\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\r\n */\r\nexport class PointerEventReceiver {\r\n public events = new EventEmitter();\r\n public primary: PointerAbstraction = new PointerAbstraction();\r\n\r\n private _activeNativePointerIdsToNormalized = new Map();\r\n public lastFramePointerCoords = new Map();\r\n public currentFramePointerCoords = new Map();\r\n\r\n public currentFramePointerDown = new Map();\r\n public lastFramePointerDown = new Map();\r\n\r\n public currentFrameDown: PointerEvent[] = [];\r\n public currentFrameUp: PointerEvent[] = [];\r\n public currentFrameMove: PointerEvent[] = [];\r\n public currentFrameCancel: PointerEvent[] = [];\r\n public currentFrameWheel: WheelEvent[] = [];\r\n\r\n private _enabled = true;\r\n\r\n constructor(public readonly target: GlobalEventHandlers & EventTarget, public engine: Engine) {}\r\n\r\n public toggleEnabled(enabled: boolean) {\r\n this._enabled = enabled;\r\n }\r\n\r\n /**\r\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\r\n * handlers.\r\n * @param target\r\n * @param engine\r\n */\r\n public recreate(target: GlobalEventHandlers & EventTarget, engine: Engine) {\r\n const eventReceiver = new PointerEventReceiver(target, engine);\r\n eventReceiver.primary = this.primary;\r\n eventReceiver._pointers = this._pointers;\r\n return eventReceiver;\r\n }\r\n\r\n private _pointers: PointerAbstraction[] = [this.primary];\r\n /**\r\n * Locates a specific pointer by id, creates it if it doesn't exist\r\n * @param index\r\n */\r\n public at(index: number): PointerAbstraction {\r\n if (index >= this._pointers.length) {\r\n // Ensure there is a pointer to retrieve\r\n for (let i = this._pointers.length - 1, max = index; i < max; i++) {\r\n this._pointers.push(new PointerAbstraction());\r\n }\r\n }\r\n return this._pointers[index];\r\n }\r\n\r\n /**\r\n * The number of pointers currently being tracked by excalibur\r\n */\r\n public count(): number {\r\n return this._pointers.length;\r\n }\r\n\r\n /**\r\n * Is the specified pointer id down this frame\r\n * @param pointerId\r\n */\r\n public isDown(pointerId: number) {\r\n return this.currentFramePointerDown.get(pointerId) ?? false;\r\n }\r\n\r\n /**\r\n * Was the specified pointer id down last frame\r\n * @param pointerId\r\n */\r\n public wasDown(pointerId: number) {\r\n return this.lastFramePointerDown.get(pointerId) ?? false;\r\n }\r\n\r\n /**\r\n * Whether the Pointer is currently dragging.\r\n */\r\n public isDragging(pointerId: number): boolean {\r\n return this.isDown(pointerId);\r\n }\r\n\r\n /**\r\n * Whether the Pointer just started dragging.\r\n */\r\n public isDragStart(pointerId: number): boolean {\r\n return this.isDown(pointerId) && !this.wasDown(pointerId);\r\n }\r\n\r\n /**\r\n * Whether the Pointer just ended dragging.\r\n */\r\n public isDragEnd(pointerId: number): boolean {\r\n return !this.isDown(pointerId) && this.wasDown(pointerId);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: PointerEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Called internally by excalibur\r\n *\r\n * Updates the current frame pointer info and emits raw pointer events\r\n *\r\n * This does not emit events to entities, see PointerSystem\r\n */\r\n public update() {\r\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\r\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\r\n\r\n for (const event of this.currentFrameDown) {\r\n this.emit('down', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('down', event);\r\n this.primary.emit('pointerdown', event);\r\n }\r\n\r\n for (const event of this.currentFrameUp) {\r\n this.emit('up', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('up', event);\r\n }\r\n\r\n for (const event of this.currentFrameMove) {\r\n this.emit('move', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('move', event);\r\n }\r\n\r\n for (const event of this.currentFrameCancel) {\r\n this.emit('cancel', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('cancel', event);\r\n }\r\n\r\n for (const event of this.currentFrameWheel) {\r\n this.emit('wheel', event);\r\n this.primary.emit('pointerwheel', event);\r\n this.primary.emit('wheel', event);\r\n }\r\n }\r\n\r\n /**\r\n * Clears the current frame event and pointer data\r\n */\r\n public clear() {\r\n for (const event of this.currentFrameUp) {\r\n this.currentFramePointerCoords.delete(event.pointerId);\r\n const ids = this._activeNativePointerIdsToNormalized.entries();\r\n for (const [native, normalized] of ids) {\r\n if (normalized === event.pointerId) {\r\n this._activeNativePointerIdsToNormalized.delete(native);\r\n }\r\n }\r\n }\r\n this.currentFrameDown.length = 0;\r\n this.currentFrameUp.length = 0;\r\n this.currentFrameMove.length = 0;\r\n this.currentFrameCancel.length = 0;\r\n this.currentFrameWheel.length = 0;\r\n }\r\n\r\n private _boundHandle = this._handle.bind(this);\r\n private _boundWheel = this._handleWheel.bind(this);\r\n /**\r\n * Initializes the pointer event receiver so that it can start listening to native\r\n * browser events.\r\n */\r\n public init(options?: PointerInitOptions) {\r\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\r\n // It is important on mobile to have touch action 'none'\r\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\r\n if (this.target === this.engine.canvas) {\r\n this.engine.canvas.style.touchAction = 'none';\r\n } else {\r\n document.body.style.touchAction = 'none';\r\n }\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.addEventListener('pointerdown', this._boundHandle);\r\n this.target.addEventListener('pointerup', this._boundHandle);\r\n this.target.addEventListener('pointermove', this._boundHandle);\r\n this.target.addEventListener('pointercancel', this._boundHandle);\r\n } else {\r\n // Touch Events\r\n this.target.addEventListener('touchstart', this._boundHandle);\r\n this.target.addEventListener('touchend', this._boundHandle);\r\n this.target.addEventListener('touchmove', this._boundHandle);\r\n this.target.addEventListener('touchcancel', this._boundHandle);\r\n\r\n // Mouse Events\r\n this.target.addEventListener('mousedown', this._boundHandle);\r\n this.target.addEventListener('mouseup', this._boundHandle);\r\n this.target.addEventListener('mousemove', this._boundHandle);\r\n }\r\n\r\n // MDN MouseWheelEvent\r\n const wheelOptions = {\r\n passive: !(\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas\r\n )\r\n };\r\n if ('onwheel' in document.createElement('div')) {\r\n // Modern Browsers\r\n this.target.addEventListener('wheel', this._boundWheel, wheelOptions);\r\n } else if (document.onmousewheel !== undefined) {\r\n // Webkit and IE\r\n this.target.addEventListener('mousewheel', this._boundWheel, wheelOptions);\r\n } else {\r\n // Remaining browser and older Firefox\r\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel, wheelOptions);\r\n }\r\n\r\n const grabWindowFocus = options?.grabWindowFocus ?? true;\r\n // Handle cross origin iframe\r\n if (grabWindowFocus && isCrossOriginIframe()) {\r\n const grabFocus = () => {\r\n window.focus();\r\n };\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.addEventListener('pointerdown', grabFocus);\r\n } else {\r\n // Touch Events\r\n this.target.addEventListener('touchstart', grabFocus);\r\n\r\n // Mouse Events\r\n this.target.addEventListener('mousedown', grabFocus);\r\n }\r\n }\r\n }\r\n\r\n public detach() {\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.removeEventListener('pointerdown', this._boundHandle);\r\n this.target.removeEventListener('pointerup', this._boundHandle);\r\n this.target.removeEventListener('pointermove', this._boundHandle);\r\n this.target.removeEventListener('pointercancel', this._boundHandle);\r\n } else {\r\n // Touch Events\r\n this.target.removeEventListener('touchstart', this._boundHandle);\r\n this.target.removeEventListener('touchend', this._boundHandle);\r\n this.target.removeEventListener('touchmove', this._boundHandle);\r\n this.target.removeEventListener('touchcancel', this._boundHandle);\r\n\r\n // Mouse Events\r\n this.target.removeEventListener('mousedown', this._boundHandle);\r\n this.target.removeEventListener('mouseup', this._boundHandle);\r\n this.target.removeEventListener('mousemove', this._boundHandle);\r\n }\r\n\r\n if ('onwheel' in document.createElement('div')) {\r\n // Modern Browsers\r\n this.target.removeEventListener('wheel', this._boundWheel);\r\n } else if (document.onmousewheel !== undefined) {\r\n // Webkit and IE\r\n this.target.addEventListener('mousewheel', this._boundWheel);\r\n } else {\r\n // Remaining browser and older Firefox\r\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel);\r\n }\r\n }\r\n\r\n /**\r\n * Take native pointer id and map it to index in active pointers\r\n * @param nativePointerId\r\n */\r\n private _normalizePointerId(nativePointerId: number) {\r\n // Add to the the native pointer set id\r\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\r\n\r\n // Native pointer ids in ascending order\r\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b) => a - b);\r\n\r\n // The index into sorted ids will be the new id, will always have an id\r\n const id = currentPointerIds.findIndex(p => p === nativePointerId);\r\n\r\n // Save the mapping so we can reverse it later\r\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\r\n\r\n // ignore pointer because game isn't watching\r\n return id;\r\n }\r\n\r\n /**\r\n * Responsible for handling and parsing pointer events\r\n */\r\n private _handle(ev: NativeTouchEvent | NativePointerEvent | NativeMouseEvent) {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n ev.preventDefault();\r\n const eventCoords = new Map();\r\n let button: PointerButton;\r\n let pointerType: PointerType;\r\n if (isTouchEvent(ev)) {\r\n button = PointerButton.Unknown;\r\n pointerType = PointerType.Touch;\r\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\r\n for (let i = 0; i < ev.changedTouches.length; i++) {\r\n const touch = ev.changedTouches[i];\r\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\r\n const nativePointerId = i + 1;\r\n const pointerId = this._normalizePointerId(nativePointerId);\r\n this.currentFramePointerCoords.set(pointerId, coordinates);\r\n eventCoords.set(pointerId, coordinates);\r\n }\r\n } else {\r\n button = this._nativeButtonToPointerButton(ev.button);\r\n pointerType = PointerType.Mouse;\r\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\r\n let nativePointerId = 1;\r\n if (isPointerEvent(ev)) {\r\n nativePointerId = ev.pointerId;\r\n pointerType = this._stringToPointerType(ev.pointerType);\r\n }\r\n const pointerId = this._normalizePointerId(nativePointerId);\r\n this.currentFramePointerCoords.set(pointerId, coordinates);\r\n eventCoords.set(pointerId, coordinates);\r\n }\r\n\r\n for (const [pointerId, coord] of eventCoords.entries()) {\r\n switch (ev.type) {\r\n case 'mousedown':\r\n case 'pointerdown':\r\n case 'touchstart':\r\n this.currentFrameDown.push(new PointerEvent('down', pointerId, button, pointerType, coord, ev));\r\n this.currentFramePointerDown.set(pointerId, true);\r\n break;\r\n case 'mouseup':\r\n case 'pointerup':\r\n case 'touchend':\r\n this.currentFrameUp.push(new PointerEvent('up', pointerId, button, pointerType, coord, ev));\r\n this.currentFramePointerDown.set(pointerId, false);\r\n break;\r\n case 'mousemove':\r\n case 'pointermove':\r\n case 'touchmove':\r\n this.currentFrameMove.push(new PointerEvent('move', pointerId, button, pointerType, coord, ev));\r\n break;\r\n case 'touchcancel':\r\n case 'pointercancel':\r\n this.currentFrameCancel.push(new PointerEvent('cancel', pointerId, button, pointerType, coord, ev));\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private _handleWheel(ev: NativeWheelEvent) {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n // Should we prevent page scroll because of this event\r\n if (\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\r\n (this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas)\r\n ) {\r\n ev.preventDefault();\r\n }\r\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\r\n const world = this.engine.screen.screenToWorldCoordinates(screen);\r\n\r\n /**\r\n * A constant used to normalize wheel events across different browsers\r\n *\r\n * This normalization factor is pulled from\r\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\r\n */\r\n const ScrollWheelNormalizationFactor = -1 / 40;\r\n\r\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\r\n const deltaY =\r\n ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\r\n const deltaZ = ev.deltaZ || 0;\r\n let deltaMode = WheelDeltaMode.Pixel;\r\n\r\n if (ev.deltaMode) {\r\n if (ev.deltaMode === 1) {\r\n deltaMode = WheelDeltaMode.Line;\r\n } else if (ev.deltaMode === 2) {\r\n deltaMode = WheelDeltaMode.Page;\r\n }\r\n }\r\n\r\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\r\n this.currentFrameWheel.push(we);\r\n }\r\n\r\n /**\r\n * Triggers an excalibur pointer event in a world space pos\r\n *\r\n * Useful for testing pointers in excalibur\r\n * @param type\r\n * @param pos\r\n */\r\n public triggerEvent(type: 'down' | 'up' | 'move' | 'cancel', pos: Vector) {\r\n const page = this.engine.screen.worldToPageCoordinates(pos);\r\n // Send an event to the event receiver\r\n if (window.PointerEvent) {\r\n this._handle(new window.PointerEvent('pointer' + type, {\r\n pointerId: 0,\r\n clientX: page.x,\r\n clientY: page.y\r\n }));\r\n } else {\r\n // Safari hack\r\n this._handle(new window.MouseEvent('mouse' + type, {\r\n clientX: page.x,\r\n clientY: page.y\r\n }));\r\n }\r\n\r\n // Force update pointer system\r\n const pointerSystem = this.engine.currentScene.world.get(PointerSystem);\r\n pointerSystem.preupdate(this.engine.currentScene, 1);\r\n pointerSystem.update(1);\r\n }\r\n\r\n private _nativeButtonToPointerButton(s: NativePointerButton): PointerButton {\r\n switch (s) {\r\n case NativePointerButton.NoButton:\r\n return PointerButton.NoButton;\r\n case NativePointerButton.Left:\r\n return PointerButton.Left;\r\n case NativePointerButton.Middle:\r\n return PointerButton.Middle;\r\n case NativePointerButton.Right:\r\n return PointerButton.Right;\r\n case NativePointerButton.Unknown:\r\n return PointerButton.Unknown;\r\n default:\r\n return fail(s);\r\n }\r\n }\r\n\r\n private _stringToPointerType(s: string) {\r\n switch (s) {\r\n case 'touch':\r\n return PointerType.Touch;\r\n case 'mouse':\r\n return PointerType.Mouse;\r\n case 'pen':\r\n return PointerType.Pen;\r\n default:\r\n return PointerType.Unknown;\r\n }\r\n }\r\n}","import { Engine } from '../Engine';\r\nimport { Gamepads } from './Gamepad';\r\nimport { InputMapper } from './InputMapper';\r\nimport { Keyboard } from './Keyboard';\r\nimport { PointerEventReceiver } from './PointerEventReceiver';\r\n\r\nexport interface InputHostOptions {\r\n pointerTarget: Document | HTMLCanvasElement\r\n grabWindowFocus: boolean,\r\n engine: Engine\r\n}\r\n\r\nexport class InputHost {\r\n private _enabled = true;\r\n\r\n keyboard: Keyboard;\r\n pointers: PointerEventReceiver;\r\n gamepads: Gamepads;\r\n inputMapper: InputMapper;\r\n\r\n constructor(options: InputHostOptions) {\r\n const { pointerTarget, grabWindowFocus, engine } = options;\r\n this.keyboard = new Keyboard();\r\n this.pointers = new PointerEventReceiver(pointerTarget, engine);\r\n this.gamepads = new Gamepads();\r\n\r\n this.keyboard.init({grabWindowFocus});\r\n this.pointers.init({grabWindowFocus});\r\n this.gamepads.init();\r\n this.inputMapper = new InputMapper({\r\n keyboard: this.keyboard,\r\n pointers: this.pointers,\r\n gamepads: this.gamepads\r\n });\r\n }\r\n\r\n get enabled() {\r\n return this._enabled;\r\n }\r\n\r\n toggleEnabled(enabled: boolean) {\r\n this._enabled = enabled;\r\n this.keyboard.toggleEnabled(this._enabled);\r\n this.pointers.toggleEnabled(this._enabled);\r\n this.gamepads.toggleEnabled(this._enabled);\r\n }\r\n\r\n update() {\r\n if (this._enabled) {\r\n this.inputMapper.execute();\r\n this.keyboard.update();\r\n this.gamepads.update();\r\n }\r\n }\r\n}","import { isScreenElement, ScreenElement } from './ScreenElement';\r\nimport {\r\n InitializeEvent,\r\n ActivateEvent,\r\n DeactivateEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n PreDebugDrawEvent,\r\n PostDebugDrawEvent\r\n} from './Events';\r\nimport { Logger } from './Util/Log';\r\nimport { Timer } from './Timer';\r\nimport { Engine } from './Engine';\r\nimport { TileMap } from './TileMap';\r\nimport { Camera } from './Camera';\r\nimport { Actor } from './Actor';\r\nimport { CanInitialize, CanActivate, CanDeactivate, CanUpdate, CanDraw, SceneActivationContext } from './Interfaces/LifecycleEvents';\r\nimport * as Util from './Util/Util';\r\nimport { Trigger } from './Trigger';\r\nimport { SystemType } from './EntityComponentSystem/System';\r\nimport { World } from './EntityComponentSystem/World';\r\nimport { MotionSystem } from './Collision/MotionSystem';\r\nimport { CollisionSystem } from './Collision/CollisionSystem';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { GraphicsSystem } from './Graphics/GraphicsSystem';\r\nimport { DebugSystem } from './Debug/DebugSystem';\r\nimport { PointerSystem } from './Input/PointerSystem';\r\nimport { ActionsSystem } from './Actions/ActionsSystem';\r\nimport { IsometricEntitySystem } from './TileMap/IsometricEntitySystem';\r\nimport { OffscreenSystem } from './Graphics/OffscreenSystem';\r\nimport { ExcaliburGraphicsContext } from './Graphics';\r\nimport { PhysicsWorld } from './Collision/PhysicsWorld';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { Color } from './Color';\r\nimport { DefaultLoader } from './Director/DefaultLoader';\r\nimport { Transition } from './Director';\r\nimport { InputHost } from './Input/InputHost';\r\nimport { PointerScope } from './Input/PointerScope';\r\nimport { DefaultPhysicsConfig } from './Collision/PhysicsConfig';\r\n\r\nexport class PreLoadEvent {\r\n loader: DefaultLoader;\r\n}\r\n\r\nexport type SceneEvents = {\r\n initialize: InitializeEvent,\r\n activate: ActivateEvent,\r\n deactivate: DeactivateEvent,\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n predraw: PreDrawEvent,\r\n postdraw: PostDrawEvent,\r\n predebugdraw: PreDebugDrawEvent,\r\n postdebugdraw: PostDebugDrawEvent\r\n preload: PreLoadEvent\r\n}\r\n\r\nexport const SceneEvents = {\r\n Initialize: 'initialize',\r\n Activate: 'activate',\r\n Deactivate: 'deactivate',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw',\r\n PreDebugDraw: 'predebugdraw',\r\n PostDebugDraw: 'postdebugdraw',\r\n PreLoad: 'preload'\r\n};\r\n\r\nexport type SceneConstructor = new (...args: any[]) => Scene;\r\n/**\r\n *\r\n */\r\nexport function isSceneConstructor(x: any): x is SceneConstructor {\r\n return !!x?.prototype && !!x?.prototype?.constructor?.name;\r\n}\r\n\r\n/**\r\n * [[Actor|Actors]] are composed together into groupings called Scenes in\r\n * Excalibur. The metaphor models the same idea behind real world\r\n * actors in a scene. Only actors in scenes will be updated and drawn.\r\n *\r\n * Typical usages of a scene include: levels, menus, loading screens, etc.\r\n */\r\nexport class Scene\r\nimplements CanInitialize, CanActivate, CanDeactivate, CanUpdate, CanDraw {\r\n private _logger: Logger = Logger.getInstance();\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Gets or sets the current camera for the scene\r\n */\r\n public camera: Camera = new Camera();\r\n\r\n /**\r\n * Scene specific background color\r\n */\r\n public backgroundColor?: Color;\r\n\r\n /**\r\n * The ECS world for the scene\r\n */\r\n public world: World = new World(this);\r\n\r\n /**\r\n * The Excalibur physics world for the scene. Used to interact\r\n * with colliders included in the scene.\r\n *\r\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\r\n */\r\n public physics = new PhysicsWorld(DefaultPhysicsConfig);\r\n\r\n /**\r\n * The actors in the current scene\r\n */\r\n public get actors(): readonly Actor[] {\r\n return this.world.entityManager.entities.filter((e: Entity) => {\r\n return e instanceof Actor;\r\n }) as Actor[];\r\n }\r\n\r\n /**\r\n * The entities in the current scene\r\n */\r\n public get entities(): readonly Entity[] {\r\n return this.world.entityManager.entities;\r\n }\r\n\r\n /**\r\n * The triggers in the current scene\r\n */\r\n public get triggers(): readonly Trigger[] {\r\n return this.world.entityManager.entities.filter((e: Entity) => {\r\n return e instanceof Trigger;\r\n }) as Trigger[];\r\n }\r\n\r\n /**\r\n * The [[TileMap]]s in the scene, if any\r\n */\r\n public get tileMaps(): readonly TileMap[] {\r\n return this.world.entityManager.entities.filter((e: Entity) => {\r\n return e instanceof TileMap;\r\n }) as TileMap[];\r\n }\r\n\r\n /**\r\n * Access to the Excalibur engine\r\n */\r\n public engine: Engine;\r\n\r\n /**\r\n * Access scene specific input, handlers on this only fire when this scene is active.\r\n */\r\n public input: InputHost;\r\n\r\n private _isInitialized: boolean = false;\r\n private _timers: Timer[] = [];\r\n public get timers(): readonly Timer[] {\r\n return this._timers;\r\n }\r\n private _cancelQueue: Timer[] = [];\r\n\r\n constructor() {\r\n // Initialize systems\r\n\r\n // Update\r\n this.world.add(ActionsSystem);\r\n this.world.add(new MotionSystem(this.world, this.physics));\r\n this.world.add(new CollisionSystem(this.world, this.physics));\r\n this.world.add(PointerSystem);\r\n this.world.add(IsometricEntitySystem);\r\n // Draw\r\n this.world.add(OffscreenSystem);\r\n this.world.add(GraphicsSystem);\r\n this.world.add(DebugSystem);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: SceneEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Event hook to provide Scenes a way of loading scene specific resources.\r\n *\r\n * This is called before the Scene.onInitialize during scene transition. It will only ever fire once for a scene.\r\n * @param loader\r\n */\r\n public onPreLoad(loader: DefaultLoader) {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Event hook fired directly before transition, either \"in\" or \"out\" of the scene\r\n *\r\n * This overrides the Engine scene definition. However transitions specified in goToScene take highest precedence\r\n *\r\n * ```typescript\r\n * // Overrides all\r\n * Engine.goToScene('scene', { destinationIn: ..., sourceOut: ... });\r\n * ```\r\n *\r\n * This can be used to configure custom transitions for a scene dynamically\r\n */\r\n public onTransition(direction: 'in' | 'out'): Transition | undefined {\r\n // will be overridden\r\n return undefined;\r\n }\r\n\r\n /**\r\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n */\r\n public onInitialize(engine: Engine): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * This is called when the scene is made active and started. It is meant to be overridden,\r\n * this is where you should setup any DOM UI or event handlers needed for the scene.\r\n */\r\n public onActivate(context: SceneActivationContext): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\r\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\r\n */\r\n public onDeactivate(context: SceneActivationContext): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */\r\n public onPreUpdate(engine: Engine, delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onPostUpdate(engine: Engine, delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreDraw` is called directly before a scene is drawn.\r\n *\r\n */\r\n public onPreDraw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostDraw` is called directly after a scene is drawn.\r\n *\r\n */\r\n public onPostDraw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Initializes actors in the scene\r\n */\r\n private _initializeChildren() {\r\n for (const child of this.entities) {\r\n child._initialize(this.engine);\r\n }\r\n }\r\n\r\n /**\r\n * Gets whether or not the [[Scene]] has been initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Initializes the scene before the first update, meant to be called by engine not by users of\r\n * Excalibur\r\n * @internal\r\n */\r\n public async _initialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n try {\r\n this.engine = engine;\r\n // PhysicsWorld config is watched so things will automagically update\r\n this.physics.config = this.engine.physics;\r\n this.input = new InputHost({\r\n pointerTarget: engine.pointerScope === PointerScope.Canvas ? engine.canvas : document,\r\n grabWindowFocus: engine.grabWindowFocus,\r\n engine\r\n });\r\n // Initialize camera first\r\n this.camera._initialize(engine);\r\n\r\n this.world.systemManager.initialize();\r\n\r\n // This order is important! we want to be sure any custom init that add actors\r\n // fire before the actor init\r\n await this.onInitialize(engine);\r\n this._initializeChildren();\r\n\r\n this._logger.debug('Scene.onInitialize', this, engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n } catch (e) {\r\n this._logger.error(`Error during scene initialization for scene ${engine.director?.getSceneName(this)}!`);\r\n throw e;\r\n }\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\r\n * @internal\r\n */\r\n public async _activate(context: SceneActivationContext) {\r\n try {\r\n this._logger.debug('Scene.onActivate', this);\r\n this.input.toggleEnabled(true);\r\n await this.onActivate(context);\r\n } catch (e) {\r\n this._logger.error(`Error during scene activation for scene ${this.engine?.director?.getSceneName(this)}!`);\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\r\n * @internal\r\n */\r\n public async _deactivate(context: SceneActivationContext) {\r\n this._logger.debug('Scene.onDeactivate', this);\r\n this.input.toggleEnabled(false);\r\n await this.onDeactivate(context);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\r\n * @internal\r\n */\r\n public _predraw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n this.emit('predraw', new PreDrawEvent(ctx, delta, this));\r\n this.onPreDraw(ctx, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\r\n * @internal\r\n */\r\n public _postdraw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\r\n this.onPostDraw(ctx, delta);\r\n }\r\n\r\n /**\r\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\r\n * @param engine Reference to the current Engine\r\n * @param delta The number of milliseconds since the last update\r\n */\r\n public update(engine: Engine, delta: number) {\r\n if (!this.isInitialized) {\r\n this._logger.warnOnce(`Scene update called before initialize for scene ${engine.director?.getSceneName(this)}!`);\r\n return;\r\n }\r\n this._preupdate(engine, delta);\r\n\r\n // TODO differed entity removal for timers\r\n let i: number, len: number;\r\n // Remove timers in the cancel queue before updating them\r\n for (i = 0, len = this._cancelQueue.length; i < len; i++) {\r\n this.removeTimer(this._cancelQueue[i]);\r\n }\r\n this._cancelQueue.length = 0;\r\n\r\n // Cycle through timers updating timers\r\n for (const timer of this._timers) {\r\n timer.update(delta);\r\n }\r\n\r\n this.world.update(SystemType.Update, delta);\r\n\r\n // Camera last keeps renders smooth that are based on entity/actor\r\n if (this.camera) {\r\n this.camera.update(engine, delta);\r\n }\r\n\r\n this._collectActorStats(engine);\r\n\r\n this._postupdate(engine, delta);\r\n\r\n this.input.update();\r\n }\r\n\r\n /**\r\n * Draws all the actors in the Scene. Called by the [[Engine]].\r\n * @param ctx The current rendering context\r\n * @param delta The number of milliseconds since the last draw\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n if (!this.isInitialized) {\r\n this._logger.warnOnce(`Scene draw called before initialize!`);\r\n return;\r\n }\r\n this._predraw(ctx, delta);\r\n\r\n this.world.update(SystemType.Draw, delta);\r\n\r\n if (this.engine?.isDebug) {\r\n this.debugDraw(ctx);\r\n }\r\n this._postdraw(ctx, delta);\r\n }\r\n\r\n /**\r\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\r\n * @param ctx The current rendering context\r\n */\r\n /* istanbul ignore next */\r\n public debugDraw(ctx: ExcaliburGraphicsContext) {\r\n this.emit('predebugdraw', new PreDebugDrawEvent(ctx, this));\r\n // pass\r\n this.emit('postdebugdraw', new PostDebugDrawEvent(ctx, this));\r\n }\r\n\r\n /**\r\n * Checks whether an actor is contained in this scene or not\r\n */\r\n public contains(actor: Actor): boolean {\r\n return this.actors.indexOf(actor) > -1;\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the current [[Scene]].\r\n * @param timer The timer to add to the current [[Scene]].\r\n */\r\n public add(timer: Timer): void;\r\n\r\n /**\r\n * Adds a [[TileMap]] to the [[Scene]], once this is done the [[TileMap]] will be drawn and updated.\r\n */\r\n public add(tileMap: TileMap): void;\r\n\r\n /**\r\n * Adds a [[Trigger]] to the [[Scene]], once this is done the [[Trigger]] will listen for interactions with other actors.\r\n * @param trigger\r\n */\r\n public add(trigger: Trigger): void;\r\n\r\n /**\r\n * Adds an actor to the scene, once this is done the [[Actor]] will be drawn and updated.\r\n * @param actor The actor to add to the current scene\r\n */\r\n public add(actor: Actor): void;\r\n\r\n /**\r\n * Adds an [[Entity]] to the scene, once this is done the [[Actor]] will be drawn and updated.\r\n * @param entity The entity to add to the current scene\r\n */\r\n public add(entity: Entity): void;\r\n\r\n /**\r\n * Adds a [[ScreenElement]] to the scene.\r\n * @param screenElement The ScreenElement to add to the current scene\r\n */\r\n public add(screenElement: ScreenElement): void;\r\n public add(entity: any): void {\r\n this.emit('entityadded', { target: entity } as any);\r\n this.world.add(entity);\r\n entity.scene = this;\r\n if (entity instanceof Timer) {\r\n if (!Util.contains(this._timers, entity)) {\r\n this.addTimer(entity);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n\r\n\r\n /**\r\n * Removes a [[Timer]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param timer The Timer to transfer to the current scene\r\n */\r\n public transfer(timer: Timer): void;\r\n\r\n /**\r\n * Removes a [[TileMap]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param tileMap The TileMap to transfer to the current scene\r\n */\r\n public transfer(tileMap: TileMap): void;\r\n\r\n /**\r\n * Removes a [[Trigger]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param trigger The Trigger to transfer to the current scene\r\n */\r\n public transfer(trigger: Trigger): void;\r\n\r\n /**\r\n * Removes an [[Actor]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param actor The Actor to transfer to the current scene\r\n */\r\n public transfer(actor: Actor): void;\r\n\r\n /**\r\n * Removes an [[Entity]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param entity The Entity to transfer to the current scene\r\n */\r\n public transfer(entity: Entity): void;\r\n\r\n /**\r\n * Removes a [[ScreenElement]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param screenElement The ScreenElement to transfer to the current scene\r\n */\r\n public transfer(screenElement: ScreenElement): void;\r\n\r\n /**\r\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param entity\r\n */\r\n public transfer(entity: any): void {\r\n let scene: Scene;\r\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\r\n scene = entity.scene;\r\n entity.scene.world.remove(entity, false);\r\n }\r\n if (entity instanceof Timer && entity.scene) {\r\n scene = entity.scene;\r\n entity.scene.removeTimer(entity);\r\n }\r\n scene?.emit('entityremoved', { target: entity } as any);\r\n this.add(entity);\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the current scene, it will no longer be updated.\r\n * @param timer The timer to remove to the current scene.\r\n */\r\n public remove(timer: Timer): void;\r\n\r\n /**\r\n * Removes a [[TileMap]] from the scene, it will no longer be drawn or updated.\r\n * @param tileMap {TileMap}\r\n */\r\n public remove(tileMap: TileMap): void;\r\n\r\n /**\r\n * Removes an actor from the scene, it will no longer be drawn or updated.\r\n * @param actor The actor to remove from the current scene.\r\n */\r\n public remove(actor: Actor): void;\r\n\r\n public remove(entity: Entity): void;\r\n\r\n /**\r\n * Removes a [[ScreenElement]] to the scene, it will no longer be drawn or updated\r\n * @param screenElement The ScreenElement to remove from the current scene\r\n */\r\n public remove(screenElement: ScreenElement): void;\r\n public remove(entity: any): void {\r\n if (entity instanceof Entity) {\r\n this.emit('entityremoved', { target: entity } as any);\r\n if (entity.active) {\r\n entity.kill();\r\n }\r\n this.world.remove(entity);\r\n }\r\n if (entity instanceof Timer) {\r\n this.removeTimer(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\r\n *\r\n * By default entities use deferred removal\r\n * @param deferred\r\n */\r\n public clear(deferred: boolean = true): void {\r\n for (let i = this.entities.length - 1; i >= 0; i--) {\r\n this.world.remove(this.entities[i], deferred);\r\n }\r\n for (let i = this.timers.length - 1; i >= 0; i--) {\r\n this.removeTimer(this.timers[i]);\r\n }\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the scene\r\n * @param timer The timer to add\r\n */\r\n public addTimer(timer: Timer): Timer {\r\n this._timers.push(timer);\r\n timer.scene = this;\r\n return timer;\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the scene.\r\n * @warning Can be dangerous, use [[cancelTimer]] instead\r\n * @param timer The timer to remove\r\n */\r\n public removeTimer(timer: Timer): Timer {\r\n const i = this._timers.indexOf(timer);\r\n if (i !== -1) {\r\n this._timers.splice(i, 1);\r\n }\r\n return timer;\r\n }\r\n\r\n /**\r\n * Cancels a [[Timer]], removing it from the scene nicely\r\n * @param timer The timer to cancel\r\n */\r\n public cancelTimer(timer: Timer): Timer {\r\n this._cancelQueue.push(timer);\r\n return timer;\r\n }\r\n\r\n /**\r\n * Tests whether a [[Timer]] is active in the scene\r\n */\r\n public isTimerActive(timer: Timer): boolean {\r\n return this._timers.indexOf(timer) > -1 && !timer.complete;\r\n }\r\n\r\n public isCurrentScene(): boolean {\r\n if (this.engine) {\r\n return this.engine.currentScene === this;\r\n }\r\n return false;\r\n }\r\n\r\n private _collectActorStats(engine: Engine) {\r\n const screenElements = this.actors.filter((a) => a instanceof ScreenElement) as ScreenElement[];\r\n for (const _ui of screenElements) {\r\n engine.stats.currFrame.actors.ui++;\r\n }\r\n\r\n for (const actor of this.actors) {\r\n engine.stats.currFrame.actors.alive++;\r\n for (const child of actor.children) {\r\n if (isScreenElement(child as Actor)) {\r\n // TODO not true\r\n engine.stats.currFrame.actors.ui++;\r\n } else {\r\n engine.stats.currFrame.actors.alive++;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","\r\n\r\nexport enum ColorBlindnessMode {\r\n Protanope = 'Protanope',\r\n Deuteranope = 'Deuteranope',\r\n Tritanope = 'Tritanope'\r\n}\r\n","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\";","import { Shader } from '../Context/shader';\r\nimport { VertexBuffer } from '../Context/vertex-buffer';\r\nimport { VertexLayout } from '../Context/vertex-layout';\r\n\r\n/**\r\n * Helper that defines a whole screen renderer, just provide a fragment source!\r\n *\r\n * Currently supports 1 varying\r\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\r\n */\r\nexport class ScreenShader {\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n constructor(gl: WebGL2RenderingContext, fragmentSource: string) {\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\r\n fragmentSource: fragmentSource\r\n });\r\n this._shader.compile();\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n type: 'static',\r\n // clip space quad + uv since we don't need a camera\r\n data: new Float32Array([\r\n -1, -1, 0, 0,\r\n -1, 1, 0, 1,\r\n 1, -1, 1, 0,\r\n\r\n 1, -1, 1, 0,\r\n -1, 1, 0, 1,\r\n 1, 1, 1, 1\r\n ])\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_texcoord', 2]\r\n ]\r\n });\r\n this._buffer.upload();\r\n }\r\n\r\n public getShader() {\r\n return this._shader;\r\n }\r\n public getLayout() {\r\n return this._layout;\r\n }\r\n}","import colorBlindCorrectSource from './color-blind-fragment.glsl';\r\nimport { PostProcessor } from './PostProcessor';\r\nimport { ColorBlindnessMode } from './ColorBlindnessMode';\r\nimport { Shader } from '../Context/shader';\r\nimport { VertexLayout } from '../Context/vertex-layout';\r\nimport { ScreenShader } from './ScreenShader';\r\n\r\nexport class ColorBlindnessPostProcessor implements PostProcessor {\r\n private _shader: ScreenShader;\r\n private _simulate = false;\r\n constructor(private _colorBlindnessMode: ColorBlindnessMode, simulate = false) {\r\n this._simulate = simulate;\r\n }\r\n\r\n initialize(gl: WebGL2RenderingContext): void {\r\n this._shader = new ScreenShader(gl, colorBlindCorrectSource);\r\n this.simulate = this._simulate;\r\n this.colorBlindnessMode = this._colorBlindnessMode;\r\n }\r\n\r\n getShader(): Shader {\r\n return this._shader.getShader();\r\n }\r\n\r\n getLayout(): VertexLayout {\r\n return this._shader.getLayout();\r\n }\r\n\r\n set colorBlindnessMode(colorBlindMode: ColorBlindnessMode) {\r\n this._colorBlindnessMode = colorBlindMode;\r\n if (this._shader) {\r\n const shader = this._shader.getShader();\r\n shader.use();\r\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) {\r\n shader.setUniformInt('u_type', 0);\r\n } else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) {\r\n shader.setUniformInt('u_type', 1);\r\n } else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) {\r\n shader.setUniformInt('u_type', 2);\r\n }\r\n }\r\n }\r\n\r\n get colorBlindnessMode(): ColorBlindnessMode {\r\n return this._colorBlindnessMode;\r\n }\r\n\r\n set simulate(value: boolean) {\r\n this._simulate = value;\r\n if (this._shader) {\r\n\r\n const shader = this._shader.getShader();\r\n shader.use();\r\n shader.setUniformBoolean('u_simulate', value);\r\n }\r\n }\r\n\r\n get simulate(): boolean {\r\n return this._simulate;\r\n }\r\n}\r\n","import { ColorBlindnessMode } from '../Graphics/PostProcessor/ColorBlindnessMode';\r\nimport { ColorBlindnessPostProcessor } from '../Graphics/PostProcessor/ColorBlindnessPostProcessor';\r\nimport { Engine } from '../Engine';\r\nimport { ExcaliburGraphicsContextWebGL } from '../Graphics/Context/ExcaliburGraphicsContextWebGL';\r\n\r\nexport class ColorBlindFlags {\r\n private _engine: Engine;\r\n private _colorBlindPostProcessor: ColorBlindnessPostProcessor;\r\n\r\n constructor(engine: Engine) {\r\n this._engine = engine;\r\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\r\n }\r\n\r\n /**\r\n * Correct colors for a specified color blindness\r\n * @param colorBlindness\r\n */\r\n public correct(colorBlindness: ColorBlindnessMode) {\r\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this.clear();\r\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\r\n this._colorBlindPostProcessor.simulate = false;\r\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\r\n }\r\n }\r\n\r\n /**\r\n * Simulate colors for a specified color blindness\r\n * @param colorBlindness\r\n */\r\n public simulate(colorBlindness: ColorBlindnessMode) {\r\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this.clear();\r\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\r\n this._colorBlindPostProcessor.simulate = true;\r\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\r\n }\r\n }\r\n\r\n /**\r\n * Remove color blindness post processor\r\n */\r\n public clear() {\r\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\r\n }\r\n}\r\n","import { ColorBlindFlags } from './DebugFlags';\r\nimport { Engine } from '../Engine';\r\nimport { Color } from '../Color';\r\nimport { CollisionContact } from '../Collision/Detection/CollisionContact';\r\nimport { StandardClock, TestClock } from '../Util/Clock';\r\n\r\n/**\r\n * Debug stats containing current and previous frame statistics\r\n */\r\nexport interface DebugStats {\r\n currFrame: FrameStats;\r\n prevFrame: FrameStats;\r\n}\r\n\r\n/**\r\n * Represents a frame's individual statistics\r\n */\r\nexport interface FrameStatistics {\r\n /**\r\n * The number of the frame\r\n */\r\n id: number;\r\n\r\n /**\r\n * Gets the frame's delta (time since last frame scaled by [[Engine.timescale]]) (in ms)\r\n */\r\n delta: number;\r\n\r\n /**\r\n * Gets the frame's frames-per-second (FPS)\r\n */\r\n fps: number;\r\n\r\n /**\r\n * Duration statistics (in ms)\r\n */\r\n duration: FrameDurationStats;\r\n\r\n /**\r\n * Actor statistics\r\n */\r\n actors: FrameActorStats;\r\n\r\n /**\r\n * Physics statistics\r\n */\r\n physics: PhysicsStatistics;\r\n\r\n /**\r\n * Graphics statistics\r\n */\r\n graphics: GraphicsStatistics;\r\n}\r\n\r\n/**\r\n * Represents actor stats for a frame\r\n */\r\nexport interface FrameActorStats {\r\n /**\r\n * Gets the frame's number of actors (alive)\r\n */\r\n alive: number;\r\n\r\n /**\r\n * Gets the frame's number of actors (killed)\r\n */\r\n killed: number;\r\n\r\n /**\r\n * Gets the frame's number of remaining actors (alive - killed)\r\n */\r\n remaining: number;\r\n\r\n /**\r\n * Gets the frame's number of UI actors\r\n */\r\n ui: number;\r\n\r\n /**\r\n * Gets the frame's number of total actors (remaining + UI)\r\n */\r\n total: number;\r\n}\r\n\r\n/**\r\n * Represents duration stats for a frame\r\n */\r\nexport interface FrameDurationStats {\r\n /**\r\n * Gets the frame's total time to run the update function (in ms)\r\n */\r\n update: number;\r\n\r\n /**\r\n * Gets the frame's total time to run the draw function (in ms)\r\n */\r\n draw: number;\r\n\r\n /**\r\n * Gets the frame's total render duration (update + draw duration) (in ms)\r\n */\r\n total: number;\r\n}\r\n\r\n/**\r\n * Represents physics stats for the current frame\r\n */\r\nexport interface PhysicsStatistics {\r\n /**\r\n * Gets the number of broadphase collision pairs which\r\n */\r\n pairs: number;\r\n\r\n /**\r\n * Gets the number of actual collisions\r\n */\r\n collisions: number;\r\n\r\n /**\r\n * Copy of the current frame contacts (only updated if debug is toggled on)\r\n */\r\n contacts: Map;\r\n\r\n /**\r\n * Gets the number of fast moving bodies using raycast continuous collisions in the scene\r\n */\r\n fastBodies: number;\r\n\r\n /**\r\n * Gets the number of bodies that had a fast body collision resolution\r\n */\r\n fastBodyCollisions: number;\r\n\r\n /**\r\n * Gets the time it took to calculate the broadphase pairs\r\n */\r\n broadphase: number;\r\n\r\n /**\r\n * Gets the time it took to calculate the narrowphase\r\n */\r\n narrowphase: number;\r\n}\r\n\r\nexport interface GraphicsStatistics {\r\n drawCalls: number;\r\n drawnImages: number;\r\n}\r\n\r\n/**\r\n * Debug statistics and flags for Excalibur. If polling these values, it would be\r\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\r\n * updated during a frame.\r\n */\r\nexport class DebugConfig {\r\n private _engine: Engine;\r\n\r\n constructor(engine: Engine) {\r\n this._engine = engine;\r\n\r\n this.colorBlindMode = new ColorBlindFlags(this._engine);\r\n }\r\n\r\n /**\r\n * Switch the current excalibur clock with the [[TestClock]] and return\r\n * it in the same running state.\r\n *\r\n * This is useful when you need to debug frame by frame.\r\n */\r\n public useTestClock(): TestClock {\r\n const clock = this._engine.clock;\r\n const wasRunning = clock.isRunning();\r\n clock.stop();\r\n\r\n const testClock = clock.toTestClock();\r\n if (wasRunning) {\r\n testClock.start();\r\n }\r\n this._engine.clock = testClock;\r\n return testClock;\r\n }\r\n\r\n /**\r\n * Switch the current excalibur clock with the [[StandardClock]] and\r\n * return it in the same running state.\r\n *\r\n * This is useful when you need to switch back to normal mode after\r\n * debugging.\r\n */\r\n public useStandardClock(): StandardClock {\r\n const currentClock = this._engine.clock;\r\n const wasRunning = currentClock.isRunning();\r\n currentClock.stop();\r\n\r\n const standardClock = currentClock.toStandardClock();\r\n if (wasRunning) {\r\n standardClock.start();\r\n }\r\n this._engine.clock = standardClock;\r\n return standardClock;\r\n }\r\n\r\n /**\r\n * Performance statistics\r\n */\r\n public stats: DebugStats = {\r\n /**\r\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[postframe]] event. See [[FrameStats]]\r\n */\r\n currFrame: new FrameStats(),\r\n\r\n /**\r\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\r\n */\r\n prevFrame: new FrameStats()\r\n };\r\n\r\n /**\r\n * Correct or simulate color blindness using [[ColorBlindnessPostProcessor]].\r\n * @warning Will reduce FPS.\r\n */\r\n public colorBlindMode: ColorBlindFlags;\r\n\r\n /**\r\n * Filter debug context to named entities or entity ids\r\n */\r\n public filter: { useFilter: boolean; nameQuery: string; ids: number[] } = {\r\n /**\r\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\r\n */\r\n useFilter: false,\r\n /**\r\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\r\n */\r\n nameQuery: '',\r\n /**\r\n * Query for Entity ids, if the id matches it will be included\r\n */\r\n ids: []\r\n };\r\n\r\n /**\r\n * Entity debug settings\r\n */\r\n public entity = {\r\n showAll: false,\r\n showId: false,\r\n showName: false\r\n };\r\n\r\n /**\r\n * Transform component debug settings\r\n */\r\n public transform = {\r\n showAll: false,\r\n\r\n debugZIndex: 10_000_000,\r\n showPosition: false,\r\n showPositionLabel: false,\r\n positionColor: Color.Yellow,\r\n\r\n showZIndex: false,\r\n\r\n showScale: false,\r\n scaleColor: Color.Green,\r\n\r\n showRotation: false,\r\n rotationColor: Color.Blue\r\n };\r\n\r\n /**\r\n * Graphics component debug settings\r\n */\r\n public graphics = {\r\n showAll: false,\r\n\r\n showBounds: false,\r\n boundsColor: Color.Yellow\r\n };\r\n\r\n /**\r\n * Collider component debug settings\r\n */\r\n public collider = {\r\n showAll: false,\r\n\r\n showBounds: false,\r\n boundsColor: Color.Blue,\r\n\r\n showOwner: false,\r\n\r\n showGeometry: true,\r\n geometryColor: Color.Green,\r\n geometryLineWidth: 1,\r\n geometryPointSize: .5\r\n };\r\n\r\n /**\r\n * Physics simulation debug settings\r\n */\r\n public physics = {\r\n showAll: false,\r\n\r\n showBroadphaseSpacePartitionDebug: false,\r\n\r\n showCollisionNormals: false,\r\n collisionNormalColor: Color.Cyan,\r\n\r\n showCollisionContacts: true,\r\n contactSize: 2,\r\n collisionContactColor: Color.Red\r\n };\r\n\r\n /**\r\n * Motion component debug settings\r\n */\r\n public motion = {\r\n showAll: false,\r\n\r\n showVelocity: false,\r\n velocityColor: Color.Yellow,\r\n\r\n showAcceleration: false,\r\n accelerationColor: Color.Red\r\n };\r\n\r\n /**\r\n * Body component debug settings\r\n */\r\n public body = {\r\n showAll: false,\r\n\r\n showCollisionGroup: false,\r\n showCollisionType: false,\r\n showSleeping: false,\r\n showMotion: false,\r\n showMass: false\r\n };\r\n\r\n /**\r\n * Camera debug settings\r\n */\r\n public camera = {\r\n showAll: false,\r\n\r\n showFocus: false,\r\n focusColor: Color.Red,\r\n\r\n showZoom: false\r\n };\r\n\r\n public tilemap = {\r\n showAll: false,\r\n\r\n showGrid: false,\r\n gridColor: Color.Red,\r\n gridWidth: .5,\r\n showSolidBounds: false,\r\n solidBoundsColor: Color.fromHex('#8080807F'), // grayish\r\n showColliderGeometry: true\r\n };\r\n\r\n public isometric = {\r\n showAll: false,\r\n showPosition: false,\r\n positionColor: Color.Yellow,\r\n positionSize: 1,\r\n showGrid: false,\r\n gridColor: Color.Red,\r\n gridWidth: 1,\r\n showColliderGeometry: true\r\n };\r\n}\r\n\r\n/**\r\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\r\n * creating instances of this every frame.\r\n */\r\nexport class FrameStats implements FrameStatistics {\r\n private _id: number = 0;\r\n private _delta: number = 0;\r\n private _fps: number = 0;\r\n private _actorStats: FrameActorStats = {\r\n alive: 0,\r\n killed: 0,\r\n ui: 0,\r\n get remaining() {\r\n return this.alive - this.killed;\r\n },\r\n get total() {\r\n return this.remaining + this.ui;\r\n }\r\n };\r\n private _durationStats: FrameDurationStats = {\r\n update: 0,\r\n draw: 0,\r\n get total() {\r\n return this.update + this.draw;\r\n }\r\n };\r\n\r\n private _physicsStats: PhysicsStats = new PhysicsStats();\r\n\r\n private _graphicsStats: GraphicsStatistics = {\r\n drawCalls: 0,\r\n drawnImages: 0\r\n };\r\n\r\n /**\r\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\r\n * @param [otherStats] Optional stats to clone\r\n */\r\n public reset(otherStats?: FrameStatistics) {\r\n if (otherStats) {\r\n this.id = otherStats.id;\r\n this.delta = otherStats.delta;\r\n this.fps = otherStats.fps;\r\n this.actors.alive = otherStats.actors.alive;\r\n this.actors.killed = otherStats.actors.killed;\r\n this.actors.ui = otherStats.actors.ui;\r\n this.duration.update = otherStats.duration.update;\r\n this.duration.draw = otherStats.duration.draw;\r\n this._physicsStats.reset(otherStats.physics);\r\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\r\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\r\n } else {\r\n this.id = this.delta = this.fps = 0;\r\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\r\n this.duration.update = this.duration.draw = 0;\r\n this._physicsStats.reset();\r\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Provides a clone of this instance.\r\n */\r\n public clone(): FrameStats {\r\n const fs = new FrameStats();\r\n\r\n fs.reset(this);\r\n\r\n return fs;\r\n }\r\n\r\n /**\r\n * Gets the frame's id\r\n */\r\n public get id() {\r\n return this._id;\r\n }\r\n\r\n /**\r\n * Sets the frame's id\r\n */\r\n public set id(value: number) {\r\n this._id = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's delta (time since last frame)\r\n */\r\n public get delta() {\r\n return this._delta;\r\n }\r\n\r\n /**\r\n * Sets the frame's delta (time since last frame). Internal use only.\r\n * @internal\r\n */\r\n public set delta(value: number) {\r\n this._delta = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's frames-per-second (FPS)\r\n */\r\n public get fps() {\r\n return this._fps;\r\n }\r\n\r\n /**\r\n * Sets the frame's frames-per-second (FPS). Internal use only.\r\n * @internal\r\n */\r\n public set fps(value: number) {\r\n this._fps = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's actor statistics\r\n */\r\n public get actors() {\r\n return this._actorStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's duration statistics\r\n */\r\n public get duration() {\r\n return this._durationStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's physics statistics\r\n */\r\n public get physics() {\r\n return this._physicsStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's graphics statistics\r\n */\r\n public get graphics() {\r\n return this._graphicsStats;\r\n }\r\n}\r\n\r\nexport class PhysicsStats implements PhysicsStatistics {\r\n private _pairs: number = 0;\r\n private _collisions: number = 0;\r\n private _contacts: Map = new Map();\r\n private _fastBodies: number = 0;\r\n private _fastBodyCollisions: number = 0;\r\n private _broadphase: number = 0;\r\n private _narrowphase: number = 0;\r\n\r\n /**\r\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\r\n * @param [otherStats] Optional stats to clone\r\n */\r\n public reset(otherStats?: PhysicsStatistics) {\r\n if (otherStats) {\r\n this.pairs = otherStats.pairs;\r\n this.collisions = otherStats.collisions;\r\n this.contacts = otherStats.contacts;\r\n this.fastBodies = otherStats.fastBodies;\r\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\r\n this.broadphase = otherStats.broadphase;\r\n this.narrowphase = otherStats.narrowphase;\r\n } else {\r\n this.pairs = this.collisions = this.fastBodies = 0;\r\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\r\n this.contacts.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Provides a clone of this instance.\r\n */\r\n public clone(): PhysicsStatistics {\r\n const ps = new PhysicsStats();\r\n\r\n ps.reset(this);\r\n\r\n return ps;\r\n }\r\n\r\n public get pairs(): number {\r\n return this._pairs;\r\n }\r\n\r\n public set pairs(value: number) {\r\n this._pairs = value;\r\n }\r\n\r\n public get collisions(): number {\r\n return this._collisions;\r\n }\r\n\r\n public set collisions(value: number) {\r\n this._collisions = value;\r\n }\r\n\r\n public get contacts(): Map {\r\n return this._contacts;\r\n }\r\n\r\n public set contacts(contacts: Map) {\r\n this._contacts = contacts;\r\n }\r\n\r\n public get fastBodies(): number {\r\n return this._fastBodies;\r\n }\r\n\r\n public set fastBodies(value: number) {\r\n this._fastBodies = value;\r\n }\r\n\r\n public get fastBodyCollisions(): number {\r\n return this._fastBodyCollisions;\r\n }\r\n\r\n public set fastBodyCollisions(value: number) {\r\n this._fastBodyCollisions = value;\r\n }\r\n\r\n public get broadphase(): number {\r\n return this._broadphase;\r\n }\r\n\r\n public set broadphase(value: number) {\r\n this._broadphase = value;\r\n }\r\n\r\n public get narrowphase(): number {\r\n return this._narrowphase;\r\n }\r\n\r\n public set narrowphase(value: number) {\r\n this._narrowphase = value;\r\n }\r\n}\r\n","export interface NativeEventable {\r\n addEventListener(name: string, handler: (...any: any[]) => any): any;\r\n removeEventListener(name: string, handler: (...any: any[]) => any): any;\r\n}\r\n\r\nexport class BrowserComponent {\r\n private _paused = false;\r\n private _nativeHandlers: { [key: string]: (handler: any) => void } = {};\r\n\r\n on(eventName: string, handler: (evt: any) => void): void {\r\n if (this._nativeHandlers[eventName]) {\r\n this.off(eventName, this._nativeHandlers[eventName]);\r\n }\r\n this._nativeHandlers[eventName] = this._decorate(handler);\r\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\r\n }\r\n off(eventName: string, handler?: (event: any) => void): void {\r\n if (!handler) {\r\n handler = this._nativeHandlers[eventName];\r\n }\r\n this.nativeComponent.removeEventListener(eventName, handler);\r\n this._nativeHandlers[eventName] = null;\r\n }\r\n\r\n private _decorate(handler: (evt: any) => void): (evt: any) => void {\r\n return (evt: any) => {\r\n if (!this._paused) {\r\n handler(evt);\r\n }\r\n };\r\n }\r\n\r\n public pause() {\r\n this._paused = true;\r\n }\r\n\r\n public resume() {\r\n this._paused = false;\r\n }\r\n\r\n public clear() {\r\n for (const event in this._nativeHandlers) {\r\n this.off(event);\r\n }\r\n }\r\n\r\n constructor(public nativeComponent: T) {}\r\n}\r\n\r\nexport class BrowserEvents {\r\n private _windowComponent: BrowserComponent;\r\n private _documentComponent: BrowserComponent;\r\n constructor(private _windowGlobal: Window, private _documentGlobal: Document) {\r\n this._windowComponent = new BrowserComponent(this._windowGlobal);\r\n this._documentComponent = new BrowserComponent(this._documentGlobal);\r\n }\r\n\r\n public get window(): BrowserComponent {\r\n return this._windowComponent;\r\n }\r\n\r\n public get document(): BrowserComponent {\r\n return this._documentComponent;\r\n }\r\n\r\n public pause() {\r\n this.window.pause();\r\n this.document.pause();\r\n }\r\n\r\n public resume() {\r\n this.window.resume();\r\n this.document.resume();\r\n }\r\n\r\n public clear() {\r\n this.window.clear();\r\n this.document.clear();\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { Color } from '../../Color';\r\nimport { ScreenDimension } from '../../Screen';\r\nimport { PostProcessor } from '../PostProcessor/PostProcessor';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Material, MaterialOptions } from './material';\r\nimport { ImageFiltering } from '../Filtering';\r\n\r\nexport type HTMLImageSource = HTMLImageElement | HTMLCanvasElement;\r\n\r\nexport interface AntialiasOptions {\r\n /**\r\n * Turns on the special pixel art sampler in excalibur's image shader for sub pixel\r\n * anti-aliasing\r\n *\r\n * Default false\r\n */\r\n pixelArtSampler?: boolean;\r\n /**\r\n * Configures the webgl's getContext('webgl2', {antialias: true | false}) or configures\r\n * Canvas2D imageSmoothing = true;\r\n *\r\n * **Note** this option is incompatible with `multiSampleAntialiasing`\r\n *\r\n * Default false\r\n */\r\n nativeContextAntialiasing?: boolean;\r\n /**\r\n * Configures the internal render buffer multi-sampling settings\r\n *\r\n * Default true, with max samples that the platform supports\r\n */\r\n multiSampleAntialiasing?: boolean | {\r\n /**\r\n * Optionally specify number of samples (will be clamped to the max the platform supports)\r\n *\r\n * Default most platforms are 16 samples\r\n */\r\n samples: number;\r\n };\r\n /**\r\n * Sets the default image filtering for excalibur\r\n *\r\n * Default [[ImageFiltering.Blended]]\r\n */\r\n filtering?: ImageFiltering;\r\n /**\r\n * Sets the canvas image rendering CSS style\r\n *\r\n * Default 'auto'\r\n */\r\n canvasImageRendering?: 'pixelated' | 'auto';\r\n}\r\n\r\nexport const DefaultAntialiasOptions: Required = {\r\n pixelArtSampler: false,\r\n nativeContextAntialiasing: false,\r\n multiSampleAntialiasing: true,\r\n filtering: ImageFiltering.Blended,\r\n canvasImageRendering: 'auto'\r\n};\r\n\r\nexport const DefaultPixelArtOptions: Required = {\r\n pixelArtSampler: true,\r\n nativeContextAntialiasing: false,\r\n multiSampleAntialiasing: true,\r\n filtering: ImageFiltering.Blended,\r\n canvasImageRendering: 'auto'\r\n};\r\n\r\nexport interface ExcaliburGraphicsContextOptions {\r\n /**\r\n * Target existing html canvas element\r\n */\r\n canvasElement: HTMLCanvasElement;\r\n /**\r\n * Enables antialiasing on the canvas context (smooths pixels with default canvas sampling)\r\n */\r\n antialiasing?: boolean;\r\n /**\r\n * Enable the sub pixel antialiasing pixel art sampler for nice looking pixel art\r\n */\r\n pixelArtSampler?: boolean;\r\n /**\r\n * Enable canvas transparency\r\n */\r\n enableTransparency?: boolean;\r\n /**\r\n * Enable or disable multi-sample antialiasing in the internal render buffer.\r\n *\r\n * If true the max number of samples will be used\r\n *\r\n * By default enabled\r\n */\r\n multiSampleAntialiasing?: boolean | {\r\n /**\r\n * Specify number of samples to use during the multi sample anti-alias, if not specified the max will be used.\r\n * Limited by the hardware (usually 16)\r\n */\r\n samples: number\r\n },\r\n /**\r\n * UV padding in pixels to use in the internal image rendering\r\n *\r\n * Recommended .25 - .5 of a pixel\r\n */\r\n uvPadding?: number;\r\n /**\r\n * Hint the power preference to the graphics context\r\n */\r\n powerPreference?: 'default' | 'high-performance' | 'low-power';\r\n /**\r\n * Snaps the pixel to an integer value (floor)\r\n */\r\n snapToPixel?: boolean;\r\n /**\r\n * Current clearing color of the context\r\n */\r\n backgroundColor?: Color;\r\n /**\r\n * Feature flag that enables draw sorting will removed in v0.29\r\n */\r\n useDrawSorting?: boolean;\r\n}\r\n\r\nexport interface ExcaliburGraphicsContextState {\r\n opacity: number;\r\n z: number;\r\n tint: Color;\r\n material: Material;\r\n}\r\nexport interface LineGraphicsOptions {\r\n color?: Color;\r\n}\r\n\r\nexport interface RectGraphicsOptions {\r\n color?: Color;\r\n}\r\n\r\nexport interface PointGraphicsOptions {\r\n color: Color;\r\n size: number;\r\n}\r\n\r\nexport interface DebugDraw {\r\n /**\r\n * Draw a debugging rectangle to the screen\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n * @param rectOptions\r\n */\r\n drawRect(x: number, y: number, width: number, height: number, rectOptions?: RectGraphicsOptions): void;\r\n /**\r\n * Draw a debugging line to the screen\r\n * @param start '\r\n * @param end\r\n * @param lineOptions\r\n */\r\n drawLine(start: Vector, end: Vector, lineOptions?: LineGraphicsOptions): void;\r\n /**\r\n * Draw a debugging point to the screen\r\n * @param point\r\n * @param pointOptions\r\n */\r\n drawPoint(point: Vector, pointOptions?: PointGraphicsOptions): void;\r\n\r\n /**\r\n * Draw debug text\r\n * @param text\r\n * @param pos\r\n */\r\n drawText(text: string, pos: Vector): void;\r\n}\r\n\r\nexport interface ExcaliburGraphicsContext {\r\n width: number;\r\n height: number;\r\n\r\n /**\r\n * Excalibur will automatically sort draw calls by z and priority for maximal draw performance,\r\n * this can disrupt a specific desired painter order.\r\n *\r\n * To force a specific draw call order, use [[ExcaliburGraphicsContext.z]]\r\n *\r\n * By default `useDrawSorting` is `true`, to opt out set this to `false`\r\n */\r\n useDrawSorting: boolean;\r\n\r\n /**\r\n * Set the current z context for the graphics context. Draw calls issued to the context will use this z\r\n * to inform their sort order.\r\n *\r\n * Note it is important to all [[ExcaliburGraphicsContext.save]] and [[ExcaliburGraphicsContext.restore]] when modifying state.\r\n */\r\n z: number;\r\n\r\n /**\r\n * Snaps all drawings to the nearest pixel truncated down, by default false\r\n */\r\n snapToPixel: boolean;\r\n\r\n /**\r\n * Enable smoothed drawing (also known as anti-aliasing), by default true\r\n */\r\n smoothing: boolean;\r\n\r\n /**\r\n * Set the background color of the graphics context, default is [[Color.ExcaliburBlue]]\r\n */\r\n backgroundColor: Color;\r\n\r\n /**\r\n * Sets the opacity of the current [[Graphic]] being drawn, default is 1\r\n */\r\n opacity: number;\r\n\r\n /**\r\n * Sets the tint color to be multiplied by any images drawn, default is black 0xFFFFFFFF\r\n */\r\n tint: Color;\r\n\r\n /**\r\n * Resets the current transform to the identity matrix\r\n */\r\n resetTransform(): void;\r\n\r\n /**\r\n * Gets the current transform\r\n */\r\n getTransform(): AffineMatrix;\r\n\r\n /**\r\n * Multiplies the current transform by a matrix\r\n * @param m\r\n */\r\n multiply(m: AffineMatrix): void;\r\n\r\n /**\r\n * Update the context with the current viewport dimensions (used in resizing)\r\n */\r\n updateViewport(resolution: ScreenDimension): void;\r\n\r\n /**\r\n * Access the debug drawing api\r\n */\r\n debug: DebugDraw;\r\n\r\n /**\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate using the images width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate with a specific width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number, width: number, height: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context specifying the source image coordinates (sx, sy, swidth, sheight)\r\n * and to a specific destination on the context (dx, dy, dwidth, dheight)\r\n */\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void;\r\n\r\n /**\r\n * Draw a solid line to the Excalibur Graphics context\r\n * @param start\r\n * @param end\r\n * @param color\r\n * @param thickness\r\n */\r\n drawLine(start: Vector, end: Vector, color: Color, thickness: number): void;\r\n\r\n /**\r\n * Draw a solid rectangle to the Excalibur Graphics context\r\n * @param pos\r\n * @param width\r\n * @param height\r\n * @param color\r\n */\r\n drawRectangle(pos: Vector, width: number, height: number, color: Color, stroke?: Color, strokeThickness?: number): void;\r\n\r\n /**\r\n * Draw a circle to the Excalibur Graphics context\r\n * @param pos\r\n * @param radius\r\n * @param color\r\n * @param stroke Optionally specify the stroke color\r\n * @param thickness\r\n */\r\n drawCircle(pos: Vector, radius: number, color: Color, stroke?: Color, thickness?: number): void;\r\n\r\n /**\r\n * Save the current state of the canvas to the stack (transforms and opacity)\r\n */\r\n save(): void;\r\n\r\n /**\r\n * Restore the state of the canvas from the stack\r\n */\r\n restore(): void;\r\n\r\n /**\r\n * Translate the origin of the context by an x and y\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number): void;\r\n\r\n /**\r\n * Rotate the context about the current origin\r\n */\r\n rotate(angle: number): void;\r\n\r\n /**\r\n * Scale the context by an x and y factor\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number): void;\r\n\r\n /**\r\n * Add a post processor to the graphics context\r\n *\r\n * Post processors are run in the order they were added.\r\n * @param postprocessor\r\n */\r\n addPostProcessor(postprocessor: PostProcessor): void;\r\n\r\n /**\r\n * Remove a specific post processor from the graphics context\r\n * @param postprocessor\r\n */\r\n removePostProcessor(postprocessor: PostProcessor): void;\r\n\r\n /**\r\n * Remove all post processors from the graphics context\r\n */\r\n clearPostProcessors(): void;\r\n\r\n /**\r\n * Updates all post processors in the graphics context\r\n *\r\n * Called internally by Excalibur\r\n * @param delta\r\n * @internal\r\n */\r\n updatePostProcessors(delta: number): void;\r\n\r\n /**\r\n * Gets or sets the material to be used in the current context's drawings\r\n *\r\n * This allows customs shaders to be used but draw calls are no longer batched by default.\r\n * @param material\r\n */\r\n material: Material;\r\n\r\n /**\r\n * Creates and initializes the material which compiles the internal shader\r\n * @param options\r\n * @returns\r\n */\r\n createMaterial(options: Omit): Material;\r\n\r\n /**\r\n * Clears the screen with the current background color\r\n */\r\n clear(): void;\r\n\r\n /**\r\n * Flushes the batched draw calls to the screen\r\n */\r\n flush(): void;\r\n\r\n beginDrawLifecycle(): void;\r\n\r\n endDrawLifecycle(): void;\r\n\r\n dispose(): void;\r\n}\r\n","export interface FpsSamplerOptions {\r\n /**\r\n * Specify the sampling period in milliseconds (default 100)\r\n */\r\n samplePeriod?: number;\r\n /**\r\n * Specify the initial FPS\r\n */\r\n initialFps: number;\r\n\r\n /**\r\n * Specify the function used to return the current time (in milliseconds)\r\n */\r\n nowFn: () => number;\r\n}\r\n\r\nexport class FpsSampler {\r\n private _fps: number;\r\n private _samplePeriod: number = 100;\r\n private _currentFrameTime: number = 0;\r\n private _frames: number = 0;\r\n private _previousSampleTime: number = 0;\r\n private _beginFrameTime: number = 0;\r\n private _nowFn: () => number;\r\n\r\n constructor(options: FpsSamplerOptions) {\r\n this._fps = options.initialFps;\r\n this._samplePeriod = options.samplePeriod ?? this._samplePeriod;\r\n this._currentFrameTime = 1000/options.initialFps;\r\n this._nowFn = options.nowFn;\r\n this._previousSampleTime = this._nowFn();\r\n }\r\n\r\n /**\r\n * Start of code block to sample FPS for\r\n */\r\n start() {\r\n this._beginFrameTime = this._nowFn();\r\n }\r\n\r\n /**\r\n * End of code block to sample FPS for\r\n */\r\n end() {\r\n this._frames++;\r\n const time = this._nowFn();\r\n\r\n this._currentFrameTime = time - this._beginFrameTime;\r\n\r\n if (time >= this._previousSampleTime + this._samplePeriod) {\r\n this._fps = (this._frames * 1000) / (time - this._previousSampleTime);\r\n this._previousSampleTime = time;\r\n this._frames = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Return the currently sampled fps over the last sample period, by default every 100ms\r\n */\r\n get fps() {\r\n return this._fps;\r\n }\r\n\r\n /**\r\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\r\n */\r\n get instant() {\r\n return 1000 / this._currentFrameTime;\r\n }\r\n}","import { Logger } from '../Util/Log';\r\nimport { FpsSampler } from './Fps';\r\n\r\nexport interface ClockOptions {\r\n /**\r\n * Define the function you'd like the clock to tick when it is started\r\n */\r\n tick: (elapsedMs: number) => any;\r\n /**\r\n * Optionally define the fatal exception handler, used if an error is thrown in tick\r\n */\r\n onFatalException?: (e: unknown) => any;\r\n /**\r\n * Optionally limit the maximum FPS of the clock\r\n */\r\n maxFps?: number;\r\n}\r\n\r\n\r\n/**\r\n * Abstract Clock is the base type of all Clocks\r\n *\r\n * It has a few opinions\r\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\r\n * 2. The default timing api is implemented in now()\r\n *\r\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\r\n * method is unique to your clock implementation.\r\n */\r\nexport abstract class Clock {\r\n protected tick: (elapsedMs: number) => any;\r\n private _onFatalException: (e: unknown) => any = () => { /* default nothing */ };\r\n private _maxFps: number = Infinity;\r\n private _lastTime: number = 0;\r\n public fpsSampler: FpsSampler;\r\n private _options: ClockOptions;\r\n private _elapsed: number = 1;\r\n private _scheduledCbs: [cb: (elapsedMs: number) => any, scheduledTime: number][] = [];\r\n private _totalElapsed: number = 0;\r\n constructor(options: ClockOptions) {\r\n this._options = options;\r\n this.tick = options.tick;\r\n this._lastTime = this.now() ?? 0;\r\n this._maxFps = options.maxFps ?? this._maxFps;\r\n this._onFatalException = options.onFatalException ?? this._onFatalException;\r\n this.fpsSampler = new FpsSampler({\r\n initialFps: 60,\r\n nowFn: () => this.now()\r\n });\r\n }\r\n\r\n /**\r\n * Get the elapsed time for the last completed frame\r\n */\r\n public elapsed(): number {\r\n return this._elapsed;\r\n }\r\n\r\n /**\r\n * Get the current time in milliseconds\r\n */\r\n public now(): number {\r\n return performance.now();\r\n }\r\n\r\n public toTestClock() {\r\n const testClock = new TestClock({\r\n ...this._options,\r\n defaultUpdateMs: 16.6\r\n });\r\n return testClock;\r\n }\r\n\r\n public toStandardClock() {\r\n const clock = new StandardClock({\r\n ...this._options\r\n });\r\n return clock;\r\n }\r\n\r\n public setFatalExceptionHandler(handler: (e: unknown) => any) {\r\n this._onFatalException = handler;\r\n }\r\n\r\n /**\r\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\r\n *\r\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\r\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\r\n * stopped or paused.\r\n * @param cb callback to fire\r\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\r\n */\r\n public schedule(cb: (elapsedMs: number) => any, timeoutMs: number = 0) {\r\n // Scheduled based on internal elapsed time\r\n const scheduledTime = this._totalElapsed + timeoutMs;\r\n this._scheduledCbs.push([cb, scheduledTime]);\r\n }\r\n\r\n private _runScheduledCbs() {\r\n // walk backwards to delete items as we loop\r\n for (let i = this._scheduledCbs.length - 1; i > -1; i--) {\r\n if (this._scheduledCbs[i][1] <= this._totalElapsed) {\r\n this._scheduledCbs[i][0](this._elapsed);\r\n this._scheduledCbs.splice(i, 1);\r\n }\r\n }\r\n }\r\n\r\n protected update(overrideUpdateMs?: number): void {\r\n try {\r\n this.fpsSampler.start();\r\n // Get the time to calculate time-elapsed\r\n const now = this.now();\r\n let elapsed = now - this._lastTime || 1; // first frame\r\n\r\n // Constrain fps\r\n const fpsInterval = (1000 / this._maxFps);\r\n\r\n // only run frame if enough time has elapsed\r\n if (elapsed >= fpsInterval) {\r\n let leftover = 0;\r\n if (fpsInterval !== 0) {\r\n leftover = (elapsed % fpsInterval);\r\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\r\n }\r\n\r\n // Resolves issue #138 if the game has been paused, or blurred for\r\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\r\n // and provides more expected behavior when the engine comes back\r\n // into focus\r\n if (elapsed > 200) {\r\n elapsed = 1;\r\n }\r\n\r\n // tick the mainloop and run scheduled callbacks\r\n this._elapsed = overrideUpdateMs || elapsed;\r\n this._totalElapsed += this._elapsed;\r\n this._runScheduledCbs();\r\n this.tick(overrideUpdateMs || elapsed);\r\n\r\n if (fpsInterval !== 0) {\r\n this._lastTime = now - leftover;\r\n } else {\r\n this._lastTime = now;\r\n }\r\n this.fpsSampler.end();\r\n }\r\n } catch (e) {\r\n this._onFatalException(e);\r\n this.stop();\r\n }\r\n }\r\n\r\n /**\r\n * Returns if the clock is currently running\r\n */\r\n public abstract isRunning(): boolean;\r\n\r\n /**\r\n * Start the clock, it will then periodically call the tick(elapsedMilliseconds) since the last tick\r\n */\r\n public abstract start(): void;\r\n\r\n /**\r\n * Stop the clock, tick() is no longer called\r\n */\r\n public abstract stop(): void;\r\n}\r\n\r\n\r\n/**\r\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\r\n */\r\nexport class StandardClock extends Clock {\r\n\r\n private _running = false;\r\n private _requestId: number;\r\n constructor(options: ClockOptions) {\r\n super(options);\r\n }\r\n\r\n public isRunning(): boolean {\r\n return this._running;\r\n }\r\n\r\n public start(): void {\r\n if (this._running) {\r\n return;\r\n }\r\n this._running = true;\r\n const mainloop = () => {\r\n // stop the loop\r\n if (!this._running) {\r\n return;\r\n }\r\n try {\r\n // request next loop\r\n this._requestId = window.requestAnimationFrame(mainloop);\r\n this.update();\r\n } catch (e) {\r\n window.cancelAnimationFrame(this._requestId);\r\n throw e;\r\n }\r\n };\r\n\r\n // begin the first frame\r\n mainloop();\r\n }\r\n\r\n public stop(): void {\r\n window.cancelAnimationFrame(this._requestId);\r\n this._running = false;\r\n }\r\n}\r\n\r\nexport interface TestClockOptions {\r\n /**\r\n * Specify the update milliseconds to use for each manual step()\r\n */\r\n defaultUpdateMs: number;\r\n}\r\n\r\n/**\r\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\r\n */\r\nexport class TestClock extends Clock {\r\n private _logger = Logger.getInstance();\r\n private _updateMs: number;\r\n private _running: boolean = false;\r\n private _currentTime = 0;\r\n constructor(options: ClockOptions & TestClockOptions) {\r\n super({\r\n ...options\r\n });\r\n this._updateMs = options.defaultUpdateMs;\r\n }\r\n\r\n /**\r\n * Get the current time in milliseconds\r\n */\r\n public override now() {\r\n return this._currentTime ?? 0;\r\n }\r\n\r\n public isRunning(): boolean {\r\n return this._running;\r\n }\r\n public start(): void {\r\n this._running = true;\r\n }\r\n public stop(): void {\r\n this._running = false;\r\n }\r\n\r\n /**\r\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\r\n * @param overrideUpdateMs\r\n */\r\n step(overrideUpdateMs?: number): void {\r\n const time = overrideUpdateMs ?? this._updateMs;\r\n\r\n if (this._running) {\r\n // to be comparable to RAF this needs to be a full blown Task\r\n // For example, images cannot decode synchronously in a single step\r\n this.update(time);\r\n this._currentTime += time;\r\n } else {\r\n this._logger.warn('The clock is not running, no step will be performed');\r\n }\r\n }\r\n\r\n /**\r\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\r\n * @param numberOfSteps\r\n * @param overrideUpdateMs\r\n */\r\n run(numberOfSteps: number, overrideUpdateMs?: number): void {\r\n for (let i = 0; i < numberOfSteps; i++) {\r\n this.step(overrideUpdateMs ?? this._updateMs);\r\n }\r\n }\r\n}","import toasterCss from './Toaster.css';\r\n\r\n/**\r\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\r\n */\r\nexport class Toaster {\r\n private _styleBlock: HTMLStyleElement;\r\n private _container: HTMLDivElement;\r\n private _toasterCss: string = toasterCss.toString();\r\n\r\n private _isInitialized = false;\r\n private _initialize() {\r\n if (!this._isInitialized) {\r\n this._container = document.createElement('div');\r\n this._container.id = 'ex-toast-container';\r\n document.body.appendChild(this._container);\r\n this._isInitialized = true;\r\n\r\n this._styleBlock = document.createElement('style');\r\n this._styleBlock.textContent = this._toasterCss;\r\n document.head.appendChild(this._styleBlock);\r\n }\r\n }\r\n\r\n public dispose() {\r\n this._container.parentElement.removeChild(this._container);\r\n\r\n this._styleBlock.parentElement.removeChild(this._styleBlock);\r\n\r\n this._isInitialized = false;\r\n }\r\n\r\n private _createFragment(message: string) {\r\n const toastMessage = document.createElement('span');\r\n toastMessage.innerText = message;\r\n return toastMessage;\r\n }\r\n\r\n /**\r\n * Display a toast message to a player\r\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\r\n * @param linkTarget Optionally specify a link location\r\n * @param linkName Optionally specify a name for that link location\r\n */\r\n public toast(message: string, linkTarget?: string, linkName?: string) {\r\n this._initialize();\r\n const toast = document.createElement('div');\r\n toast.className = 'ex-toast-message';\r\n\r\n const messageFragments: HTMLElement[] = message.split('[LINK]').map(message => this._createFragment(message));\r\n\r\n if (linkTarget) {\r\n const link = document.createElement('a');\r\n link.href = linkTarget;\r\n if (linkName) {\r\n link.innerText = linkName;\r\n } else {\r\n link.innerText = linkTarget;\r\n }\r\n messageFragments.splice(1, 0, link);\r\n }\r\n\r\n // Assembly message\r\n const finalMessage = document.createElement('div');\r\n messageFragments.forEach(message => {\r\n finalMessage.appendChild(message);\r\n });\r\n toast.appendChild(finalMessage);\r\n\r\n // Dismiss button\r\n const dismissBtn = document.createElement('button');\r\n dismissBtn.innerText = 'x';\r\n dismissBtn.addEventListener('click', () => {\r\n this._container.removeChild(toast);\r\n });\r\n toast.appendChild(dismissBtn);\r\n\r\n // Escape to dismiss\r\n const keydownHandler = (evt: KeyboardEvent) => {\r\n if (evt.key === 'Escape') {\r\n try {\r\n this._container.removeChild(toast);\r\n } catch {\r\n // pass\r\n }\r\n }\r\n document.removeEventListener('keydown', keydownHandler);\r\n };\r\n document.addEventListener('keydown', keydownHandler);\r\n\r\n // Insert into container\r\n const first = this._container.firstChild;\r\n this._container.insertBefore(toast, first);\r\n }\r\n}","import { Engine } from '../Engine';\r\nimport { DefaultLoader, LoaderConstructor, isLoaderConstructor } from './DefaultLoader';\r\nimport { Scene, SceneConstructor, isSceneConstructor } from '../Scene';\r\nimport { Transition } from './Transition';\r\nimport { Loader } from './Loader';\r\nimport { Logger } from '../Util/Log';\r\nimport { ActivateEvent, DeactivateEvent } from '../Events';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport interface DirectorNavigationEvent {\r\n sourceName: string;\r\n sourceScene: Scene;\r\n destinationName: string;\r\n destinationScene: Scene;\r\n}\r\n\r\nexport type DirectorEvents = {\r\n navigationstart: DirectorNavigationEvent,\r\n navigation: DirectorNavigationEvent,\r\n navigationend: DirectorNavigationEvent,\r\n}\r\n\r\nexport const DirectorEvents = {\r\n NavigationStart: 'navigationstart',\r\n Navigation: 'navigation',\r\n NavigationEnd: 'navigationend'\r\n};\r\n\r\nexport interface SceneWithOptions {\r\n /**\r\n * Scene associated with this route\r\n *\r\n * If a constructor is provided it will not be constructed until navigation is requested\r\n */\r\n scene: Scene | SceneConstructor;\r\n /**\r\n * Specify scene transitions\r\n */\r\n transitions?: {\r\n /**\r\n * Optionally specify a transition when going \"in\" to this scene\r\n */\r\n in?: Transition;\r\n /**\r\n * Optionally specify a transition when going \"out\" of this scene\r\n */\r\n out?: Transition;\r\n };\r\n /**\r\n * Optionally specify a loader for the scene\r\n */\r\n loader?: DefaultLoader | LoaderConstructor;\r\n}\r\n\r\nexport type WithRoot = TScenes | 'root';\r\n\r\nexport type SceneMap = Record;\r\n\r\nexport interface StartOptions {\r\n /**\r\n * First transition from the game start screen\r\n */\r\n inTransition: Transition;\r\n /**\r\n * Optionally provide a main loader to run before the game starts\r\n */\r\n loader?: DefaultLoader | LoaderConstructor\r\n}\r\n\r\n\r\n/**\r\n * Provide scene activation data and override any existing configured route transitions or loaders\r\n */\r\nexport interface GoToOptions {\r\n /**\r\n * Optionally supply scene activation data passed to Scene.onActivate\r\n */\r\n sceneActivationData?: TActivationData;\r\n /**\r\n * Optionally supply destination scene \"in\" transition, this will override any previously defined transition\r\n */\r\n destinationIn?: Transition;\r\n /**\r\n * Optionally supply source scene \"out\" transition, this will override any previously defined transition\r\n */\r\n sourceOut?: Transition;\r\n /**\r\n * Optionally supply a different loader for the destination scene, this will override any previously defined loader\r\n */\r\n loader?: DefaultLoader;\r\n}\r\n\r\n/**\r\n * The Director is responsible for managing scenes and changing scenes in Excalibur.\r\n *\r\n * It deals with transitions, scene loaders, switching scenes\r\n *\r\n * This is used internally by Excalibur, generally not mean to\r\n * be instantiated end users directly.\r\n */\r\nexport class Director {\r\n public events = new EventEmitter();\r\n private _logger = Logger.getInstance();\r\n private _deferredGoto: string;\r\n private _deferredTransition: Transition;\r\n private _initialized = false;\r\n\r\n /**\r\n * Current scene's name\r\n */\r\n currentSceneName: string;\r\n /**\r\n * Current scene playing in excalibur\r\n */\r\n currentScene: Scene;\r\n /**\r\n * Current transition if any\r\n */\r\n currentTransition: Transition | null;\r\n\r\n /**\r\n * All registered scenes in Excalibur\r\n */\r\n public readonly scenes: SceneMap> = {} as SceneMap>;\r\n\r\n /**\r\n * Holds all instantiated scenes\r\n */\r\n private _sceneToInstance = new Map();\r\n\r\n startScene: string;\r\n mainLoader: DefaultLoader;\r\n\r\n /**\r\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\r\n */\r\n public readonly rootScene: Scene;\r\n\r\n private _sceneToLoader = new Map();\r\n private _sceneToTransition = new Map();\r\n /**\r\n * Used to keep track of scenes that have already been loaded so we don't load multiple times\r\n */\r\n private _loadedScenes = new Set();\r\n\r\n private _isTransitioning = false;\r\n\r\n /**\r\n * Gets whether the director currently transitioning between scenes\r\n *\r\n * Useful if you need to block behavior during transition\r\n */\r\n public get isTransitioning() {\r\n return this._isTransitioning;\r\n }\r\n\r\n constructor(private _engine: Engine, scenes: SceneMap) {\r\n this.rootScene = this.currentScene = new Scene();\r\n this.add('root', this.rootScene);\r\n this.currentScene = this.rootScene;\r\n this.currentSceneName = 'root';\r\n for (const sceneKey in scenes) {\r\n const sceneOrOptions = scenes[sceneKey];\r\n this.add(sceneKey, sceneOrOptions);\r\n if (sceneKey === 'root') {\r\n this.rootScene = this.getSceneInstance('root');\r\n this.currentScene = this.rootScene;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initialize the director's internal state\r\n */\r\n async onInitialize() {\r\n if (!this._initialized) {\r\n this._initialized = true;\r\n if (this._deferredGoto) {\r\n const deferredScene = this._deferredGoto;\r\n const deferredTransition = this._deferredTransition;\r\n this._deferredGoto = null;\r\n this._deferredTransition = null;\r\n await this.swapScene(deferredScene);\r\n if (deferredTransition) {\r\n await this.playTransition(deferredTransition);\r\n }\r\n } else {\r\n await this.swapScene('root');\r\n }\r\n }\r\n }\r\n\r\n get isInitialized() {\r\n return this._initialized;\r\n }\r\n\r\n /**\r\n * Configures the start scene, and optionally the transition & loader for the director\r\n *\r\n * Typically this is called at the beginning of the game to the start scene and transition and never again.\r\n * @param startScene\r\n * @param options\r\n */\r\n configureStart(startScene: WithRoot, options?: StartOptions) {\r\n const maybeLoaderOrCtor = options?.loader;\r\n if (maybeLoaderOrCtor instanceof DefaultLoader) {\r\n this.mainLoader = maybeLoaderOrCtor;\r\n } else if (isLoaderConstructor(maybeLoaderOrCtor)) {\r\n this.mainLoader = new maybeLoaderOrCtor();\r\n } else {\r\n this.mainLoader = new Loader();\r\n }\r\n\r\n let maybeStartTransition: Transition;\r\n\r\n if (options) {\r\n const { inTransition } = options;\r\n maybeStartTransition = inTransition;\r\n }\r\n\r\n this.startScene = startScene;\r\n\r\n // Fire and forget promise for the initial scene\r\n if (maybeStartTransition) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.swapScene(this.startScene).then(() => {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.playTransition(maybeStartTransition);\r\n });\r\n } else {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.swapScene(this.startScene);\r\n }\r\n\r\n this.currentSceneName = this.startScene;\r\n }\r\n\r\n private _getLoader(sceneName: string) {\r\n return this._sceneToLoader.get(sceneName);\r\n }\r\n\r\n private _getInTransition(sceneName: string): Transition | undefined {\r\n const sceneOrRoute = this.scenes[sceneName as TKnownScenes];\r\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) {\r\n return null;\r\n }\r\n return sceneOrRoute?.transitions?.in;\r\n }\r\n\r\n private _getOutTransition(sceneName: string): Transition | undefined {\r\n const sceneOrRoute = this.scenes[sceneName as TKnownScenes];\r\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) {\r\n return null;\r\n }\r\n return sceneOrRoute?.transitions?.out;\r\n }\r\n\r\n getDeferredScene() {\r\n const maybeDeferred = this.getSceneDefinition(this._deferredGoto);\r\n if (this._deferredGoto && maybeDeferred) {\r\n return maybeDeferred;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns a scene by name if it exists, might be the constructor and not the instance of a scene\r\n * @param name\r\n */\r\n getSceneDefinition(name: string): Scene | SceneConstructor | undefined {\r\n const maybeScene = this.scenes[name as TKnownScenes];\r\n if (maybeScene instanceof Scene || isSceneConstructor(maybeScene)) {\r\n return maybeScene;\r\n } else if (maybeScene) {\r\n return maybeScene.scene;\r\n }\r\n return undefined;\r\n }\r\n\r\n getSceneName(scene: Scene) {\r\n for (const [name, sceneInstance] of this._sceneToInstance) {\r\n if (scene === sceneInstance) {\r\n return name;\r\n }\r\n }\r\n return 'unknown scene name';\r\n }\r\n\r\n /**\r\n * Returns the same Director, but asserts a scene DOES exist to the type system\r\n * @param name\r\n */\r\n assertAdded(name: TScene): Director {\r\n return this as Director;\r\n }\r\n\r\n /**\r\n * Returns the same Director, but asserts a scene DOES NOT exist to the type system\r\n * @param name\r\n */\r\n assertRemoved(name: TScene): Director> {\r\n return this as Director>;\r\n }\r\n\r\n /**\r\n * Adds additional Scenes to the game!\r\n * @param name\r\n * @param sceneOrRoute\r\n */\r\n add(name: TScene, sceneOrRoute: Scene | SceneConstructor | SceneWithOptions): Director {\r\n if (!(sceneOrRoute instanceof Scene) && !(isSceneConstructor(sceneOrRoute))) {\r\n const { loader, transitions } = sceneOrRoute;\r\n const {in: inTransition, out: outTransition } = transitions ?? {};\r\n this._sceneToTransition.set(name, {in: inTransition, out: outTransition});\r\n\r\n if (isLoaderConstructor(loader)) {\r\n this._sceneToLoader.set(name, new loader());\r\n } else {\r\n this._sceneToLoader.set(name, loader);\r\n }\r\n }\r\n\r\n if (this.scenes[name as unknown as TKnownScenes]) {\r\n this._logger.warn('Scene', name, 'already exists overwriting');\r\n }\r\n this.scenes[name as unknown as TKnownScenes] = sceneOrRoute;\r\n return this.assertAdded(name);\r\n }\r\n\r\n remove(scene: Scene): void;\r\n remove(sceneCtor: SceneConstructor): void;\r\n remove(name: WithRoot): void;\r\n remove(nameOrScene: TKnownScenes | Scene | SceneConstructor | string) {\r\n\r\n if (nameOrScene instanceof Scene || isSceneConstructor(nameOrScene)) {\r\n const sceneOrCtor = nameOrScene;\r\n // remove scene\r\n for (const key in this.scenes) {\r\n if (this.scenes.hasOwnProperty(key)) {\r\n const potentialSceneOrOptions = this.scenes[key as TKnownScenes];\r\n let scene: Scene | SceneConstructor;\r\n if (potentialSceneOrOptions instanceof Scene || isSceneConstructor(potentialSceneOrOptions)) {\r\n scene = potentialSceneOrOptions;\r\n } else {\r\n scene = potentialSceneOrOptions.scene;\r\n }\r\n\r\n if (scene === sceneOrCtor) {\r\n if (key === this.currentSceneName) {\r\n throw new Error(`Cannot remove a currently active scene: ${key}`);\r\n }\r\n\r\n this._sceneToTransition.delete(key);\r\n this._sceneToLoader.delete(key);\r\n delete this.scenes[key as TKnownScenes];\r\n }\r\n }\r\n }\r\n }\r\n if (typeof nameOrScene === 'string') {\r\n if (nameOrScene === this.currentSceneName) {\r\n throw new Error(`Cannot remove a currently active scene: ${nameOrScene}`);\r\n }\r\n\r\n // remove scene\r\n this._sceneToTransition.delete(nameOrScene);\r\n this._sceneToLoader.delete(nameOrScene);\r\n delete this.scenes[nameOrScene as TKnownScenes];\r\n }\r\n }\r\n\r\n /**\r\n * Go to a specific scene, and optionally override loaders and transitions\r\n * @param destinationScene\r\n * @param options\r\n */\r\n async goto(destinationScene: TKnownScenes | string, options?: GoToOptions) {\r\n\r\n const maybeDest = this.getSceneInstance(destinationScene);\r\n if (!maybeDest) {\r\n this._logger.warn(`Scene ${destinationScene} does not exist! Check the name, are you sure you added it?`);\r\n return;\r\n }\r\n\r\n const sourceScene = this.currentSceneName;\r\n const engineInputEnabled = this._engine.input?.enabled ?? true;\r\n this._isTransitioning = true;\r\n\r\n const maybeSourceOut = this.getSceneInstance(sourceScene)?.onTransition('out');\r\n const maybeDestinationIn = maybeDest?.onTransition('in');\r\n\r\n options = {\r\n // Engine configuration then dynamic scene transitions\r\n ...{ sourceOut: this._getOutTransition(this.currentSceneName) ?? maybeSourceOut},\r\n ...{ destinationIn: this._getInTransition(destinationScene) ?? maybeDestinationIn},\r\n // Goto options\r\n ...options };\r\n\r\n const { sourceOut, destinationIn, sceneActivationData } = options;\r\n\r\n const outTransition = sourceOut ?? this._getOutTransition(this.currentSceneName);\r\n const inTransition = destinationIn ?? this._getInTransition(destinationScene);\r\n\r\n const hideLoader = outTransition?.hideLoader || inTransition?.hideLoader;\r\n if (hideLoader) {\r\n // Start hidden loader early and take advantage of the transition\r\n // Don't await and block on a hidden loader\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.maybeLoadScene(destinationScene, hideLoader);\r\n }\r\n\r\n this._emitEvent('navigationstart', sourceScene, destinationScene);\r\n\r\n // Run the out transition on the current scene if present\r\n await this.playTransition(outTransition);\r\n\r\n // Run the loader if present\r\n await this.maybeLoadScene(destinationScene, hideLoader);\r\n\r\n // Give incoming transition a chance to grab info from previous\r\n await inTransition?.onPreviousSceneDeactivate(this.currentScene);\r\n\r\n // Swap to the new scene\r\n await this.swapScene(destinationScene, sceneActivationData);\r\n this._emitEvent('navigation', sourceScene, destinationScene);\r\n\r\n // Run the in transition on the new scene if present\r\n await this.playTransition(inTransition);\r\n this._emitEvent('navigationend', sourceScene, destinationScene);\r\n\r\n this._engine.input?.toggleEnabled(engineInputEnabled);\r\n this._isTransitioning = false;\r\n }\r\n\r\n /**\r\n * Retrieves a scene instance by key if it's registered.\r\n *\r\n * This will call any constructors that were given as a definition\r\n * @param scene\r\n */\r\n getSceneInstance(scene: string): Scene | undefined {\r\n const sceneDefinition = this.getSceneDefinition(scene);\r\n if (!sceneDefinition) {\r\n return undefined;\r\n }\r\n if (this._sceneToInstance.has(scene)) {\r\n return this._sceneToInstance.get(scene) as Scene;\r\n }\r\n if (sceneDefinition instanceof Scene) {\r\n this._sceneToInstance.set(scene, sceneDefinition);\r\n return sceneDefinition;\r\n }\r\n const newScene = new sceneDefinition();\r\n this._sceneToInstance.set(scene, newScene);\r\n return newScene;\r\n }\r\n\r\n /**\r\n * Triggers scene loading if has not already been loaded\r\n * @param scene\r\n * @param hideLoader\r\n */\r\n async maybeLoadScene(scene: string, hideLoader = false) {\r\n const loader = this._getLoader(scene) ?? new DefaultLoader();\r\n const sceneToLoad = this.getSceneDefinition(scene);\r\n const sceneToLoadInstance = this.getSceneInstance(scene);\r\n if (sceneToLoad && sceneToLoadInstance && !this._loadedScenes.has(sceneToLoadInstance)) {\r\n sceneToLoadInstance.onPreLoad(loader);\r\n sceneToLoadInstance.events.emit('preload', { loader });\r\n if (hideLoader) {\r\n // Don't await a hidden loader\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this._engine.load(loader, hideLoader);\r\n } else {\r\n await this._engine.load(loader);\r\n }\r\n this._loadedScenes.add(sceneToLoadInstance);\r\n }\r\n }\r\n\r\n /**\r\n * Plays a transition in the current scene\r\n * @param transition\r\n */\r\n async playTransition(transition: Transition) {\r\n if (!this.isInitialized) {\r\n this._deferredTransition = transition;\r\n return;\r\n }\r\n\r\n if (transition) {\r\n this.currentTransition = transition;\r\n const currentScene = this._engine.currentScene;\r\n const sceneInputEnabled = currentScene.input?.enabled ?? true;\r\n\r\n currentScene.input?.toggleEnabled(!transition.blockInput);\r\n this._engine.input?.toggleEnabled(!transition.blockInput);\r\n\r\n await this.currentTransition.play(this._engine);\r\n\r\n currentScene.input?.toggleEnabled(sceneInputEnabled);\r\n }\r\n this.currentTransition?.kill();\r\n this.currentTransition?.reset();\r\n this.currentTransition = null;\r\n }\r\n\r\n /**\r\n * Swaps the current and destination scene after performing required lifecycle events\r\n * @param destinationScene\r\n * @param data\r\n */\r\n async swapScene(destinationScene: string, data?: TData): Promise {\r\n const engine = this._engine;\r\n // if not yet initialized defer goToScene\r\n if (!this.isInitialized) {\r\n this._deferredGoto = destinationScene;\r\n return;\r\n }\r\n\r\n const maybeDest = this.getSceneInstance(destinationScene);\r\n\r\n if (maybeDest) {\r\n const previousScene = this.currentScene;\r\n const nextScene = maybeDest;\r\n\r\n this._logger.debug('Going to scene:', destinationScene);\r\n // only deactivate when initialized\r\n if (this.currentScene.isInitialized) {\r\n const context = { engine, previousScene, nextScene };\r\n await this.currentScene._deactivate(context);\r\n this.currentScene.events.emit('deactivate', new DeactivateEvent(context, this.currentScene));\r\n }\r\n\r\n // wait for the scene to be loaded if needed\r\n const destLoader = this._sceneToLoader.get(destinationScene);\r\n await destLoader?.areResourcesLoaded();\r\n\r\n // set current scene to new one\r\n this.currentScene = nextScene;\r\n this.currentSceneName = destinationScene;\r\n engine.screen.setCurrentCamera(nextScene.camera);\r\n\r\n // initialize the current scene if has not been already\r\n await this.currentScene._initialize(engine);\r\n\r\n const context = { engine, previousScene, nextScene, data };\r\n await this.currentScene._activate(context);\r\n this.currentScene.events.emit('activate', new ActivateEvent(context, this.currentScene));\r\n } else {\r\n this._logger.error('Scene', destinationScene, 'does not exist!');\r\n }\r\n }\r\n\r\n private _emitEvent(eventName: keyof DirectorEvents, sourceScene: string, destinationScene: string) {\r\n const source = this.getSceneDefinition(sourceScene)!;\r\n const dest = this.getSceneDefinition(destinationScene)!;\r\n this.events.emit(eventName, {\r\n sourceScene: source,\r\n sourceName: sourceScene,\r\n destinationScene: dest,\r\n destinationName: destinationScene\r\n } as DirectorNavigationEvent);\r\n }\r\n}\r\n\r\n\r\n","import { EX_VERSION } from './';\r\nimport { Future } from './Util/Future';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { PointerScope } from './Input/PointerScope';\r\nimport { Flags } from './Flags';\r\nimport { polyfill } from './Polyfill';\r\npolyfill();\r\nimport { CanUpdate, CanDraw, CanInitialize } from './Interfaces/LifecycleEvents';\r\nimport { Vector } from './Math/vector';\r\nimport { Screen, DisplayMode, ScreenDimension, Resolution } from './Screen';\r\nimport { ScreenElement } from './ScreenElement';\r\nimport { Actor } from './Actor';\r\nimport { Timer } from './Timer';\r\nimport { TileMap } from './TileMap';\r\nimport { DefaultLoader } from './Director/DefaultLoader';\r\nimport { Loader } from './Director/Loader';\r\nimport { Detector } from './Util/Detector';\r\nimport {\r\n VisibleEvent,\r\n HiddenEvent,\r\n GameStartEvent,\r\n GameStopEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PreFrameEvent,\r\n PostFrameEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n InitializeEvent\r\n} from './Events';\r\nimport { Logger, LogLevel } from './Util/Log';\r\nimport { Color } from './Color';\r\nimport { Scene, SceneConstructor, isSceneConstructor } from './Scene';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { DebugConfig, DebugStats } from './Debug/DebugConfig';\r\nimport { BrowserEvents } from './Util/Browser';\r\nimport {\r\n AntialiasOptions,\r\n DefaultAntialiasOptions,\r\n DefaultPixelArtOptions,\r\n ExcaliburGraphicsContext,\r\n ExcaliburGraphicsContext2DCanvas,\r\n ExcaliburGraphicsContextWebGL,\r\n TextureLoader\r\n} from './Graphics';\r\nimport { Clock, StandardClock } from './Util/Clock';\r\nimport { ImageFiltering } from './Graphics/Filtering';\r\nimport { GraphicsDiagnostics } from './Graphics/GraphicsDiagnostics';\r\nimport { Toaster } from './Util/Toaster';\r\nimport { InputMapper } from './Input/InputMapper';\r\nimport { GoToOptions, SceneMap, Director, StartOptions, SceneWithOptions, WithRoot } from './Director/Director';\r\nimport { InputHost } from './Input/InputHost';\r\nimport { DefaultPhysicsConfig, DeprecatedStaticToConfig, PhysicsConfig } from './Collision/PhysicsConfig';\r\nimport { DeepRequired } from './Util/Required';\r\n\r\nexport type EngineEvents = {\r\n fallbackgraphicscontext: ExcaliburGraphicsContext2DCanvas,\r\n initialize: InitializeEvent,\r\n visible: VisibleEvent,\r\n hidden: HiddenEvent,\r\n start: GameStartEvent,\r\n stop: GameStopEvent,\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n preframe: PreFrameEvent,\r\n postframe: PostFrameEvent,\r\n predraw: PreDrawEvent,\r\n postdraw: PostDrawEvent,\r\n}\r\n\r\nexport const EngineEvents = {\r\n FallbackGraphicsContext: 'fallbackgraphicscontext',\r\n Initialize: 'initialize',\r\n Visible: 'visible',\r\n Hidden: 'hidden',\r\n Start: 'start',\r\n Stop: 'stop',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreFrame: 'preframe',\r\n PostFrame: 'postframe',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw'\r\n} as const;\r\n\r\n\r\n\r\n/**\r\n * Enum representing the different mousewheel event bubble prevention\r\n */\r\nexport enum ScrollPreventionMode {\r\n /**\r\n * Do not prevent any page scrolling\r\n */\r\n None,\r\n /**\r\n * Prevent page scroll if mouse is over the game canvas\r\n */\r\n Canvas,\r\n /**\r\n * Prevent all page scrolling via mouse wheel\r\n */\r\n All\r\n}\r\n\r\n/**\r\n * Defines the available options to configure the Excalibur engine at constructor time.\r\n */\r\nexport interface EngineOptions {\r\n /**\r\n * Optionally configure the width of the viewport in css pixels\r\n */\r\n width?: number;\r\n\r\n /**\r\n * Optionally configure the height of the viewport in css pixels\r\n */\r\n height?: number;\r\n\r\n /**\r\n * Optionally configure the width & height of the viewport in css pixels.\r\n * Use `viewport` instead of [[EngineOptions.width]] and [[EngineOptions.height]], or vice versa.\r\n */\r\n viewport?: ScreenDimension;\r\n\r\n /**\r\n * Optionally specify the size the logical pixel resolution, if not specified it will be width x height.\r\n * See [[Resolution]] for common presets.\r\n */\r\n resolution?: ScreenDimension;\r\n\r\n /**\r\n * Optionally specify antialiasing (smoothing), by default true (smooth pixels)\r\n *\r\n * * `true` - useful for high resolution art work you would like smoothed, this also hints excalibur to load images\r\n * with default blending [[ImageFiltering.Blended]]\r\n *\r\n * * `false` - useful for pixel art style art work you would like sharp, this also hints excalibur to load images\r\n * with default blending [[ImageFiltering.Pixel]]\r\n *\r\n * * [[AntialiasOptions]] Optionally deeply configure the different antialiasing settings, **WARNING** thar be dragons here.\r\n * It is recommended you stick to `true` or `false` unless you understand what you're doing and need to control rendering to\r\n * a high degree.\r\n */\r\n antialiasing?: boolean | AntialiasOptions\r\n\r\n /**\r\n * Quick convenience property to configure Excalibur to use special settings for \"pretty\" anti-aliased pixel art\r\n *\r\n * 1. Turns on special shader condition to blend for pixel art and enables various antialiasing settings,\r\n * notice blending is ON for this special mode.\r\n *\r\n * Equivalent to:\r\n * ```javascript\r\n * antialiasing: {\r\n * pixelArtSampler: true,\r\n * canvasImageRendering: 'auto',\r\n * filtering: ImageFiltering.Blended,\r\n * webglAntialiasing: true\r\n * }\r\n * ```\r\n */\r\n pixelArt?: boolean;\r\n\r\n /**\r\n * Specify any UV padding you want use in pixels, this brings sampling into the texture if you're using\r\n * a sprite sheet in one image to prevent sampling bleed.\r\n *\r\n * Defaults:\r\n * * `antialiasing: false` or `filtering: ImageFiltering.Pixel` - 0.0;\r\n * * `pixelArt: true` - 0.25\r\n * * All else 0.01\r\n */\r\n uvPadding?: number;\r\n\r\n /**\r\n * Optionally hint the graphics context into a specific power profile\r\n *\r\n * Default \"high-performance\"\r\n */\r\n powerPreference?: 'default' | 'high-performance' | 'low-power';\r\n\r\n /**\r\n * Optionally upscale the number of pixels in the canvas. Normally only useful if you need a smoother look to your assets, especially\r\n * [[Text]] or Pixel Art assets.\r\n *\r\n * **WARNING** It is recommended you try using `antialiasing: true` before adjusting pixel ratio. Pixel ratio will consume more memory\r\n * and on mobile may break if the internal size of the canvas exceeds 4k pixels in width or height.\r\n *\r\n * Default is based the display's pixel ratio, for example a HiDPI screen might have the value 2;\r\n */\r\n pixelRatio?: number;\r\n\r\n /**\r\n * Optionally configure the native canvas transparent backdrop\r\n */\r\n enableCanvasTransparency?: boolean;\r\n\r\n /**\r\n * Optionally specify the target canvas DOM element to render the game in\r\n */\r\n canvasElementId?: string;\r\n\r\n /**\r\n * Optionally specify the target canvas DOM element directly\r\n */\r\n canvasElement?: HTMLCanvasElement;\r\n\r\n /**\r\n * Optionally snap graphics to nearest pixel, default is false\r\n */\r\n snapToPixel?: boolean;\r\n\r\n /**\r\n * The [[DisplayMode]] of the game, by default [[DisplayMode.FitScreen]] with aspect ratio 4:3 (800x600).\r\n * Depending on this value, [[width]] and [[height]] may be ignored.\r\n */\r\n displayMode?: DisplayMode;\r\n\r\n /**\r\n * Configures the pointer scope. Pointers scoped to the 'Canvas' can only fire events within the canvas viewport; whereas, 'Document'\r\n * (default) scoped will fire anywhere on the page.\r\n */\r\n pointerScope?: PointerScope;\r\n\r\n /**\r\n * Suppress boot up console message, which contains the \"powered by Excalibur message\"\r\n */\r\n suppressConsoleBootMessage?: boolean;\r\n\r\n /**\r\n * Suppress minimum browser feature detection, it is not recommended users of excalibur switch this off. This feature ensures that\r\n * the currently running browser meets the minimum requirements for running excalibur. This can be useful if running on non-standard\r\n * browsers or if there is a bug in excalibur preventing execution.\r\n */\r\n suppressMinimumBrowserFeatureDetection?: boolean;\r\n\r\n /**\r\n * Suppress HiDPI auto detection and scaling, it is not recommended users of excalibur switch off this feature. This feature detects\r\n * and scales the drawing canvas appropriately to accommodate HiDPI screens.\r\n */\r\n suppressHiDPIScaling?: boolean;\r\n\r\n /**\r\n * Suppress play button, it is not recommended users of excalibur switch this feature. Some browsers require a user gesture (like a click)\r\n * for certain browser features to work like web audio.\r\n */\r\n suppressPlayButton?: boolean;\r\n\r\n /**\r\n * Sets the focus of the window, this is needed when hosting excalibur in a cross-origin iframe in order for certain events\r\n * (like keyboard) to work.\r\n * For example: itch.io or codesandbox.io\r\n *\r\n * By default set to true,\r\n */\r\n grabWindowFocus?: boolean;\r\n\r\n /**\r\n * Scroll prevention method.\r\n */\r\n scrollPreventionMode?: ScrollPreventionMode;\r\n\r\n /**\r\n * Optionally set the background color\r\n */\r\n backgroundColor?: Color;\r\n\r\n /**\r\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\r\n *\r\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\r\n * one that bounces between 30fps and 60fps\r\n */\r\n maxFps?: number;\r\n\r\n /**\r\n * Optionally configure a fixed update fps, this can be desireable if you need the physics simulation to be very stable. When set\r\n * the update step and physics will use the same elapsed time for each tick even if the graphical framerate drops. In order for the\r\n * simulation to be correct, excalibur will run multiple updates in a row (at the configured update elapsed) to catch up, for example\r\n * there could be X updates and 1 draw each clock step.\r\n *\r\n * **NOTE:** This does come at a potential perf cost because each catch-up update will need to be run if the fixed rate is greater than\r\n * the current instantaneous framerate, or perf gain if the fixed rate is less than the current framerate.\r\n *\r\n * By default is unset and updates will use the current instantaneous framerate with 1 update and 1 draw each clock step.\r\n */\r\n fixedUpdateFps?: number\r\n\r\n /**\r\n * Default `true`, optionally configure excalibur to use optimal draw call sorting, to opt out set this to `false`.\r\n *\r\n * Excalibur will automatically sort draw calls by z and priority into renderer batches for maximal draw performance,\r\n * this can disrupt a specific desired painter order.\r\n */\r\n useDrawSorting?: boolean;\r\n\r\n /**\r\n * Optionally configure how excalibur handles poor performance on a player's browser\r\n */\r\n configurePerformanceCanvas2DFallback?: {\r\n /**\r\n * By default `false`, this will switch the internal graphics context to Canvas2D which can improve performance on non hardware\r\n * accelerated browsers.\r\n */\r\n allow: boolean;\r\n /**\r\n * By default `false`, if set to `true` a dialogue will be presented to the player about their browser and how to potentially\r\n * address any issues.\r\n */\r\n showPlayerMessage?: boolean;\r\n /**\r\n * Default `{ numberOfFrames: 100, fps: 20 }`, optionally configure excalibur to fallback to the 2D Canvas renderer\r\n * if bad performance is detected.\r\n *\r\n * In this example of the default if excalibur is running at 20fps or less for 100 frames it will trigger the fallback to the 2D\r\n * Canvas renderer.\r\n */\r\n threshold?: { numberOfFrames: number, fps: number };\r\n },\r\n\r\n /**\r\n * Optionally configure the physics simulation in excalibur\r\n *\r\n * If false, Excalibur will not produce a physics simulation.\r\n *\r\n * Default is configured to use [[SolverStrategy.Arcade]] physics simulation\r\n */\r\n physics?: boolean | PhysicsConfig\r\n\r\n /**\r\n * Optionally specify scenes with their transitions and loaders to excalibur's scene [[Director]]\r\n *\r\n * Scene transitions can can overridden dynamically by the `Scene` or by the call to `.goToScene`\r\n */\r\n scenes?: SceneMap\r\n}\r\n\r\n/**\r\n * The Excalibur Engine\r\n *\r\n * The [[Engine]] is the main driver for a game. It is responsible for\r\n * starting/stopping the game, maintaining state, transmitting events,\r\n * loading resources, and managing the scene.\r\n */\r\nexport class Engine implements CanInitialize, CanUpdate, CanDraw {\r\n /**\r\n * Current Excalibur version string\r\n *\r\n * Useful for plugins or other tools that need to know what features are available\r\n */\r\n public readonly version = EX_VERSION;\r\n\r\n /**\r\n * Listen to and emit events on the Engine\r\n */\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Excalibur browser events abstraction used for wiring to native browser events safely\r\n */\r\n public browser: BrowserEvents;\r\n\r\n /**\r\n * Screen abstraction\r\n */\r\n public screen: Screen;\r\n\r\n /**\r\n * Scene director, manages all scenes, scene transitions, and loaders in excalibur\r\n */\r\n public director: Director;\r\n\r\n /**\r\n * Direct access to the engine's canvas element\r\n */\r\n public canvas: HTMLCanvasElement;\r\n\r\n /**\r\n * Direct access to the ExcaliburGraphicsContext used for drawing things to the screen\r\n */\r\n public graphicsContext: ExcaliburGraphicsContext;\r\n\r\n /**\r\n * Direct access to the canvas element ID, if an ID exists\r\n */\r\n public canvasElementId: string;\r\n\r\n /**\r\n * Direct access to the physics configuration for excalibur\r\n */\r\n public physics: DeepRequired;\r\n\r\n /**\r\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\r\n *\r\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\r\n * one that bounces between 30fps and 60fps\r\n */\r\n public maxFps: number = Number.POSITIVE_INFINITY;\r\n\r\n /**\r\n * Optionally configure a fixed update fps, this can be desireable if you need the physics simulation to be very stable. When set\r\n * the update step and physics will use the same elapsed time for each tick even if the graphical framerate drops. In order for the\r\n * simulation to be correct, excalibur will run multiple updates in a row (at the configured update elapsed) to catch up, for example\r\n * there could be X updates and 1 draw each clock step.\r\n *\r\n * **NOTE:** This does come at a potential perf cost because each catch-up update will need to be run if the fixed rate is greater than\r\n * the current instantaneous framerate, or perf gain if the fixed rate is less than the current framerate.\r\n *\r\n * By default is unset and updates will use the current instantaneous framerate with 1 update and 1 draw each clock step.\r\n */\r\n public fixedUpdateFps?: number;\r\n\r\n /**\r\n * Direct access to the excalibur clock\r\n */\r\n public clock: Clock;\r\n\r\n public readonly pointerScope: PointerScope;\r\n public readonly grabWindowFocus: boolean;\r\n\r\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */\r\n public get canvasWidth(): number {\r\n return this.screen.canvasWidth;\r\n }\r\n\r\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */\r\n public get halfCanvasWidth(): number {\r\n return this.screen.halfCanvasWidth;\r\n }\r\n\r\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */\r\n public get canvasHeight(): number {\r\n return this.screen.canvasHeight;\r\n }\r\n\r\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */\r\n public get halfCanvasHeight(): number {\r\n return this.screen.halfCanvasHeight;\r\n }\r\n\r\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawWidth(): number {\r\n return this.screen.drawWidth;\r\n }\r\n\r\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawWidth(): number {\r\n return this.screen.halfDrawWidth;\r\n }\r\n\r\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawHeight(): number {\r\n return this.screen.drawHeight;\r\n }\r\n\r\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawHeight(): number {\r\n return this.screen.halfDrawHeight;\r\n }\r\n\r\n /**\r\n * Returns whether excalibur detects the current screen to be HiDPI\r\n */\r\n public get isHiDpi(): boolean {\r\n return this.screen.isHiDpi;\r\n }\r\n\r\n /**\r\n * Access engine input like pointer, keyboard, or gamepad\r\n */\r\n public input: InputHost;\r\n\r\n /**\r\n * Map multiple input sources to specific game actions actions\r\n */\r\n public inputMapper: InputMapper;\r\n\r\n private _inputEnabled: boolean = true;\r\n\r\n /**\r\n * Access Excalibur debugging functionality.\r\n *\r\n * Useful when you want to debug different aspects of built in engine features like\r\n * * Transform\r\n * * Graphics\r\n * * Colliders\r\n */\r\n public debug: DebugConfig;\r\n\r\n /**\r\n * Access [[stats]] that holds frame statistics.\r\n */\r\n public get stats(): DebugStats {\r\n return this.debug.stats;\r\n }\r\n\r\n /**\r\n * The current [[Scene]] being drawn and updated on screen\r\n */\r\n public get currentScene(): Scene {\r\n return this.director.currentScene;\r\n }\r\n\r\n\r\n /**\r\n * The current [[Scene]] being drawn and updated on screen\r\n */\r\n public get currentSceneName(): string {\r\n return this.director.currentSceneName;\r\n }\r\n\r\n /**\r\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\r\n */\r\n public get rootScene(): Scene {\r\n return this.director.rootScene;\r\n }\r\n\r\n /**\r\n * Contains all the scenes currently registered with Excalibur\r\n */\r\n public get scenes(): { [key: string]: Scene | SceneConstructor | SceneWithOptions } {\r\n return this.director.scenes;\r\n };\r\n\r\n /**\r\n * Indicates whether the engine is set to fullscreen or not\r\n */\r\n public get isFullscreen(): boolean {\r\n return this.screen.isFullScreen;\r\n }\r\n\r\n /**\r\n * Indicates the current [[DisplayMode]] of the engine.\r\n */\r\n public get displayMode(): DisplayMode {\r\n return this.screen.displayMode;\r\n }\r\n\r\n private _suppressPlayButton: boolean = false;\r\n /**\r\n * Returns the calculated pixel ration for use in rendering\r\n */\r\n public get pixelRatio(): number {\r\n return this.screen.pixelRatio;\r\n }\r\n\r\n /**\r\n * Indicates whether audio should be paused when the game is no longer visible.\r\n */\r\n public pauseAudioWhenHidden: boolean = true;\r\n\r\n /**\r\n * Indicates whether the engine should draw with debug information\r\n */\r\n private _isDebug: boolean = false;\r\n public get isDebug(): boolean {\r\n return this._isDebug;\r\n }\r\n\r\n /**\r\n * Sets the background color for the engine.\r\n */\r\n public backgroundColor: Color;\r\n\r\n /**\r\n * Sets the Transparency for the engine.\r\n */\r\n public enableCanvasTransparency: boolean = true;\r\n\r\n /**\r\n * Hints the graphics context to truncate fractional world space coordinates\r\n */\r\n public get snapToPixel(): boolean {\r\n return this.graphicsContext.snapToPixel;\r\n };\r\n\r\n public set snapToPixel(shouldSnapToPixel: boolean) {\r\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\r\n };\r\n\r\n /**\r\n * The action to take when a fatal exception is thrown\r\n */\r\n public onFatalException = (e: any) => {\r\n Logger.getInstance().fatal(e, e.stack);\r\n };\r\n\r\n /**\r\n * The mouse wheel scroll prevention mode\r\n */\r\n public pageScrollPreventionMode: ScrollPreventionMode;\r\n\r\n private _logger: Logger;\r\n\r\n private _toaster: Toaster = new Toaster();\r\n\r\n // this determines whether excalibur is compatible with your browser\r\n private _compatible: boolean;\r\n\r\n private _timescale: number = 1.0;\r\n\r\n // loading\r\n private _loader: DefaultLoader;\r\n\r\n private _isInitialized: boolean = false;\r\n\r\n public emit>(eventName: TEventName, event: EngineEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Default [[EngineOptions]]\r\n */\r\n private static _DEFAULT_ENGINE_OPTIONS: EngineOptions = {\r\n width: 0,\r\n height: 0,\r\n enableCanvasTransparency: true,\r\n useDrawSorting: true,\r\n configurePerformanceCanvas2DFallback: {\r\n allow: false,\r\n showPlayerMessage: false,\r\n threshold: { fps: 20, numberOfFrames: 100 }\r\n },\r\n canvasElementId: '',\r\n canvasElement: undefined,\r\n snapToPixel: false,\r\n antialiasing: true,\r\n pixelArt: false,\r\n powerPreference: 'high-performance',\r\n pointerScope: PointerScope.Canvas,\r\n suppressConsoleBootMessage: null,\r\n suppressMinimumBrowserFeatureDetection: null,\r\n suppressHiDPIScaling: null,\r\n suppressPlayButton: null,\r\n grabWindowFocus: true,\r\n scrollPreventionMode: ScrollPreventionMode.Canvas,\r\n backgroundColor: Color.fromHex('#2185d0') // Excalibur blue\r\n };\r\n\r\n private _originalOptions: EngineOptions = {};\r\n public readonly _originalDisplayMode: DisplayMode;\r\n\r\n /**\r\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\r\n * the game will be rendered full screen (taking up all available browser window space).\r\n * You can customize the game rendering through [[EngineOptions]].\r\n *\r\n * Example:\r\n *\r\n * ```js\r\n * var game = new ex.Engine({\r\n * width: 0, // the width of the canvas\r\n * height: 0, // the height of the canvas\r\n * enableCanvasTransparency: true, // the transparencySection of the canvas\r\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\r\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\r\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\r\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\r\n * });\r\n *\r\n * // call game.start, which is a Promise\r\n * game.start().then(function () {\r\n * // ready, set, go!\r\n * });\r\n * ```\r\n */\r\n constructor(options?: EngineOptions) {\r\n options = { ...Engine._DEFAULT_ENGINE_OPTIONS, ...options };\r\n this._originalOptions = options;\r\n\r\n Flags.freeze();\r\n\r\n // Initialize browser events facade\r\n this.browser = new BrowserEvents(window, document);\r\n\r\n // Check compatibility\r\n const detector = new Detector();\r\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\r\n const message = document.createElement('div');\r\n message.innerText = 'Sorry, your browser does not support all the features needed for Excalibur';\r\n document.body.appendChild(message);\r\n\r\n detector.failedTests.forEach(function (test) {\r\n const testMessage = document.createElement('div');\r\n testMessage.innerText = 'Browser feature missing ' + test;\r\n document.body.appendChild(testMessage);\r\n });\r\n\r\n if (options.canvasElementId) {\r\n const canvas = document.getElementById(options.canvasElementId);\r\n if (canvas) {\r\n canvas.parentElement.removeChild(canvas);\r\n }\r\n }\r\n\r\n return;\r\n } else {\r\n this._compatible = true;\r\n }\r\n\r\n // Use native console API for color fun\r\n // eslint-disable-next-line no-console\r\n if (console.log && !options.suppressConsoleBootMessage) {\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `%cPowered by Excalibur.js (v${EX_VERSION})`,\r\n 'background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;'\r\n );\r\n // eslint-disable-next-line no-console\r\n console.log('\\n\\\r\n /| ________________\\n\\\r\nO|===|* >________________>\\n\\\r\n \\\\|');\r\n // eslint-disable-next-line no-console\r\n console.log('Visit', 'http://excaliburjs.com', 'for more information');\r\n }\r\n\r\n // Suppress play button\r\n if (options.suppressPlayButton) {\r\n this._suppressPlayButton = true;\r\n }\r\n\r\n this._logger = Logger.getInstance();\r\n\r\n // If debug is enabled, let's log browser features to the console.\r\n if (this._logger.defaultLevel === LogLevel.Debug) {\r\n detector.logBrowserFeatures();\r\n }\r\n\r\n this._logger.debug('Building engine...');\r\n\r\n this.canvasElementId = options.canvasElementId;\r\n\r\n if (options.canvasElementId) {\r\n this._logger.debug('Using Canvas element specified: ' + options.canvasElementId);\r\n\r\n //test for existence of element\r\n if (document.getElementById(options.canvasElementId) === null) {\r\n throw new Error('Cannot find existing element in the DOM, please ensure element is created prior to engine creation.');\r\n }\r\n\r\n this.canvas = document.getElementById(options.canvasElementId);\r\n } else if (options.canvasElement) {\r\n this._logger.debug('Using Canvas element specified:', options.canvasElement);\r\n this.canvas = options.canvasElement;\r\n } else {\r\n this._logger.debug('Using generated canvas element');\r\n this.canvas = document.createElement('canvas');\r\n }\r\n\r\n let displayMode = options.displayMode ?? DisplayMode.Fixed;\r\n if ((options.width && options.height) || options.viewport) {\r\n if (options.displayMode === undefined) {\r\n displayMode = DisplayMode.Fixed;\r\n }\r\n this._logger.debug('Engine viewport is size ' + options.width + ' x ' + options.height);\r\n } else if (!options.displayMode) {\r\n this._logger.debug('Engine viewport is fit');\r\n displayMode = DisplayMode.FitScreen;\r\n }\r\n\r\n this._originalDisplayMode = displayMode;\r\n\r\n let pixelArtSampler: boolean;\r\n let uvPadding: number;\r\n let nativeContextAntialiasing: boolean;\r\n let canvasImageRendering: 'pixelated' | 'auto';\r\n let filtering: ImageFiltering;\r\n let multiSampleAntialiasing: boolean | { samples: number };\r\n if (typeof options.antialiasing === 'object') {\r\n ({\r\n pixelArtSampler,\r\n nativeContextAntialiasing,\r\n multiSampleAntialiasing,\r\n filtering,\r\n canvasImageRendering\r\n } = {\r\n ...(options.pixelArt ? DefaultPixelArtOptions : DefaultAntialiasOptions),\r\n ...options.antialiasing\r\n });\r\n\r\n } else {\r\n pixelArtSampler = !!options.pixelArt;\r\n nativeContextAntialiasing = false;\r\n multiSampleAntialiasing = options.antialiasing;\r\n canvasImageRendering = options.antialiasing ? 'auto' : 'pixelated';\r\n filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\r\n }\r\n\r\n if (nativeContextAntialiasing && multiSampleAntialiasing) {\r\n this._logger.warnOnce(`Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing` +\r\n ` at the same time, they are incompatible settings. If you aren\\'t sure use multiSampleAntialiasing`);\r\n }\r\n\r\n if (options.pixelArt) {\r\n uvPadding = .25;\r\n }\r\n\r\n if (!options.antialiasing || filtering === ImageFiltering.Pixel) {\r\n uvPadding = 0;\r\n }\r\n\r\n // Override with any user option, if non default to .25 for pixel art, 0.01 for everything else\r\n uvPadding = options.uvPadding ?? uvPadding ?? 0.01;\r\n\r\n // Canvas 2D fallback can be flagged on\r\n let useCanvasGraphicsContext = Flags.isEnabled('use-canvas-context');\r\n if (!useCanvasGraphicsContext) {\r\n // Attempt webgl first\r\n try {\r\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n pixelArtSampler: pixelArtSampler,\r\n antialiasing: nativeContextAntialiasing,\r\n multiSampleAntialiasing: multiSampleAntialiasing,\r\n uvPadding: uvPadding,\r\n powerPreference: options.powerPreference,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n } catch (e) {\r\n this._logger.warn(\r\n `Excalibur could not load webgl for some reason (${(e as Error).message}) and loaded a Canvas 2D fallback. ` +\r\n `Some features of Excalibur will not work in this mode. \\n\\n` +\r\n 'Read more about this issue at https://excaliburjs.com/docs/webgl'\r\n );\r\n // fallback to canvas in case of failure\r\n useCanvasGraphicsContext = true;\r\n }\r\n }\r\n\r\n if (useCanvasGraphicsContext) {\r\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n antialiasing: nativeContextAntialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n }\r\n\r\n this.screen = new Screen({\r\n canvas: this.canvas,\r\n context: this.graphicsContext,\r\n antialiasing: nativeContextAntialiasing,\r\n canvasImageRendering: canvasImageRendering,\r\n browser: this.browser,\r\n viewport: options.viewport ?? (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\r\n resolution: options.resolution,\r\n displayMode,\r\n pixelRatio: options.suppressHiDPIScaling ? 1 : (options.pixelRatio ?? null)\r\n });\r\n\r\n // TODO REMOVE STATIC!!!\r\n // Set default filtering based on antialiasing\r\n TextureLoader.filtering = filtering;\r\n\r\n if (options.backgroundColor) {\r\n this.backgroundColor = options.backgroundColor.clone();\r\n }\r\n\r\n this.grabWindowFocus = options.grabWindowFocus;\r\n this.pointerScope = options.pointerScope;\r\n\r\n this.maxFps = options.maxFps ?? this.maxFps;\r\n this.fixedUpdateFps = options.fixedUpdateFps ?? this.fixedUpdateFps;\r\n\r\n this.clock = new StandardClock({\r\n maxFps: this.maxFps,\r\n tick: this._mainloop.bind(this),\r\n onFatalException: (e) => this.onFatalException(e)\r\n });\r\n\r\n this.enableCanvasTransparency = options.enableCanvasTransparency;\r\n\r\n if (typeof options.physics === 'boolean') {\r\n this.physics = {\r\n ...DefaultPhysicsConfig,\r\n ...DeprecatedStaticToConfig(),\r\n enabled: options.physics\r\n };\r\n } else {\r\n this.physics = {\r\n ...DefaultPhysicsConfig,\r\n ...DeprecatedStaticToConfig(),\r\n ...options.physics as DeepRequired\r\n };\r\n }\r\n\r\n this.debug = new DebugConfig(this);\r\n\r\n this.director = new Director(this, options.scenes);\r\n\r\n this._initialize(options);\r\n\r\n (window as any).___EXCALIBUR_DEVTOOL = this;\r\n }\r\n\r\n private _performanceThresholdTriggered = false;\r\n private _fpsSamples: number[] = [];\r\n private _monitorPerformanceThresholdAndTriggerFallback() {\r\n const { allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\r\n let { threshold, showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\r\n if (threshold === undefined) {\r\n threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\r\n }\r\n if (showPlayerMessage === undefined) {\r\n showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\r\n }\r\n if (!Flags.isEnabled('use-canvas-context') && allow && this.ready && !this._performanceThresholdTriggered) {\r\n // Calculate Average fps for last X number of frames after start\r\n if (this._fpsSamples.length === threshold.numberOfFrames) {\r\n this._fpsSamples.splice(0, 1);\r\n }\r\n this._fpsSamples.push(this.clock.fpsSampler.fps);\r\n let total = 0;\r\n for (let i = 0; i < this._fpsSamples.length; i++) {\r\n total += this._fpsSamples[i];\r\n }\r\n const average = total / this._fpsSamples.length;\r\n\r\n if (this._fpsSamples.length === threshold.numberOfFrames) {\r\n if (average <= threshold.fps) {\r\n this._performanceThresholdTriggered = true;\r\n this._logger.warn(\r\n `Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` +\r\n 'this might mean your browser doesn\\'t have webgl enabled or hardware acceleration is unavailable.\\n\\n' +\r\n 'If in Chrome:\\n' +\r\n ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n'+\r\n ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' +\r\n 'If in Firefox, visit about:config\\n' +\r\n ' * Ensure webgl.disabled = false\\n' +\r\n ' * Ensure webgl.force-enabled = true\\n' +\r\n ' * Ensure layers.acceleration.force-enabled = true\\n\\n' +\r\n 'Read more about this issue at https://excaliburjs.com/docs/performance'\r\n );\r\n\r\n if (showPlayerMessage) {\r\n this._toaster.toast(\r\n 'Excalibur is encountering performance issues. '+\r\n 'It\\'s possible that your browser doesn\\'t have hardware acceleration enabled. ' +\r\n 'Visit [LINK] for more information and potential solutions.',\r\n 'https://excaliburjs.com/docs/performance'\r\n );\r\n }\r\n this.useCanvas2DFallback();\r\n this.emit('fallbackgraphicscontext', this.graphicsContext);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Switches the engine's graphics context to the 2D Canvas.\r\n * @warning Some features of Excalibur will not work in this mode.\r\n */\r\n public useCanvas2DFallback() {\r\n // Swap out the canvas\r\n const newCanvas = this.canvas.cloneNode(false) as HTMLCanvasElement;\r\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\r\n this.canvas = newCanvas;\r\n\r\n const options = { ...this._originalOptions, antialiasing: this.getAntialiasing() };\r\n const displayMode = this._originalDisplayMode;\r\n\r\n // New graphics context\r\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n antialiasing: options.antialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n\r\n // Reset screen\r\n if (this.screen) {\r\n this.screen.dispose();\r\n }\r\n\r\n this.screen = new Screen({\r\n canvas: this.canvas,\r\n context: this.graphicsContext,\r\n antialiasing: options.antialiasing ?? true,\r\n browser: this.browser,\r\n viewport: options.viewport ?? (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\r\n resolution: options.resolution,\r\n displayMode,\r\n pixelRatio: options.suppressHiDPIScaling ? 1 : (options.pixelRatio ?? null)\r\n });\r\n this.screen.setCurrentCamera(this.currentScene.camera);\r\n\r\n // Reset pointers\r\n this.input.pointers.detach();\r\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\r\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\r\n this.input.pointers.init();\r\n }\r\n\r\n private _disposed = false;\r\n /**\r\n * Attempts to completely clean up excalibur resources, including removing the canvas from the dom.\r\n *\r\n * To start again you will need to new up an Engine.\r\n */\r\n public dispose() {\r\n if (!this._disposed) {\r\n this._disposed = true;\r\n this.stop();\r\n this.input.toggleEnabled(false);\r\n this.canvas.parentNode.removeChild(this.canvas);\r\n this.canvas = null;\r\n this.screen.dispose();\r\n this.graphicsContext.dispose();\r\n this.graphicsContext = null;\r\n }\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n */\r\n public getWorldBounds() {\r\n return this.screen.getWorldBounds();\r\n }\r\n\r\n /**\r\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\r\n */\r\n public get timescale() {\r\n return this._timescale;\r\n }\r\n\r\n /**\r\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\r\n * when using time-based movement.\r\n */\r\n public set timescale(value: number) {\r\n if (value <= 0) {\r\n Logger.getInstance().error('Cannot set engine.timescale to a value of 0 or less than 0.');\r\n return;\r\n }\r\n\r\n this._timescale = value;\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the [[currentScene]].\r\n * @param timer The timer to add to the [[currentScene]].\r\n */\r\n public addTimer(timer: Timer): Timer {\r\n return this.currentScene.addTimer(timer);\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the [[currentScene]].\r\n * @param timer The timer to remove to the [[currentScene]].\r\n */\r\n public removeTimer(timer: Timer): Timer {\r\n return this.currentScene.removeTimer(timer);\r\n }\r\n\r\n /**\r\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\r\n * would levels or menus.\r\n * @param key The name of the scene, must be unique\r\n * @param scene The scene to add to the engine\r\n */\r\n public addScene(key: TScene, scene: Scene | SceneConstructor | SceneWithOptions): Engine {\r\n this.director.add(key, scene);\r\n return this as Engine;\r\n }\r\n\r\n /**\r\n * Removes a [[Scene]] instance from the engine\r\n * @param scene The scene to remove\r\n */\r\n public removeScene(scene: Scene | SceneConstructor): void;\r\n /**\r\n * Removes a scene from the engine by key\r\n * @param key The scene key to remove\r\n */\r\n public removeScene(key: string): void;\r\n /**\r\n * @internal\r\n */\r\n public removeScene(entity: any): void {\r\n this.director.remove(entity);\r\n }\r\n\r\n /**\r\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\r\n * would levels or menus.\r\n * @param sceneKey The key of the scene, must be unique\r\n * @param scene The scene to add to the engine\r\n */\r\n public add(sceneKey: string, scene: Scene | SceneConstructor | SceneWithOptions): void;\r\n /**\r\n * Adds a [[Timer]] to the [[currentScene]].\r\n * @param timer The timer to add to the [[currentScene]].\r\n */\r\n public add(timer: Timer): void;\r\n /**\r\n * Adds a [[TileMap]] to the [[currentScene]], once this is done the TileMap\r\n * will be drawn and updated.\r\n */\r\n public add(tileMap: TileMap): void;\r\n /**\r\n * Adds an actor to the [[currentScene]] of the game. This is synonymous\r\n * to calling `engine.currentScene.add(actor)`.\r\n *\r\n * Actors can only be drawn if they are a member of a scene, and only\r\n * the [[currentScene]] may be drawn or updated.\r\n * @param actor The actor to add to the [[currentScene]]\r\n */\r\n public add(actor: Actor): void;\r\n\r\n public add(entity: Entity): void;\r\n\r\n /**\r\n * Adds a [[ScreenElement]] to the [[currentScene]] of the game,\r\n * ScreenElements do not participate in collisions, instead the\r\n * remain in the same place on the screen.\r\n * @param screenElement The ScreenElement to add to the [[currentScene]]\r\n */\r\n public add(screenElement: ScreenElement): void;\r\n public add(entity: any): void {\r\n if (arguments.length === 2) {\r\n this.director.add(arguments[0], arguments[1]);\r\n return;\r\n }\r\n const maybeDeferred = this.director.getDeferredScene();\r\n if (maybeDeferred instanceof Scene) {\r\n maybeDeferred.add(entity);\r\n } else {\r\n this.currentScene.add(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Removes a scene instance from the engine\r\n * @param scene The scene to remove\r\n */\r\n public remove(scene: Scene | SceneConstructor): void;\r\n /**\r\n * Removes a scene from the engine by key\r\n * @param sceneKey The scene to remove\r\n */\r\n public remove(sceneKey: string): void;\r\n /**\r\n * Removes a [[Timer]] from the [[currentScene]].\r\n * @param timer The timer to remove to the [[currentScene]].\r\n */\r\n public remove(timer: Timer): void;\r\n /**\r\n * Removes a [[TileMap]] from the [[currentScene]], it will no longer be drawn or updated.\r\n */\r\n public remove(tileMap: TileMap): void;\r\n /**\r\n * Removes an actor from the [[currentScene]] of the game. This is synonymous\r\n * to calling `engine.currentScene.removeChild(actor)`.\r\n * Actors that are removed from a scene will no longer be drawn or updated.\r\n * @param actor The actor to remove from the [[currentScene]].\r\n */\r\n public remove(actor: Actor): void;\r\n /**\r\n * Removes a [[ScreenElement]] to the scene, it will no longer be drawn or updated\r\n * @param screenElement The ScreenElement to remove from the [[currentScene]]\r\n */\r\n public remove(screenElement: ScreenElement): void;\r\n public remove(entity: any): void {\r\n if (entity instanceof Entity) {\r\n this.currentScene.remove(entity);\r\n }\r\n\r\n if (entity instanceof Scene || isSceneConstructor(entity)) {\r\n this.removeScene(entity);\r\n }\r\n\r\n if (typeof entity === 'string') {\r\n this.removeScene(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Changes the current scene with optionally supplied:\r\n * * Activation data\r\n * * Transitions\r\n * * Loaders\r\n *\r\n * Example:\r\n * ```typescript\r\n * game.goToScene('myScene', {\r\n * sceneActivationData: {any: 'thing at all'},\r\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\r\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\r\n * loader: MyLoader\r\n * });\r\n * ```\r\n *\r\n * Scenes are defined in the Engine constructor\r\n * ```typescript\r\n * const engine = new ex.Engine({\r\n scenes: {...}\r\n });\r\n * ```\r\n * Or by adding dynamically\r\n *\r\n * ```typescript\r\n * engine.addScene('myScene', new ex.Scene());\r\n * ```\r\n * @param destinationScene\r\n * @param options\r\n * @deprecated use goToScene, it now behaves the same as goto\r\n */\r\n public async goto(destinationScene: WithRoot, options?: GoToOptions) {\r\n await this.director.goto(destinationScene, options);\r\n }\r\n\r\n /**\r\n * Changes the current scene with optionally supplied:\r\n * * Activation data\r\n * * Transitions\r\n * * Loaders\r\n *\r\n * Example:\r\n * ```typescript\r\n * game.goToScene('myScene', {\r\n * sceneActivationData: {any: 'thing at all'},\r\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\r\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\r\n * loader: MyLoader\r\n * });\r\n * ```\r\n *\r\n * Scenes are defined in the Engine constructor\r\n * ```typescript\r\n * const engine = new ex.Engine({\r\n scenes: {...}\r\n });\r\n * ```\r\n * Or by adding dynamically\r\n *\r\n * ```typescript\r\n * engine.addScene('myScene', new ex.Scene());\r\n * ```\r\n * @param destinationScene\r\n * @param options\r\n */\r\n public async goToScene(destinationScene: WithRoot, options?: GoToOptions): Promise {\r\n await this.director.goto(destinationScene, options);\r\n }\r\n\r\n /**\r\n * Transforms the current x, y from screen coordinates to world coordinates\r\n * @param point Screen coordinate to convert\r\n */\r\n public screenToWorldCoordinates(point: Vector): Vector {\r\n return this.screen.screenToWorldCoordinates(point);\r\n }\r\n\r\n /**\r\n * Transforms a world coordinate, to a screen coordinate\r\n * @param point World coordinate to convert\r\n */\r\n public worldToScreenCoordinates(point: Vector): Vector {\r\n return this.screen.worldToScreenCoordinates(point);\r\n }\r\n\r\n /**\r\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\r\n */\r\n private _initialize(options?: EngineOptions) {\r\n this.pageScrollPreventionMode = options.scrollPreventionMode;\r\n\r\n // initialize inputs\r\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\r\n const grabWindowFocus = this._originalOptions?.grabWindowFocus ?? true;\r\n this.input = new InputHost({\r\n pointerTarget,\r\n grabWindowFocus,\r\n engine: this\r\n });\r\n this.inputMapper = this.input.inputMapper;\r\n\r\n // Issue #385 make use of the visibility api\r\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\r\n\r\n this.browser.document.on('visibilitychange', () => {\r\n if (document.visibilityState === 'hidden') {\r\n this.events.emit('hidden', new HiddenEvent(this));\r\n this._logger.debug('Window hidden');\r\n } else if (document.visibilityState === 'visible') {\r\n this.events.emit('visible', new VisibleEvent(this));\r\n this._logger.debug('Window visible');\r\n }\r\n });\r\n\r\n if (!this.canvasElementId && !options.canvasElement) {\r\n document.body.appendChild(this.canvas);\r\n }\r\n }\r\n\r\n public toggleInputEnabled(enabled: boolean) {\r\n this._inputEnabled = enabled;\r\n this.input.toggleEnabled(this._inputEnabled);\r\n }\r\n\r\n public onInitialize(engine: Engine) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * If supported by the browser, this will set the antialiasing flag on the\r\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\r\n * image resources.\r\n * @param isSmooth Set smoothing to true or false\r\n * @deprecated Set in engine constructor, will be removed in v0.30\r\n */\r\n public setAntialiasing(isSmooth: boolean) {\r\n this.screen.antialiasing = isSmooth;\r\n }\r\n\r\n /**\r\n * Return the current smoothing status of the canvas\r\n * @deprecated Set in engine constructor, will be removed in v0.30\r\n */\r\n public getAntialiasing(): boolean {\r\n return this.screen.antialiasing;\r\n }\r\n\r\n /**\r\n * Gets whether the actor is Initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n private async _overrideInitialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n await this.director.onInitialize();\r\n await this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * Updates the entire state of the game\r\n * @param delta Number of milliseconds elapsed since the last update.\r\n */\r\n private _update(delta: number) {\r\n if (this._isLoading) {\r\n // suspend updates until loading is finished\r\n this._loader?.onUpdate(this, delta);\r\n // Update input listeners\r\n this.input.update();\r\n return;\r\n }\r\n\r\n // Publish preupdate events\r\n this._preupdate(delta);\r\n\r\n // process engine level events\r\n this.currentScene.update(this, delta);\r\n\r\n // Update graphics postprocessors\r\n this.graphicsContext.updatePostProcessors(delta);\r\n\r\n // Publish update event\r\n this._postupdate(delta);\r\n\r\n // Update input listeners\r\n this.input.update();\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _preupdate(delta: number) {\r\n this.emit('preupdate', new PreUpdateEvent(this, delta, this));\r\n this.onPreUpdate(this, delta);\r\n }\r\n\r\n public onPreUpdate(engine: Engine, delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _postupdate(delta: number) {\r\n this.emit('postupdate', new PostUpdateEvent(this, delta, this));\r\n this.onPostUpdate(this, delta);\r\n }\r\n\r\n public onPostUpdate(engine: Engine, delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Draws the entire game\r\n * @param delta Number of milliseconds elapsed since the last draw.\r\n */\r\n private _draw(delta: number) {\r\n this.graphicsContext.beginDrawLifecycle();\r\n this.graphicsContext.clear();\r\n this._predraw(this.graphicsContext, delta);\r\n\r\n // Drawing nothing else while loading\r\n if (this._isLoading) {\r\n if (!this._hideLoader) {\r\n this._loader?.canvas.draw(this.graphicsContext, 0, 0);\r\n this.graphicsContext.flush();\r\n this.graphicsContext.endDrawLifecycle();\r\n }\r\n return;\r\n }\r\n\r\n // Use scene background color if present, fallback to engine\r\n this.graphicsContext.backgroundColor = this.currentScene.backgroundColor ?? this.backgroundColor;\r\n\r\n this.currentScene.draw(this.graphicsContext, delta);\r\n\r\n this._postdraw(this.graphicsContext, delta);\r\n\r\n // Flush any pending drawings\r\n this.graphicsContext.flush();\r\n this.graphicsContext.endDrawLifecycle();\r\n\r\n this._checkForScreenShots();\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _predraw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n this.emit('predraw', new PreDrawEvent(ctx, delta, this));\r\n this.onPreDraw(ctx, delta);\r\n }\r\n\r\n public onPreDraw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _postdraw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\r\n this.onPostDraw(ctx, delta);\r\n }\r\n\r\n public onPostDraw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Enable or disable Excalibur debugging functionality.\r\n * @param toggle a value that debug drawing will be changed to\r\n */\r\n public showDebug(toggle: boolean): void {\r\n this._isDebug = toggle;\r\n }\r\n\r\n /**\r\n * Toggle Excalibur debugging functionality.\r\n */\r\n public toggleDebug(): boolean {\r\n this._isDebug = !this._isDebug;\r\n return this._isDebug;\r\n }\r\n\r\n /**\r\n * Returns true when loading is totally complete and the player has clicked start\r\n */\r\n public get loadingComplete() {\r\n return !this._isLoading;\r\n }\r\n\r\n private _isLoading = false;\r\n private _hideLoader = false;\r\n private _isReadyFuture = new Future();\r\n public get ready() {\r\n return this._isReadyFuture.isCompleted;\r\n }\r\n public isReady(): Promise {\r\n return this._isReadyFuture.promise;\r\n }\r\n\r\n\r\n\r\n /**\r\n * Starts the internal game loop for Excalibur after loading\r\n * any provided assets.\r\n * @param loader Optional [[Loader]] to use to load resources. The default loader is [[Loader]],\r\n * override to provide your own custom loader.\r\n *\r\n * Note: start() only resolves AFTER the user has clicked the play button\r\n */\r\n public async start(loader?: DefaultLoader): Promise;\r\n /**\r\n * Starts the internal game loop for Excalibur after configuring any routes, loaders, or transitions\r\n * @param startOptions Optional [[StartOptions]] to configure the routes for scenes in Excalibur\r\n *\r\n * Note: start() only resolves AFTER the user has clicked the play button\r\n */\r\n public async start(sceneName: WithRoot, options?: StartOptions): Promise;\r\n /**\r\n * Starts the internal game loop after any loader is finished\r\n * @param loader\r\n */\r\n public async start(loader?: DefaultLoader): Promise;\r\n public async start(sceneNameOrLoader?: WithRoot | DefaultLoader, options?: StartOptions): Promise {\r\n if (!this._compatible) {\r\n throw new Error('Excalibur is incompatible with your browser');\r\n }\r\n this._isLoading = true;\r\n let loader: DefaultLoader;\r\n if (sceneNameOrLoader instanceof DefaultLoader) {\r\n loader = sceneNameOrLoader;\r\n } else if (typeof sceneNameOrLoader === 'string') {\r\n this.director.configureStart(sceneNameOrLoader, options);\r\n loader = this.director.mainLoader;\r\n }\r\n\r\n // Start the excalibur clock which drives the mainloop\r\n this._logger.debug('Starting game clock...');\r\n this.browser.resume();\r\n this.clock.start();\r\n this._logger.debug('Game clock started');\r\n\r\n await this.load(loader ?? new Loader());\r\n\r\n // Initialize before ready\r\n await this._overrideInitialize(this);\r\n\r\n this._isReadyFuture.resolve();\r\n this.emit('start', new GameStartEvent(this));\r\n return this._isReadyFuture.promise;\r\n }\r\n\r\n /**\r\n * Returns the current frames elapsed milliseconds\r\n */\r\n public currentFrameElapsedMs = 0;\r\n\r\n /**\r\n * Returns the current frame lag when in fixed update mode\r\n */\r\n public currentFrameLagMs = 0;\r\n\r\n private _lagMs = 0;\r\n private _mainloop(elapsed: number) {\r\n this.emit('preframe', new PreFrameEvent(this, this.stats.prevFrame));\r\n const delta = elapsed * this.timescale;\r\n this.currentFrameElapsedMs = delta;\r\n\r\n // reset frame stats (reuse existing instances)\r\n const frameId = this.stats.prevFrame.id + 1;\r\n this.stats.currFrame.reset();\r\n this.stats.currFrame.id = frameId;\r\n this.stats.currFrame.delta = delta;\r\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\r\n GraphicsDiagnostics.clear();\r\n\r\n const beforeUpdate = this.clock.now();\r\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\r\n if (this.fixedUpdateFps) {\r\n this._lagMs += delta;\r\n while (this._lagMs >= fixedTimestepMs) {\r\n this._update(fixedTimestepMs);\r\n this._lagMs -= fixedTimestepMs;\r\n }\r\n } else {\r\n this._update(delta);\r\n }\r\n const afterUpdate = this.clock.now();\r\n this.currentFrameLagMs = this._lagMs;\r\n this._draw(delta);\r\n const afterDraw = this.clock.now();\r\n\r\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\r\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\r\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\r\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\r\n\r\n this.emit('postframe', new PostFrameEvent(this, this.stats.currFrame));\r\n this.stats.prevFrame.reset(this.stats.currFrame);\r\n\r\n this._monitorPerformanceThresholdAndTriggerFallback();\r\n }\r\n\r\n /**\r\n * Stops Excalibur's main loop, useful for pausing the game.\r\n */\r\n public stop() {\r\n if (this.clock.isRunning()) {\r\n this.emit('stop', new GameStopEvent(this));\r\n this.browser.pause();\r\n this.clock.stop();\r\n this._logger.debug('Game stopped');\r\n }\r\n }\r\n\r\n /**\r\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\r\n */\r\n public isRunning() {\r\n return this.clock.isRunning();\r\n }\r\n\r\n\r\n private _screenShotRequests: { preserveHiDPIResolution: boolean, resolve: (image: HTMLImageElement) => void }[] = [];\r\n /**\r\n * Takes a screen shot of the current viewport and returns it as an\r\n * HTML Image Element.\r\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\r\n */\r\n public screenshot(preserveHiDPIResolution = false): Promise {\r\n const screenShotPromise = new Promise((resolve) => {\r\n this._screenShotRequests.push({preserveHiDPIResolution, resolve});\r\n });\r\n return screenShotPromise;\r\n }\r\n\r\n private _checkForScreenShots() {\r\n // We must grab the draw buffer before we yield to the browser\r\n // the draw buffer is cleared after compositing\r\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\r\n // forces the browser to copy buffers which can have a mass perf impact on mobile\r\n for (const request of this._screenShotRequests) {\r\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\r\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\r\n const screenshot = document.createElement('canvas');\r\n screenshot.width = finalWidth;\r\n screenshot.height = finalHeight;\r\n const ctx = screenshot.getContext('2d');\r\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\r\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\r\n\r\n const result = new Image();\r\n const raw = screenshot.toDataURL('image/png');\r\n result.src = raw;\r\n request.resolve(result);\r\n }\r\n // Reset state\r\n this._screenShotRequests.length = 0;\r\n }\r\n\r\n /**\r\n * Another option available to you to load resources into the game.\r\n * Immediately after calling this the game will pause and the loading screen\r\n * will appear.\r\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\r\n */\r\n public async load(loader: DefaultLoader, hideLoader = false): Promise {\r\n try {\r\n // early exit if loaded\r\n if (loader.isLoaded()) {\r\n return;\r\n }\r\n this._loader = loader;\r\n this._isLoading = true;\r\n this._hideLoader = hideLoader;\r\n\r\n if (loader instanceof Loader) {\r\n loader.suppressPlayButton = this._suppressPlayButton;\r\n }\r\n this._loader.onInitialize(this);\r\n\r\n await loader.load();\r\n } catch (e) {\r\n this._logger.error('Error loading resources, things may not behave properly', e);\r\n await Promise.resolve();\r\n } finally {\r\n this._isLoading = false;\r\n this._hideLoader = false;\r\n this._loader = null;\r\n }\r\n }\r\n}","export * from './vector';\r\nexport * from './vector-view';\r\nexport * from './matrix';\r\nexport * from './affine-matrix';\r\nexport * from './transform';\r\nexport * from './coord-plane';\r\nexport * from './Random';\r\nexport * from './global-coordinates';\r\nexport * from './line-segment';\r\nexport * from './projection';\r\nexport * from './ray';\r\nexport * from './util';","export * from './DebugConfig';\r\nexport * from './DebugFlags';\r\nexport * from './DebugSystem';\r\n","import { GameEvent } from './Events';\r\nimport { Eventable } from './Interfaces/Evented';\r\n\r\n/**\r\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\r\n */\r\nexport class EventDispatcher implements Eventable {\r\n private _handlers: { [key: string]: { (event: GameEvent): void }[] } = {};\r\n private _wiredEventDispatchers: Eventable[] = [];\r\n\r\n /**\r\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\r\n */\r\n public clear() {\r\n this._handlers = {};\r\n this._wiredEventDispatchers = [];\r\n }\r\n\r\n private _deferedHandlerRemovals: {name: string, handler?: (...args: any[]) => any }[] = [];\r\n private _processDeferredHandlerRemovals() {\r\n for (const eventHandler of this._deferedHandlerRemovals) {\r\n this._removeHandler(eventHandler.name, eventHandler.handler);\r\n }\r\n this._deferedHandlerRemovals.length = 0;\r\n }\r\n\r\n /**\r\n * Emits an event for target\r\n * @param eventName The name of the event to publish\r\n * @param event Optionally pass an event data object to the handler\r\n */\r\n public emit(eventName: string, event: GameEvent) {\r\n this._processDeferredHandlerRemovals();\r\n if (!eventName) {\r\n // key not mapped\r\n return;\r\n }\r\n eventName = eventName.toLowerCase();\r\n if (typeof event === 'undefined' || event === null) {\r\n event = new GameEvent();\r\n }\r\n let i: number, len: number;\r\n\r\n if (this._handlers[eventName]) {\r\n i = 0;\r\n len = this._handlers[eventName].length;\r\n for (i; i < len; i++) {\r\n this._handlers[eventName][i](event);\r\n }\r\n }\r\n\r\n i = 0;\r\n len = this._wiredEventDispatchers.length;\r\n\r\n for (i; i < len; i++) {\r\n this._wiredEventDispatchers[i].emit(eventName, event);\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\r\n * @param eventName The name of the event to subscribe to\r\n * @param handler The handler callback to fire on this event\r\n */\r\n public on(eventName: string, handler: (event: GameEvent) => void) {\r\n this._processDeferredHandlerRemovals();\r\n eventName = eventName.toLowerCase();\r\n\r\n if (!this._handlers[eventName]) {\r\n this._handlers[eventName] = [];\r\n }\r\n this._handlers[eventName].push(handler);\r\n }\r\n\r\n /**\r\n * Unsubscribe an event handler(s) from an event. If a specific handler\r\n * is specified for an event, only that handler will be unsubscribed.\r\n * Otherwise all handlers will be unsubscribed for that event.\r\n * @param eventName The name of the event to unsubscribe\r\n * @param handler Optionally the specific handler to unsubscribe\r\n */\r\n public off(eventName: string, handler?: (event: GameEvent) => void) {\r\n this._deferedHandlerRemovals.push({name: eventName, handler});\r\n }\r\n\r\n private _removeHandler(eventName: string, handler?: (event: GameEvent) => void) {\r\n eventName = eventName.toLowerCase();\r\n const eventHandlers = this._handlers[eventName];\r\n\r\n if (eventHandlers) {\r\n // if no explicit handler is give with the event name clear all handlers\r\n if (!handler) {\r\n this._handlers[eventName].length = 0;\r\n } else {\r\n const index = eventHandlers.indexOf(handler);\r\n if (index > -1) {\r\n this._handlers[eventName].splice(index, 1);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Once listens to an event one time, then unsubscribes from that event\r\n * @param eventName The name of the event to subscribe to once\r\n * @param handler The handler of the event that will be auto unsubscribed\r\n */\r\n public once(eventName: string, handler: (event: GameEvent) => void) {\r\n this._processDeferredHandlerRemovals();\r\n const metaHandler = (event: GameEvent) => {\r\n const ev = event || new GameEvent();\r\n this.off(eventName, metaHandler);\r\n handler(ev);\r\n };\r\n\r\n this.on(eventName, metaHandler);\r\n }\r\n\r\n /**\r\n * Wires this event dispatcher to also receive events from another\r\n */\r\n public wire(eventDispatcher: EventDispatcher): void {\r\n eventDispatcher._wiredEventDispatchers.push(this);\r\n }\r\n\r\n /**\r\n * Unwires this event dispatcher from another\r\n */\r\n public unwire(eventDispatcher: EventDispatcher): void {\r\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\r\n if (index > -1) {\r\n eventDispatcher._wiredEventDispatchers.splice(index, 1);\r\n }\r\n }\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Color } from './Color';\r\nimport { vec, Vector } from './Math/vector';\r\nimport { Text } from './Graphics/Text';\r\nimport { GraphicsComponent, SpriteFont } from './Graphics';\r\nimport { Font } from './Graphics/Font';\r\nimport { Actor } from './Actor';\r\nimport { ActorArgs } from './Actor';\r\n\r\n/**\r\n * Option for creating a label\r\n */\r\nexport interface LabelOptions {\r\n /**\r\n * Specify the label text\r\n */\r\n text?: string;\r\n /**\r\n * Specify the color of the text (does not apply to SpriteFonts)\r\n */\r\n color?: Color;\r\n x?: number;\r\n y?: number;\r\n pos?: Vector;\r\n /**\r\n * Optionally specify a sprite font, will take precedence over any other [[Font]]\r\n */\r\n spriteFont?: SpriteFont;\r\n /**\r\n * Specify a custom font\r\n */\r\n font?: Font\r\n}\r\n\r\n/**\r\n * Labels are the way to draw small amounts of text to the screen. They are\r\n * actors and inherit all of the benefits and capabilities.\r\n */\r\nexport class Label extends Actor {\r\n private _font: Font = new Font();\r\n private _text: Text = new Text({ text: '', font: this._font });\r\n\r\n public get font(): Font {\r\n return this._font;\r\n }\r\n\r\n public set font(newFont: Font) {\r\n this._font = newFont;\r\n this._text.font = newFont;\r\n }\r\n\r\n /**\r\n * The text to draw.\r\n */\r\n public get text(): string {\r\n return this._text.text;\r\n }\r\n\r\n public set text(text: string) {\r\n this._text.text = text;\r\n }\r\n\r\n public override get color(): Color {\r\n return this._text.color;\r\n }\r\n\r\n public override set color(color: Color) {\r\n if (this._text) {\r\n this._text.color = color;\r\n }\r\n }\r\n\r\n public get opacity(): number {\r\n return this._text.opacity;\r\n }\r\n\r\n public set opacity(opacity: number) {\r\n this._text.opacity = opacity;\r\n }\r\n\r\n private _spriteFont: SpriteFont;\r\n /**\r\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\r\n */\r\n public get spriteFont(): SpriteFont {\r\n return this._spriteFont;\r\n }\r\n\r\n public set spriteFont(sf: SpriteFont) {\r\n if (sf) {\r\n this._spriteFont = sf;\r\n this._text.font = this._spriteFont;\r\n }\r\n }\r\n\r\n /**\r\n * Build a new label\r\n * @param options\r\n */\r\n constructor(options?: LabelOptions & ActorArgs) {\r\n super(options);\r\n const {text, pos, x, y, spriteFont, font, color} = { text: '', ...options };\r\n\r\n this.pos = pos ?? (x && y ? vec(x, y) : this.pos);\r\n this.text = text ?? this.text;\r\n this.font = font ?? this.font;\r\n this.spriteFont = spriteFont ?? this.spriteFont;\r\n this._text.color = color ?? this.color;\r\n const gfx = this.get(GraphicsComponent);\r\n gfx.anchor = Vector.Zero;\r\n gfx.use(this._text);\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n }\r\n\r\n /**\r\n * Returns the width of the text in the label (in pixels);\r\n */\r\n public getTextWidth(): number {\r\n return this._text.width;\r\n }\r\n}\r\n","import { BodyComponent } from '../Collision/BodyComponent';\r\nimport { BoundingBox} from '../Collision/BoundingBox';\r\nimport { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { Collider } from '../Collision/Colliders/Collider';\r\nimport { CollisionType } from '../Collision/CollisionType';\r\nimport { CompositeCollider } from '../Collision/Colliders/CompositeCollider';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { DebugGraphicsComponent, ExcaliburGraphicsContext, Graphic, GraphicsComponent } from '../Graphics';\r\nimport { IsometricEntityComponent } from './IsometricEntityComponent';\r\nimport { DebugConfig } from '../Debug';\r\nexport class IsometricTile extends Entity {\r\n /**\r\n * Indicates whether this tile is solid\r\n */\r\n public solid: boolean = false;\r\n\r\n private _gfx: GraphicsComponent;\r\n private _tileBounds = new BoundingBox();\r\n private _graphics: Graphic[] = [];\r\n public getGraphics(): readonly Graphic[] {\r\n return this._graphics;\r\n }\r\n /**\r\n * Tile graphics\r\n */\r\n public addGraphic(graphic: Graphic, options?: {offset?: Vector}) {\r\n this._graphics.push(graphic);\r\n this._gfx.visible = this.map.visible;\r\n this._gfx.opacity = this.map.opacity;\r\n if (options?.offset) {\r\n this._gfx.offset = options.offset;\r\n }\r\n // TODO detect when this changes on the map and apply to all tiles\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n private _recalculateBounds(): BoundingBox {\r\n let bounds = this._tileBounds.clone();\r\n for (const graphic of this._graphics) {\r\n const offset = vec(\r\n this.map.graphicsOffset.x - this.map.tileWidth / 2,\r\n this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\r\n bounds = bounds.combine(graphic.localBounds.translate(offset));\r\n }\r\n return bounds;\r\n }\r\n\r\n public removeGraphic(graphic: Graphic) {\r\n const index = this._graphics.indexOf(graphic);\r\n if (index > -1) {\r\n this._graphics.splice(index, 1);\r\n }\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n public clearGraphics() {\r\n this._graphics.length = 0;\r\n this._gfx.visible = false;\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n /**\r\n * Tile colliders\r\n */\r\n private _colliders: Collider[] = [];\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n /**\r\n * Adds a collider to the IsometricTile\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */\r\n public addCollider(collider: Collider) {\r\n this._colliders.push(collider);\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Removes a collider from the IsometricTile\r\n * @param collider\r\n */\r\n public removeCollider(collider: Collider) {\r\n const index = this._colliders.indexOf(collider);\r\n if (index > -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Clears all colliders from the IsometricTile\r\n */\r\n public clearColliders(): void {\r\n this._colliders.length = 0;\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Integer tile x coordinate\r\n */\r\n public readonly x: number;\r\n /**\r\n * Integer tile y coordinate\r\n */\r\n public readonly y: number;\r\n /**\r\n * Reference to the [[IsometricMap]] this tile is part of\r\n */\r\n public readonly map: IsometricMap;\r\n\r\n private _transform: TransformComponent;\r\n private _isometricEntityComponent: IsometricEntityComponent;\r\n\r\n /**\r\n * Returns the top left corner of the [[IsometricTile]] in world space\r\n */\r\n public get pos(): Vector {\r\n return this.map.tileToWorld(vec(this.x, this.y));\r\n }\r\n\r\n /**\r\n * Returns the center of the [[IsometricTile]]\r\n */\r\n public get center(): Vector {\r\n return this.pos.add(vec(0, this.map.tileHeight / 2));\r\n }\r\n\r\n /**\r\n * Arbitrary data storage per tile, useful for any game specific data\r\n */\r\n public data = new Map();\r\n\r\n /**\r\n * Construct a new IsometricTile\r\n * @param x tile coordinate in x (not world position)\r\n * @param y tile coordinate in y (not world position)\r\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\r\n * @param map reference to owning IsometricMap\r\n */\r\n constructor(x: number, y: number, graphicsOffset: Vector | null, map: IsometricMap) {\r\n super([\r\n new TransformComponent(),\r\n new GraphicsComponent({\r\n offset: graphicsOffset ?? Vector.Zero,\r\n onPostDraw: (gfx, elapsed) => this.draw(gfx, elapsed)\r\n }),\r\n new IsometricEntityComponent(map)\r\n ]);\r\n this.x = x;\r\n this.y = y;\r\n this.map = map;\r\n this._transform = this.get(TransformComponent);\r\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\r\n\r\n const halfTileWidth = this.map.tileWidth / 2;\r\n const halfTileHeight = this.map.tileHeight / 2;\r\n // See https://clintbellanger.net/articles/isometric_math/ for formula\r\n // The x position shifts left with every y step\r\n const xPos = (this.x - this.y) * halfTileWidth;\r\n // The y position needs to go down with every x step\r\n const yPos = (this.x + this.y) * halfTileHeight;\r\n this._transform.pos = vec(xPos, yPos);\r\n this._isometricEntityComponent.elevation = map.elevation;\r\n\r\n this._gfx = this.get(GraphicsComponent);\r\n this._gfx.visible = false; // start not visible\r\n const totalWidth = this.map.tileWidth;\r\n const totalHeight = this.map.tileHeight;\r\n\r\n // initial guess at gfx bounds based on the tile\r\n const offset = vec(0, (this.map.renderFromTopOfGraphic ? totalHeight : 0));\r\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\r\n left: -totalWidth / 2,\r\n top: -totalHeight,\r\n right: totalWidth / 2,\r\n bottom: totalHeight\r\n }).translate(offset);\r\n }\r\n\r\n draw(gfx: ExcaliburGraphicsContext, _elapsed: number) {\r\n const halfTileWidth = this.map.tileWidth / 2;\r\n gfx.save();\r\n // shift left origin to corner of map, not the left corner of the first sprite\r\n gfx.translate(-halfTileWidth, 0);\r\n for (const graphic of this._graphics) {\r\n graphic.draw(\r\n gfx,\r\n this.map.graphicsOffset.x,\r\n this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\r\n }\r\n gfx.restore();\r\n }\r\n}\r\n\r\nexport interface IsometricMapOptions {\r\n /**\r\n * Optionally name the isometric tile map\r\n */\r\n name?: string;\r\n /**\r\n * Optionally specify the position of the isometric tile map\r\n */\r\n pos?: Vector;\r\n /**\r\n * Optionally render from the top of the graphic, by default tiles are rendered from the bottom\r\n */\r\n renderFromTopOfGraphic?: boolean;\r\n /**\r\n * Optionally present a graphics offset, this can be useful depending on your tile graphics\r\n */\r\n graphicsOffset?: Vector;\r\n /**\r\n * Width of an individual tile in pixels, this should be the width of the parallelogram of the base of the tile art asset.\r\n */\r\n tileWidth: number;\r\n /**\r\n * Height of an individual tile in pixels, this should be the height of the parallelogram of the base of the tile art asset.\r\n */\r\n tileHeight: number;\r\n /**\r\n * The number of tile columns, or the number of tiles wide\r\n */\r\n columns: number;\r\n /**\r\n * The number of tile rows, or the number of tiles high\r\n */\r\n rows: number;\r\n\r\n elevation?: number;\r\n}\r\n\r\n/**\r\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\r\n *\r\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\r\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\r\n *\r\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\r\n * your art assets.\r\n */\r\nexport class IsometricMap extends Entity {\r\n public readonly elevation: number = 0;\r\n\r\n /**\r\n * Width of individual tile in pixels\r\n */\r\n public readonly tileWidth: number;\r\n /**\r\n * Height of individual tile in pixels\r\n */\r\n public readonly tileHeight: number;\r\n /**\r\n * Number of tiles wide\r\n */\r\n public readonly columns: number;\r\n /**\r\n * Number of tiles high\r\n */\r\n public readonly rows: number;\r\n /**\r\n * List containing all of the tiles in IsometricMap\r\n */\r\n public readonly tiles: IsometricTile[];\r\n\r\n /**\r\n * Whether tiles should be visible\r\n */\r\n public visible = true;\r\n\r\n /**\r\n * Opacity of tiles\r\n */\r\n public opacity = 1.0;\r\n\r\n /**\r\n * Render the tile graphic from the top instead of the bottom\r\n *\r\n * default is `false` meaning rendering from the bottom\r\n */\r\n public renderFromTopOfGraphic: boolean = false;\r\n public graphicsOffset: Vector = vec(0, 0);\r\n\r\n /**\r\n * Isometric map [[TransformComponent]]\r\n */\r\n public transform: TransformComponent;\r\n\r\n /**\r\n * Isometric map [[ColliderComponent]]\r\n */\r\n public collider: ColliderComponent;\r\n\r\n private _composite: CompositeCollider;\r\n\r\n constructor(options: IsometricMapOptions) {\r\n super([\r\n new TransformComponent(),\r\n new BodyComponent({\r\n type: CollisionType.Fixed\r\n }),\r\n new ColliderComponent(),\r\n new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false)\r\n ], options.name);\r\n const { pos, tileWidth, tileHeight, columns: width, rows: height, renderFromTopOfGraphic, graphicsOffset, elevation } = options;\r\n\r\n this.transform = this.get(TransformComponent);\r\n if (pos) {\r\n this.transform.pos = pos;\r\n }\r\n\r\n this.collider = this.get(ColliderComponent);\r\n if (this.collider) {\r\n this.collider.set(this._composite = new CompositeCollider([]));\r\n }\r\n\r\n\r\n this.renderFromTopOfGraphic = renderFromTopOfGraphic ?? this.renderFromTopOfGraphic;\r\n this.graphicsOffset = graphicsOffset ?? this.graphicsOffset;\r\n\r\n this.elevation = elevation ?? this.elevation;\r\n this.tileWidth = tileWidth;\r\n this.tileHeight = tileHeight;\r\n this.columns = width;\r\n this.rows = height;\r\n\r\n this.tiles = new Array(width * height);\r\n\r\n // build up tile representation\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\r\n this.tiles[x + y * width] = tile;\r\n this.addChild(tile);\r\n }\r\n }\r\n }\r\n\r\n public update(): void {\r\n if (this._collidersDirty) {\r\n this.updateColliders();\r\n this._collidersDirty = false;\r\n }\r\n }\r\n\r\n private _collidersDirty = false;\r\n public flagCollidersDirty() {\r\n this._collidersDirty = true;\r\n }\r\n\r\n private _originalOffsets = new WeakMap();\r\n private _getOrSetColliderOriginalOffset(collider: Collider): Vector {\r\n if (!this._originalOffsets.has(collider)) {\r\n const originalOffset = collider.offset;\r\n this._originalOffsets.set(collider, originalOffset);\r\n return originalOffset;\r\n } else {\r\n return this._originalOffsets.get(collider);\r\n }\r\n }\r\n public updateColliders() {\r\n this._composite.clearColliders();\r\n const pos = this.get(TransformComponent).pos;\r\n for (const tile of this.tiles) {\r\n if (tile.solid) {\r\n for (const collider of tile.getColliders()) {\r\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\r\n collider.offset = this.tileToWorld(vec(tile.x, tile.y))\r\n .sub(pos)\r\n .add(originalOffset)\r\n .sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n }\r\n }\r\n this.collider.update();\r\n }\r\n\r\n /**\r\n * Convert world space coordinates to the tile x, y coordinate\r\n * @param worldCoordinate\r\n */\r\n public worldToTile(worldCoordinate: Vector): Vector {\r\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\r\n\r\n const halfTileWidth = this.tileWidth / 2;\r\n const halfTileHeight = this.tileHeight / 2;\r\n // See https://clintbellanger.net/articles/isometric_math/ for formula\r\n return vec(\r\n ~~((worldCoordinate.x / halfTileWidth + (worldCoordinate.y / halfTileHeight)) / 2),\r\n ~~((worldCoordinate.y / halfTileHeight - (worldCoordinate.x / halfTileWidth)) / 2));\r\n }\r\n\r\n /**\r\n * Given a tile coordinate, return the top left corner in world space\r\n * @param tileCoordinate\r\n */\r\n public tileToWorld(tileCoordinate: Vector): Vector {\r\n const halfTileWidth = this.tileWidth / 2;\r\n const halfTileHeight = this.tileHeight / 2;\r\n // The x position shifts left with every y step\r\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\r\n // The y position needs to go down with every x step\r\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\r\n return vec(xPos, yPos).add(this.transform.pos);\r\n }\r\n\r\n /**\r\n * Returns the [[IsometricTile]] by its x and y coordinates\r\n */\r\n public getTile(x: number, y: number): IsometricTile | null {\r\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\r\n return null;\r\n }\r\n return this.tiles[x + y * this.columns];\r\n }\r\n\r\n /**\r\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */\r\n public getTileByPoint(point: Vector): IsometricTile | null {\r\n const tileCoord = this.worldToTile(point);\r\n const tile = this.getTile(tileCoord.x, tileCoord.y);\r\n return tile;\r\n }\r\n\r\n private _getMaxZIndex(): number {\r\n let maxZ = Number.NEGATIVE_INFINITY;\r\n for (const tile of this.tiles) {\r\n const currentZ = tile.get(TransformComponent).z;\r\n if (currentZ > maxZ) {\r\n maxZ = currentZ;\r\n }\r\n }\r\n return maxZ;\r\n }\r\n\r\n /**\r\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\r\n * @param gfx\r\n */\r\n public debug(gfx: ExcaliburGraphicsContext, debugFlags: DebugConfig) {\r\n const {\r\n showAll,\r\n showPosition,\r\n positionColor,\r\n positionSize,\r\n showGrid,\r\n gridColor,\r\n gridWidth,\r\n showColliderGeometry\r\n } = debugFlags.isometric;\r\n\r\n const {\r\n geometryColor,\r\n geometryLineWidth,\r\n geometryPointSize\r\n } = debugFlags.collider;\r\n gfx.save();\r\n gfx.z = this._getMaxZIndex() + 0.5;\r\n if (showAll || showGrid) {\r\n for (let y = 0; y < this.rows + 1; y++) {\r\n const left = this.tileToWorld(vec(0, y));\r\n const right = this.tileToWorld(vec(this.columns, y));\r\n gfx.drawLine(left, right, gridColor, gridWidth);\r\n }\r\n\r\n for (let x = 0; x < this.columns + 1; x++) {\r\n const top = this.tileToWorld(vec(x, 0));\r\n const bottom = this.tileToWorld(vec(x, this.rows));\r\n gfx.drawLine(top, bottom, gridColor, gridWidth);\r\n }\r\n }\r\n\r\n if (showAll || showPosition) {\r\n for (const tile of this.tiles) {\r\n gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), positionSize, positionColor);\r\n }\r\n }\r\n if (showAll || showColliderGeometry) {\r\n for (const tile of this.tiles) {\r\n if (tile.solid) { // only draw solid tiles\r\n for (const collider of tile.getColliders()) {\r\n collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize });\r\n }\r\n }\r\n }\r\n }\r\n gfx.restore();\r\n }\r\n}","export * from './TileMap';\r\nexport * from './IsometricMap';\r\nexport * from './IsometricEntityComponent';\r\nexport * from './IsometricEntitySystem';","import { Entity } from '../../EntityComponentSystem';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\n/**\r\n * Action that can represent a sequence of actions, this can be useful in conjunction with\r\n * [[ParallelActions]] to run multiple sequences in parallel.\r\n */\r\nexport class ActionSequence implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _stopped: boolean = false;\r\n private _sequenceContext: ActionContext;\r\n private _sequenceBuilder: (actionContext: ActionContext) => any;\r\n constructor(entity: Entity, actionBuilder: (actionContext: ActionContext) => any) {\r\n this._sequenceBuilder = actionBuilder;\r\n this._sequenceContext = new ActionContext(entity);\r\n this._actionQueue = this._sequenceContext.getQueue();\r\n this._sequenceBuilder(this._sequenceContext);\r\n }\r\n\r\n public update(delta: number): void {\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._actionQueue.isComplete();\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._stopped = false;\r\n this._actionQueue.reset();\r\n }\r\n\r\n public clone(entity: Entity) {\r\n return new ActionSequence(entity, this._sequenceBuilder);\r\n }\r\n}","import { Entity } from '../../EntityComponentSystem';\r\nimport { Action } from '../Action';\r\n\r\n\r\n/**\r\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\r\n */\r\nexport class ParallelActions implements Action {\r\n private _actions: Action[];\r\n\r\n constructor(parallelActions: Action[]) {\r\n this._actions = parallelActions;\r\n }\r\n\r\n update(delta: number): void {\r\n for (let i = 0; i < this._actions.length; i++) {\r\n this._actions[i].update(delta);\r\n }\r\n }\r\n isComplete(entity: Entity): boolean {\r\n return this._actions.every(a => a.isComplete(entity));\r\n }\r\n reset(): void {\r\n this._actions.forEach(a => a.reset());\r\n }\r\n stop(): void {\r\n this._actions.forEach(a => a.stop());\r\n }\r\n}","export * from './ActionContext';\r\nexport * from './ActionQueue';\r\nexport * from './Actionable';\r\nexport * from './RotationType';\r\n\r\nexport * from './Action';\r\nexport * from './Action/ActionSequence';\r\nexport * from './Action/ParallelActions';\r\nexport * from './Action/Repeat';\r\nexport * from './Action/RepeatForever';\r\nexport * from './Action/Blink';\r\nexport * from './Action/Die';\r\nexport * from './Action/EaseTo';\r\nexport * from './Action/EaseBy';\r\nexport * from './Action/Fade';\r\nexport * from './Action/Follow';\r\nexport * from './Action/Meet';\r\nexport * from './Action/MoveBy';\r\nexport * from './Action/MoveTo';\r\nexport * from './Action/RotateBy';\r\nexport * from './Action/RotateTo';\r\nexport * from './Action/ScaleBy';\r\nexport * from './Action/ScaleTo';\r\nexport * from './Action/Delay';\r\n\r\nexport * from './ActionsComponent';\r\nexport * from './ActionsSystem';","import { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics';\r\nimport { BoundingBox } from '../BoundingBox';\r\n\r\nexport interface QuadTreeItem {\r\n bounds: BoundingBox;\r\n}\r\n\r\nexport interface QuadTreeOptions {\r\n maxDepth?: number;\r\n capacity: number;\r\n level?: number;\r\n}\r\n\r\n/**\r\n * QuadTree spatial data structure. Useful for quickly retrieving all objects that might\r\n * be in a specific location.\r\n */\r\nexport class QuadTree {\r\n private _defaultOptions: QuadTreeOptions = {\r\n maxDepth: 10,\r\n capacity: 10,\r\n level: 0\r\n };\r\n\r\n public halfWidth: number;\r\n public halfHeight: number;\r\n public items: TItem[] = [];\r\n private _isDivided = false;\r\n\r\n public topLeft: QuadTree | null = null;\r\n public topRight: QuadTree | null = null;\r\n public bottomLeft: QuadTree | null = null;\r\n public bottomRight: QuadTree | null = null;\r\n\r\n constructor(public bounds: BoundingBox, public options?: QuadTreeOptions) {\r\n this.options = {...this._defaultOptions, ...options};\r\n this.halfWidth = bounds.width / 2;\r\n this.halfHeight = bounds.height / 2;\r\n }\r\n\r\n /**\r\n * Splits the quad tree one level deeper\r\n */\r\n private _split() {\r\n this._isDivided = true;\r\n const newLevelOptions = {\r\n maxDepth: this.options.maxDepth,\r\n capacity: this.options.capacity,\r\n level: this.options.level + 1\r\n };\r\n this.topLeft = new QuadTree(\r\n new BoundingBox({\r\n left: this.bounds.left,\r\n top: this.bounds.top,\r\n right: this.bounds.left + this.halfWidth,\r\n bottom: this.bounds.top + this.halfHeight\r\n }), newLevelOptions);\r\n this.topRight = new QuadTree(\r\n new BoundingBox({\r\n left: this.bounds.left + this.halfWidth,\r\n top: this.bounds.top,\r\n right: this.bounds.right,\r\n bottom: this.bounds.top + this.halfHeight\r\n }), newLevelOptions);\r\n this.bottomLeft = new QuadTree(new BoundingBox({\r\n left: this.bounds.left,\r\n top: this.bounds.top + this.halfHeight,\r\n right: this.bounds.left + this.halfWidth,\r\n bottom: this.bounds.bottom\r\n }), newLevelOptions);\r\n this.bottomRight = new QuadTree(\r\n new BoundingBox({\r\n left: this.bounds.left + this.halfWidth,\r\n top: this.bounds.top + this.halfHeight,\r\n right: this.bounds.right,\r\n bottom: this.bounds.bottom\r\n }), newLevelOptions);\r\n }\r\n\r\n private _insertIntoSubNodes(item: TItem) {\r\n if (this.topLeft?.bounds.overlaps(item.bounds)) {\r\n this.topLeft.insert(item);\r\n }\r\n\r\n if (this.topRight?.bounds.overlaps(item.bounds)) {\r\n this.topRight.insert(item);\r\n }\r\n\r\n if (this.bottomLeft?.bounds.overlaps(item.bounds)) {\r\n this.bottomLeft.insert(item);\r\n }\r\n\r\n if (this.bottomRight?.bounds.overlaps(item.bounds)) {\r\n this.bottomRight.insert(item);\r\n }\r\n }\r\n\r\n /**\r\n * Insert an item to be tracked in the QuadTree\r\n * @param item\r\n */\r\n insert(item: TItem): void {\r\n // add to subnodes if it matches\r\n if (this._isDivided) {\r\n this._insertIntoSubNodes(item);\r\n return;\r\n }\r\n\r\n\r\n // leaf case\r\n this.items.push(item);\r\n\r\n // capacity\r\n if (this.items.length > this.options.capacity && this.options.level < this.options.maxDepth) {\r\n if (!this._isDivided) {\r\n this._split();\r\n }\r\n // divide this level's items into it's subnodes\r\n for (const item of this.items) {\r\n this._insertIntoSubNodes(item);\r\n }\r\n // clear this level\r\n this.items.length = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Remove a tracked item in the QuadTree\r\n * @param item\r\n */\r\n remove(item: TItem): void {\r\n if (!this.bounds.overlaps(item.bounds)) {\r\n return;\r\n }\r\n\r\n if (!this._isDivided) {\r\n const index = this.items.indexOf(item);\r\n if (index > -1) {\r\n this.items.splice(index, 1);\r\n }\r\n return;\r\n }\r\n\r\n if (this.topLeft?.bounds.overlaps(item.bounds)) {\r\n this.topLeft.remove(item);\r\n }\r\n\r\n if (this.topRight?.bounds.overlaps(item.bounds)) {\r\n this.topRight.remove(item);\r\n }\r\n\r\n if (this.bottomLeft?.bounds.overlaps(item.bounds)) {\r\n this.bottomLeft.remove(item);\r\n }\r\n\r\n if (this.bottomRight?.bounds.overlaps(item.bounds)) {\r\n this.bottomRight.remove(item);\r\n }\r\n }\r\n\r\n /**\r\n * Query the structure for all objects that intersect the bounding box\r\n * @param boundingBox\r\n * @returns items\r\n */\r\n query(boundingBox: BoundingBox): TItem[] {\r\n\r\n let results = this.items;\r\n\r\n if (this._isDivided) {\r\n if (this.topLeft.bounds.overlaps(boundingBox)) {\r\n results = results.concat(this.topLeft.query(boundingBox));\r\n }\r\n if (this.topRight.bounds.overlaps(boundingBox)) {\r\n results = results.concat(this.topRight.query(boundingBox));\r\n }\r\n if (this.bottomLeft.bounds.overlaps(boundingBox)) {\r\n results = results.concat(this.bottomLeft.query(boundingBox));\r\n }\r\n if (this.bottomRight.bounds.overlaps(boundingBox)) {\r\n results = results.concat(this.bottomRight.query(boundingBox));\r\n }\r\n }\r\n\r\n results = results.filter((item, index) => {\r\n return results.indexOf(item) >= index;\r\n });\r\n\r\n return results;\r\n }\r\n\r\n clear() {\r\n this.items = [];\r\n this._isDivided = false;\r\n\r\n this.topLeft = null;\r\n this.topRight = null;\r\n this.bottomLeft = null;\r\n this.bottomRight = null;\r\n }\r\n\r\n getAllItems(): TItem[] {\r\n let results = this.items;\r\n\r\n if (this._isDivided) {\r\n results = results.concat(this.topLeft.getAllItems());\r\n results = results.concat(this.topRight.getAllItems());\r\n results = results.concat(this.bottomLeft.getAllItems());\r\n results = results.concat(this.bottomRight.getAllItems());\r\n }\r\n\r\n results = results.filter((item, index) => {\r\n return results.indexOf(item) >= index;\r\n });\r\n\r\n return results;\r\n }\r\n\r\n getTreeDepth(): number {\r\n if (!this._isDivided) {\r\n return 0;\r\n }\r\n\r\n return 1 + Math.max(\r\n this.topLeft.getTreeDepth(),\r\n this.topRight.getTreeDepth(),\r\n this.bottomLeft.getTreeDepth(),\r\n this.bottomRight.getTreeDepth()\r\n );\r\n }\r\n\r\n debug(ctx: ExcaliburGraphicsContext) {\r\n this.bounds.draw(ctx, Color.Yellow);\r\n if (this._isDivided) {\r\n this.topLeft.bounds.draw(ctx, Color.Yellow);\r\n this.topRight.bounds.draw(ctx, Color.Yellow);\r\n this.bottomLeft.bounds.draw(ctx, Color.Yellow);\r\n this.bottomRight.bounds.draw(ctx, Color.Yellow);\r\n }\r\n }\r\n}","export * from './BodyComponent';\r\nexport * from './ColliderComponent';\r\nexport * from './CollisionType';\r\nexport * from './SolverStrategy';\r\n\r\nexport * from './Colliders/Collider';\r\nexport * from './BoundingBox';\r\n\r\nexport * from './Colliders/Shape';\r\nexport * from './Colliders/Collider';\r\nexport * from './Colliders/CompositeCollider';\r\nexport * from './Colliders/CircleCollider';\r\nexport * from './Colliders/EdgeCollider';\r\nexport * from './Colliders/PolygonCollider';\r\nexport * from './Colliders/CollisionJumpTable';\r\nexport * from './Colliders/ClosestLineJumpTable';\r\n\r\nexport * from './Group/CollisionGroup';\r\nexport * from './Group/CollisionGroupManager';\r\n\r\nexport * from './Detection/Pair';\r\nexport * from './Detection/CollisionContact';\r\nexport * from './Detection/RayCastHit';\r\nexport * from './Detection/CollisionProcessor';\r\nexport * from './Detection/DynamicTree';\r\nexport * from './Detection/DynamicTreeCollisionProcessor';\r\nexport * from './Detection/QuadTree';\r\n\r\nexport * from './Solver/ArcadeSolver';\r\nexport * from './Solver/ContactBias';\r\nexport * from './Solver/ContactConstraintPoint';\r\nexport * from './Solver/RealisticSolver';\r\nexport * from './Solver/Solver';\r\n\r\nexport * from './CollisionSystem';\r\nexport * from './MotionSystem';\r\n\r\nexport * from './PhysicsWorld';\r\nexport * from './PhysicsConfig';\r\nexport * from './Physics';\r\nexport * from './Side';\r\n","import { Engine } from './../Engine';\r\nimport * as Events from './../Events';\r\nimport { Scene } from '../Scene';\r\nimport { ExcaliburGraphicsContext } from '../Graphics';\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _initialize {\r\n _initialize(engine: Engine): void;\r\n}\r\n\r\n/**\r\n * Type guard checking for internal initialize method\r\n * @internal\r\n * @param a\r\n */\r\nexport function has_initialize(a: any): a is _initialize {\r\n return !!a._initialize;\r\n}\r\n\r\nexport interface OnInitialize {\r\n onInitialize(engine: Engine): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnInitialize(a: any): a is OnInitialize {\r\n return !!a.onInitialize;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _preupdate {\r\n _preupdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function has_preupdate(a: any): a is _preupdate {\r\n return !!a._preupdate;\r\n}\r\n\r\nexport interface OnPreUpdate {\r\n onPreUpdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnPreUpdate(a: any): a is OnPreUpdate {\r\n return !!a.onPreUpdate;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _postupdate {\r\n _postupdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function has_postupdate(a: any): a is _postupdate {\r\n return !!a.onPostUpdate;\r\n}\r\n\r\nexport interface OnPostUpdate {\r\n onPostUpdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnPostUpdate(a: any): a is OnPostUpdate {\r\n return !!a.onPostUpdate;\r\n}\r\n\r\nexport interface CanInitialize {\r\n /**\r\n * Overridable implementation\r\n */\r\n onInitialize(engine: Engine): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.initialize, handler: (event: Events.InitializeEvent) => void): void;\r\n once(eventName: Events.initialize, handler: (event: Events.InitializeEvent) => void): void;\r\n off(eventName: Events.initialize, handler?: (event: Events.InitializeEvent) => void): void;\r\n}\r\n\r\nexport interface SceneActivationContext {\r\n data?: TData;\r\n previousScene: Scene;\r\n nextScene: Scene;\r\n engine: Engine;\r\n}\r\n\r\nexport interface CanActivate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onActivate(context: SceneActivationContext): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.activate, handler: (event: Events.ActivateEvent) => void): void;\r\n once(eventName: Events.activate, handler: (event: Events.ActivateEvent) => void): void;\r\n off(eventName: Events.activate, handler?: (event: Events.ActivateEvent) => void): void;\r\n}\r\n\r\nexport interface CanDeactivate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onDeactivate(context: SceneActivationContext): void;\r\n\r\n /**\r\n * Event signature\r\n */\r\n on(eventName: Events.deactivate, handler: (event: Events.DeactivateEvent) => void): void;\r\n once(eventName: Events.deactivate, handler: (event: Events.DeactivateEvent) => void): void;\r\n off(eventName: Events.deactivate, handler?: (event: Events.DeactivateEvent) => void): void;\r\n}\r\n\r\nexport interface CanUpdate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreUpdate(engine: Engine, delta: number): void;\r\n\r\n /**\r\n * Event signature\r\n */\r\n on(eventName: Events.preupdate, handler: (event: Events.PreUpdateEvent) => void): void;\r\n once(eventName: Events.preupdate, handler: (event: Events.PreUpdateEvent) => void): void;\r\n off(eventName: Events.preupdate, handler?: (event: Events.PreUpdateEvent) => void): void;\r\n\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostUpdate(engine: Engine, delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postupdate, handler: (event: Events.PostUpdateEvent) => void): void;\r\n once(eventName: Events.postupdate, handler: (event: Events.PostUpdateEvent) => void): void;\r\n off(eventName: Events.postupdate, handler?: (event: Events.PostUpdateEvent) => void): void;\r\n}\r\n\r\nexport interface OnPreDraw {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreDraw(ctx: ExcaliburGraphicsContext, delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n once(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n off(eventName: Events.predraw, handler?: (event: Events.PreDrawEvent) => void): void;\r\n}\r\n\r\nexport interface OnPostDraw {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostDraw(ctx: ExcaliburGraphicsContext, delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n once(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n off(eventName: Events.postdraw, handler?: (event: Events.PostDrawEvent) => void): void;\r\n}\r\n\r\nexport interface CanDraw extends OnPreDraw, OnPostDraw {\r\n on(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n on(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n\r\n once(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n once(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n\r\n off(eventName: Events.predraw, handler?: (event: Events.PreDrawEvent) => void): void;\r\n off(eventName: Events.postdraw, handler?: (event: Events.PostDrawEvent) => void): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasPreDraw(a: any): a is OnPreDraw {\r\n return !!a.onPreDraw;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasPostDraw(a: any): a is OnPostDraw {\r\n return !!a.onPostDraw;\r\n}\r\n\r\nexport interface CanBeKilled {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreKill(_scene: Scene): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n once(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n off(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostKill(_scene: Scene): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n once(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n off(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n}\r\n","export * from './Clonable';\r\nexport * from './Audio';\r\nexport * from './AudioImplementation';\r\nexport * from './Evented';\r\nexport * from './Loadable';\r\nexport * from './LifecycleEvents';\r\nexport * from './PointerEventHandlers';\r\n","export * from './Sound';\r\nexport * from './AudioContext';\r\nexport * from './WebAudioInstance';\r\n","import { Resource } from './Resource';\r\nimport { Sprite } from '../Graphics/Sprite';\r\nimport { Color } from '../Color';\r\nimport { SpriteSheet } from '../Graphics/SpriteSheet';\r\nimport { Animation } from '../Graphics/Animation';\r\nimport { Loadable } from '../Interfaces/Index';\r\nimport { ImageSource } from '../Graphics/ImageSource';\r\nimport { range } from '../Math/util';\r\n/**\r\n * The [[Texture]] object allows games built in Excalibur to load image resources.\r\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\r\n * to pre-load before starting a level or game.\r\n */\r\nexport class Gif implements Loadable {\r\n private _resource: Resource;\r\n\r\n /**\r\n * The width of the texture in pixels\r\n */\r\n public width: number;\r\n\r\n /**\r\n * The height of the texture in pixels\r\n */\r\n public height: number;\r\n\r\n\r\n private _stream: Stream = null;\r\n private _gif: ParseGif = null;\r\n private _textures: ImageSource[] = [];\r\n private _animation: Animation = null;\r\n private _transparentColor: Color = null;\r\n\r\n public data: ImageSource[];\r\n\r\n /**\r\n * @param path Path to the image resource\r\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\r\n * @param bustCache Optionally load texture with cache busting\r\n */\r\n constructor(public path: string, public color: Color = Color.Magenta, bustCache = false) {\r\n this._resource = new Resource(path, 'arraybuffer', bustCache);\r\n this._transparentColor = color;\r\n }\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n /**\r\n * Begins loading the texture and returns a promise to be resolved on completion\r\n */\r\n public async load(): Promise {\r\n const arraybuffer = await this._resource.load();\r\n this._stream = new Stream(arraybuffer);\r\n this._gif = new ParseGif(this._stream, this._transparentColor);\r\n const images = this._gif.images.map(i => new ImageSource(i.src, false));\r\n\r\n // Load all textures\r\n await Promise.all(images.map(t => t.load()));\r\n return this.data = this._textures = images;\r\n }\r\n\r\n public isLoaded() {\r\n return !!this.data;\r\n }\r\n\r\n /**\r\n * Return a frame of the gif as a sprite by id\r\n * @param id\r\n */\r\n public toSprite(id: number = 0): Sprite {\r\n const sprite = this._textures[id].toSprite();\r\n return sprite;\r\n }\r\n\r\n /**\r\n * Return the gif as a spritesheet\r\n */\r\n public toSpriteSheet(): SpriteSheet {\r\n const sprites: Sprite[] = this._textures.map((image) => {\r\n return image.toSprite();\r\n });\r\n return new SpriteSheet({ sprites });\r\n }\r\n\r\n /**\r\n * Transform the GIF into an animation with duration per frame\r\n */\r\n public toAnimation(durationPerFrameMs: number): Animation {\r\n const spriteSheet: SpriteSheet = this.toSpriteSheet();\r\n const length = spriteSheet.sprites.length;\r\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\r\n return this._animation;\r\n }\r\n\r\n public get readCheckBytes(): number[] {\r\n return this._gif.checkBytes;\r\n }\r\n}\r\n\r\nexport interface GifFrame {\r\n sentinel: number;\r\n type: string;\r\n leftPos: number;\r\n topPos: number;\r\n width: number;\r\n height: number;\r\n lctFlag: boolean;\r\n interlaced: boolean;\r\n sorted: boolean;\r\n reserved: boolean[];\r\n lctSize: number;\r\n lzwMinCodeSize: number;\r\n pixels: number[];\r\n}\r\n\r\nconst bitsToNum = (ba: any) => {\r\n return ba.reduce(function (s: number, n: number) {\r\n return s * 2 + n;\r\n }, 0);\r\n};\r\n\r\nconst byteToBitArr = (bite: any) => {\r\n const a = [];\r\n for (let i = 7; i >= 0; i--) {\r\n a.push(!!(bite & (1 << i)));\r\n }\r\n return a;\r\n};\r\n\r\nexport class Stream {\r\n data: any = null;\r\n len: number = 0;\r\n position: number = 0;\r\n\r\n constructor(dataArray: ArrayBuffer) {\r\n this.data = new Uint8Array(dataArray);\r\n this.len = this.data.byteLength;\r\n if (this.len === 0) {\r\n throw new Error('No data loaded from file');\r\n }\r\n }\r\n\r\n public readByte = () => {\r\n if (this.position >= this.data.byteLength) {\r\n throw new Error('Attempted to read past end of stream.');\r\n }\r\n return this.data[this.position++];\r\n };\r\n\r\n public readBytes = (n: number) => {\r\n const bytes = [];\r\n for (let i = 0; i < n; i++) {\r\n bytes.push(this.readByte());\r\n }\r\n return bytes;\r\n };\r\n\r\n public read = (n: number) => {\r\n let s = '';\r\n for (let i = 0; i < n; i++) {\r\n s += String.fromCharCode(this.readByte());\r\n }\r\n return s;\r\n };\r\n\r\n public readUnsigned = () => {\r\n // Little-endian.\r\n const a = this.readBytes(2);\r\n return (a[1] << 8) + a[0];\r\n };\r\n}\r\n\r\nconst lzwDecode = function (minCodeSize: number, data: any) {\r\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\r\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\r\n\r\n const readCode = function (size: number) {\r\n let code = 0;\r\n for (let i = 0; i < size; i++) {\r\n if (data.charCodeAt(pos >> 3) & (1 << (pos & 7))) {\r\n code |= 1 << i;\r\n }\r\n pos++;\r\n }\r\n return code;\r\n };\r\n\r\n const output: any[] = [];\r\n\r\n const clearCode = 1 << minCodeSize;\r\n const eoiCode = clearCode + 1;\r\n\r\n let codeSize = minCodeSize + 1;\r\n\r\n let dict: any[] = [];\r\n\r\n const clear = function () {\r\n dict = [];\r\n codeSize = minCodeSize + 1;\r\n for (let i = 0; i < clearCode; i++) {\r\n dict[i] = [i];\r\n }\r\n dict[clearCode] = [];\r\n dict[eoiCode] = null;\r\n };\r\n\r\n let code;\r\n let last;\r\n\r\n while (true) {\r\n last = code;\r\n code = readCode(codeSize);\r\n if (code === clearCode) {\r\n clear();\r\n continue;\r\n }\r\n if (code === eoiCode) {\r\n break;\r\n }\r\n\r\n if (code < dict.length) {\r\n if (last !== clearCode) {\r\n dict.push(dict[last].concat(dict[code][0]));\r\n }\r\n } else {\r\n if (code !== dict.length) {\r\n throw new Error('Invalid LZW code.');\r\n }\r\n dict.push(dict[last].concat(dict[last][0]));\r\n }\r\n output.push.apply(output, dict[code]);\r\n\r\n if (dict.length === 1 << codeSize && codeSize < 12) {\r\n // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\r\n codeSize++;\r\n }\r\n }\r\n\r\n // I don't know if this is technically an error, but some GIFs do it.\r\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\r\n return output;\r\n};\r\n\r\n// The actual parsing; returns an object with properties.\r\nexport class ParseGif {\r\n private _st: Stream = null;\r\n private _handler: any = {};\r\n private _transparentColor: Color = null;\r\n public frames: GifFrame[] = [];\r\n public images: HTMLImageElement[] = [];\r\n public globalColorTable: any[] = [];\r\n public checkBytes: number[] = [];\r\n\r\n constructor(stream: Stream, color: Color = Color.Magenta) {\r\n this._st = stream;\r\n this._handler = {};\r\n this._transparentColor = color;\r\n this.parseHeader();\r\n this.parseBlock();\r\n }\r\n\r\n // LZW (GIF-specific)\r\n parseColorTable = (entries: any) => {\r\n // Each entry is 3 bytes, for RGB.\r\n const ct = [];\r\n for (let i = 0; i < entries; i++) {\r\n const rgb: number[] = this._st.readBytes(3);\r\n const rgba =\r\n '#' +\r\n rgb\r\n .map((x: any) => {\r\n const hex = x.toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n })\r\n .join('');\r\n ct.push(rgba);\r\n }\r\n return ct;\r\n };\r\n\r\n readSubBlocks = () => {\r\n let size, data;\r\n data = '';\r\n do {\r\n size = this._st.readByte();\r\n data += this._st.read(size);\r\n } while (size !== 0);\r\n return data;\r\n };\r\n\r\n parseHeader = () => {\r\n const hdr: any = {\r\n sig: null,\r\n ver: null,\r\n width: null,\r\n height: null,\r\n colorRes: null,\r\n globalColorTableSize: null,\r\n gctFlag: null,\r\n sorted: null,\r\n globalColorTable: [],\r\n bgColor: null,\r\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\r\n };\r\n\r\n hdr.sig = this._st.read(3);\r\n hdr.ver = this._st.read(3);\r\n if (hdr.sig !== 'GIF') {\r\n throw new Error('Not a GIF file.'); // XXX: This should probably be handled more nicely.\r\n }\r\n\r\n hdr.width = this._st.readUnsigned();\r\n hdr.height = this._st.readUnsigned();\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n hdr.gctFlag = bits.shift();\r\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\r\n hdr.sorted = bits.shift();\r\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\r\n\r\n hdr.bgColor = this._st.readByte();\r\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\r\n\r\n if (hdr.gctFlag) {\r\n hdr.globalColorTable = this.parseColorTable(1 << (hdr.globalColorTableSize + 1));\r\n this.globalColorTable = hdr.globalColorTable;\r\n }\r\n if (this._handler.hdr && this._handler.hdr(hdr)) {\r\n this.checkBytes.push(this._handler.hdr);\r\n }\r\n };\r\n\r\n parseExt = (block: any) => {\r\n const parseGCExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 4\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\r\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\r\n block.userInput = bits.shift();\r\n block.transparencyGiven = bits.shift();\r\n\r\n block.delayTime = this._st.readUnsigned();\r\n\r\n block.transparencyIndex = this._st.readByte();\r\n\r\n block.terminator = this._st.readByte();\r\n\r\n if (this._handler.gce && this._handler.gce(block)) {\r\n this.checkBytes.push(this._handler.gce);\r\n }\r\n };\r\n\r\n const parseComExt = (block: any) => {\r\n block.comment = this.readSubBlocks();\r\n if (this._handler.com && this._handler.com(block)) {\r\n this.checkBytes.push(this._handler.com);\r\n }\r\n };\r\n\r\n const parsePTExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 12\r\n block.ptHeader = this._st.readBytes(12);\r\n block.ptData = this.readSubBlocks();\r\n if (this._handler.pte && this._handler.pte(block)) {\r\n this.checkBytes.push(this._handler.pte);\r\n }\r\n };\r\n\r\n const parseAppExt = (block: any) => {\r\n const parseNetscapeExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 3\r\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\r\n block.iterations = this._st.readUnsigned();\r\n block.terminator = this._st.readByte();\r\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) {\r\n this.checkBytes.push(this._handler.app);\r\n }\r\n };\r\n\r\n const parseUnknownAppExt = (block: any) => {\r\n block.appData = this.readSubBlocks();\r\n // FIXME: This won't work if a handler wants to match on any identifier.\r\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) {\r\n this.checkBytes.push(this._handler.app[block.identifier]);\r\n }\r\n };\r\n\r\n this.checkBytes.push(this._st.readByte()); // Always 11\r\n block.identifier = this._st.read(8);\r\n block.authCode = this._st.read(3);\r\n switch (block.identifier) {\r\n case 'NETSCAPE':\r\n parseNetscapeExt(block);\r\n break;\r\n default:\r\n parseUnknownAppExt(block);\r\n break;\r\n }\r\n };\r\n\r\n const parseUnknownExt = (block: any) => {\r\n block.data = this.readSubBlocks();\r\n if (this._handler.unknown && this._handler.unknown(block)) {\r\n this.checkBytes.push(this._handler.unknown);\r\n }\r\n };\r\n\r\n block.label = this._st.readByte();\r\n switch (block.label) {\r\n case 0xf9:\r\n block.extType = 'gce';\r\n parseGCExt(block);\r\n break;\r\n case 0xfe:\r\n block.extType = 'com';\r\n parseComExt(block);\r\n break;\r\n case 0x01:\r\n block.extType = 'pte';\r\n parsePTExt(block);\r\n break;\r\n case 0xff:\r\n block.extType = 'app';\r\n parseAppExt(block);\r\n break;\r\n default:\r\n block.extType = 'unknown';\r\n parseUnknownExt(block);\r\n break;\r\n }\r\n };\r\n\r\n parseImg = (img: any) => {\r\n const deinterlace = (pixels: any, width: any) => {\r\n // Of course this defeats the purpose of interlacing. And it's *probably*\r\n // the least efficient way it's ever been implemented. But nevertheless...\r\n\r\n const newPixels = new Array(pixels.length);\r\n const rows = pixels.length / width;\r\n const cpRow = (toRow: any, fromRow: any) => {\r\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\r\n newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels));\r\n };\r\n\r\n const offsets = [0, 4, 2, 1];\r\n const steps = [8, 8, 4, 2];\r\n\r\n let fromRow = 0;\r\n for (let pass = 0; pass < 4; pass++) {\r\n for (let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) {\r\n cpRow(toRow, fromRow);\r\n fromRow++;\r\n }\r\n }\r\n\r\n return newPixels;\r\n };\r\n\r\n img.leftPos = this._st.readUnsigned();\r\n img.topPos = this._st.readUnsigned();\r\n img.width = this._st.readUnsigned();\r\n img.height = this._st.readUnsigned();\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n img.lctFlag = bits.shift();\r\n img.interlaced = bits.shift();\r\n img.sorted = bits.shift();\r\n img.reserved = bits.splice(0, 2);\r\n img.lctSize = bitsToNum(bits.splice(0, 3));\r\n\r\n if (img.lctFlag) {\r\n img.lct = this.parseColorTable(1 << (img.lctSize + 1));\r\n }\r\n\r\n img.lzwMinCodeSize = this._st.readByte();\r\n\r\n const lzwData = this.readSubBlocks();\r\n\r\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\r\n\r\n if (img.interlaced) {\r\n // Move\r\n img.pixels = deinterlace(img.pixels, img.width);\r\n }\r\n\r\n this.frames.push(img);\r\n this.arrayToImage(img);\r\n if (this._handler.img && this._handler.img(img)) {\r\n this.checkBytes.push(this._handler);\r\n }\r\n };\r\n\r\n public parseBlock = () => {\r\n const block = {\r\n sentinel: this._st.readByte(),\r\n type: ''\r\n };\r\n const blockChar = String.fromCharCode(block.sentinel);\r\n switch (blockChar) {\r\n case '!':\r\n block.type = 'ext';\r\n this.parseExt(block);\r\n break;\r\n case ',':\r\n block.type = 'img';\r\n this.parseImg(block);\r\n break;\r\n case ';':\r\n block.type = 'eof';\r\n if (this._handler.eof && this._handler.eof(block)) {\r\n this.checkBytes.push(this._handler.eof);\r\n }\r\n break;\r\n default:\r\n throw new Error('Unknown block: 0x' + block.sentinel.toString(16));\r\n }\r\n\r\n if (block.type !== 'eof') {\r\n this.parseBlock();\r\n }\r\n };\r\n\r\n arrayToImage = (frame: GifFrame) => {\r\n let count = 0;\r\n const c = document.createElement('canvas');\r\n c.id = count.toString();\r\n c.width = frame.width;\r\n c.height = frame.height;\r\n count++;\r\n const context = c.getContext('2d');\r\n const pixSize = 1;\r\n let y = 0;\r\n let x = 0;\r\n for (let i = 0; i < frame.pixels.length; i++) {\r\n if (x % frame.width === 0) {\r\n y++;\r\n x = 0;\r\n }\r\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) {\r\n context.fillStyle = `rgba(0, 0, 0, 0)`;\r\n } else {\r\n context.fillStyle = this.globalColorTable[frame.pixels[i]];\r\n }\r\n\r\n context.fillRect(x, y, pixSize, pixSize);\r\n x++;\r\n }\r\n const img = new Image();\r\n img.src = c.toDataURL();\r\n this.images.push(img);\r\n };\r\n}\r\n","import { Font } from '../Graphics/Font';\r\nimport { FontOptions } from '../Graphics/FontCommon';\r\nimport { GraphicOptions, RasterOptions } from '../Graphics';\r\nimport { Loadable } from '../Interfaces/Loadable';\r\nimport { Resource } from './Resource';\r\n\r\n\r\nexport interface FontSourceOptions\r\n extends Omit,\r\n GraphicOptions,\r\n RasterOptions {\r\n /**\r\n * Whether or not to cache-bust requests\r\n */\r\n bustCache?: boolean\r\n}\r\n\r\nexport class FontSource implements Loadable {\r\n private _resource: Resource;\r\n private _isLoaded = false;\r\n private _options: FontSourceOptions;\r\n\r\n data!: FontFace;\r\n\r\n\r\n constructor(\r\n /**\r\n * Path to the font resource relative from the HTML document hosting the game, or absolute\r\n */\r\n public readonly path: string,\r\n /**\r\n * The font family name\r\n */\r\n public readonly family: string,\r\n { bustCache, ...options }: FontSourceOptions = {}\r\n ) {\r\n this._resource = new Resource(path, 'blob', bustCache);\r\n this._options = options;\r\n }\r\n\r\n async load(): Promise {\r\n if (this.isLoaded()) {\r\n return this.data;\r\n }\r\n\r\n try {\r\n const blob = await this._resource.load();\r\n const url = URL.createObjectURL(blob);\r\n\r\n if (!this.data) {\r\n this.data = new FontFace(this.family, `url(${url})`);\r\n document.fonts.add(this.data);\r\n }\r\n\r\n await this.data.load();\r\n this._isLoaded = true;\r\n } catch (error) {\r\n throw `Error loading FontSource from path '${this.path}' with error [${\r\n (error as Error).message\r\n }]`;\r\n }\r\n return this.data;\r\n }\r\n\r\n isLoaded(): boolean {\r\n return this._isLoaded;\r\n }\r\n\r\n /**\r\n * Build a font from this FontSource.\r\n * @param options {FontOptions} Override the font options\r\n */\r\n toFont(options?: FontOptions): Font {\r\n return new Font({ family: this.family, ...this._options, ...options });\r\n }\r\n}\r\n","export * from './Resource';\r\nexport * from './Sound/Index';\r\nexport * from './Gif';\r\nexport * from './Font';","export * from './Component';\r\nexport * from './Entity';\r\nexport * from './EntityManager';\r\nexport * from './Query';\r\nexport * from './TagQuery';\r\nexport * from './QueryManager';\r\nexport * from './System';\r\nexport * from './SystemManager';\r\nexport * from './World';\r\nexport * from './Types';\r\nexport * from './Priority';\r\n\r\nexport * from './Components/TransformComponent';\r\nexport * from './Components/MotionComponent';\r\n","import { Engine } from '../Engine';\r\nexport type CoroutineGenerator = () => Generator, void, number>;\r\n\r\n/**\r\n * Excalibur coroutine helper, returns a promise when complete. Coroutines run before frame update.\r\n *\r\n * Each coroutine yield is 1 excalibur frame. Coroutines get passed the elapsed time our of yield. Coroutines\r\n * run internally on the excalibur clock.\r\n *\r\n * If you yield a promise it will be awaited before resumed\r\n * If you yield a number it will wait that many ms before resumed\r\n * @param engine\r\n * @param coroutineGenerator\r\n */\r\nexport function coroutine(engine: Engine, coroutineGenerator: CoroutineGenerator): Promise {\r\n return new Promise((resolve, reject) => {\r\n const generator = coroutineGenerator();\r\n const loop = (elapsedMs: number) => {\r\n try {\r\n const { done, value } = generator.next(elapsedMs);\r\n if (done) {\r\n resolve();\r\n }\r\n\r\n if (value instanceof Promise) {\r\n value.then(() => {\r\n // schedule next loop\r\n engine.clock.schedule(loop);\r\n });\r\n } else if (value === undefined || value === (void 0)) {\r\n // schedule next frame\r\n engine.clock.schedule(loop);\r\n } else {\r\n // schedule value milliseconds from now\r\n engine.clock.schedule(loop, value || 0);\r\n }\r\n } catch (e) {\r\n reject(e);\r\n }\r\n };\r\n loop(engine.clock.elapsed());// run first frame immediately\r\n });\r\n}","import { Engine } from '../Engine';\r\nimport { Scene } from '../Scene';\r\nimport { Future } from '../Util/Future';\r\nimport { Entity, TransformComponent } from '../EntityComponentSystem';\r\nimport { GraphicsComponent } from '../Graphics';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { Vector } from '../Math/vector';\r\nimport { clamp } from '../Math/util';\r\nimport { EasingFunction, EasingFunctions } from '../Util/EasingFunctions';\r\nimport { coroutine } from '../Util/Coroutine';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport interface TransitionOptions {\r\n /**\r\n * Transition duration in milliseconds\r\n */\r\n duration: number;\r\n\r\n /**\r\n * Optionally hides the loader during the transition\r\n *\r\n * If either the out or in transition have this set to true, then the loader will be hidden.\r\n *\r\n * Default false\r\n */\r\n hideLoader?: boolean;\r\n\r\n /**\r\n * Optionally blocks user input during a transition\r\n *\r\n * Default false\r\n */\r\n blockInput?: boolean;\r\n\r\n /**\r\n * Optionally specify a easing function, by default linear\r\n */\r\n easing?: EasingFunction;\r\n /**\r\n * Optionally specify a transition direction, by default 'out'\r\n *\r\n * * For 'in' direction transitions start at 1 and complete is at 0\r\n * * For 'out' direction transitions start at 0 and complete is at 1\r\n */\r\n direction?: 'out' | 'in';\r\n}\r\n\r\n/**\r\n * Base Transition that can be extended to provide custom scene transitions in Excalibur.\r\n */\r\nexport class Transition extends Entity {\r\n private _logger: Logger = Logger.getInstance();\r\n transform = new TransformComponent();\r\n graphics = new GraphicsComponent();\r\n readonly hideLoader: boolean;\r\n readonly blockInput: boolean;\r\n readonly duration: number;\r\n readonly easing: EasingFunction;\r\n readonly direction: 'out' | 'in';\r\n private _completeFuture = new Future();\r\n\r\n // State needs to be reset between uses\r\n public started = false;\r\n private _currentDistance: number = 0;\r\n private _currentProgress: number = 0;\r\n\r\n public done = this._completeFuture.promise;\r\n\r\n /**\r\n * Returns a number between [0, 1] indicating what state the transition is in.\r\n *\r\n * * For 'out' direction transitions start at 0 and end at 1\r\n * * For 'in' direction transitions start at 1 and end at 0\r\n */\r\n get progress(): number {\r\n return this._currentProgress;\r\n }\r\n\r\n get complete(): boolean {\r\n if (this.direction === 'out') {\r\n return this.progress >= 1;\r\n } else {\r\n return this.progress <= 0;\r\n }\r\n }\r\n\r\n constructor(options: TransitionOptions) {\r\n super();\r\n this.name = `Transition#${this.id}`;\r\n this.duration = options.duration;\r\n this.easing = options.easing ?? EasingFunctions.Linear;\r\n this.direction = options.direction ?? 'out';\r\n this.hideLoader = options.hideLoader ?? false;\r\n this.blockInput = options.blockInput ?? false;\r\n this.transform.coordPlane = CoordPlane.Screen;\r\n this.transform.pos = Vector.Zero;\r\n this.transform.z = Infinity; // Transitions sit on top of everything\r\n this.graphics.anchor = Vector.Zero;\r\n this.addComponent(this.transform);\r\n this.addComponent(this.graphics);\r\n\r\n if (this.direction === 'out') {\r\n this._currentProgress = 0;\r\n } else {\r\n this._currentProgress = 1;\r\n }\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called before each update.\r\n *\r\n * **WARNING BE SURE** to call `super.updateTransition()` if overriding in your own custom implementation\r\n * @param engine\r\n * @param delta\r\n */\r\n public updateTransition(engine: Engine, delta: number): void {\r\n if (this.complete) {\r\n return;\r\n }\r\n\r\n this._currentDistance += clamp(delta / this.duration, 0, 1);\r\n if (this._currentDistance >= 1) {\r\n this._currentDistance = 1;\r\n }\r\n\r\n if (this.direction === 'out') {\r\n this._currentProgress = clamp(this.easing(this._currentDistance, 0, 1, 1), 0, 1);\r\n } else {\r\n this._currentProgress = clamp(this.easing(this._currentDistance, 1, 0, 1), 0, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called right before the previous scene has deactivated.\r\n *\r\n * This gives incoming transition a chance to grab info from previous scene if desired\r\n * @param scene\r\n */\r\n async onPreviousSceneDeactivate(scene: Scene) {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called once at the beginning of the transition\r\n *\r\n * `progress` is given between 0 and 1\r\n * @param progress\r\n */\r\n onStart(progress: number) {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called every frame of the transition\r\n *\r\n * `progress` is given between 0 and 1\r\n * @param progress\r\n */\r\n onUpdate(progress: number) {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called at the end of the transition,\r\n *\r\n * `progress` is given between 0 and 1\r\n * @param progress\r\n */\r\n onEnd(progress: number) {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called when the transition is reset\r\n *\r\n * Use this to override and provide your own reset logic for internal state in custom transition implementations\r\n */\r\n onReset() {\r\n // override me\r\n }\r\n\r\n /**\r\n * reset() is called by the engine to reset transitions\r\n */\r\n reset() {\r\n this.started = false;\r\n this._completeFuture = new Future();\r\n this.done = this._completeFuture.promise;\r\n this._currentDistance = 0;\r\n if (this.direction === 'out') {\r\n this._currentProgress = 0;\r\n } else {\r\n this._currentProgress = 1;\r\n }\r\n this.onReset();\r\n }\r\n\r\n play(engine: Engine, targetScene?: Scene) {\r\n if (this.started) {\r\n this.reset();\r\n this._logger.warn(`Attempted to play a transition ${this.name} that is already playing, reset transition.`);\r\n }\r\n\r\n const currentScene = targetScene ?? engine.currentScene;\r\n currentScene.add(this);\r\n const self = this;\r\n return coroutine(engine, function * () {\r\n while (!self.complete) {\r\n const elapsed = yield; // per frame\r\n self.updateTransition(engine, elapsed);\r\n self.execute();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * execute() is called by the engine every frame to update the Transition lifecycle onStart/onUpdate/onEnd\r\n */\r\n execute() {\r\n if (!this.isInitialized) {\r\n return;\r\n }\r\n\r\n if (!this.started) {\r\n this.started = true;\r\n this.onStart(this.progress);\r\n }\r\n\r\n this.onUpdate(this.progress);\r\n\r\n if (this.complete && !this._completeFuture.isCompleted) {\r\n this.onEnd(this.progress);\r\n this._completeFuture.resolve();\r\n }\r\n }\r\n}","import { Engine } from '../Engine';\r\nimport { Color } from '../Color';\r\nimport { Rectangle } from '../Graphics';\r\nimport { Transition, TransitionOptions } from './Transition';\r\n\r\nexport interface FadeOptions {\r\n duration?: number;\r\n color?: Color;\r\n}\r\n\r\nexport class FadeInOut extends Transition {\r\n screenCover: Rectangle;\r\n color: Color;\r\n constructor(options: FadeOptions & TransitionOptions) {\r\n super({\r\n ...options,\r\n duration: options.duration ?? 2000\r\n });\r\n this.name = `FadeInOut#${this.id}`;\r\n this.color = options.color ?? Color.Black;\r\n }\r\n\r\n public onInitialize(engine: Engine): void {\r\n this.transform.pos = engine.screen.unsafeArea.topLeft;\r\n this.screenCover = new Rectangle({\r\n width: engine.screen.resolution.width,\r\n height: engine.screen.resolution.height,\r\n color: this.color\r\n });\r\n this.graphics.add(this.screenCover);\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onReset() {\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onStart(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n\r\n override onEnd(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n\r\n override onUpdate(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n}","import { ImageSource, Sprite } from '../Graphics';\r\nimport { Engine } from '../Engine';\r\nimport { Scene } from '../Scene';\r\nimport { Transition, TransitionOptions } from './Transition';\r\nimport { vec } from '../Math/vector';\r\n\r\nexport interface CrossFadeOptions {\r\n duration: number;\r\n}\r\n\r\n/**\r\n * CrossFades between the previous scene and the destination scene\r\n *\r\n * Note: CrossFade only works as an \"in\" transition\r\n */\r\nexport class CrossFade extends Transition {\r\n engine: Engine;\r\n image: HTMLImageElement;\r\n screenCover: Sprite;\r\n constructor(options: TransitionOptions & CrossFadeOptions) {\r\n super({direction: 'in', ...options}); // default the correct direction\r\n this.name = `CrossFade#${this.id}`;\r\n }\r\n\r\n override async onPreviousSceneDeactivate(scene: Scene) {\r\n this.image = await scene.engine.screenshot(true);\r\n // Firefox is particularly slow\r\n // needed in case the image isn't ready yet\r\n await this.image.decode();\r\n }\r\n\r\n override onInitialize(engine: Engine): void {\r\n this.engine = engine;\r\n this.transform.pos = engine.screen.unsafeArea.topLeft;\r\n this.screenCover = ImageSource.fromHtmlImageElement(this.image).toSprite();\r\n this.graphics.add(this.screenCover);\r\n this.transform.scale = vec(1 / engine.screen.pixelRatio, 1 / engine.screen.pixelRatio);\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onStart(_progress: number): void {\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onReset() {\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onEnd(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n\r\n override onUpdate(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n}","\r\nexport * from './Transition';\r\nexport * from './FadeInOut';\r\nexport * from './CrossFade';\r\nexport * from './Director';\r\nexport * from './Loader';\r\nexport * from './DefaultLoader';","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Graphic } from './Graphic';\r\n\r\nexport interface LineOptions {\r\n start: Vector;\r\n end: Vector;\r\n color?: Color;\r\n thickness?: number;\r\n}\r\nexport class Line extends Graphic {\r\n readonly start: Vector;\r\n readonly end: Vector;\r\n color: Color = Color.Black;\r\n thickness: number = 1;\r\n private _localBounds: BoundingBox;\r\n constructor(options: LineOptions) {\r\n super();\r\n const { start, end, color, thickness } = options;\r\n this.start = start;\r\n this.end = end;\r\n this.color = color ?? this.color;\r\n this.thickness = thickness ?? this.thickness;\r\n this._localBounds = this._calculateBounds();\r\n const { width, height } = this._localBounds;\r\n\r\n this.width = width;\r\n this.height = height;\r\n }\r\n\r\n public get localBounds() {\r\n return this._localBounds;\r\n }\r\n\r\n private _calculateBounds(): BoundingBox {\r\n const lineNormal = this.end.sub(this.start).normal();\r\n\r\n const halfThickness = this.thickness / 2;\r\n\r\n const points = [\r\n this.start.add(lineNormal.scale(halfThickness)),\r\n this.end.add(lineNormal.scale(halfThickness)),\r\n this.end.add(lineNormal.scale(-halfThickness)),\r\n this.start.add(lineNormal.scale(-halfThickness))\r\n ];\r\n\r\n return BoundingBox.fromPoints(points);\r\n }\r\n\r\n protected _drawImage(ctx: ExcaliburGraphicsContext, _x: number, _y: number): void {\r\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\r\n }\r\n\r\n clone(): Line {\r\n return new Line({\r\n start: this.start,\r\n end: this.end,\r\n color: this.color,\r\n thickness: this.thickness\r\n });\r\n }\r\n}","import { ImageFiltering } from './Filtering';\r\nimport { Vector, vec } from '../Math/vector';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface PolygonOptions {\r\n points: Vector[];\r\n}\r\n\r\n/**\r\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Polygons default to [[ImageFiltering.Blended]]\r\n */\r\nexport class Polygon extends Raster {\r\n private _points: Vector[];\r\n public get points(): Vector[] {\r\n return this._points;\r\n }\r\n public set points(points: Vector[]) {\r\n this._points = points;\r\n const min = this.minPoint;\r\n this.width = this._points.reduce((max, p) => Math.max(p.x, max), 0) - min.x;\r\n this.height = this._points.reduce((max, p) => Math.max(p.y, max), 0) - min.y;\r\n this.flagDirty();\r\n }\r\n\r\n public get minPoint() {\r\n const minX = this._points.reduce((min, p) => Math.min(p.x, min), Infinity);\r\n const minY = this._points.reduce((min, p) => Math.min(p.y, min), Infinity);\r\n return vec(minX, minY);\r\n }\r\n\r\n constructor(options: RasterOptions & PolygonOptions) {\r\n super(options);\r\n this.points = options.points;\r\n this.filtering = ImageFiltering.Blended;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Polygon {\r\n return new Polygon({\r\n points: this.points.map((p) => p.clone()),\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.points && this.points.length) {\r\n ctx.beginPath();\r\n // Iterate through the supplied points and construct a 'polygon'\r\n const min = this.minPoint.negate();\r\n const firstPoint = this.points[0].add(min);\r\n ctx.moveTo(firstPoint.x, firstPoint.y);\r\n this.points.forEach((point) => {\r\n ctx.lineTo(point.x + min.x, point.y + min.y);\r\n });\r\n ctx.lineTo(firstPoint.x, firstPoint.y);\r\n ctx.closePath();\r\n if (this.color) {\r\n ctx.fill();\r\n }\r\n if (this.strokeColor) {\r\n ctx.stroke();\r\n }\r\n }\r\n }\r\n}\r\n","// Graphics\r\nexport * from './Graphic';\r\nexport * from './Sprite';\r\nexport * from './SpriteSheet';\r\nexport * from './GraphicsGroup';\r\nexport * from './ImageSource';\r\nexport * from './Animation';\r\nexport * from './Line';\r\n\r\n// Graphics ECS\r\nexport * from './GraphicsComponent';\r\nexport * from './DebugGraphicsComponent';\r\nexport * from './GraphicsSystem';\r\nexport * from './OffscreenSystem';\r\nexport * from './ParallaxComponent';\r\n\r\n// Raster graphics\r\nexport * from './Raster';\r\nexport * from './Circle';\r\nexport * from './Rectangle';\r\nexport * from './Polygon';\r\nexport * from './Text';\r\nexport * from './FontCommon';\r\nexport * from './Font';\r\nexport * from './FontCache';\r\nexport * from './SpriteFont';\r\nexport * from './Canvas';\r\n\r\nexport * from './Context/ExcaliburGraphicsContext';\r\nexport * from './Context/ExcaliburGraphicsContext2DCanvas';\r\nexport * from './Context/ExcaliburGraphicsContextWebGL';\r\n\r\nexport * from './Context/debug-text';\r\n\r\n// Post Processor\r\nexport * from './PostProcessor/PostProcessor';\r\nexport * from './PostProcessor/ScreenShader';\r\nexport * from './PostProcessor/ColorBlindnessMode';\r\nexport * from './PostProcessor/ColorBlindnessPostProcessor';\r\n\r\nexport * from './Context/texture-loader';\r\nexport * from './Filtering';\r\n\r\n\r\n// Rendering\r\nexport * from './Context/shader';\r\nexport * from './Context/vertex-buffer';\r\nexport * from './Context/vertex-layout';\r\nexport * from './Context/quad-index-buffer';\r\nexport * from './Context/material';\r\n\r\n// Debug\r\nexport * from './Debug';\r\n\r\n// Util\r\n\r\nimport * as webgl from './Context/webgl-util';\r\nexport { webgl };","// This import site is deprecated\r\n// TODO remove deprecated exports in v0.29.0\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.WheelEvent import site will be removed in v0.29.0, use ex.WheelEvent\r\n */\r\n WheelEvent\r\n} from './WheelEvent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerEvent import site will be removed in v0.29.0, use ex.PointerEvent\r\n */\r\n PointerEvent\r\n} from './PointerEvent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.WheelDeltaMode import site will be removed in v0.29.0, use ex.WheelDeltaMode\r\n */\r\n WheelDeltaMode\r\n} from './WheelDeltaMode';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerButton import site will be removed in v0.29.0, use ex.PointerButton\r\n */\r\n PointerButton\r\n} from './PointerButton';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.NativePointerButton import site will be removed in v0.29.0, use ex.NativePointerButton\r\n */\r\n NativePointerButton\r\n} from './NativePointerButton';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.CapturePointerConfig import site will be removed in v0.29.0, use ex.CapturePointerConfig\r\n */\r\n CapturePointerConfig\r\n} from './CapturePointerConfig';\r\n\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.NativePointerEvent import site will be removed in v0.29.0, use ex.NativePointerEvent\r\n */\r\n NativePointerEvent,\r\n /**\r\n * @deprecated ex.Input.NativeMouseEvent import site will be removed in v0.29.0, use ex.NativeMouseEvent\r\n */\r\n NativeMouseEvent,\r\n /**\r\n * @deprecated ex.Input.NativeTouchEvent import site will be removed in v0.29.0, use ex.NativeTouchEvent\r\n */\r\n NativeTouchEvent,\r\n /**\r\n * @deprecated ex.Input.NativeWheelEvent import site will be removed in v0.29.0, use ex.NativeWheelEvent\r\n */\r\n NativeWheelEvent,\r\n /**\r\n * @deprecated ex.Input.PointerInitOptions import site will be removed in v0.29.0, use ex.PointerInitOptions\r\n */\r\n PointerInitOptions,\r\n /**\r\n * @deprecated ex.Input.PointerEventReceiver import site will be removed in v0.29.0, use ex.PointerEventReceiver\r\n */\r\n PointerEventReceiver\r\n} from './PointerEventReceiver';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerComponent import site will be removed in v0.29.0, use ex.PointerComponent\r\n */\r\n PointerComponent\r\n} from './PointerComponent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerSystem import site will be removed in v0.29.0, use ex.PointerSystem\r\n */\r\n PointerSystem\r\n} from './PointerSystem';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerType import site will be removed in v0.29.0, use ex.PointerType\r\n */\r\n PointerType\r\n} from './PointerType';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerScope import site will be removed in v0.29.0, use ex.PointerScope\r\n */\r\n PointerScope\r\n} from './PointerScope';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.Keys import site will be removed in v0.29.0, use ex.Keys\r\n */\r\n Keys,\r\n /**\r\n * @deprecated ex.Input.KeyEvent import site will be removed in v0.29.0, use ex.KeyEvent\r\n */\r\n KeyEvent,\r\n /**\r\n * @deprecated ex.Input.KeyboardInitOptions import site will be removed in v0.29.0, use ex.KeyboardInitOptions\r\n */\r\n KeyboardInitOptions,\r\n /**\r\n * @deprecated ex.Input.Keyboard import site will be removed in v0.29.0, use ex.Keyboard\r\n */\r\n Keyboard\r\n} from './Keyboard';\r\n\r\n// Re-export hack to deprecate import site gently\r\nexport {\r\n /**\r\n * @deprecated ex.Input.Gamepads import site will be removed in v0.29.0, use ex.Gamepads\r\n */\r\n Gamepads,\r\n /**\r\n * @deprecated ex.Input.Gamepad import site will be removed in v0.29.0, use ex.Gamepad\r\n */\r\n Gamepad,\r\n /**\r\n * @deprecated ex.Input.Buttons import site will be removed in v0.29.0, use ex.Buttons\r\n */\r\n Buttons,\r\n /**\r\n * @deprecated ex.Input.Axes import site will be removed in v0.29.0, use ex.Axes\r\n */\r\n Axes,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepads import site will be removed in v0.29.0, use ex.NavigatorGamepads\r\n */\r\n NavigatorGamepads,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepad import site will be removed in v0.29.0, use ex.NavigatorGamepad\r\n */\r\n NavigatorGamepad,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepadButton import site will be removed in v0.29.0, use ex.NavigatorGamepadButton\r\n */\r\n NavigatorGamepadButton,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepadEvent import site will be removed in v0.29.0, use ex.NavigatorGamepadEvent\r\n */\r\n NavigatorGamepadEvent,\r\n /**\r\n * @deprecated ex.Input.GamepadConfiguration import site will be removed in v0.29.0, use ex.GamepadConfiguration\r\n */\r\n GamepadConfiguration\r\n} from './Gamepad';","export * from './Util';\r\n\r\nexport * from './Log';\r\n\r\nexport * from './Observable';\r\n\r\nexport * from './EasingFunctions';\r\n\r\nimport * as drawUtil from './DrawUtil';\r\nexport { drawUtil as DrawUtil };\r\n","import { Flags } from '../Flags';\r\nimport { Logger } from './Log';\r\n\r\n/**\r\n * Obsolete decorator options\r\n */\r\nexport interface ObsoleteOptions {\r\n // Optionally specify a custom message\r\n message?: string;\r\n // Optionally indicate that an alternate method to the obsolete one exists\r\n alternateMethod?: string;\r\n // Optional show stack trace, by default off\r\n showStackTrace?: boolean;\r\n}\r\n\r\nexport const maxMessages = 5;\r\nconst obsoleteMessage: { [messageCount: string]: number } = {};\r\nexport const resetObsoleteCounter = () => {\r\n for (const message in obsoleteMessage) {\r\n obsoleteMessage[message] = 0;\r\n }\r\n};\r\n\r\nconst logMessage = (message: string, options: ObsoleteOptions) => {\r\n const suppressObsoleteMessages = Flags.isEnabled('suppress-obsolete-message');\r\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\r\n Logger.getInstance().warn(message);\r\n\r\n // tslint:disable-next-line: no-console\r\n if (console.trace && options.showStackTrace) {\r\n // tslint:disable-next-line: no-console\r\n console.trace();\r\n }\r\n }\r\n obsoleteMessage[message]++;\r\n};\r\n\r\n/**\r\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\r\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\r\n */\r\nexport function obsolete(options?: ObsoleteOptions): any {\r\n options = {\r\n message: 'This feature will be removed in future versions of Excalibur.',\r\n alternateMethod: null,\r\n showStackTrace: false,\r\n ...options\r\n };\r\n\r\n return function (target: any, property: string, descriptor: PropertyDescriptor): any {\r\n if (\r\n descriptor &&\r\n !(typeof descriptor.value === 'function' || typeof descriptor.get === 'function' || typeof descriptor.set === 'function')\r\n ) {\r\n throw new SyntaxError('Only classes/functions/getters/setters can be marked as obsolete');\r\n }\r\n const methodSignature = `${target.name || ''}${target.name && property ? '.' : ''}${property ? property : ''}`;\r\n\r\n const message =\r\n `${methodSignature} is marked obsolete: ${options.message}` +\r\n (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : '');\r\n\r\n if (!obsoleteMessage[message]) {\r\n obsoleteMessage[message] = 0;\r\n }\r\n\r\n // If descriptor is null it is a class\r\n const method = descriptor ? { ...descriptor } : target;\r\n if (!descriptor) {\r\n // with es2015 classes we need to change our decoration tactic\r\n class DecoratedClass extends method {\r\n constructor(...args: any) {\r\n logMessage(message, options);\r\n super(...args);\r\n }\r\n }\r\n return DecoratedClass;\r\n }\r\n\r\n if (descriptor && descriptor.value) {\r\n method.value = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.value.apply(this, arguments);\r\n };\r\n return method;\r\n }\r\n\r\n if (descriptor && descriptor.get) {\r\n method.get = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.get.apply(this, arguments);\r\n };\r\n }\r\n\r\n if (descriptor && descriptor.set) {\r\n method.set = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.set.apply(this, arguments);\r\n };\r\n }\r\n return method;\r\n };\r\n}\r\n","import { Future } from './Future';\r\n\r\nclass AsyncWaitQueue {\r\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\r\n private _queue: Future[] = [];\r\n\r\n public get length(): number {\r\n return this._queue.length;\r\n }\r\n\r\n public enqueue(): Promise {\r\n const future = new Future();\r\n this._queue.push(future);\r\n return future.promise;\r\n }\r\n\r\n public dequeue(value: T): void {\r\n const future = this._queue.shift();\r\n future.resolve(value);\r\n }\r\n}\r\n\r\n/**\r\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\r\n *\r\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\r\n * around browser limitations like max Image.decode() calls in chromium being 256.\r\n */\r\nexport class Semaphore {\r\n private _waitQueue = new AsyncWaitQueue();\r\n constructor(private _count: number) { }\r\n\r\n public get count() {\r\n return this._count;\r\n }\r\n\r\n public get waiting() {\r\n return this._waitQueue.length;\r\n }\r\n\r\n // eslint-disable-next-line require-await\r\n public async enter() {\r\n if (this._count !== 0) {\r\n this._count--;\r\n return Promise.resolve();\r\n }\r\n return this._waitQueue.enqueue();\r\n }\r\n\r\n public exit(count: number = 1) {\r\n if (count === 0) {\r\n return;\r\n }\r\n while (count !== 0 && this._waitQueue.length !== 0) {\r\n this._waitQueue.dequeue(null);\r\n count--;\r\n }\r\n this._count += count;\r\n }\r\n}","/**\r\n * The current Excalibur version string\r\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\r\n */\r\nexport const EX_VERSION = process.env.__EX_VERSION;\r\nimport { polyfill } from './Polyfill';\r\npolyfill();\r\n\r\n// This file is used as the bundle entry point and exports everything\r\n// that will be exposed as the `ex` global variable.\r\nexport * from './Flags';\r\nexport * from './Id';\r\nexport * from './Engine';\r\nexport * from './Screen';\r\nexport { Actor, ActorArgs } from './Actor';\r\nexport * from './Math/Index';\r\nexport * from './Camera';\r\nexport * from './Configurable';\r\nexport * from './Debug/index';\r\nexport * from './EventDispatcher';\r\nexport * from './EventEmitter';\r\nexport * from './Events/MediaEvents';\r\nexport * from './Events';\r\nexport * from './Label';\r\nexport { FontStyle, FontUnit, TextAlign, BaseAlign } from './Graphics/FontCommon';\r\nexport { Particle, ParticleTransform, ParticleEmitter, ParticleArgs, ParticleEmitterArgs, EmitterType } from './Particles';\r\nexport * from './Collision/Physics';\r\nexport * from './Scene';\r\n\r\nexport * from './TileMap/index';\r\n\r\nexport * from './Timer';\r\nexport * from './Trigger';\r\nexport * from './ScreenElement';\r\n\r\nexport * from './Actions/Index';\r\nexport * from './Collision/Index';\r\n\r\nexport * from './Interfaces/Index';\r\nexport * from './Resources/Index';\r\n\r\nexport * from './EntityComponentSystem/index';\r\n\r\nexport * from './Director/index';\r\n\r\nexport * from './Color';\r\n\r\nexport * from './Graphics/index';\r\n\r\n// ex.Events namespace\r\nimport * as events from './Events';\r\nexport { events as Events };\r\n\r\n// ex.Input namespace\r\n// TODO deprecated import site remove in v0.29.0\r\nimport * as input from './Input/Index';\r\nexport { input as Input };\r\n\r\nexport {\r\n WheelEvent\r\n} from './Input/WheelEvent';\r\n\r\nexport {\r\n PointerEvent\r\n} from './Input/PointerEvent';\r\n\r\nexport {\r\n WheelDeltaMode\r\n} from './Input/WheelDeltaMode';\r\n\r\nexport {\r\n PointerButton\r\n} from './Input/PointerButton';\r\n\r\nexport {\r\n NativePointerButton\r\n} from './Input/NativePointerButton';\r\n\r\nexport {\r\n CapturePointerConfig\r\n} from './Input/CapturePointerConfig';\r\n\r\n\r\nexport {\r\n NativePointerEvent,\r\n NativeMouseEvent,\r\n NativeTouchEvent,\r\n NativeWheelEvent,\r\n PointerInitOptions,\r\n PointerEventReceiver\r\n} from './Input/PointerEventReceiver';\r\n\r\nexport { PointerAbstraction } from './Input/PointerAbstraction';\r\nexport { PointerComponent } from './Input/PointerComponent';\r\nexport { PointerSystem } from './Input/PointerSystem';\r\nexport { PointerType } from './Input/PointerType';\r\nexport { PointerScope } from './Input/PointerScope';\r\n\r\nexport {\r\n Gamepads,\r\n Gamepad,\r\n Buttons,\r\n Axes,\r\n NavigatorGamepads,\r\n NavigatorGamepad,\r\n NavigatorGamepadButton,\r\n NavigatorGamepadEvent,\r\n GamepadConfiguration\r\n} from './Input/Gamepad';\r\n\r\nexport {\r\n Keys,\r\n KeyEvent,\r\n KeyboardInitOptions,\r\n Keyboard\r\n} from './Input/Keyboard';\r\nexport * from './Input/InputHost';\r\nexport * from './Input/InputMapper';\r\n\r\n// ex.Util namespaces\r\nimport * as util from './Util/Index';\r\nexport { util as Util };\r\n\r\nexport * from './Util/Browser';\r\nexport * from './Util/Decorators';\r\nexport * from './Util/Detector';\r\nexport * from './Util/EasingFunctions';\r\nexport * from './Util/Observable';\r\nexport * from './Util/Log';\r\nexport * from './Util/Pool';\r\nexport * from './Util/Fps';\r\nexport * from './Util/Clock';\r\nexport * from './Util/WebAudio';\r\nexport * from './Util/Toaster';\r\nexport * from './Util/StateMachine';\r\nexport * from './Util/Future';\r\nexport * from './Util/Semaphore';\r\nexport * from './Util/Coroutine';\r\n\r\n// ex.Deprecated\r\n// import * as deprecated from './Deprecated';\r\n// export { deprecated as Deprecated };\r\n// export * from './Deprecated';\r\n","\nimport * as ex from \"excalibur\";\nimport { Player } from './player';\nimport { Resources, loader } from \"./resources\";\nimport { House } from \"./house\";\nimport { Overworld } from \"./overworld\";\n\nconst game = new ex.Engine({\n resolution: {\n width: 256,\n height: 256,\n },\n suppressPlayButton: true,\n displayMode: ex.DisplayMode.FitScreenAndFill,\n pixelArt: true,\n pixelRatio: 4,\n scenes: {\n overworld: {\n scene: Overworld,\n transitions: {\n out: new ex.FadeInOut({direction: 'out', duration: 1000, color: ex.Color.Black}),\n in: new ex.FadeInOut({direction: 'in', duration: 1000, color: ex.Color.Black})\n }\n },\n house: {\n scene: House,\n transitions: {\n out: new ex.FadeInOut({direction: 'out', duration: 1000, color: ex.Color.Black}),\n in: new ex.FadeInOut({direction: 'in', duration: 1000, color: ex.Color.Black})\n }\n }\n }\n});\n\nResources.LdtkResource.registerEntityIdentifierFactory('PlayerStart', (props) => {\n const player = new Player({\n name: 'player',\n anchor: ex.vec(props.entity.__pivot[0],props.entity.__pivot[1]),\n width: props.entity.width,\n height: props.entity.height,\n pos: props.worldPos,\n z: props.layer.order\n });\n return player;\n});\n\nResources.LdtkResource.registerEntityIdentifierFactory('Door', (props) => {\n const trigger = new ex.Trigger({\n width: props.entity.width,\n height: props.entity.height,\n pos: props.worldPos.add(ex.vec(props.entity.width/2, props.entity.height/2)),\n filter: (entity) => {\n return entity instanceof Player\n },\n action: () => {\n game.goToScene(props.entity.fieldInstances[0].__value);\n }\n });\n return trigger;\n});\n\nconst inTransition = new ex.FadeInOut({\n duration: 1000,\n direction: 'in',\n color: ex.Color.ExcaliburBlue\n});\ngame.start('overworld', {\n loader,\n inTransition\n});","import * as ex from 'excalibur';\nimport { Resources } from './resources';\nimport { Config } from './config';\n\nexport class Player extends ex.Actor {\n constructor(args: ex.ActorArgs) {\n super({\n ...args,\n collisionType: ex.CollisionType.Active\n })\n }\n\n onInitialize(engine: ex.Engine): void {\n const playerSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.HeroSpriteSheetPng as ex.ImageSource,\n grid: {\n spriteWidth: 16,\n spriteHeight: 16,\n rows: 8,\n columns: 8\n }\n });\n\n const leftIdle = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 1) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 1) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 1) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 1) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('left-idle', leftIdle);\n\n const rightIdle = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 2) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 2) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 2) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 2) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('right-idle', rightIdle);\n\n\n const upIdle = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 3) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 3) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 3) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 3) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('up-idle', upIdle);\n\n const downIdle = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 0) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 0) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 0) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 0) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('down-idle', downIdle);\n\n const leftWalk = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 5) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 5) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 5) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 5) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('left-walk', leftWalk);\n\n const rightWalk = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 6) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 6) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 6) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 6) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n });\n this.graphics.add('right-walk', rightWalk);\n\n const upWalk = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 7) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 7) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 7) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 7) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n });\n this.graphics.add('up-walk', upWalk);\n\n const downWalk = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 4) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 4) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 4) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 4) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n });\n this.graphics.add('down-walk', downWalk);\n }\n\n onPreUpdate(engine: ex.Engine, elapsedMs: number): void {\n this.vel = ex.Vector.Zero;\n\n this.graphics.use('down-idle');\n if (engine.input.keyboard.isHeld(ex.Input.Keys.ArrowRight)) {\n this.vel = ex.vec(Config.PlayerSpeed, 0);\n this.graphics.use('right-walk');\n }\n if (engine.input.keyboard.isHeld(ex.Input.Keys.ArrowLeft)) {\n this.vel = ex.vec(-Config.PlayerSpeed, 0);\n this.graphics.use('left-walk');\n }\n if (engine.input.keyboard.isHeld(ex.Input.Keys.ArrowUp)) {\n this.vel = ex.vec(0, -Config.PlayerSpeed);\n this.graphics.use('up-walk');\n }\n if (engine.input.keyboard.isHeld(ex.Input.Keys.ArrowDown)) {\n this.vel = ex.vec(0, Config.PlayerSpeed);\n this.graphics.use('down-walk');\n }\n\n }\n}","import { ImageFiltering, ImageSource, Loader } from \"excalibur\";\nimport { LdtkResource } from '@excaliburjs/plugin-ldtk';\nimport heroImgPath from '../res/Solaria Demo Pack Update 03/Solaria Demo Pack Update 03/16x16/Sprites/Hero 01.png';\nimport tilesetPath from '../res/Solaria Demo Pack Update 03/Solaria Demo Pack Update 03/16x16/Tilesets/Solaria Demo Update 01.png';\nimport ldtkLevel0 from '../res/top-down/Level_0.ldtkl';\nimport ldtkLevel1 from '../res/top-down/Level_1.ldtkl';\nimport ldtkHouse from '../res/top-down/House.ldtkl';\nimport ldtkPath from '../res/top-down.ldtk';\n\nexport const Resources = {\n HeroSpriteSheetPng: new ImageSource(heroImgPath),\n LdtkResource: new LdtkResource(ldtkPath, {\n useTilemapCameraStrategy: true,\n useMapBackgroundColor: true,\n // Path map intercepts and redirects to work around parcel's static bundling\n pathMap: [\n { path: 'Hero 01.png', output: heroImgPath },\n { path: 'Level_0.ldtkl', output: ldtkLevel0 },\n { path: 'Level_1.ldtkl', output: ldtkLevel1 },\n { path: 'House.ldtkl', output: ldtkHouse },\n { path: 'Solaria Demo Update 01.png', output: tilesetPath },\n ]\n })\n} as const;\n\n\nexport const loader = new Loader();\nfor (let resource of Object.values(Resources)) {\n loader.addResource(resource);\n}","!function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t(require(\"excalibur\")):\"function\"==typeof define&&define.amd?define([\"excalibur\"],t):\"object\"==typeof exports?exports.ex=t(require(\"excalibur\")):(e.ex=e.ex||{},e.ex.Plugin=e.ex.Plugin||{},e.ex.Plugin.Ldtk=t(e.ex))}(self,(e=>(()=>{\"use strict\";var t={445:(e,t,s)=>{s.r(t),s.d(t,{compare:()=>u,compareVersions:()=>l,satisfies:()=>f,validate:()=>m,validateStrict:()=>y});const r=/^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i,i=e=>{if(\"string\"!=typeof e)throw new TypeError(\"Invalid argument expected string\");const t=e.match(r);if(!t)throw new Error(`Invalid argument not valid semver ('${e}' received)`);return t.shift(),t},a=e=>\"*\"===e||\"x\"===e||\"X\"===e,n=e=>{const t=parseInt(e,10);return isNaN(t)?e:t},o=(e,t)=>{if(a(e)||a(t))return 0;const[s,r]=((e,t)=>typeof e!=typeof t?[String(e),String(t)]:[e,t])(n(e),n(t));return s>r?1:s{for(let s=0;s{const s=i(e),r=i(t),a=s.pop(),n=r.pop(),o=d(s,r);return 0!==o?o:a&&n?d(a.split(\".\"),n.split(\".\")):a||n?a?-1:1:0},u=(e,t,s)=>{h(s);const r=l(e,t);return c[s].includes(r)},c={\">\":[1],\">=\":[0,1],\"=\":[0],\"<=\":[-1,0],\"<\":[-1],\"!=\":[-1,1]},p=Object.keys(c),h=e=>{if(\"string\"!=typeof e)throw new TypeError(\"Invalid operator type, expected string but got \"+typeof e);if(-1===p.indexOf(e))throw new Error(`Invalid operator, expected one of ${p.join(\"|\")}`)},f=(e,t)=>{if((t=t.replace(/([><=]+)\\s+/g,\"$1\")).includes(\"||\"))return t.split(\"||\").some((t=>f(e,t)));if(t.includes(\" - \")){const[s,r]=t.split(\" - \",2);return f(e,`>=${s} <=${r}`)}if(t.includes(\" \"))return t.trim().replace(/\\s{2,}/g,\" \").split(\" \").every((t=>f(e,t)));const s=t.match(/^([<>=~^]+)/),r=s?s[1]:\"=\";if(\"^\"!==r&&\"~\"!==r)return u(e,t,r);const[a,n,o,,l]=i(e),[c,p,h,,m]=i(t),y=[a,n,o],_=[c,null!=p?p:\"x\",null!=h?h:\"x\"];if(m){if(!l)return!1;if(0!==d(y,_))return!1;if(-1===d(l.split(\".\"),m.split(\".\")))return!1}const v=_.findIndex((e=>\"0\"!==e))+1,g=\"~\"===r?2:v>1?v:1;return 0===d(y.slice(0,g),_.slice(0,g))&&-1!==d(y.slice(g),_.slice(g))},m=e=>\"string\"==typeof e&&/^[v\\d]/.test(e)&&r.test(e),y=e=>\"string\"==typeof e&&/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/.test(e)},961:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.EntityLayer=void 0;const r=s(205);t.EntityLayer=class{constructor(e,t,s,i){var a,n;if(this.ldtkLayer=t,this.resource=s,this.order=i,this.entities=[],this.ldtkToEntity=new Map,this.entityToLdtk=new Map,this.worldPos=(0,r.vec)(e.ldtkLevel.worldX,e.ldtkLevel.worldY),this.offset=(0,r.vec)(t.__pxTotalOffsetX,t.__pxTotalOffsetY),t.entityInstances)for(let e of t.entityInstances){const t=s.projectMetadata.defs.entities.find((t=>t.identifier===e.__identifier));if(s.factories.has(e.__identifier)){const i=s.factories.get(e.__identifier);if(i){const s=i({type:e.__identifier,worldPos:(0,r.vec)(e.px[0],e.px[1]).add(this.worldPos.add(this.offset)),entity:e,definition:t,layer:this});s&&(this.entities.push(s),this.ldtkToEntity.set(e,s),this.entityToLdtk.set(s,e))}}else{const o=new r.Actor({name:e.__identifier,pos:(0,r.vec)(e.px[0],e.px[1]).add(this.worldPos.add(this.offset)),width:e.width,height:e.height,anchor:(0,r.vec)(null!==(a=null==t?void 0:t.pivotX)&&void 0!==a?a:0,null!==(n=null==t?void 0:t.pivotY)&&void 0!==n?n:0),z:i});if(e.__tile){const t=s.tilesets.get(e.__tile.tilesetUid);if(t){const s=Math.floor(e.__tile.x/e.__tile.w),r=Math.floor(e.__tile.y/e.__tile.h),i=t.spritesheet.getSprite(s,r);i&&o.graphics.use(i)}}this.entities.push(o),this.ldtkToEntity.set(e,o),this.entityToLdtk.set(o,e)}}}runFactory(e){if(this.resource.factories.has(e)&&this.ldtkLayer.entityInstances)for(let e of this.ldtkLayer.entityInstances){const t=this.resource.projectMetadata.defs.entities.find((t=>t.identifier===e.__identifier)),s=this.resource.factories.get(e.__identifier);if(s){const i=s({type:e.__identifier,worldPos:(0,r.vec)(e.px[0],e.px[1]).add(this.worldPos.add(this.offset)),entity:e,definition:t,layer:this});if(i){const t=this.ldtkToEntity.get(e);if(t){const s=this.entities.indexOf(t);s>-1&&(this.entities.splice(s,1),this.ldtkToEntity.delete(e),this.entityToLdtk.delete(t))}return this.entities.push(i),this.ldtkToEntity.set(e,i),this.entityToLdtk.set(i,e),i}}}}getEntitiesByIdentifier(e){const t=this.getLdtkEntitiesByIdentifier(e);let s=[];for(const e of t){const t=this.ldtkToEntity.get(e);t&&s.push(t)}return s}getEntitiesByField(e,t){const s=this.getLdtkEntitiesByField(e,t);let r=[];for(const e of s){const t=this.ldtkToEntity.get(e);t&&r.push(t)}return r}getLdtkEntitiesByIdentifier(e){return this.ldtkLayer.entityInstances.filter((t=>t.__identifier.toLocaleLowerCase()===e.toLowerCase()))}getLdtkEntitiesByField(e,t){return this.ldtkLayer.entityInstances.filter((s=>{if(void 0!==t){let r=t;\"string\"==typeof t&&(r=t.toLocaleLowerCase());const i=s.fieldInstances.find((t=>t.__identifier.toLocaleLowerCase()===e.toLocaleLowerCase()));return!!i&&i.__value===r}return!!s.fieldInstances.find((t=>t.__identifier.toLocaleLowerCase()===e.toLocaleLowerCase()))}))}}},710:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.FetchLoader=void 0,t.FetchLoader=async(e,t)=>{const s=await fetch(e);switch(t.toLowerCase()){case\"xml\":default:return await s.text();case\"json\":return await s.json()}}},607:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s);var i=Object.getOwnPropertyDescriptor(t,s);i&&!(\"get\"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,r,i)}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__exportStar||function(e,t){for(var s in e)\"default\"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)};Object.defineProperty(t,\"__esModule\",{value:!0}),i(s(398),t),i(s(961),t),i(s(710),t),i(s(920),t),i(s(515),t),i(s(512),t),i(s(289),t),i(s(32),t),i(s(692),t),i(s(245),t),i(s(699),t)},920:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.IntGridLayer=void 0;const r=s(205);t.IntGridLayer=class{constructor(e,t,s,i){if(this.order=i,this.worldPos=(0,r.vec)(e.ldtkLevel.worldX,e.ldtkLevel.worldY),this.offset=(0,r.vec)(t.__pxTotalOffsetX,t.__pxTotalOffsetY),this.ldtkLayer=t,t.intGridCsv.length){const e=t.__cHei,i=t.__cWid;this.tilemap=new r.TileMap({name:t.__identifier,pos:this.worldPos.add(this.offset),tileWidth:t.__gridSize,tileHeight:t.__gridSize,rows:e,columns:i});const a=s.projectMetadata.defs.layers.find((e=>t.__identifier===e.identifier));if(a){const e=a.intGridValues.find((e=>{var t;return\"solid\"===(null===(t=null==e?void 0:e.identifier)||void 0===t?void 0:t.toLocaleLowerCase())}));for(let s=0;s{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LdtkResource=void 0;const r=s(692),i=s(32),a=s(710),n=s(699),o=s(445),d=s(289),l=s(205),u=s(515),c=s(245),p=s(512),h=s(961),f=s(920);class m{constructor(e,t){this.path=e,this.tilesets=new Map,this.levels=new Map,this.levelsByName=new Map,this.factories=new Map,this.fileLoader=a.FetchLoader,this._imageLoader=new d.LoaderCache(l.ImageSource),this._levelLoader=new d.LoaderCache(u.LevelResource),this.startZIndex=0,this.textQuality=4,this.useExcaliburWiring=!0,this.useMapBackgroundColor=!1,this.useTilemapCameraStrategy=!1,this.headless=!1,this.strict=!0;const{useExcaliburWiring:s,useTilemapCameraStrategy:r,entityIdentifierFactories:i,pathMap:n,useMapBackgroundColor:o,fileLoader:c,strict:p,headless:h,startZIndex:f}={...t};this.strict=null!=p?p:this.strict,this.headless=null!=h?h:this.headless,this.useExcaliburWiring=null!=s?s:this.useExcaliburWiring,this.useTilemapCameraStrategy=null!=r?r:this.useTilemapCameraStrategy,this.useMapBackgroundColor=null!=o?o:this.useMapBackgroundColor,this.startZIndex=null!=f?f:this.startZIndex,this.fileLoader=null!=c?c:this.fileLoader,this.pathMap=n;for(const e in i)this.registerEntityIdentifierFactory(e,i[e])}async load(){var e;const t=await this.fileLoader(this.path,\"json\");if(this.strict)try{this.projectMetadata=n.LdtkProjectMetadata.parse(t)}catch(e){throw console.error(`Could not parse LDtk map from location ${this.path}.\\nExcalibur only supports the latest version of LDtk formats as of the plugin's release.`),console.error(\"Is your map file corrupted or being interpreted as the wrong type?\"),e}else this.projectMetadata=t;(0,o.compare)(m.supportedLdtkVersion,null!==(e=this.projectMetadata.jsonVersion)&&void 0!==e?e:\"0.0.0\",\">\")&&console.warn(`The excalibur ldtk plugin officially supports ${m.supportedLdtkVersion}+, the current map has LDtk version ${this.projectMetadata.jsonVersion}`);for(let e of this.projectMetadata.defs.tilesets)if(e.relPath){const t=(0,i.pathRelativeToBase)(this.path,e.relPath,this.pathMap),s=this._imageLoader.getOrAdd(t),r=new c.Tileset({image:s,ldtkTileset:e});this.tilesets.set(e.uid,r)}else\"Internal_Icons\"!==e.identifier&&console.warn(`No tileset image provided for ${e.identifier}`);for(let e of this.projectMetadata.levels)if(e.externalRelPath){const t=(0,i.pathRelativeToBase)(this.path,e.externalRelPath,this.pathMap);this._levelLoader.getOrAdd(t,this,{headless:this.headless,strict:this.strict,fileLoader:this.fileLoader,imageLoader:this._imageLoader,pathMap:this.pathMap})}else{const t=new p.Level(e,this);this.levels.set(e.uid,t),this.levelsByName.set(e.identifier.toLowerCase(),t)}return await Promise.all([this._imageLoader.load(),this._levelLoader.load()]),this._levelLoader.values().forEach((e=>{this.levels.set(e.data.ldtkLevel.uid,e.data),this.levelsByName.set(e.data.ldtkLevel.identifier.toLowerCase(),e.data)})),this.data=this.projectMetadata}isLoaded(){return!!this.data}registerEntityIdentifierFactory(e,t){if(this.factories.set(e,t),this.isLoaded())for(let t of this.getEntityLayers())t.runFactory(e)}getLevel(e){return this.levelsByName.get(e.toLowerCase())}getEntityLayers(e){let t=[];if(e){const s=this.getLevel(e);if(s)for(let e of s.layers)e instanceof h.EntityLayer&&t.push(e)}else for(const e of this.levels.values())for(let s of e.layers)s instanceof h.EntityLayer&&t.push(s);return t}getTileLayers(e){let t=[];if(e){const s=this.getLevel(e);if(s)for(let e of s.layers)e instanceof r.TileLayer&&t.push(e)}else for(const e of this.levels.values())for(let s of e.layers)s instanceof r.TileLayer&&t.push(s);return t}getIntGridLayers(e){let t=[];if(e){const s=this.getLevel(e);if(s)for(let e of s.layers)e instanceof f.IntGridLayer&&t.push(e)}else for(const e of this.levels.values())for(let s of e.layers)s instanceof f.IntGridLayer&&t.push(s);return t}getLdtkEntitiesByIdentifier(e,t){let s=[];const r=null!=t?t:Array.from(this.levels.values()).map((e=>e.ldtkLevel.identifier));for(const t of r){const r=this.getEntityLayers(t);for(let t of r)s=s.concat(t.getLdtkEntitiesByIdentifier(e))}return s}getLdtkEntitiesByField(e,t,s){let r=[];const i=null!=s?s:Array.from(this.levels.values()).map((e=>e.ldtkLevel.identifier));for(const s of i){const i=this.getEntityLayers(s);for(let s of i)r=r.concat(s.getLdtkEntitiesByField(e,t))}return r}getEntitiesByIdentifier(e,t){let s=[];const r=null!=t?t:Array.from(this.levels.values()).map((e=>e.ldtkLevel.identifier));for(const t of r){const r=this.getEntityLayers(t);for(let t of r)s=s.concat(t.getEntitiesByIdentifier(e))}return s}getEntitiesByField(e,t,s){let r=[];const i=null!=s?s:Array.from(this.levels.values()).map((e=>e.ldtkLevel.identifier));for(const s of i){const i=this.getEntityLayers(s);for(let s of i)r=r.concat(s.getEntitiesByField(e,t))}return r}getLevelBounds(e){e=null!=e?e:Array.from(this.levelsByName.keys());let t=new l.BoundingBox;for(const s of this.levels.values()){if(!e.includes(s.ldtkLevel.identifier))continue;const r=this.getTileLayers(s.ldtkLevel.identifier)[0];r&&(t=t.combine(l.BoundingBox.fromDimension(r.tilemap.tileWidth*r.tilemap.columns,r.tilemap.tileHeight*r.tilemap.rows,l.Vector.Zero,r.tilemap.pos)))}return t}addToScene(e,t){var s,i;const{pos:a,useLevelOffsets:n}={pos:(0,l.vec)(0,0),useLevelOffsets:!0,...t};for(let[i,o]of this.levels.entries())if(!(null===(s=null==t?void 0:t.levelFilter)||void 0===s?void 0:s.length)||t.levelFilter.includes(o.ldtkLevel.identifier))for(let t of o.layers)if(t instanceof r.TileLayer||t instanceof f.IntGridLayer)t.tilemap.pos=t.tilemap.pos.add(a),n||(t.tilemap.pos=t.tilemap.pos.sub(t.worldPos)),e.add(t.tilemap);else for(let s of t.entities){const r=s.get(l.TransformComponent);r&&(r.pos=r.pos.add(a),n||(r.pos=r.pos.sub(t.worldPos))),e.add(s)}if(this.useExcaliburWiring){const t=this.getLdtkEntitiesByField(\"camera\",!0)[0];if(t){e.camera.pos=(0,l.vec)(t.px[0],t.px[0]);const s=t.fieldInstances.find((e=>\"zoom\"===e.__identifier.toLocaleLowerCase()));s&&(e.camera.zoom=+s.__value)}}if(this.useTilemapCameraStrategy){let s=this.getLevelBounds(null==t?void 0:t.levelFilter);e.camera.strategy.limitCameraBounds(s)}if(this.useMapBackgroundColor)for(let[s,r]of this.levels.entries())if(!(null===(i=null==t?void 0:t.levelFilter)||void 0===i?void 0:i.length)||t.levelFilter.includes(r.ldtkLevel.identifier)){e.backgroundColor=r.backgroundColor;break}}}t.LdtkResource=m,m.supportedLdtkVersion=\"1.5.3\"},515:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LevelResource=void 0;const r=s(205),i=s(289),a=s(710),n=s(512),o=s(699);t.LevelResource=class{constructor(e,t,s){this.path=e,this.resource=t,this.fileLoader=a.FetchLoader,this.strict=!0,this.headless=!1;const{headless:n,strict:o,fileLoader:d,imageLoader:l,pathMap:u}={...s};this.fileLoader=null!=d?d:this.fileLoader,this.strict=null!=o?o:this.strict,this.headless=null!=n?n:this.headless,this.imageLoader=null!=l?l:new i.LoaderCache(r.ImageSource),this.pathMap=null!=u?u:this.pathMap}async load(){const e=await this.fileLoader(this.path,\"json\");let t;if(this.strict)try{t=o.LdtkLevel.parse(e)}catch(e){throw console.error(`Could not parse LDtk level data at ${this.path} are you sure a level is there and not corrupt?`),e}else t=e;return this.data=new n.Level(t,this.resource)}isLoaded(){return!!this.data}}},512:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Level=void 0;const r=s(205),i=s(961),a=s(920),n=s(692);t.Level=class{constructor(e,t){var s,o,d;if(this.ldtkLevel=e,this.resource=t,this.layers=[],e.__bgColor&&(this.backgroundColor=r.Color.fromHex(e.__bgColor)),e.layerInstances){let r=t.startZIndex,l=e.layerInstances.slice().reverse();for(let e of l)0!==(null===(s=e.entityInstances)||void 0===s?void 0:s.length)&&this.layers.push(new i.EntityLayer(this,e,t,r)),0!==(null===(o=e.gridTiles)||void 0===o?void 0:o.length)&&this.layers.push(new n.TileLayer(this,e,t,r)),0!==(null===(d=e.intGridCsv)||void 0===d?void 0:d.length)&&this.layers.push(new a.IntGridLayer(this,e,t,r)),r++}}}},289:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LoaderCache=void 0,t.LoaderCache=class{constructor(e){this.type=e,this._loaded=!1,this.cache=new Map}getOrAdd(...e){let t=this.cache.get(e.join(\"+\"));return t||(t=new this.type(...e),this.cache.set(e.join(\"+\"),t),t)}values(){if(this._loaded)return Array.from(this.cache.values());throw new Error(\"Read through cache not yet loaded! No values to return!\")}async load(){const e=Array.from(this.cache.entries()),t=await Promise.allSettled(e.map((e=>e[1].load())));let s=0;for(let r=0;r{function s(e,t){for(const{path:s,output:r}of t)if(\"string\"==typeof s){if(e.includes(s))return r}else{const t=e.match(s);if(t)return r.replace(\"[match]\",t[0])}return e}function r(e,t){if(!t)return!1;for(const{path:s,output:r}of t)if(\"string\"==typeof s){if(e.includes(s))return!0}else if(e.match(s))return!0;return!1}Object.defineProperty(t,\"__esModule\",{value:!0}),t.pathRelativeToBase=t.pathInMap=t.mapPath=t.filenameFromPath=void 0,t.filenameFromPath=function(e){const t=e.match(/[^/\\\\&\\?]+\\.\\w{2,4}(?=([\\#\\?&].*$|$))/gi);if(t)return t[0];throw new Error(`Could not locate filename from path: ${e}`)},t.mapPath=s,t.pathInMap=r,t.pathRelativeToBase=function(e,t,i){if(r(t,i)&&i)return s(t,i);if(0===t.indexOf(\"/\"))return t;const a=e.split(\"/\"),n=t.split(\"/\");return a[a.length-1].includes(\".\")&&a.pop(),a.concat(n).join(\"/\")}},692:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.TileLayer=void 0;const r=s(205);t.TileLayer=class{constructor(e,t,s,i){this.order=i,this.worldPos=(0,r.vec)(e.ldtkLevel.worldX,e.ldtkLevel.worldY),this.offset=(0,r.vec)(t.__pxTotalOffsetX,t.__pxTotalOffsetY),this.ldtkLayer=t,this.tilemap=new r.TileMap({name:t.__identifier,pos:this.worldPos.add(this.offset),tileWidth:t.__gridSize,tileHeight:t.__gridSize,rows:t.__cHei,columns:t.__cWid}),this.tilemap.z=i;for(let e of t.gridTiles){const r=Math.floor(e.px[0]/t.__gridSize),i=Math.floor(e.px[1]/t.__gridSize),a=this.tilemap.getTile(r,i);if(t.__tilesetDefUid){const r=s.tilesets.get(t.__tilesetDefUid);if(r){const t=Math.floor(e.src[0]/r.ldtkTileset.tileGridSize),s=Math.floor(e.src[1]/r.ldtkTileset.tileGridSize),i=r.spritesheet.getSprite(t,s);i?a.addGraphic(i):console.error(\"Could not find sprite in LDtk spritesheet at\",t,s)}}else console.error(\"Could not tileset in LDtk\",t.__tilesetDefUid,t.__tilesetRelPath)}}}},245:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Tileset=void 0;const r=s(205);t.Tileset=class{constructor(e){const{image:t,ldtkTileset:s}=e;this.image=t,this.ldtkTileset=s,this.spritesheet=r.SpriteSheet.fromImageSource({image:t,grid:{rows:s.pxHei/s.tileGridSize,columns:s.pxWid/s.tileGridSize,spriteHeight:s.tileGridSize,spriteWidth:s.tileGridSize}})}}},699:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LdtkProjectMetadata=t.LdtkEntityDefinition=t.LdtkLayerDefinition=t.LdtkLevel=t.LdtkLayerInstance=t.LdtkEntityInstance=void 0;const r=s(754),i=r.z.object({h:r.z.number(),tilesetUid:r.z.number(),w:r.z.number(),x:r.z.number(),y:r.z.number()}),a=r.z.tuple([r.z.number(),r.z.number()]),n=r.z.object({__identifier:r.z.string(),__tile:i.nullable(),__type:r.z.string(),__value:r.z.any(),defUid:r.z.number()}),o=r.z.object({a:r.z.number(),f:r.z.number(),px:a,src:a,t:r.z.number()});t.LdtkEntityInstance=r.z.object({__grid:a,__identifier:r.z.string(),__pivot:a,__smartColor:r.z.string(),__tags:r.z.array(r.z.string()),__tile:i.nullable(),__worldX:r.z.number().nullable(),__worldY:r.z.number().nullable(),defUid:r.z.number(),fieldInstances:r.z.array(n),height:r.z.number(),iid:r.z.string(),px:a,width:r.z.number()}),t.LdtkLayerInstance=r.z.object({__cHei:r.z.number(),__cWid:r.z.number(),__gridSize:r.z.number(),__identifier:r.z.string(),__opacity:r.z.number(),__pxTotalOffsetX:r.z.number(),__pxTotalOffsetY:r.z.number(),__tilesetDefUid:r.z.number().nullable(),__tilesetRelPath:r.z.string().nullable(),__type:r.z.union([r.z.literal(\"IntGrid\"),r.z.literal(\"Entities\"),r.z.literal(\"Tiles\"),r.z.literal(\"AutoLayer\")]),autoLayerTiles:r.z.array(o),entityInstances:r.z.array(t.LdtkEntityInstance),gridTiles:r.z.array(o),iid:r.z.string(),intGridCsv:r.z.array(r.z.number()),layerDefUid:r.z.number(),levelId:r.z.number(),overrideTilesetUid:r.z.number().nullable(),pxOffsetX:r.z.number(),pxOffsetY:r.z.number(),visible:r.z.boolean()}),t.LdtkLevel=r.z.object({__bgColor:r.z.string().nullable(),bgColor:r.z.string().nullable(),__bgPos:r.z.object({cropRect:r.z.array(r.z.tuple([r.z.number(),r.z.number(),r.z.number(),r.z.number()])),scale:r.z.tuple([r.z.number(),r.z.number()]),topLeftPx:a}).nullable(),__neighbours:r.z.array(r.z.object({dir:r.z.union([r.z.literal(\"n\"),r.z.literal(\"s\"),r.z.literal(\"w\"),r.z.literal(\"e\"),r.z.literal(\"ne\"),r.z.literal(\"nw\"),r.z.literal(\"se\"),r.z.literal(\"sw\"),r.z.literal(\"o\"),r.z.literal(\"<\"),r.z.literal(\">\")]),levelIid:r.z.string()})),bgRelPath:r.z.string().nullable(),externalRelPath:r.z.string().nullable(),fieldInstances:r.z.array(n),identifier:r.z.string(),iid:r.z.string(),layerInstances:r.z.array(t.LdtkLayerInstance).nullable(),pxHei:r.z.number(),pxWid:r.z.number(),uid:r.z.number(),worldDepth:r.z.number(),worldX:r.z.number(),worldY:r.z.number()});const d=r.z.object({identifier:r.z.string(),iid:r.z.string(),levels:r.z.array(t.LdtkLevel),worldGridHeight:r.z.number(),worldGridWidth:r.z.number(),worldLayout:r.z.union([r.z.literal(\"Free\"),r.z.literal(\"GridVania\"),r.z.literal(\"LinearHorizontal\"),r.z.literal(\"LinearVertical\")])}),l=r.z.object({color:r.z.number(),id:r.z.string(),tileRect:i.nullable()}),u=r.z.object({externalRelPath:r.z.string().nullable(),iconTilesetUid:r.z.number().nullable(),identifier:r.z.string(),tags:r.z.array(r.z.string()),uid:r.z.number(),values:r.z.array(l)}),c=r.z.object({__cHei:r.z.number(),__cWid:r.z.number(),customData:r.z.array(r.z.object({data:r.z.string(),tileId:r.z.number()})),embedAtlas:r.z.string().nullable(),enumsTags:r.z.optional(r.z.array(r.z.object({enumValueId:r.z.string(),tileIds:r.z.array(r.z.number())}))),identifier:r.z.string(),padding:r.z.number(),pxHei:r.z.number(),pxWid:r.z.number(),relPath:r.z.string().nullable(),spacing:r.z.number(),tags:r.z.array(r.z.string()),tagsSourceEnumUid:r.z.number().nullable(),tileGridSize:r.z.number(),uid:r.z.number()});t.LdtkLayerDefinition=r.z.object({__type:r.z.union([r.z.literal(\"IntGrid\"),r.z.literal(\"Entities\"),r.z.literal(\"Tiles\"),r.z.literal(\"AutoLayer\")]),autoSourceLayerDefUid:r.z.number().nullable(),displayOpacity:r.z.number(),gridSize:r.z.number(),identifier:r.z.string(),intGridValues:r.z.array(r.z.object({color:r.z.string(),groupUid:r.z.number(),identifier:r.z.string().nullable(),tile:i.nullable(),value:r.z.number()})),intGridValuesGroups:r.z.array(r.z.object({color:r.z.string().nullable(),identifier:r.z.string().nullable(),uid:r.z.number()})),parallaxFactorX:r.z.number(),parallaxFactorY:r.z.number(),parallaxScaling:r.z.boolean(),pxOffsetX:r.z.number(),pxOffsetY:r.z.number(),tilesetDefUid:r.z.number().nullable(),uid:r.z.number()}),t.LdtkEntityDefinition=r.z.object({color:r.z.string(),height:r.z.number(),identifier:r.z.string(),nineSliceBorders:r.z.array(r.z.number()),pivotX:r.z.number(),pivotY:r.z.number(),tileRect:i.nullable(),tileRenderMode:r.z.union([r.z.literal(\"Cover\"),r.z.literal(\"FitInside\"),r.z.literal(\"Repeat\"),r.z.literal(\"Stretch\"),r.z.literal(\"FullSizeCropped\"),r.z.literal(\"FullSizeUncropped\"),r.z.literal(\"NineSlice\")]),tilesetId:r.z.number().nullable(),uiTileRect:i.nullable(),uid:r.z.number(),width:r.z.number()});const p=r.z.object({tilesets:r.z.array(c),enums:r.z.array(u),layers:r.z.array(t.LdtkLayerDefinition),entities:r.z.array(t.LdtkEntityDefinition)});t.LdtkProjectMetadata=r.z.object({iid:r.z.string(),bgColor:r.z.string().nullable(),defs:p,externalLevels:r.z.boolean(),jsonVersion:r.z.string(),levels:r.z.array(t.LdtkLevel),toc:r.z.array(r.z.object({identifier:r.z.string(),instancesData:r.z.array(r.z.object({fields:r.z.any(),heiPx:r.z.number(),iids:r.z.string(),widPix:r.z.number(),worldX:r.z.number(),worldY:r.z.number()}))})),worldGridHeight:r.z.number().nullable(),worldGridWidth:r.z.number().nullable(),worldLayout:r.z.union([r.z.literal(\"Free\"),r.z.literal(\"GridVania\"),r.z.literal(\"LinearHorizontal\"),r.z.literal(\"LinearVertical\")]).nullable(),worlds:r.z.array(d)})},280:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ZodError=t.quotelessJson=t.ZodIssueCode=void 0;const r=s(110);t.ZodIssueCode=r.util.arrayToEnum([\"invalid_type\",\"invalid_literal\",\"custom\",\"invalid_union\",\"invalid_union_discriminator\",\"invalid_enum_value\",\"unrecognized_keys\",\"invalid_arguments\",\"invalid_return_type\",\"invalid_date\",\"invalid_string\",\"too_small\",\"too_big\",\"invalid_intersection_types\",\"not_multiple_of\",\"not_finite\"]),t.quotelessJson=e=>JSON.stringify(e,null,2).replace(/\"([^\"]+)\":/g,\"$1:\");class i extends Error{constructor(e){super(),this.issues=[],this.addIssue=e=>{this.issues=[...this.issues,e]},this.addIssues=(e=[])=>{this.issues=[...this.issues,...e]};const t=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,t):this.__proto__=t,this.name=\"ZodError\",this.issues=e}get errors(){return this.issues}format(e){const t=e||function(e){return e.message},s={_errors:[]},r=e=>{for(const i of e.issues)if(\"invalid_union\"===i.code)i.unionErrors.map(r);else if(\"invalid_return_type\"===i.code)r(i.returnTypeError);else if(\"invalid_arguments\"===i.code)r(i.argumentsError);else if(0===i.path.length)s._errors.push(t(i));else{let e=s,r=0;for(;re.message)){const t={},s=[];for(const r of this.issues)r.path.length>0?(t[r.path[0]]=t[r.path[0]]||[],t[r.path[0]].push(e(r))):s.push(e(r));return{formErrors:s,fieldErrors:t}}get formErrors(){return this.flatten()}}t.ZodError=i,i.create=e=>new i(e)},996:function(e,t,s){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.getErrorMap=t.setErrorMap=t.defaultErrorMap=void 0;const i=r(s(325));t.defaultErrorMap=i.default;let a=i.default;t.setErrorMap=function(e){a=e},t.getErrorMap=function(){return a}},349:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[s]}})}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__exportStar||function(e,t){for(var s in e)\"default\"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)};Object.defineProperty(t,\"__esModule\",{value:!0}),i(s(996),t),i(s(187),t),i(s(116),t),i(s(110),t),i(s(433),t),i(s(280),t)},762:(e,t)=>{var s;Object.defineProperty(t,\"__esModule\",{value:!0}),t.errorUtil=void 0,(s=t.errorUtil||(t.errorUtil={})).errToObj=e=>\"string\"==typeof e?{message:e}:e||{},s.toString=e=>\"string\"==typeof e?e:null==e?void 0:e.message},187:function(e,t,s){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.isAsync=t.isValid=t.isDirty=t.isAborted=t.OK=t.DIRTY=t.INVALID=t.ParseStatus=t.addIssueToContext=t.EMPTY_PATH=t.makeIssue=void 0;const i=s(996),a=r(s(325));t.makeIssue=e=>{const{data:t,path:s,errorMaps:r,issueData:i}=e,a=[...s,...i.path||[]],n={...i,path:a};let o=\"\";const d=r.filter((e=>!!e)).slice().reverse();for(const e of d)o=e(n,{data:t,defaultError:o}).message;return{...i,path:a,message:i.message||o}},t.EMPTY_PATH=[],t.addIssueToContext=function(e,s){const r=(0,t.makeIssue)({issueData:s,data:e.data,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,(0,i.getErrorMap)(),a.default].filter((e=>!!e))});e.common.issues.push(r)};class n{constructor(){this.value=\"valid\"}dirty(){\"valid\"===this.value&&(this.value=\"dirty\")}abort(){\"aborted\"!==this.value&&(this.value=\"aborted\")}static mergeArray(e,s){const r=[];for(const i of s){if(\"aborted\"===i.status)return t.INVALID;\"dirty\"===i.status&&e.dirty(),r.push(i.value)}return{status:e.value,value:r}}static async mergeObjectAsync(e,t){const s=[];for(const e of t)s.push({key:await e.key,value:await e.value});return n.mergeObjectSync(e,s)}static mergeObjectSync(e,s){const r={};for(const i of s){const{key:s,value:a}=i;if(\"aborted\"===s.status)return t.INVALID;if(\"aborted\"===a.status)return t.INVALID;\"dirty\"===s.status&&e.dirty(),\"dirty\"===a.status&&e.dirty(),\"__proto__\"===s.value||void 0===a.value&&!i.alwaysSet||(r[s.value]=a.value)}return{status:e.value,value:r}}}t.ParseStatus=n,t.INVALID=Object.freeze({status:\"aborted\"}),t.DIRTY=e=>({status:\"dirty\",value:e}),t.OK=e=>({status:\"valid\",value:e}),t.isAborted=e=>\"aborted\"===e.status,t.isDirty=e=>\"dirty\"===e.status,t.isValid=e=>\"valid\"===e.status,t.isAsync=e=>\"undefined\"!=typeof Promise&&e instanceof Promise},116:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0})},110:(e,t)=>{var s;Object.defineProperty(t,\"__esModule\",{value:!0}),t.getParsedType=t.ZodParsedType=t.objectUtil=t.util=void 0,function(e){e.assertEqual=e=>e,e.assertIs=function(e){},e.assertNever=function(e){throw new Error},e.arrayToEnum=e=>{const t={};for(const s of e)t[s]=s;return t},e.getValidEnumValues=t=>{const s=e.objectKeys(t).filter((e=>\"number\"!=typeof t[t[e]])),r={};for(const e of s)r[e]=t[e];return e.objectValues(r)},e.objectValues=t=>e.objectKeys(t).map((function(e){return t[e]})),e.objectKeys=\"function\"==typeof Object.keys?e=>Object.keys(e):e=>{const t=[];for(const s in e)Object.prototype.hasOwnProperty.call(e,s)&&t.push(s);return t},e.find=(e,t)=>{for(const s of e)if(t(s))return s},e.isInteger=\"function\"==typeof Number.isInteger?e=>Number.isInteger(e):e=>\"number\"==typeof e&&isFinite(e)&&Math.floor(e)===e,e.joinValues=function(e,t=\" | \"){return e.map((e=>\"string\"==typeof e?`'${e}'`:e)).join(t)},e.jsonStringifyReplacer=(e,t)=>\"bigint\"==typeof t?t.toString():t}(s=t.util||(t.util={})),(t.objectUtil||(t.objectUtil={})).mergeShapes=(e,t)=>({...e,...t}),t.ZodParsedType=s.arrayToEnum([\"string\",\"nan\",\"number\",\"integer\",\"float\",\"boolean\",\"date\",\"bigint\",\"symbol\",\"function\",\"undefined\",\"null\",\"array\",\"object\",\"unknown\",\"promise\",\"void\",\"never\",\"map\",\"set\"]),t.getParsedType=e=>{switch(typeof e){case\"undefined\":return t.ZodParsedType.undefined;case\"string\":return t.ZodParsedType.string;case\"number\":return isNaN(e)?t.ZodParsedType.nan:t.ZodParsedType.number;case\"boolean\":return t.ZodParsedType.boolean;case\"function\":return t.ZodParsedType.function;case\"bigint\":return t.ZodParsedType.bigint;case\"symbol\":return t.ZodParsedType.symbol;case\"object\":return Array.isArray(e)?t.ZodParsedType.array:null===e?t.ZodParsedType.null:e.then&&\"function\"==typeof e.then&&e.catch&&\"function\"==typeof e.catch?t.ZodParsedType.promise:\"undefined\"!=typeof Map&&e instanceof Map?t.ZodParsedType.map:\"undefined\"!=typeof Set&&e instanceof Set?t.ZodParsedType.set:\"undefined\"!=typeof Date&&e instanceof Date?t.ZodParsedType.date:t.ZodParsedType.object;default:return t.ZodParsedType.unknown}}},754:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[s]}})}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var s in e)\"default\"!==s&&Object.prototype.hasOwnProperty.call(e,s)&&r(t,e,s);return i(t,e),t},n=this&&this.__exportStar||function(e,t){for(var s in e)\"default\"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)};Object.defineProperty(t,\"__esModule\",{value:!0}),t.z=void 0;const o=a(s(349));t.z=o,n(s(349),t),t.default=o},325:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0});const r=s(110),i=s(280);t.default=(e,t)=>{let s;switch(e.code){case i.ZodIssueCode.invalid_type:s=e.received===r.ZodParsedType.undefined?\"Required\":`Expected ${e.expected}, received ${e.received}`;break;case i.ZodIssueCode.invalid_literal:s=`Invalid literal value, expected ${JSON.stringify(e.expected,r.util.jsonStringifyReplacer)}`;break;case i.ZodIssueCode.unrecognized_keys:s=`Unrecognized key(s) in object: ${r.util.joinValues(e.keys,\", \")}`;break;case i.ZodIssueCode.invalid_union:s=\"Invalid input\";break;case i.ZodIssueCode.invalid_union_discriminator:s=`Invalid discriminator value. Expected ${r.util.joinValues(e.options)}`;break;case i.ZodIssueCode.invalid_enum_value:s=`Invalid enum value. Expected ${r.util.joinValues(e.options)}, received '${e.received}'`;break;case i.ZodIssueCode.invalid_arguments:s=\"Invalid function arguments\";break;case i.ZodIssueCode.invalid_return_type:s=\"Invalid function return type\";break;case i.ZodIssueCode.invalid_date:s=\"Invalid date\";break;case i.ZodIssueCode.invalid_string:\"object\"==typeof e.validation?\"includes\"in e.validation?(s=`Invalid input: must include \"${e.validation.includes}\"`,\"number\"==typeof e.validation.position&&(s=`${s} at one or more positions greater than or equal to ${e.validation.position}`)):\"startsWith\"in e.validation?s=`Invalid input: must start with \"${e.validation.startsWith}\"`:\"endsWith\"in e.validation?s=`Invalid input: must end with \"${e.validation.endsWith}\"`:r.util.assertNever(e.validation):s=\"regex\"!==e.validation?`Invalid ${e.validation}`:\"Invalid\";break;case i.ZodIssueCode.too_small:s=\"array\"===e.type?`Array must contain ${e.exact?\"exactly\":e.inclusive?\"at least\":\"more than\"} ${e.minimum} element(s)`:\"string\"===e.type?`String must contain ${e.exact?\"exactly\":e.inclusive?\"at least\":\"over\"} ${e.minimum} character(s)`:\"number\"===e.type?`Number must be ${e.exact?\"exactly equal to \":e.inclusive?\"greater than or equal to \":\"greater than \"}${e.minimum}`:\"date\"===e.type?`Date must be ${e.exact?\"exactly equal to \":e.inclusive?\"greater than or equal to \":\"greater than \"}${new Date(Number(e.minimum))}`:\"Invalid input\";break;case i.ZodIssueCode.too_big:s=\"array\"===e.type?`Array must contain ${e.exact?\"exactly\":e.inclusive?\"at most\":\"less than\"} ${e.maximum} element(s)`:\"string\"===e.type?`String must contain ${e.exact?\"exactly\":e.inclusive?\"at most\":\"under\"} ${e.maximum} character(s)`:\"number\"===e.type?`Number must be ${e.exact?\"exactly\":e.inclusive?\"less than or equal to\":\"less than\"} ${e.maximum}`:\"bigint\"===e.type?`BigInt must be ${e.exact?\"exactly\":e.inclusive?\"less than or equal to\":\"less than\"} ${e.maximum}`:\"date\"===e.type?`Date must be ${e.exact?\"exactly\":e.inclusive?\"smaller than or equal to\":\"smaller than\"} ${new Date(Number(e.maximum))}`:\"Invalid input\";break;case i.ZodIssueCode.custom:s=\"Invalid input\";break;case i.ZodIssueCode.invalid_intersection_types:s=\"Intersection results could not be merged\";break;case i.ZodIssueCode.not_multiple_of:s=`Number must be a multiple of ${e.multipleOf}`;break;case i.ZodIssueCode.not_finite:s=\"Number must be finite\";break;default:s=t.defaultError,r.util.assertNever(e)}return{message:s}}},433:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.date=t.boolean=t.bigint=t.array=t.any=t.coerce=t.ZodFirstPartyTypeKind=t.late=t.ZodSchema=t.Schema=t.custom=t.ZodReadonly=t.ZodPipeline=t.ZodBranded=t.BRAND=t.ZodNaN=t.ZodCatch=t.ZodDefault=t.ZodNullable=t.ZodOptional=t.ZodTransformer=t.ZodEffects=t.ZodPromise=t.ZodNativeEnum=t.ZodEnum=t.ZodLiteral=t.ZodLazy=t.ZodFunction=t.ZodSet=t.ZodMap=t.ZodRecord=t.ZodTuple=t.ZodIntersection=t.ZodDiscriminatedUnion=t.ZodUnion=t.ZodObject=t.ZodArray=t.ZodVoid=t.ZodNever=t.ZodUnknown=t.ZodAny=t.ZodNull=t.ZodUndefined=t.ZodSymbol=t.ZodDate=t.ZodBoolean=t.ZodBigInt=t.ZodNumber=t.ZodString=t.ZodType=void 0,t.NEVER=t.void=t.unknown=t.union=t.undefined=t.tuple=t.transformer=t.symbol=t.string=t.strictObject=t.set=t.record=t.promise=t.preprocess=t.pipeline=t.ostring=t.optional=t.onumber=t.oboolean=t.object=t.number=t.nullable=t.null=t.never=t.nativeEnum=t.nan=t.map=t.literal=t.lazy=t.intersection=t.instanceof=t.function=t.enum=t.effect=t.discriminatedUnion=void 0;const r=s(996),i=s(762),a=s(187),n=s(110),o=s(280);class d{constructor(e,t,s,r){this._cachedPath=[],this.parent=e,this.data=t,this._path=s,this._key=r}get path(){return this._cachedPath.length||(this._key instanceof Array?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}}const l=(e,t)=>{if((0,a.isValid)(t))return{success:!0,data:t.value};if(!e.common.issues.length)throw new Error(\"Validation failed but no issues detected.\");return{success:!1,get error(){if(this._error)return this._error;const t=new o.ZodError(e.common.issues);return this._error=t,this._error}}};function u(e){if(!e)return{};const{errorMap:t,invalid_type_error:s,required_error:r,description:i}=e;if(t&&(s||r))throw new Error('Can\\'t use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.');return t?{errorMap:t,description:i}:{errorMap:(e,t)=>\"invalid_type\"!==e.code?{message:t.defaultError}:void 0===t.data?{message:null!=r?r:t.defaultError}:{message:null!=s?s:t.defaultError},description:i}}class c{constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this)}get description(){return this._def.description}_getType(e){return(0,n.getParsedType)(e.data)}_getOrReturnCtx(e,t){return t||{common:e.parent.common,data:e.data,parsedType:(0,n.getParsedType)(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new a.ParseStatus,ctx:{common:e.parent.common,data:e.data,parsedType:(0,n.getParsedType)(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){const t=this._parse(e);if((0,a.isAsync)(t))throw new Error(\"Synchronous parse encountered promise.\");return t}_parseAsync(e){const t=this._parse(e);return Promise.resolve(t)}parse(e,t){const s=this.safeParse(e,t);if(s.success)return s.data;throw s.error}safeParse(e,t){var s;const r={common:{issues:[],async:null!==(s=null==t?void 0:t.async)&&void 0!==s&&s,contextualErrorMap:null==t?void 0:t.errorMap},path:(null==t?void 0:t.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:(0,n.getParsedType)(e)},i=this._parseSync({data:e,path:r.path,parent:r});return l(r,i)}async parseAsync(e,t){const s=await this.safeParseAsync(e,t);if(s.success)return s.data;throw s.error}async safeParseAsync(e,t){const s={common:{issues:[],contextualErrorMap:null==t?void 0:t.errorMap,async:!0},path:(null==t?void 0:t.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:(0,n.getParsedType)(e)},r=this._parse({data:e,path:s.path,parent:s}),i=await((0,a.isAsync)(r)?r:Promise.resolve(r));return l(s,i)}refine(e,t){const s=e=>\"string\"==typeof t||void 0===t?{message:t}:\"function\"==typeof t?t(e):t;return this._refinement(((t,r)=>{const i=e(t),a=()=>r.addIssue({code:o.ZodIssueCode.custom,...s(t)});return\"undefined\"!=typeof Promise&&i instanceof Promise?i.then((e=>!!e||(a(),!1))):!!i||(a(),!1)}))}refinement(e,t){return this._refinement(((s,r)=>!!e(s)||(r.addIssue(\"function\"==typeof t?t(s,r):t),!1)))}_refinement(e){return new J({schema:this,typeName:oe.ZodEffects,effect:{type:\"refinement\",refinement:e}})}superRefine(e){return this._refinement(e)}optional(){return Q.create(this,this._def)}nullable(){return ee.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return E.create(this,this._def)}promise(){return X.create(this,this._def)}or(e){return A.create([this,e],this._def)}and(e){return R.create(this,e,this._def)}transform(e){return new J({...u(this._def),schema:this,typeName:oe.ZodEffects,effect:{type:\"transform\",transform:e}})}default(e){const t=\"function\"==typeof e?e:()=>e;return new te({...u(this._def),innerType:this,defaultValue:t,typeName:oe.ZodDefault})}brand(){return new ie({typeName:oe.ZodBranded,type:this,...u(this._def)})}catch(e){const t=\"function\"==typeof e?e:()=>e;return new se({...u(this._def),innerType:this,catchValue:t,typeName:oe.ZodCatch})}describe(e){return new(0,this.constructor)({...this._def,description:e})}pipe(e){return ae.create(this,e)}readonly(){return ne.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}}t.ZodType=c,t.Schema=c,t.ZodSchema=c;const p=/^c[^\\s-]{8,}$/i,h=/^[a-z][a-z0-9]*$/,f=/^[0-9A-HJKMNP-TV-Z]{26}$/,m=/^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i,y=/^(?!\\.)(?!.*\\.\\.)([A-Z0-9_+-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;let _;const v=/^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/,g=/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;class b extends c{_parse(e){if(this._def.coerce&&(e.data=String(e.data)),this._getType(e)!==n.ZodParsedType.string){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.string,received:t.parsedType}),a.INVALID}const t=new a.ParseStatus;let s;for(const l of this._def.checks)if(\"min\"===l.kind)e.data.lengthl.value&&(s=this._getOrReturnCtx(e,s),(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.too_big,maximum:l.value,type:\"string\",inclusive:!0,exact:!1,message:l.message}),t.dirty());else if(\"length\"===l.kind){const r=e.data.length>l.value,i=e.data.lengthe.test(t)),{validation:t,code:o.ZodIssueCode.invalid_string,...i.errorUtil.errToObj(s)})}_addCheck(e){return new b({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:\"email\",...i.errorUtil.errToObj(e)})}url(e){return this._addCheck({kind:\"url\",...i.errorUtil.errToObj(e)})}emoji(e){return this._addCheck({kind:\"emoji\",...i.errorUtil.errToObj(e)})}uuid(e){return this._addCheck({kind:\"uuid\",...i.errorUtil.errToObj(e)})}cuid(e){return this._addCheck({kind:\"cuid\",...i.errorUtil.errToObj(e)})}cuid2(e){return this._addCheck({kind:\"cuid2\",...i.errorUtil.errToObj(e)})}ulid(e){return this._addCheck({kind:\"ulid\",...i.errorUtil.errToObj(e)})}ip(e){return this._addCheck({kind:\"ip\",...i.errorUtil.errToObj(e)})}datetime(e){var t;return\"string\"==typeof e?this._addCheck({kind:\"datetime\",precision:null,offset:!1,message:e}):this._addCheck({kind:\"datetime\",precision:void 0===(null==e?void 0:e.precision)?null:null==e?void 0:e.precision,offset:null!==(t=null==e?void 0:e.offset)&&void 0!==t&&t,...i.errorUtil.errToObj(null==e?void 0:e.message)})}regex(e,t){return this._addCheck({kind:\"regex\",regex:e,...i.errorUtil.errToObj(t)})}includes(e,t){return this._addCheck({kind:\"includes\",value:e,position:null==t?void 0:t.position,...i.errorUtil.errToObj(null==t?void 0:t.message)})}startsWith(e,t){return this._addCheck({kind:\"startsWith\",value:e,...i.errorUtil.errToObj(t)})}endsWith(e,t){return this._addCheck({kind:\"endsWith\",value:e,...i.errorUtil.errToObj(t)})}min(e,t){return this._addCheck({kind:\"min\",value:e,...i.errorUtil.errToObj(t)})}max(e,t){return this._addCheck({kind:\"max\",value:e,...i.errorUtil.errToObj(t)})}length(e,t){return this._addCheck({kind:\"length\",value:e,...i.errorUtil.errToObj(t)})}nonempty(e){return this.min(1,i.errorUtil.errToObj(e))}trim(){return new b({...this._def,checks:[...this._def.checks,{kind:\"trim\"}]})}toLowerCase(){return new b({...this._def,checks:[...this._def.checks,{kind:\"toLowerCase\"}]})}toUpperCase(){return new b({...this._def,checks:[...this._def.checks,{kind:\"toUpperCase\"}]})}get isDatetime(){return!!this._def.checks.find((e=>\"datetime\"===e.kind))}get isEmail(){return!!this._def.checks.find((e=>\"email\"===e.kind))}get isURL(){return!!this._def.checks.find((e=>\"url\"===e.kind))}get isEmoji(){return!!this._def.checks.find((e=>\"emoji\"===e.kind))}get isUUID(){return!!this._def.checks.find((e=>\"uuid\"===e.kind))}get isCUID(){return!!this._def.checks.find((e=>\"cuid\"===e.kind))}get isCUID2(){return!!this._def.checks.find((e=>\"cuid2\"===e.kind))}get isULID(){return!!this._def.checks.find((e=>\"ulid\"===e.kind))}get isIP(){return!!this._def.checks.find((e=>\"ip\"===e.kind))}get minLength(){let e=null;for(const t of this._def.checks)\"min\"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxLength(){let e=null;for(const t of this._def.checks)\"max\"===t.kind&&(null===e||t.valuer?s:r;return parseInt(e.toFixed(i).replace(\".\",\"\"))%parseInt(t.toFixed(i).replace(\".\",\"\"))/Math.pow(10,i)}t.ZodString=b,b.create=e=>{var t;return new b({checks:[],typeName:oe.ZodString,coerce:null!==(t=null==e?void 0:e.coerce)&&void 0!==t&&t,...u(e)})};class I extends c{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(e){if(this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==n.ZodParsedType.number){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.number,received:t.parsedType}),a.INVALID}let t;const s=new a.ParseStatus;for(const r of this._def.checks)\"int\"===r.kind?n.util.isInteger(e.data)||(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:\"integer\",received:\"float\",message:r.message}),s.dirty()):\"min\"===r.kind?(r.inclusive?e.datar.value:e.data>=r.value)&&(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.too_big,maximum:r.value,type:\"number\",inclusive:r.inclusive,exact:!1,message:r.message}),s.dirty()):\"multipleOf\"===r.kind?0!==x(e.data,r.value)&&(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.not_multiple_of,multipleOf:r.value,message:r.message}),s.dirty()):\"finite\"===r.kind?Number.isFinite(e.data)||(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.not_finite,message:r.message}),s.dirty()):n.util.assertNever(r);return{status:s.value,value:e.data}}gte(e,t){return this.setLimit(\"min\",e,!0,i.errorUtil.toString(t))}gt(e,t){return this.setLimit(\"min\",e,!1,i.errorUtil.toString(t))}lte(e,t){return this.setLimit(\"max\",e,!0,i.errorUtil.toString(t))}lt(e,t){return this.setLimit(\"max\",e,!1,i.errorUtil.toString(t))}setLimit(e,t,s,r){return new I({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:s,message:i.errorUtil.toString(r)}]})}_addCheck(e){return new I({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:\"int\",message:i.errorUtil.toString(e)})}positive(e){return this._addCheck({kind:\"min\",value:0,inclusive:!1,message:i.errorUtil.toString(e)})}negative(e){return this._addCheck({kind:\"max\",value:0,inclusive:!1,message:i.errorUtil.toString(e)})}nonpositive(e){return this._addCheck({kind:\"max\",value:0,inclusive:!0,message:i.errorUtil.toString(e)})}nonnegative(e){return this._addCheck({kind:\"min\",value:0,inclusive:!0,message:i.errorUtil.toString(e)})}multipleOf(e,t){return this._addCheck({kind:\"multipleOf\",value:e,message:i.errorUtil.toString(t)})}finite(e){return this._addCheck({kind:\"finite\",message:i.errorUtil.toString(e)})}safe(e){return this._addCheck({kind:\"min\",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:i.errorUtil.toString(e)})._addCheck({kind:\"max\",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:i.errorUtil.toString(e)})}get minValue(){let e=null;for(const t of this._def.checks)\"min\"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxValue(){let e=null;for(const t of this._def.checks)\"max\"===t.kind&&(null===e||t.value\"int\"===e.kind||\"multipleOf\"===e.kind&&n.util.isInteger(e.value)))}get isFinite(){let e=null,t=null;for(const s of this._def.checks){if(\"finite\"===s.kind||\"int\"===s.kind||\"multipleOf\"===s.kind)return!0;\"min\"===s.kind?(null===t||s.value>t)&&(t=s.value):\"max\"===s.kind&&(null===e||s.valuenew I({checks:[],typeName:oe.ZodNumber,coerce:(null==e?void 0:e.coerce)||!1,...u(e)});class Z extends c{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(e){if(this._def.coerce&&(e.data=BigInt(e.data)),this._getType(e)!==n.ZodParsedType.bigint){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.bigint,received:t.parsedType}),a.INVALID}let t;const s=new a.ParseStatus;for(const r of this._def.checks)\"min\"===r.kind?(r.inclusive?e.datar.value:e.data>=r.value)&&(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.too_big,type:\"bigint\",maximum:r.value,inclusive:r.inclusive,message:r.message}),s.dirty()):\"multipleOf\"===r.kind?e.data%r.value!==BigInt(0)&&(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.not_multiple_of,multipleOf:r.value,message:r.message}),s.dirty()):n.util.assertNever(r);return{status:s.value,value:e.data}}gte(e,t){return this.setLimit(\"min\",e,!0,i.errorUtil.toString(t))}gt(e,t){return this.setLimit(\"min\",e,!1,i.errorUtil.toString(t))}lte(e,t){return this.setLimit(\"max\",e,!0,i.errorUtil.toString(t))}lt(e,t){return this.setLimit(\"max\",e,!1,i.errorUtil.toString(t))}setLimit(e,t,s,r){return new Z({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:s,message:i.errorUtil.toString(r)}]})}_addCheck(e){return new Z({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!1,message:i.errorUtil.toString(e)})}negative(e){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!1,message:i.errorUtil.toString(e)})}nonpositive(e){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!0,message:i.errorUtil.toString(e)})}nonnegative(e){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!0,message:i.errorUtil.toString(e)})}multipleOf(e,t){return this._addCheck({kind:\"multipleOf\",value:e,message:i.errorUtil.toString(t)})}get minValue(){let e=null;for(const t of this._def.checks)\"min\"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxValue(){let e=null;for(const t of this._def.checks)\"max\"===t.kind&&(null===e||t.value{var t;return new Z({checks:[],typeName:oe.ZodBigInt,coerce:null!==(t=null==e?void 0:e.coerce)&&void 0!==t&&t,...u(e)})};class T extends c{_parse(e){if(this._def.coerce&&(e.data=Boolean(e.data)),this._getType(e)!==n.ZodParsedType.boolean){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.boolean,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodBoolean=T,T.create=e=>new T({typeName:oe.ZodBoolean,coerce:(null==e?void 0:e.coerce)||!1,...u(e)});class k extends c{_parse(e){if(this._def.coerce&&(e.data=new Date(e.data)),this._getType(e)!==n.ZodParsedType.date){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.date,received:t.parsedType}),a.INVALID}if(isNaN(e.data.getTime())){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_date}),a.INVALID}const t=new a.ParseStatus;let s;for(const r of this._def.checks)\"min\"===r.kind?e.data.getTime()r.value&&(s=this._getOrReturnCtx(e,s),(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.too_big,message:r.message,inclusive:!0,exact:!1,maximum:r.value,type:\"date\"}),t.dirty()):n.util.assertNever(r);return{status:t.value,value:new Date(e.data.getTime())}}_addCheck(e){return new k({...this._def,checks:[...this._def.checks,e]})}min(e,t){return this._addCheck({kind:\"min\",value:e.getTime(),message:i.errorUtil.toString(t)})}max(e,t){return this._addCheck({kind:\"max\",value:e.getTime(),message:i.errorUtil.toString(t)})}get minDate(){let e=null;for(const t of this._def.checks)\"min\"===t.kind&&(null===e||t.value>e)&&(e=t.value);return null!=e?new Date(e):null}get maxDate(){let e=null;for(const t of this._def.checks)\"max\"===t.kind&&(null===e||t.valuenew k({checks:[],coerce:(null==e?void 0:e.coerce)||!1,typeName:oe.ZodDate,...u(e)});class w extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.symbol){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.symbol,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodSymbol=w,w.create=e=>new w({typeName:oe.ZodSymbol,...u(e)});class C extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.undefined){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.undefined,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodUndefined=C,C.create=e=>new C({typeName:oe.ZodUndefined,...u(e)});class z extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.null){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.null,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodNull=z,z.create=e=>new z({typeName:oe.ZodNull,...u(e)});class L extends c{constructor(){super(...arguments),this._any=!0}_parse(e){return(0,a.OK)(e.data)}}t.ZodAny=L,L.create=e=>new L({typeName:oe.ZodAny,...u(e)});class P extends c{constructor(){super(...arguments),this._unknown=!0}_parse(e){return(0,a.OK)(e.data)}}t.ZodUnknown=P,P.create=e=>new P({typeName:oe.ZodUnknown,...u(e)});class O extends c{_parse(e){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.never,received:t.parsedType}),a.INVALID}}t.ZodNever=O,O.create=e=>new O({typeName:oe.ZodNever,...u(e)});class j extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.undefined){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.void,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodVoid=j,j.create=e=>new j({typeName:oe.ZodVoid,...u(e)});class E extends c{_parse(e){const{ctx:t,status:s}=this._processInputParams(e),r=this._def;if(t.parsedType!==n.ZodParsedType.array)return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.array,received:t.parsedType}),a.INVALID;if(null!==r.exactLength){const e=t.data.length>r.exactLength.value,i=t.data.lengthr.maxLength.value&&((0,a.addIssueToContext)(t,{code:o.ZodIssueCode.too_big,maximum:r.maxLength.value,type:\"array\",inclusive:!0,exact:!1,message:r.maxLength.message}),s.dirty()),t.common.async)return Promise.all([...t.data].map(((e,s)=>r.type._parseAsync(new d(t,e,t.path,s))))).then((e=>a.ParseStatus.mergeArray(s,e)));const i=[...t.data].map(((e,s)=>r.type._parseSync(new d(t,e,t.path,s))));return a.ParseStatus.mergeArray(s,i)}get element(){return this._def.type}min(e,t){return new E({...this._def,minLength:{value:e,message:i.errorUtil.toString(t)}})}max(e,t){return new E({...this._def,maxLength:{value:e,message:i.errorUtil.toString(t)}})}length(e,t){return new E({...this._def,exactLength:{value:e,message:i.errorUtil.toString(t)}})}nonempty(e){return this.min(1,e)}}function N(e){if(e instanceof S){const t={};for(const s in e.shape){const r=e.shape[s];t[s]=Q.create(N(r))}return new S({...e._def,shape:()=>t})}return e instanceof E?new E({...e._def,type:N(e.element)}):e instanceof Q?Q.create(N(e.unwrap())):e instanceof ee?ee.create(N(e.unwrap())):e instanceof V?V.create(e.items.map((e=>N(e)))):e}t.ZodArray=E,E.create=(e,t)=>new E({type:e,minLength:null,maxLength:null,exactLength:null,typeName:oe.ZodArray,...u(t)});class S extends c{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;const e=this._def.shape(),t=n.util.objectKeys(e);return this._cached={shape:e,keys:t}}_parse(e){if(this._getType(e)!==n.ZodParsedType.object){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.object,received:t.parsedType}),a.INVALID}const{status:t,ctx:s}=this._processInputParams(e),{shape:r,keys:i}=this._getCached(),l=[];if(!(this._def.catchall instanceof O&&\"strip\"===this._def.unknownKeys))for(const e in s.data)i.includes(e)||l.push(e);const u=[];for(const e of i){const t=r[e],i=s.data[e];u.push({key:{status:\"valid\",value:e},value:t._parse(new d(s,i,s.path,e)),alwaysSet:e in s.data})}if(this._def.catchall instanceof O){const e=this._def.unknownKeys;if(\"passthrough\"===e)for(const e of l)u.push({key:{status:\"valid\",value:e},value:{status:\"valid\",value:s.data[e]}});else if(\"strict\"===e)l.length>0&&((0,a.addIssueToContext)(s,{code:o.ZodIssueCode.unrecognized_keys,keys:l}),t.dirty());else if(\"strip\"!==e)throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\")}else{const e=this._def.catchall;for(const t of l){const r=s.data[t];u.push({key:{status:\"valid\",value:t},value:e._parse(new d(s,r,s.path,t)),alwaysSet:t in s.data})}}return s.common.async?Promise.resolve().then((async()=>{const e=[];for(const t of u){const s=await t.key;e.push({key:s,value:await t.value,alwaysSet:t.alwaysSet})}return e})).then((e=>a.ParseStatus.mergeObjectSync(t,e))):a.ParseStatus.mergeObjectSync(t,u)}get shape(){return this._def.shape()}strict(e){return i.errorUtil.errToObj,new S({...this._def,unknownKeys:\"strict\",...void 0!==e?{errorMap:(t,s)=>{var r,a,n,o;const d=null!==(n=null===(a=(r=this._def).errorMap)||void 0===a?void 0:a.call(r,t,s).message)&&void 0!==n?n:s.defaultError;return\"unrecognized_keys\"===t.code?{message:null!==(o=i.errorUtil.errToObj(e).message)&&void 0!==o?o:d}:{message:d}}}:{}})}strip(){return new S({...this._def,unknownKeys:\"strip\"})}passthrough(){return new S({...this._def,unknownKeys:\"passthrough\"})}extend(e){return new S({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new S({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:oe.ZodObject})}setKey(e,t){return this.augment({[e]:t})}catchall(e){return new S({...this._def,catchall:e})}pick(e){const t={};return n.util.objectKeys(e).forEach((s=>{e[s]&&this.shape[s]&&(t[s]=this.shape[s])})),new S({...this._def,shape:()=>t})}omit(e){const t={};return n.util.objectKeys(this.shape).forEach((s=>{e[s]||(t[s]=this.shape[s])})),new S({...this._def,shape:()=>t})}deepPartial(){return N(this)}partial(e){const t={};return n.util.objectKeys(this.shape).forEach((s=>{const r=this.shape[s];e&&!e[s]?t[s]=r:t[s]=r.optional()})),new S({...this._def,shape:()=>t})}required(e){const t={};return n.util.objectKeys(this.shape).forEach((s=>{if(e&&!e[s])t[s]=this.shape[s];else{let e=this.shape[s];for(;e instanceof Q;)e=e._def.innerType;t[s]=e}})),new S({...this._def,shape:()=>t})}keyof(){return Y(n.util.objectKeys(this.shape))}}t.ZodObject=S,S.create=(e,t)=>new S({shape:()=>e,unknownKeys:\"strip\",catchall:O.create(),typeName:oe.ZodObject,...u(t)}),S.strictCreate=(e,t)=>new S({shape:()=>e,unknownKeys:\"strict\",catchall:O.create(),typeName:oe.ZodObject,...u(t)}),S.lazycreate=(e,t)=>new S({shape:e,unknownKeys:\"strip\",catchall:O.create(),typeName:oe.ZodObject,...u(t)});class A extends c{_parse(e){const{ctx:t}=this._processInputParams(e),s=this._def.options;if(t.common.async)return Promise.all(s.map((async e=>{const s={...t,common:{...t.common,issues:[]},parent:null};return{result:await e._parseAsync({data:t.data,path:t.path,parent:s}),ctx:s}}))).then((function(e){for(const t of e)if(\"valid\"===t.result.status)return t.result;for(const s of e)if(\"dirty\"===s.result.status)return t.common.issues.push(...s.ctx.common.issues),s.result;const s=e.map((e=>new o.ZodError(e.ctx.common.issues)));return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_union,unionErrors:s}),a.INVALID}));{let e;const r=[];for(const i of s){const s={...t,common:{...t.common,issues:[]},parent:null},a=i._parseSync({data:t.data,path:t.path,parent:s});if(\"valid\"===a.status)return a;\"dirty\"!==a.status||e||(e={result:a,ctx:s}),s.common.issues.length&&r.push(s.common.issues)}if(e)return t.common.issues.push(...e.ctx.common.issues),e.result;const i=r.map((e=>new o.ZodError(e)));return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_union,unionErrors:i}),a.INVALID}}get options(){return this._def.options}}t.ZodUnion=A,A.create=(e,t)=>new A({options:e,typeName:oe.ZodUnion,...u(t)});const M=e=>e instanceof G?M(e.schema):e instanceof J?M(e.innerType()):e instanceof W?[e.value]:e instanceof H?e.options:e instanceof q?Object.keys(e.enum):e instanceof te?M(e._def.innerType):e instanceof C?[void 0]:e instanceof z?[null]:null;class D extends c{_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==n.ZodParsedType.object)return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.object,received:t.parsedType}),a.INVALID;const s=this.discriminator,r=t.data[s],i=this.optionsMap.get(r);return i?t.common.async?i._parseAsync({data:t.data,path:t.path,parent:t}):i._parseSync({data:t.data,path:t.path,parent:t}):((0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[s]}),a.INVALID)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,t,s){const r=new Map;for(const s of t){const t=M(s.shape[e]);if(!t)throw new Error(`A discriminator value for key \\`${e}\\` could not be extracted from all schema options`);for(const i of t){if(r.has(i))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(i)}`);r.set(i,s)}}return new D({typeName:oe.ZodDiscriminatedUnion,discriminator:e,options:t,optionsMap:r,...u(s)})}}function U(e,t){const s=(0,n.getParsedType)(e),r=(0,n.getParsedType)(t);if(e===t)return{valid:!0,data:e};if(s===n.ZodParsedType.object&&r===n.ZodParsedType.object){const s=n.util.objectKeys(t),r=n.util.objectKeys(e).filter((e=>-1!==s.indexOf(e))),i={...e,...t};for(const s of r){const r=U(e[s],t[s]);if(!r.valid)return{valid:!1};i[s]=r.data}return{valid:!0,data:i}}if(s===n.ZodParsedType.array&&r===n.ZodParsedType.array){if(e.length!==t.length)return{valid:!1};const s=[];for(let r=0;r{if((0,a.isAborted)(e)||(0,a.isAborted)(r))return a.INVALID;const i=U(e.value,r.value);return i.valid?(((0,a.isDirty)(e)||(0,a.isDirty)(r))&&t.dirty(),{status:t.value,value:i.data}):((0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_intersection_types}),a.INVALID)};return s.common.async?Promise.all([this._def.left._parseAsync({data:s.data,path:s.path,parent:s}),this._def.right._parseAsync({data:s.data,path:s.path,parent:s})]).then((([e,t])=>r(e,t))):r(this._def.left._parseSync({data:s.data,path:s.path,parent:s}),this._def.right._parseSync({data:s.data,path:s.path,parent:s}))}}t.ZodIntersection=R,R.create=(e,t,s)=>new R({left:e,right:t,typeName:oe.ZodIntersection,...u(s)});class V extends c{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==n.ZodParsedType.array)return(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.array,received:s.parsedType}),a.INVALID;if(s.data.lengththis._def.items.length&&((0,a.addIssueToContext)(s,{code:o.ZodIssueCode.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),t.dirty());const r=[...s.data].map(((e,t)=>{const r=this._def.items[t]||this._def.rest;return r?r._parse(new d(s,e,s.path,t)):null})).filter((e=>!!e));return s.common.async?Promise.all(r).then((e=>a.ParseStatus.mergeArray(t,e))):a.ParseStatus.mergeArray(t,r)}get items(){return this._def.items}rest(e){return new V({...this._def,rest:e})}}t.ZodTuple=V,V.create=(e,t)=>{if(!Array.isArray(e))throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");return new V({items:e,typeName:oe.ZodTuple,rest:null,...u(t)})};class $ extends c{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==n.ZodParsedType.object)return(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.object,received:s.parsedType}),a.INVALID;const r=[],i=this._def.keyType,l=this._def.valueType;for(const e in s.data)r.push({key:i._parse(new d(s,e,s.path,e)),value:l._parse(new d(s,s.data[e],s.path,e))});return s.common.async?a.ParseStatus.mergeObjectAsync(t,r):a.ParseStatus.mergeObjectSync(t,r)}get element(){return this._def.valueType}static create(e,t,s){return new $(t instanceof c?{keyType:e,valueType:t,typeName:oe.ZodRecord,...u(s)}:{keyType:b.create(),valueType:e,typeName:oe.ZodRecord,...u(t)})}}t.ZodRecord=$;class B extends c{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==n.ZodParsedType.map)return(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.map,received:s.parsedType}),a.INVALID;const r=this._def.keyType,i=this._def.valueType,l=[...s.data.entries()].map((([e,t],a)=>({key:r._parse(new d(s,e,s.path,[a,\"key\"])),value:i._parse(new d(s,t,s.path,[a,\"value\"]))})));if(s.common.async){const e=new Map;return Promise.resolve().then((async()=>{for(const s of l){const r=await s.key,i=await s.value;if(\"aborted\"===r.status||\"aborted\"===i.status)return a.INVALID;\"dirty\"!==r.status&&\"dirty\"!==i.status||t.dirty(),e.set(r.value,i.value)}return{status:t.value,value:e}}))}{const e=new Map;for(const s of l){const r=s.key,i=s.value;if(\"aborted\"===r.status||\"aborted\"===i.status)return a.INVALID;\"dirty\"!==r.status&&\"dirty\"!==i.status||t.dirty(),e.set(r.value,i.value)}return{status:t.value,value:e}}}}t.ZodMap=B,B.create=(e,t,s)=>new B({valueType:t,keyType:e,typeName:oe.ZodMap,...u(s)});class F extends c{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==n.ZodParsedType.set)return(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.set,received:s.parsedType}),a.INVALID;const r=this._def;null!==r.minSize&&s.data.sizer.maxSize.value&&((0,a.addIssueToContext)(s,{code:o.ZodIssueCode.too_big,maximum:r.maxSize.value,type:\"set\",inclusive:!0,exact:!1,message:r.maxSize.message}),t.dirty());const i=this._def.valueType;function l(e){const s=new Set;for(const r of e){if(\"aborted\"===r.status)return a.INVALID;\"dirty\"===r.status&&t.dirty(),s.add(r.value)}return{status:t.value,value:s}}const u=[...s.data.values()].map(((e,t)=>i._parse(new d(s,e,s.path,t))));return s.common.async?Promise.all(u).then((e=>l(e))):l(u)}min(e,t){return new F({...this._def,minSize:{value:e,message:i.errorUtil.toString(t)}})}max(e,t){return new F({...this._def,maxSize:{value:e,message:i.errorUtil.toString(t)}})}size(e,t){return this.min(e,t).max(e,t)}nonempty(e){return this.min(1,e)}}t.ZodSet=F,F.create=(e,t)=>new F({valueType:e,minSize:null,maxSize:null,typeName:oe.ZodSet,...u(t)});class K extends c{constructor(){super(...arguments),this.validate=this.implement}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==n.ZodParsedType.function)return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.function,received:t.parsedType}),a.INVALID;function s(e,s){return(0,a.makeIssue)({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,(0,r.getErrorMap)(),r.defaultErrorMap].filter((e=>!!e)),issueData:{code:o.ZodIssueCode.invalid_arguments,argumentsError:s}})}function i(e,s){return(0,a.makeIssue)({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,(0,r.getErrorMap)(),r.defaultErrorMap].filter((e=>!!e)),issueData:{code:o.ZodIssueCode.invalid_return_type,returnTypeError:s}})}const d={errorMap:t.common.contextualErrorMap},l=t.data;if(this._def.returns instanceof X){const e=this;return(0,a.OK)((async function(...t){const r=new o.ZodError([]),a=await e._def.args.parseAsync(t,d).catch((e=>{throw r.addIssue(s(t,e)),r})),n=await Reflect.apply(l,this,a);return await e._def.returns._def.type.parseAsync(n,d).catch((e=>{throw r.addIssue(i(n,e)),r}))}))}{const e=this;return(0,a.OK)((function(...t){const r=e._def.args.safeParse(t,d);if(!r.success)throw new o.ZodError([s(t,r.error)]);const a=Reflect.apply(l,this,r.data),n=e._def.returns.safeParse(a,d);if(!n.success)throw new o.ZodError([i(a,n.error)]);return n.data}))}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new K({...this._def,args:V.create(e).rest(P.create())})}returns(e){return new K({...this._def,returns:e})}implement(e){return this.parse(e)}strictImplement(e){return this.parse(e)}static create(e,t,s){return new K({args:e||V.create([]).rest(P.create()),returns:t||P.create(),typeName:oe.ZodFunction,...u(s)})}}t.ZodFunction=K;class G extends c{get schema(){return this._def.getter()}_parse(e){const{ctx:t}=this._processInputParams(e);return this._def.getter()._parse({data:t.data,path:t.path,parent:t})}}t.ZodLazy=G,G.create=(e,t)=>new G({getter:e,typeName:oe.ZodLazy,...u(t)});class W extends c{_parse(e){if(e.data!==this._def.value){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{received:t.data,code:o.ZodIssueCode.invalid_literal,expected:this._def.value}),a.INVALID}return{status:\"valid\",value:e.data}}get value(){return this._def.value}}function Y(e,t){return new H({values:e,typeName:oe.ZodEnum,...u(t)})}t.ZodLiteral=W,W.create=(e,t)=>new W({value:e,typeName:oe.ZodLiteral,...u(t)});class H extends c{_parse(e){if(\"string\"!=typeof e.data){const t=this._getOrReturnCtx(e),s=this._def.values;return(0,a.addIssueToContext)(t,{expected:n.util.joinValues(s),received:t.parsedType,code:o.ZodIssueCode.invalid_type}),a.INVALID}if(-1===this._def.values.indexOf(e.data)){const t=this._getOrReturnCtx(e),s=this._def.values;return(0,a.addIssueToContext)(t,{received:t.data,code:o.ZodIssueCode.invalid_enum_value,options:s}),a.INVALID}return(0,a.OK)(e.data)}get options(){return this._def.values}get enum(){const e={};for(const t of this._def.values)e[t]=t;return e}get Values(){const e={};for(const t of this._def.values)e[t]=t;return e}get Enum(){const e={};for(const t of this._def.values)e[t]=t;return e}extract(e){return H.create(e)}exclude(e){return H.create(this.options.filter((t=>!e.includes(t))))}}t.ZodEnum=H,H.create=Y;class q extends c{_parse(e){const t=n.util.getValidEnumValues(this._def.values),s=this._getOrReturnCtx(e);if(s.parsedType!==n.ZodParsedType.string&&s.parsedType!==n.ZodParsedType.number){const e=n.util.objectValues(t);return(0,a.addIssueToContext)(s,{expected:n.util.joinValues(e),received:s.parsedType,code:o.ZodIssueCode.invalid_type}),a.INVALID}if(-1===t.indexOf(e.data)){const e=n.util.objectValues(t);return(0,a.addIssueToContext)(s,{received:s.data,code:o.ZodIssueCode.invalid_enum_value,options:e}),a.INVALID}return(0,a.OK)(e.data)}get enum(){return this._def.values}}t.ZodNativeEnum=q,q.create=(e,t)=>new q({values:e,typeName:oe.ZodNativeEnum,...u(t)});class X extends c{unwrap(){return this._def.type}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==n.ZodParsedType.promise&&!1===t.common.async)return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.promise,received:t.parsedType}),a.INVALID;const s=t.parsedType===n.ZodParsedType.promise?t.data:Promise.resolve(t.data);return(0,a.OK)(s.then((e=>this._def.type.parseAsync(e,{path:t.path,errorMap:t.common.contextualErrorMap}))))}}t.ZodPromise=X,X.create=(e,t)=>new X({type:e,typeName:oe.ZodPromise,...u(t)});class J extends c{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===oe.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(e){const{status:t,ctx:s}=this._processInputParams(e),r=this._def.effect||null,i={addIssue:e=>{(0,a.addIssueToContext)(s,e),e.fatal?t.abort():t.dirty()},get path(){return s.path}};if(i.addIssue=i.addIssue.bind(i),\"preprocess\"===r.type){const e=r.transform(s.data,i);return s.common.issues.length?{status:\"dirty\",value:s.data}:s.common.async?Promise.resolve(e).then((e=>this._def.schema._parseAsync({data:e,path:s.path,parent:s}))):this._def.schema._parseSync({data:e,path:s.path,parent:s})}if(\"refinement\"===r.type){const e=e=>{const t=r.refinement(e,i);if(s.common.async)return Promise.resolve(t);if(t instanceof Promise)throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");return e};if(!1===s.common.async){const r=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});return\"aborted\"===r.status?a.INVALID:(\"dirty\"===r.status&&t.dirty(),e(r.value),{status:t.value,value:r.value})}return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then((s=>\"aborted\"===s.status?a.INVALID:(\"dirty\"===s.status&&t.dirty(),e(s.value).then((()=>({status:t.value,value:s.value}))))))}if(\"transform\"===r.type){if(!1===s.common.async){const e=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});if(!(0,a.isValid)(e))return e;const n=r.transform(e.value,i);if(n instanceof Promise)throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");return{status:t.value,value:n}}return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then((e=>(0,a.isValid)(e)?Promise.resolve(r.transform(e.value,i)).then((e=>({status:t.value,value:e}))):e))}n.util.assertNever(r)}}t.ZodEffects=J,t.ZodTransformer=J,J.create=(e,t,s)=>new J({schema:e,typeName:oe.ZodEffects,effect:t,...u(s)}),J.createWithPreprocess=(e,t,s)=>new J({schema:t,effect:{type:\"preprocess\",transform:e},typeName:oe.ZodEffects,...u(s)});class Q extends c{_parse(e){return this._getType(e)===n.ZodParsedType.undefined?(0,a.OK)(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}t.ZodOptional=Q,Q.create=(e,t)=>new Q({innerType:e,typeName:oe.ZodOptional,...u(t)});class ee extends c{_parse(e){return this._getType(e)===n.ZodParsedType.null?(0,a.OK)(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}t.ZodNullable=ee,ee.create=(e,t)=>new ee({innerType:e,typeName:oe.ZodNullable,...u(t)});class te extends c{_parse(e){const{ctx:t}=this._processInputParams(e);let s=t.data;return t.parsedType===n.ZodParsedType.undefined&&(s=this._def.defaultValue()),this._def.innerType._parse({data:s,path:t.path,parent:t})}removeDefault(){return this._def.innerType}}t.ZodDefault=te,te.create=(e,t)=>new te({innerType:e,typeName:oe.ZodDefault,defaultValue:\"function\"==typeof t.default?t.default:()=>t.default,...u(t)});class se extends c{_parse(e){const{ctx:t}=this._processInputParams(e),s={...t,common:{...t.common,issues:[]}},r=this._def.innerType._parse({data:s.data,path:s.path,parent:{...s}});return(0,a.isAsync)(r)?r.then((e=>({status:\"valid\",value:\"valid\"===e.status?e.value:this._def.catchValue({get error(){return new o.ZodError(s.common.issues)},input:s.data})}))):{status:\"valid\",value:\"valid\"===r.status?r.value:this._def.catchValue({get error(){return new o.ZodError(s.common.issues)},input:s.data})}}removeCatch(){return this._def.innerType}}t.ZodCatch=se,se.create=(e,t)=>new se({innerType:e,typeName:oe.ZodCatch,catchValue:\"function\"==typeof t.catch?t.catch:()=>t.catch,...u(t)});class re extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.nan){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.nan,received:t.parsedType}),a.INVALID}return{status:\"valid\",value:e.data}}}t.ZodNaN=re,re.create=e=>new re({typeName:oe.ZodNaN,...u(e)}),t.BRAND=Symbol(\"zod_brand\");class ie extends c{_parse(e){const{ctx:t}=this._processInputParams(e),s=t.data;return this._def.type._parse({data:s,path:t.path,parent:t})}unwrap(){return this._def.type}}t.ZodBranded=ie;class ae extends c{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.common.async)return(async()=>{const e=await this._def.in._parseAsync({data:s.data,path:s.path,parent:s});return\"aborted\"===e.status?a.INVALID:\"dirty\"===e.status?(t.dirty(),(0,a.DIRTY)(e.value)):this._def.out._parseAsync({data:e.value,path:s.path,parent:s})})();{const e=this._def.in._parseSync({data:s.data,path:s.path,parent:s});return\"aborted\"===e.status?a.INVALID:\"dirty\"===e.status?(t.dirty(),{status:\"dirty\",value:e.value}):this._def.out._parseSync({data:e.value,path:s.path,parent:s})}}static create(e,t){return new ae({in:e,out:t,typeName:oe.ZodPipeline})}}t.ZodPipeline=ae;class ne extends c{_parse(e){const t=this._def.innerType._parse(e);return(0,a.isValid)(t)&&(t.value=Object.freeze(t.value)),t}}var oe;t.ZodReadonly=ne,ne.create=(e,t)=>new ne({innerType:e,typeName:oe.ZodReadonly,...u(t)}),t.custom=(e,t={},s)=>e?L.create().superRefine(((r,i)=>{var a,n;if(!e(r)){const e=\"function\"==typeof t?t(r):\"string\"==typeof t?{message:t}:t,o=null===(n=null!==(a=e.fatal)&&void 0!==a?a:s)||void 0===n||n,d=\"string\"==typeof e?{message:e}:e;i.addIssue({code:\"custom\",...d,fatal:o})}})):L.create(),t.late={object:S.lazycreate},function(e){e.ZodString=\"ZodString\",e.ZodNumber=\"ZodNumber\",e.ZodNaN=\"ZodNaN\",e.ZodBigInt=\"ZodBigInt\",e.ZodBoolean=\"ZodBoolean\",e.ZodDate=\"ZodDate\",e.ZodSymbol=\"ZodSymbol\",e.ZodUndefined=\"ZodUndefined\",e.ZodNull=\"ZodNull\",e.ZodAny=\"ZodAny\",e.ZodUnknown=\"ZodUnknown\",e.ZodNever=\"ZodNever\",e.ZodVoid=\"ZodVoid\",e.ZodArray=\"ZodArray\",e.ZodObject=\"ZodObject\",e.ZodUnion=\"ZodUnion\",e.ZodDiscriminatedUnion=\"ZodDiscriminatedUnion\",e.ZodIntersection=\"ZodIntersection\",e.ZodTuple=\"ZodTuple\",e.ZodRecord=\"ZodRecord\",e.ZodMap=\"ZodMap\",e.ZodSet=\"ZodSet\",e.ZodFunction=\"ZodFunction\",e.ZodLazy=\"ZodLazy\",e.ZodLiteral=\"ZodLiteral\",e.ZodEnum=\"ZodEnum\",e.ZodEffects=\"ZodEffects\",e.ZodNativeEnum=\"ZodNativeEnum\",e.ZodOptional=\"ZodOptional\",e.ZodNullable=\"ZodNullable\",e.ZodDefault=\"ZodDefault\",e.ZodCatch=\"ZodCatch\",e.ZodPromise=\"ZodPromise\",e.ZodBranded=\"ZodBranded\",e.ZodPipeline=\"ZodPipeline\",e.ZodReadonly=\"ZodReadonly\"}(oe=t.ZodFirstPartyTypeKind||(t.ZodFirstPartyTypeKind={})),t.instanceof=(e,s={message:`Input not instance of ${e.name}`})=>(0,t.custom)((t=>t instanceof e),s);const de=b.create;t.string=de;const le=I.create;t.number=le;const ue=re.create;t.nan=ue;const ce=Z.create;t.bigint=ce;const pe=T.create;t.boolean=pe;const he=k.create;t.date=he;const fe=w.create;t.symbol=fe;const me=C.create;t.undefined=me;const ye=z.create;t.null=ye;const _e=L.create;t.any=_e;const ve=P.create;t.unknown=ve;const ge=O.create;t.never=ge;const be=j.create;t.void=be;const xe=E.create;t.array=xe;const Ie=S.create;t.object=Ie;const Ze=S.strictCreate;t.strictObject=Ze;const Te=A.create;t.union=Te;const ke=D.create;t.discriminatedUnion=ke;const we=R.create;t.intersection=we;const Ce=V.create;t.tuple=Ce;const ze=$.create;t.record=ze;const Le=B.create;t.map=Le;const Pe=F.create;t.set=Pe;const Oe=K.create;t.function=Oe;const je=G.create;t.lazy=je;const Ee=W.create;t.literal=Ee;const Ne=H.create;t.enum=Ne;const Se=q.create;t.nativeEnum=Se;const Ae=X.create;t.promise=Ae;const Me=J.create;t.effect=Me,t.transformer=Me;const De=Q.create;t.optional=De;const Ue=ee.create;t.nullable=Ue;const Re=J.createWithPreprocess;t.preprocess=Re;const Ve=ae.create;t.pipeline=Ve,t.ostring=()=>de().optional(),t.onumber=()=>le().optional(),t.oboolean=()=>pe().optional(),t.coerce={string:e=>b.create({...e,coerce:!0}),number:e=>I.create({...e,coerce:!0}),boolean:e=>T.create({...e,coerce:!0}),bigint:e=>Z.create({...e,coerce:!0}),date:e=>k.create({...e,coerce:!0})},t.NEVER=a.INVALID},205:t=>{t.exports=e}},s={};function r(e){var i=s[e];if(void 0!==i)return i.exports;var a=s[e]={exports:{}};return t[e].call(a.exports,a,a.exports,r),a.exports}return r.d=(e,t)=>{for(var s in t)r.o(t,s)&&!r.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},r(607)})()));\n//# sourceMappingURL=excalibur-ldtk.min.js.map","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"excalibur\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"excalibur\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ex\"] = factory(require(\"excalibur\"));\n\telse\n\t\troot[\"ex\"] = root[\"ex\"] || {}, root[\"ex\"][\"Plugin\"] = root[\"ex\"][\"Plugin\"] || {}, root[\"ex\"][\"Plugin\"][\"Ldtk\"] = factory(root[\"ex\"]);\n})(self, (__WEBPACK_EXTERNAL_MODULE__205__) => {\nreturn ","export const semver = /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\nexport const validateAndParse = (version) => {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n const match = version.match(semver);\n if (!match) {\n throw new Error(`Invalid argument not valid semver ('${version}' received)`);\n }\n match.shift();\n return match;\n};\nconst isWildcard = (s) => s === '*' || s === 'x' || s === 'X';\nconst tryParse = (v) => {\n const n = parseInt(v, 10);\n return isNaN(n) ? v : n;\n};\nconst forceType = (a, b) => typeof a !== typeof b ? [String(a), String(b)] : [a, b];\nconst compareStrings = (a, b) => {\n if (isWildcard(a) || isWildcard(b))\n return 0;\n const [ap, bp] = forceType(tryParse(a), tryParse(b));\n if (ap > bp)\n return 1;\n if (ap < bp)\n return -1;\n return 0;\n};\nexport const compareSegments = (a, b) => {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const r = compareStrings(a[i] || '0', b[i] || '0');\n if (r !== 0)\n return r;\n }\n return 0;\n};\n//# sourceMappingURL=utils.js.map","import { compareSegments, validateAndParse } from './utils';\n/**\n * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser.\n * This library supports the full semver specification, including comparing versions with different number of digits like `1.0.0`, `1.0`, `1`, and pre-release versions like `1.0.0-alpha`.\n * @param v1 - First version to compare\n * @param v2 - Second version to compare\n * @returns Numeric value compatible with the [Array.sort(fn) interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters).\n */\nexport const compareVersions = (v1, v2) => {\n // validate input and split into segments\n const n1 = validateAndParse(v1);\n const n2 = validateAndParse(v2);\n // pop off the patch\n const p1 = n1.pop();\n const p2 = n2.pop();\n // validate numbers\n const r = compareSegments(n1, n2);\n if (r !== 0)\n return r;\n // validate pre-release\n if (p1 && p2) {\n return compareSegments(p1.split('.'), p2.split('.'));\n }\n else if (p1 || p2) {\n return p1 ? -1 : 1;\n }\n return 0;\n};\n//# sourceMappingURL=compareVersions.js.map","import { compareVersions } from './compareVersions';\n/**\n * Compare [semver](https://semver.org/) version strings using the specified operator.\n *\n * @param v1 First version to compare\n * @param v2 Second version to compare\n * @param operator Allowed arithmetic operator to use\n * @returns `true` if the comparison between the firstVersion and the secondVersion satisfies the operator, `false` otherwise.\n *\n * @example\n * ```\n * compare('10.1.8', '10.0.4', '>'); // return true\n * compare('10.0.1', '10.0.1', '='); // return true\n * compare('10.1.1', '10.2.2', '<'); // return true\n * compare('10.1.1', '10.2.2', '<='); // return true\n * compare('10.1.1', '10.2.2', '>='); // return false\n * ```\n */\nexport const compare = (v1, v2, operator) => {\n // validate input operator\n assertValidOperator(operator);\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n const res = compareVersions(v1, v2);\n return operatorResMap[operator].includes(res);\n};\nconst operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1],\n '!=': [-1, 1],\n};\nconst allowedOperators = Object.keys(operatorResMap);\nconst assertValidOperator = (op) => {\n if (typeof op !== 'string') {\n throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new Error(`Invalid operator, expected one of ${allowedOperators.join('|')}`);\n }\n};\n//# sourceMappingURL=compare.js.map","import { compare } from './compare';\nimport { compareSegments, validateAndParse } from './utils';\n/**\n * Match [npm semver](https://docs.npmjs.com/cli/v6/using-npm/semver) version range.\n *\n * @param version Version number to match\n * @param range Range pattern for version\n * @returns `true` if the version number is within the range, `false` otherwise.\n *\n * @example\n * ```\n * satisfies('1.1.0', '^1.0.0'); // return true\n * satisfies('1.1.0', '~1.0.0'); // return false\n * ```\n */\nexport const satisfies = (version, range) => {\n // clean input\n range = range.replace(/([><=]+)\\s+/g, '$1');\n // handle multiple comparators\n if (range.includes('||')) {\n return range.split('||').some((r) => satisfies(version, r));\n }\n else if (range.includes(' - ')) {\n const [a, b] = range.split(' - ', 2);\n return satisfies(version, `>=${a} <=${b}`);\n }\n else if (range.includes(' ')) {\n return range\n .trim()\n .replace(/\\s{2,}/g, ' ')\n .split(' ')\n .every((r) => satisfies(version, r));\n }\n // if no range operator then \"=\"\n const m = range.match(/^([<>=~^]+)/);\n const op = m ? m[1] : '=';\n // if gt/lt/eq then operator compare\n if (op !== '^' && op !== '~')\n return compare(version, range, op);\n // else range of either \"~\" or \"^\" is assumed\n const [v1, v2, v3, , vp] = validateAndParse(version);\n const [r1, r2, r3, , rp] = validateAndParse(range);\n const v = [v1, v2, v3];\n const r = [r1, r2 !== null && r2 !== void 0 ? r2 : 'x', r3 !== null && r3 !== void 0 ? r3 : 'x'];\n // validate pre-release\n if (rp) {\n if (!vp)\n return false;\n if (compareSegments(v, r) !== 0)\n return false;\n if (compareSegments(vp.split('.'), rp.split('.')) === -1)\n return false;\n }\n // first non-zero number\n const nonZero = r.findIndex((v) => v !== '0') + 1;\n // pointer to where segments can be >=\n const i = op === '~' ? 2 : nonZero > 1 ? nonZero : 1;\n // before pointer must be equal\n if (compareSegments(v.slice(0, i), r.slice(0, i)) !== 0)\n return false;\n // after pointer must be >=\n if (compareSegments(v.slice(i), r.slice(i)) === -1)\n return false;\n return true;\n};\n//# sourceMappingURL=satisfies.js.map","import { semver } from './utils';\n/**\n * Validate [semver](https://semver.org/) version strings.\n *\n * @param version Version number to validate\n * @returns `true` if the version number is a valid semver version number, `false` otherwise.\n *\n * @example\n * ```\n * validate('1.0.0-rc.1'); // return true\n * validate('1.0-rc.1'); // return false\n * validate('foo'); // return false\n * ```\n */\nexport const validate = (version) => typeof version === 'string' && /^[v\\d]/.test(version) && semver.test(version);\n/**\n * Validate [semver](https://semver.org/) version strings strictly. Will not accept wildcards and version ranges.\n *\n * @param version Version number to validate\n * @returns `true` if the version number is a valid semver version number `false` otherwise\n *\n * @example\n * ```\n * validate('1.0.0-rc.1'); // return true\n * validate('1.0-rc.1'); // return false\n * validate('foo'); // return false\n * ```\n */\nexport const validateStrict = (version) => typeof version === 'string' &&\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/.test(version);\n//# sourceMappingURL=validate.js.map","import { Actor, Entity, Vector, vec } from \"excalibur\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\nimport { LdtkEntityInstance, LdtkLayerInstance } from \"./types\";\r\nimport { Level } from \"./level\";\r\n\r\nexport class EntityLayer {\r\n public worldPos: Vector;\r\n public offset: Vector;\r\n public entities: Entity[] = [];\r\n public ldtkToEntity = new Map();\r\n public entityToLdtk = new Map();\r\n constructor(level: Level, public readonly ldtkLayer: LdtkLayerInstance, private resource: LdtkResource, public readonly order: number) {\r\n this.worldPos = vec(level.ldtkLevel.worldX, level.ldtkLevel.worldY);\r\n this.offset = vec(ldtkLayer.__pxTotalOffsetX, ldtkLayer.__pxTotalOffsetY);\r\n if (ldtkLayer.entityInstances) {\r\n for (let entity of ldtkLayer.entityInstances) {\r\n const entityMetadata = resource.projectMetadata.defs.entities.find(e => {\r\n return e.identifier === entity.__identifier\r\n });\r\n if (resource.factories.has(entity.__identifier)) {\r\n const factory = resource.factories.get(entity.__identifier);\r\n if (factory) {\r\n const newEntity = factory({\r\n type: entity.__identifier,\r\n worldPos: vec(entity.px[0], entity.px[1]).add(this.worldPos.add(this.offset)),\r\n entity,\r\n definition: entityMetadata,\r\n layer: this,\r\n });\r\n if (newEntity) {\r\n this.entities.push(newEntity);\r\n this.ldtkToEntity.set(entity, newEntity);\r\n this.entityToLdtk.set(newEntity, entity);\r\n }\r\n }\r\n } else {\r\n const actor = new Actor({\r\n name: entity.__identifier,\r\n pos: vec(entity.px[0], entity.px[1]).add(this.worldPos.add(this.offset)),\r\n width: entity.width,\r\n height: entity.height,\r\n anchor: vec(entityMetadata?.pivotX ?? 0, entityMetadata?.pivotY ?? 0),\r\n z: order\r\n });\r\n if (entity.__tile) {\r\n const ts = resource.tilesets.get(entity.__tile.tilesetUid);\r\n if (ts) {\r\n const tsxCoord = Math.floor(entity.__tile.x / entity.__tile.w);\r\n const tsyCoord = Math.floor(entity.__tile.y / entity.__tile.h);\r\n const sprite = ts.spritesheet.getSprite(tsxCoord, tsyCoord);\r\n if (sprite) {\r\n actor.graphics.use(sprite);\r\n }\r\n }\r\n }\r\n this.entities.push(actor);\r\n this.ldtkToEntity.set(entity, actor);\r\n this.entityToLdtk.set(actor, entity);\r\n }\r\n }\r\n }\r\n }\r\n\r\n runFactory(ldtkEntityIdentifier: string): Entity | undefined {\r\n if (this.resource.factories.has(ldtkEntityIdentifier)) {\r\n if (this.ldtkLayer.entityInstances) {\r\n for (let entity of this.ldtkLayer.entityInstances) {\r\n const entityMetadata = this.resource.projectMetadata.defs.entities.find(e => {\r\n return e.identifier === entity.__identifier\r\n });\r\n const factory = this.resource.factories.get(entity.__identifier);\r\n if (factory) {\r\n const newEntity = factory({\r\n type: entity.__identifier,\r\n worldPos: vec(entity.px[0], entity.px[1]).add(this.worldPos.add(this.offset)),\r\n entity,\r\n definition: entityMetadata,\r\n layer: this,\r\n });\r\n if (newEntity) {\r\n // remove any pre done entities if a factor covered it\r\n const preExisting = this.ldtkToEntity.get(entity);\r\n if (preExisting) {\r\n const index = this.entities.indexOf(preExisting);\r\n if (index > -1) {\r\n this.entities.splice(index, 1);\r\n this.ldtkToEntity.delete(entity);\r\n this.entityToLdtk.delete(preExisting);\r\n }\r\n }\r\n\r\n this.entities.push(newEntity);\r\n this.ldtkToEntity.set(entity, newEntity);\r\n this.entityToLdtk.set(newEntity, entity);\r\n return newEntity;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n getEntitiesByIdentifier(identifier: string): Entity[] {\r\n const ldtkEntities = this.getLdtkEntitiesByIdentifier(identifier);\r\n let results: Entity[] = [];\r\n for (const ldtk of ldtkEntities) {\r\n const maybeEntity = this.ldtkToEntity.get(ldtk);\r\n if (maybeEntity) {\r\n results.push(maybeEntity);\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n getEntitiesByField(fieldIdentifier: string, value?: any): Entity[] {\r\n const ldtkEntities = this.getLdtkEntitiesByField(fieldIdentifier, value);\r\n let results: Entity[] = [];\r\n for (const ldtk of ldtkEntities) {\r\n const maybeEntity = this.ldtkToEntity.get(ldtk);\r\n if (maybeEntity) {\r\n results.push(maybeEntity);\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Search layer for entities that match an identifier (case insensitive)\r\n * @param identifier \r\n * @returns \r\n */\r\n getLdtkEntitiesByIdentifier(identifier: string): LdtkEntityInstance[] {\r\n return this.ldtkLayer.entityInstances.filter(e => e.__identifier.toLocaleLowerCase() === identifier.toLowerCase());\r\n }\r\n\r\n /**\r\n * Search layer for entities that match a field and optionally a value (both case insensitive)\r\n * @param fieldIdentifier \r\n * @param value\r\n */\r\n getLdtkEntitiesByField(fieldIdentifier: string, value?: any): LdtkEntityInstance[] {\r\n return this.ldtkLayer.entityInstances.filter(e => {\r\n if (value !== undefined) {\r\n let normalizedValue = value;\r\n if (typeof value === 'string') {\r\n normalizedValue = value.toLocaleLowerCase();\r\n }\r\n\r\n const field = e.fieldInstances.find(f => f.__identifier.toLocaleLowerCase() === fieldIdentifier.toLocaleLowerCase());\r\n if (field) {\r\n return field.__value === normalizedValue;\r\n }\r\n return false;\r\n } else {\r\n return !!e.fieldInstances.find(f => f.__identifier.toLocaleLowerCase() === fieldIdentifier.toLocaleLowerCase());\r\n }\r\n });\r\n }\r\n}","\r\n\r\nexport type FileLoader = (path: string, contentType: 'json' | 'xml') => Promise;\r\n\r\nexport const FetchLoader: FileLoader = async (path: string, contentType: 'json' | 'xml') => {\r\n const response = await fetch(path);\r\n switch(contentType.toLowerCase()) {\r\n case 'xml': return await response.text();\r\n case 'json': return await response.json();\r\n default: return await response.text();\r\n }\r\n}","\r\nexport * from './ldtk-resource';\r\nexport * from './entity-layer';\r\nexport * from './file-loader';\r\nexport * from './intgrid-layer';\r\nexport * from './level-resource';\r\nexport * from './level';\r\nexport * from './loader-cache';\r\nexport * from './path-util';\r\nexport * from './tile-layer';\r\nexport * from './tileset';\r\nexport * from './types';","import { TileMap, Vector, vec } from \"excalibur\";\r\nimport { LdtkLayerInstance } from \"./types\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\nimport { Level } from \"./level\";\r\n\r\nexport class IntGridLayer {\r\n\r\n public ldtkLayer: LdtkLayerInstance;\r\n public worldPos: Vector;\r\n public offset: Vector;\r\n public tilemap!: TileMap;\r\n constructor(level: Level, ldtkLayer: LdtkLayerInstance, resource: LdtkResource, public readonly order: number) {\r\n this.worldPos = vec(level.ldtkLevel.worldX, level.ldtkLevel.worldY);\r\n this.offset = vec(ldtkLayer.__pxTotalOffsetX, ldtkLayer.__pxTotalOffsetY);\r\n this.ldtkLayer = ldtkLayer;\r\n if (ldtkLayer.intGridCsv.length) {\r\n\r\n const rows = ldtkLayer.__cHei;\r\n const columns = ldtkLayer.__cWid;\r\n this.tilemap = new TileMap({\r\n name: ldtkLayer.__identifier,\r\n pos: this.worldPos.add(this.offset),\r\n tileWidth: ldtkLayer.__gridSize,\r\n tileHeight: ldtkLayer.__gridSize,\r\n rows,\r\n columns,\r\n });\r\n\r\n // find the intgrid metadata\r\n const layerMetadata = resource.projectMetadata.defs.layers.find(l => {\r\n return ldtkLayer.__identifier === l.identifier;\r\n });\r\n\r\n if (layerMetadata) {\r\n const solidValue = layerMetadata.intGridValues.find(val => {\r\n return val?.identifier?.toLocaleLowerCase() === 'solid';\r\n });\r\n\r\n for (let i = 0; i < ldtkLayer.intGridCsv.length; i++) {\r\n const xCoord = i % columns;\r\n const yCoord = Math.floor(i / columns);\r\n const tile = this.tilemap.getTile(xCoord, yCoord);\r\n if (solidValue && ldtkLayer.intGridCsv[i] === solidValue.value) {\r\n tile.solid = true;\r\n }\r\n\r\n // TODO might be a mistake to treat 1 as solid if there isn't a labelled solid\r\n if (!solidValue && ldtkLayer.intGridCsv[i] === 1) {\r\n tile.solid = true;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}","import { TileLayer } from './tile-layer';\r\nimport { PathMap, pathRelativeToBase } from './path-util';\r\nimport { FetchLoader, FileLoader } from './file-loader';\r\nimport { LdtkEntityDefinition, LdtkEntityInstance, LdtkProjectMetadata } from './types';\r\nimport { compare } from 'compare-versions';\r\nimport { LoaderCache } from './loader-cache';\r\nimport { BoundingBox, Entity, ImageSource, Loadable, Scene, TransformComponent, Vector, vec } from 'excalibur';\r\nimport { LevelResource } from './level-resource';\r\nimport { Tileset } from './tileset';\r\nimport { Level } from './level';\r\nimport { EntityLayer } from './entity-layer';\r\nimport { IntGridLayer } from './intgrid-layer';\r\n\r\nexport interface AddToSceneOptions {\r\n /**\r\n * Optionally set the position to place the levels\r\n * \r\n * Default is vec(0, 0)\r\n */\r\n pos?: Vector;\r\n /**\r\n * Optionally add only specific levels to the scene\r\n * \r\n * Default includes all levels\r\n */\r\n levelFilter?: string[];\r\n\r\n /**\r\n * Optionally use the level world offsets, this is useful if your levels are arranged the way you want them\r\n * to appear in your game.\r\n * \r\n * Default is true\r\n */\r\n useLevelOffsets?: boolean;\r\n}\r\n\r\nexport interface FactoryProps {\r\n /**\r\n * Excalibur world position\r\n */\r\n worldPos: Vector;\r\n /**\r\n * LDtk name in UI\r\n */\r\n name?: string;\r\n /**\r\n * LDtk type in UI\r\n */\r\n type: string;\r\n /**\r\n * LDtk entity\r\n */\r\n entity: LdtkEntityInstance;\r\n /**\r\n * LDtk entity metadata\r\n */\r\n definition: LdtkEntityDefinition | undefined;\r\n /**\r\n * Layer\r\n */\r\n layer: EntityLayer;\r\n}\r\n\r\nexport interface LdtkResourceOptions {\r\n /**\r\n * Add a starting z index for the layers to use. By default the layers count up from 0.\r\n *\r\n * If you'd like to manually override a z-index on a layer use the 'zindex' custom property on a layer.\r\n */\r\n startZIndex?: number;\r\n\r\n /**\r\n * Default true. If false, only tilemap will be parsed and displayed, it's up to you to wire up any excalibur behavior.\r\n * Automatically wires excalibur to the following\r\n * * Wire up current scene camera\r\n *\r\n * Read more at excaliburjs.com!\r\n */\r\n useExcaliburWiring?: boolean;\r\n\r\n /**\r\n * Sets excalibur's background color to match the LDtk map\r\n */\r\n useMapBackgroundColor?: boolean;\r\n\r\n /**\r\n * The pathMap helps work around odd things bundlers do with static files by providing a way to redirect the original\r\n * source paths in the LDtk files to new locations.\r\n *\r\n * When the LDtk resource comes across something that matches `path`, it will use the output string instead.\r\n * \r\n * Example:\r\n * ```typescript\r\n * const newResource = new LdtkResource('./example-city.ldtk', {\r\n * pathMap: [\r\n * // If the \"path\" is included in the source path, the output will be used\r\n * { path: 'cone.png', output: '/static/assets/cone.png' },\r\n * // Regex matching with special [match] in output string that is replaced with the first match from the regex\r\n * { path: /(.*\\..*$)/, output: '/static/assets/[match]'}\r\n * ]\r\n * }\r\n * ```\r\n */\r\n pathMap?: PathMap;\r\n\r\n /**\r\n * Optionally provide a custom file loader implementation instead of using the built in ajax (fetch) loader\r\n * that takes a path and returns file data\r\n * \r\n */\r\n fileLoader?: FileLoader;\r\n\r\n /**\r\n * By default `true`, means LDtk files must pass the plugins Typed parse pass.\r\n *\r\n * If you have something that the LDtk plugin does not expect, you can set this to false and it will do it's best\r\n * to parse the LDtk source map file.\r\n */\r\n strict?: boolean;\r\n\r\n /**\r\n * Plugin will operate in headless mode and skip all graphics related\r\n * excalibur items including creating ImageSource's for LDtk items.\r\n *\r\n * Default false.\r\n */\r\n headless?: boolean;\r\n\r\n /**\r\n * Keeps the camera viewport within the bounds of the TileMap, uses the first tile layer's bounds.\r\n *\r\n * Defaults true, if false the camera will use the layer bounds to keep the camera from showing the background.\r\n */\r\n useTilemapCameraStrategy?: boolean;\r\n\r\n /**\r\n * Configure custom Actor/Entity factory functions to construct Actors/Entities\r\n * given a LDtk type name\r\n */\r\n entityIdentifierFactories?: Record Entity | undefined>;\r\n}\r\n\r\nexport class LdtkResource implements Loadable {\r\n public static supportedLdtkVersion = \"1.5.3\";\r\n public projectMetadata!: LdtkProjectMetadata;\r\n data!: LdtkProjectMetadata;\r\n\r\n\r\n public tilesets = new Map();\r\n public levels = new Map();\r\n public levelsByName = new Map();\r\n public factories = new Map Entity | undefined>();\r\n public fileLoader: FileLoader = FetchLoader;\r\n public pathMap: PathMap | undefined;\r\n\r\n private _imageLoader = new LoaderCache(ImageSource);\r\n private _levelLoader = new LoaderCache(LevelResource);\r\n\r\n\r\n public readonly startZIndex: number = 0;\r\n public readonly textQuality: number = 4;\r\n public readonly useExcaliburWiring: boolean = true;\r\n public readonly useMapBackgroundColor: boolean = false;\r\n public readonly useTilemapCameraStrategy: boolean = false;\r\n public readonly headless: boolean = false;\r\n public readonly strict: boolean = true;\r\n\r\n constructor(public readonly path: string, options?: LdtkResourceOptions) {\r\n const {\r\n useExcaliburWiring,\r\n useTilemapCameraStrategy,\r\n entityIdentifierFactories,\r\n pathMap,\r\n useMapBackgroundColor,\r\n fileLoader,\r\n strict,\r\n headless,\r\n startZIndex\r\n } = { ...options };\r\n this.strict = strict ?? this.strict;\r\n this.headless = headless ?? this.headless;\r\n this.useExcaliburWiring = useExcaliburWiring ?? this.useExcaliburWiring;\r\n this.useTilemapCameraStrategy = useTilemapCameraStrategy ?? this.useTilemapCameraStrategy;\r\n this.useMapBackgroundColor = useMapBackgroundColor ?? this.useMapBackgroundColor;\r\n this.startZIndex = startZIndex ?? this.startZIndex;\r\n this.fileLoader = fileLoader ?? this.fileLoader;\r\n this.pathMap = pathMap;\r\n for (const key in entityIdentifierFactories) {\r\n this.registerEntityIdentifierFactory(key, entityIdentifierFactories[key]);\r\n }\r\n\r\n }\r\n async load(): Promise {\r\n const data = await this.fileLoader(this.path, 'json');\r\n if (this.strict) {\r\n try {\r\n this.projectMetadata = LdtkProjectMetadata.parse(data);\r\n } catch (e) {\r\n console.error(`Could not parse LDtk map from location ${this.path}.\\nExcalibur only supports the latest version of LDtk formats as of the plugin's release.`);\r\n console.error(`Is your map file corrupted or being interpreted as the wrong type?`)\r\n throw e;\r\n }\r\n } else {\r\n this.projectMetadata = data as LdtkProjectMetadata;\r\n }\r\n\r\n if (compare(LdtkResource.supportedLdtkVersion, this.projectMetadata.jsonVersion ?? '0.0.0', \">\")) {\r\n console.warn(`The excalibur ldtk plugin officially supports ${LdtkResource.supportedLdtkVersion}+, the current map has LDtk version ${this.projectMetadata.jsonVersion}`)\r\n }\r\n\r\n // iterate through the defs\r\n // load the tilesets\r\n const imagesToLoad: Promise[] = [];\r\n for (let tileset of this.projectMetadata.defs.tilesets) {\r\n if (tileset.relPath) {\r\n const imagePath = pathRelativeToBase(this.path, tileset.relPath, this.pathMap);\r\n const image = this._imageLoader.getOrAdd(imagePath);\r\n const friendlyTileset = new Tileset({\r\n image,\r\n ldtkTileset: tileset\r\n });\r\n this.tilesets.set(tileset.uid, friendlyTileset);\r\n } else {\r\n if (tileset.identifier !== 'Internal_Icons') {\r\n console.warn(`No tileset image provided for ${tileset.identifier}`);\r\n }\r\n }\r\n }\r\n\r\n // iterate through the levels\r\n // load the level metadata\r\n for (let level of this.projectMetadata.levels) {\r\n if (level.externalRelPath) {\r\n // external levels\r\n const levelPath = pathRelativeToBase(this.path, level.externalRelPath, this.pathMap);\r\n this._levelLoader.getOrAdd(levelPath, this, {\r\n headless: this.headless,\r\n strict: this.strict,\r\n fileLoader: this.fileLoader,\r\n imageLoader: this._imageLoader,\r\n pathMap: this.pathMap\r\n });\r\n } else {\r\n // embedded levels\r\n const friendlyLevel = new Level(level, this);\r\n this.levels.set(level.uid, friendlyLevel);\r\n this.levelsByName.set(level.identifier.toLowerCase(), friendlyLevel);\r\n }\r\n }\r\n\r\n await Promise.all([this._imageLoader.load(), this._levelLoader.load()]);\r\n this._levelLoader.values().forEach(level => {\r\n this.levels.set(level.data.ldtkLevel.uid, level.data);\r\n this.levelsByName.set(level.data.ldtkLevel.identifier.toLowerCase(), level.data);\r\n });\r\n\r\n return this.data = this.projectMetadata;\r\n };\r\n\r\n isLoaded(): boolean {\r\n return !!this.data;\r\n }\r\n\r\n registerEntityIdentifierFactory(ldtkEntityIdentifier: string, factory: (props: FactoryProps) => Entity | undefined): void {\r\n this.factories.set(ldtkEntityIdentifier, factory);\r\n if (this.isLoaded()) {\r\n for (let entityLayer of this.getEntityLayers()) {\r\n entityLayer.runFactory(ldtkEntityIdentifier);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get a level by identifier\r\n * @param identifier \r\n * @returns \r\n */\r\n getLevel(identifier: string): Level | undefined {\r\n return this.levelsByName.get(identifier.toLowerCase());\r\n }\r\n\r\n /**\r\n * Get the entity layers, optionally provide a level identifier to filter to\r\n * @param levelIdentifier \r\n */\r\n getEntityLayers(levelIdentifier?: string): EntityLayer[] {\r\n let results: EntityLayer[] = [];\r\n if (levelIdentifier) {\r\n const level = this.getLevel(levelIdentifier);\r\n if (level) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof EntityLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const level of this.levels.values()) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof EntityLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return results\r\n }\r\n\r\n getTileLayers(identifier?: string): TileLayer[] {\r\n let results: TileLayer[] = [];\r\n if (identifier) {\r\n const level = this.getLevel(identifier);\r\n if (level) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof TileLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const level of this.levels.values()) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof TileLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n getIntGridLayers(identifier?: string): IntGridLayer[] {\r\n let results: IntGridLayer[] = [];\r\n if (identifier) {\r\n const level = this.getLevel(identifier);\r\n if (level) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof IntGridLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const level of this.levels.values()) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof IntGridLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Search layer for entities that match an identifier (case insensitive)\r\n * @param identifier \r\n * @returns \r\n */\r\n getLdtkEntitiesByIdentifier(identifier: string, levels?: string[]): LdtkEntityInstance[] {\r\n let results: LdtkEntityInstance[] = [];\r\n const levelsToSearch = levels ?? Array.from(this.levels.values()).map(l => l.ldtkLevel.identifier);\r\n for (const level of levelsToSearch) {\r\n const layers = this.getEntityLayers(level);\r\n for (let layer of layers) {\r\n results = results.concat(layer.getLdtkEntitiesByIdentifier(identifier));\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Search levels for ldtk entities that match a field and optionally a value (both case insensitive)\r\n * @param fieldIdentifier \r\n * @param value\r\n */\r\n getLdtkEntitiesByField(fieldIdentifier: string, value?: any, levels?: string[]): LdtkEntityInstance[] {\r\n let results: LdtkEntityInstance[] = [];\r\n const levelsToSearch = levels ?? Array.from(this.levels.values()).map(l => l.ldtkLevel.identifier);\r\n for (const level of levelsToSearch) {\r\n const layers = this.getEntityLayers(level);\r\n for (let layer of layers) {\r\n results = results.concat(layer.getLdtkEntitiesByField(fieldIdentifier, value));\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Search levels for excalibur entities that match an identifier (case insensitive)\r\n * @param identifier\r\n * @param levels\r\n */\r\n getEntitiesByIdentifier(identifier: string, levels?: string[]): Entity[] {\r\n let results: Entity[] = [];\r\n const levelsToSearch = levels ?? Array.from(this.levels.values()).map(l => l.ldtkLevel.identifier);\r\n for (const level of levelsToSearch) {\r\n const layers = this.getEntityLayers(level);\r\n for (let layer of layers) {\r\n results = results.concat(layer.getEntitiesByIdentifier(identifier));\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Search levels for excalibur entities that match a field and optionally a value (both case insensitive)\r\n * @param fieldIdentifier\r\n * @param value\r\n * @param levels\r\n */\r\n getEntitiesByField(fieldIdentifier: string, value?: any, levels?: string[]): Entity[] {\r\n let results: Entity[] = [];\r\n const levelsToSearch = levels ?? Array.from(this.levels.values()).map(l => l.ldtkLevel.identifier);\r\n for (const level of levelsToSearch) {\r\n const layers = this.getEntityLayers(level);\r\n for (let layer of layers) {\r\n results = results.concat(layer.getEntitiesByField(fieldIdentifier, value));\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Get the level bounds given a list of level identifiers (case insensitive)\r\n * @param levels\r\n */\r\n getLevelBounds(levels?: string[]): BoundingBox {\r\n levels = levels ?? Array.from(this.levelsByName.keys());\r\n let bounds = new BoundingBox();\r\n for (const level of this.levels.values()) {\r\n if (!levels.includes(level.ldtkLevel.identifier)) {\r\n continue;\r\n }\r\n const firstTileLayer = this.getTileLayers(level.ldtkLevel.identifier)[0];\r\n if (firstTileLayer) {\r\n bounds = bounds.combine(\r\n BoundingBox.fromDimension(\r\n firstTileLayer.tilemap.tileWidth * firstTileLayer.tilemap.columns,\r\n firstTileLayer.tilemap.tileHeight * firstTileLayer.tilemap.rows,\r\n Vector.Zero,\r\n firstTileLayer.tilemap.pos)\r\n );\r\n }\r\n }\r\n return bounds;\r\n }\r\n\r\n addToScene(scene: Scene, options?: AddToSceneOptions) {\r\n const { pos, useLevelOffsets } = {pos: vec(0, 0), useLevelOffsets: true, ...options};\r\n\r\n for (let [id, level] of this.levels.entries()) {\r\n if (options?.levelFilter?.length) {\r\n if (!options.levelFilter.includes(level.ldtkLevel.identifier)) {\r\n continue;\r\n }\r\n }\r\n for (let layer of level.layers) {\r\n if (layer instanceof TileLayer || layer instanceof IntGridLayer) {\r\n layer.tilemap.pos = layer.tilemap.pos.add(pos);\r\n if (!useLevelOffsets) {\r\n layer.tilemap.pos = layer.tilemap.pos.sub(layer.worldPos);\r\n }\r\n scene.add(layer.tilemap)\r\n } else {\r\n for (let entity of layer.entities) {\r\n const tx = entity.get(TransformComponent);\r\n if (tx) {\r\n tx.pos = tx.pos.add(pos);\r\n if (!useLevelOffsets) {\r\n tx.pos = tx.pos.sub(layer.worldPos);\r\n }\r\n }\r\n scene.add(entity);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(this.useExcaliburWiring) {\r\n const camera = this.getLdtkEntitiesByField('camera', true)[0];\r\n if (camera) {\r\n scene.camera.pos = vec(camera.px[0], camera.px[0]);\r\n const zoom = camera.fieldInstances.find(f => f.__identifier.toLocaleLowerCase() === 'zoom');\r\n if (zoom) {\r\n scene.camera.zoom = +zoom.__value;\r\n }\r\n }\r\n }\r\n\r\n if (this.useTilemapCameraStrategy) {\r\n let bounds = this.getLevelBounds(options?.levelFilter);\r\n scene.camera.strategy.limitCameraBounds(bounds);\r\n }\r\n\r\n if (this.useMapBackgroundColor) {\r\n for (let [id, level] of this.levels.entries()) {\r\n if (options?.levelFilter?.length) {\r\n if (!options.levelFilter.includes(level.ldtkLevel.identifier)) {\r\n continue;\r\n }\r\n }\r\n scene.backgroundColor = level.backgroundColor;\r\n break;\r\n }\r\n }\r\n\r\n\r\n }\r\n}","import { ImageSource, Loadable } from \"excalibur\";\r\nimport { PathMap } from \"./path-util\";\r\nimport { LoaderCache } from \"./loader-cache\";\r\nimport { FetchLoader, FileLoader } from \"./file-loader\";\r\nimport { Level } from \"./level\";\r\nimport { LdtkLevel } from \"./types\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\n\r\nexport interface LevelResourceOptions {\r\n headless?: boolean;\r\n strict?: boolean;\r\n fileLoader?: FileLoader;\r\n imageLoader?: LoaderCache;\r\n pathMap?: PathMap;\r\n}\r\n\r\n/**\r\n * Loads LDtk levels that are stored in separate files\r\n */\r\nexport class LevelResource implements Loadable {\r\n private fileLoader: FileLoader = FetchLoader;\r\n private imageLoader: LoaderCache;\r\n private pathMap?: PathMap;\r\n public readonly strict: boolean = true;\r\n public readonly headless: boolean = false;\r\n constructor(public readonly path: string, public readonly resource: LdtkResource, options?: LevelResourceOptions) {\r\n const { headless, strict, fileLoader, imageLoader, pathMap } = { ...options };\r\n this.fileLoader = fileLoader ?? this.fileLoader;\r\n this.strict = strict ?? this.strict;\r\n this.headless = headless ?? this.headless;\r\n this.imageLoader = imageLoader ?? new LoaderCache(ImageSource);\r\n this.pathMap = pathMap ?? this.pathMap;\r\n }\r\n data!: Level;\r\n async load(): Promise {\r\n const data = await this.fileLoader(this.path, 'json');\r\n let level: LdtkLevel;\r\n if (this.strict) {\r\n try {\r\n level = LdtkLevel.parse(data)\r\n } catch (e) {\r\n console.error(`Could not parse LDtk level data at ${this.path} are you sure a level is there and not corrupt?`);\r\n throw e;\r\n }\r\n } else {\r\n level = data as LdtkLevel;\r\n }\r\n return this.data = new Level(level, this.resource);\r\n }\r\n isLoaded(): boolean {\r\n return !!this.data;\r\n }\r\n\r\n}","import { Color } from \"excalibur\";\r\nimport { EntityLayer } from \"./entity-layer\";\r\nimport { IntGridLayer } from \"./intgrid-layer\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\nimport { TileLayer } from \"./tile-layer\";\r\nimport { LdtkLevel } from \"./types\";\r\n\r\nexport class Level {\r\n\r\n public backgroundColor?: Color;\r\n public layers: (TileLayer | IntGridLayer | EntityLayer)[] = []; \r\n\r\n constructor(public ldtkLevel: LdtkLevel, public resource: LdtkResource) {\r\n if (ldtkLevel.__bgColor) {\r\n this.backgroundColor = Color.fromHex(ldtkLevel.__bgColor);\r\n }\r\n if (ldtkLevel.layerInstances) {\r\n let order = resource.startZIndex;\r\n let layers = ldtkLevel.layerInstances.slice().reverse();\r\n for (let layer of layers) {\r\n if (layer.entityInstances?.length !== 0) {\r\n this.layers.push(new EntityLayer(this, layer, resource, order));\r\n }\r\n\r\n if (layer.gridTiles?.length !== 0) {\r\n this.layers.push(new TileLayer(this, layer, resource, order));\r\n }\r\n\r\n if (layer.intGridCsv?.length !== 0) {\r\n this.layers.push(new IntGridLayer(this, layer, resource, order));\r\n }\r\n order++;\r\n }\r\n }\r\n }\r\n}","export interface CanLoad {\r\n load(): Promise;\r\n }\r\n \r\n /**\r\n * Read through cache for loadables\r\n */\r\n export class LoaderCache {\r\n private _loaded = false;\r\n cache = new Map();\r\n \r\n constructor(public readonly type: new (...args: any[]) => T){}\r\n \r\n getOrAdd(...args: any[]): T {\r\n let resource = this.cache.get(args.join('+'));\r\n if (resource) {\r\n return resource;\r\n }\r\n \r\n resource = new this.type(...args);\r\n this.cache.set(args.join('+'), resource);\r\n return resource;\r\n }\r\n \r\n values(): T[] {\r\n if (this._loaded) {\r\n return Array.from(this.cache.values());\r\n }\r\n throw new Error(`Read through cache not yet loaded! No values to return!`);\r\n }\r\n \r\n async load() {\r\n const resources = Array.from(this.cache.entries());\r\n const results = await Promise.allSettled(resources.map(i => i[1].load()));\r\n \r\n // Check for errors loading resources\r\n let errored = 0;\r\n for (let i = 0; i < results.length; i++) {\r\n const result = results[i];\r\n if (result.status === 'rejected') {\r\n console.error(`Error loading resource at ${resources[i][0]}, is your pathMap correct? or your LDtk map corrupted?`, result.reason);\r\n errored++;\r\n }\r\n }\r\n if (errored) {\r\n throw new Error(`Error loading ${errored} resources`);\r\n }\r\n this._loaded = true;\r\n }\r\n }","\r\n\r\nexport type PathMap = { path: string | RegExp, output: string }[];\r\n\r\nexport function filenameFromPath(inputPath: string): string {\r\n const filenameExpression = /[^/\\\\&\\?]+\\.\\w{2,4}(?=([\\#\\?&].*$|$))/ig\r\n\r\n const matches = inputPath.match(filenameExpression);\r\n\r\n if (matches) {\r\n const match = matches[0];\r\n return match;\r\n }\r\n\r\n throw new Error(`Could not locate filename from path: ${inputPath}`);\r\n}\r\n\r\nexport function mapPath(inputPath: string, pathMap: PathMap): string {\r\n\r\n for (const { path, output } of pathMap) {\r\n if (typeof path === 'string') {\r\n if (inputPath.includes(path)) {\r\n return output;\r\n }\r\n } else {\r\n const match = inputPath.match(path);\r\n if (match) {\r\n return output.replace('[match]', match[0]);;\r\n }\r\n }\r\n }\r\n return inputPath;\r\n}\r\n\r\nexport function pathInMap(inputPath: string, pathMap?: PathMap): boolean {\r\n if (!pathMap) return false;\r\n for (const { path, output } of pathMap) {\r\n if (typeof path === 'string') {\r\n if (inputPath.includes(path)) {\r\n return true;\r\n }\r\n } else {\r\n const match = inputPath.match(path);\r\n if (match) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n\r\nexport function pathRelativeToBase(basePath: string, relativeToBase: string, pathMap?: PathMap) {\r\n if (pathInMap(relativeToBase, pathMap) && pathMap) {\r\n return mapPath(relativeToBase, pathMap);\r\n }\r\n\r\n // Use absolute path if specified\r\n if (relativeToBase.indexOf('/') === 0) {\r\n return relativeToBase;\r\n }\r\n\r\n const originSplit = basePath.split('/');\r\n const relativeSplit = relativeToBase.split('/');\r\n // if origin path is a file, remove it so it's a directory\r\n if (originSplit[originSplit.length - 1].includes('.')) {\r\n originSplit.pop();\r\n }\r\n return originSplit.concat(relativeSplit).join('/');\r\n}","import { TileMap, Vector, vec } from \"excalibur\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\nimport { LdtkLayerInstance } from \"./types\";\r\nimport { Level } from \"./level\";\r\n\r\n\r\nexport class TileLayer {\r\n public ldtkLayer: LdtkLayerInstance;\r\n public worldPos: Vector;\r\n public offset: Vector;\r\n public tilemap: TileMap;\r\n constructor(level: Level, ldtkLayer: LdtkLayerInstance, resource: LdtkResource, public readonly order: number) {\r\n this.worldPos = vec(level.ldtkLevel.worldX, level.ldtkLevel.worldY);\r\n this.offset = vec(ldtkLayer.__pxTotalOffsetX, ldtkLayer.__pxTotalOffsetY);\r\n this.ldtkLayer = ldtkLayer;\r\n this.tilemap = new TileMap({\r\n name: ldtkLayer.__identifier,\r\n pos: this.worldPos.add(this.offset),\r\n tileWidth: ldtkLayer.__gridSize,\r\n tileHeight: ldtkLayer.__gridSize,\r\n rows: ldtkLayer.__cHei,\r\n columns: ldtkLayer.__cWid,\r\n });\r\n this.tilemap.z = order;\r\n\r\n for (let tile of ldtkLayer.gridTiles) {\r\n const xCoord = Math.floor(tile.px[0] / ldtkLayer.__gridSize);\r\n const yCoord = Math.floor(tile.px[1] / ldtkLayer.__gridSize);\r\n const exTile = this.tilemap.getTile(xCoord, yCoord);\r\n if (ldtkLayer.__tilesetDefUid) {\r\n const ts = resource.tilesets.get(ldtkLayer.__tilesetDefUid);\r\n if (ts) {\r\n const tsxCoord = Math.floor(tile.src[0] / ts.ldtkTileset.tileGridSize);\r\n const tsyCoord = Math.floor(tile.src[1] / ts.ldtkTileset.tileGridSize);\r\n const sprite = ts.spritesheet.getSprite(tsxCoord, tsyCoord);\r\n if (sprite) {\r\n exTile.addGraphic(sprite);\r\n } else {\r\n console.error('Could not find sprite in LDtk spritesheet at', tsxCoord, tsyCoord);\r\n }\r\n }\r\n } else {\r\n console.error('Could not tileset in LDtk', ldtkLayer.__tilesetDefUid, ldtkLayer.__tilesetRelPath);\r\n }\r\n }\r\n }\r\n}","import { ImageSource, SpriteSheet } from \"excalibur\";\r\nimport { LdtkTilesetDefinition } from \"./types\";\r\n\r\nexport interface TilesetOptions {\r\n image: ImageSource,\r\n ldtkTileset: LdtkTilesetDefinition\r\n}\r\n\r\nexport class Tileset {\r\n public readonly image: ImageSource;\r\n public readonly ldtkTileset: LdtkTilesetDefinition;\r\n public readonly spritesheet: SpriteSheet;\r\n constructor(options: TilesetOptions) {\r\n const {image, ldtkTileset} = options;\r\n this.image = image;\r\n this.ldtkTileset = ldtkTileset;\r\n this.spritesheet = SpriteSheet.fromImageSource({\r\n image,\r\n grid: {\r\n rows: ldtkTileset.pxHei / ldtkTileset.tileGridSize,\r\n columns: ldtkTileset.pxWid / ldtkTileset.tileGridSize,\r\n spriteHeight: ldtkTileset.tileGridSize,\r\n spriteWidth: ldtkTileset.tileGridSize\r\n }\r\n });\r\n }\r\n}","import { z } from 'zod';\r\n\r\n\r\n\r\nconst LdtkTilesetRectangle = z.object({\r\n h: z.number(),\r\n tilesetUid: z.number(),\r\n w: z.number(),\r\n x: z.number(),\r\n y: z.number()\r\n});\r\nconst LdtkPixel = z.tuple([z.number(), z.number()]);\r\nconst LdtkFieldInstance = z.object({\r\n __identifier: z.string(),\r\n __tile: LdtkTilesetRectangle.nullable(),\r\n __type: z.string(),//z.union([z.literal('Int'), z.literal('Float'), z.literal('String'), z.literal('Bool'), z.literal('Enum')]), // TODO this might not work with ENUM\r\n __value: z.any(),\r\n defUid: z.number()\r\n})\r\nconst LdtkTileInstance = z.object({\r\n a: z.number(),\r\n f: z.number(), // 2-bit int 0bXY flip\r\n px: LdtkPixel,\r\n src: LdtkPixel,\r\n t: z.number()\r\n});\r\n\r\nexport const LdtkEntityInstance = z.object({\r\n __grid: LdtkPixel,\r\n __identifier: z.string(),\r\n __pivot: LdtkPixel,\r\n __smartColor: z.string(),\r\n __tags: z.array(z.string()),\r\n __tile: LdtkTilesetRectangle.nullable(),\r\n __worldX: z.number().nullable(),\r\n __worldY: z.number().nullable(),\r\n defUid: z.number(),\r\n fieldInstances: z.array(LdtkFieldInstance),\r\n height: z.number(),\r\n iid: z.string(),\r\n px: LdtkPixel,\r\n width: z.number()\r\n});\r\nexport type LdtkEntityInstance = z.infer;\r\n\r\nexport const LdtkLayerInstance = z.object({\r\n __cHei: z.number(),\r\n __cWid: z.number(),\r\n __gridSize: z.number(),\r\n __identifier: z.string(),\r\n __opacity: z.number(),\r\n __pxTotalOffsetX: z.number(),\r\n __pxTotalOffsetY: z.number(),\r\n __tilesetDefUid: z.number().nullable(),\r\n __tilesetRelPath:z.string().nullable(),\r\n __type: z.union([z.literal('IntGrid'), z.literal('Entities'), z.literal('Tiles'), z.literal('AutoLayer')]),\r\n autoLayerTiles: z.array(LdtkTileInstance), // only in auto layers\r\n entityInstances: z.array(LdtkEntityInstance),// only in entity layers\r\n gridTiles: z.array(LdtkTileInstance),\r\n iid: z.string(),\r\n intGridCsv: z.array(z.number()), // __cWid x __cHei, 0 means empty, values start at 1\r\n layerDefUid: z.number(),\r\n levelId: z.number(),\r\n overrideTilesetUid: z.number().nullable(),\r\n pxOffsetX: z.number(),\r\n pxOffsetY: z.number(),\r\n visible: z.boolean()\r\n});\r\nexport type LdtkLayerInstance = z.infer;\r\n\r\nexport const LdtkLevel = z.object({\r\n __bgColor: z.string().nullable(),\r\n bgColor: z.string().nullable(),\r\n __bgPos: z.object({\r\n cropRect: z.array(z.tuple([z.number(), z.number(), z.number(), z.number()])), // cropX, cropY, cropWidth, cropHeight\r\n scale: z.tuple([z.number(), z.number()]),\r\n topLeftPx: LdtkPixel\r\n }).nullable(),\r\n __neighbours: z.array(z.object({\r\n dir: z.union([z.literal('n'), z.literal('s'), z.literal('w'), z.literal('e'), z.literal('ne'), z.literal('nw'), z.literal('se'), z.literal('sw'), z.literal('o'), z.literal('<'), z.literal('>')]),\r\n levelIid: z.string()\r\n })),\r\n bgRelPath: z.string().nullable(),\r\n externalRelPath: z.string().nullable(),\r\n fieldInstances: z.array(LdtkFieldInstance),\r\n identifier: z.string(),\r\n iid: z.string(),\r\n layerInstances: z.array(LdtkLayerInstance).nullable(), // null if the save levels separately is enabled\r\n pxHei: z.number(),\r\n pxWid: z.number(),\r\n uid: z.number(),\r\n worldDepth: z.number(),\r\n worldX: z.number(),\r\n worldY: z.number()\r\n});\r\nexport type LdtkLevel = z.infer;\r\n\r\nconst LdtkWorld = z.object({\r\n identifier: z.string(),\r\n iid: z.string(),\r\n levels: z.array(LdtkLevel),\r\n worldGridHeight:z.number(),\r\n worldGridWidth: z.number(),\r\n // TODO is this a typo Vania?\r\n worldLayout: z.union([z.literal('Free'), z.literal('GridVania'), z.literal('LinearHorizontal'), z.literal('LinearVertical')]),\r\n});\r\nexport type LdtkWorld = z.infer;\r\n\r\nconst LdtkEnumValueDefinition = z.object({\r\n color: z.number(),\r\n id: z.string(),\r\n tileRect: LdtkTilesetRectangle.nullable()\r\n});\r\n\r\nconst LdtkEnumDefinition = z.object({\r\n externalRelPath: z.string().nullable(),\r\n iconTilesetUid: z.number().nullable(),\r\n identifier: z.string(),\r\n tags: z.array(z.string()),\r\n uid: z.number(),\r\n values: z.array(LdtkEnumValueDefinition)\r\n})\r\n\r\nexport type LdtkEnumDefinition = z.infer;\r\n\r\nconst LdtkTilesetDefinition = z.object({\r\n __cHei: z.number(),\r\n __cWid: z.number(),\r\n customData: z.array(z.object({\r\n data: z.string(),\r\n tileId: z.number()\r\n })),\r\n embedAtlas: z.string().nullable(),\r\n enumsTags: z.optional(z.array(z.object({\r\n enumValueId: z.string(),\r\n tileIds: z.array(z.number())\r\n }))),\r\n identifier: z.string(),\r\n padding: z.number(),\r\n pxHei: z.number(),\r\n pxWid: z.number(),\r\n relPath: z.string().nullable(),\r\n spacing: z.number(),\r\n tags: z.array(z.string()),\r\n tagsSourceEnumUid: z.number().nullable(),\r\n tileGridSize: z.number(),\r\n uid: z.number()\r\n})\r\nexport type LdtkTilesetDefinition = z.infer;\r\n\r\nexport const LdtkLayerDefinition = z.object({\r\n __type: z.union([z.literal(\"IntGrid\"), z.literal(\"Entities\"), z.literal(\"Tiles\"), z.literal(\"AutoLayer\")]),\r\n autoSourceLayerDefUid: z.number().nullable(),\r\n displayOpacity: z.number(),\r\n gridSize: z.number(),\r\n identifier: z.string(),\r\n intGridValues: z.array(z.object({\r\n color: z.string(),\r\n groupUid: z.number(),\r\n identifier: z.string().nullable(),\r\n tile: LdtkTilesetRectangle.nullable(),\r\n value: z.number()\r\n })),\r\n intGridValuesGroups: z.array(z.object({\r\n color: z.string().nullable(),\r\n identifier: z.string().nullable(),\r\n uid: z.number()\r\n })),\r\n parallaxFactorX: z.number(),\r\n parallaxFactorY: z.number(),\r\n parallaxScaling: z.boolean(),\r\n pxOffsetX: z.number(),\r\n pxOffsetY: z.number(),\r\n tilesetDefUid: z.number().nullable(),\r\n uid: z.number(),\r\n});\r\nexport type LdtkLayerDefinition = z.infer;\r\n\r\nexport const LdtkEntityDefinition = z.object({\r\n color: z.string(),\r\n height: z.number(),\r\n identifier: z.string(),\r\n nineSliceBorders: z.array(z.number()),\r\n pivotX: z.number(),\r\n pivotY: z.number(),\r\n tileRect: LdtkTilesetRectangle.nullable(),\r\n tileRenderMode: z.union([\r\n z.literal(\"Cover\"),\r\n z.literal(\"FitInside\"),\r\n z.literal(\"Repeat\"),\r\n z.literal(\"Stretch\"),\r\n z.literal(\"FullSizeCropped\"),\r\n z.literal(\"FullSizeUncropped\"),\r\n z.literal(\"NineSlice\")\r\n ]),\r\n tilesetId: z.number().nullable(),\r\n uiTileRect: LdtkTilesetRectangle.nullable(),\r\n uid: z.number(),\r\n width: z.number()\r\n});\r\nexport type LdtkEntityDefinition = z.infer;\r\n\r\nconst LdtkDefinitions = z.object({\r\n tilesets: z.array(LdtkTilesetDefinition),\r\n enums: z.array(LdtkEnumDefinition),\r\n layers: z.array(LdtkLayerDefinition),\r\n entities: z.array(LdtkEntityDefinition)\r\n})\r\nexport type LdtkDefinitions = z.infer;\r\n\r\nexport const LdtkProjectMetadata = z.object({\r\n iid: z.string(),\r\n bgColor: z.string().nullable(),\r\n defs: LdtkDefinitions,\r\n externalLevels: z.boolean(),\r\n jsonVersion: z.string(),\r\n levels: z.array(LdtkLevel),\r\n toc: z.array(z.object({\r\n identifier: z.string(),\r\n instancesData: z.array(z.object({\r\n fields: z.any(),\r\n heiPx: z.number(),\r\n iids: z.string(),\r\n widPix: z.number(),\r\n worldX: z.number(),\r\n worldY: z.number()\r\n }))\r\n })),\r\n // Moving to worlds array\r\n worldGridHeight: z.number().nullable(),\r\n worldGridWidth: z.number().nullable(),\r\n // TODO is this a LDtk docs typo Vania?\r\n worldLayout: z.union([z.literal('Free'), z.literal('GridVania'), z.literal('LinearHorizontal'), z.literal('LinearVertical')]).nullable(),\r\n worlds: z.array(LdtkWorld)\r\n});\r\nexport type LdtkProjectMetadata = z.infer;\r\n\r\n\r\n\r\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ZodError = exports.quotelessJson = exports.ZodIssueCode = void 0;\nconst util_1 = require(\"./helpers/util\");\nexports.ZodIssueCode = util_1.util.arrayToEnum([\n \"invalid_type\",\n \"invalid_literal\",\n \"custom\",\n \"invalid_union\",\n \"invalid_union_discriminator\",\n \"invalid_enum_value\",\n \"unrecognized_keys\",\n \"invalid_arguments\",\n \"invalid_return_type\",\n \"invalid_date\",\n \"invalid_string\",\n \"too_small\",\n \"too_big\",\n \"invalid_intersection_types\",\n \"not_multiple_of\",\n \"not_finite\",\n]);\nconst quotelessJson = (obj) => {\n const json = JSON.stringify(obj, null, 2);\n return json.replace(/\"([^\"]+)\":/g, \"$1:\");\n};\nexports.quotelessJson = quotelessJson;\nclass ZodError extends Error {\n constructor(issues) {\n super();\n this.issues = [];\n this.addIssue = (sub) => {\n this.issues = [...this.issues, sub];\n };\n this.addIssues = (subs = []) => {\n this.issues = [...this.issues, ...subs];\n };\n const actualProto = new.target.prototype;\n if (Object.setPrototypeOf) {\n // eslint-disable-next-line ban/ban\n Object.setPrototypeOf(this, actualProto);\n }\n else {\n this.__proto__ = actualProto;\n }\n this.name = \"ZodError\";\n this.issues = issues;\n }\n get errors() {\n return this.issues;\n }\n format(_mapper) {\n const mapper = _mapper ||\n function (issue) {\n return issue.message;\n };\n const fieldErrors = { _errors: [] };\n const processError = (error) => {\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\") {\n issue.unionErrors.map(processError);\n }\n else if (issue.code === \"invalid_return_type\") {\n processError(issue.returnTypeError);\n }\n else if (issue.code === \"invalid_arguments\") {\n processError(issue.argumentsError);\n }\n else if (issue.path.length === 0) {\n fieldErrors._errors.push(mapper(issue));\n }\n else {\n let curr = fieldErrors;\n let i = 0;\n while (i < issue.path.length) {\n const el = issue.path[i];\n const terminal = i === issue.path.length - 1;\n if (!terminal) {\n curr[el] = curr[el] || { _errors: [] };\n // if (typeof el === \"string\") {\n // curr[el] = curr[el] || { _errors: [] };\n // } else if (typeof el === \"number\") {\n // const errorArray: any = [];\n // errorArray._errors = [];\n // curr[el] = curr[el] || errorArray;\n // }\n }\n else {\n curr[el] = curr[el] || { _errors: [] };\n curr[el]._errors.push(mapper(issue));\n }\n curr = curr[el];\n i++;\n }\n }\n }\n };\n processError(this);\n return fieldErrors;\n }\n toString() {\n return this.message;\n }\n get message() {\n return JSON.stringify(this.issues, util_1.util.jsonStringifyReplacer, 2);\n }\n get isEmpty() {\n return this.issues.length === 0;\n }\n flatten(mapper = (issue) => issue.message) {\n const fieldErrors = {};\n const formErrors = [];\n for (const sub of this.issues) {\n if (sub.path.length > 0) {\n fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];\n fieldErrors[sub.path[0]].push(mapper(sub));\n }\n else {\n formErrors.push(mapper(sub));\n }\n }\n return { formErrors, fieldErrors };\n }\n get formErrors() {\n return this.flatten();\n }\n}\nexports.ZodError = ZodError;\nZodError.create = (issues) => {\n const error = new ZodError(issues);\n return error;\n};\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getErrorMap = exports.setErrorMap = exports.defaultErrorMap = void 0;\nconst en_1 = __importDefault(require(\"./locales/en\"));\nexports.defaultErrorMap = en_1.default;\nlet overrideErrorMap = en_1.default;\nfunction setErrorMap(map) {\n overrideErrorMap = map;\n}\nexports.setErrorMap = setErrorMap;\nfunction getErrorMap() {\n return overrideErrorMap;\n}\nexports.getErrorMap = getErrorMap;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./errors\"), exports);\n__exportStar(require(\"./helpers/parseUtil\"), exports);\n__exportStar(require(\"./helpers/typeAliases\"), exports);\n__exportStar(require(\"./helpers/util\"), exports);\n__exportStar(require(\"./types\"), exports);\n__exportStar(require(\"./ZodError\"), exports);\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.errorUtil = void 0;\nvar errorUtil;\n(function (errorUtil) {\n errorUtil.errToObj = (message) => typeof message === \"string\" ? { message } : message || {};\n errorUtil.toString = (message) => typeof message === \"string\" ? message : message === null || message === void 0 ? void 0 : message.message;\n})(errorUtil = exports.errorUtil || (exports.errorUtil = {}));\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isAsync = exports.isValid = exports.isDirty = exports.isAborted = exports.OK = exports.DIRTY = exports.INVALID = exports.ParseStatus = exports.addIssueToContext = exports.EMPTY_PATH = exports.makeIssue = void 0;\nconst errors_1 = require(\"../errors\");\nconst en_1 = __importDefault(require(\"../locales/en\"));\nconst makeIssue = (params) => {\n const { data, path, errorMaps, issueData } = params;\n const fullPath = [...path, ...(issueData.path || [])];\n const fullIssue = {\n ...issueData,\n path: fullPath,\n };\n let errorMessage = \"\";\n const maps = errorMaps\n .filter((m) => !!m)\n .slice()\n .reverse();\n for (const map of maps) {\n errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;\n }\n return {\n ...issueData,\n path: fullPath,\n message: issueData.message || errorMessage,\n };\n};\nexports.makeIssue = makeIssue;\nexports.EMPTY_PATH = [];\nfunction addIssueToContext(ctx, issueData) {\n const issue = (0, exports.makeIssue)({\n issueData: issueData,\n data: ctx.data,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n (0, errors_1.getErrorMap)(),\n en_1.default, // then global default map\n ].filter((x) => !!x),\n });\n ctx.common.issues.push(issue);\n}\nexports.addIssueToContext = addIssueToContext;\nclass ParseStatus {\n constructor() {\n this.value = \"valid\";\n }\n dirty() {\n if (this.value === \"valid\")\n this.value = \"dirty\";\n }\n abort() {\n if (this.value !== \"aborted\")\n this.value = \"aborted\";\n }\n static mergeArray(status, results) {\n const arrayValue = [];\n for (const s of results) {\n if (s.status === \"aborted\")\n return exports.INVALID;\n if (s.status === \"dirty\")\n status.dirty();\n arrayValue.push(s.value);\n }\n return { status: status.value, value: arrayValue };\n }\n static async mergeObjectAsync(status, pairs) {\n const syncPairs = [];\n for (const pair of pairs) {\n syncPairs.push({\n key: await pair.key,\n value: await pair.value,\n });\n }\n return ParseStatus.mergeObjectSync(status, syncPairs);\n }\n static mergeObjectSync(status, pairs) {\n const finalObject = {};\n for (const pair of pairs) {\n const { key, value } = pair;\n if (key.status === \"aborted\")\n return exports.INVALID;\n if (value.status === \"aborted\")\n return exports.INVALID;\n if (key.status === \"dirty\")\n status.dirty();\n if (value.status === \"dirty\")\n status.dirty();\n if (key.value !== \"__proto__\" &&\n (typeof value.value !== \"undefined\" || pair.alwaysSet)) {\n finalObject[key.value] = value.value;\n }\n }\n return { status: status.value, value: finalObject };\n }\n}\nexports.ParseStatus = ParseStatus;\nexports.INVALID = Object.freeze({\n status: \"aborted\",\n});\nconst DIRTY = (value) => ({ status: \"dirty\", value });\nexports.DIRTY = DIRTY;\nconst OK = (value) => ({ status: \"valid\", value });\nexports.OK = OK;\nconst isAborted = (x) => x.status === \"aborted\";\nexports.isAborted = isAborted;\nconst isDirty = (x) => x.status === \"dirty\";\nexports.isDirty = isDirty;\nconst isValid = (x) => x.status === \"valid\";\nexports.isValid = isValid;\nconst isAsync = (x) => typeof Promise !== \"undefined\" && x instanceof Promise;\nexports.isAsync = isAsync;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getParsedType = exports.ZodParsedType = exports.objectUtil = exports.util = void 0;\nvar util;\n(function (util) {\n util.assertEqual = (val) => val;\n function assertIs(_arg) { }\n util.assertIs = assertIs;\n function assertNever(_x) {\n throw new Error();\n }\n util.assertNever = assertNever;\n util.arrayToEnum = (items) => {\n const obj = {};\n for (const item of items) {\n obj[item] = item;\n }\n return obj;\n };\n util.getValidEnumValues = (obj) => {\n const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== \"number\");\n const filtered = {};\n for (const k of validKeys) {\n filtered[k] = obj[k];\n }\n return util.objectValues(filtered);\n };\n util.objectValues = (obj) => {\n return util.objectKeys(obj).map(function (e) {\n return obj[e];\n });\n };\n util.objectKeys = typeof Object.keys === \"function\" // eslint-disable-line ban/ban\n ? (obj) => Object.keys(obj) // eslint-disable-line ban/ban\n : (object) => {\n const keys = [];\n for (const key in object) {\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n keys.push(key);\n }\n }\n return keys;\n };\n util.find = (arr, checker) => {\n for (const item of arr) {\n if (checker(item))\n return item;\n }\n return undefined;\n };\n util.isInteger = typeof Number.isInteger === \"function\"\n ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban\n : (val) => typeof val === \"number\" && isFinite(val) && Math.floor(val) === val;\n function joinValues(array, separator = \" | \") {\n return array\n .map((val) => (typeof val === \"string\" ? `'${val}'` : val))\n .join(separator);\n }\n util.joinValues = joinValues;\n util.jsonStringifyReplacer = (_, value) => {\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n return value;\n };\n})(util = exports.util || (exports.util = {}));\nvar objectUtil;\n(function (objectUtil) {\n objectUtil.mergeShapes = (first, second) => {\n return {\n ...first,\n ...second, // second overwrites first\n };\n };\n})(objectUtil = exports.objectUtil || (exports.objectUtil = {}));\nexports.ZodParsedType = util.arrayToEnum([\n \"string\",\n \"nan\",\n \"number\",\n \"integer\",\n \"float\",\n \"boolean\",\n \"date\",\n \"bigint\",\n \"symbol\",\n \"function\",\n \"undefined\",\n \"null\",\n \"array\",\n \"object\",\n \"unknown\",\n \"promise\",\n \"void\",\n \"never\",\n \"map\",\n \"set\",\n]);\nconst getParsedType = (data) => {\n const t = typeof data;\n switch (t) {\n case \"undefined\":\n return exports.ZodParsedType.undefined;\n case \"string\":\n return exports.ZodParsedType.string;\n case \"number\":\n return isNaN(data) ? exports.ZodParsedType.nan : exports.ZodParsedType.number;\n case \"boolean\":\n return exports.ZodParsedType.boolean;\n case \"function\":\n return exports.ZodParsedType.function;\n case \"bigint\":\n return exports.ZodParsedType.bigint;\n case \"symbol\":\n return exports.ZodParsedType.symbol;\n case \"object\":\n if (Array.isArray(data)) {\n return exports.ZodParsedType.array;\n }\n if (data === null) {\n return exports.ZodParsedType.null;\n }\n if (data.then &&\n typeof data.then === \"function\" &&\n data.catch &&\n typeof data.catch === \"function\") {\n return exports.ZodParsedType.promise;\n }\n if (typeof Map !== \"undefined\" && data instanceof Map) {\n return exports.ZodParsedType.map;\n }\n if (typeof Set !== \"undefined\" && data instanceof Set) {\n return exports.ZodParsedType.set;\n }\n if (typeof Date !== \"undefined\" && data instanceof Date) {\n return exports.ZodParsedType.date;\n }\n return exports.ZodParsedType.object;\n default:\n return exports.ZodParsedType.unknown;\n }\n};\nexports.getParsedType = getParsedType;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.z = void 0;\nconst z = __importStar(require(\"./external\"));\nexports.z = z;\n__exportStar(require(\"./external\"), exports);\nexports.default = z;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst util_1 = require(\"../helpers/util\");\nconst ZodError_1 = require(\"../ZodError\");\nconst errorMap = (issue, _ctx) => {\n let message;\n switch (issue.code) {\n case ZodError_1.ZodIssueCode.invalid_type:\n if (issue.received === util_1.ZodParsedType.undefined) {\n message = \"Required\";\n }\n else {\n message = `Expected ${issue.expected}, received ${issue.received}`;\n }\n break;\n case ZodError_1.ZodIssueCode.invalid_literal:\n message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util_1.util.jsonStringifyReplacer)}`;\n break;\n case ZodError_1.ZodIssueCode.unrecognized_keys:\n message = `Unrecognized key(s) in object: ${util_1.util.joinValues(issue.keys, \", \")}`;\n break;\n case ZodError_1.ZodIssueCode.invalid_union:\n message = `Invalid input`;\n break;\n case ZodError_1.ZodIssueCode.invalid_union_discriminator:\n message = `Invalid discriminator value. Expected ${util_1.util.joinValues(issue.options)}`;\n break;\n case ZodError_1.ZodIssueCode.invalid_enum_value:\n message = `Invalid enum value. Expected ${util_1.util.joinValues(issue.options)}, received '${issue.received}'`;\n break;\n case ZodError_1.ZodIssueCode.invalid_arguments:\n message = `Invalid function arguments`;\n break;\n case ZodError_1.ZodIssueCode.invalid_return_type:\n message = `Invalid function return type`;\n break;\n case ZodError_1.ZodIssueCode.invalid_date:\n message = `Invalid date`;\n break;\n case ZodError_1.ZodIssueCode.invalid_string:\n if (typeof issue.validation === \"object\") {\n if (\"includes\" in issue.validation) {\n message = `Invalid input: must include \"${issue.validation.includes}\"`;\n if (typeof issue.validation.position === \"number\") {\n message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;\n }\n }\n else if (\"startsWith\" in issue.validation) {\n message = `Invalid input: must start with \"${issue.validation.startsWith}\"`;\n }\n else if (\"endsWith\" in issue.validation) {\n message = `Invalid input: must end with \"${issue.validation.endsWith}\"`;\n }\n else {\n util_1.util.assertNever(issue.validation);\n }\n }\n else if (issue.validation !== \"regex\") {\n message = `Invalid ${issue.validation}`;\n }\n else {\n message = \"Invalid\";\n }\n break;\n case ZodError_1.ZodIssueCode.too_small:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact\n ? `exactly equal to `\n : issue.inclusive\n ? `greater than or equal to `\n : `greater than `}${issue.minimum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact\n ? `exactly equal to `\n : issue.inclusive\n ? `greater than or equal to `\n : `greater than `}${new Date(Number(issue.minimum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodError_1.ZodIssueCode.too_big:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `less than or equal to`\n : `less than`} ${issue.maximum}`;\n else if (issue.type === \"bigint\")\n message = `BigInt must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `less than or equal to`\n : `less than`} ${issue.maximum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `smaller than or equal to`\n : `smaller than`} ${new Date(Number(issue.maximum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodError_1.ZodIssueCode.custom:\n message = `Invalid input`;\n break;\n case ZodError_1.ZodIssueCode.invalid_intersection_types:\n message = `Intersection results could not be merged`;\n break;\n case ZodError_1.ZodIssueCode.not_multiple_of:\n message = `Number must be a multiple of ${issue.multipleOf}`;\n break;\n case ZodError_1.ZodIssueCode.not_finite:\n message = \"Number must be finite\";\n break;\n default:\n message = _ctx.defaultError;\n util_1.util.assertNever(issue);\n }\n return { message };\n};\nexports.default = errorMap;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.date = exports.boolean = exports.bigint = exports.array = exports.any = exports.coerce = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.custom = exports.ZodReadonly = exports.ZodPipeline = exports.ZodBranded = exports.BRAND = exports.ZodNaN = exports.ZodCatch = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodSymbol = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.ZodType = void 0;\nexports.NEVER = exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.symbol = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.pipeline = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = exports.intersection = exports.instanceof = exports.function = exports.enum = exports.effect = exports.discriminatedUnion = void 0;\nconst errors_1 = require(\"./errors\");\nconst errorUtil_1 = require(\"./helpers/errorUtil\");\nconst parseUtil_1 = require(\"./helpers/parseUtil\");\nconst util_1 = require(\"./helpers/util\");\nconst ZodError_1 = require(\"./ZodError\");\nclass ParseInputLazyPath {\n constructor(parent, value, path, key) {\n this._cachedPath = [];\n this.parent = parent;\n this.data = value;\n this._path = path;\n this._key = key;\n }\n get path() {\n if (!this._cachedPath.length) {\n if (this._key instanceof Array) {\n this._cachedPath.push(...this._path, ...this._key);\n }\n else {\n this._cachedPath.push(...this._path, this._key);\n }\n }\n return this._cachedPath;\n }\n}\nconst handleResult = (ctx, result) => {\n if ((0, parseUtil_1.isValid)(result)) {\n return { success: true, data: result.value };\n }\n else {\n if (!ctx.common.issues.length) {\n throw new Error(\"Validation failed but no issues detected.\");\n }\n return {\n success: false,\n get error() {\n if (this._error)\n return this._error;\n const error = new ZodError_1.ZodError(ctx.common.issues);\n this._error = error;\n return this._error;\n },\n };\n }\n};\nfunction processCreateParams(params) {\n if (!params)\n return {};\n const { errorMap, invalid_type_error, required_error, description } = params;\n if (errorMap && (invalid_type_error || required_error)) {\n throw new Error(`Can't use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.`);\n }\n if (errorMap)\n return { errorMap: errorMap, description };\n const customMap = (iss, ctx) => {\n if (iss.code !== \"invalid_type\")\n return { message: ctx.defaultError };\n if (typeof ctx.data === \"undefined\") {\n return { message: required_error !== null && required_error !== void 0 ? required_error : ctx.defaultError };\n }\n return { message: invalid_type_error !== null && invalid_type_error !== void 0 ? invalid_type_error : ctx.defaultError };\n };\n return { errorMap: customMap, description };\n}\nclass ZodType {\n constructor(def) {\n /** Alias of safeParseAsync */\n this.spa = this.safeParseAsync;\n this._def = def;\n this.parse = this.parse.bind(this);\n this.safeParse = this.safeParse.bind(this);\n this.parseAsync = this.parseAsync.bind(this);\n this.safeParseAsync = this.safeParseAsync.bind(this);\n this.spa = this.spa.bind(this);\n this.refine = this.refine.bind(this);\n this.refinement = this.refinement.bind(this);\n this.superRefine = this.superRefine.bind(this);\n this.optional = this.optional.bind(this);\n this.nullable = this.nullable.bind(this);\n this.nullish = this.nullish.bind(this);\n this.array = this.array.bind(this);\n this.promise = this.promise.bind(this);\n this.or = this.or.bind(this);\n this.and = this.and.bind(this);\n this.transform = this.transform.bind(this);\n this.brand = this.brand.bind(this);\n this.default = this.default.bind(this);\n this.catch = this.catch.bind(this);\n this.describe = this.describe.bind(this);\n this.pipe = this.pipe.bind(this);\n this.readonly = this.readonly.bind(this);\n this.isNullable = this.isNullable.bind(this);\n this.isOptional = this.isOptional.bind(this);\n }\n get description() {\n return this._def.description;\n }\n _getType(input) {\n return (0, util_1.getParsedType)(input.data);\n }\n _getOrReturnCtx(input, ctx) {\n return (ctx || {\n common: input.parent.common,\n data: input.data,\n parsedType: (0, util_1.getParsedType)(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n });\n }\n _processInputParams(input) {\n return {\n status: new parseUtil_1.ParseStatus(),\n ctx: {\n common: input.parent.common,\n data: input.data,\n parsedType: (0, util_1.getParsedType)(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n },\n };\n }\n _parseSync(input) {\n const result = this._parse(input);\n if ((0, parseUtil_1.isAsync)(result)) {\n throw new Error(\"Synchronous parse encountered promise.\");\n }\n return result;\n }\n _parseAsync(input) {\n const result = this._parse(input);\n return Promise.resolve(result);\n }\n parse(data, params) {\n const result = this.safeParse(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n safeParse(data, params) {\n var _a;\n const ctx = {\n common: {\n issues: [],\n async: (_a = params === null || params === void 0 ? void 0 : params.async) !== null && _a !== void 0 ? _a : false,\n contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,\n },\n path: (params === null || params === void 0 ? void 0 : params.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: (0, util_1.getParsedType)(data),\n };\n const result = this._parseSync({ data, path: ctx.path, parent: ctx });\n return handleResult(ctx, result);\n }\n async parseAsync(data, params) {\n const result = await this.safeParseAsync(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n async safeParseAsync(data, params) {\n const ctx = {\n common: {\n issues: [],\n contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,\n async: true,\n },\n path: (params === null || params === void 0 ? void 0 : params.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: (0, util_1.getParsedType)(data),\n };\n const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });\n const result = await ((0, parseUtil_1.isAsync)(maybeAsyncResult)\n ? maybeAsyncResult\n : Promise.resolve(maybeAsyncResult));\n return handleResult(ctx, result);\n }\n refine(check, message) {\n const getIssueProperties = (val) => {\n if (typeof message === \"string\" || typeof message === \"undefined\") {\n return { message };\n }\n else if (typeof message === \"function\") {\n return message(val);\n }\n else {\n return message;\n }\n };\n return this._refinement((val, ctx) => {\n const result = check(val);\n const setError = () => ctx.addIssue({\n code: ZodError_1.ZodIssueCode.custom,\n ...getIssueProperties(val),\n });\n if (typeof Promise !== \"undefined\" && result instanceof Promise) {\n return result.then((data) => {\n if (!data) {\n setError();\n return false;\n }\n else {\n return true;\n }\n });\n }\n if (!result) {\n setError();\n return false;\n }\n else {\n return true;\n }\n });\n }\n refinement(check, refinementData) {\n return this._refinement((val, ctx) => {\n if (!check(val)) {\n ctx.addIssue(typeof refinementData === \"function\"\n ? refinementData(val, ctx)\n : refinementData);\n return false;\n }\n else {\n return true;\n }\n });\n }\n _refinement(refinement) {\n return new ZodEffects({\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: \"refinement\", refinement },\n });\n }\n superRefine(refinement) {\n return this._refinement(refinement);\n }\n optional() {\n return ZodOptional.create(this, this._def);\n }\n nullable() {\n return ZodNullable.create(this, this._def);\n }\n nullish() {\n return this.nullable().optional();\n }\n array() {\n return ZodArray.create(this, this._def);\n }\n promise() {\n return ZodPromise.create(this, this._def);\n }\n or(option) {\n return ZodUnion.create([this, option], this._def);\n }\n and(incoming) {\n return ZodIntersection.create(this, incoming, this._def);\n }\n transform(transform) {\n return new ZodEffects({\n ...processCreateParams(this._def),\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: \"transform\", transform },\n });\n }\n default(def) {\n const defaultValueFunc = typeof def === \"function\" ? def : () => def;\n return new ZodDefault({\n ...processCreateParams(this._def),\n innerType: this,\n defaultValue: defaultValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n });\n }\n brand() {\n return new ZodBranded({\n typeName: ZodFirstPartyTypeKind.ZodBranded,\n type: this,\n ...processCreateParams(this._def),\n });\n }\n catch(def) {\n const catchValueFunc = typeof def === \"function\" ? def : () => def;\n return new ZodCatch({\n ...processCreateParams(this._def),\n innerType: this,\n catchValue: catchValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n });\n }\n describe(description) {\n const This = this.constructor;\n return new This({\n ...this._def,\n description,\n });\n }\n pipe(target) {\n return ZodPipeline.create(this, target);\n }\n readonly() {\n return ZodReadonly.create(this);\n }\n isOptional() {\n return this.safeParse(undefined).success;\n }\n isNullable() {\n return this.safeParse(null).success;\n }\n}\nexports.ZodType = ZodType;\nexports.Schema = ZodType;\nexports.ZodSchema = ZodType;\nconst cuidRegex = /^c[^\\s-]{8,}$/i;\nconst cuid2Regex = /^[a-z][a-z0-9]*$/;\nconst ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/;\n// const uuidRegex =\n// /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i;\nconst uuidRegex = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i;\n// from https://stackoverflow.com/a/46181/1550155\n// old version: too slow, didn't support unicode\n// const emailRegex = /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i;\n//old email regex\n// const emailRegex = /^(([^<>()[\\].,;:\\s@\"]+(\\.[^<>()[\\].,;:\\s@\"]+)*)|(\".+\"))@((?!-)([^<>()[\\].,;:\\s@\"]+\\.)+[^<>()[\\].,;:\\s@\"]{1,})[^-<>()[\\].,;:\\s@\"]$/i;\n// eslint-disable-next-line\n// const emailRegex =\n// /^(([^<>()[\\]\\\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@((\\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\])|(\\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\\.[A-Za-z]{2,})+))$/;\n// const emailRegex =\n// /^[a-zA-Z0-9\\.\\!\\#\\$\\%\\&\\'\\*\\+\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~\\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n// const emailRegex =\n// /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$/i;\nconst emailRegex = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_+-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\n// const emailRegex =\n// /^[a-z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\\.[a-z0-9\\-]+)*$/i;\n// from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression\nconst _emojiRegex = `^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$`;\nlet emojiRegex;\nconst ipv4Regex = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/;\nconst ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;\n// Adapted from https://stackoverflow.com/a/3143231\nconst datetimeRegex = (args) => {\n if (args.precision) {\n if (args.offset) {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{${args.precision}}(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$`);\n }\n else {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{${args.precision}}Z$`);\n }\n }\n else if (args.precision === 0) {\n if (args.offset) {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$`);\n }\n else {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}Z$`);\n }\n }\n else {\n if (args.offset) {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$`);\n }\n else {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?Z$`);\n }\n }\n};\nfunction isValidIP(ip, version) {\n if ((version === \"v4\" || !version) && ipv4Regex.test(ip)) {\n return true;\n }\n if ((version === \"v6\" || !version) && ipv6Regex.test(ip)) {\n return true;\n }\n return false;\n}\nclass ZodString extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = String(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.string) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.string,\n received: ctx.parsedType,\n }\n //\n );\n return parseUtil_1.INVALID;\n }\n const status = new parseUtil_1.ParseStatus();\n let ctx = undefined;\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n if (input.data.length < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: check.value,\n type: \"string\",\n inclusive: true,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n if (input.data.length > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: check.value,\n type: \"string\",\n inclusive: true,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"length\") {\n const tooBig = input.data.length > check.value;\n const tooSmall = input.data.length < check.value;\n if (tooBig || tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n if (tooBig) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: check.value,\n type: \"string\",\n inclusive: true,\n exact: true,\n message: check.message,\n });\n }\n else if (tooSmall) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: check.value,\n type: \"string\",\n inclusive: true,\n exact: true,\n message: check.message,\n });\n }\n status.dirty();\n }\n }\n else if (check.kind === \"email\") {\n if (!emailRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"email\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"emoji\") {\n if (!emojiRegex) {\n emojiRegex = new RegExp(_emojiRegex, \"u\");\n }\n if (!emojiRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"emoji\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"uuid\") {\n if (!uuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"uuid\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cuid\") {\n if (!cuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"cuid\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cuid2\") {\n if (!cuid2Regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"cuid2\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"ulid\") {\n if (!ulidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"ulid\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"url\") {\n try {\n new URL(input.data);\n }\n catch (_a) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"url\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"regex\") {\n check.regex.lastIndex = 0;\n const testResult = check.regex.test(input.data);\n if (!testResult) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"regex\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"trim\") {\n input.data = input.data.trim();\n }\n else if (check.kind === \"includes\") {\n if (!input.data.includes(check.value, check.position)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_string,\n validation: { includes: check.value, position: check.position },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"toLowerCase\") {\n input.data = input.data.toLowerCase();\n }\n else if (check.kind === \"toUpperCase\") {\n input.data = input.data.toUpperCase();\n }\n else if (check.kind === \"startsWith\") {\n if (!input.data.startsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_string,\n validation: { startsWith: check.value },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"endsWith\") {\n if (!input.data.endsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_string,\n validation: { endsWith: check.value },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"datetime\") {\n const regex = datetimeRegex(check);\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_string,\n validation: \"datetime\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"ip\") {\n if (!isValidIP(input.data, check.version)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"ip\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util_1.util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n _regex(regex, validation, message) {\n return this.refinement((data) => regex.test(data), {\n validation,\n code: ZodError_1.ZodIssueCode.invalid_string,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n _addCheck(check) {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n email(message) {\n return this._addCheck({ kind: \"email\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n url(message) {\n return this._addCheck({ kind: \"url\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n emoji(message) {\n return this._addCheck({ kind: \"emoji\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n uuid(message) {\n return this._addCheck({ kind: \"uuid\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n cuid(message) {\n return this._addCheck({ kind: \"cuid\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n cuid2(message) {\n return this._addCheck({ kind: \"cuid2\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n ulid(message) {\n return this._addCheck({ kind: \"ulid\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n ip(options) {\n return this._addCheck({ kind: \"ip\", ...errorUtil_1.errorUtil.errToObj(options) });\n }\n datetime(options) {\n var _a;\n if (typeof options === \"string\") {\n return this._addCheck({\n kind: \"datetime\",\n precision: null,\n offset: false,\n message: options,\n });\n }\n return this._addCheck({\n kind: \"datetime\",\n precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === \"undefined\" ? null : options === null || options === void 0 ? void 0 : options.precision,\n offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false,\n ...errorUtil_1.errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),\n });\n }\n regex(regex, message) {\n return this._addCheck({\n kind: \"regex\",\n regex: regex,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n includes(value, options) {\n return this._addCheck({\n kind: \"includes\",\n value: value,\n position: options === null || options === void 0 ? void 0 : options.position,\n ...errorUtil_1.errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),\n });\n }\n startsWith(value, message) {\n return this._addCheck({\n kind: \"startsWith\",\n value: value,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n endsWith(value, message) {\n return this._addCheck({\n kind: \"endsWith\",\n value: value,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n min(minLength, message) {\n return this._addCheck({\n kind: \"min\",\n value: minLength,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n max(maxLength, message) {\n return this._addCheck({\n kind: \"max\",\n value: maxLength,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n length(len, message) {\n return this._addCheck({\n kind: \"length\",\n value: len,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n /**\n * @deprecated Use z.string().min(1) instead.\n * @see {@link ZodString.min}\n */\n nonempty(message) {\n return this.min(1, errorUtil_1.errorUtil.errToObj(message));\n }\n trim() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"trim\" }],\n });\n }\n toLowerCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"toLowerCase\" }],\n });\n }\n toUpperCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"toUpperCase\" }],\n });\n }\n get isDatetime() {\n return !!this._def.checks.find((ch) => ch.kind === \"datetime\");\n }\n get isEmail() {\n return !!this._def.checks.find((ch) => ch.kind === \"email\");\n }\n get isURL() {\n return !!this._def.checks.find((ch) => ch.kind === \"url\");\n }\n get isEmoji() {\n return !!this._def.checks.find((ch) => ch.kind === \"emoji\");\n }\n get isUUID() {\n return !!this._def.checks.find((ch) => ch.kind === \"uuid\");\n }\n get isCUID() {\n return !!this._def.checks.find((ch) => ch.kind === \"cuid\");\n }\n get isCUID2() {\n return !!this._def.checks.find((ch) => ch.kind === \"cuid2\");\n }\n get isULID() {\n return !!this._def.checks.find((ch) => ch.kind === \"ulid\");\n }\n get isIP() {\n return !!this._def.checks.find((ch) => ch.kind === \"ip\");\n }\n get minLength() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxLength() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n}\nexports.ZodString = ZodString;\nZodString.create = (params) => {\n var _a;\n return new ZodString({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodString,\n coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,\n ...processCreateParams(params),\n });\n};\n// https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034\nfunction floatSafeRemainder(val, step) {\n const valDecCount = (val.toString().split(\".\")[1] || \"\").length;\n const stepDecCount = (step.toString().split(\".\")[1] || \"\").length;\n const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;\n const valInt = parseInt(val.toFixed(decCount).replace(\".\", \"\"));\n const stepInt = parseInt(step.toFixed(decCount).replace(\".\", \"\"));\n return (valInt % stepInt) / Math.pow(10, decCount);\n}\nclass ZodNumber extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n this.step = this.multipleOf;\n }\n _parse(input) {\n if (this._def.coerce) {\n input.data = Number(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.number) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.number,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n let ctx = undefined;\n const status = new parseUtil_1.ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === \"int\") {\n if (!util_1.util.isInteger(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: \"integer\",\n received: \"float\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"min\") {\n const tooSmall = check.inclusive\n ? input.data < check.value\n : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: check.value,\n type: \"number\",\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n const tooBig = check.inclusive\n ? input.data > check.value\n : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: check.value,\n type: \"number\",\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"multipleOf\") {\n if (floatSafeRemainder(input.data, check.value) !== 0) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"finite\") {\n if (!Number.isFinite(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.not_finite,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util_1.util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n gte(value, message) {\n return this.setLimit(\"min\", value, true, errorUtil_1.errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit(\"min\", value, false, errorUtil_1.errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit(\"max\", value, true, errorUtil_1.errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit(\"max\", value, false, errorUtil_1.errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodNumber({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil_1.errorUtil.toString(message),\n },\n ],\n });\n }\n _addCheck(check) {\n return new ZodNumber({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n int(message) {\n return this._addCheck({\n kind: \"int\",\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n positive(message) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: false,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n negative(message) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: false,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: true,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: true,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: \"multipleOf\",\n value: value,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n finite(message) {\n return this._addCheck({\n kind: \"finite\",\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n safe(message) {\n return this._addCheck({\n kind: \"min\",\n inclusive: true,\n value: Number.MIN_SAFE_INTEGER,\n message: errorUtil_1.errorUtil.toString(message),\n })._addCheck({\n kind: \"max\",\n inclusive: true,\n value: Number.MAX_SAFE_INTEGER,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n get isInt() {\n return !!this._def.checks.find((ch) => ch.kind === \"int\" ||\n (ch.kind === \"multipleOf\" && util_1.util.isInteger(ch.value)));\n }\n get isFinite() {\n let max = null, min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"finite\" ||\n ch.kind === \"int\" ||\n ch.kind === \"multipleOf\") {\n return true;\n }\n else if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n else if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return Number.isFinite(min) && Number.isFinite(max);\n }\n}\nexports.ZodNumber = ZodNumber;\nZodNumber.create = (params) => {\n return new ZodNumber({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodNumber,\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n ...processCreateParams(params),\n });\n};\nclass ZodBigInt extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n }\n _parse(input) {\n if (this._def.coerce) {\n input.data = BigInt(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.bigint) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.bigint,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n let ctx = undefined;\n const status = new parseUtil_1.ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n const tooSmall = check.inclusive\n ? input.data < check.value\n : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n type: \"bigint\",\n minimum: check.value,\n inclusive: check.inclusive,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n const tooBig = check.inclusive\n ? input.data > check.value\n : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n type: \"bigint\",\n maximum: check.value,\n inclusive: check.inclusive,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"multipleOf\") {\n if (input.data % check.value !== BigInt(0)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util_1.util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n gte(value, message) {\n return this.setLimit(\"min\", value, true, errorUtil_1.errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit(\"min\", value, false, errorUtil_1.errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit(\"max\", value, true, errorUtil_1.errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit(\"max\", value, false, errorUtil_1.errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodBigInt({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil_1.errorUtil.toString(message),\n },\n ],\n });\n }\n _addCheck(check) {\n return new ZodBigInt({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n positive(message) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n negative(message) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: \"multipleOf\",\n value,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n}\nexports.ZodBigInt = ZodBigInt;\nZodBigInt.create = (params) => {\n var _a;\n return new ZodBigInt({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodBigInt,\n coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,\n ...processCreateParams(params),\n });\n};\nclass ZodBoolean extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = Boolean(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.boolean) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.boolean,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodBoolean = ZodBoolean;\nZodBoolean.create = (params) => {\n return new ZodBoolean({\n typeName: ZodFirstPartyTypeKind.ZodBoolean,\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n ...processCreateParams(params),\n });\n};\nclass ZodDate extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = new Date(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.date) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.date,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n if (isNaN(input.data.getTime())) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_date,\n });\n return parseUtil_1.INVALID;\n }\n const status = new parseUtil_1.ParseStatus();\n let ctx = undefined;\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n if (input.data.getTime() < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n message: check.message,\n inclusive: true,\n exact: false,\n minimum: check.value,\n type: \"date\",\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n if (input.data.getTime() > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n message: check.message,\n inclusive: true,\n exact: false,\n maximum: check.value,\n type: \"date\",\n });\n status.dirty();\n }\n }\n else {\n util_1.util.assertNever(check);\n }\n }\n return {\n status: status.value,\n value: new Date(input.data.getTime()),\n };\n }\n _addCheck(check) {\n return new ZodDate({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n min(minDate, message) {\n return this._addCheck({\n kind: \"min\",\n value: minDate.getTime(),\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n max(maxDate, message) {\n return this._addCheck({\n kind: \"max\",\n value: maxDate.getTime(),\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n get minDate() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min != null ? new Date(min) : null;\n }\n get maxDate() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max != null ? new Date(max) : null;\n }\n}\nexports.ZodDate = ZodDate;\nZodDate.create = (params) => {\n return new ZodDate({\n checks: [],\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n typeName: ZodFirstPartyTypeKind.ZodDate,\n ...processCreateParams(params),\n });\n};\nclass ZodSymbol extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.symbol) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.symbol,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodSymbol = ZodSymbol;\nZodSymbol.create = (params) => {\n return new ZodSymbol({\n typeName: ZodFirstPartyTypeKind.ZodSymbol,\n ...processCreateParams(params),\n });\n};\nclass ZodUndefined extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.undefined,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodUndefined = ZodUndefined;\nZodUndefined.create = (params) => {\n return new ZodUndefined({\n typeName: ZodFirstPartyTypeKind.ZodUndefined,\n ...processCreateParams(params),\n });\n};\nclass ZodNull extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.null) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.null,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodNull = ZodNull;\nZodNull.create = (params) => {\n return new ZodNull({\n typeName: ZodFirstPartyTypeKind.ZodNull,\n ...processCreateParams(params),\n });\n};\nclass ZodAny extends ZodType {\n constructor() {\n super(...arguments);\n // to prevent instances of other classes from extending ZodAny. this causes issues with catchall in ZodObject.\n this._any = true;\n }\n _parse(input) {\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodAny = ZodAny;\nZodAny.create = (params) => {\n return new ZodAny({\n typeName: ZodFirstPartyTypeKind.ZodAny,\n ...processCreateParams(params),\n });\n};\nclass ZodUnknown extends ZodType {\n constructor() {\n super(...arguments);\n // required\n this._unknown = true;\n }\n _parse(input) {\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodUnknown = ZodUnknown;\nZodUnknown.create = (params) => {\n return new ZodUnknown({\n typeName: ZodFirstPartyTypeKind.ZodUnknown,\n ...processCreateParams(params),\n });\n};\nclass ZodNever extends ZodType {\n _parse(input) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.never,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n}\nexports.ZodNever = ZodNever;\nZodNever.create = (params) => {\n return new ZodNever({\n typeName: ZodFirstPartyTypeKind.ZodNever,\n ...processCreateParams(params),\n });\n};\nclass ZodVoid extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.void,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodVoid = ZodVoid;\nZodVoid.create = (params) => {\n return new ZodVoid({\n typeName: ZodFirstPartyTypeKind.ZodVoid,\n ...processCreateParams(params),\n });\n};\nclass ZodArray extends ZodType {\n _parse(input) {\n const { ctx, status } = this._processInputParams(input);\n const def = this._def;\n if (ctx.parsedType !== util_1.ZodParsedType.array) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.array,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n if (def.exactLength !== null) {\n const tooBig = ctx.data.length > def.exactLength.value;\n const tooSmall = ctx.data.length < def.exactLength.value;\n if (tooBig || tooSmall) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: tooBig ? ZodError_1.ZodIssueCode.too_big : ZodError_1.ZodIssueCode.too_small,\n minimum: (tooSmall ? def.exactLength.value : undefined),\n maximum: (tooBig ? def.exactLength.value : undefined),\n type: \"array\",\n inclusive: true,\n exact: true,\n message: def.exactLength.message,\n });\n status.dirty();\n }\n }\n if (def.minLength !== null) {\n if (ctx.data.length < def.minLength.value) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: def.minLength.value,\n type: \"array\",\n inclusive: true,\n exact: false,\n message: def.minLength.message,\n });\n status.dirty();\n }\n }\n if (def.maxLength !== null) {\n if (ctx.data.length > def.maxLength.value) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: def.maxLength.value,\n type: \"array\",\n inclusive: true,\n exact: false,\n message: def.maxLength.message,\n });\n status.dirty();\n }\n }\n if (ctx.common.async) {\n return Promise.all([...ctx.data].map((item, i) => {\n return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));\n })).then((result) => {\n return parseUtil_1.ParseStatus.mergeArray(status, result);\n });\n }\n const result = [...ctx.data].map((item, i) => {\n return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));\n });\n return parseUtil_1.ParseStatus.mergeArray(status, result);\n }\n get element() {\n return this._def.type;\n }\n min(minLength, message) {\n return new ZodArray({\n ...this._def,\n minLength: { value: minLength, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n max(maxLength, message) {\n return new ZodArray({\n ...this._def,\n maxLength: { value: maxLength, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n length(len, message) {\n return new ZodArray({\n ...this._def,\n exactLength: { value: len, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n nonempty(message) {\n return this.min(1, message);\n }\n}\nexports.ZodArray = ZodArray;\nZodArray.create = (schema, params) => {\n return new ZodArray({\n type: schema,\n minLength: null,\n maxLength: null,\n exactLength: null,\n typeName: ZodFirstPartyTypeKind.ZodArray,\n ...processCreateParams(params),\n });\n};\nfunction deepPartialify(schema) {\n if (schema instanceof ZodObject) {\n const newShape = {};\n for (const key in schema.shape) {\n const fieldSchema = schema.shape[key];\n newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));\n }\n return new ZodObject({\n ...schema._def,\n shape: () => newShape,\n });\n }\n else if (schema instanceof ZodArray) {\n return new ZodArray({\n ...schema._def,\n type: deepPartialify(schema.element),\n });\n }\n else if (schema instanceof ZodOptional) {\n return ZodOptional.create(deepPartialify(schema.unwrap()));\n }\n else if (schema instanceof ZodNullable) {\n return ZodNullable.create(deepPartialify(schema.unwrap()));\n }\n else if (schema instanceof ZodTuple) {\n return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));\n }\n else {\n return schema;\n }\n}\nclass ZodObject extends ZodType {\n constructor() {\n super(...arguments);\n this._cached = null;\n /**\n * @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped.\n * If you want to pass through unknown properties, use `.passthrough()` instead.\n */\n this.nonstrict = this.passthrough;\n // extend<\n // Augmentation extends ZodRawShape,\n // NewOutput extends util.flatten<{\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k][\"_output\"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // }>,\n // NewInput extends util.flatten<{\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k][\"_input\"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }>\n // >(\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape,\n // UnknownKeys,\n // Catchall,\n // NewOutput,\n // NewInput\n // > {\n // return new ZodObject({\n // ...this._def,\n // shape: () => ({\n // ...this._def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // }\n /**\n * @deprecated Use `.extend` instead\n * */\n this.augment = this.extend;\n }\n _getCached() {\n if (this._cached !== null)\n return this._cached;\n const shape = this._def.shape();\n const keys = util_1.util.objectKeys(shape);\n return (this._cached = { shape, keys });\n }\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.object) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.object,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const { status, ctx } = this._processInputParams(input);\n const { shape, keys: shapeKeys } = this._getCached();\n const extraKeys = [];\n if (!(this._def.catchall instanceof ZodNever &&\n this._def.unknownKeys === \"strip\")) {\n for (const key in ctx.data) {\n if (!shapeKeys.includes(key)) {\n extraKeys.push(key);\n }\n }\n }\n const pairs = [];\n for (const key of shapeKeys) {\n const keyValidator = shape[key];\n const value = ctx.data[key];\n pairs.push({\n key: { status: \"valid\", value: key },\n value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),\n alwaysSet: key in ctx.data,\n });\n }\n if (this._def.catchall instanceof ZodNever) {\n const unknownKeys = this._def.unknownKeys;\n if (unknownKeys === \"passthrough\") {\n for (const key of extraKeys) {\n pairs.push({\n key: { status: \"valid\", value: key },\n value: { status: \"valid\", value: ctx.data[key] },\n });\n }\n }\n else if (unknownKeys === \"strict\") {\n if (extraKeys.length > 0) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.unrecognized_keys,\n keys: extraKeys,\n });\n status.dirty();\n }\n }\n else if (unknownKeys === \"strip\") {\n }\n else {\n throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);\n }\n }\n else {\n // run catchall validation\n const catchall = this._def.catchall;\n for (const key of extraKeys) {\n const value = ctx.data[key];\n pairs.push({\n key: { status: \"valid\", value: key },\n value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value)\n ),\n alwaysSet: key in ctx.data,\n });\n }\n }\n if (ctx.common.async) {\n return Promise.resolve()\n .then(async () => {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n syncPairs.push({\n key,\n value: await pair.value,\n alwaysSet: pair.alwaysSet,\n });\n }\n return syncPairs;\n })\n .then((syncPairs) => {\n return parseUtil_1.ParseStatus.mergeObjectSync(status, syncPairs);\n });\n }\n else {\n return parseUtil_1.ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get shape() {\n return this._def.shape();\n }\n strict(message) {\n errorUtil_1.errorUtil.errToObj;\n return new ZodObject({\n ...this._def,\n unknownKeys: \"strict\",\n ...(message !== undefined\n ? {\n errorMap: (issue, ctx) => {\n var _a, _b, _c, _d;\n const defaultError = (_c = (_b = (_a = this._def).errorMap) === null || _b === void 0 ? void 0 : _b.call(_a, issue, ctx).message) !== null && _c !== void 0 ? _c : ctx.defaultError;\n if (issue.code === \"unrecognized_keys\")\n return {\n message: (_d = errorUtil_1.errorUtil.errToObj(message).message) !== null && _d !== void 0 ? _d : defaultError,\n };\n return {\n message: defaultError,\n };\n },\n }\n : {}),\n });\n }\n strip() {\n return new ZodObject({\n ...this._def,\n unknownKeys: \"strip\",\n });\n }\n passthrough() {\n return new ZodObject({\n ...this._def,\n unknownKeys: \"passthrough\",\n });\n }\n // const AugmentFactory =\n // (def: Def) =>\n // (\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape, Augmentation>,\n // Def[\"unknownKeys\"],\n // Def[\"catchall\"]\n // > => {\n // return new ZodObject({\n // ...def,\n // shape: () => ({\n // ...def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // };\n extend(augmentation) {\n return new ZodObject({\n ...this._def,\n shape: () => ({\n ...this._def.shape(),\n ...augmentation,\n }),\n });\n }\n /**\n * Prior to zod@1.0.12 there was a bug in the\n * inferred type of merged objects. Please\n * upgrade if you are experiencing issues.\n */\n merge(merging) {\n const merged = new ZodObject({\n unknownKeys: merging._def.unknownKeys,\n catchall: merging._def.catchall,\n shape: () => ({\n ...this._def.shape(),\n ...merging._def.shape(),\n }),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n });\n return merged;\n }\n // merge<\n // Incoming extends AnyZodObject,\n // Augmentation extends Incoming[\"shape\"],\n // NewOutput extends {\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k][\"_output\"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // },\n // NewInput extends {\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k][\"_input\"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }\n // >(\n // merging: Incoming\n // ): ZodObject<\n // extendShape>,\n // Incoming[\"_def\"][\"unknownKeys\"],\n // Incoming[\"_def\"][\"catchall\"],\n // NewOutput,\n // NewInput\n // > {\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n setKey(key, schema) {\n return this.augment({ [key]: schema });\n }\n // merge(\n // merging: Incoming\n // ): //ZodObject = (merging) => {\n // ZodObject<\n // extendShape>,\n // Incoming[\"_def\"][\"unknownKeys\"],\n // Incoming[\"_def\"][\"catchall\"]\n // > {\n // // const mergedShape = objectUtil.mergeShapes(\n // // this._def.shape(),\n // // merging._def.shape()\n // // );\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n catchall(index) {\n return new ZodObject({\n ...this._def,\n catchall: index,\n });\n }\n pick(mask) {\n const shape = {};\n util_1.util.objectKeys(mask).forEach((key) => {\n if (mask[key] && this.shape[key]) {\n shape[key] = this.shape[key];\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => shape,\n });\n }\n omit(mask) {\n const shape = {};\n util_1.util.objectKeys(this.shape).forEach((key) => {\n if (!mask[key]) {\n shape[key] = this.shape[key];\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => shape,\n });\n }\n /**\n * @deprecated\n */\n deepPartial() {\n return deepPartialify(this);\n }\n partial(mask) {\n const newShape = {};\n util_1.util.objectKeys(this.shape).forEach((key) => {\n const fieldSchema = this.shape[key];\n if (mask && !mask[key]) {\n newShape[key] = fieldSchema;\n }\n else {\n newShape[key] = fieldSchema.optional();\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => newShape,\n });\n }\n required(mask) {\n const newShape = {};\n util_1.util.objectKeys(this.shape).forEach((key) => {\n if (mask && !mask[key]) {\n newShape[key] = this.shape[key];\n }\n else {\n const fieldSchema = this.shape[key];\n let newField = fieldSchema;\n while (newField instanceof ZodOptional) {\n newField = newField._def.innerType;\n }\n newShape[key] = newField;\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => newShape,\n });\n }\n keyof() {\n return createZodEnum(util_1.util.objectKeys(this.shape));\n }\n}\nexports.ZodObject = ZodObject;\nZodObject.create = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: \"strip\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nZodObject.strictCreate = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: \"strict\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nZodObject.lazycreate = (shape, params) => {\n return new ZodObject({\n shape,\n unknownKeys: \"strip\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nclass ZodUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const options = this._def.options;\n function handleResults(results) {\n // return first issue-free validation if it exists\n for (const result of results) {\n if (result.result.status === \"valid\") {\n return result.result;\n }\n }\n for (const result of results) {\n if (result.result.status === \"dirty\") {\n // add issues from dirty option\n ctx.common.issues.push(...result.ctx.common.issues);\n return result.result;\n }\n }\n // return invalid\n const unionErrors = results.map((result) => new ZodError_1.ZodError(result.ctx.common.issues));\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_union,\n unionErrors,\n });\n return parseUtil_1.INVALID;\n }\n if (ctx.common.async) {\n return Promise.all(options.map(async (option) => {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n parent: null,\n };\n return {\n result: await option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx,\n }),\n ctx: childCtx,\n };\n })).then(handleResults);\n }\n else {\n let dirty = undefined;\n const issues = [];\n for (const option of options) {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n parent: null,\n };\n const result = option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx,\n });\n if (result.status === \"valid\") {\n return result;\n }\n else if (result.status === \"dirty\" && !dirty) {\n dirty = { result, ctx: childCtx };\n }\n if (childCtx.common.issues.length) {\n issues.push(childCtx.common.issues);\n }\n }\n if (dirty) {\n ctx.common.issues.push(...dirty.ctx.common.issues);\n return dirty.result;\n }\n const unionErrors = issues.map((issues) => new ZodError_1.ZodError(issues));\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_union,\n unionErrors,\n });\n return parseUtil_1.INVALID;\n }\n }\n get options() {\n return this._def.options;\n }\n}\nexports.ZodUnion = ZodUnion;\nZodUnion.create = (types, params) => {\n return new ZodUnion({\n options: types,\n typeName: ZodFirstPartyTypeKind.ZodUnion,\n ...processCreateParams(params),\n });\n};\n/////////////////////////////////////////////////////\n/////////////////////////////////////////////////////\n////////// //////////\n////////// ZodDiscriminatedUnion //////////\n////////// //////////\n/////////////////////////////////////////////////////\n/////////////////////////////////////////////////////\nconst getDiscriminator = (type) => {\n if (type instanceof ZodLazy) {\n return getDiscriminator(type.schema);\n }\n else if (type instanceof ZodEffects) {\n return getDiscriminator(type.innerType());\n }\n else if (type instanceof ZodLiteral) {\n return [type.value];\n }\n else if (type instanceof ZodEnum) {\n return type.options;\n }\n else if (type instanceof ZodNativeEnum) {\n // eslint-disable-next-line ban/ban\n return Object.keys(type.enum);\n }\n else if (type instanceof ZodDefault) {\n return getDiscriminator(type._def.innerType);\n }\n else if (type instanceof ZodUndefined) {\n return [undefined];\n }\n else if (type instanceof ZodNull) {\n return [null];\n }\n else {\n return null;\n }\n};\nclass ZodDiscriminatedUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.object) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.object,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const discriminator = this.discriminator;\n const discriminatorValue = ctx.data[discriminator];\n const option = this.optionsMap.get(discriminatorValue);\n if (!option) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_union_discriminator,\n options: Array.from(this.optionsMap.keys()),\n path: [discriminator],\n });\n return parseUtil_1.INVALID;\n }\n if (ctx.common.async) {\n return option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n }\n else {\n return option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n get discriminator() {\n return this._def.discriminator;\n }\n get options() {\n return this._def.options;\n }\n get optionsMap() {\n return this._def.optionsMap;\n }\n /**\n * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.\n * However, it only allows a union of objects, all of which need to share a discriminator property. This property must\n * have a different value for each object in the union.\n * @param discriminator the name of the discriminator property\n * @param types an array of object schemas\n * @param params\n */\n static create(discriminator, options, params) {\n // Get all the valid discriminator values\n const optionsMap = new Map();\n // try {\n for (const type of options) {\n const discriminatorValues = getDiscriminator(type.shape[discriminator]);\n if (!discriminatorValues) {\n throw new Error(`A discriminator value for key \\`${discriminator}\\` could not be extracted from all schema options`);\n }\n for (const value of discriminatorValues) {\n if (optionsMap.has(value)) {\n throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);\n }\n optionsMap.set(value, type);\n }\n }\n return new ZodDiscriminatedUnion({\n typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,\n discriminator,\n options,\n optionsMap,\n ...processCreateParams(params),\n });\n }\n}\nexports.ZodDiscriminatedUnion = ZodDiscriminatedUnion;\nfunction mergeValues(a, b) {\n const aType = (0, util_1.getParsedType)(a);\n const bType = (0, util_1.getParsedType)(b);\n if (a === b) {\n return { valid: true, data: a };\n }\n else if (aType === util_1.ZodParsedType.object && bType === util_1.ZodParsedType.object) {\n const bKeys = util_1.util.objectKeys(b);\n const sharedKeys = util_1.util\n .objectKeys(a)\n .filter((key) => bKeys.indexOf(key) !== -1);\n const newObj = { ...a, ...b };\n for (const key of sharedKeys) {\n const sharedValue = mergeValues(a[key], b[key]);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newObj[key] = sharedValue.data;\n }\n return { valid: true, data: newObj };\n }\n else if (aType === util_1.ZodParsedType.array && bType === util_1.ZodParsedType.array) {\n if (a.length !== b.length) {\n return { valid: false };\n }\n const newArray = [];\n for (let index = 0; index < a.length; index++) {\n const itemA = a[index];\n const itemB = b[index];\n const sharedValue = mergeValues(itemA, itemB);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newArray.push(sharedValue.data);\n }\n return { valid: true, data: newArray };\n }\n else if (aType === util_1.ZodParsedType.date &&\n bType === util_1.ZodParsedType.date &&\n +a === +b) {\n return { valid: true, data: a };\n }\n else {\n return { valid: false };\n }\n}\nclass ZodIntersection extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const handleParsed = (parsedLeft, parsedRight) => {\n if ((0, parseUtil_1.isAborted)(parsedLeft) || (0, parseUtil_1.isAborted)(parsedRight)) {\n return parseUtil_1.INVALID;\n }\n const merged = mergeValues(parsedLeft.value, parsedRight.value);\n if (!merged.valid) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_intersection_types,\n });\n return parseUtil_1.INVALID;\n }\n if ((0, parseUtil_1.isDirty)(parsedLeft) || (0, parseUtil_1.isDirty)(parsedRight)) {\n status.dirty();\n }\n return { status: status.value, value: merged.data };\n };\n if (ctx.common.async) {\n return Promise.all([\n this._def.left._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }),\n this._def.right._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }),\n ]).then(([left, right]) => handleParsed(left, right));\n }\n else {\n return handleParsed(this._def.left._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }), this._def.right._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }));\n }\n }\n}\nexports.ZodIntersection = ZodIntersection;\nZodIntersection.create = (left, right, params) => {\n return new ZodIntersection({\n left: left,\n right: right,\n typeName: ZodFirstPartyTypeKind.ZodIntersection,\n ...processCreateParams(params),\n });\n};\nclass ZodTuple extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.array) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.array,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n if (ctx.data.length < this._def.items.length) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: \"array\",\n });\n return parseUtil_1.INVALID;\n }\n const rest = this._def.rest;\n if (!rest && ctx.data.length > this._def.items.length) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: \"array\",\n });\n status.dirty();\n }\n const items = [...ctx.data]\n .map((item, itemIndex) => {\n const schema = this._def.items[itemIndex] || this._def.rest;\n if (!schema)\n return null;\n return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));\n })\n .filter((x) => !!x); // filter nulls\n if (ctx.common.async) {\n return Promise.all(items).then((results) => {\n return parseUtil_1.ParseStatus.mergeArray(status, results);\n });\n }\n else {\n return parseUtil_1.ParseStatus.mergeArray(status, items);\n }\n }\n get items() {\n return this._def.items;\n }\n rest(rest) {\n return new ZodTuple({\n ...this._def,\n rest,\n });\n }\n}\nexports.ZodTuple = ZodTuple;\nZodTuple.create = (schemas, params) => {\n if (!Array.isArray(schemas)) {\n throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");\n }\n return new ZodTuple({\n items: schemas,\n typeName: ZodFirstPartyTypeKind.ZodTuple,\n rest: null,\n ...processCreateParams(params),\n });\n};\nclass ZodRecord extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.object) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.object,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const pairs = [];\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n for (const key in ctx.data) {\n pairs.push({\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),\n value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),\n });\n }\n if (ctx.common.async) {\n return parseUtil_1.ParseStatus.mergeObjectAsync(status, pairs);\n }\n else {\n return parseUtil_1.ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get element() {\n return this._def.valueType;\n }\n static create(first, second, third) {\n if (second instanceof ZodType) {\n return new ZodRecord({\n keyType: first,\n valueType: second,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(third),\n });\n }\n return new ZodRecord({\n keyType: ZodString.create(),\n valueType: first,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(second),\n });\n }\n}\nexports.ZodRecord = ZodRecord;\nclass ZodMap extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.map) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.map,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n const pairs = [...ctx.data.entries()].map(([key, value], index) => {\n return {\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, \"key\"])),\n value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, \"value\"])),\n };\n });\n if (ctx.common.async) {\n const finalMap = new Map();\n return Promise.resolve().then(async () => {\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n if (key.status === \"aborted\" || value.status === \"aborted\") {\n return parseUtil_1.INVALID;\n }\n if (key.status === \"dirty\" || value.status === \"dirty\") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n });\n }\n else {\n const finalMap = new Map();\n for (const pair of pairs) {\n const key = pair.key;\n const value = pair.value;\n if (key.status === \"aborted\" || value.status === \"aborted\") {\n return parseUtil_1.INVALID;\n }\n if (key.status === \"dirty\" || value.status === \"dirty\") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n }\n }\n}\nexports.ZodMap = ZodMap;\nZodMap.create = (keyType, valueType, params) => {\n return new ZodMap({\n valueType,\n keyType,\n typeName: ZodFirstPartyTypeKind.ZodMap,\n ...processCreateParams(params),\n });\n};\nclass ZodSet extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.set) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.set,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const def = this._def;\n if (def.minSize !== null) {\n if (ctx.data.size < def.minSize.value) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: def.minSize.value,\n type: \"set\",\n inclusive: true,\n exact: false,\n message: def.minSize.message,\n });\n status.dirty();\n }\n }\n if (def.maxSize !== null) {\n if (ctx.data.size > def.maxSize.value) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: def.maxSize.value,\n type: \"set\",\n inclusive: true,\n exact: false,\n message: def.maxSize.message,\n });\n status.dirty();\n }\n }\n const valueType = this._def.valueType;\n function finalizeSet(elements) {\n const parsedSet = new Set();\n for (const element of elements) {\n if (element.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (element.status === \"dirty\")\n status.dirty();\n parsedSet.add(element.value);\n }\n return { status: status.value, value: parsedSet };\n }\n const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));\n if (ctx.common.async) {\n return Promise.all(elements).then((elements) => finalizeSet(elements));\n }\n else {\n return finalizeSet(elements);\n }\n }\n min(minSize, message) {\n return new ZodSet({\n ...this._def,\n minSize: { value: minSize, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n max(maxSize, message) {\n return new ZodSet({\n ...this._def,\n maxSize: { value: maxSize, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n size(size, message) {\n return this.min(size, message).max(size, message);\n }\n nonempty(message) {\n return this.min(1, message);\n }\n}\nexports.ZodSet = ZodSet;\nZodSet.create = (valueType, params) => {\n return new ZodSet({\n valueType,\n minSize: null,\n maxSize: null,\n typeName: ZodFirstPartyTypeKind.ZodSet,\n ...processCreateParams(params),\n });\n};\nclass ZodFunction extends ZodType {\n constructor() {\n super(...arguments);\n this.validate = this.implement;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.function) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.function,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n function makeArgsIssue(args, error) {\n return (0, parseUtil_1.makeIssue)({\n data: args,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n (0, errors_1.getErrorMap)(),\n errors_1.defaultErrorMap,\n ].filter((x) => !!x),\n issueData: {\n code: ZodError_1.ZodIssueCode.invalid_arguments,\n argumentsError: error,\n },\n });\n }\n function makeReturnsIssue(returns, error) {\n return (0, parseUtil_1.makeIssue)({\n data: returns,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n (0, errors_1.getErrorMap)(),\n errors_1.defaultErrorMap,\n ].filter((x) => !!x),\n issueData: {\n code: ZodError_1.ZodIssueCode.invalid_return_type,\n returnTypeError: error,\n },\n });\n }\n const params = { errorMap: ctx.common.contextualErrorMap };\n const fn = ctx.data;\n if (this._def.returns instanceof ZodPromise) {\n // Would love a way to avoid disabling this rule, but we need\n // an alias (using an arrow function was what caused 2651).\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const me = this;\n return (0, parseUtil_1.OK)(async function (...args) {\n const error = new ZodError_1.ZodError([]);\n const parsedArgs = await me._def.args\n .parseAsync(args, params)\n .catch((e) => {\n error.addIssue(makeArgsIssue(args, e));\n throw error;\n });\n const result = await Reflect.apply(fn, this, parsedArgs);\n const parsedReturns = await me._def.returns._def.type\n .parseAsync(result, params)\n .catch((e) => {\n error.addIssue(makeReturnsIssue(result, e));\n throw error;\n });\n return parsedReturns;\n });\n }\n else {\n // Would love a way to avoid disabling this rule, but we need\n // an alias (using an arrow function was what caused 2651).\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const me = this;\n return (0, parseUtil_1.OK)(function (...args) {\n const parsedArgs = me._def.args.safeParse(args, params);\n if (!parsedArgs.success) {\n throw new ZodError_1.ZodError([makeArgsIssue(args, parsedArgs.error)]);\n }\n const result = Reflect.apply(fn, this, parsedArgs.data);\n const parsedReturns = me._def.returns.safeParse(result, params);\n if (!parsedReturns.success) {\n throw new ZodError_1.ZodError([makeReturnsIssue(result, parsedReturns.error)]);\n }\n return parsedReturns.data;\n });\n }\n }\n parameters() {\n return this._def.args;\n }\n returnType() {\n return this._def.returns;\n }\n args(...items) {\n return new ZodFunction({\n ...this._def,\n args: ZodTuple.create(items).rest(ZodUnknown.create()),\n });\n }\n returns(returnType) {\n return new ZodFunction({\n ...this._def,\n returns: returnType,\n });\n }\n implement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n strictImplement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n static create(args, returns, params) {\n return new ZodFunction({\n args: (args\n ? args\n : ZodTuple.create([]).rest(ZodUnknown.create())),\n returns: returns || ZodUnknown.create(),\n typeName: ZodFirstPartyTypeKind.ZodFunction,\n ...processCreateParams(params),\n });\n }\n}\nexports.ZodFunction = ZodFunction;\nclass ZodLazy extends ZodType {\n get schema() {\n return this._def.getter();\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const lazySchema = this._def.getter();\n return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });\n }\n}\nexports.ZodLazy = ZodLazy;\nZodLazy.create = (getter, params) => {\n return new ZodLazy({\n getter: getter,\n typeName: ZodFirstPartyTypeKind.ZodLazy,\n ...processCreateParams(params),\n });\n};\nclass ZodLiteral extends ZodType {\n _parse(input) {\n if (input.data !== this._def.value) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n received: ctx.data,\n code: ZodError_1.ZodIssueCode.invalid_literal,\n expected: this._def.value,\n });\n return parseUtil_1.INVALID;\n }\n return { status: \"valid\", value: input.data };\n }\n get value() {\n return this._def.value;\n }\n}\nexports.ZodLiteral = ZodLiteral;\nZodLiteral.create = (value, params) => {\n return new ZodLiteral({\n value: value,\n typeName: ZodFirstPartyTypeKind.ZodLiteral,\n ...processCreateParams(params),\n });\n};\nfunction createZodEnum(values, params) {\n return new ZodEnum({\n values,\n typeName: ZodFirstPartyTypeKind.ZodEnum,\n ...processCreateParams(params),\n });\n}\nclass ZodEnum extends ZodType {\n _parse(input) {\n if (typeof input.data !== \"string\") {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n (0, parseUtil_1.addIssueToContext)(ctx, {\n expected: util_1.util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodError_1.ZodIssueCode.invalid_type,\n });\n return parseUtil_1.INVALID;\n }\n if (this._def.values.indexOf(input.data) === -1) {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n (0, parseUtil_1.addIssueToContext)(ctx, {\n received: ctx.data,\n code: ZodError_1.ZodIssueCode.invalid_enum_value,\n options: expectedValues,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n get options() {\n return this._def.values;\n }\n get enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Values() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n extract(values) {\n return ZodEnum.create(values);\n }\n exclude(values) {\n return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)));\n }\n}\nexports.ZodEnum = ZodEnum;\nZodEnum.create = createZodEnum;\nclass ZodNativeEnum extends ZodType {\n _parse(input) {\n const nativeEnumValues = util_1.util.getValidEnumValues(this._def.values);\n const ctx = this._getOrReturnCtx(input);\n if (ctx.parsedType !== util_1.ZodParsedType.string &&\n ctx.parsedType !== util_1.ZodParsedType.number) {\n const expectedValues = util_1.util.objectValues(nativeEnumValues);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n expected: util_1.util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodError_1.ZodIssueCode.invalid_type,\n });\n return parseUtil_1.INVALID;\n }\n if (nativeEnumValues.indexOf(input.data) === -1) {\n const expectedValues = util_1.util.objectValues(nativeEnumValues);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n received: ctx.data,\n code: ZodError_1.ZodIssueCode.invalid_enum_value,\n options: expectedValues,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n get enum() {\n return this._def.values;\n }\n}\nexports.ZodNativeEnum = ZodNativeEnum;\nZodNativeEnum.create = (values, params) => {\n return new ZodNativeEnum({\n values: values,\n typeName: ZodFirstPartyTypeKind.ZodNativeEnum,\n ...processCreateParams(params),\n });\n};\nclass ZodPromise extends ZodType {\n unwrap() {\n return this._def.type;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.promise &&\n ctx.common.async === false) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.promise,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const promisified = ctx.parsedType === util_1.ZodParsedType.promise\n ? ctx.data\n : Promise.resolve(ctx.data);\n return (0, parseUtil_1.OK)(promisified.then((data) => {\n return this._def.type.parseAsync(data, {\n path: ctx.path,\n errorMap: ctx.common.contextualErrorMap,\n });\n }));\n }\n}\nexports.ZodPromise = ZodPromise;\nZodPromise.create = (schema, params) => {\n return new ZodPromise({\n type: schema,\n typeName: ZodFirstPartyTypeKind.ZodPromise,\n ...processCreateParams(params),\n });\n};\nclass ZodEffects extends ZodType {\n innerType() {\n return this._def.schema;\n }\n sourceType() {\n return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects\n ? this._def.schema.sourceType()\n : this._def.schema;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const effect = this._def.effect || null;\n const checkCtx = {\n addIssue: (arg) => {\n (0, parseUtil_1.addIssueToContext)(ctx, arg);\n if (arg.fatal) {\n status.abort();\n }\n else {\n status.dirty();\n }\n },\n get path() {\n return ctx.path;\n },\n };\n checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);\n if (effect.type === \"preprocess\") {\n const processed = effect.transform(ctx.data, checkCtx);\n if (ctx.common.issues.length) {\n return {\n status: \"dirty\",\n value: ctx.data,\n };\n }\n if (ctx.common.async) {\n return Promise.resolve(processed).then((processed) => {\n return this._def.schema._parseAsync({\n data: processed,\n path: ctx.path,\n parent: ctx,\n });\n });\n }\n else {\n return this._def.schema._parseSync({\n data: processed,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n if (effect.type === \"refinement\") {\n const executeRefinement = (acc\n // effect: RefinementEffect\n ) => {\n const result = effect.refinement(acc, checkCtx);\n if (ctx.common.async) {\n return Promise.resolve(result);\n }\n if (result instanceof Promise) {\n throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");\n }\n return acc;\n };\n if (ctx.common.async === false) {\n const inner = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inner.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (inner.status === \"dirty\")\n status.dirty();\n // return value is ignored\n executeRefinement(inner.value);\n return { status: status.value, value: inner.value };\n }\n else {\n return this._def.schema\n ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })\n .then((inner) => {\n if (inner.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (inner.status === \"dirty\")\n status.dirty();\n return executeRefinement(inner.value).then(() => {\n return { status: status.value, value: inner.value };\n });\n });\n }\n }\n if (effect.type === \"transform\") {\n if (ctx.common.async === false) {\n const base = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (!(0, parseUtil_1.isValid)(base))\n return base;\n const result = effect.transform(base.value, checkCtx);\n if (result instanceof Promise) {\n throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);\n }\n return { status: status.value, value: result };\n }\n else {\n return this._def.schema\n ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })\n .then((base) => {\n if (!(0, parseUtil_1.isValid)(base))\n return base;\n return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result }));\n });\n }\n }\n util_1.util.assertNever(effect);\n }\n}\nexports.ZodEffects = ZodEffects;\nexports.ZodTransformer = ZodEffects;\nZodEffects.create = (schema, effect, params) => {\n return new ZodEffects({\n schema,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect,\n ...processCreateParams(params),\n });\n};\nZodEffects.createWithPreprocess = (preprocess, schema, params) => {\n return new ZodEffects({\n schema,\n effect: { type: \"preprocess\", transform: preprocess },\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n ...processCreateParams(params),\n });\n};\nclass ZodOptional extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === util_1.ZodParsedType.undefined) {\n return (0, parseUtil_1.OK)(undefined);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nexports.ZodOptional = ZodOptional;\nZodOptional.create = (type, params) => {\n return new ZodOptional({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodOptional,\n ...processCreateParams(params),\n });\n};\nclass ZodNullable extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === util_1.ZodParsedType.null) {\n return (0, parseUtil_1.OK)(null);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nexports.ZodNullable = ZodNullable;\nZodNullable.create = (type, params) => {\n return new ZodNullable({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodNullable,\n ...processCreateParams(params),\n });\n};\nclass ZodDefault extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n let data = ctx.data;\n if (ctx.parsedType === util_1.ZodParsedType.undefined) {\n data = this._def.defaultValue();\n }\n return this._def.innerType._parse({\n data,\n path: ctx.path,\n parent: ctx,\n });\n }\n removeDefault() {\n return this._def.innerType;\n }\n}\nexports.ZodDefault = ZodDefault;\nZodDefault.create = (type, params) => {\n return new ZodDefault({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n defaultValue: typeof params.default === \"function\"\n ? params.default\n : () => params.default,\n ...processCreateParams(params),\n });\n};\nclass ZodCatch extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n // newCtx is used to not collect issues from inner types in ctx\n const newCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n };\n const result = this._def.innerType._parse({\n data: newCtx.data,\n path: newCtx.path,\n parent: {\n ...newCtx,\n },\n });\n if ((0, parseUtil_1.isAsync)(result)) {\n return result.then((result) => {\n return {\n status: \"valid\",\n value: result.status === \"valid\"\n ? result.value\n : this._def.catchValue({\n get error() {\n return new ZodError_1.ZodError(newCtx.common.issues);\n },\n input: newCtx.data,\n }),\n };\n });\n }\n else {\n return {\n status: \"valid\",\n value: result.status === \"valid\"\n ? result.value\n : this._def.catchValue({\n get error() {\n return new ZodError_1.ZodError(newCtx.common.issues);\n },\n input: newCtx.data,\n }),\n };\n }\n }\n removeCatch() {\n return this._def.innerType;\n }\n}\nexports.ZodCatch = ZodCatch;\nZodCatch.create = (type, params) => {\n return new ZodCatch({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n catchValue: typeof params.catch === \"function\" ? params.catch : () => params.catch,\n ...processCreateParams(params),\n });\n};\nclass ZodNaN extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.nan) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.nan,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return { status: \"valid\", value: input.data };\n }\n}\nexports.ZodNaN = ZodNaN;\nZodNaN.create = (params) => {\n return new ZodNaN({\n typeName: ZodFirstPartyTypeKind.ZodNaN,\n ...processCreateParams(params),\n });\n};\nexports.BRAND = Symbol(\"zod_brand\");\nclass ZodBranded extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const data = ctx.data;\n return this._def.type._parse({\n data,\n path: ctx.path,\n parent: ctx,\n });\n }\n unwrap() {\n return this._def.type;\n }\n}\nexports.ZodBranded = ZodBranded;\nclass ZodPipeline extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.common.async) {\n const handleAsync = async () => {\n const inResult = await this._def.in._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inResult.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (inResult.status === \"dirty\") {\n status.dirty();\n return (0, parseUtil_1.DIRTY)(inResult.value);\n }\n else {\n return this._def.out._parseAsync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx,\n });\n }\n };\n return handleAsync();\n }\n else {\n const inResult = this._def.in._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inResult.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (inResult.status === \"dirty\") {\n status.dirty();\n return {\n status: \"dirty\",\n value: inResult.value,\n };\n }\n else {\n return this._def.out._parseSync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n }\n static create(a, b) {\n return new ZodPipeline({\n in: a,\n out: b,\n typeName: ZodFirstPartyTypeKind.ZodPipeline,\n });\n }\n}\nexports.ZodPipeline = ZodPipeline;\nclass ZodReadonly extends ZodType {\n _parse(input) {\n const result = this._def.innerType._parse(input);\n if ((0, parseUtil_1.isValid)(result)) {\n result.value = Object.freeze(result.value);\n }\n return result;\n }\n}\nexports.ZodReadonly = ZodReadonly;\nZodReadonly.create = (type, params) => {\n return new ZodReadonly({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodReadonly,\n ...processCreateParams(params),\n });\n};\nconst custom = (check, params = {}, \n/**\n * @deprecated\n *\n * Pass `fatal` into the params object instead:\n *\n * ```ts\n * z.string().custom((val) => val.length > 5, { fatal: false })\n * ```\n *\n */\nfatal) => {\n if (check)\n return ZodAny.create().superRefine((data, ctx) => {\n var _a, _b;\n if (!check(data)) {\n const p = typeof params === \"function\"\n ? params(data)\n : typeof params === \"string\"\n ? { message: params }\n : params;\n const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;\n const p2 = typeof p === \"string\" ? { message: p } : p;\n ctx.addIssue({ code: \"custom\", ...p2, fatal: _fatal });\n }\n });\n return ZodAny.create();\n};\nexports.custom = custom;\nexports.late = {\n object: ZodObject.lazycreate,\n};\nvar ZodFirstPartyTypeKind;\n(function (ZodFirstPartyTypeKind) {\n ZodFirstPartyTypeKind[\"ZodString\"] = \"ZodString\";\n ZodFirstPartyTypeKind[\"ZodNumber\"] = \"ZodNumber\";\n ZodFirstPartyTypeKind[\"ZodNaN\"] = \"ZodNaN\";\n ZodFirstPartyTypeKind[\"ZodBigInt\"] = \"ZodBigInt\";\n ZodFirstPartyTypeKind[\"ZodBoolean\"] = \"ZodBoolean\";\n ZodFirstPartyTypeKind[\"ZodDate\"] = \"ZodDate\";\n ZodFirstPartyTypeKind[\"ZodSymbol\"] = \"ZodSymbol\";\n ZodFirstPartyTypeKind[\"ZodUndefined\"] = \"ZodUndefined\";\n ZodFirstPartyTypeKind[\"ZodNull\"] = \"ZodNull\";\n ZodFirstPartyTypeKind[\"ZodAny\"] = \"ZodAny\";\n ZodFirstPartyTypeKind[\"ZodUnknown\"] = \"ZodUnknown\";\n ZodFirstPartyTypeKind[\"ZodNever\"] = \"ZodNever\";\n ZodFirstPartyTypeKind[\"ZodVoid\"] = \"ZodVoid\";\n ZodFirstPartyTypeKind[\"ZodArray\"] = \"ZodArray\";\n ZodFirstPartyTypeKind[\"ZodObject\"] = \"ZodObject\";\n ZodFirstPartyTypeKind[\"ZodUnion\"] = \"ZodUnion\";\n ZodFirstPartyTypeKind[\"ZodDiscriminatedUnion\"] = \"ZodDiscriminatedUnion\";\n ZodFirstPartyTypeKind[\"ZodIntersection\"] = \"ZodIntersection\";\n ZodFirstPartyTypeKind[\"ZodTuple\"] = \"ZodTuple\";\n ZodFirstPartyTypeKind[\"ZodRecord\"] = \"ZodRecord\";\n ZodFirstPartyTypeKind[\"ZodMap\"] = \"ZodMap\";\n ZodFirstPartyTypeKind[\"ZodSet\"] = \"ZodSet\";\n ZodFirstPartyTypeKind[\"ZodFunction\"] = \"ZodFunction\";\n ZodFirstPartyTypeKind[\"ZodLazy\"] = \"ZodLazy\";\n ZodFirstPartyTypeKind[\"ZodLiteral\"] = \"ZodLiteral\";\n ZodFirstPartyTypeKind[\"ZodEnum\"] = \"ZodEnum\";\n ZodFirstPartyTypeKind[\"ZodEffects\"] = \"ZodEffects\";\n ZodFirstPartyTypeKind[\"ZodNativeEnum\"] = \"ZodNativeEnum\";\n ZodFirstPartyTypeKind[\"ZodOptional\"] = \"ZodOptional\";\n ZodFirstPartyTypeKind[\"ZodNullable\"] = \"ZodNullable\";\n ZodFirstPartyTypeKind[\"ZodDefault\"] = \"ZodDefault\";\n ZodFirstPartyTypeKind[\"ZodCatch\"] = \"ZodCatch\";\n ZodFirstPartyTypeKind[\"ZodPromise\"] = \"ZodPromise\";\n ZodFirstPartyTypeKind[\"ZodBranded\"] = \"ZodBranded\";\n ZodFirstPartyTypeKind[\"ZodPipeline\"] = \"ZodPipeline\";\n ZodFirstPartyTypeKind[\"ZodReadonly\"] = \"ZodReadonly\";\n})(ZodFirstPartyTypeKind = exports.ZodFirstPartyTypeKind || (exports.ZodFirstPartyTypeKind = {}));\n// requires TS 4.4+\nclass Class {\n constructor(..._) { }\n}\nconst instanceOfType = (\n// const instanceOfType = any>(\ncls, params = {\n message: `Input not instance of ${cls.name}`,\n}) => (0, exports.custom)((data) => data instanceof cls, params);\nexports.instanceof = instanceOfType;\nconst stringType = ZodString.create;\nexports.string = stringType;\nconst numberType = ZodNumber.create;\nexports.number = numberType;\nconst nanType = ZodNaN.create;\nexports.nan = nanType;\nconst bigIntType = ZodBigInt.create;\nexports.bigint = bigIntType;\nconst booleanType = ZodBoolean.create;\nexports.boolean = booleanType;\nconst dateType = ZodDate.create;\nexports.date = dateType;\nconst symbolType = ZodSymbol.create;\nexports.symbol = symbolType;\nconst undefinedType = ZodUndefined.create;\nexports.undefined = undefinedType;\nconst nullType = ZodNull.create;\nexports.null = nullType;\nconst anyType = ZodAny.create;\nexports.any = anyType;\nconst unknownType = ZodUnknown.create;\nexports.unknown = unknownType;\nconst neverType = ZodNever.create;\nexports.never = neverType;\nconst voidType = ZodVoid.create;\nexports.void = voidType;\nconst arrayType = ZodArray.create;\nexports.array = arrayType;\nconst objectType = ZodObject.create;\nexports.object = objectType;\nconst strictObjectType = ZodObject.strictCreate;\nexports.strictObject = strictObjectType;\nconst unionType = ZodUnion.create;\nexports.union = unionType;\nconst discriminatedUnionType = ZodDiscriminatedUnion.create;\nexports.discriminatedUnion = discriminatedUnionType;\nconst intersectionType = ZodIntersection.create;\nexports.intersection = intersectionType;\nconst tupleType = ZodTuple.create;\nexports.tuple = tupleType;\nconst recordType = ZodRecord.create;\nexports.record = recordType;\nconst mapType = ZodMap.create;\nexports.map = mapType;\nconst setType = ZodSet.create;\nexports.set = setType;\nconst functionType = ZodFunction.create;\nexports.function = functionType;\nconst lazyType = ZodLazy.create;\nexports.lazy = lazyType;\nconst literalType = ZodLiteral.create;\nexports.literal = literalType;\nconst enumType = ZodEnum.create;\nexports.enum = enumType;\nconst nativeEnumType = ZodNativeEnum.create;\nexports.nativeEnum = nativeEnumType;\nconst promiseType = ZodPromise.create;\nexports.promise = promiseType;\nconst effectsType = ZodEffects.create;\nexports.effect = effectsType;\nexports.transformer = effectsType;\nconst optionalType = ZodOptional.create;\nexports.optional = optionalType;\nconst nullableType = ZodNullable.create;\nexports.nullable = nullableType;\nconst preprocessType = ZodEffects.createWithPreprocess;\nexports.preprocess = preprocessType;\nconst pipelineType = ZodPipeline.create;\nexports.pipeline = pipelineType;\nconst ostring = () => stringType().optional();\nexports.ostring = ostring;\nconst onumber = () => numberType().optional();\nexports.onumber = onumber;\nconst oboolean = () => booleanType().optional();\nexports.oboolean = oboolean;\nexports.coerce = {\n string: ((arg) => ZodString.create({ ...arg, coerce: true })),\n number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),\n boolean: ((arg) => ZodBoolean.create({\n ...arg,\n coerce: true,\n })),\n bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),\n date: ((arg) => ZodDate.create({ ...arg, coerce: true })),\n};\nexports.NEVER = parseUtil_1.INVALID;\n","module.exports = __WEBPACK_EXTERNAL_MODULE__205__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(607);\n","module.exports = new __parcel__URL__(\"Hero 01.0a89e3b5.png\").toString();","module.exports = new __parcel__URL__(\"Solaria Demo Update 01.c847244e.png\").toString();","module.exports = new __parcel__URL__(\"Level_0.4121d29c.ldtkl\").toString();","module.exports = new __parcel__URL__(\"Level_1.0859d067.ldtkl\").toString();","module.exports = new __parcel__URL__(\"House.9ff42634.ldtkl\").toString();","module.exports = new __parcel__URL__(\"top-down.3490dc55.ldtk\").toString();","export const Config = {\n PlayerSpeed: 16*2, // pixels/sec\n PlayerFrameSpeed: 200, // ms\n}","import { Actor, DefaultLoader, Engine, Scene, SceneActivationContext, TransformComponent, vec } from \"excalibur\";\nimport { Resources } from \"./resources\";\nimport { Player } from \"./player\";\n\nexport class House extends Scene {\n\n playerSpawnLocation = vec(0, 0);\n onPreLoad(loader: DefaultLoader): void {\n }\n\n onInitialize(engine: Engine): void {\n Resources.LdtkResource.addToScene(this, {\n levelFilter: ['House']\n });\n const entities = Resources.LdtkResource.getEntityLayers('House')[0];\n const playerStart = entities.getLdtkEntitiesByIdentifier('PlayerStart')[0];\n this.playerSpawnLocation = vec(playerStart.__worldX ?? 0, playerStart.__worldY ?? 0);\n }\n\n onActivate(context: SceneActivationContext): void {\n const player = this.world.entityManager.getByName('player')[0];\n player.get(TransformComponent).pos = this.playerSpawnLocation;\n if (player instanceof Player) {\n this.camera.strategy.lockToActor(player as Actor);\n }\n const bounds = Resources.LdtkResource.getLevelBounds(['House']);\n this.camera.strategy.limitCameraBounds(bounds);\n }\n}","import { Actor, Engine, Scene, SceneActivationContext, TransformComponent, vec } from \"excalibur\";\nimport { Resources } from \"./resources\";\nimport { Player } from \"./player\";\n\n\nexport class Overworld extends Scene {\n \n onInitialize(engine: Engine): void {\n Resources.LdtkResource.addToScene(this, {\n pos: vec(0, 0),\n levelFilter: ['Level_0', 'Level_1']\n });\n }\n\n onActivate(context: SceneActivationContext): void {\n const player = this.world.entityManager.getByName('player')[0];\n if (player instanceof Player) {\n this.camera.strategy.lockToActor(player as Actor);\n }\n const bounds = Resources.LdtkResource.getLevelBounds(['Level_0', 'Level_1']);\n this.camera.strategy.limitCameraBounds(bounds);\n }\n}"],"names":["e","$parcel$export","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$parcel$interopDefault","a","__esModule","default","$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","$2c23f148d58cd887$export$f05c91211c084e80","$2c23f148d58cd887$export$e04e17a44f37debc","$2c23f148d58cd887$export$dfcd1bb88f6d711b","$2c23f148d58cd887$export$89f31cec7c284d42","$2c23f148d58cd887$export$a3f070f3e473c3b","$2c23f148d58cd887$export$856e7d6d9d698871","$2c23f148d58cd887$export$caffe607ed29fca1","$2c23f148d58cd887$export$adc62e83dbcda319","$2c23f148d58cd887$export$f73d3eb6fd876d80","$2c23f148d58cd887$export$da248c61eea53296","$2c23f148d58cd887$export$f0455ab08e3fbd0e","$2c23f148d58cd887$export$c35d437ae5945fcd","$2c23f148d58cd887$export$67ee29bab3792d4c","$2c23f148d58cd887$export$d230853e97069d46","$2c23f148d58cd887$export$6cfd78ddb48c90c6","$2c23f148d58cd887$export$3769e64eb87b5ecc","$2c23f148d58cd887$export$54dc36bc2fac5425","$2c23f148d58cd887$export$387a78ab20784494","$2c23f148d58cd887$export$d06866a9fb0606da","$2c23f148d58cd887$export$83c931ba0d3bbaf5","$2c23f148d58cd887$export$1a553341cd0b8415","$2c23f148d58cd887$export$43416332cf06b1f","$2c23f148d58cd887$export$63080c4de6cfc362","$2c23f148d58cd887$export$fa45ecb18b97ae89","$2c23f148d58cd887$export$c24f8f35353a1e26","$2c23f148d58cd887$export$8688def55452cbca","$2c23f148d58cd887$export$665d5a662b7213f3","$2c23f148d58cd887$export$79f141de891a5fed","$2c23f148d58cd887$export$41606648ac8a293c","$2c23f148d58cd887$export$8d01c972ee8b14a9","$2c23f148d58cd887$export$c89a927ffc67e6fa","$2c23f148d58cd887$export$e2395b697f5a931f","$2c23f148d58cd887$export$9735c82c4bae3302","$2c23f148d58cd887$export$44e6803d1d57f89a","$2c23f148d58cd887$export$1ed419d47673a225","$2c23f148d58cd887$export$b7c6eef0ebb06133","$2c23f148d58cd887$export$3c9e91dc1b611d2e","$2c23f148d58cd887$export$ce0ca64520c7bfd2","$2c23f148d58cd887$export$83caf30c40e9d4b8","$2c23f148d58cd887$export$4df0464d8c812c98","$2c23f148d58cd887$export$55e924fc640a8405","$2c23f148d58cd887$export$fbd6eb86d6a3f08","$2c23f148d58cd887$export$7cd2649c3408da6c","$2c23f148d58cd887$export$897cd666d936ac4c","$2c23f148d58cd887$export$cf976780b3106589","$2c23f148d58cd887$export$5dcfde0f6b96512b","$2c23f148d58cd887$export$ddb2ed749236e720","$2c23f148d58cd887$export$892596cec99bc70e","$2c23f148d58cd887$export$8ed4b5bb5352fe14","$2c23f148d58cd887$export$c46090c9df657074","$2c23f148d58cd887$export$b3bf2ffaa538264b","$2c23f148d58cd887$export$16fa2f45be04daa8","$2c23f148d58cd887$export$d16a7c95008e315d","$2c23f148d58cd887$export$abda45806f5adbae","$2c23f148d58cd887$export$e5a30aa3d28b26e2","$2c23f148d58cd887$export$de7807bd8bd828df","$2c23f148d58cd887$export$1bdfb0c7c42d632d","$2c23f148d58cd887$export$bf92f329076cd7a3","$2c23f148d58cd887$export$71de6146fb6d69d2","$2c23f148d58cd887$export$71efaa2be447940c","$2c23f148d58cd887$export$d78c8c6074541cf2","$2c23f148d58cd887$export$7d34ad93c25aa8e7","$2c23f148d58cd887$export$153e5dc2c098b35c","$2c23f148d58cd887$export$f7c1896972d6c454","$2c23f148d58cd887$export$c3e6e677dda8521a","$2c23f148d58cd887$export$e52858e61b0ea117","$2c23f148d58cd887$export$3d1f12550a40f54d","$2c23f148d58cd887$export$4544b2d7eff33859","$2c23f148d58cd887$export$dd6b48f99ee8a36","$2c23f148d58cd887$export$aafe01318a900193","$2c23f148d58cd887$export$fd69b6a3b7f47e29","$2c23f148d58cd887$export$e1545123b54f6785","$2c23f148d58cd887$export$7419ff430885d61c","$2c23f148d58cd887$export$a340d4e5571cbd07","$2c23f148d58cd887$export$e695250628cde35","$2c23f148d58cd887$export$c5e124f7bab3d492","$2c23f148d58cd887$export$cacd6541cfeeb6c1","$2c23f148d58cd887$export$a74d557191881f82","$2c23f148d58cd887$export$99bf88c530739783","$2c23f148d58cd887$export$4b7264771109adb6","$2c23f148d58cd887$export$62053d374d83dfb1","$2c23f148d58cd887$export$d7078bb1ea3ba3f2","$2c23f148d58cd887$export$86ae8da356d53161","$2c23f148d58cd887$export$62230588c4867d28","$2c23f148d58cd887$export$df007b1d5b86e25a","$2c23f148d58cd887$export$6ff391a2049fdf40","$2c23f148d58cd887$export$89e5ccdc4c19a8f6","$2c23f148d58cd887$export$2cbc8fe61dd10773","$2c23f148d58cd887$export$d45269226a4bbdc1","$2c23f148d58cd887$export$2c3b404bf3a77a1f","$2c23f148d58cd887$export$20434e7e042d306a","$2c23f148d58cd887$export$462adefbb095232e","$2c23f148d58cd887$export$83f8212621739c1f","$2c23f148d58cd887$export$bc644a473284d944","$2c23f148d58cd887$export$66b8a9cb33a156c","$2c23f148d58cd887$export$c7b7134fd828a5","$2c23f148d58cd887$export$ec8b666c5fe2c75a","$2c23f148d58cd887$export$4fae95256245c8c0","$2c23f148d58cd887$export$86d9a347f2bf71d6","$2c23f148d58cd887$export$ada873a34909da65","$2c23f148d58cd887$export$afee3afd6be961ec","$2c23f148d58cd887$export$c03216fb3a7a2f87","$2c23f148d58cd887$export$81940238f313e11f","$2c23f148d58cd887$export$40f8f9a8f94db930","$2c23f148d58cd887$export$c579e21b95165414","$2c23f148d58cd887$export$c983850c6c9d8b0e","$2c23f148d58cd887$export$be5b6c6ac24b4683","$2c23f148d58cd887$export$434ba092ed0eee4e","$2c23f148d58cd887$export$455f05776f1ba8ba","$2c23f148d58cd887$export$89abf52a030e56ee","$2c23f148d58cd887$export$549c899505235621","$2c23f148d58cd887$export$1f6d1255105a925c","$2c23f148d58cd887$export$23b468d4ca3f8c96","$2c23f148d58cd887$export$6976e674e6d5804c","$2c23f148d58cd887$export$420acfc1740638d3","$2c23f148d58cd887$export$e84927905accfe51","$2c23f148d58cd887$export$c9d7bf589772a8ce","$2c23f148d58cd887$export$d5011a4647754c9b","$2c23f148d58cd887$export$b8c6aa234afa01bc","$2c23f148d58cd887$export$6c3776220abeb931","$2c23f148d58cd887$export$27a9cd7ebdd38262","$2c23f148d58cd887$export$fb1b94e06ba8ebc8","$2c23f148d58cd887$export$3d953a2d86354b5f","$2c23f148d58cd887$export$88528019d270f582","$2c23f148d58cd887$export$402da60b1c009e43","$2c23f148d58cd887$export$757ccd1717b77f48","$2c23f148d58cd887$export$48ebf29bc7cb1dd7","$2c23f148d58cd887$export$3c8c04bde7eed7cb","$2c23f148d58cd887$export$adfa9d260876eca5","$2c23f148d58cd887$export$6c043ed3a716859a","$2c23f148d58cd887$export$9f9afb456a8bef30","$2c23f148d58cd887$export$1033a6fa0779f4f5","$2c23f148d58cd887$export$38f8109d2b8f43ef","$2c23f148d58cd887$export$b5aa7fe3676b74a9","$2c23f148d58cd887$export$5213deb2877a09f2","$2c23f148d58cd887$export$280e9a68c3ffd919","$2c23f148d58cd887$export$49a1ecce8d203","$2c23f148d58cd887$export$f5b8910cec6cf069","$2c23f148d58cd887$export$99f13cbf742a0580","$2c23f148d58cd887$export$2ae6ec0f10d96242","$2c23f148d58cd887$export$d379657aa3df1705","$2c23f148d58cd887$export$ffed6a4cd9a88787","$2c23f148d58cd887$export$7705889256a9371a","$2c23f148d58cd887$export$539f65e788a82c62","$2c23f148d58cd887$export$851e6d93385b6ad2","$2c23f148d58cd887$export$4b0c1c390bf9a356","$2c23f148d58cd887$export$16e4d70cc375e707","$2c23f148d58cd887$export$4b0075e5ea5e1f26","$2c23f148d58cd887$export$f3a6c1ca682fd40f","$2c23f148d58cd887$export$b04be29aa201d4f5","$2c23f148d58cd887$export$b3509fba7d85d294","$2c23f148d58cd887$export$17d680238e50603e","$2c23f148d58cd887$export$8b98feb4a2766c75","$2c23f148d58cd887$export$3b0d6d7590275603","$2c23f148d58cd887$export$38d47553764a3d88","$2c23f148d58cd887$export$1c4c6d3f8d56581","$2c23f148d58cd887$export$fc869739b2177284","$2c23f148d58cd887$export$243e62d78d3b544d","$2c23f148d58cd887$export$efa9a398d6368992","$2c23f148d58cd887$export$a2d8b23205c25948","$2c23f148d58cd887$export$5b12bf1653c0dd85","$2c23f148d58cd887$export$9f9b2346169b00c0","$2c23f148d58cd887$export$8c37b217b84d3f89","$2c23f148d58cd887$export$35624b13e79b24a9","$2c23f148d58cd887$export$f75e7304717c9cbc","$2c23f148d58cd887$export$ec1251c88c8bd5c9","$2c23f148d58cd887$export$d17844835b0fe8a8","$2c23f148d58cd887$export$d1d8cb3d5c2a5671","$2c23f148d58cd887$export$4d607ef791645d6","$2c23f148d58cd887$export$f0b55daf9f154b55","$2c23f148d58cd887$export$fa9699e41ba6faff","$2c23f148d58cd887$export$57ca7e07b341709d","$2c23f148d58cd887$export$77cea355fa80b5f4","$2c23f148d58cd887$export$8844adde4348f85c","$2c23f148d58cd887$export$d63d7cff08fe4dc9","$2c23f148d58cd887$export$a960801e47624f4f","$2c23f148d58cd887$export$ed6a63ee685a4d78","$2c23f148d58cd887$export$4fe52ae24ae61d51","$2c23f148d58cd887$export$c36c68baa13912a5","$2c23f148d58cd887$export$616c632b282478dd","$2c23f148d58cd887$export$459b1801e3134a24","$2c23f148d58cd887$export$2f09efa5b67124a7","$2c23f148d58cd887$export$618424ba3f30cd41","$2c23f148d58cd887$export$4a963ea7a16edf21","$2c23f148d58cd887$export$a4017560efebe97d","$2c23f148d58cd887$export$982e5de016bedff1","$2c23f148d58cd887$export$6860c0696b73f79b","$2c23f148d58cd887$export$94806efd9890932f","$2c23f148d58cd887$export$3bee0b2628b43478","$2c23f148d58cd887$export$caed39dbb767d548","$2c23f148d58cd887$export$7e5ab4f7f9fd407","$2c23f148d58cd887$export$330520496d871ecf","$2c23f148d58cd887$export$7d31b617c820d435","$2c23f148d58cd887$export$f23a2a272a8df60","$2c23f148d58cd887$export$14963ee5c8637e11","$2c23f148d58cd887$export$1d2c184034fc4cc2","$2c23f148d58cd887$export$fea21a521a6360c1","$2c23f148d58cd887$export$8c15bdf7e3727f73","$2c23f148d58cd887$export$6eb043bf81d89752","$2c23f148d58cd887$export$e390b859365a3d5b","$2c23f148d58cd887$export$82a33120f6a0d987","$2c23f148d58cd887$export$1ec85152758537e0","$2c23f148d58cd887$export$a8584993858a18df","$2c23f148d58cd887$export$906049a3747337a6","$2c23f148d58cd887$export$dbd8a6303ac26a42","$2c23f148d58cd887$export$9f68b6f37a444556","$2c23f148d58cd887$export$fe2b6ac465da985d","$2c23f148d58cd887$export$4c3c82f4dcd79fcc","$2c23f148d58cd887$export$e4ce43ec0499fb8f","$2c23f148d58cd887$export$e44279b5c44add28","$2c23f148d58cd887$export$dfa3a012bb2ef2e1","$2c23f148d58cd887$export$8201b979875baf73","$2c23f148d58cd887$export$b82688eb02220411","$2c23f148d58cd887$export$62297b13309008b2","$2c23f148d58cd887$export$b986383a50b53ea4","$2c23f148d58cd887$export$ad5b3d166367714c","$2c23f148d58cd887$export$a92776769f460054","$2c23f148d58cd887$export$eeb71495ca594706","$2c23f148d58cd887$export$a186db52eed6d40e","$2c23f148d58cd887$export$c07ce6d13c46df49","$2c23f148d58cd887$export$4617fb02663045ef","$2c23f148d58cd887$export$32437fc39ad02208","$2c23f148d58cd887$export$f9d61a2a6155ab51","$2c23f148d58cd887$export$9bd81f7d9b69ccb3","$2c23f148d58cd887$export$3e4ff2216a90b8a4","$2c23f148d58cd887$export$39a853cfb5a94a63","$2c23f148d58cd887$export$62833702c6700187","$2c23f148d58cd887$export$a43177620e7a9310","$2c23f148d58cd887$export$a16b6ef1fd362a19","$2c23f148d58cd887$export$91397be43fc980cc","$2c23f148d58cd887$export$23b9d128e61caefd","$2c23f148d58cd887$export$ab681471d41eeddc","$2c23f148d58cd887$export$38af1803e3442a7f","$2c23f148d58cd887$export$c1825d965cf69ea3","$2c23f148d58cd887$export$a98515d67472a41f","$2c23f148d58cd887$export$57486627f01aaaf3","$2c23f148d58cd887$export$77630fcd7c3f2eb6","$2c23f148d58cd887$export$3bf088dd0bb7575","$2c23f148d58cd887$export$2f3ac66e390c188b","$2c23f148d58cd887$export$d160a188872e1e4e","$2c23f148d58cd887$export$5c7bd08c630c970c","$2c23f148d58cd887$export$462bb059fed9d9e5","$2c23f148d58cd887$export$6428a7f2611ef1fa","$2c23f148d58cd887$export$80a00690bda7f17e","$2c23f148d58cd887$export$50994fad4c4676f4","$2c23f148d58cd887$export$85990f0f98a390bb","$2c23f148d58cd887$export$5bff0d6cc6200d64","$2c23f148d58cd887$export$3075603db8e6204c","$2c23f148d58cd887$export$e1896ac0c4970221","$2c23f148d58cd887$export$bd73ddfe5f8475d8","$2c23f148d58cd887$export$f62bb2892382b3dd","$2c23f148d58cd887$export$cbf2d83d1eab018a","$2c23f148d58cd887$export$9ad53eded130cce4","$2c23f148d58cd887$export$6a4eb2e7fc9e8903","$2c23f148d58cd887$export$e1dae5660003ffa7","$2c23f148d58cd887$export$a12e67a4b4590901","$2c23f148d58cd887$export$7c88eb83095afadd","$2c23f148d58cd887$export$c586aa7b67d94d19","$2c23f148d58cd887$export$47b45ce774071a36","$2c23f148d58cd887$export$9440a22058545f9a","$2c23f148d58cd887$export$5f1af8db9871e1d6","$2c23f148d58cd887$export$3720eb13f948f394","$2c23f148d58cd887$export$fd1bfc71f64c538c","$2c23f148d58cd887$export$235cb65c20ad2b7","$2c23f148d58cd887$export$16ec26812de3ce7a","$2c23f148d58cd887$export$dac3abbdc575ce73","$2c23f148d58cd887$export$c57e9b2d8b9e4de","$2c23f148d58cd887$export$fb98e3a2a4cd92d7","$2c23f148d58cd887$export$563a914cafbdc389","$2c23f148d58cd887$export$1def2aa75b7c7fe0","$2c23f148d58cd887$export$be58926105124dd4","$2c23f148d58cd887$export$2eba8ec3a333fdbb","$2c23f148d58cd887$export$41fb9f06171c75f4","$2c23f148d58cd887$export$14963f945d6d59f0","$2c23f148d58cd887$export$ba8651401a8a2b84","$2c23f148d58cd887$export$f8f26dd395d7e1bd","$2c23f148d58cd887$export$9b781de7bf37bf48","$2c23f148d58cd887$export$ab650c8e5b9b9f2c","$2c23f148d58cd887$export$41825a1ed6473903","$2c23f148d58cd887$export$f5ae2f144b95ebf4","$2c23f148d58cd887$export$31ac8f65680039dd","$2c23f148d58cd887$export$d5c6f73f7a77b9d","$2c23f148d58cd887$export$8bfbf00b5dba81f6","$2c23f148d58cd887$export$2af5ef044257da25","$2c23f148d58cd887$export$8c3375c231593a9d","$2c23f148d58cd887$export$9a4eae43f302c46e","$2c23f148d58cd887$export$812cd9544993280d","$2c23f148d58cd887$export$a4913eafbb02ceb4","$2c23f148d58cd887$export$7d15b64cf5a3a4c4","$2c23f148d58cd887$export$c372a5d5a3996cbf","$2c23f148d58cd887$export$7149c6ffc9994c32","$2c23f148d58cd887$export$d436988b04cb99a5","$2c23f148d58cd887$export$3ba9f2e94585ecc6","$2c23f148d58cd887$export$25dac40984956196","$2c23f148d58cd887$export$57932b71da6538b7","$2c23f148d58cd887$export$a17402ef5f32064d","$2c23f148d58cd887$export$d5dea09620a858fd","$2c23f148d58cd887$export$1377812d73ae3cab","$2c23f148d58cd887$export$331f4c7ef74a9752","$2c23f148d58cd887$export$5f4e18965661d41f","$2c23f148d58cd887$export$817667946f51142b","$2c23f148d58cd887$export$adc479603c39b28","$2c23f148d58cd887$export$ba30ba18962891e7","$2c23f148d58cd887$export$bcf8f1355133000b","$2c23f148d58cd887$export$256576ea924e6c90","$2c23f148d58cd887$export$786d9ab531bddbaa","$2c23f148d58cd887$export$e87630d8ef35465d","$2c23f148d58cd887$export$c3cedacda2d7ce48","$2c23f148d58cd887$export$5a62d8eea226ddc","$2c23f148d58cd887$export$640d107500a3202a","$2c23f148d58cd887$export$506bf22710a79182","$2c23f148d58cd887$export$8b958c8ecd94a804","$2c23f148d58cd887$export$816343276f749e02","$2c23f148d58cd887$export$d02631cccf789723","$2c23f148d58cd887$export$5dc5812d8b390c43","$2c23f148d58cd887$export$c5552dfdbc7cec71","$2c23f148d58cd887$export$56cb859c01fa134d","$2c23f148d58cd887$export$cba01ba138429a1d","$2c23f148d58cd887$export$202e0172ed3c7be0","$2c23f148d58cd887$export$d55298c9efc5ed14","$2c23f148d58cd887$var$__webpack_modules__","__webpack_exports__","__webpack_require__","d","Z","__WEBPACK_DEFAULT_EXPORT__","_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__","_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default","_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__","___CSS_LOADER_EXPORT___","_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default","push","cssWithMappingToString","list","toString","map","item","content","needLayer","concat","length","join","i","modules","media","dedupe","supports","layer","undefined","alreadyImportedModules","k","_k","cssMapping","btoa","base64","unescape","encodeURIComponent","JSON","stringify","__unused_webpack_exports","entryUnbind","path","keys","isCallable","tryToString","$TypeError","TypeError","argument","isObject","$String","String","toIndexedObject","toAbsoluteIndex","lengthOfArrayLike","createMethod","IS_INCLUDES","$this","el","fromIndex","value","O","index","includes","indexOf","fails","METHOD_NAME","method","uncurryThis","slice","arraySlice","floor","Math","sort","array","comparefn","element","j","middle","left","right","llength","rlength","lindex","rindex","stringSlice","it","TO_STRING_TAG_SUPPORT","classofRaw","TO_STRING_TAG","wellKnownSymbol","$Object","CORRECT_ARGUMENTS","arguments","tryGet","key","error","tag","result","callee","hasOwn","ownKeys","getOwnPropertyDescriptorModule","definePropertyModule","target","source","exceptions","f","getOwnPropertyDescriptor","DESCRIPTORS","createPropertyDescriptor","object","bitmap","writable","makeBuiltIn","defineGlobalProperty","options","simple","name","global","unsafe","nonConfigurable","nonWritable","P","document1","document","EXISTS","createElement","firefox","userAgent","match","UA","test","navigator","version","process","Deno","versions","v8","split","webkit","CONSTRUCTOR","METHOD","prototype","createNonEnumerableProperty","defineBuiltIn","copyConstructorProperties","isForced","targetProperty","sourceProperty","descriptor","TARGET","GLOBAL","STATIC","stat","dontCallGetSet","forced","sham","exec","bind","hasOwnProperty","NATIVE_BIND","Function","apply","FunctionPrototype","getDescriptor","CONFIGURABLE","PROPER","uncurryThisWithBind","fn","namespace","aCallable","isNullOrUndefined","V","func","check","window","self","g","toObject","classof","propertyIsEnumerable","store","functionToString","inspectSource","has","NATIVE_WEAK_MAP","shared","sharedKey","hiddenKeys","OBJECT_ALREADY_INITIALIZED","TypeError1","WeakMap1","WeakMap","state","metadata","facade","STATE","enforce","getterFor","TYPE","type","documentAll","all","replacement","feature","detection","data","normalize","POLYFILL","NATIVE","string","replace","toLowerCase","getBuiltIn","isPrototypeOf","USE_SYMBOL_AS_UID","$Symbol","toLength","obj","CONFIGURABLE_FUNCTION_NAME","InternalStateModule","enforceInternalState","getInternalState","CONFIGURABLE_LENGTH","TEMPLATE","getter","setter","arity","constructor","ceil","trunc","x","__unused_webpack_module","IE8_DOM_DEFINE","V8_PROTOTYPE_DEFINE_BUG","anObject","toPropertyKey","$defineProperty","$getOwnPropertyDescriptor","ENUMERABLE","WRITABLE","Attributes","current","propertyIsEnumerableModule","internalObjectKeys","enumBugKeys","getOwnPropertyNames","getOwnPropertySymbols","names","$propertyIsEnumerable","NASHORN_BUG","input","pref","val","valueOf","getOwnPropertyNamesModule","getOwnPropertySymbolsModule","uid","SHARED","IS_PURE","mode","copyright","license","V8_VERSION","symbol","Symbol","toIntegerOrInfinity","max","min","integer","IndexedObject","requireObjectCoercible","number","len","isSymbol","getMethod","ordinaryToPrimitive","TO_PRIMITIVE","exoticToPrim","toPrimitive","postfix","random","NATIVE_SYMBOL","iterator","Symbol1","WellKnownSymbolsStore","createWellKnownSymbol","withoutSetter","$","deletePropertyOrThrow","internalSort","arrayMethodIsStrict","FF","IE_OR_EDGE","V8","WEBKIT","nativeSort","FAILS_ON_UNDEFINED","FAILS_ON_NULL","STRICT_METHOD","STABLE_SORT","chr","fromCharCode","b","charAt","proto","itemsLength","items","arrayLength","y","nativeKeys","$2c23f148d58cd887$var$__webpack_module_cache__","$2c23f148d58cd887$var$__webpack_require__","moduleId","cachedModule","definition","o","prop","r","toStringTag","$2c23f148d58cd887$var$__webpack_exports__","y1j","ActionCompleteEvent","fWn","ActionContext","Ia8","ActionQueue","rqv","ActionSequence","zH6","ActionStartEvent","hLI","ActionsComponent","yyv","ActionsSystem","tX5","ActivateEvent","vtX","Actor","r7K","AddedComponent","cE4","AffineMatrix","fwF","Animation","sce","AnimationDirection","AQ6","AnimationEvents","_c7","AnimationStrategy","KUs","ArcadeSolver","Ajp","AudioContextFactory","dkO","Axes","RDh","Axis","_H9","BaseAlign","mxs","Blink","OmD","BodyComponent","kBf","BoundingBox","C4F","BroadphaseStrategy","NQt","BrowserComponent","JjN","BrowserEvents","EK_","Buttons","V1s","Camera","xHm","CameraEvents","Xz7","Canvas","Cdc","Circle","FKn","CircleCollider","SUY","Clock","ab2","ClosestLine","GfZ","ClosestLineJumpTable","YMS","Collider","oyv","ColliderComponent","aUb","CollisionContact","SdD","CollisionEndEvent","JUv","CollisionGroup","jEj","CollisionGroupManager","TFq","CollisionJumpTable","HDU","CollisionPostSolveEvent","R_y","CollisionPreSolveEvent","t50","CollisionStartEvent","s$$","CollisionSystem","v2G","CollisionType","Ilk","Color","s9i","ColorBlindFlags","dxL","ColorBlindnessMode","LLX","ColorBlindnessPostProcessor","wA2","Component","R_p","CompositeCollider","IQ$","Configurable","I5F","ConsoleAppender","X8$","ContactConstraintPoint","FR6","ContactEndEvent","pTZ","ContactSolveBias","U8o","ContactStartEvent","kbG","CoordPlane","FEv","CrossFade","iS_","DeactivateEvent","cGG","Debug","ETM","DebugConfig","RPN","DebugGraphicsComponent","skb","DebugSystem","SLU","DebugText","Q3w","DefaultAntialiasOptions","xK2","DefaultLoader","vrO","DefaultPhysicsConfig","EA2","DefaultPixelArtOptions","RdJ","DegreeOfFreedom","cNu","Delay","wtG","DeprecatedStaticToConfig","gU7","Detector","LSk","Die","Nmp","Direction","twX","Director","UND","DirectorEvents","d1Y","DisplayMode","xrL","DynamicTree","sRW","DynamicTreeCollisionProcessor","cmV","EX_VERSION","qWz","EaseBy","N0Q","EaseTo","q8b","EasingFunctions","ynB","EdgeCollider","jT9","ElasticToActorStrategy","wAz","EmitterType","D4V","Engine","NLr","EngineEvents","N6H","EnterTriggerEvent","W1A","EnterViewPortEvent","JHW","Entity","ZZ$","EntityEvents","v2K","EntityManager","pBf","EventDispatcher","vpe","EventEmitter","GMl","EventTypes","zW2","Events_namespaceObject","B0K","ExResponse","Nv7","ExcaliburGraphicsContext2DCanvas","C_p","ExcaliburGraphicsContextWebGL","MUA","ExitTriggerEvent","xqU","ExitViewPortEvent","pTp","Fade","trb","FadeInOut","vUK","Flags","j9l","Follow","Zxw","Font","v51","FontCache","gYv","FontSource","Hdx","FontStyle","Z$d","FontUnit","iqV","FpsSampler","o$7","FrameStats","olM","Future","Zm$","GameEvent","$QH","GameStartEvent","i78","GameStopEvent","nJg","Gamepad","h6u","GamepadAxisEvent","hts","GamepadButtonEvent","j88","GamepadConnectEvent","VME","GamepadDisconnectEvent","fy2","Gamepads","nt","Gif","Ukr","GlobalCoordinates","zsu","Graphic","oA6","GraphicsComponent","TVh","GraphicsGroup","xxj","GraphicsSystem","XdK","HiddenEvent","fBD","HorizontalFirst","Jmb","ImageFiltering","cXo","ImageSource","Dm5","InitializeEvent","IIB","Input_Index_namespaceObject","IX$","InputHost","ebW","InputMapper","zI0","Integrator","LYD","IsometricEntityComponent","cEG","IsometricEntitySystem","SEl","IsometricMap","t9V","IsometricTile","ez5","KeyEvent","N1d","Keyboard","R8U","Keys","SKZ","KillEvent","__J","Label","RI$","LimitCameraBoundsStrategy","x12","Line","ccz","LineSegment","aNw","Loader","XrL","LoaderEvents","xwn","LockCameraToActorAxisStrategy","dNK","LockCameraToActorStrategy","ini","LogLevel","YdH","Logger","F5T","Material","y3G","Matrix","l57","MatrixLocations","xn0","MediaEvent","t2V","Meet","uxB","MotionComponent","cpd","MotionSystem","fiy","MoveBy","$XZ","MoveTo","UG6","NativePointerButton","uqK","NativeSoundEvent","STE","NativeSoundProcessedEvent","Hq9","None","y$z","Observable","mAD","OffscreenSystem","sOq","Pair","hUw","ParallaxComponent","_0G","ParallelActions","Sqs","ParseGif","hpZ","Particle","Vol","ParticleEmitter","vYX","ParticleTransform","wIZ","Physics","cBi","PhysicsStats","c30","PhysicsWorld","PGK","PointerAbstraction","MPV","PointerButton","RFv","PointerComponent","Ux6","PointerEvent","rxy","PointerEventReceiver","I$c","PointerScope","kfC","PointerSystem","VjY","PointerType","mgq","Polygon","YVA","PolygonCollider","Kgp","Pool","HH$","PostCollisionEvent","M_d","PostDebugDrawEvent","rgh","PostDrawEvent","Ra6","PostFrameEvent","KhR","PostKillEvent","gvQ","PostTransformDrawEvent","BS5","PostUpdateEvent","xhz","PreCollisionEvent","xOq","PreDebugDrawEvent","a9j","PreDrawEvent","bHk","PreFrameEvent","CgK","PreKillEvent","A0M","PreLoadEvent","cEd","PreTransformDrawEvent","cuY","PreUpdateEvent","kvE","Projection","SBu","QuadIndexBuffer","PsT","QuadTree","AE_","Query","ctO","QueryManager","OLH","RadiusAroundActorStrategy","kky","Random","nSF","Raster","zHn","Ray","zwx","RealisticSolver","AeJ","Rectangle","hLz","RemovedComponent","wA","Repeat","jhr","RepeatForever","GVs","Resolution","_zO","Resource","LXZ","ResourceEvents","w6$","RotateBy","mhV","RotateTo","MOD","RotationType","kwd","ScaleBy","Lmr","ScaleTo","xsS","Scene","K5l","SceneEvents","lLr","Screen","Z$r","ScreenAppender","IXb","ScreenElement","Xsu","ScreenEvents","SGH","ScreenShader","SMj","ScrollPreventionMode","L34","Semaphore","exe","Shader","bnF","Shape","MFA","Side","kPj","SolverStrategy","$uU","Sound","Sap","SoundEvents","jyi","Sprite","E03","SpriteFont","V6q","SpriteSheet","rg2","StandardClock","DVW","StateMachine","nVo","StrategyContainer","F6N","Stream","xP7","System","Odq","SystemManager","uY9","SystemPriority","Zif","SystemType","c_d","TagQuery","MJk","TestClock","xvT","Text","PHM","TextAlign","dpR","TextureLoader","n9L","Tile","KwO","TileMap","SxM","TileMapEvents","B7y","Timer","x7r","Toaster","wx7","transform_Transform","Uvn","TransformComponent","uTP","Transition","OFT","TreeNode","xzN","Trigger","CcZ","TriggerEvents","M5Z","TwoPI","ZrN","Util_Index_namespaceObject","OWs","Vector","dF9","VectorView","oZy","VertexBuffer","rD2","VertexLayout","KmN","VerticalFirst","VHo","VisibleEvent","ohE","WebAudio","R$E","WebAudioInstance","xQN","WheelDeltaMode","AdJ","WheelEvent","q3I","World","Pab","canonicalizeAngle","uZ5","clamp","TAE","coroutine","McK","createId","F9c","frac","k0b","hasGraphicsTick","hnT","hasOnInitialize","RSJ","hasOnPostUpdate","Mku","hasOnPreUpdate","h90","hasPostDraw","rms","hasPreDraw","ErP","has_initialize","aVg","has_postupdate","lPc","has_preupdate","Z8E","isAddedComponent","k15","isComponentCtor","YsU","isLoaderConstructor","lNv","isRemovedComponent","Xyg","isSceneConstructor","cu9","isScreenElement","p88","isSystemConstructor","MZQ","maxMessages","FUM","obsolete","BxR","pixelSnapEpsilon","vdf","randomInRange","iaL","randomIntInRange","w6H","range","Q4c","resetObsoleteCounter","Xxe","sign","Uxb","toDegrees","Yr5","toRadians","Bhw","vec","yOA","webgl_util_namespaceObject","getAttributeComponentSize","getAttributePointerType","getGlTypeSizeBytes","DrawUtil_namespaceObject","circle","line","point","roundRect","vector","polyfill","audioContext","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","callback","setInterval","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","AudioContext","webkitAudioContext","replaceMe","ctx","decodeAudioData","arrayBuffer","Promise","resolve","reject","mozAudioContext","msAudioContext","oAudioContext","devicePixelRatio","DrawUtil","addItemToArray","contains","delay","fail","getPosition","omit","removeItemFromArray","useCanvasGraphicsContext","enable","freeze","_FROZEN","_reset","_FLAGS","flagName","disable","isEnabled","show","_isCompleted","promise","_resolver","_rejecter","isCompleted","_paused","_listeners","_listenersOnce","_pipes","clear","on","eventName","handler","_a","close","off","once","_b","newListeners","filter","h","newOnceListeners","emit","event","forEach","onces","pipe","emitter","splice","unpipe","pause","unpause","seed","_lowerMask","_upperMask","_w","_n","_m","_u","_s","_t","_c","_l","_f","_mt","Array","Date","now","_index","_twist","mag01","nextInt","next","floating","bool","likelihood","pickOne","pickSet","numPicks","allowDuplicates","_pickSetWithDuplicates","_pickSetWithoutDuplicates","currentPick","tempArray","shuffle","swap","randomIndex","d4","d6","d8","d10","d12","d20","PI","angle","tmpAngle","radians","degrees","from","to","_x","round","Zero","One","Half","Up","Down","Left","Right","fromAngle","cos","sin","isValid","isNaN","Infinity","distance","vec1","vec2","sqrt","pow","_y","setTo","equals","tolerance","abs","deltaX","deltaY","squareDistance","clampMagnitude","magnitude","newSize","size","newLength","scale","average","add","sizeOrScale","dest","sub","addEqual","subEqual","scaleEqual","dot","cross","num","perpendicular","normal","negate","toAngle","atan2","rotate","anchor","sinAngle","cosAngle","clone","fixed","toFixed","fromRGB","fromRGBString","parseInt","parseFloat","fromHex","hex","fromHSL","l","temp","HSLColor","toRGBA","lighten","factor","fromRGBA","darken","saturate","desaturate","multiply","color","newR","screen","color1","invert","color2","equal","format","toHSLA","toHex","_componentToHex","c","fillStyle","Black","White","Gray","LightGray","DarkGray","Yellow","Orange","Red","Vermilion","Rose","Magenta","Violet","Blue","Azure","Cyan","Viridian","Green","Chartreuse","Transparent","ExcaliburBlue","hue2rgb","p","q","t","_appenders","defaultLevel","Info","_logOnceSet","Set","_INSTANCE","addAppender","getInstance","appender","clearAppenders","_log","level","args","log","_logOnce","serialized","debug","debugOnce","info","infoOnce","warn","Warn","warnOnce","errorOnce","fatal","Fatal","fatalOnce","console","consoleArgs","unshift","_messages","_pos","_color","_options","canvas","_ctx","getContext","style","position","zIndex","body","appendChild","_positionScreenAppenderCanvas","engine","events","_d","width","resolution","height","pagePos","screenToPageCoordinates","top","xPos","message","clearRect","pos","fillText","getOpposite","side","Top","Bottom","fromDirection","direction","directions","directionEnum","Number","MAX_VALUE","maxIndex","leftOrOptions","bottom","_points","getSideFromIntersection","intersection","fromPoints","points","minX","minY","maxX","maxY","fromDimension","hasZeroDimensions","center","topLeft","bottomRight","topRight","bottomLeft","translate","getPoints","shifted","transform","matrix","xa1","xa2","xb1","xb2","ya1","ya2","yb1","yb2","matrixPos","getPerimeter","wx","_left","_right","_top","_bottom","rayCast","ray","farClipDistance","tmin","tmax","xinv","dir","yinv","tx1","tx2","ty1","ty2","rayCastTime","combine","other","dimensions","overlaps","epsilon","totalBoundingBox","intersect","overlapX","overlapY","intersectWithSide","bb","draw","ex","drawRect","rect","getBoundingClientRect","scrollX","scrollY","milliseconds","clock","future","schedule","setTimeout","newObj","Float32Array","_scaleX","_scaleSignX","_scaleY","_scaleSignY","ortho","near","far","mat","toDOMMatrix","DOMMatrix","fromFloat32Array","identity","reset","translation","sx","sy","rotation","angleRadians","vectorOrMatrix","resultX","resultY","a11","a21","a31","a41","a12","a22","a32","a42","a13","a23","a33","a43","a14","a24","a34","a44","b11","b21","b31","b41","b12","b22","b32","b42","b13","b23","b33","b43","b14","b24","b34","b44","getScale","setPosition","sine","cosine","setRotation","currentScale","getRotation","getScaleY","getScaleX","xscale","yscale","setScaleX","setScaleY","setScale","getBasisDeterminant","getAffineInverse","inverseDet","m","tx","ty","isIdentity","Float64Array","_scale","determinant","inverse","to4x4","TransformStack","_transforms","_currentTransform","save","restore","pop","StateStack","_states","_currentState","_getDefaultState","opacity","z","tint","material","_cloneState","Complete","Load","LoadStart","Progress","responseType","bustCache","logger","isLoaded","_cacheBust","uri","query","load","request","XMLHttpRequest","open","addEventListener","status","response","statusText","send","watch","change","__isProxy","Proxy","createHandler","typeType","watchAny","isStale","_transformStale","flipHorizontal","_flipHorizontal","flipVertical","_flipVertical","_rotation","origin","_origin","_e","_g","_ID","showDebug","_width","_height","cloneGraphicOptions","localBounds","_preDraw","_drawImage","_postDraw","_rotate","_flip","scaleDirX","scaleDirY","image","_logger","_dirty","sourceView","destSize","_updateSpriteDimensions","ready","then","newWidth","newHeight","nativeWidth","nativeHeight","drawImage","gl","_textureMap","Map","_gl","_MAX_TEXTURE_SIZE","getParameter","MAX_TEXTURE_SIZE","dispose","delete","filtering","forceUpdate","tex","bindTexture","TEXTURE_2D","texImage2D","RGBA","UNSIGNED_BYTE","createTexture","checkImageSizeSupportedAndLog","pixelStorei","UNPACK_PREMULTIPLY_ALPHA_WEBGL","texParameteri","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","filterMode","TEXTURE_MIN_FILTER","Pixel","NEAREST","LINEAR","TEXTURE_MAG_FILTER","deleteTexture","originalSrc","dataset","_LOGGER","Blended","naturalWidth","naturalHeight","_src","src","Image","_readyFuture","_resource","endsWith","fromHtmlImageElement","imageSource","setAttribute","url","blob","URL","createObjectURL","loadedFuture","onload","toSprite","unload","_text","alphabet","shadow","caseInsensitive","spacing","lineHeight","spriteSheet","_getCharacterSprites","text","results","textToRender","toLocaleLowerCase","letterIndex","letter","spriteIndex","letterSprite","sprites","measureText","maxWidth","lines","_getLinesFromText","maxWidthLine","reduce","sprite","xCursor","yCursor","render","bounds","offset","_cachedText","_cachedRenderWidth","_cachedLines","newLine","rows","columns","getSprite","_h","_j","spriteWithOptions","fromImageSourceWithSourceViews","sourceViews","fromImageSource","grid","cols","spriteWidth","spriteHeight","originOffset","margin","offsetDefaults","marginDefaults","fontSheet","_imageSource","_spriteSheet","_spriteFont","write","RenderSource","_texture","use","activeTexture","TEXTURE0","RenderTarget","antialias","samples","transparency","MAX_SAMPLES","drawingBufferFormat","bufferFormat","RGBA8","RGB8","_setupRenderBuffer","_setupFramebuffer","setResolution","_frameTexture","_renderBuffer","bindRenderbuffer","RENDERBUFFER","renderbufferStorageMultisample","renderBuffer","renderFrameBuffer","_renderFrameBuffer","frameBuffer","_frameBuffer","frameTexture","createRenderbuffer","createFramebuffer","bindFramebuffer","FRAMEBUFFER","framebufferRenderbuffer","COLOR_ATTACHMENT0","attachmentPoint","framebufferTexture2D","toRenderSource","blitRenderBufferToFrameBuffer","blitToScreen","READ_FRAMEBUFFER","DRAW_FRAMEBUFFER","clearBufferfv","COLOR","blitFramebuffer","COLOR_BUFFER_BIT","copyToTexture","texture","copyTexImage2D","viewport","FLOAT","SHORT","UNSIGNED_SHORT","BYTE","LOW_FLOAT","HIGH_FLOAT","FLOAT_VEC2","FLOAT_VEC3","FLOAT_VEC4","compiled","_compiled","uniforms","attributes","vertexSource","fragmentSource","deleteProgram","program","useProgram","_ACTIVE_SHADER_INSTANCE","isCurrentlyBound","compile","vertexShader","_compileShader","VERTEX_SHADER","fragmentShader","FRAGMENT_SHADER","attribute","_createProgram","getAttributes","uniform","getUniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","getActiveUniform","uniformLocation","getUniformLocation","glType","location","attributeCount","ACTIVE_ATTRIBUTES","getActiveAttrib","attributeLocation","getAttribLocation","normalized","setTexture","slotNumber","setUniformInt","setUniform","trySetUniformInt","trySetUniform","setUniformIntArray","trySetUniformIntArray","setUniformBoolean","trySetUniformBoolean","setUniformFloat","trySetUniformFloat","setUniformFloatArray","trySetUniformFloatArray","setUniformFloatVector","trySetUniformFloatVector","setUniformFloatColor","trySetUniformFloatColor","setUniformMatrix","trySetUniformMatrix","uniformType","createProgram","attachShader","linkProgram","LINK_STATUS","getProgramInfoLog","typeName","shader","createShader","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","errorInfo","getShaderInfoLog","_processSourceForError","errorLineStart","search","errorLineEnd","_","error2","buffer","createBuffer","bufferData","bindBuffer","ARRAY_BUFFER","STATIC_DRAW","DYNAMIC_DRAW","upload","count","bufferSubData","deleteBuffer","vertexBuffer","_vertexBuffer","_attributes","_layout","_vertexTotalSizeBytes","_shader","initialize","totalVertexSizeBytes","shaderAttributes","attrib","componentsPerVertex","vertAttribute","typeSize","uploadBuffer","vert","vertexAttribPointer","enableVertexAttribArray","GraphicsDiagnostics","DrawCallCount","DrawnImagesCount","LineRenderer","priority","_maxLines","_vertexIndex","_lineCount","context","_context","start","end","_isFull","flush","getTransform","finalStart","finalEnd","hasPendingDraws","drawArrays","LINES","PointRenderer","_maxPoints","_pointCount","_buffer","snapToPixel","finalPoint","POINTS","ScreenPassPainter","renderWithPostProcessor","postprocessor","getShader","getLayout","TRIANGLES","renderToScreen","numberOfQuads","useUint16","ELEMENT_ARRAY_BUFFER","totalVertices","maxUint16Index","bufferGlType","Uint16Array","Uint32Array","currentQuad","ImageRenderer","_maxImages","_maxTextures","_imageCount","_textures","pixelArtSampler","uvPadding","MAX_TEXTURE_IMAGE_UNITS","transformedFrag","_transformFragmentSource","_quads","maxTextures","newSource","texturePickerBuilder","_addImageAsTexture","maybeFiltering","getAttribute","force","textureLoader","removeAttribute","_bindTextures","_getTextureIdForImage","maybeTexture","swidth","sheight","dx","dy","dwidth","dheight","view","sw","sh","textureId","imageWidth","imageHeight","uvx0","uvy0","uvx1","uvy1","txWidth","txHeight","drawElements","RectangleRenderer","_maxRectangles","_rectangleCount","drawLine","drawRectangle","thickness","halfThick","startTop","startBottom","endTop","endBottom","stroke","strokeThickness","CircleRenderer","_maxCircles","_circleCount","radius","builder","recycler","maxObjects","totalAllocations","objects","disableWarnings","preallocate","using","done","borrow","poolIndex","DrawCall","defaultVertexSource","_initialized","_images","graphicsContext","images","_name","_vertexSource","_fragmentSource","_graphicsContext","_initialize","addImageSource","graphicsContextWebGL","__gl","_maxTextureSlots","isUsingScreenTexture","update","textureUniformName","removeImageSource","textureName","_loadImageSource","imageElement","uploadAndBind","startingTextureSlot","textureSlot","entries","MaterialRenderer","vertexIndex","topLeftScreen","bottomRightScreen","screenUVX0","screenUVY0","screenUVX1","screenUVY1","performance","materialScreenTexture","ExcaliburGraphicsContextWebGLDebug","_webglCtx","_debugText","rectOptions","lineOptions","drawPoint","pointOptions","drawText","_state","_ortho","checkIfResolutionSupported","dim","supported","_renderers","_isDrawLifecycle","useDrawSorting","_drawCallPool","instance","renderer","_drawCalls","_postProcessTargets","_postprocessors","_transform","smoothing","backgroundColor","multiSampleAntialiasing","_disposed","_totalPostProcessorTime","canvasElement","enableTransparency","antialiasing","powerPreference","premultipliedAlpha","alpha","depth","_init","values","clearColor","BLEND","blendEquation","FUNC_ADD","blendFunc","ONE","ONE_MINUS_SRC_ALPHA","blendEquationSeparate","blendFuncSeparate","REPEAT","_screenRenderer","_renderTarget","_msaaTarget","rendererName","_isCurrentRenderer","_currentRenderer","beginDrawLifecycle","endDrawLifecycle","drawCall","resetTransform","updateViewport","trace","drawCircle","addPostProcessor","removePostProcessor","clearPostProcessors","updatePostProcessors","delta","find","u","onUpdate","createMaterial","currentTarget","originalSort","firstIndex","findIndex","dc","originalSortOrder","oldTransform","oldState","currentRendererName","currentRenderer","ExcaliburGraphicsContext2DCanvasDebug","_ex","__ctx","strokeStyle","strokeRect","beginPath","moveTo","lineTo","lineWidth","closePath","arc","fill","imageSmoothingEnabled","_resolution","globalAlpha","fillRect","setTransform","_postprocessor","SVGA","Standard","Atari2600","GameBoy","GameBoyAdvance","NintendoDS","NES","SNES","ScreenResize","PixelRatioChange","FullScreenChange","_antialiasing","_canvasImageRendering","_resolutionStack","_viewportStack","_pixelRatioOverride","_isFullScreen","_isDisposed","_fullscreenChangeHandler","fullscreen","isFullScreen","_pixelRatioChangeHandler","_listenForPixelRatio","_devicePixelRatio","_calculateDevicePixelRatio","applyResolutionAndViewport","pixelRatio","_resizeHandler","parent","_setResolutionAndViewportByDisplayMode","_contentArea","_unsafeArea","_contentResolution","_displayMode","displayMode","Fixed","_canvas","canvasImageRendering","_browser","browser","_applyDisplayMode","_mediaQueryList","removeListener","nativeComponent","matchMedia","addListener","_resizeObserver","disconnect","removeEventListener","pixelRatioOverride","isHiDpi","FillContainer","FitContainer","FitContainerAndFill","FitContainerAndZoom","parentElement","_viewport","aspectRatio","scaledWidth","scaledHeight","setCurrentCamera","camera","_camera","pushResolutionAndViewport","peekViewport","peekResolution","popResolutionAndViewport","imageRendering","isSmooth","goFullScreen","elementId","maybeElement","getElementById","requestFullscreen","exitFullScreen","exitFullscreen","pageToScreenCoordinates","newX","newY","innerWidth","innerHeight","screenHeight","screenWidth","contentArea","screenMarginY","screenMarginX","screenToWorldCoordinates","worldToScreenCoordinates","pageToWorldCoordinates","worldToPageCoordinates","getWorldBounds","zoom","getScreenBounds","canvasWidth","halfCanvasWidth","canvasHeight","halfCanvasHeight","drawWidth","halfDrawWidth","drawHeight","halfDrawHeight","unsafeArea","_computeFit","overflow","aspect","adjustedWidth","adjustedHeight","_computeFitScreenAndFill","vw","vh","_computeFitAndFill","_computeFitContainerAndFill","clientWidth","clientHeight","clip","_computeFitScreenAndZoom","_computeFitAndZoom","_computeFitContainerAndZoom","maxScaleFactor","zoomedWidth","zoomedHeight","_computeFitContainer","Window","ResizeObserver","observe","FillScreen","FitScreen","FitScreenAndFill","FitScreenAndZoom","create","unlock","_UNLOCKED","unlockTimeoutTimer","resume","createBufferSource","ended","connect","destination","onended","playbackState","PLAYING_STATE","FINISHED_STATE","currentTime","clearTimeout","isUnlocked","lineCap","quality","_smoothing","flagDirty","_lineWidth","_lineDash","_padding","strokeColor","lineDash","padding","_bitmap","bitmapWidth","bitmapHeight","maybeCtx","cloneRasterOptions","dirty","_getTotalWidth","_originalWidth","_getTotalHeight","_originalHeight","_strokeColor","rasterize","_applyRasterProperties","execute","setLineDash","getLineDash","cache","any","json","arraybuffer","states","currentState","machineDescription","machine","stateName","transitionState","transitions","startState","in","go","eventData","potentialNewState","onExit","canExit","onEnter","canEnter","onState","elapsedMs","saveKey","localStorage","setItem","parse","getItem","_createNewBufferSource","_instance","_audioContext","loop","playbackRate","_playbackRate","_volumeNode","_handleEnd","_playingFuture","_loop","volume","_volume","_stateMachine","gain","setTargetAtTime","duration","_duration","getTotalPlaybackDuration","createGain","PLAYING","pausedAt","startedAt","_playStarted","stop","SEEK","STOPPED","PAUSED","isPlaying","isPaused","isStopped","play","playStarted","seek","getPlaybackPosition","_bubbles","bubbles","stopPropagation","prevStats","stats","gamepad","button","axis","actor","contact","lastContact","action","_value","_path","_val","propagate","layPath","_actor","track","_processedData","VolumeChange","Processed","Pause","Stop","PlaybackEnd","Resume","PlaybackStart","_tracks","instances","paths","_isStopped","_wasPlayingOnHidden","canPlayFile","file","Audio","canPlayType","audiobuffer","decodeAudio","wireEngine","_engine","pauseAudioWhenHidden","instanceCount","some","_resumePlayback","_startPlayback","trackId","_getTrackInstance","getTrackId","resumed","complete","newTrack","BeforeLoad","AfterLoad","UserAction","LoadResourceStart","LoadResourceEnd","resources","_resources","onDraw","_numLoaded","_totalTimeMs","_loadingFuture","loadables","addResources","onInitialize","onUserAction","onBeforeLoad","onAfterLoad","addResource","loadable","markResourceComplete","progress","total","elapsedMilliseconds","seconds","speed","font","textbox","actualBoundingBoxLeft","actualBoundingBoxRight","actualBoundingBoxAscent","actualBoundingBoxDescent","areResourcesLoaded","resource","finally","x1","y1","x2","y2","cap","br","tl","tr","bl","defaultRadius","quadraticCurveTo","Director_Loader","_image","_imageElement","logo","playButtonRootElement","_playButtonRootElement","playButtonElement","_playButtonElement","_playButton","existingRoot","_styleBlock","textContent","_playButtonStyles","head","startButtonFactory","loadablesOrOptions","isArray","_originalOptions","_playButtonShown","logoWidth","logoHeight","loadingBarColor","suppressPlayButton","playButtonText","buttonElement","display","_configuredPixelRatio","_DEFAULT_LOADER_OPTIONS","showPlayButton","hidePlayButton","resizeHandler","_positionPlayButton","evt","click","playButtonClicked","startButtonHandler","fullscreenAfterLoad","fullscreenContainer","HTMLElement","removeChild","decode","offsetLeft","offsetTop","buttonWidth","buttonHeight","playButtonPosition","logoY","logoX","logoPosition","oldAntialias","getAntialiasing","setAntialiasing","loadingX","loadingY","loadingBarPosition","progressWidth","REPORTED_FEATURES","webgl","webaudio","gamepadapi","_features","failedTests","_criticalTests","canvasSupport","elem","arrayBufferSupport","xhr","dataUrlSupport","toDataURL","objectUrlSupport","rgbaSupport","cssText","_warningTest","webAudioSupport","webglSupport","_loadBrowserFeatures","getBrowserFeatures","logBrowserFeatures","msg","dataurl","objecturl","rgba","getGamepads","failedCritical","warning","_getX","getX","_getY","getY","_setX","setX","_setY","setY","WatchVector","original","_parent","_children","_isDirty","_isInverseDirty","_matrix","_inverse","children","globalPos","localPos","canonRotation","globalRotation","inverseRotation","globalScale","inverseScale","globalScaleX","globalScaleY","_calculateMatrix","applyInverse","owner","newComponent","hasClone","observers","subscriptions","observer","subscribe","unregister","unsubscribe","notifyAll","observersLength","notify","subscriptionsLength","_parentComponent","_addChildTransform","child","childTxComponent","zIndexChanged$","_z","_coordPlane","onAdd","childrenAdded$","childrenRemoved$","onRemove","_previousOwner","oldz","coordPlane","component","vel","acc","scaleFactor","angularVelocity","torque","inertia","mask","_CURRENT_GROUP","_MAX_GROUPS","_GROUPS","existingGroup","group","_CURRENT_BIT","groups","groupByName","_STARTING_BIT","category","_category","_mask","canCollide","overlap1","overlap2","collisionGroups","combinedName","combinedCategory","collidesWith","combinedMask","padStart","All","colliderA","colliderB","calculatePairHash","bodyA","bodyB","collisionType","PreventCollision","active","collide","hasCollider","collider","idA","idB","projection","getOverlap","isLeaf","_config","worldBounds","root","nodes","_insert","leaf","leafAABB","currentRoot","oldArea","area","combinedArea","combinedAABB","cost","inheritanceCost","leftCost","leftCombined","newArea","rightCost","rightCombined","oldParent","newParent","currentNode","_balance","_remove","sibling","grandParent","trackCollider","node","updateCollider","untrackCollider","boundsPadding","multdx","velocityMultiplier","multdy","balance","getHeight","helper","rayCastQuery","getNodes","numerator","begin","getSlope","divisor","getLength","intersectPoint","time","getPoint","_pairs","_collisionPairCache","_colliders","_dynamicCollisionTree","dynamicTree","getColliders","maxDistance","collisionGroup","collisionMask","searchAllColliders","maybeBody","ignoreCollisionGroupAll","hit","untrack","_pairExists","hash","broadphase","targets","potentialColliders","pair","physics","pairs","continuous","checkForFastBodies","Active","updateDistance","minDimension","disableMinimumSpeedForFastBody","minCollider","fastBodies","updateVec","oldPos","centerPoint","furthestPoint","getFurthestPoint","surfaceEpsilon","minTranslate","shift","fastBodyCollisions","narrowphase","contacts","newContacts","collisions","updated","composite","touching","gravity","useArcadePhysics","collisionResolutionStrategy","Arcade","useRealisticPhysics","Realistic","enabled","broadphaseStrategy","DynamicAABBTree","defaultMass","integrator","Euler","dynamicTreeVelocityMultiplier","positionIterations","velocityIterations","slop","steeringFactor","warmStart","bodiesCanSleepByDefault","sleepEpsilon","wakeThreshold","sleepBias","solver","colliders","compositeStrategy","bodies","canSleepByDefault","arcade","contactSolveBias","realistic","_compositeStrategy","_collisionProcessor","_dynamicAABBTree","addCollider","clearColliders","removeCollider","worldPos","axes","furthestPoints","bestPoint","getInertia","mass","totalInertia","otherColliders","potentialCollider","getClosestLineBetween","maybeLine","minLength","minLine","hits","minHit","minDistance","project","projections","proj","newProjection","slope","intercept","_normal","_dir","_slope","getEdge","_length","midpoint","flip","below","above2","sideVector","distanceToPoint","signed","x0","y0","findVectorToPoint","aMinusP","findPoint","hasPoint","currPoint","threshold","dxc","dyc","dx1","dy1","p0","q0","w0","denom","sDenom","tDenom","sClosest","tClosest","PolygonPolygonClosestLine","polygonA","polygonB","otherWorldPos","otherDirection","thisDirection","rayTowardsOther","rayTowardsThis","thisPoint","otherPoint","thisFace","getClosestFace","otherFace","face","PolygonEdgeClosestLine","polygon","edge","edgeLine","asLine","PolygonCircleClosestLine","circlex","circley","CircleCircleClosestLine","circleA","circleB","thisWorldPos","CircleEdgeClosestLine","circleWorldPos","edgeStart","edgeVector","EdgeEdgeClosestLine","edgeA","edgeB","edgeLineA","edgeStartA","edgeVectorA","edgeLineB","_globalMatrix","_naturalRadius","orig","discriminant","toi","toi1","toi2","positiveToi","minToi","shape","CollideCircleCircle","CollideCirclePolygon","CollideCircleEdge","getFurthestLocalPoint","globalMat","scalars","dotProduct","mtv","tangent","localPoints","_canceled","colliderAId","colliderBId","matchAwake","sleeping","sleepMotion","setSleeping","isCanceled","cancel","SeparatingAxis","findPolygonPolygonSeparation","polyA","polyB","bestSeparation","bestSide","bestAxis","bestSideIndex","bestOtherPoint","sides","getSides","localSides","getLocalSides","vertB","vertSeparation","separation","localSide","sideId","localPoint","findCirclePolygonSeparation","polyDir","pc","closestPointOnPoly","minOverlap","minAxis","minIndex","proj1","proj2","overlap","circleAPos","circleBPos","combinedRadius","mvt","local","samedir","xf","findSide","findLocalSide","cc","edgeWorld","asLocalLine","da","dda","db","ddb","den","pointOnEdge","dd","CollideEdgeEdge","CollidePolygonEdge","ec","linePoly","CollidePolygonPolygon","separationA","separationB","incident","reference","refDir","clipRight","clipLeft","FindContactSeparation","shapeA","txA","shapeB","txB","worldPoint","circlePoint","dist","_getTransformedBegin","_getTransformedEnd","transformedBegin","transformedEnd","_boundsFromBeginEnd","edgeNormal","registerGraphicsContext","debugDrawCall","drawLines","drawPolygon","firstPoint","drawBounds","boundingBox","drawRay","_localBoundsDirty","_localSidesDirty","_transformedPointsDirty","_sidesDirty","_transformedPoints","_sides","_localSides","_isCounterClockwiseWinding","reverse","isConvex","suppressConvexWarning","_calculateTransformation","sum","oldPoint","newPoint","oldDirection","orientation","angleSum","tessellate","polygons","triangulate","triangles","vertices","vertexCount","getPrevIndex","getNextIndex","prev","va","vb","vc","leftArm","rightArm","convexVertices","cutEarTip","findEarTip","isEar","isPointInTriangle","ab","bc","ca","ap","bp","cp","cross1","cross2","cross3","getTransformedPoints","currentSide","mostDirection","sideNormal","testRay","intersectCount","accum","pts","POSITIVE_INFINITY","faceIndex","_localBounds","_cachedMass","_cachedInertia","denominator","iplusone","crossTerm","contactSide","minContactTime","contactIndex","contactTime","scalar","Box","Edge","Capsule","$colliderAdded","$colliderRemoved","_collidersToRemove","_collider","processColliderRemoval","flipped","entity","precollision","onPreCollisionResolve","postcollision","onPostCollisionResolve","onCollisionStart","onCollisionEnd","useBoxCollider","usePolygonCollider","poly","useCircleCollider","useEdgeCollider","useCompositeCollider","dependencies","__oldTransformCaptured","enableFixedUpdateInterpolate","_sleeping","bounciness","friction","useGravity","limitDegreeOfFreedom","oldVel","oldAcc","_bodyConfig","config","updatePhysicsConfig","_mass","_DEFAULT_CONFIG","canSleep","updateDefaultPhysicsConfig","newMass","_cachedInverseInertia","inverseMass","updateMotion","currentMotion","bias","maybeCollider","inverseInertia","motion","oldRotation","oldScale","applyImpulse","impulse","finalImpulse","X","Y","Rotation","distanceFromCenter","applyLinearImpulse","applyAngularImpulse","captureOldTransform","Initialize","PreUpdate","PostUpdate","Kill","componentsOrOptions","componentsToAdd","nameToAdd","_tags","componentAdded$","componentRemoved$","tagAdded$","tagRemoved$","components","_componentsToRemove","_instanceOfComponentCacheDirty","_instanceOfComponentCache","scene","_isInitialized","addComponent","kill","unparent","isKilled","tags","hasTag","addTag","removeTag","types","getComponents","hasAll","requiredTypes","hasAllTags","requiredTags","_getCachedInstanceOfType","maybeComponent","addChild","getAncestors","removeAllChildren","getDescendants","queue","curr","newEntity","componentInstance","addTemplate","templateEntity","removeComponent","ctor","typeOrInstance","componentToRemove","clearComponents","processComponentRemoval","isInitialized","_preupdate","onPreUpdate","_postupdate","onPostUpdate","graphic","tick","_offset","recalculateBounds","_anchor","_current","_graphics","visible","copyGraphics","graphics","onPreDraw","onPostDraw","onPreTransformDraw","onPostTransformDraw","graphicOrOptions","getGraphic","getOptions","getNames","currentOptions","nameOrGraphic","optionsToSet","graphicToSet","remove","hide","offsetX","offsetY","elapsed","idempotencyToken","_radius","useColliderShape","useGraphicsBounds","CreateReversibleEasingFunction","easing","CreateVectorEasingFunction","Linear","startValue","endValue","EaseInQuad","EaseOutQuad","EaseInOutQuad","EaseInCubic","EaseOutCubic","EaseInOutCubic","_actions","_currentAction","_completedActions","_entity","clearActions","getActions","hasNext","isComplete","repeatBuilder","repeat","_stopped","_repeatBuilder","_repeatContext","_actionQueue","getQueue","_repeat","_originalRepeat","_started","_tx","_motion","_speed","_delta","_start","_end","_distance","destx","desty","rotationType","_rotationType","ShortestPath","_currentNonCannonAngle","distance1","distance2","_shortDistance","_longDistance","_shortestPathIsPositive","_direction","LongestPath","Clockwise","CounterClockwise","distanceTraveled","angleRadiansOffset","scaleX","scaleY","speedX","speedY","_endX","_endY","_speedX","_speedY","_startX","_startY","_distanceX","_distanceY","directionX","directionY","scaleOffsetX","scaleOffsetY","_startScale","_endScale","_directionX","_directionY","CallMethod","_method","_hasBeenCalled","easingFcn","_currentLerpTime","_lerpDuration","_lerpStart","_lerpEnd","timeVisible","timeNotVisible","numBlinks","_timeVisible","_timeNotVisible","_elapsedTime","_totalTime","endOpacity","_multiplier","_endOpacity","_ogspeed","_delay","entityToFollow","followDistance","_followTx","_followMotion","_maximumDistance","_distanceBetween","actorToFollowSpeed","actorToMeet","_speedWasSpecified","_meetTx","_meetMotion","actorToMeetSpeed","_queue","runAction","easeTo","easeBy","xOrPos","yOrSpeed","speedOrUndefined","moveBy","xOffsetOrVector","yOffsetOrSpeed","xOffset","yOffset","rotateTo","rotateBy","scaleTo","sizeXOrVector","sizeYOrSpeed","speedXOrUndefined","speedYOrUndefined","sizeX","sizeY","scaleBy","sizeOffsetXOrVector","sizeOffsetYOrSpeed","sizeOffsetX","sizeOffsetY","blink","fade","die","callMethod","times","repeatForever","follow","meet","toPromise","_getCtx","FontTextInstance","_textFragments","disposed","_setDimension","_lastHashCode","getHashCode","_applyFont","metrics","textHeight","lineAdjustedHeight","bottomBounds","textBounds","lineHeightRatio","fontString","textAlign","baseAlign","includeColor","textBaseline","shadowColor","shadowBlur","blur","shadowOffsetX","shadowOffsetY","_drawText","strokeText","_splitTextBitmap","textImages","currentX","currentY","hashCode","frag","_MEASURE_CACHE","measurement","measureTextWithoutCache","getTextInstance","textInstance","_TEXT_CACHE","_TEXT_USAGE","checkAndClearCache","deferred","currentHashCodes","FONT_TIMEOUT","newTextMeasurementCache","cacheSize","clearCache","_o","_p","_q","_r","_v","family","Normal","bold","unit","Px","LeftToRight","_textBounds","_textMeasurement","colorOverride","_textWidth","_textHeight","_calculateDimension","_font","thePos","theVel","theAcc","theAngle","_handleAnchorChange","_handleOffsetChange","isOffScreen","draggable","_draggable","isDraggable","_pointerDragStartHandler","_pointerDragEndHandler","_pointerDragMoveHandler","_pointerDragLeaveHandler","currentGraphic","_dragging","pe","defaults","pointer","actions","Passive","builtInComponents","_prekill","onPreKill","_postkill","onPostKill","unkill","newZ","getGlobalPos","localCenter","getGlobalScale","getGlobalRotation","recurse","geom","containment","within","otherCollider","me","self1","useWorld","coords","_complete","fcn","interval","repeats","numberOfRepeats","randomRange","_totalTimeAlive","_running","_numberOfTicks","maxNumberOfRepeats","_baseInterval","_generateRandomInterval","_MAX_ID","_callbacks","newInterval","newNumberOfRepeats","timesRepeated","getTimeRunning","timeToNextAction","timeElapsedTowardNextAction","isRunning","cancelTimer","parallaxFactor","useTransform","PreDraw","PostDraw","flagCollidersDirty","_collidersDirty","flagTilesDirty","tiles","_token","_rows","_cols","renderFromTopOfGraphic","meshingLookBehind","_originalOffsets","debugFlags","_composite","_oldPos","_oldScale","tileWidth","tileHeight","currentCol","tile","_getOrSetColliderOriginalOffset","originalOffset","_updateColliders","shareEdges","checkAndCombine","maxLookBack","solid","defaultGeometry","getTileByIndex","getTile","getTileByPoint","_getTileCoordinates","getRows","getColumns","getOnScreenTiles","maybeParallax","oneMinusFactor","parallaxOffset","currentScene","tileStartX","tileStartY","tileEndX","tileEndY","_oldRotation","graphicsIndex","graphicsLen","offsets","getGraphicsOffsets","getGraphics","gfx","showAll","showGrid","gridColor","gridWidth","showSolidBounds","showColliderBounds","solidBoundsColor","colliderBoundsColor","showColliderGeometry","tilemap","geometryColor","geometryLineWidth","geometryPointSize","pointSize","_posDirty","_recalculate","_solid","_offsets","addGraphic","removeGraphic","clearGraphics","geometryPos","_geometry","_bounds","lockToActor","addStrategy","lockToActorAxis","elasticToActor","cameraElasticity","cameraFriction","radiusAroundActor","limitCameraBounds","box","cam","_eng","currentFocus","getFocus","focus","cameraVel","stretch","boundSizeChecked","focusX","focusY","_cameraStrategies","strategy","dz","az","_angularVelocity","_posChanged","drawPos","_cameraMoving","_isShaking","_shakeMagnitudeX","_shakeMagnitudeY","_shakeDuration","_elapsedShakeTime","_xShake","_yShake","_isZooming","_zoomStart","_zoomEnd","_currentZoomTime","_zoomDuration","_zoomEasing","_easing","_halfWidth","_halfHeight","_snapPos","_follow","ax","ay","move","easingFn","_lerpPromise","_lerpResolve","shake","magnitudeX","magnitudeY","zoomOverTime","_zoomPromise","_zoomResolve","cameraStrategy","removeStrategy","clearAllStrategies","_screen","currentRes","loadingComplete","res","updateTransform","runStrategies","newZoom","zoomEasing","lerpPoint","moveEasing","_isDoneShaking","fixedUpdateFps","blend","currentFrameLagMs","interpolatedPos","snapPos","newCanvasWidth","newCanvasHeight","cameraPos","ExitTrigger","EnterTrigger","triggerDefaults","opts","_dispatchAction","_target","Highest","Higher","Average","Lower","Lowest","_world","entities","_entityIndex","_entitiesToRemove","updateEntities","removeEntity","findEntitiesForRemoval","addEntity","queryManager","idOrEntity","currFrame","actors","killed","processEntityRemovals","processComponentRemovals","getById","getByName","requiredComponents","entityAdded$","entityRemoved$","checkAndAdd","getEntities","_queries","_addComponentHandlers","_removeComponentHandlers","_componentToQueriesIndex","_tagQueries","_addTagHandlers","_removeTagHandlers","_tagToQueriesIndex","_createAddComponentHandler","_createRemoveComponentHandler","_createAddTagHandler","_createRemoveTagHandler","createQuery","queries","createTagQuery","maybeAddComponent","maybeRemoveComponent","maybeAddTag","maybeRemoveTag","tagQuery","systems","initialized","systemType","addSystem","systemOrCtor","system","removeSystem","updateSystems","preupdate","postupdate","entityManager","systemManager","queryTags","Update","entityOrSystem","clearEntities","clearSystems","EulerIntegrator","integrate","totalAcc","_ACC","_VEL","_POS","_VEL_ACC","_SCALE_FACTOR","_SCALE","world","_physicsConfigDirty","$configUpdate","optionalBody","directionMap","distanceMap","solve","preSolve","aDir","bDir","aDist","bDist","solvePosition","solveVelocity","postSolve","opposite","velAdj","normalImpulse","tangentImpulse","normalMass","tangentMass","aToContact","bToContact","originalVelocityAndRestitution","aToContactNormal","bToContactNormal","aToContactTangent","bToContactTangent","getRelativeVelocity","velA","velB","lastFrameContacts","idToContactConstraint","getContactConstraints","finishedContactIds","contactPoints","pointIndex","restitution","relativeVelocity","steeringForce","steeringConstant","impulseForce","constraints","impulseDelta","tangentVelocity","maxFriction","newImpulse","normalVelocity","_processor","_physics","collisionProcessor","_configDirty","_lastFrameContacts","_currentFrameContacts","_arcadeSolver","_realisticSolver","_trackCollider","_untrackCollider","colliderComponent","colliderComp","compositeColliders","getSolver","compositeId","substring","runContactStartEnd","Frame","Loop","End","frames","frameDuration","_idempotencyToken","_firstTick","_currentFrame","_timeLeftInFrame","_pingPongDirection","_done","_playing","_reversed","totalDuration","goToFrame","maybeFrame","currentFrame","fromSpriteSheet","frameIndices","durationPerFrameMs","invalidIndices","fromSpriteSheetCoordinates","frameCoordinates","defaultDuration","coord","currentFrameIndex","currentFrameTimeLeft","reversed","Backward","Forward","canFinish","Freeze","frameNumber","frameIndex","_nextFrame","PingPong","members","_updateDimensions","member","useBounds","shouldUseBounds","_isAnimationOrGroup","base","assign","props","ParticleImpl","emitterOrConfig","life","beginColor","endColor","velocity","acceleration","startSize","endSize","particleSprite","particleRotationalVelocity","currentRotation","focusAccel","fadeFlag","_rRate","_gRate","_bRate","_aRate","_currentColor","particleSize","sizeRate","elapsedMultiplier","isOffscreen","particleTransform","Global","tmpColor","removeParticle","accel","_sprite","_particlesToEmit","numParticles","isEmitting","particles","deadParticles","minVel","maxVel","minAngle","maxAngle","emitRate","particleLife","minSize","maxSize","emitterType","randomRotation","particle","emitParticles","particleCount","_createParticle","clearParticles","ranX","ranY","sortedTransforms","_sortedTransforms","Draw","_zHasChanged","_zIndexUpdate","_targetInterpolationTransform","parallax","_applyTransform","particleOpacity","_drawGraphicsComponent","graphicsComponent","transformComponent","oldFlipHorizontal","oldFlipVertical","isDebug","showBounds","boundsColor","ancestor","blendTransform","oldTx","newTx","oldTxWithNewParent","oldGlobalPos","oldGlobalScale","oldGlobalRotation","interpolatedScale","interpolatedRotation","_collisionSystem","debugDraw","filterSettings","entitySettings","txSettings","motionSettings","colliderSettings","physicsSettings","graphicsSettings","bodySettings","cameraSettings","useFilter","allIds","ids","allNames","nameQuery","cursor","_pushCameraTransform","debugZIndex","showPosition","positionColor","showPositionLabel","showZIndex","showId","showName","showRotation","rotationColor","showScale","scaleColor","showCollisionGroup","showCollisionType","showMass","showMotion","showSleeping","showVelocity","velocityColor","showAcceleration","accelerationColor","showGeometry","showOwner","_popCameraTransform","showBroadphaseSpacePartitionDebug","showCollisionContacts","showCollisionNormals","contactSize","collisionContactColor","collisionNormalColor","showFocus","focusColor","showZoom","overrideUseColliderShape","overrideUseGraphicsBounds","lastFrameEntityToPointers","currentFrameEntityToPointers","_sortedEntities","_scene","_receivers","pointers","_engineReceiver","entityCurrentlyUnderPointer","pointerId","entityWasUnderPointer","entered","addPointerToEntity","_processPointerToEntity","_dispatchEvents","receiver","currentFramePointerCoords","screenPos","graphicBounds","_processDownAndEmit","lastDownPerPointer","currentFrameDown","isDragStart","_processUpAndEmit","lastUpPerPointer","currentFrameUp","isDragEnd","_processMoveAndEmit","lastMovePerPointer","currentFrameMove","isDragging","_processEnterLeaveAndEmit","lastUpDownMoveEvents","_processCancelAndEmit","currentFrameCancel","_processWheelAndEmit","currentFrameWheel","lastFrameEntities","currentFrameEntities","mapOrOptions","elevation","iso","maxZindexPerElevation","_worldBounds","entityOffscreen","_isOffscreen","transformedBounds","newConfig","_gamePadTimeStamps","_oldPads","_pads","_initSuccess","_navigator","_minimumConfiguration","_enabled","_clonePads","toggleEnabled","setMinimumGamepadConfiguration","_enableAndUpdate","_isGamepadValid","pad","axesLength","buttonLength","buttons","connected","gamepads","bi","ai","at","timestamp","navigatorGamepad","getButton","pressed","updateButton","getAxes","updateAxes","_clonePad","getValidGamepads","pads","arr","clonedPad","MinAxisMoveThreshold","_axes","_buttons","_buttonsUp","_buttonsDown","isButtonPressed","isButtonHeld","wasButtonPressed","wasButtonReleased","Boolean","buttonIndex","axesIndex","inputs","_handlers","command","inputHandler","commandHandler","isCrossOriginIframe","noop","originalEvent","_keys","_keysUp","_keysDown","_releaseAllKeys","ev","keyEvent","_handleKeyDown","metaKey","MetaLeft","MetaRight","_handleKeyUp","keyboardOptions","grabWindowFocus","getKeys","wasPressed","isHeld","wasReleased","triggerEvent","character","KeyboardEvent","fromPagePosition","yOrEngine","engineOrUndefined","coordinates","pointerType","nativeEvent","pageX","pageY","screenX","screenY","deltaZ","deltaMode","lastPagePos","lastScreenPos","lastWorldPos","_onPointerMove","_onPointerDown","primary","_activeNativePointerIdsToNormalized","lastFramePointerCoords","currentFramePointerDown","lastFramePointerDown","_pointers","_boundHandle","_handle","_boundWheel","_handleWheel","recreate","eventReceiver","isDown","wasDown","native","touchAction","wheelOptions","passive","pageScrollPreventionMode","onmousewheel","grabFocus","detach","_normalizePointerId","nativePointerId","currentPointerIds","preventDefault","eventCoords","TouchEvent","Unknown","Touch","changedTouches","touch","_nativeButtonToPointerButton","Mouse","_stringToPointerType","ScrollWheelNormalizationFactor","wheelDeltaX","wheelDeltaY","wheelDelta","detail","Page","we","page","clientX","clientY","MouseEvent","pointerSystem","NoButton","Middle","Pen","pointerTarget","keyboard","inputMapper","Activate","Deactivate","PreDebugDraw","PostDebugDraw","PreLoad","triggers","tileMaps","timers","_timers","_cancelQueue","onPreLoad","loader","onTransition","onActivate","onDeactivate","_initializeChildren","pointerScope","director","getSceneName","_activate","_deactivate","_predraw","_postdraw","removeTimer","timer","_collectActorStats","addTimer","transfer","isTimerActive","isCurrentScene","_ui","ui","alive","_colorBlindnessMode","simulate","_simulate","colorBlindnessMode","colorBlindMode","Protanope","Deuteranope","Tritanope","_colorBlindPostProcessor","correct","colorBlindness","prevFrame","isometric","positionSize","useTestClock","wasRunning","testClock","toTestClock","useStandardClock","currentClock","standardClock","toStandardClock","_id","_fps","_actorStats","remaining","_durationStats","_physicsStats","_graphicsStats","drawCalls","drawnImages","otherStats","fps","fs","_collisions","_contacts","_fastBodies","_fastBodyCollisions","_broadphase","_narrowphase","ps","_nativeHandlers","_decorate","_windowGlobal","_documentGlobal","_windowComponent","_documentComponent","nativeContextAntialiasing","_samplePeriod","_currentFrameTime","_frames","_previousSampleTime","_beginFrameTime","initialFps","samplePeriod","_nowFn","nowFn","instant","_onFatalException","_maxFps","_lastTime","_elapsed","_scheduledCbs","_totalElapsed","maxFps","onFatalException","fpsSampler","defaultUpdateMs","setFatalExceptionHandler","cb","timeoutMs","scheduledTime","_runScheduledCbs","overrideUpdateMs","fpsInterval","leftover","mainloop","_requestId","_currentTime","_updateMs","step","run","numberOfSteps","Util_Toaster","_toasterCss","_container","_createFragment","toastMessage","innerText","toast","linkTarget","linkName","className","messageFragments","link","href","finalMessage","dismissBtn","keydownHandler","first","firstChild","insertBefore","NavigationStart","Navigation","NavigationEnd","isTransitioning","_isTransitioning","scenes","sceneKey","_sceneToInstance","_sceneToLoader","_sceneToTransition","_loadedScenes","rootScene","currentSceneName","sceneOrOptions","getSceneInstance","_deferredGoto","deferredScene","deferredTransition","_deferredTransition","swapScene","playTransition","configureStart","startScene","maybeStartTransition","maybeLoaderOrCtor","mainLoader","inTransition","_getLoader","sceneName","_getInTransition","sceneOrRoute","_getOutTransition","out","getDeferredScene","maybeDeferred","getSceneDefinition","maybeScene","sceneInstance","assertAdded","assertRemoved","outTransition","nameOrScene","potentialSceneOrOptions","goto","destinationScene","maybeDest","sourceScene","engineInputEnabled","maybeSourceOut","maybeDestinationIn","sourceOut","destinationIn","sceneActivationData","hideLoader","maybeLoadScene","_emitEvent","onPreviousSceneDeactivate","sceneDefinition","newScene","sceneToLoad","sceneToLoadInstance","transition","currentTransition","sceneInputEnabled","blockInput","previousScene","nextScene","destLoader","sourceName","destinationName","FallbackGraphicsContext","Visible","Hidden","Start","PreFrame","PostFrame","isFullscreen","_isDebug","shouldSnapToPixel","_inputEnabled","_suppressPlayButton","enableCanvasTransparency","stack","_toaster","_timescale","_performanceThresholdTriggered","_fpsSamples","_isLoading","_hideLoader","_isReadyFuture","currentFrameElapsedMs","_lagMs","_screenShotRequests","_DEFAULT_ENGINE_OPTIONS","detector","suppressMinimumBrowserFeatureDetection","_compatible","testMessage","canvasElementId","suppressConsoleBootMessage","_originalDisplayMode","pixelArt","suppressHiDPIScaling","_mainloop","___EXCALIBUR_DEVTOOL","_monitorPerformanceThresholdAndTriggerFallback","allow","configurePerformanceCanvas2DFallback","showPlayerMessage","numberOfFrames","useCanvas2DFallback","newCanvas","cloneNode","parentNode","replaceChild","Document","timescale","addScene","removeScene","goToScene","scrollPreventionMode","visibilityState","toggleInputEnabled","_overrideInitialize","_update","_loader","_draw","_checkForScreenShots","toggle","toggleDebug","isReady","sceneNameOrLoader","frameId","beforeUpdate","fixedTimestepMs","afterUpdate","afterDraw","screenshot","preserveHiDPIResolution","finalWidth","finalHeight","raw","_wiredEventDispatchers","_deferedHandlerRemovals","_processDeferredHandlerRemovals","eventHandler","_removeHandler","eventHandlers","metaHandler","wire","eventDispatcher","unwire","newFont","spriteFont","sf","getTextWidth","_gfx","_recalculateBounds","_tileBounds","graphicsOffset","tileToWorld","_isometricEntityComponent","halfTileWidth","halfTileHeight","yPos","totalWidth","totalHeight","updateColliders","worldToTile","worldCoordinate","tileCoordinate","tileCoord","_getMaxZIndex","maxZ","NEGATIVE_INFINITY","currentZ","actionBuilder","_sequenceBuilder","_sequenceContext","parallelActions","every","_defaultOptions","maxDepth","capacity","_isDivided","halfWidth","halfHeight","_split","newLevelOptions","_insertIntoSubNodes","insert","getAllItems","getTreeDepth","_stream","_gif","_animation","_transparentColor","toSpriteSheet","toAnimation","readCheckBytes","checkBytes","bitsToNum","ba","byteToBitArr","bite","dataArray","readByte","byteLength","readBytes","bytes","read","readUnsigned","Uint8Array","lzwDecode","minCodeSize","last","output","clearCode","eoiCode","codeSize","dict","readCode","charCodeAt","stream","_st","_handler","globalColorTable","parseColorTable","ct","rgb","readSubBlocks","parseHeader","hdr","sig","ver","colorRes","globalColorTableSize","gctFlag","sorted","bgColor","pixelAspectRatio","bits","parseExt","block","label","extType","parseGCExt","reserved","disposalMethod","userInput","transparencyGiven","delayTime","transparencyIndex","terminator","gce","parseComExt","comment","com","parsePTExt","ptHeader","ptData","pte","parseAppExt","identifier","authCode","parseNetscapeExt","unknown","iterations","app","NETSCAPE","parseUnknownAppExt","appData","parseUnknownExt","parseImg","img","leftPos","topPos","lctFlag","interlaced","lctSize","lct","lzwMinCodeSize","lzwData","pixels","deinterlace","newPixels","cpRow","toRow","fromRow","fromPixels","steps","pass","arrayToImage","parseBlock","sentinel","eof","frame","_isLoaded","FontFace","fonts","toFont","coroutineGenerator","generator","_currentProgress","_completeFuture","started","_currentDistance","updateTransition","onStart","onEnd","onReset","targetScene","screenCover","_progress","_calculateBounds","lineNormal","halfThickness","minPoint","obsoleteMessage","logMessage","suppressObsoleteMessages","showStackTrace","alternateMethod","property","SyntaxError","methodSignature","AsyncWaitQueue","enqueue","dequeue","_count","_waitQueue","waiting","enter","exit","$3MXpL","$f82d5511d53990a3$exports","compare","compareVersions","satisfies","validate","validateStrict","trim","EntityLayer","ldtkLayer","order","ldtkToEntity","entityToLdtk","ldtkLevel","worldX","worldY","__pxTotalOffsetX","__pxTotalOffsetY","entityInstances","projectMetadata","defs","__identifier","factories","px","pivotX","pivotY","__tile","tilesets","tilesetUid","w","spritesheet","runFactory","getEntitiesByIdentifier","getLdtkEntitiesByIdentifier","getEntitiesByField","getLdtkEntitiesByField","fieldInstances","__value","FetchLoader","fetch","__createBinding","__exportStar","IntGridLayer","intGridCsv","__cHei","__cWid","__gridSize","layers","intGridValues","LdtkResource","levels","levelsByName","fileLoader","_imageLoader","LoaderCache","_levelLoader","LevelResource","startZIndex","textQuality","useExcaliburWiring","useMapBackgroundColor","useTilemapCameraStrategy","headless","strict","entityIdentifierFactories","pathMap","registerEntityIdentifierFactory","LdtkProjectMetadata","supportedLdtkVersion","jsonVersion","relPath","pathRelativeToBase","getOrAdd","Tileset","ldtkTileset","externalRelPath","imageLoader","Level","getEntityLayers","getLevel","getTileLayers","TileLayer","getIntGridLayers","getLevelBounds","addToScene","useLevelOffsets","levelFilter","LdtkLevel","__bgColor","layerInstances","gridTiles","_loaded","allSettled","reason","pathInMap","mapPath","filenameFromPath","__tilesetDefUid","tileGridSize","__tilesetRelPath","pxHei","pxWid","LdtkEntityDefinition","LdtkLayerDefinition","LdtkLayerInstance","LdtkEntityInstance","tuple","nullable","__type","defUid","__grid","__pivot","__smartColor","__tags","__worldX","__worldY","iid","__opacity","union","literal","autoLayerTiles","layerDefUid","levelId","overrideTilesetUid","pxOffsetX","pxOffsetY","boolean","__bgPos","cropRect","topLeftPx","__neighbours","levelIid","bgRelPath","worldDepth","worldGridHeight","worldGridWidth","worldLayout","tileRect","iconTilesetUid","customData","tileId","embedAtlas","enumsTags","optional","enumValueId","tileIds","tagsSourceEnumUid","autoSourceLayerDefUid","displayOpacity","gridSize","groupUid","intGridValuesGroups","parallaxFactorX","parallaxFactorY","parallaxScaling","tilesetDefUid","nineSliceBorders","tileRenderMode","tilesetId","uiTileRect","enums","externalLevels","toc","instancesData","fields","heiPx","iids","widPix","worlds","ZodError","quotelessJson","ZodIssueCode","util","arrayToEnum","issues","addIssue","addIssues","setPrototypeOf","__proto__","errors","_errors","unionErrors","returnTypeError","argumentsError","jsonStringifyReplacer","isEmpty","flatten","formErrors","fieldErrors","__importDefault","getErrorMap","setErrorMap","defaultErrorMap","errorUtil","errToObj","isAsync","isDirty","isAborted","OK","DIRTY","INVALID","ParseStatus","addIssueToContext","EMPTY_PATH","makeIssue","errorMaps","issueData","defaultError","common","contextualErrorMap","schemaErrorMap","abort","mergeArray","mergeObjectAsync","mergeObjectSync","alwaysSet","getParsedType","ZodParsedType","objectUtil","assertEqual","assertIs","assertNever","getValidEnumValues","objectKeys","objectValues","isInteger","isFinite","joinValues","mergeShapes","nan","function","bigint","null","catch","date","__setModuleDefault","__importStar","invalid_type","received","expected","invalid_literal","unrecognized_keys","invalid_union","invalid_union_discriminator","invalid_enum_value","invalid_arguments","invalid_return_type","invalid_date","invalid_string","validation","startsWith","too_small","exact","inclusive","minimum","too_big","maximum","custom","invalid_intersection_types","not_multiple_of","multipleOf","not_finite","oe","coerce","ZodFirstPartyTypeKind","late","ZodSchema","Schema","ZodReadonly","ZodPipeline","ZodBranded","BRAND","ZodNaN","ZodCatch","ZodDefault","ZodNullable","ZodOptional","ZodTransformer","ZodEffects","ZodPromise","ZodNativeEnum","ZodEnum","ZodLiteral","ZodLazy","ZodFunction","ZodSet","ZodMap","ZodRecord","ZodTuple","ZodIntersection","ZodDiscriminatedUnion","ZodUnion","ZodObject","ZodArray","ZodVoid","ZodNever","ZodUnknown","ZodAny","ZodNull","ZodUndefined","ZodSymbol","ZodDate","ZodBoolean","ZodBigInt","ZodNumber","ZodString","ZodType","NEVER","void","transformer","strictObject","record","preprocess","pipeline","ostring","onumber","oboolean","never","nativeEnum","lazy","instanceof","enum","effect","discriminatedUnion","_cachedPath","_key","success","_error","errorMap","invalid_type_error","required_error","description","spa","safeParseAsync","_def","safeParse","parseAsync","refine","refinement","superRefine","nullish","or","and","brand","describe","readonly","isNullable","isOptional","_getType","_getOrReturnCtx","parsedType","_processInputParams","_parseSync","_parse","_parseAsync","async","_refinement","J","schema","Q","ee","E","A","R","te","innerType","defaultValue","ie","se","catchValue","ae","ne","checks","kind","RegExp","regex","lastIndex","toUpperCase","precision","_regex","_addCheck","email","emoji","uuid","cuid","cuid2","ulid","ip","datetime","nonempty","isDatetime","isEmail","isURL","isEmoji","isUUID","isCUID","isCUID2","isULID","isIP","maxLength","I","gte","lte","setLimit","gt","lt","int","positive","negative","nonpositive","nonnegative","finite","safe","MIN_SAFE_INTEGER","MAX_SAFE_INTEGER","minValue","maxValue","isInt","BigInt","T","getTime","minDate","maxDate","C","L","_any","_unknown","exactLength","S","_cached","nonstrict","passthrough","augment","extend","_getCached","catchall","unknownKeys","strip","merge","setKey","pick","deepPartial","N","unwrap","partial","required","keyof","strictCreate","lazycreate","M","G","W","H","D","discriminator","optionsMap","U","valid","rest","keySchema","keyType","valueSchema","valueType","B","F","K","implement","returns","Reflect","parameters","returnType","strictImplement","Values","Enum","extract","exclude","sourceType","createWithPreprocess","removeDefault","removeCatch","re","de","le","ue","ce","he","fe","ye","ve","ge","be","xe","Ie","Ze","Te","ke","Ce","ze","Le","Pe","Oe","je","Ee","Ne","Se","Ae","Me","De","Ue","Re","Ve","$53be842a0003f2fd$exports","$ee38e295ce16494f$exports","$6e5a0b5cd91b5e01$exports","$bbaeefda90929bac$exports","$63f629692c824b7c$exports","$2b4fa2e46d897f1a$exports","$7c4c300842bd4cf2$export$e9a269813a6315a4","HeroSpriteSheetPng","$7c4c300842bd4cf2$export$f4c5de44377d2946","$9d936a2aecb96285$export$29cd7b75162a9425","PlayerSpeed","PlayerFrameSpeed","$51d548b0596e1d08$export$2616165974278734","playerSpriteSheet","leftIdle","rightIdle","upIdle","downIdle","leftWalk","rightWalk","upWalk","downWalk","Input","ArrowRight","ArrowLeft","ArrowUp","ArrowDown","$4c16b4f5569f0f92$export$1027d4534a5ce60b","playerStart","playerSpawnLocation","player","$7daec61009a51988$export$f38c40ba0ccca861","$ad2bcec7a0192558$var$game","overworld","house","$ad2bcec7a0192558$var$inTransition","factory","require","define","amd","__WEBPACK_EXTERNAL_MODULE__205__","semver","validateAndParse","isWildcard","tryParse","compareStrings","forceType","compareSegments","v1","v2","n1","n2","p1","p2","operator","assertValidOperator","operatorResMap","allowedOperators","op","v3","vp","r1","r2","r3","rp","nonZero","this","entityMetadata","ts","tsxCoord","tsyCoord","ldtkEntityIdentifier","preExisting","ldtkEntities","ldtk","maybeEntity","fieldIdentifier","normalizedValue","field","contentType","layerMetadata","solidValue","xCoord","yCoord","tileset","imagePath","friendlyTileset","levelPath","friendlyLevel","entityLayer","levelIdentifier","levelsToSearch","firstTileLayer","errored","inputPath","matches","basePath","relativeToBase","originSplit","relativeSplit","exTile","LdtkTilesetRectangle","LdtkPixel","LdtkFieldInstance","LdtkTileInstance","LdtkWorld","LdtkEnumValueDefinition","LdtkEnumDefinition","LdtkTilesetDefinition","LdtkDefinitions","util_1","super","subs","actualProto","_mapper","mapper","issue","processError","mod","en_1","overrideErrorMap","k2","errors_1","params","fullPath","fullIssue","errorMessage","maps","arrayValue","syncPairs","finalObject","_arg","validKeys","filtered","checker","separator","second","ZodError_1","errorUtil_1","parseUtil_1","ParseInputLazyPath","handleResult","processCreateParams","iss","def","maybeAsyncResult","getIssueProperties","setError","refinementData","option","incoming","defaultValueFunc","catchValueFunc","This","cuidRegex","cuid2Regex","ulidRegex","uuidRegex","emailRegex","emojiRegex","ipv4Regex","ipv6Regex","tooBig","tooSmall","ch","floatSafeRemainder","valDecCount","stepDecCount","decCount","deepPartialify","newShape","fieldSchema","shapeKeys","extraKeys","keyValidator","augmentation","merging","newField","createZodEnum","childCtx","getDiscriminator","discriminatorValue","discriminatorValues","mergeValues","aType","bType","bKeys","sharedKeys","sharedValue","newArray","handleParsed","parsedLeft","parsedRight","merged","itemIndex","schemas","third","finalMap","finalizeSet","elements","parsedSet","makeArgsIssue","makeReturnsIssue","parsedArgs","parsedReturns","expectedValues","enumValues","opt","nativeEnumValues","promisified","checkCtx","arg","processed","executeRefinement","inner","newCtx","inResult","handleAsync","_fatal","cls","stringType","numberType","nanType","bigIntType","booleanType","dateType","symbolType","undefinedType","nullType","anyType","unknownType","neverType","voidType","arrayType","objectType","strictObjectType","unionType","discriminatedUnionType","intersectionType","tupleType","recordType","mapType","setType","functionType","lazyType","literalType","enumType","nativeEnumType","promiseType","effectsType","optionalType","nullableType","preprocessType","pipelineType","__webpack_module_cache__","__webpack_modules__"],"version":3,"file":"index.a78842eb.js.map"} \ No newline at end of file diff --git a/index.c2a0b4ac.js.map b/index.c2a0b4ac.js.map deleted file mode 100644 index 4ee96bf..0000000 --- a/index.c2a0b4ac.js.map +++ /dev/null @@ -1 +0,0 @@ -{"mappings":"IgVSU0vK,E,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,S,E,C,E,O,G,E,U,C,E,O,C,C,C,I,E,W,E,C,E,E,C,E,E,E,iB,A,O,I,A,C,E,S,C,E,G,K,E,O,C,C,E,C,O,C,G,K,E,C,I,E,C,C,E,A,Q,C,C,E,C,I,E,C,G,E,Q,C,C,E,O,C,C,E,C,E,E,I,C,E,O,C,E,E,O,E,E,O,A,C,I,E,A,M,uB,E,I,O,E,I,C,mB,C,C,E,Q,C,S,C,C,C,E,C,C,E,C,C,E,E,iB,C,G,A,C,E,E,Q,A,E,Q,S,C,C,C,E,E,E,O,C,sB,I,G,E,E,O,C,gB,I,G,E,E,O,C,c,I,G,E,E,O,C,iB,I,G,E,E,O,C,mB,I,G,E,E,O,C,mB,I,G,E,E,O,C,gB,I,G,E,E,O,C,gB,I,G,E,E,O,C,Q,I,G,E,E,O,C,iB,I,G,E,E,O,C,e,I,G,E,E,O,C,Y,I,G,E,E,O,C,qB,I,G,E,E,O,C,kB,I,G,E,E,O,C,oB,I,G,E,E,O,C,e,I,G,E,E,O,C,sB,I,G,E,E,O,C,O,I,G,E,E,O,C,O,I,G,E,E,O,C,Y,I,G,E,E,O,C,Q,I,G,E,E,O,C,gB,I,G,E,E,O,C,c,I,G,E,E,O,C,qB,I,G,E,E,O,C,mB,I,G,E,E,O,C,gB,I,G,E,E,O,C,U,I,G,E,E,O,C,S,I,G,E,E,O,C,e,I,G,E,E,O,C,S,I,G,E,E,O,C,S,I,G,E,E,O,C,iB,I,G,E,E,O,C,Q,I,G,E,E,O,C,c,I,G,E,E,O,C,uB,I,G,E,E,O,C,W,I,G,E,E,O,C,oB,I,G,E,E,O,C,mB,I,G,E,E,O,C,oB,I,G,E,E,O,C,iB,I,G,E,E,O,C,wB,I,G,E,E,O,C,qB,I,G,E,E,O,C,0B,I,G,E,E,O,C,yB,I,G,E,E,O,C,sB,I,G,E,E,O,C,kB,I,G,E,E,O,C,gB,I,G,E,E,O,C,Q,I,I,E,E,O,C,kB,I,I,E,E,O,C,qB,I,I,E,E,O,C,8B,I,I,E,E,O,C,Y,I,I,E,E,O,C,oB,I,I,E,E,O,C,e,I,I,E,E,O,C,kB,I,I,E,E,O,C,yB,I,I,E,E,O,C,kB,I,I,E,E,O,C,mB,I,I,E,E,O,C,oB,I,I,E,E,O,C,a,I,I,E,E,O,C,Y,I,I,E,E,O,C,kB,I,I,E,E,O,C,Q,I,I,E,E,O,C,c,I,I,E,E,O,C,yB,I,I,E,E,O,C,c,I,I,E,E,O,C,Y,I,I,E,E,O,C,0B,I,I,E,E,O,C,gB,I,I,E,E,O,C,uB,I,I,E,E,O,C,yB,I,I,E,E,O,C,kB,I,I,E,E,O,C,Q,I,I,E,E,O,C,2B,I,I,E,E,O,C,W,I,I,E,E,O,C,M,I,I,E,E,O,C,Y,I,I,E,E,O,C,W,I,I,E,E,O,C,iB,I,I,E,E,O,C,c,I,I,E,E,O,C,c,I,I,E,E,O,C,gC,I,I,E,E,O,C,a,I,I,E,E,O,C,S,I,I,E,E,O,C,S,I,I,E,E,O,C,kB,I,I,E,E,O,C,e,I,I,E,E,O,C,yB,I,I,E,E,O,C,c,I,I,E,E,O,C,S,I,I,E,E,O,C,e,I,I,E,E,O,C,oB,I,I,E,E,O,C,qB,I,I,E,E,O,C,S,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,kB,I,I,E,E,O,C,e,I,I,E,E,O,C,a,I,I,E,E,O,C,S,I,I,E,E,O,C,a,I,I,E,E,O,C,mC,I,I,E,E,O,C,gC,I,I,E,E,O,C,mB,I,I,E,E,O,C,oB,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,Q,I,I,E,E,O,C,S,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,a,I,I,E,E,O,C,Y,I,I,E,E,O,C,W,I,I,E,E,O,C,a,I,I,E,E,O,C,a,I,I,E,E,O,C,S,I,I,E,E,O,C,Y,I,I,E,E,O,C,iB,I,I,E,E,O,C,gB,I,I,E,E,O,C,U,I,I,E,E,O,C,mB,I,I,E,E,O,C,qB,I,I,E,E,O,C,sB,I,I,E,E,O,C,yB,I,I,E,E,O,C,W,I,I,E,E,O,C,M,I,I,E,E,O,C,oB,I,I,E,E,O,C,U,I,I,E,E,O,C,oB,I,I,E,E,O,C,gB,I,I,E,E,O,C,iB,I,I,E,E,O,C,c,I,I,E,E,O,C,kB,I,I,E,E,O,C,iB,I,I,E,E,O,C,c,I,I,E,E,O,C,kB,I,I,E,E,O,C,Q,I,I,E,E,O,C,Y,I,I,E,E,O,C,c,I,I,E,E,O,C,a,I,I,E,E,O,C,2B,I,I,E,E,O,C,wB,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,W,I,I,E,E,O,C,W,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,Q,I,I,E,E,O,C,4B,I,I,E,E,O,C,O,I,I,E,E,O,C,c,I,I,E,E,O,C,S,I,I,E,E,O,C,e,I,I,E,E,O,C,gC,I,I,E,E,O,C,4B,I,I,E,E,O,C,W,I,I,E,E,O,C,S,I,I,E,E,O,C,W,I,I,E,E,O,C,S,I,I,E,E,O,C,kB,I,I,E,E,O,C,a,I,I,E,E,O,C,O,I,I,E,E,O,C,kB,I,I,E,E,O,C,e,I,I,E,E,O,C,S,I,I,E,E,O,C,S,I,I,E,E,O,C,sB,I,I,E,E,O,C,mB,I,I,E,E,O,C,4B,I,I,E,E,O,C,O,I,I,E,E,O,C,a,I,I,E,E,O,C,kB,I,I,E,E,O,C,O,I,I,E,E,O,C,oB,I,I,E,E,O,C,kB,I,I,E,E,O,C,W,I,I,E,E,O,C,W,I,I,E,E,O,C,kB,I,I,E,E,O,C,oB,I,I,E,E,O,C,U,I,I,E,E,O,C,e,I,I,E,E,O,C,e,I,I,E,E,O,C,qB,I,I,E,E,O,C,gB,I,I,E,E,O,C,mB,I,I,E,E,O,C,e,I,I,E,E,O,C,uB,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,c,I,I,E,E,O,C,U,I,I,E,E,O,C,kB,I,I,E,E,O,C,O,I,I,E,E,O,C,qB,I,I,E,E,O,C,qB,I,I,E,E,O,C,gB,I,I,E,E,O,C,iB,I,I,E,E,O,C,gB,I,I,E,E,O,C,yB,I,I,E,E,O,C,kB,I,I,E,E,O,C,oB,I,I,E,E,O,C,oB,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,e,I,I,E,E,O,C,e,I,I,E,E,O,C,wB,I,I,E,E,O,C,iB,I,I,E,E,O,C,a,I,I,E,E,O,C,kB,I,I,E,E,O,C,W,I,I,E,E,O,C,Q,I,I,E,E,O,C,e,I,I,E,E,O,C,4B,I,I,E,E,O,C,S,I,I,E,E,O,C,S,I,I,E,E,O,C,M,I,I,E,E,O,C,kB,I,I,E,E,O,C,Y,I,I,E,E,O,C,mB,I,I,E,E,O,C,S,I,I,E,E,O,C,gB,I,I,E,E,O,C,a,I,I,E,E,O,C,W,I,I,E,E,O,C,iB,I,I,E,E,O,C,W,I,I,E,E,O,C,W,I,I,E,E,O,C,e,I,I,E,E,O,C,U,I,I,E,E,O,C,U,I,I,E,E,O,C,Q,I,I,E,E,O,C,c,I,I,E,E,O,C,S,I,I,E,E,O,C,iB,I,I,E,E,O,C,gB,I,I,E,E,O,C,e,I,I,E,E,O,C,e,I,I,E,E,O,C,uB,I,I,E,E,O,C,Y,I,I,E,E,O,C,S,I,I,E,E,O,C,Q,I,I,E,E,O,C,O,I,I,E,E,O,C,iB,I,I,E,E,O,C,Q,I,I,E,E,O,C,c,I,I,E,E,O,C,S,I,I,E,E,O,C,a,I,I,E,E,O,C,c,I,I,E,E,O,C,gB,I,I,E,E,O,C,e,I,I,E,E,O,C,oB,I,I,E,E,O,C,S,I,I,E,E,O,C,S,I,I,E,E,O,C,gB,I,I,E,E,O,C,iB,I,I,E,E,O,C,a,I,I,E,E,O,C,W,I,I,E,E,O,C,Y,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,gB,I,I,E,E,O,C,O,I,I,E,E,O,C,U,I,I,E,E,O,C,gB,I,I,E,E,O,C,Q,I,I,E,E,O,C,U,I,I,E,E,O,C,Y,I,I,E,E,O,C,qB,I,I,E,E,O,C,a,I,I,E,E,O,C,W,I,I,E,E,O,C,U,I,I,E,E,O,C,gB,I,I,E,E,O,C,Q,I,I,E,E,O,C,O,I,I,E,E,O,C,S,I,I,E,E,O,C,a,I,I,E,E,O,C,e,I,I,E,E,O,C,e,I,I,E,E,O,C,gB,I,I,E,E,O,C,e,I,I,E,E,O,C,W,I,I,E,E,O,C,mB,I,I,E,E,O,C,iB,I,I,E,E,O,C,a,I,I,E,E,O,C,Q,I,I,E,E,O,C,oB,I,I,E,E,O,C,Q,I,I,E,E,O,C,Y,I,I,E,E,O,C,W,I,I,E,E,O,C,O,I,I,E,E,O,C,kB,I,I,E,E,O,C,kB,I,I,E,E,O,C,kB,I,I,E,E,O,C,iB,I,I,E,E,O,C,c,I,I,E,E,O,C,a,I,I,E,E,O,C,iB,I,I,E,E,O,C,iB,I,I,E,E,O,C,gB,I,I,E,E,O,C,mB,I,I,E,E,O,C,kB,I,I,E,E,O,C,sB,I,I,E,E,O,C,qB,I,I,E,E,O,C,qB,I,I,E,E,O,C,kB,I,I,E,E,O,C,sB,I,I,E,E,O,C,c,I,I,E,E,O,C,W,I,I,E,E,O,C,mB,I,I,E,E,O,C,gB,I,I,E,E,O,C,mB,I,I,E,E,O,C,Q,I,I,E,E,O,C,uB,I,I,E,E,O,C,O,I,I,E,E,O,C,Y,I,I,E,E,O,C,Y,I,I,E,E,O,C,M,I,I,E,E,O,C,Q,I,G;;;;;;C,E,I,E,C,K,C,E,E,K,E,C,C,E,C,E,I,C,G,I,E,E,K,E,E,C,C,G,E,E,M9UNV,EAA8B,A,E,C,C,KAA4B,KAE1D,EAAA,IAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0HA,CAAA,CAAA,GAAA,CAAO,QAAA,EAAA,QAAA,CAAA,kCAAA,CAAA,MAAA,EAAA,CAAA,SAAA,09BAAoiC,eAAA,CAAA,+/EAAihF,CAAA,WAAA,EAAA,EAA5jH,EAEA,IAAA,EAAe,C,E,K,C,E,E,K,E,C,C,E,C,E,I,C,G,I,E,E,K,E,E,C,C,G,E,E,MC9Hf,EAA8B,A,E,C,C,KAA4B,KAE1D,EAAA,IAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BC,CAAA,CAAA,GAAA,CAAO,QAAA,EAAA,QAAA,CAAA,+BAAA,CAAA,MAAA,EAAA,CAAA,SAAA,wOAA8S,eAAA,CAAA,ihBAAwiB,CAAA,WAAA,EAAA,EAA91B,EAEA,IAAA,EAAe,C,E,K,A,IC7Bf,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,IAAA,EAAA,EAAA,CA4EA,OAzEA,EAAA,QAAA,CAAA,WACA,OAAA,IAAA,CAAA,GAAA,CAAA,SAAA,CAAA,EACA,IAAA,EAAA,GACA,EAAA,AAAA,KAAA,IAAA,CAAA,CAAA,EAAA,CAoBA,OAnBA,CAAA,CAAA,EAAA,EACA,CAAA,GAAA,cAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,MADA,EAGA,CAAA,CAAA,EAAA,EACA,CAAA,GAAA,UAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,KADA,EAGA,GACA,CAAA,GAAA,SAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,MAAA,CAAA,EAAA,IAAA,MAAA,CAAA,CAAA,CAAA,EAAA,EAAA,GAAA,KADA,EAGA,GAAA,EAAA,GACA,GACA,CAAA,GAAA,GADA,EAGA,CAAA,CAAA,EAAA,EACA,CAAA,GAAA,GADA,EAGA,CAAA,CAAA,EAAA,EACA,CAAA,GAAA,GADA,EAGA,CACA,GAAA,IAAA,CAAA,GACA,EAGA,EAAA,CAAA,CAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EACA,UAAA,OAAA,GACA,CAAA,EAAA,CAAA,CAAA,KAAA,EAAA,KAAA,EAAA,CAAA,AAAA,EAEA,IAAA,EAAA,CAAA,EACA,GAAA,EACA,IAAA,IAAA,EAAA,EAAsB,EAAA,IAAA,CAAA,MAAA,CAAiB,IAAvC,CACA,IAAA,EAAA,IAAA,CAAA,EAAA,CAAA,EAAA,AACA,OAAA,GACA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CADA,CAGA,CAEA,IAAA,IAAA,EAAA,EAAqB,EAAA,EAAA,MAAA,CAAqB,IAA1C,CACA,IAAA,EAAA,EAAA,CAAA,MAAA,CAAA,CAAA,CAAA,EAAA,EACA,GAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,GAGA,KAAA,IAAA,IACA,KAAA,IAAA,CAAA,CAAA,EAAA,EAGA,CAAA,CAAA,CAAA,EAAA,CAAA,SAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,MAAA,CAAA,EAAA,IAAA,MAAA,CAAA,CAAA,CAAA,EAAA,EAAA,GAAA,MAAsF,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,IAAtF,EAFA,CAAA,CAAA,EAAA,CAAA,GAMA,IACA,CAAA,CAAA,EAAA,EAGA,CAAA,CAAA,CAAA,EAAA,CAAA,UAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,MAAiD,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,IAAjD,EAFA,CAAA,CAAA,EAAA,CAAA,GAMA,IACA,CAAA,CAAA,EAAA,EAGA,CAAA,CAAA,EAAA,CAAA,cAAA,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,OAAsD,MAAA,CAAA,CAAA,CAAA,EAAA,CAAA,KACtD,CAAA,CAAA,EAAA,CAAA,GAHA,CAAA,CAAA,EAAA,CAAA,GAAA,MAAA,CAAA,IAMA,EAAA,IAAA,CAAA,GACA,CACA,EACA,CACA,C,E,I,A,IClFA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,IAAA,EAAA,CAAA,CAAA,EAAA,CACA,EAAA,CAAA,CAAA,EAAA,CACA,GAAA,CAAA,EACA,OAAA,EAEA,GAAA,AAAA,YAAA,OAAA,KAAA,CACA,IAAA,EAAA,KAAA,SAAA,mBAAA,KAAA,SAAA,CAAA,MAGA,MAAA,CAAA,EAAA,CAAA,MAAA,CAAA,CADA,OAAA,MAAA,CADA,+DAAA,MAAA,CAAA,GACA,OACA,EAAA,IAAA,CAAA,KACA,CACA,MAAA,CAAA,EAAA,CAAA,IAAA,CAAA,KACA,C,E,K,C,E,E,KCdA,EAAQ,MACR,IAAA,EAAkB,EAAQ,KAE1B,CAAA,EAAA,OAAA,CAAA,EAAA,QAAA,O,E,K,C,E,E,KCHA,EAAQ,MACR,IAAA,EAAW,EAAQ,KAEnB,CAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,IAAA,A,E,K,C,E,E,KCHA,IAAA,EAAiB,EAAQ,KACzB,EAAkB,EAAQ,MAE1B,EAAA,SAGA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,GAAA,EAAA,GAAA,OAAA,CACA,OAAA,IAAA,EAAA,EAAA,GAAA,qBACA,C,E,K,C,E,E,KCTA,IAAA,EAAe,EAAQ,MAEvB,EAAA,OACA,EAAA,SAGA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,GAAA,EAAA,GAAA,OAAA,CACA,OAAA,IAAA,EAAA,EAAA,GAAA,oBACA,C,E,K,C,E,E,KCTA,IAAA,EAAsB,EAAQ,MAC9B,EAAsB,EAAQ,MAC9B,EAAwB,EAAQ,MAGhC,EAAA,SAAA,CAAA,EACA,OAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EACA,IAGA,EAHA,EAAA,EAAA,GACA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,GAIA,GAAA,GAAA,GAAA,EAAA,CAAA,KAAA,EAAA,GAGA,GAAA,AAFA,CAAA,EAAA,CAAA,CAAA,IAAA,AAAA,GAEA,EAAA,MAAA,CAAA,CAEA,MAAM,KAAW,EAAA,EAAgB,IACjC,GAAA,AAAA,CAAA,GAAA,KAAA,CAAA,GAAA,CAAA,CAAA,EAAA,GAAA,EAAA,OAAA,GAAA,GAAA,EACM,MAAN,CAAA,GAAA,EACA,CACA,CAEA,CAAA,EAAA,OAAA,CAAA,CAGA,SAAA,EAAA,CAAA,GAGA,QAAA,EAAA,CAAA,EACA,C,E,I,C,E,E,KC/BA,IAAA,EAAY,EAAQ,KAEpB,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,IAAA,EAAA,EAAA,CAAA,EAAA,CACA,MAAA,CAAA,CAAA,GAAA,EAAA,WAEA,EAAA,IAAA,CAAA,KAAA,GAAA,WAAgD,OAAA,CAAA,EAAhD,EACA,EACA,C,E,K,C,E,E,KCRA,IAAA,EAAkB,EAAQ,KAE1B,CAAA,EAAA,OAAA,CAAA,EAAA,EAAA,CAAA,KAAA,C,E,K,C,E,E,KCFA,IAAA,EAAiB,EAAQ,MAEzB,EAAA,KAAA,KAAA,CAEA,EAAA,SAAA,CAAA,CAAA,CAAA,EACA,IAAA,EAAA,EAAA,MAAA,CAEA,GAAA,EAAA,EAKA,IAHA,IACA,EAAA,EADA,EAAA,EAGA,EAAA,GAAA,CAGA,IAFA,EAAA,EACA,EAAA,CAAA,CAAA,EAAA,CACA,GAAA,EAAA,CAAA,CAAA,EAAA,EAAA,CAAA,GAAA,GACA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAEA,IAAA,KAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CACA,MAWA,IARA,IAAA,EAAA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,EAAA,EAAA,GAAA,GACA,EAAA,EAAA,EAAA,EAAA,GAAA,GACA,EAAA,EAAA,MAAA,CACA,EAAA,EAAA,MAAA,CACA,EAAA,EACA,EAAA,EAEA,EAAA,GAAA,EAAA,GACA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,GAAA,EAAA,EACA,AAAA,GAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,IAAA,CACA,EAAA,EAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,IAAA,CAIA,OAAA,CACA,CAEA,CAAA,EAAA,OAAA,CAAA,C,E,K,C,E,E,KCxCA,IAAA,EAAkB,EAAQ,MAE1B,EAAA,EAAA,CAAA,EAAA,QAAA,EACA,EAAA,EAAA,GAAA,KAAA,CAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,GAAA,EAAA,GACA,C,E,K,C,E,E,KCPA,IAAA,EAA4B,EAAQ,MACpC,EAAiB,EAAQ,KACzB,EAAiB,EAAQ,MAGzB,EAAA,AAFsB,EAAQ,MAE9B,eACA,EAAA,OAGA,EAAA,AAAA,cAAA,EAAA,WAAiD,OAAA,SAAA,KAGjD,EAAA,SAAA,CAAA,CAAA,CAAA,EACA,GAAA,CACA,OAAA,CAAA,CAAA,EAAA,AACA,CAAI,MAAA,EAAA,CAAJ,CACA,CAGA,CAAA,EAAA,OAAA,CAAA,EAAA,EAAA,SAAA,CAAA,EACA,IAAA,EAAA,EAAA,EACA,OAAA,AAAA,KAAA,IAAA,EAAA,YAAA,AAAA,OAAA,EAAA,OAEA,AAAA,UAAA,MAAA,CAAA,EAAA,EAAA,EAAA,EAAA,GAAA,EAAA,EAAA,EAEA,EAAA,EAAA,GAEA,AAAA,WAAA,CAAA,EAAA,EAAA,EAAA,GAAA,EAAA,EAAA,MAAA,EAAA,YAAA,CACA,C,E,K,C,E,E,KC5BA,IAAA,EAAa,EAAQ,MACrB,EAAc,EAAQ,KACtB,EAAqC,EAAQ,MAC7C,EAA2B,EAAQ,KAEnC,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAIA,IAAA,IAHA,EAAA,EAAA,GACA,EAAA,EAAA,CAAA,CACA,EAAA,EAAA,CAAA,CACA,EAAA,EAAkB,EAAA,EAAA,MAAA,CAAiB,IAAnC,CACA,IAAA,EAAA,CAAA,CAAA,EAAA,CACA,EAAA,EAAA,IAAA,GAAA,EAAA,EAAA,IACA,EAAA,EAAA,EAAA,EAAA,EAAA,GAEA,CACA,C,E,K,C,E,E,KCfA,IAAA,EAAkB,EAAQ,MAC1B,EAA2B,EAAQ,MACnC,EAA+B,EAAQ,KAEvC,CAAA,EAAA,OAAA,CAAA,EAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EACA,OAAA,EAAA,CAAA,CAAA,EAAA,EAAA,EAAA,EAAA,GACA,EAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAEA,OADA,CAAA,CAAA,EAAA,CAAA,EACA,CACA,C,E,K,A,ICTA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,MAAA,CACA,WAAA,CAAA,CAAA,AAAA,EAAA,CAAA,EACA,aAAA,CAAA,CAAA,AAAA,EAAA,CAAA,EACA,SAAA,CAAA,CAAA,AAAA,EAAA,CAAA,EACA,MAAA,CACA,CACA,C,E,K,C,E,E,KCPA,IAAA,EAAiB,EAAQ,KACzB,EAA2B,EAAQ,MACnC,EAAkB,EAAQ,MAC1B,EAA2B,EAAQ,KAEnC,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EACA,GAAA,CAAA,EAAA,CAAA,CAAA,EACA,IAAA,EAAA,EAAA,UAAA,CACA,EAAA,AAAA,KAAA,IAAA,EAAA,IAAA,CAAA,EAAA,IAAA,CAAA,EAEA,GADA,EAAA,IAAA,EAAA,EAAA,EAAA,GACA,EAAA,MAAA,CACA,EAAA,CAAA,CAAA,EAAA,CAAA,EACA,EAAA,EAAA,OACA,CACA,GAAA,CACA,EAAA,MAAA,CACA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EADA,OAAA,CAAA,CAAA,EAAA,AAEA,CAAM,MAAA,EAAA,CAAN,CACA,EAAA,CAAA,CAAA,EAAA,CAAA,EACA,EAAA,CAAA,CAAA,EAAA,EAAA,CACA,MAAA,EACA,WAAA,CAAA,EACA,aAAA,CAAA,EAAA,eAAA,CACA,SAAA,CAAA,EAAA,WAAA,AACA,EACA,CAAI,OAAJ,CACA,C,E,K,C,E,E,KC1BA,IAAA,EAAa,EAAQ,MAGrB,EAAA,OAAA,cAAA,AAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,GAAA,CACA,EAAA,EAAA,EAAA,CAAkC,MAAA,EAAA,aAAA,CAAA,EAAA,SAAA,CAAA,CAAA,EAClC,CAAI,MAAJ,EAAA,CACA,CAAA,CAAA,EAAA,CAAA,CACA,CAAI,OAAJ,CACA,C,E,I,C,E,E,KCXA,IAAA,EAAkB,EAAQ,MAE1B,EAAA,SAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,GAAA,CAAA,OAAA,CAAA,CAAA,EAAA,CAAA,MAAA,IAAA,EAAA,0BAAA,EAAA,GAAA,OAAA,EAAA,GACA,C,E,K,C,E,E,KCNA,IAAA,EAAY,EAAQ,KAGpB,CAAA,EAAA,OAAA,CAAA,CAAA,EAAA,WAEA,OAAA,AAAA,IAAA,OAAA,cAAA,CAAA,CAAA,EAAiC,EAAA,CAAO,IAAA,WAAmB,OAAA,CAAA,CAAA,EAA3D,CAAA,EAAA,AACA,E,E,K,C,E,E,KCNA,IAAA,EAAa,EAAQ,MACrB,EAAe,EAAQ,MAEvB,EAAA,EAAA,QAAA,CAEA,EAAA,EAAA,IAAA,EAAA,EAAA,aAAA,CAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,aAAA,CAAA,GAAA,CAAA,CACA,C,E,K,C,E,E,KCPA,IAAA,EAAA,AAFgB,EAAQ,MAExB,KAAA,CAAA,kBAEA,CAAA,EAAA,OAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,EAAA,A,E,I,C,E,E,KCJA,IAAA,EAAS,EAAQ,KAEjB,CAAA,EAAA,OAAA,CAAA,eAAA,IAAA,CAAA,E,E,K,A,ICFA,EAAA,OAAA,CAAA,AAAA,aAAA,OAAA,WAAA,OAAA,UAAA,SAAA,GAAA,E,E,K,C,E,E,KCAA,IAOA,EAAA,EAPA,EAAa,EAAQ,MACrB,EAAgB,EAAQ,MAExB,EAAA,EAAA,OAAA,CACA,EAAA,EAAA,IAAA,CACA,EAAA,GAAA,EAAA,QAAA,EAAA,GAAA,EAAA,OAAA,CACA,EAAA,GAAA,EAAA,EAAA,CAGA,GAIA,CAAA,EAAA,AAHA,CAAA,EAAA,EAAA,KAAA,CAAA,IAAA,CAGA,CAAA,EAAA,CAAA,GAAA,CAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,AAAA,CAAA,EAKA,CAAA,GAAA,GAEA,CAAA,CADA,CAAA,EAAA,EAAA,KAAA,CAAA,cAAA,GACA,CAAA,CAAA,EAAA,EAAA,EAAA,GACA,CAAA,EAAA,EAAA,KAAA,CAAA,gBAAA,GACA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,AAAA,EAIA,EAAA,OAAA,CAAA,C,E,K,C,E,E,KCxBA,IAAA,EAAA,AAFgB,EAAQ,MAExB,KAAA,CAAA,uBAEA,CAAA,EAAA,OAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,EAAA,A,E,K,C,E,E,KCJA,IAAA,EAAa,EAAQ,MACrB,EAAkB,EAAQ,KAE1B,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,OAAA,EAAA,CAAA,CAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CACA,C,E,K,A,ICJA,EAAA,OAAA,CAAA,CACA,cACA,iBACA,gBACA,uBACA,iBACA,WACA,UACA,A,E,K,C,E,E,KCTA,IAAA,EAAa,EAAQ,MACrB,EAA+B,EAAA,MAAA,CAAA,CAC/B,EAAkC,EAAQ,MAC1C,EAAoB,EAAQ,MAC5B,EAA2B,EAAQ,MACnC,EAAgC,EAAQ,MACxC,EAAe,EAAQ,KAiBvB,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,IAGA,EAAA,EAAA,EAAA,EAAA,EAHA,EAAA,EAAA,MAAA,CACA,EAAA,EAAA,MAAA,CACA,EAAA,EAAA,IAAA,CASA,GANA,EADA,EACA,EACA,EACA,CAAA,CAAA,EAAA,EAAA,EAAA,EAAA,CAAA,GAEA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,EAAA,CAAA,SAAA,CAEA,IAAA,KAAA,EAAA,CAQA,GAPA,EAAA,CAAA,CAAA,EAAA,CAGA,EAFA,EAAA,cAAA,CAEA,AADA,CAAA,EAAA,EAAA,EAAA,EAAA,GACA,EAAA,KAAA,CACA,CAAA,CAAA,EAAA,CAGA,CAFA,EAAA,EAAA,EAAA,EAAA,CAAA,EAAA,IAAA,GAAA,EAAA,EAAA,EAAA,MAAA,GAEA,AAAA,KAAA,IAAA,EAAA,CACA,GAAA,OAAA,GAAA,OAAA,EAAA,SACA,EAAA,EAAA,EACA,CAEA,CAAA,EAAA,IAAA,EAAA,GAAA,EAAA,IAAA,AAAA,GACA,EAAA,EAAA,OAAA,CAAA,GAEA,EAAA,EAAA,EAAA,EAAA,EACA,CACA,C,E,K,A,ICrDA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,GAAA,CACA,MAAA,CAAA,CAAA,GACA,CAAI,MAAJ,EAAA,CACA,MAAA,CAAA,CACA,CACA,C,E,K,C,E,E,KCNA,IAAA,EAAY,EAAQ,KAEpB,CAAA,EAAA,OAAA,CAAA,CAAA,EAAA,WAEA,IAAA,EAAA,AAAA,CAAA,WAA4B,CAAA,EAA5B,IAAA,GAEA,MAAA,AAAA,YAAA,OAAA,GAAA,EAAA,cAAA,CAAA,YACA,E,E,K,C,E,E,KCPA,IAAA,EAAkB,EAAQ,MAE1B,EAAA,SAAA,SAAA,CAAA,IAAA,AAEA,CAAA,EAAA,OAAA,CAAA,EAAA,EAAA,IAAA,CAAA,GAAA,WACA,OAAA,EAAA,KAAA,CAAA,EAAA,UACA,C,E,I,C,E,E,KCNA,IAAA,EAAkB,EAAQ,MAC1B,EAAa,EAAQ,MAErB,EAAA,SAAA,SAAA,CAEA,EAAA,GAAA,OAAA,wBAAA,CAEA,EAAA,EAAA,EAAA,QAGA,EAAA,GAAA,CAAA,CAAA,GAAA,GAAA,EAAA,EAAA,QAAA,YAAA,AAAA,CAEA,CAAA,EAAA,OAAA,CAAA,CACA,OAAA,EACA,OALA,GAAA,AAAA,cAAA,AAAA,CAAA,WAA+C,CAAA,EAA/C,IAAA,CAMA,aAAA,CACA,C,E,K,C,E,E,KChBA,IAAA,EAAkB,EAAQ,MAE1B,EAAA,SAAA,SAAA,CACA,EAAA,EAAA,IAAA,CACA,EAAA,GAAA,EAAA,IAAA,CAAA,IAAA,CAAA,EAAA,EAEA,CAAA,EAAA,OAAA,CAAA,EAAA,EAAA,SAAA,CAAA,EACA,OAAA,WACA,OAAA,EAAA,KAAA,CAAA,EAAA,UACA,CACA,C,E,K,C,E,E,KCVA,IAAA,EAAa,EAAQ,MACrB,EAAiB,EAAQ,IAMzB,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,MAJA,EAKA,OAAA,UAAA,MAAA,CAAA,EAJA,EADA,EAKA,CAAA,CAAA,EAAA,EAJA,EAAA,KAAA,EAIA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,EAAA,CAAA,EAAA,AACA,C,E,K,C,E,E,KCTA,IAAA,EAAgB,EAAQ,MACxB,EAAwB,EAAQ,KAIhC,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,IAAA,EAAA,CAAA,CAAA,EAAA,CACA,OAAA,EAAA,GAAA,KAAA,EAAA,EAAA,EACA,C,E,K,S,C,C,C,C,C,ECRA,IAAA,EAAA,SAAA,CAAA,EACA,OAAA,GAAA,EAAA,IAAA,GAAA,MAAA,CACA,CAGA,CAAA,EAAA,OAAA,CAEA,EAAA,AAAA,UAAA,OAAA,YAAA,aACA,EAAA,AAAA,UAAA,OAAA,QAAA,SAEA,EAAA,AAAA,UAAA,OAAA,MAAA,OACA,EAAA,AAAqB,UAArB,OAAe,EAAA,CAAM,EAAgB,EAAA,CAAM,GAC3C,EAAA,AAAA,UAAA,OAAA,IAAA,EAAA,IAAA,GAEA,WAAiB,OAAA,IAAA,AAAA,KAAjB,SAAA,gB,E,K,C,E,E,KCdA,IAAA,EAAkB,EAAQ,MAC1B,EAAe,EAAQ,KAEvB,EAAA,EAAA,CAAA,EAAA,cAAA,CAKA,CAAA,EAAA,OAAA,CAAA,OAAA,MAAA,EAAA,SAAA,CAAA,CAAA,CAAA,EACA,OAAA,EAAA,EAAA,GAAA,EACA,C,E,K,A,ICVA,EAAA,OAAA,CAAA,CAAA,C,E,K,C,E,E,KCAA,IAAA,EAAkB,EAAQ,MAC1B,EAAY,EAAQ,MACpB,EAAoB,EAAQ,KAG5B,CAAA,EAAA,OAAA,CAAA,CAAA,GAAA,CAAA,EAAA,WAEA,OAAA,AAEA,IAFA,OAAA,cAAA,CAAA,EAAA,OAAA,IAAA,CACA,IAAA,WAAuB,OAAvB,CAAA,CACA,GAAA,CAAA,AACA,E,E,K,C,E,E,KCVA,IAAA,EAAkB,EAAQ,MAC1B,EAAY,EAAQ,MACpB,EAAc,EAAQ,MAEtB,EAAA,OACA,EAAA,EAAA,GAAA,KAAA,CAGA,CAAA,EAAA,OAAA,CAAA,EAAA,WAGA,MAAA,CAAA,EAAA,KAAA,oBAAA,CAAA,EACA,GAAA,SAAA,CAAA,EACA,MAAA,AAAA,WAAA,EAAA,GAAA,EAAA,EAAA,IAAA,EAAA,EACA,EAAA,C,E,K,C,E,E,KCdA,IAAA,EAAkB,EAAQ,MAC1B,EAAiB,EAAQ,KACzB,EAAY,EAAQ,MAEpB,EAAA,EAAA,SAAA,QAAA,EAGA,EAAA,EAAA,aAAA,GACA,CAAA,EAAA,aAAA,CAAA,SAAA,CAAA,EACA,OAAA,EAAA,EACA,CAAA,EAGA,EAAA,OAAA,CAAA,EAAA,aAAA,A,E,K,C,E,E,KCbA,IAYA,EAAA,EAAA,EAZA,EAAsB,EAAQ,MAC9B,EAAa,EAAQ,MACrB,EAAe,EAAQ,MACvB,EAAkC,EAAQ,MAC1C,EAAa,EAAQ,MACrB,EAAa,EAAQ,MACrB,EAAgB,EAAQ,MACxB,EAAiB,EAAQ,MAEzB,EAAA,6BACA,EAAA,EAAA,SAAA,CACA,EAAA,EAAA,OAAA,CAgBA,GAAA,GAAA,EAAA,KAAA,CAAA,CACA,IAAA,EAAA,EAAA,KAAA,EAAA,CAAA,EAAA,KAAA,CAAA,IAAA,CAAA,CAEA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CACA,EAAA,GAAA,CAAA,EAAA,GAAA,CACA,EAAA,GAAA,CAAA,EAAA,GAAA,CAEA,EAAA,SAAA,CAAA,CAAA,CAAA,EACA,GAAA,EAAA,GAAA,CAAA,GAAA,MAAA,IAAA,EAAA,GAGA,OAFA,EAAA,MAAA,CAAA,EACA,EAAA,GAAA,CAAA,EAAA,GACA,CACA,EACA,EAAA,SAAA,CAAA,EACA,OAAA,EAAA,GAAA,CAAA,IAAA,CAAA,CACA,EACA,EAAA,SAAA,CAAA,EACA,OAAA,EAAA,GAAA,CAAA,EACA,CACA,KAAA,CACA,IAAA,EAAA,EAAA,QACA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EACA,EAAA,SAAA,CAAA,CAAA,CAAA,EACA,GAAA,EAAA,EAAA,GAAA,MAAA,IAAA,EAAA,GAGA,OAFA,EAAA,MAAA,CAAA,EACA,EAAA,EAAA,EAAA,GACA,CACA,EACA,EAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CACA,EACA,EAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,EACA,CACA,CAEA,EAAA,OAAA,CAAA,CACA,IAAA,EACA,IAAA,EACA,IAAA,EACA,QArDA,SAAA,CAAA,EACA,OAAA,EAAA,GAAA,EAAA,GAAA,EAAA,EAAA,CAAA,EACA,EAoDA,UAlDA,SAAA,CAAA,EACA,OAAA,SAAA,CAAA,EACA,IAAA,EACA,GAAA,CAAA,EAAA,IAAA,AAAA,CAAA,EAAA,EAAA,EAAA,EAAA,IAAA,GAAA,EACA,MAAA,IAAA,EAAA,0BAAA,EAAA,aACM,OAAN,CACA,CACA,CA4CA,C,E,I,A,ICpEA,IAAA,EAAA,AAAA,UAAA,OAAA,UAAA,SAAA,GAAA,AAKA,CAAA,EAAA,OAAA,CAAA,AAAA,KAAA,IAAA,GAAA,AAAA,KAAA,IAAA,EAAA,SAAA,CAAA,EACA,MAAA,AAAA,YAAA,OAAA,GAAA,IAAA,CACA,EAAA,SAAA,CAAA,EACA,MAAA,AAAA,YAAA,OAAA,CACA,C,E,K,C,E,E,KCVA,IAAA,EAAY,EAAQ,MACpB,EAAiB,EAAQ,KAEzB,EAAA,kBAEA,EAAA,SAAA,CAAA,CAAA,CAAA,EACA,IAAA,EAAA,CAAA,CAAA,EAAA,GAAA,CACA,OAAA,IAAA,GACA,IAAA,GACA,CAAA,EAAA,GAAA,EAAA,GACA,CAAA,CAAA,CAHA,CAIA,EAEA,EAAA,EAAA,SAAA,CAAA,SAAA,CAAA,EACA,OAAA,OAAA,GAAA,OAAA,CAAA,EAAA,KAAA,WAAA,EACA,EAEA,EAAA,EAAA,IAAA,CAAA,CAAA,EACA,EAAA,EAAA,MAAA,CAAA,IACA,EAAA,EAAA,QAAA,CAAA,GAEA,CAAA,EAAA,OAAA,CAAA,C,E,K,A,ICnBA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,OAAA,MAAA,CACA,C,E,K,C,E,E,KCJA,IAAA,EAAiB,EAAQ,IAEzB,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,MAAA,AAAA,UAAA,OAAA,EAAA,AAAA,OAAA,EAAA,EAAA,EACA,C,E,K,A,ICJA,EAAA,OAAA,CAAA,CAAA,C,E,K,C,E,E,KCAA,IAAA,EAAiB,EAAQ,MACzB,EAAiB,EAAQ,KACzB,EAAoB,EAAQ,MAC5B,EAAwB,EAAQ,MAEhC,EAAA,MAEA,CAAA,EAAA,OAAA,CAAA,EAAA,SAAA,CAAA,EACA,MAAA,AAAA,UAAA,OAAA,CACA,EAAA,SAAA,CAAA,EACA,IAAA,EAAA,EAAA,UACA,OAAA,EAAA,IAAA,EAAA,EAAA,SAAA,CAAA,EAAA,GACA,C,E,K,C,E,E,KCZA,IAAA,EAAe,EAAQ,KAIvB,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,MAAA,CACA,C,E,K,C,E,E,KCNA,IAAA,EAAkB,EAAQ,MAC1B,EAAY,EAAQ,MACpB,EAAiB,EAAQ,KACzB,EAAa,EAAQ,MACrB,EAAkB,EAAQ,MAC1B,EAAiC,EAAA,KAAA,YAAA,CACjC,EAAoB,EAAQ,MAC5B,EAA0B,EAAQ,MAElC,EAAA,EAAA,OAAA,CACA,EAAA,EAAA,GAAA,CACA,EAAA,OAEA,EAAA,OAAA,cAAA,CACA,EAAA,EAAA,GAAA,KAAA,EACA,EAAA,EAAA,GAAA,OAAA,EACA,EAAA,EAAA,EAAA,CAAA,IAAA,EAEA,EAAA,GAAA,CAAA,EAAA,WACA,OAAA,AAAA,IAAA,EAAA,WAAsC,EAAa,SAAA,CAAc,MAAA,CAAA,GAAjE,MAAA,AACA,GAEA,EAAA,OAAA,QAAA,KAAA,CAAA,UAEA,EAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EACA,YAAA,EAAA,EAAA,GAAA,EAAA,IACA,CAAA,EAAA,IAAA,EAAA,EAAA,GAAA,wBAAA,MAAA,GADA,EAGA,GAAA,EAAA,MAAA,EAAA,CAAA,EAAA,OAAA,CAAA,EACA,GAAA,EAAA,MAAA,EAAA,CAAA,EAAA,OAAA,CAAA,EACA,CAAA,CAAA,EAAA,EAAA,SAAA,GAAA,EAAA,IAAA,GAAA,CAAA,IACA,EAAA,EAAA,EAAA,OAAA,CAAqD,MAAA,EAAA,aAAA,CAAA,CAAA,GACrD,EAAA,IAAA,CAAA,GAEA,GAAA,GAAA,EAAA,EAAA,UAAA,EAAA,MAAA,GAAA,EAAA,KAAA,EACA,EAAA,EAAA,SAAA,CAAsC,MAAA,EAAA,KAAA,AAAA,GAEtC,GAAA,CACA,GAAA,EAAA,EAAA,gBAAA,EAAA,WAAA,CACA,GAAA,EAAA,EAAA,YAAA,CAA4D,SAAA,CAAA,CAAA,GAE5D,EAAA,SAAA,EAAA,CAAA,EAAA,SAAA,CAAA,KAAA,CAFA,CAGA,CAAI,MAAA,EAAA,CAAJ,CACA,IAAA,EAAA,EAAA,GAGI,OAFJ,EAAA,EAAA,WACA,CAAA,EAAA,MAAA,CAAA,EAAA,EAAA,AAAA,UAAA,OAAA,EAAA,EAAA,GADA,EAEA,CACA,CAIA,CAAA,SAAA,SAAA,CAAA,QAAA,CAAA,EAAA,WACA,OAAA,EAAA,IAAA,GAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,IAAA,CACA,EAAA,W,E,K,A,ICrDA,IAAA,EAAA,KAAA,IAAA,CACA,EAAA,KAAA,KAAA,AAKA,CAAA,EAAA,OAAA,CAAA,KAAA,KAAA,EAAA,SAAA,CAAA,EACA,IAAA,EAAA,CAAA,EACA,MAAA,AAAA,CAAA,EAAA,EAAA,EAAA,CAAA,EAAA,EACA,C,E,K,C,E,E,KCTA,IAAA,EAAkB,EAAQ,MAC1B,EAAqB,EAAQ,MAC7B,EAA8B,EAAQ,MACtC,EAAe,EAAQ,MACvB,EAAoB,EAAQ,MAE5B,EAAA,UAEA,EAAA,OAAA,cAAA,CAEA,EAAA,OAAA,wBAAA,CACA,EAAA,aACA,EAAA,eACA,EAAA,UAIA,CAAA,EAAA,CAAS,CAAT,EAAA,EAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAIA,GAHA,EAAA,GACA,EAAA,EAAA,GACA,EAAA,GACA,AAAA,YAAA,OAAA,GAAA,AAAA,cAAA,GAAA,UAAA,GAAA,KAAA,GAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CACA,IAAA,EAAA,EAAA,EAAA,GACA,GAAA,CAAA,CAAA,EAAA,GACA,CAAA,CAAA,EAAA,CAAA,EAAA,KAAA,CACA,EAAA,CACA,aAAA,KAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CACA,WAAA,KAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CACA,SAAA,CAAA,CACA,EAEA,CAAI,OAAJ,EAAA,EAAA,EAAA,EACA,EAAA,EAAA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAIA,GAHA,EAAA,GACA,EAAA,EAAA,GACA,EAAA,GACA,EAAA,GAAA,CACA,OAAA,EAAA,EAAA,EAAA,EACA,CAAI,MAAA,EAAA,CAAJ,CACA,GAAA,QAAA,GAAA,QAAA,EAAA,MAAA,IAAA,EAAA,2BAEA,MADA,UAAA,GAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,KAAA,AAAA,EACA,CACA,C,E,K,C,E,E,KC1CA,IAAA,EAAkB,EAAQ,MAC1B,EAAW,EAAQ,MACnB,EAAiC,EAAQ,MACzC,EAA+B,EAAQ,MACvC,EAAsB,EAAQ,MAC9B,EAAoB,EAAQ,MAC5B,EAAa,EAAQ,MACrB,EAAqB,EAAQ,MAG7B,EAAA,OAAA,wBAAA,AAIA,CAAA,EAAA,CAAS,CAAT,EAAA,EAAA,SAAA,CAAA,CAAA,CAAA,EAGA,GAFA,EAAA,EAAA,GACA,EAAA,EAAA,GACA,EAAA,GAAA,CACA,OAAA,EAAA,EAAA,EACA,CAAI,MAAA,EAAA,CAAJ,CACA,GAAA,EAAA,EAAA,GAAA,OAAA,EAAA,CAAA,EAAA,EAAA,CAAA,CAAA,EAAA,GAAA,CAAA,CAAA,EAAA,CACA,C,E,K,C,E,E,KCrBA,IAAA,EAAyB,EAAQ,MAGjC,EAAA,AAFkB,EAAQ,MAE1B,MAAA,CAAA,SAAA,YAKA,CAAA,EAAA,CAAS,CAAT,OAAA,mBAAA,EAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,EACA,C,E,K,C,E,KCTA,EAAA,CAAS,CAAT,OAAA,qBAAA,A,E,K,C,E,E,KCDA,IAAA,EAAkB,EAAQ,KAE1B,CAAA,EAAA,OAAA,CAAA,EAAA,CAAA,EAAA,aAAA,C,E,K,C,E,E,KCFA,IAAA,EAAkB,EAAQ,MAC1B,EAAa,EAAQ,MACrB,EAAsB,EAAQ,MAC9B,EAAc,EAAA,MAAA,OAAA,CACd,EAAiB,EAAQ,MAEzB,EAAA,EAAA,EAAA,CAAA,IAAA,CAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,IAGA,EAHA,EAAA,EAAA,GACA,EAAA,EACA,EAAA,EAAA,CAEA,IAAA,KAAA,EAAA,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,GAEA,KAAA,EAAA,MAAA,CAAA,GAAA,EAAA,EAAA,EAAA,CAAA,CAAA,IAAA,GACA,CAAA,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,EADA,EAGA,OAAA,CACA,C,E,K,C,E,E,KCnBA,IAAA,EAAyB,EAAQ,MACjC,EAAkB,EAAQ,KAK1B,CAAA,EAAA,OAAA,CAAA,OAAA,IAAA,EAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,EACA,C,E,K,C,E,KCRA,IAAA,EAAA,CAAA,EAAA,oBAAA,CAEA,EAAA,OAAA,wBAAA,CAGA,EAAA,GAAA,CAAA,EAAA,IAAA,CAAA,CAA4E,EAAA,CAAA,EAA5E,EAIA,CAAA,EAAA,CAAS,CAAT,EAAA,SAAA,CAAA,EACA,IAAA,EAAA,EAAA,IAAA,CAAA,GACA,MAAA,CAAA,CAAA,GAAA,EAAA,UAAA,AACA,EAAA,C,E,I,C,E,E,KCZA,IAAA,EAAW,EAAQ,MACnB,EAAiB,EAAQ,KACzB,EAAe,EAAQ,MAEvB,EAAA,SAIA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,IAAA,EAAA,EACA,GAAA,WAAA,GAAA,EAAA,EAAA,EAAA,QAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,KACA,EAAA,EAAA,EAAA,OAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,KACA,AAAA,WAAA,GAAA,EAAA,EAAA,EAAA,QAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,IAFA,OAAA,CAGA,OAAA,IAAA,EAAA,0CACA,C,E,I,C,E,E,KCdA,IAAA,EAAiB,EAAQ,MACzB,EAAkB,EAAQ,MAC1B,EAAgC,EAAQ,MACxC,EAAkC,EAAQ,MAC1C,EAAe,EAAQ,MAEvB,EAAA,EAAA,EAAA,CAAA,MAAA,CAGA,CAAA,EAAA,OAAA,CAAA,EAAA,UAAA,YAAA,SAAA,CAAA,EACA,IAAA,EAAA,EAAA,CAAA,CAAA,EAAA,IACA,EAAA,EAAA,CAAA,CACA,OAAA,EAAA,EAAA,EAAA,EAAA,IAAA,CACA,C,E,K,C,E,E,KCbA,IAAA,EAAa,EAAQ,KAErB,CAAA,EAAA,OAAA,CAAA,C,E,K,C,E,E,KCFA,IAAA,EAAwB,EAAQ,MAEhC,EAAA,SAIA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,GAAA,EAAA,GAAA,MAAA,IAAA,EAAA,wBAAA,GACA,OAAA,CACA,C,E,K,C,E,E,KCTA,IAAA,EAAa,EAAQ,MACrB,EAAU,EAAQ,MAElB,EAAA,EAAA,OAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,OAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CACA,C,E,K,C,E,E,KCPA,IAAA,EAAa,EAAQ,MACrB,EAA2B,EAAQ,MAEnC,EAAA,qBACA,EAAA,CAAA,CAAA,EAAA,EAAA,EAAA,EAAA,CAAA,EAEA,CAAA,EAAA,OAAA,CAAA,C,E,K,C,E,E,KCNA,IAAA,EAAc,EAAQ,MACtB,EAAY,EAAQ,MAEpB,AAAA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,OAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,AAAA,KAAA,IAAA,EAAA,EAAA,CAAA,CAAA,CACA,CAAA,EAAA,WAAA,EAAA,EAAA,IAAA,CAAA,CACA,QAAA,SACA,KAAA,EAAA,OAAA,SACA,UAAA,4CACA,QAAA,2DACA,OAAA,qCACA,E,E,K,C,E,E,KCVA,IAAA,EAAiB,EAAQ,MACzB,EAAY,EAAQ,MAGpB,EAAA,AAFa,EAAQ,MAErB,MAAA,AAGA,CAAA,EAAA,OAAA,CAAA,CAAA,CAAA,OAAA,qBAAA,EAAA,CAAA,EAAA,WACA,IAAA,EAAA,OAAA,oBAKA,MAAA,CAAA,EAAA,IAAA,CAAA,CAAA,OAAA,cAAA,MAAA,GAEA,CAAA,OAAA,IAAA,EAAA,GAAA,EAAA,EACA,E,E,K,C,E,E,KCjBA,IAAA,EAA0B,EAAQ,MAElC,EAAA,KAAA,GAAA,CACA,EAAA,KAAA,GAAA,AAKA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,IAAA,EAAA,EAAA,GACA,OAAA,EAAA,EAAA,EAAA,EAAA,EAAA,GAAA,EAAA,EAAA,EACA,C,E,K,C,E,E,KCVA,IAAA,EAAoB,EAAQ,MAC5B,EAA6B,EAAQ,KAErC,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,GACA,C,E,K,C,E,E,KCNA,IAAA,EAAY,EAAQ,KAIpB,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,IAAA,EAAA,CAAA,EAEA,OAAA,GAAA,GAAA,AAAA,IAAA,EAAA,EAAA,EAAA,EACA,C,E,K,C,E,E,KCRA,IAAA,EAA0B,EAAQ,MAElC,EAAA,KAAA,GAAA,AAIA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,IAAA,EAAA,EAAA,GACA,OAAA,EAAA,EAAA,EAAA,EAAA,kBAAA,CACA,C,E,I,C,E,E,KCTA,IAAA,EAA6B,EAAQ,MAErC,EAAA,MAIA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,GACA,C,E,K,C,E,E,KCRA,IAAA,EAAW,EAAQ,MACnB,EAAe,EAAQ,MACvB,EAAe,EAAQ,MACvB,EAAgB,EAAQ,MACxB,EAA0B,EAAQ,KAClC,EAAsB,EAAQ,MAE9B,EAAA,UACA,EAAA,EAAA,cAIA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EACA,GAAA,CAAA,EAAA,IAAA,EAAA,GAAA,OAAA,EACA,IACA,EADA,EAAA,EAAA,EAAA,GAEA,GAAA,EAAA,CAGA,GAFA,KAAA,IAAA,GAAA,CAAA,EAAA,SAAA,EAEA,CAAA,EADA,EAAA,EAAA,EAAA,EAAA,KACA,EAAA,GAAA,OAAA,CACA,OAAA,IAAA,EAAA,0CACA,CAEA,OADA,KAAA,IAAA,GAAA,CAAA,EAAA,QAAA,EACA,EAAA,EAAA,EACA,C,E,K,C,E,E,KCxBA,IAAA,EAAkB,EAAQ,MAC1B,EAAe,EAAQ,KAIvB,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,IAAA,EAAA,EAAA,EAAA,UACA,OAAA,EAAA,GAAA,EAAA,EAAA,EACA,C,E,K,C,E,E,KCNA,IAAA,EAAA,AAFsB,EAAQ,MAE9B,eACA,EAAA,CAAA,CAEA,CAAA,CAAA,CAAA,EAAA,CAAA,IAEA,EAAA,OAAA,CAAA,AAAA,eAAA,OAAA,E,E,I,C,E,E,KCPA,IAAA,EAAc,EAAQ,MAEtB,EAAA,MAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,GAAA,AAAA,WAAA,EAAA,GAAA,MAAA,AAAA,UAAA,6CACA,OAAA,EAAA,EACA,C,E,K,A,ICPA,IAAA,EAAA,MAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,GAAA,CACA,OAAA,EAAA,EACA,CAAI,MAAJ,EAAA,CACA,MAAA,QACA,CACA,C,E,K,C,E,E,KCRA,IAAA,EAAkB,EAAQ,MAE1B,EAAA,EACA,EAAA,KAAA,MAAA,GACA,EAAA,EAAA,GAAA,QAAA,CAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EACA,MAAA,UAAA,CAAA,AAAA,KAAA,IAAA,EAAA,GAAA,CAAA,EAAA,KAAA,EAAA,EAAA,EAAA,EAAA,GACA,C,E,K,C,E,E,KCPA,IAAA,EAAoB,EAAQ,KAE5B,CAAA,EAAA,OAAA,CAAA,GACA,CAAA,OAAA,IAAA,EACA,AAAA,UAAA,OAAA,OAAA,QAAA,A,E,K,C,E,E,KCLA,IAAA,EAAkB,EAAQ,MAC1B,EAAY,EAAQ,KAIpB,CAAA,EAAA,OAAA,CAAA,GAAA,EAAA,WAEA,OAAA,AAGA,KAHA,OAAA,cAAA,CAAA,WAA6C,EAA7C,YAAA,CACA,MAAA,GACA,SAAA,CAAA,CACA,GAAA,SAAA,AACA,E,E,K,C,E,E,KCXA,IAAA,EAAa,EAAQ,MACrB,EAAiB,EAAQ,KAEzB,EAAA,EAAA,OAAA,AAEA,CAAA,EAAA,OAAA,CAAA,EAAA,IAAA,cAAA,IAAA,CAAA,OAAA,G,E,K,C,E,E,KCLA,IAAA,EAAa,EAAQ,MACrB,EAAa,EAAQ,MACrB,EAAa,EAAQ,MACrB,EAAU,EAAQ,MAClB,EAAoB,EAAQ,MAC5B,EAAwB,EAAQ,MAEhC,EAAA,EAAA,MAAA,CACA,EAAA,EAAA,OACA,EAAA,EAAA,EAAA,GAAA,EAAA,EAAA,GAAA,EAAA,aAAA,EAAA,CAEA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EAKI,OAJJ,EAAA,EAAA,IACA,CAAA,CAAA,CAAA,EAAA,CAAA,GAAA,EAAA,EAAA,GACA,CAAA,CAAA,EAAA,CACA,EAAA,UAAA,EAHA,EAIA,CAAA,CAAA,EAAA,AACA,C,E,K,C,E,E,KCjBA,IAAA,EAAQ,EAAQ,MAChB,EAAkB,EAAQ,MAC1B,EAAgB,EAAQ,MACxB,EAAe,EAAQ,KACvB,EAAwB,EAAQ,MAChC,EAA4B,EAAQ,KACpC,EAAe,EAAQ,KACvB,EAAY,EAAQ,MACpB,EAAmB,EAAQ,MAC3B,EAA0B,EAAQ,KAClC,EAAS,EAAQ,MACjB,EAAiB,EAAQ,KACzB,EAAS,EAAQ,MACjB,EAAa,EAAQ,MAErB,EAAA,EAAA,CACA,EAAA,EAAA,EAAA,IAAA,EACA,EAAA,EAAA,EAAA,IAAA,EAGA,EAAA,EAAA,WACA,EAAA,IAAA,CAAA,KAAA,EACA,GAEA,EAAA,EAAA,WACA,EAAA,IAAA,CAAA,KACA,GAEA,EAAA,EAAA,QAEA,EAAA,CAAA,EAAA,WAEA,GAAA,EAAA,OAAA,EAAA,GACA,GAAA,CAAA,IAAA,CAAA,EAAA,CAAA,GACA,GAAA,EAAA,MAAA,CAAA,EACA,GAAA,EAAA,OAAA,EAAA,IAEA,IACA,EAAA,EAAA,EAAA,EADA,EAAA,GAIA,IAAA,EAAA,GAAkB,EAAA,GAAW,IAA7B,CAGA,OAFA,EAAA,OAAA,YAAA,CAAA,GAEA,GACA,KAAA,GAAA,KAAA,GAAA,KAAA,GAAA,KAAA,GAAA,EAAA,EAAqD,KACrD,MAAA,GAAA,KAAA,GAAA,EAAA,EAAmC,KACnC,SAAA,EAAA,CACA,CAEA,IAAA,EAAA,EAAoB,EAAA,GAAY,IAChC,EAAA,IAAA,CAAA,CAAkB,EAAA,EAAA,EAAA,EAAA,CAAA,EAElB,CAIA,IAFA,EAAA,IAAA,CAAA,SAAA,CAAA,CAAA,CAAA,EAA8B,OAAA,EAAA,CAAA,CAAA,EAAA,CAAA,AAAA,GAE9B,EAAA,EAAkB,EAAA,EAAA,MAAA,CAAqB,IACvC,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,MAAA,CAAA,GACA,EAAA,MAAA,CAAA,EAAA,MAAA,CAAA,KAAA,GAAA,CAAA,GAAA,CAAA,EAGA,MAAA,AAAA,gBAAA,EACA,GAeA,EAAA,CAAI,OAAA,QAAA,MAAA,CAAA,EAAA,OAbJ,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,CAaI,EAAJ,CACA,KAAA,SAAA,CAAA,EACA,KAAA,IAAA,GAAA,EAAA,GAEA,IAMA,EAAA,EANA,EAAA,EAAA,IAAA,EAEA,GAAA,EAAA,OAAA,AAAA,KAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,GAEA,IAAA,EAAA,EAAA,CACA,EAAA,EAAA,GAGA,IAAA,EAAA,EAAoB,EAAA,EAAqB,IACzC,KAAA,GAAA,EAAA,EAAA,CAAA,CAAA,EAAA,EAQA,IALA,EAAA,EA1BA,SAAA,CAAA,CAAA,CAAA,SACA,AAAA,AAAA,KAAA,IAAA,EAAA,GACA,AAAA,KAAA,IAAA,EAAA,EACA,AAAA,KAAA,IAuBA,EAvBA,CAAA,AAuBA,EAvBA,EAAA,IAAA,EACA,EAAA,GAAA,EAAA,GAAA,EAAA,EACA,GAuBA,EAAA,EAAA,GACA,EAAA,EAEA,EAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,IAAA,CACA,KAAA,EAAA,GAAA,EAAA,EAAA,KAEA,OAAA,CACA,CACA,E,E,K,C,E,E,KCxGA,IAAA,EAAQ,EAAQ,MAChB,EAAe,EAAQ,KACvB,EAAiB,EAAQ,MAOzB,EAAA,CAAI,OAAA,SAAA,KAAA,CAAA,EAAA,OAJJ,AAFY,EAAQ,MAEpB,WAA8C,EAAA,EAAA,EAI1C,EAAJ,CACA,KAAA,SAAA,CAAA,EACA,OAAA,EAAA,EAAA,GACA,CACA,E,C,ECbA,EAAA,CAAA,EAGA,SAAA,EAAA,CAAA,EAEA,IAAA,EAAA,CAAA,CAAA,EAAA,CACA,GAAA,AAAA,KAAA,IAAA,EACA,OAAA,EAAA,OAAA,CAGA,IAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CACA,GAAA,EAEA,QAAA,CAAA,CACA,EAMA,OAHA,CAAA,CAAA,EAAA,CAAA,IAAA,CAAA,EAAA,OAAA,CAAA,EAAA,EAAA,OAAA,CAAA,GAGA,EAAA,OAAA,AACA,CCrBA,EAAA,CAAA,CAAA,AAAA,IACA,IAAA,EAAA,GAAA,EAAA,UAAA,CACA,IAAA,EAAA,OAAA,CACA,IAAA,EAEA,OADA,EAAA,CAAA,CAAA,EAAA,CAAiC,EAAA,CAAA,GACjC,CACA,ECNA,EAAA,CAAA,CAAA,CAAA,EAAA,KACA,IAAA,IAAA,KAAA,EACA,EAAA,CAAA,CAAA,EAAA,IAAA,CAAA,EAAA,CAAA,CAAA,EAAA,IACA,OAAA,cAAA,CAAA,EAAA,EAAA,CAAyC,WAAA,CAAA,EAAA,IAAA,CAAA,CAAA,EAAA,AAAA,EAGzC,ECPA,EAAA,CAAA,CAAA,WACA,GAAA,AAAA,UAAA,OAAA,WAAA,OAAA,WACA,GAAA,CACA,OAAA,IAAA,EAAA,AAAA,SAAA,gBACA,CAAG,MAAH,EAAA,CACA,GAAA,AAAA,UAAA,OAAA,OAAA,OAAA,MACA,CACA,ICPA,EAAA,CAAA,CAAA,CAAA,EAAA,IAAA,OAAA,SAAA,CAAA,cAAA,CAAA,IAAA,CAAA,EAAA,GCCA,EAAA,CAAA,CAAA,AAAA,IACA,aAAA,OAAA,QAAA,OAAA,WAAA,EACA,OAAA,cAAA,CAAA,EAAA,OAAA,WAAA,CAAA,CAAuD,MAAA,QAAA,GAEvD,OAAA,cAAA,CAAA,EAAA,aAAA,CAAgD,MAAA,CAAA,CAAA,EAChD,E,I,E,C,E,A,C,K,E,C,C,E,C,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,G,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,G,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,I,I,E,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,G,I,I,E,G,IMFY,EKKA,ECJA,EAQE,EGTF,EQAA,EuCUA,EQGA,ESdA,ECAA,EgBMA,ECCA,EAQA,ECdA,EckBA,EYnBA,EgBMA,EA0BA,EA4BA,EAoCA,EASA,EWdA,EGvFA,EaSA,EAWA,EGTA,EAwOA,EUqKA,EAsEA,EG7dA,EKPA,ECEA,ECAA,ECAA,EIDA,EYwFA,EzMtFA,EKKA,ECJA,EGDA,EQAA,EuCUA,EQGA,ESdA,ECAA,EgBMA,ECCA,EAQA,ECdA,EckBA,EYnBA,EgBMA,EA0BA,GA4BA,GAoCA,GASA,GWdA,GGvFA,GaSA,GAWA,GGTA,GAwOA,GUqKA,GAsEA,GG7dA,GKPA,GCEA,GCAA,GCAA,GIDA,GYwFA,G,G,C,E,E,C,C,I,E,C,C,G,C,0B,I,G,wB,I,G,mB,I,E,G,I,G,C,E,E,C,C,I,E,C,C,G,C,oB,I,G,iB,I,G,c,I,G,kB,I,G,wB,I,G,uB,I,G,oB,I,G,gB,I,G,kB,I,G,gB,I,G,kB,I,G,mB,I,G,W,I,E,iB,I,G,kB,I,G,U,I,G,e,I,G,c,I,G,iB,I,G,mB,I,G,oB,I,G,uB,I,G,Y,I,G,gB,I,G,U,I,G,mB,I,G,mB,I,G,c,I,G,e,I,G,c,I,G,uB,I,G,gB,I,G,kB,I,G,kB,I,G,a,I,G,c,I,G,a,I,G,sB,I,G,e,I,G,a,I,E,G,I,G,C,E,E,C,C,I,E,C,C,G,C,O,I,G,K,I,G,M,I,G,U,I,G,O,I,E,G,I,G,C,E,E,C,C,I,E,C,C,G,C,K,I,G,Q,I,G,Q,I,G,S,I,G,S,I,G,S,I,G,K,I,G,oB,I,G,c,I,G,iB,I,G,a,I,G,qB,I,G,a,I,E,c,I,G,Y,I,G,e,I,G,W,I,E,G,I,G,C,E9MpFL,SAAS,KA4Bd,GA1BsB,aAAlB,OAAO,QACT,CAAA,OAAc,CACZ,aAAc,WAEd,CACD,CAAA,EAGmB,aAAlB,OAAO,QAA2B,OAAO,qBAAqB,EAC1D,CAAA,OAAQ,qBAAqB,CAC3B,OAAQ,2BAA2B,EACnC,OAAQ,wBAAwB,EACtC,SAAU,CAAkB,EA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AA,KACA,EAAA,EAAA,CAAA,KACA,EAAA,EAAA,CAAA,KACA,EAAA,EAAA,CAAA,KACA,EAAA,EAAA,CAAA,KACA,EAAA,EAAA,CAAA,KACA,EAAA,EAAA,CAAA,KACA,EAAA,GAAA,CAAA,MACA,EAAA,GAAA,CAAA,MACA,EAAA,GAAA,CAAA,MAGA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CAAA,OACA,EAAA,IAAA,CA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E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,E,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,E,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,E,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,C,G,E,G,A,G,I,G,E,S,E,S,E,U,E,C,EKGG5uJ,KAAO4uJ,EAPRnuK,EAAAA,SAAAA,E,A,C,K,I,E,C,I,C,E,E,K,E,C,C,G,E,C,C,E,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AI+5G,GACOA,EAAM/hB,OAAAA,GAAY8hB,C,CAI7B,MAAA,CAAA,CAAS/xK,EAAEgwJ,cAAAA,CAAe19E,IAAAA,CAAK91D,AAAAA,GAAKA,EAAEyyI,YAAAA,CAAah3F,iBAAAA,KAAwB65G,EAAgB75G,iBAAAA,G,EAGvG,CAAA,C,E,I,C,E,K,O,c,C,E,a,C,M,C,C,G,E,W,C,K,ECzJS,EAAAi4F,WAAAA,CAA0B4T,MAAOvrJ,EAAc05J,KACzD,IAAMjhH,EAAAA,MAAiBm/F,MAAM53I,GAC7B,OAAO05J,EAAY/uJ,WAAAA,IAChB,IAAK,MAEL,QAAS,OAAA,MAAa8tC,EAAS8G,IAAAA,EAD/B,KAAK,OAAQ,OAAA,MAAa9G,EAASiuB,IAAAA,EAAAA,C,C,E,I,S,C,C,C,C,C,E,I,E,I,E,I,C,e,E,C,O,M,C,S,C,C,C,C,C,C,C,E,K,I,G,C,E,C,E,I,E,O,wB,C,E,E,C,G,C,C,Q,E,C,E,U,C,E,Q,E,E,Y,A,G,C,E,C,W,C,E,I,W,O,C,C,E,A,C,C,E,O,c,C,E,E,E,E,S,C,C,C,C,C,C,C,E,K,I,G,C,E,C,E,C,C,E,C,C,C,E,A,C,E,E,I,E,I,C,Y,E,S,C,C,C,E,I,I,K,E,Y,G,O,S,C,c,C,I,C,E,I,E,E,E,E,C,C,O,c,C,E,a,C,M,C,C,GCPzC,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,IAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,GACA,EAAA,EAAA,KAAA,E,E,I,C,E,E,K,O,c,C,E,a,C,M,C,C,G,E,Y,C,K,ECXA,IAAA,EAAA,EAAA,IAKA,CAAA,EAAA,YAAA,CAAA,MAMI,YAAYr9B,CAAAA,CAAcysG,CAAAA,CAA8BtmE,CAAAA,CAAwCumE,CAAAA,CAAAA,CAI5F,GAJ4F,IAAA,CAAAA,KAAAA,CAAAA,EAC5F8iB,IAAAA,CAAK70E,QAAAA,CAAAA,AAAW,CAAA,EAAA,EAAA3qD,GA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","sources":["","node_modules/excalibur/build/esm/excalibur.js","node_modules/excalibur/build/esm/webpack:/Director/Loader.css","node_modules/excalibur/build/esm/webpack:/Util/Toaster.css","node_modules/excalibur/build/node_modules/css-loader/dist/runtime/api.js","node_modules/excalibur/build/node_modules/css-loader/dist/runtime/sourceMaps.js","node_modules/excalibur/build/node_modules/core-js/es/array/sort.js","node_modules/excalibur/build/node_modules/core-js/es/object/keys.js","node_modules/excalibur/build/node_modules/core-js/internals/a-callable.js","node_modules/excalibur/build/node_modules/core-js/internals/an-object.js","node_modules/excalibur/build/node_modules/core-js/internals/array-includes.js","node_modules/excalibur/build/node_modules/core-js/internals/array-method-is-strict.js","node_modules/excalibur/build/node_modules/core-js/internals/array-slice.js","node_modules/excalibur/build/node_modules/core-js/internals/array-sort.js","node_modules/excalibur/build/node_modules/core-js/internals/classof-raw.js","node_modules/excalibur/build/node_modules/core-js/internals/classof.js","node_modules/excalibur/build/node_modules/core-js/internals/copy-constructor-properties.js","node_modules/excalibur/build/node_modules/core-js/internals/create-non-enumerable-property.js","node_modules/excalibur/build/node_modules/core-js/internals/create-property-descriptor.js","node_modules/excalibur/build/node_modules/core-js/internals/define-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/define-global-property.js","node_modules/excalibur/build/node_modules/core-js/internals/delete-property-or-throw.js","node_modules/excalibur/build/node_modules/core-js/internals/descriptors.js","node_modules/excalibur/build/node_modules/core-js/internals/document-create-element.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-ff-version.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-is-ie-or-edge.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-user-agent.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-v8-version.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-webkit-version.js","node_modules/excalibur/build/node_modules/core-js/internals/entry-unbind.js","node_modules/excalibur/build/node_modules/core-js/internals/enum-bug-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/export.js","node_modules/excalibur/build/node_modules/core-js/internals/fails.js","node_modules/excalibur/build/node_modules/core-js/internals/function-bind-native.js","node_modules/excalibur/build/node_modules/core-js/internals/function-call.js","node_modules/excalibur/build/node_modules/core-js/internals/function-name.js","node_modules/excalibur/build/node_modules/core-js/internals/function-uncurry-this.js","node_modules/excalibur/build/node_modules/core-js/internals/get-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/get-method.js","node_modules/excalibur/build/node_modules/core-js/internals/global.js","node_modules/excalibur/build/node_modules/core-js/internals/has-own-property.js","node_modules/excalibur/build/node_modules/core-js/internals/hidden-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/ie8-dom-define.js","node_modules/excalibur/build/node_modules/core-js/internals/indexed-object.js","node_modules/excalibur/build/node_modules/core-js/internals/inspect-source.js","node_modules/excalibur/build/node_modules/core-js/internals/internal-state.js","node_modules/excalibur/build/node_modules/core-js/internals/is-callable.js","node_modules/excalibur/build/node_modules/core-js/internals/is-forced.js","node_modules/excalibur/build/node_modules/core-js/internals/is-null-or-undefined.js","node_modules/excalibur/build/node_modules/core-js/internals/is-object.js","node_modules/excalibur/build/node_modules/core-js/internals/is-pure.js","node_modules/excalibur/build/node_modules/core-js/internals/is-symbol.js","node_modules/excalibur/build/node_modules/core-js/internals/length-of-array-like.js","node_modules/excalibur/build/node_modules/core-js/internals/make-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/math-trunc.js","node_modules/excalibur/build/node_modules/core-js/internals/object-define-property.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-descriptor.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-names.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-symbols.js","node_modules/excalibur/build/node_modules/core-js/internals/object-is-prototype-of.js","node_modules/excalibur/build/node_modules/core-js/internals/object-keys-internal.js","node_modules/excalibur/build/node_modules/core-js/internals/object-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/object-property-is-enumerable.js","node_modules/excalibur/build/node_modules/core-js/internals/ordinary-to-primitive.js","node_modules/excalibur/build/node_modules/core-js/internals/own-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/path.js","node_modules/excalibur/build/node_modules/core-js/internals/require-object-coercible.js","node_modules/excalibur/build/node_modules/core-js/internals/shared-key.js","node_modules/excalibur/build/node_modules/core-js/internals/shared-store.js","node_modules/excalibur/build/node_modules/core-js/internals/shared.js","node_modules/excalibur/build/node_modules/core-js/internals/symbol-constructor-detection.js","node_modules/excalibur/build/node_modules/core-js/internals/to-absolute-index.js","node_modules/excalibur/build/node_modules/core-js/internals/to-indexed-object.js","node_modules/excalibur/build/node_modules/core-js/internals/to-integer-or-infinity.js","node_modules/excalibur/build/node_modules/core-js/internals/to-length.js","node_modules/excalibur/build/node_modules/core-js/internals/to-object.js","node_modules/excalibur/build/node_modules/core-js/internals/to-primitive.js","node_modules/excalibur/build/node_modules/core-js/internals/to-property-key.js","node_modules/excalibur/build/node_modules/core-js/internals/to-string-tag-support.js","node_modules/excalibur/build/node_modules/core-js/internals/to-string.js","node_modules/excalibur/build/node_modules/core-js/internals/try-to-string.js","node_modules/excalibur/build/node_modules/core-js/internals/uid.js","node_modules/excalibur/build/node_modules/core-js/internals/use-symbol-as-uid.js","node_modules/excalibur/build/node_modules/core-js/internals/v8-prototype-define-bug.js","node_modules/excalibur/build/node_modules/core-js/internals/weak-map-basic-detection.js","node_modules/excalibur/build/node_modules/core-js/internals/well-known-symbol.js","node_modules/excalibur/build/node_modules/core-js/modules/es.array.sort.js","node_modules/excalibur/build/node_modules/core-js/modules/es.object.keys.js","node_modules/excalibur/build/esm/webpack:/webpack/bootstrap","node_modules/excalibur/build/esm/webpack:/webpack/runtime/compat get default export","node_modules/excalibur/build/esm/webpack:/webpack/runtime/define property getters","node_modules/excalibur/build/esm/webpack:/webpack/runtime/global","node_modules/excalibur/build/esm/webpack:/webpack/runtime/hasOwnProperty shorthand","node_modules/excalibur/build/esm/webpack:/webpack/runtime/make namespace object","node_modules/excalibur/build/esm/webpack:/Polyfill.ts","node_modules/excalibur/build/esm/webpack:/Flags.ts","node_modules/excalibur/build/esm/webpack:/Id.ts","node_modules/excalibur/build/esm/webpack:/Util/Future.ts","node_modules/excalibur/build/esm/webpack:/EventEmitter.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerScope.ts","node_modules/excalibur/build/esm/webpack:/Math/Random.ts","node_modules/excalibur/build/esm/webpack:/Math/util.ts","node_modules/excalibur/build/esm/webpack:/Math/vector.ts","node_modules/excalibur/build/esm/webpack:/Color.ts","node_modules/excalibur/build/esm/webpack:/Util/Log.ts","node_modules/excalibur/build/esm/webpack:/Collision/Side.ts","node_modules/excalibur/build/esm/webpack:/Collision/BoundingBox.ts","node_modules/excalibur/build/esm/webpack:/Util/Util.ts","node_modules/excalibur/build/esm/webpack:/Math/matrix.ts","node_modules/excalibur/build/esm/webpack:/Math/affine-matrix.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/transform-stack.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/state-stack.ts","node_modules/excalibur/build/esm/webpack:/Resources/Resource.ts","node_modules/excalibur/build/esm/webpack:/Util/Watch.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Graphic.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Sprite.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Filtering.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/texture-loader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/ImageSource.ts","node_modules/excalibur/build/esm/webpack:/Graphics/SpriteFont.ts","node_modules/excalibur/build/esm/webpack:/Graphics/SpriteSheet.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/debug-font.png","node_modules/excalibur/build/esm/webpack:/Graphics/Context/debug-text.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/render-source.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/render-target.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/webgl-util.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/shader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/vertex-buffer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/vertex-layout.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsDiagnostics.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-pass-painter.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/quad-index-buffer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.ts","node_modules/excalibur/build/esm/webpack:/Util/Pool.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/draw-call.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/material.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/material-renderer/material-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/ExcaliburGraphicsContextWebGL.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts","node_modules/excalibur/build/esm/webpack:/Screen.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/AudioContext.ts","node_modules/excalibur/build/esm/webpack:/Util/WebAudio.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Raster.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Canvas.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/AudioImplementation.ts","node_modules/excalibur/build/esm/webpack:/Util/StateMachine.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/WebAudioInstance.ts","node_modules/excalibur/build/esm/webpack:/Events.ts","node_modules/excalibur/build/esm/webpack:/Events/MediaEvents.ts","node_modules/excalibur/build/esm/webpack:/Util/Sound.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/Sound.ts","node_modules/excalibur/build/esm/webpack:/Director/DefaultLoader.ts","node_modules/excalibur/build/esm/webpack:/Util/DrawUtil.ts","node_modules/excalibur/build/esm/webpack:/Director/Loader.logo.png","node_modules/excalibur/build/esm/webpack:/Director/Loader.ts","node_modules/excalibur/build/esm/webpack:/Util/Detector.ts","node_modules/excalibur/build/esm/webpack:/Collision/CollisionType.ts","node_modules/excalibur/build/esm/webpack:/Math/coord-plane.ts","node_modules/excalibur/build/esm/webpack:/Math/vector-view.ts","node_modules/excalibur/build/esm/webpack:/Math/watch-vector.ts","node_modules/excalibur/build/esm/webpack:/Math/transform.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Component.ts","node_modules/excalibur/build/esm/webpack:/Util/Observable.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Components/TransformComponent.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Components/MotionComponent.ts","node_modules/excalibur/build/esm/webpack:/Collision/Group/CollisionGroupManager.ts","node_modules/excalibur/build/esm/webpack:/Collision/Group/CollisionGroup.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/Pair.ts","node_modules/excalibur/build/esm/webpack:/Math/projection.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/DynamicTree.ts","node_modules/excalibur/build/esm/webpack:/Math/ray.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/DynamicTreeCollisionProcessor.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/Collider.ts","node_modules/excalibur/build/esm/webpack:/Collision/SolverStrategy.ts","node_modules/excalibur/build/esm/webpack:/Collision/Physics.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/ContactBias.ts","node_modules/excalibur/build/esm/webpack:/Collision/PhysicsConfig.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CompositeCollider.ts","node_modules/excalibur/build/esm/webpack:/Math/line-segment.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/ClosestLineJumpTable.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CircleCollider.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/CollisionContact.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/SeparatingAxis.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CollisionJumpTable.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/EdgeCollider.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Debug.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/PolygonCollider.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/Shape.ts","node_modules/excalibur/build/esm/webpack:/Collision/ColliderComponent.ts","node_modules/excalibur/build/esm/webpack:/Collision/BodyComponent.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Entity.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Rectangle.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Circle.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerComponent.ts","node_modules/excalibur/build/esm/webpack:/Util/EasingFunctions.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionQueue.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Repeat.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RepeatForever.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/MoveBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/MoveTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/RotationType.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RotateTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RotateBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ScaleTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ScaleBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/CallMethod.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/EaseTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/EaseBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Blink.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Fade.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Delay.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Die.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Follow.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Meet.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionContext.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionsComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontCommon.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontTextInstance.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontCache.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Font.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Text.ts","node_modules/excalibur/build/esm/webpack:/Actor.ts","node_modules/excalibur/build/esm/webpack:/ScreenElement.ts","node_modules/excalibur/build/esm/webpack:/Timer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/ParallaxComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/DebugGraphicsComponent.ts","node_modules/excalibur/build/esm/webpack:/TileMap/TileMap.ts","node_modules/excalibur/build/esm/webpack:/Camera.ts","node_modules/excalibur/build/esm/webpack:/Trigger.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Priority.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/System.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/EntityManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Query.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/TagQuery.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/QueryManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/SystemManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/World.ts","node_modules/excalibur/build/esm/webpack:/Collision/Integrator.ts","node_modules/excalibur/build/esm/webpack:/Collision/MotionSystem.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/ArcadeSolver.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/ContactConstraintPoint.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/RealisticSolver.ts","node_modules/excalibur/build/esm/webpack:/Collision/CollisionSystem.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Animation.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsGroup.ts","node_modules/excalibur/build/esm/webpack:/Configurable.ts","node_modules/excalibur/build/esm/webpack:/Particles.ts","node_modules/excalibur/build/esm/webpack:/Graphics/TransformInterpolation.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsSystem.ts","node_modules/excalibur/build/esm/webpack:/Debug/DebugSystem.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerSystem.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionsSystem.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricEntityComponent.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricEntitySystem.ts","node_modules/excalibur/build/esm/webpack:/Graphics/OffscreenSystem.ts","node_modules/excalibur/build/esm/webpack:/Collision/PhysicsWorld.ts","node_modules/excalibur/build/esm/webpack:/Input/Gamepad.ts","node_modules/excalibur/build/esm/webpack:/Input/InputMapper.ts","node_modules/excalibur/build/esm/webpack:/Util/IFrame.ts","node_modules/excalibur/build/esm/webpack:/Input/Keyboard.ts","node_modules/excalibur/build/esm/webpack:/Math/global-coordinates.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerEvent.ts","node_modules/excalibur/build/esm/webpack:/Input/WheelEvent.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerAbstraction.ts","node_modules/excalibur/build/esm/webpack:/Input/WheelDeltaMode.ts","node_modules/excalibur/build/esm/webpack:/Input/NativePointerButton.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerButton.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerType.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerEventReceiver.ts","node_modules/excalibur/build/esm/webpack:/Input/InputHost.ts","node_modules/excalibur/build/esm/webpack:/Scene.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ColorBlindnessMode.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/color-blind-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ScreenShader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ColorBlindnessPostProcessor.ts","node_modules/excalibur/build/esm/webpack:/Debug/DebugFlags.ts","node_modules/excalibur/build/esm/webpack:/Debug/DebugConfig.ts","node_modules/excalibur/build/esm/webpack:/Util/Browser.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/ExcaliburGraphicsContext.ts","node_modules/excalibur/build/esm/webpack:/Util/Fps.ts","node_modules/excalibur/build/esm/webpack:/Util/Clock.ts","node_modules/excalibur/build/esm/webpack:/Util/Toaster.ts","node_modules/excalibur/build/esm/webpack:/Director/Director.ts","node_modules/excalibur/build/esm/webpack:/Engine.ts","node_modules/excalibur/build/esm/webpack:/Math/Index.ts","node_modules/excalibur/build/esm/webpack:/Debug/index.ts","node_modules/excalibur/build/esm/webpack:/EventDispatcher.ts","node_modules/excalibur/build/esm/webpack:/Label.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricMap.ts","node_modules/excalibur/build/esm/webpack:/TileMap/index.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ActionSequence.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ParallelActions.ts","node_modules/excalibur/build/esm/webpack:/Actions/Index.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/QuadTree.ts","node_modules/excalibur/build/esm/webpack:/Collision/Index.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/LifecycleEvents.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/Index.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/Index.ts","node_modules/excalibur/build/esm/webpack:/Resources/Gif.ts","node_modules/excalibur/build/esm/webpack:/Resources/Font.ts","node_modules/excalibur/build/esm/webpack:/Resources/Index.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/index.ts","node_modules/excalibur/build/esm/webpack:/Util/Coroutine.ts","node_modules/excalibur/build/esm/webpack:/Director/Transition.ts","node_modules/excalibur/build/esm/webpack:/Director/FadeInOut.ts","node_modules/excalibur/build/esm/webpack:/Director/CrossFade.ts","node_modules/excalibur/build/esm/webpack:/Director/index.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Line.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Polygon.ts","node_modules/excalibur/build/esm/webpack:/Graphics/index.ts","node_modules/excalibur/build/esm/webpack:/Input/Index.ts","node_modules/excalibur/build/esm/webpack:/Util/Index.ts","node_modules/excalibur/build/esm/webpack:/Util/Decorators.ts","node_modules/excalibur/build/esm/webpack:/Util/Semaphore.ts","node_modules/excalibur/build/esm/webpack:/index.ts","src/main.ts","src/player.ts","src/resources.ts","node_modules/@excaliburjs/plugin-ldtk/dist/excalibur-ldtk.min.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/universalModuleDefinition","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/utils.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/compareVersions.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/compare.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/satisfies.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/compare-versions/lib/esm/validate.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/entity-layer.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/file-loader.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/index.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/intgrid-layer.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/ldtk-resource.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/level-resource.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/level.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/loader-cache.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/path-util.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/tile-layer.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/tileset.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/src/types.ts","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/ZodError.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/errors.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/external.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/helpers/errorUtil.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/helpers/parseUtil.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/helpers/typeAliases.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/helpers/util.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/index.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/locales/en.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/node_modules/zod/lib/types.js","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/external umd {\"commonjs\":\"excalibur\",\"commonjs2\":\"excalibur\",\"amd\":\"excalibur\",\"root\":\"ex\"}","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/bootstrap","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/runtime/define property getters","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/runtime/hasOwnProperty shorthand","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/runtime/make namespace object","node_modules/@excaliburjs/plugin-ldtk/dist/webpack:/ex.Plugin.Ldtk/webpack/startup","node_modules/@parcel/runtime-js/lib/runtime-ff40237c10907382.js","node_modules/@parcel/runtime-js/lib/runtime-6179d0fd6488673c.js","node_modules/@parcel/runtime-js/lib/runtime-98d03baec8dc2a57.js","node_modules/@parcel/runtime-js/lib/runtime-55a51091189a0419.js","node_modules/@parcel/runtime-js/lib/runtime-88268e1a7c58dd66.js","src/config.ts"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\nfunction $parcel$interopDefault(a) {\n return a && a.__esModule ? a.default : a;\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequire4b3c\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequire4b3c\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"3MXpL\", function(module, exports) {\n\n$parcel$export(module.exports, \"ActionCompleteEvent\", () => $2c23f148d58cd887$export$f05c91211c084e80);\n$parcel$export(module.exports, \"ActionContext\", () => $2c23f148d58cd887$export$e04e17a44f37debc);\n$parcel$export(module.exports, \"ActionQueue\", () => $2c23f148d58cd887$export$dfcd1bb88f6d711b);\n$parcel$export(module.exports, \"ActionSequence\", () => $2c23f148d58cd887$export$89f31cec7c284d42);\n$parcel$export(module.exports, \"ActionStartEvent\", () => $2c23f148d58cd887$export$a3f070f3e473c3b);\n$parcel$export(module.exports, \"ActionsComponent\", () => $2c23f148d58cd887$export$856e7d6d9d698871);\n$parcel$export(module.exports, \"ActionsSystem\", () => $2c23f148d58cd887$export$caffe607ed29fca1);\n$parcel$export(module.exports, \"ActivateEvent\", () => $2c23f148d58cd887$export$adc62e83dbcda319);\n$parcel$export(module.exports, \"Actor\", () => $2c23f148d58cd887$export$f73d3eb6fd876d80);\n$parcel$export(module.exports, \"AddedComponent\", () => $2c23f148d58cd887$export$da248c61eea53296);\n$parcel$export(module.exports, \"AffineMatrix\", () => $2c23f148d58cd887$export$f0455ab08e3fbd0e);\n$parcel$export(module.exports, \"Animation\", () => $2c23f148d58cd887$export$c35d437ae5945fcd);\n$parcel$export(module.exports, \"AnimationDirection\", () => $2c23f148d58cd887$export$67ee29bab3792d4c);\n$parcel$export(module.exports, \"AnimationEvents\", () => $2c23f148d58cd887$export$d230853e97069d46);\n$parcel$export(module.exports, \"AnimationStrategy\", () => $2c23f148d58cd887$export$6cfd78ddb48c90c6);\n$parcel$export(module.exports, \"ArcadeSolver\", () => $2c23f148d58cd887$export$3769e64eb87b5ecc);\n$parcel$export(module.exports, \"AudioContextFactory\", () => $2c23f148d58cd887$export$54dc36bc2fac5425);\n$parcel$export(module.exports, \"Axes\", () => $2c23f148d58cd887$export$387a78ab20784494);\n$parcel$export(module.exports, \"Axis\", () => $2c23f148d58cd887$export$d06866a9fb0606da);\n$parcel$export(module.exports, \"BaseAlign\", () => $2c23f148d58cd887$export$83c931ba0d3bbaf5);\n$parcel$export(module.exports, \"Blink\", () => $2c23f148d58cd887$export$1a553341cd0b8415);\n$parcel$export(module.exports, \"BodyComponent\", () => $2c23f148d58cd887$export$43416332cf06b1f);\n$parcel$export(module.exports, \"BoundingBox\", () => $2c23f148d58cd887$export$63080c4de6cfc362);\n$parcel$export(module.exports, \"BroadphaseStrategy\", () => $2c23f148d58cd887$export$fa45ecb18b97ae89);\n$parcel$export(module.exports, \"BrowserComponent\", () => $2c23f148d58cd887$export$c24f8f35353a1e26);\n$parcel$export(module.exports, \"BrowserEvents\", () => $2c23f148d58cd887$export$8688def55452cbca);\n$parcel$export(module.exports, \"Buttons\", () => $2c23f148d58cd887$export$665d5a662b7213f3);\n$parcel$export(module.exports, \"Camera\", () => $2c23f148d58cd887$export$79f141de891a5fed);\n$parcel$export(module.exports, \"CameraEvents\", () => $2c23f148d58cd887$export$41606648ac8a293c);\n$parcel$export(module.exports, \"Canvas\", () => $2c23f148d58cd887$export$8d01c972ee8b14a9);\n$parcel$export(module.exports, \"Circle\", () => $2c23f148d58cd887$export$c89a927ffc67e6fa);\n$parcel$export(module.exports, \"CircleCollider\", () => $2c23f148d58cd887$export$e2395b697f5a931f);\n$parcel$export(module.exports, \"Clock\", () => $2c23f148d58cd887$export$9735c82c4bae3302);\n$parcel$export(module.exports, \"ClosestLine\", () => $2c23f148d58cd887$export$44e6803d1d57f89a);\n$parcel$export(module.exports, \"ClosestLineJumpTable\", () => $2c23f148d58cd887$export$1ed419d47673a225);\n$parcel$export(module.exports, \"Collider\", () => $2c23f148d58cd887$export$b7c6eef0ebb06133);\n$parcel$export(module.exports, \"ColliderComponent\", () => $2c23f148d58cd887$export$3c9e91dc1b611d2e);\n$parcel$export(module.exports, \"CollisionContact\", () => $2c23f148d58cd887$export$ce0ca64520c7bfd2);\n$parcel$export(module.exports, \"CollisionEndEvent\", () => $2c23f148d58cd887$export$83caf30c40e9d4b8);\n$parcel$export(module.exports, \"CollisionGroup\", () => $2c23f148d58cd887$export$4df0464d8c812c98);\n$parcel$export(module.exports, \"CollisionGroupManager\", () => $2c23f148d58cd887$export$55e924fc640a8405);\n$parcel$export(module.exports, \"CollisionJumpTable\", () => $2c23f148d58cd887$export$fbd6eb86d6a3f08);\n$parcel$export(module.exports, \"CollisionPostSolveEvent\", () => $2c23f148d58cd887$export$7cd2649c3408da6c);\n$parcel$export(module.exports, \"CollisionPreSolveEvent\", () => $2c23f148d58cd887$export$897cd666d936ac4c);\n$parcel$export(module.exports, \"CollisionStartEvent\", () => $2c23f148d58cd887$export$cf976780b3106589);\n$parcel$export(module.exports, \"CollisionSystem\", () => $2c23f148d58cd887$export$5dcfde0f6b96512b);\n$parcel$export(module.exports, \"CollisionType\", () => $2c23f148d58cd887$export$ddb2ed749236e720);\n$parcel$export(module.exports, \"Color\", () => $2c23f148d58cd887$export$892596cec99bc70e);\n$parcel$export(module.exports, \"ColorBlindFlags\", () => $2c23f148d58cd887$export$8ed4b5bb5352fe14);\n$parcel$export(module.exports, \"ColorBlindnessMode\", () => $2c23f148d58cd887$export$c46090c9df657074);\n$parcel$export(module.exports, \"ColorBlindnessPostProcessor\", () => $2c23f148d58cd887$export$b3bf2ffaa538264b);\n$parcel$export(module.exports, \"Component\", () => $2c23f148d58cd887$export$16fa2f45be04daa8);\n$parcel$export(module.exports, \"CompositeCollider\", () => $2c23f148d58cd887$export$d16a7c95008e315d);\n$parcel$export(module.exports, \"Configurable\", () => $2c23f148d58cd887$export$abda45806f5adbae);\n$parcel$export(module.exports, \"ConsoleAppender\", () => $2c23f148d58cd887$export$e5a30aa3d28b26e2);\n$parcel$export(module.exports, \"ContactConstraintPoint\", () => $2c23f148d58cd887$export$de7807bd8bd828df);\n$parcel$export(module.exports, \"ContactEndEvent\", () => $2c23f148d58cd887$export$1bdfb0c7c42d632d);\n$parcel$export(module.exports, \"ContactSolveBias\", () => $2c23f148d58cd887$export$bf92f329076cd7a3);\n$parcel$export(module.exports, \"ContactStartEvent\", () => $2c23f148d58cd887$export$71de6146fb6d69d2);\n$parcel$export(module.exports, \"CoordPlane\", () => $2c23f148d58cd887$export$71efaa2be447940c);\n$parcel$export(module.exports, \"CrossFade\", () => $2c23f148d58cd887$export$d78c8c6074541cf2);\n$parcel$export(module.exports, \"DeactivateEvent\", () => $2c23f148d58cd887$export$7d34ad93c25aa8e7);\n$parcel$export(module.exports, \"Debug\", () => $2c23f148d58cd887$export$153e5dc2c098b35c);\n$parcel$export(module.exports, \"DebugConfig\", () => $2c23f148d58cd887$export$f7c1896972d6c454);\n$parcel$export(module.exports, \"DebugGraphicsComponent\", () => $2c23f148d58cd887$export$c3e6e677dda8521a);\n$parcel$export(module.exports, \"DebugSystem\", () => $2c23f148d58cd887$export$e52858e61b0ea117);\n$parcel$export(module.exports, \"DebugText\", () => $2c23f148d58cd887$export$3d1f12550a40f54d);\n$parcel$export(module.exports, \"DefaultAntialiasOptions\", () => $2c23f148d58cd887$export$4544b2d7eff33859);\n$parcel$export(module.exports, \"DefaultLoader\", () => $2c23f148d58cd887$export$dd6b48f99ee8a36);\n$parcel$export(module.exports, \"DefaultPhysicsConfig\", () => $2c23f148d58cd887$export$aafe01318a900193);\n$parcel$export(module.exports, \"DefaultPixelArtOptions\", () => $2c23f148d58cd887$export$fd69b6a3b7f47e29);\n$parcel$export(module.exports, \"DegreeOfFreedom\", () => $2c23f148d58cd887$export$e1545123b54f6785);\n$parcel$export(module.exports, \"Delay\", () => $2c23f148d58cd887$export$7419ff430885d61c);\n$parcel$export(module.exports, \"DeprecatedStaticToConfig\", () => $2c23f148d58cd887$export$a340d4e5571cbd07);\n$parcel$export(module.exports, \"Detector\", () => $2c23f148d58cd887$export$e695250628cde35);\n$parcel$export(module.exports, \"Die\", () => $2c23f148d58cd887$export$c5e124f7bab3d492);\n$parcel$export(module.exports, \"Direction\", () => $2c23f148d58cd887$export$cacd6541cfeeb6c1);\n$parcel$export(module.exports, \"Director\", () => $2c23f148d58cd887$export$a74d557191881f82);\n$parcel$export(module.exports, \"DirectorEvents\", () => $2c23f148d58cd887$export$99bf88c530739783);\n$parcel$export(module.exports, \"DisplayMode\", () => $2c23f148d58cd887$export$4b7264771109adb6);\n$parcel$export(module.exports, \"DynamicTree\", () => $2c23f148d58cd887$export$62053d374d83dfb1);\n$parcel$export(module.exports, \"DynamicTreeCollisionProcessor\", () => $2c23f148d58cd887$export$d7078bb1ea3ba3f2);\n$parcel$export(module.exports, \"EX_VERSION\", () => $2c23f148d58cd887$export$86ae8da356d53161);\n$parcel$export(module.exports, \"EaseBy\", () => $2c23f148d58cd887$export$62230588c4867d28);\n$parcel$export(module.exports, \"EaseTo\", () => $2c23f148d58cd887$export$df007b1d5b86e25a);\n$parcel$export(module.exports, \"EasingFunctions\", () => $2c23f148d58cd887$export$6ff391a2049fdf40);\n$parcel$export(module.exports, \"EdgeCollider\", () => $2c23f148d58cd887$export$89e5ccdc4c19a8f6);\n$parcel$export(module.exports, \"ElasticToActorStrategy\", () => $2c23f148d58cd887$export$2cbc8fe61dd10773);\n$parcel$export(module.exports, \"EmitterType\", () => $2c23f148d58cd887$export$d45269226a4bbdc1);\n$parcel$export(module.exports, \"Engine\", () => $2c23f148d58cd887$export$2c3b404bf3a77a1f);\n$parcel$export(module.exports, \"EngineEvents\", () => $2c23f148d58cd887$export$20434e7e042d306a);\n$parcel$export(module.exports, \"EnterTriggerEvent\", () => $2c23f148d58cd887$export$462adefbb095232e);\n$parcel$export(module.exports, \"EnterViewPortEvent\", () => $2c23f148d58cd887$export$83f8212621739c1f);\n$parcel$export(module.exports, \"Entity\", () => $2c23f148d58cd887$export$bc644a473284d944);\n$parcel$export(module.exports, \"EntityEvents\", () => $2c23f148d58cd887$export$66b8a9cb33a156c);\n$parcel$export(module.exports, \"EntityManager\", () => $2c23f148d58cd887$export$c7b7134fd828a5);\n$parcel$export(module.exports, \"EventDispatcher\", () => $2c23f148d58cd887$export$ec8b666c5fe2c75a);\n$parcel$export(module.exports, \"EventEmitter\", () => $2c23f148d58cd887$export$4fae95256245c8c0);\n$parcel$export(module.exports, \"EventTypes\", () => $2c23f148d58cd887$export$86d9a347f2bf71d6);\n$parcel$export(module.exports, \"Events\", () => $2c23f148d58cd887$export$ada873a34909da65);\n$parcel$export(module.exports, \"ExResponse\", () => $2c23f148d58cd887$export$afee3afd6be961ec);\n$parcel$export(module.exports, \"ExcaliburGraphicsContext2DCanvas\", () => $2c23f148d58cd887$export$c03216fb3a7a2f87);\n$parcel$export(module.exports, \"ExcaliburGraphicsContextWebGL\", () => $2c23f148d58cd887$export$81940238f313e11f);\n$parcel$export(module.exports, \"ExitTriggerEvent\", () => $2c23f148d58cd887$export$40f8f9a8f94db930);\n$parcel$export(module.exports, \"ExitViewPortEvent\", () => $2c23f148d58cd887$export$c579e21b95165414);\n$parcel$export(module.exports, \"Fade\", () => $2c23f148d58cd887$export$c983850c6c9d8b0e);\n$parcel$export(module.exports, \"FadeInOut\", () => $2c23f148d58cd887$export$be5b6c6ac24b4683);\n$parcel$export(module.exports, \"Flags\", () => $2c23f148d58cd887$export$434ba092ed0eee4e);\n$parcel$export(module.exports, \"Follow\", () => $2c23f148d58cd887$export$455f05776f1ba8ba);\n$parcel$export(module.exports, \"Font\", () => $2c23f148d58cd887$export$89abf52a030e56ee);\n$parcel$export(module.exports, \"FontCache\", () => $2c23f148d58cd887$export$549c899505235621);\n$parcel$export(module.exports, \"FontSource\", () => $2c23f148d58cd887$export$1f6d1255105a925c);\n$parcel$export(module.exports, \"FontStyle\", () => $2c23f148d58cd887$export$23b468d4ca3f8c96);\n$parcel$export(module.exports, \"FontUnit\", () => $2c23f148d58cd887$export$6976e674e6d5804c);\n$parcel$export(module.exports, \"FpsSampler\", () => $2c23f148d58cd887$export$420acfc1740638d3);\n$parcel$export(module.exports, \"FrameStats\", () => $2c23f148d58cd887$export$e84927905accfe51);\n$parcel$export(module.exports, \"Future\", () => $2c23f148d58cd887$export$c9d7bf589772a8ce);\n$parcel$export(module.exports, \"GameEvent\", () => $2c23f148d58cd887$export$d5011a4647754c9b);\n$parcel$export(module.exports, \"GameStartEvent\", () => $2c23f148d58cd887$export$b8c6aa234afa01bc);\n$parcel$export(module.exports, \"GameStopEvent\", () => $2c23f148d58cd887$export$6c3776220abeb931);\n$parcel$export(module.exports, \"Gamepad\", () => $2c23f148d58cd887$export$27a9cd7ebdd38262);\n$parcel$export(module.exports, \"GamepadAxisEvent\", () => $2c23f148d58cd887$export$fb1b94e06ba8ebc8);\n$parcel$export(module.exports, \"GamepadButtonEvent\", () => $2c23f148d58cd887$export$3d953a2d86354b5f);\n$parcel$export(module.exports, \"GamepadConnectEvent\", () => $2c23f148d58cd887$export$88528019d270f582);\n$parcel$export(module.exports, \"GamepadDisconnectEvent\", () => $2c23f148d58cd887$export$402da60b1c009e43);\n$parcel$export(module.exports, \"Gamepads\", () => $2c23f148d58cd887$export$757ccd1717b77f48);\n$parcel$export(module.exports, \"Gif\", () => $2c23f148d58cd887$export$48ebf29bc7cb1dd7);\n$parcel$export(module.exports, \"GlobalCoordinates\", () => $2c23f148d58cd887$export$3c8c04bde7eed7cb);\n$parcel$export(module.exports, \"Graphic\", () => $2c23f148d58cd887$export$adfa9d260876eca5);\n$parcel$export(module.exports, \"GraphicsComponent\", () => $2c23f148d58cd887$export$6c043ed3a716859a);\n$parcel$export(module.exports, \"GraphicsGroup\", () => $2c23f148d58cd887$export$9f9afb456a8bef30);\n$parcel$export(module.exports, \"GraphicsSystem\", () => $2c23f148d58cd887$export$1033a6fa0779f4f5);\n$parcel$export(module.exports, \"HiddenEvent\", () => $2c23f148d58cd887$export$38f8109d2b8f43ef);\n$parcel$export(module.exports, \"HorizontalFirst\", () => $2c23f148d58cd887$export$b5aa7fe3676b74a9);\n$parcel$export(module.exports, \"ImageFiltering\", () => $2c23f148d58cd887$export$5213deb2877a09f2);\n$parcel$export(module.exports, \"ImageSource\", () => $2c23f148d58cd887$export$280e9a68c3ffd919);\n$parcel$export(module.exports, \"InitializeEvent\", () => $2c23f148d58cd887$export$49a1ecce8d203);\n$parcel$export(module.exports, \"Input\", () => $2c23f148d58cd887$export$f5b8910cec6cf069);\n$parcel$export(module.exports, \"InputHost\", () => $2c23f148d58cd887$export$99f13cbf742a0580);\n$parcel$export(module.exports, \"InputMapper\", () => $2c23f148d58cd887$export$2ae6ec0f10d96242);\n$parcel$export(module.exports, \"Integrator\", () => $2c23f148d58cd887$export$d379657aa3df1705);\n$parcel$export(module.exports, \"IsometricEntityComponent\", () => $2c23f148d58cd887$export$ffed6a4cd9a88787);\n$parcel$export(module.exports, \"IsometricEntitySystem\", () => $2c23f148d58cd887$export$7705889256a9371a);\n$parcel$export(module.exports, \"IsometricMap\", () => $2c23f148d58cd887$export$539f65e788a82c62);\n$parcel$export(module.exports, \"IsometricTile\", () => $2c23f148d58cd887$export$851e6d93385b6ad2);\n$parcel$export(module.exports, \"KeyEvent\", () => $2c23f148d58cd887$export$4b0c1c390bf9a356);\n$parcel$export(module.exports, \"Keyboard\", () => $2c23f148d58cd887$export$16e4d70cc375e707);\n$parcel$export(module.exports, \"Keys\", () => $2c23f148d58cd887$export$4b0075e5ea5e1f26);\n$parcel$export(module.exports, \"KillEvent\", () => $2c23f148d58cd887$export$f3a6c1ca682fd40f);\n$parcel$export(module.exports, \"Label\", () => $2c23f148d58cd887$export$b04be29aa201d4f5);\n$parcel$export(module.exports, \"LimitCameraBoundsStrategy\", () => $2c23f148d58cd887$export$b3509fba7d85d294);\n$parcel$export(module.exports, \"Line\", () => $2c23f148d58cd887$export$17d680238e50603e);\n$parcel$export(module.exports, \"LineSegment\", () => $2c23f148d58cd887$export$8b98feb4a2766c75);\n$parcel$export(module.exports, \"Loader\", () => $2c23f148d58cd887$export$3b0d6d7590275603);\n$parcel$export(module.exports, \"LoaderEvents\", () => $2c23f148d58cd887$export$38d47553764a3d88);\n$parcel$export(module.exports, \"LockCameraToActorAxisStrategy\", () => $2c23f148d58cd887$export$1c4c6d3f8d56581);\n$parcel$export(module.exports, \"LockCameraToActorStrategy\", () => $2c23f148d58cd887$export$fc869739b2177284);\n$parcel$export(module.exports, \"LogLevel\", () => $2c23f148d58cd887$export$243e62d78d3b544d);\n$parcel$export(module.exports, \"Logger\", () => $2c23f148d58cd887$export$efa9a398d6368992);\n$parcel$export(module.exports, \"Material\", () => $2c23f148d58cd887$export$a2d8b23205c25948);\n$parcel$export(module.exports, \"Matrix\", () => $2c23f148d58cd887$export$5b12bf1653c0dd85);\n$parcel$export(module.exports, \"MatrixLocations\", () => $2c23f148d58cd887$export$9f9b2346169b00c0);\n$parcel$export(module.exports, \"MediaEvent\", () => $2c23f148d58cd887$export$8c37b217b84d3f89);\n$parcel$export(module.exports, \"Meet\", () => $2c23f148d58cd887$export$35624b13e79b24a9);\n$parcel$export(module.exports, \"MotionComponent\", () => $2c23f148d58cd887$export$f75e7304717c9cbc);\n$parcel$export(module.exports, \"MotionSystem\", () => $2c23f148d58cd887$export$ec1251c88c8bd5c9);\n$parcel$export(module.exports, \"MoveBy\", () => $2c23f148d58cd887$export$d17844835b0fe8a8);\n$parcel$export(module.exports, \"MoveTo\", () => $2c23f148d58cd887$export$d1d8cb3d5c2a5671);\n$parcel$export(module.exports, \"NativePointerButton\", () => $2c23f148d58cd887$export$4d607ef791645d6);\n$parcel$export(module.exports, \"NativeSoundEvent\", () => $2c23f148d58cd887$export$f0b55daf9f154b55);\n$parcel$export(module.exports, \"NativeSoundProcessedEvent\", () => $2c23f148d58cd887$export$fa9699e41ba6faff);\n$parcel$export(module.exports, \"None\", () => $2c23f148d58cd887$export$57ca7e07b341709d);\n$parcel$export(module.exports, \"Observable\", () => $2c23f148d58cd887$export$77cea355fa80b5f4);\n$parcel$export(module.exports, \"OffscreenSystem\", () => $2c23f148d58cd887$export$8844adde4348f85c);\n$parcel$export(module.exports, \"Pair\", () => $2c23f148d58cd887$export$d63d7cff08fe4dc9);\n$parcel$export(module.exports, \"ParallaxComponent\", () => $2c23f148d58cd887$export$a960801e47624f4f);\n$parcel$export(module.exports, \"ParallelActions\", () => $2c23f148d58cd887$export$ed6a63ee685a4d78);\n$parcel$export(module.exports, \"ParseGif\", () => $2c23f148d58cd887$export$4fe52ae24ae61d51);\n$parcel$export(module.exports, \"Particle\", () => $2c23f148d58cd887$export$c36c68baa13912a5);\n$parcel$export(module.exports, \"ParticleEmitter\", () => $2c23f148d58cd887$export$616c632b282478dd);\n$parcel$export(module.exports, \"ParticleTransform\", () => $2c23f148d58cd887$export$459b1801e3134a24);\n$parcel$export(module.exports, \"Physics\", () => $2c23f148d58cd887$export$2f09efa5b67124a7);\n$parcel$export(module.exports, \"PhysicsStats\", () => $2c23f148d58cd887$export$618424ba3f30cd41);\n$parcel$export(module.exports, \"PhysicsWorld\", () => $2c23f148d58cd887$export$4a963ea7a16edf21);\n$parcel$export(module.exports, \"PointerAbstraction\", () => $2c23f148d58cd887$export$a4017560efebe97d);\n$parcel$export(module.exports, \"PointerButton\", () => $2c23f148d58cd887$export$982e5de016bedff1);\n$parcel$export(module.exports, \"PointerComponent\", () => $2c23f148d58cd887$export$6860c0696b73f79b);\n$parcel$export(module.exports, \"PointerEvent\", () => $2c23f148d58cd887$export$94806efd9890932f);\n$parcel$export(module.exports, \"PointerEventReceiver\", () => $2c23f148d58cd887$export$3bee0b2628b43478);\n$parcel$export(module.exports, \"PointerScope\", () => $2c23f148d58cd887$export$caed39dbb767d548);\n$parcel$export(module.exports, \"PointerSystem\", () => $2c23f148d58cd887$export$7e5ab4f7f9fd407);\n$parcel$export(module.exports, \"PointerType\", () => $2c23f148d58cd887$export$330520496d871ecf);\n$parcel$export(module.exports, \"Polygon\", () => $2c23f148d58cd887$export$7d31b617c820d435);\n$parcel$export(module.exports, \"PolygonCollider\", () => $2c23f148d58cd887$export$f23a2a272a8df60);\n$parcel$export(module.exports, \"Pool\", () => $2c23f148d58cd887$export$14963ee5c8637e11);\n$parcel$export(module.exports, \"PostCollisionEvent\", () => $2c23f148d58cd887$export$1d2c184034fc4cc2);\n$parcel$export(module.exports, \"PostDebugDrawEvent\", () => $2c23f148d58cd887$export$fea21a521a6360c1);\n$parcel$export(module.exports, \"PostDrawEvent\", () => $2c23f148d58cd887$export$8c15bdf7e3727f73);\n$parcel$export(module.exports, \"PostFrameEvent\", () => $2c23f148d58cd887$export$6eb043bf81d89752);\n$parcel$export(module.exports, \"PostKillEvent\", () => $2c23f148d58cd887$export$e390b859365a3d5b);\n$parcel$export(module.exports, \"PostTransformDrawEvent\", () => $2c23f148d58cd887$export$82a33120f6a0d987);\n$parcel$export(module.exports, \"PostUpdateEvent\", () => $2c23f148d58cd887$export$1ec85152758537e0);\n$parcel$export(module.exports, \"PreCollisionEvent\", () => $2c23f148d58cd887$export$a8584993858a18df);\n$parcel$export(module.exports, \"PreDebugDrawEvent\", () => $2c23f148d58cd887$export$906049a3747337a6);\n$parcel$export(module.exports, \"PreDrawEvent\", () => $2c23f148d58cd887$export$dbd8a6303ac26a42);\n$parcel$export(module.exports, \"PreFrameEvent\", () => $2c23f148d58cd887$export$9f68b6f37a444556);\n$parcel$export(module.exports, \"PreKillEvent\", () => $2c23f148d58cd887$export$fe2b6ac465da985d);\n$parcel$export(module.exports, \"PreLoadEvent\", () => $2c23f148d58cd887$export$4c3c82f4dcd79fcc);\n$parcel$export(module.exports, \"PreTransformDrawEvent\", () => $2c23f148d58cd887$export$e4ce43ec0499fb8f);\n$parcel$export(module.exports, \"PreUpdateEvent\", () => $2c23f148d58cd887$export$e44279b5c44add28);\n$parcel$export(module.exports, \"Projection\", () => $2c23f148d58cd887$export$dfa3a012bb2ef2e1);\n$parcel$export(module.exports, \"QuadIndexBuffer\", () => $2c23f148d58cd887$export$8201b979875baf73);\n$parcel$export(module.exports, \"QuadTree\", () => $2c23f148d58cd887$export$b82688eb02220411);\n$parcel$export(module.exports, \"Query\", () => $2c23f148d58cd887$export$62297b13309008b2);\n$parcel$export(module.exports, \"QueryManager\", () => $2c23f148d58cd887$export$b986383a50b53ea4);\n$parcel$export(module.exports, \"RadiusAroundActorStrategy\", () => $2c23f148d58cd887$export$ad5b3d166367714c);\n$parcel$export(module.exports, \"Random\", () => $2c23f148d58cd887$export$a92776769f460054);\n$parcel$export(module.exports, \"Raster\", () => $2c23f148d58cd887$export$eeb71495ca594706);\n$parcel$export(module.exports, \"Ray\", () => $2c23f148d58cd887$export$a186db52eed6d40e);\n$parcel$export(module.exports, \"RealisticSolver\", () => $2c23f148d58cd887$export$c07ce6d13c46df49);\n$parcel$export(module.exports, \"Rectangle\", () => $2c23f148d58cd887$export$4617fb02663045ef);\n$parcel$export(module.exports, \"RemovedComponent\", () => $2c23f148d58cd887$export$32437fc39ad02208);\n$parcel$export(module.exports, \"Repeat\", () => $2c23f148d58cd887$export$f9d61a2a6155ab51);\n$parcel$export(module.exports, \"RepeatForever\", () => $2c23f148d58cd887$export$9bd81f7d9b69ccb3);\n$parcel$export(module.exports, \"Resolution\", () => $2c23f148d58cd887$export$3e4ff2216a90b8a4);\n$parcel$export(module.exports, \"Resource\", () => $2c23f148d58cd887$export$39a853cfb5a94a63);\n$parcel$export(module.exports, \"ResourceEvents\", () => $2c23f148d58cd887$export$62833702c6700187);\n$parcel$export(module.exports, \"RotateBy\", () => $2c23f148d58cd887$export$a43177620e7a9310);\n$parcel$export(module.exports, \"RotateTo\", () => $2c23f148d58cd887$export$a16b6ef1fd362a19);\n$parcel$export(module.exports, \"RotationType\", () => $2c23f148d58cd887$export$91397be43fc980cc);\n$parcel$export(module.exports, \"ScaleBy\", () => $2c23f148d58cd887$export$23b9d128e61caefd);\n$parcel$export(module.exports, \"ScaleTo\", () => $2c23f148d58cd887$export$ab681471d41eeddc);\n$parcel$export(module.exports, \"Scene\", () => $2c23f148d58cd887$export$38af1803e3442a7f);\n$parcel$export(module.exports, \"SceneEvents\", () => $2c23f148d58cd887$export$c1825d965cf69ea3);\n$parcel$export(module.exports, \"Screen\", () => $2c23f148d58cd887$export$a98515d67472a41f);\n$parcel$export(module.exports, \"ScreenAppender\", () => $2c23f148d58cd887$export$57486627f01aaaf3);\n$parcel$export(module.exports, \"ScreenElement\", () => $2c23f148d58cd887$export$77630fcd7c3f2eb6);\n$parcel$export(module.exports, \"ScreenEvents\", () => $2c23f148d58cd887$export$3bf088dd0bb7575);\n$parcel$export(module.exports, \"ScreenShader\", () => $2c23f148d58cd887$export$2f3ac66e390c188b);\n$parcel$export(module.exports, \"ScrollPreventionMode\", () => $2c23f148d58cd887$export$d160a188872e1e4e);\n$parcel$export(module.exports, \"Semaphore\", () => $2c23f148d58cd887$export$5c7bd08c630c970c);\n$parcel$export(module.exports, \"Shader\", () => $2c23f148d58cd887$export$462bb059fed9d9e5);\n$parcel$export(module.exports, \"Shape\", () => $2c23f148d58cd887$export$6428a7f2611ef1fa);\n$parcel$export(module.exports, \"Side\", () => $2c23f148d58cd887$export$80a00690bda7f17e);\n$parcel$export(module.exports, \"SolverStrategy\", () => $2c23f148d58cd887$export$50994fad4c4676f4);\n$parcel$export(module.exports, \"Sound\", () => $2c23f148d58cd887$export$85990f0f98a390bb);\n$parcel$export(module.exports, \"SoundEvents\", () => $2c23f148d58cd887$export$5bff0d6cc6200d64);\n$parcel$export(module.exports, \"Sprite\", () => $2c23f148d58cd887$export$3075603db8e6204c);\n$parcel$export(module.exports, \"SpriteFont\", () => $2c23f148d58cd887$export$e1896ac0c4970221);\n$parcel$export(module.exports, \"SpriteSheet\", () => $2c23f148d58cd887$export$bd73ddfe5f8475d8);\n$parcel$export(module.exports, \"StandardClock\", () => $2c23f148d58cd887$export$f62bb2892382b3dd);\n$parcel$export(module.exports, \"StateMachine\", () => $2c23f148d58cd887$export$cbf2d83d1eab018a);\n$parcel$export(module.exports, \"StrategyContainer\", () => $2c23f148d58cd887$export$9ad53eded130cce4);\n$parcel$export(module.exports, \"Stream\", () => $2c23f148d58cd887$export$6a4eb2e7fc9e8903);\n$parcel$export(module.exports, \"System\", () => $2c23f148d58cd887$export$e1dae5660003ffa7);\n$parcel$export(module.exports, \"SystemManager\", () => $2c23f148d58cd887$export$a12e67a4b4590901);\n$parcel$export(module.exports, \"SystemPriority\", () => $2c23f148d58cd887$export$7c88eb83095afadd);\n$parcel$export(module.exports, \"SystemType\", () => $2c23f148d58cd887$export$c586aa7b67d94d19);\n$parcel$export(module.exports, \"TagQuery\", () => $2c23f148d58cd887$export$47b45ce774071a36);\n$parcel$export(module.exports, \"TestClock\", () => $2c23f148d58cd887$export$9440a22058545f9a);\n$parcel$export(module.exports, \"Text\", () => $2c23f148d58cd887$export$5f1af8db9871e1d6);\n$parcel$export(module.exports, \"TextAlign\", () => $2c23f148d58cd887$export$3720eb13f948f394);\n$parcel$export(module.exports, \"TextureLoader\", () => $2c23f148d58cd887$export$fd1bfc71f64c538c);\n$parcel$export(module.exports, \"Tile\", () => $2c23f148d58cd887$export$235cb65c20ad2b7);\n$parcel$export(module.exports, \"TileMap\", () => $2c23f148d58cd887$export$16ec26812de3ce7a);\n$parcel$export(module.exports, \"TileMapEvents\", () => $2c23f148d58cd887$export$dac3abbdc575ce73);\n$parcel$export(module.exports, \"Timer\", () => $2c23f148d58cd887$export$c57e9b2d8b9e4de);\n$parcel$export(module.exports, \"Toaster\", () => $2c23f148d58cd887$export$fb98e3a2a4cd92d7);\n$parcel$export(module.exports, \"Transform\", () => $2c23f148d58cd887$export$563a914cafbdc389);\n$parcel$export(module.exports, \"TransformComponent\", () => $2c23f148d58cd887$export$1def2aa75b7c7fe0);\n$parcel$export(module.exports, \"Transition\", () => $2c23f148d58cd887$export$be58926105124dd4);\n$parcel$export(module.exports, \"TreeNode\", () => $2c23f148d58cd887$export$2eba8ec3a333fdbb);\n$parcel$export(module.exports, \"Trigger\", () => $2c23f148d58cd887$export$41fb9f06171c75f4);\n$parcel$export(module.exports, \"TriggerEvents\", () => $2c23f148d58cd887$export$14963f945d6d59f0);\n$parcel$export(module.exports, \"TwoPI\", () => $2c23f148d58cd887$export$ba8651401a8a2b84);\n$parcel$export(module.exports, \"Util\", () => $2c23f148d58cd887$export$f8f26dd395d7e1bd);\n$parcel$export(module.exports, \"Vector\", () => $2c23f148d58cd887$export$9b781de7bf37bf48);\n$parcel$export(module.exports, \"VectorView\", () => $2c23f148d58cd887$export$ab650c8e5b9b9f2c);\n$parcel$export(module.exports, \"VertexBuffer\", () => $2c23f148d58cd887$export$41825a1ed6473903);\n$parcel$export(module.exports, \"VertexLayout\", () => $2c23f148d58cd887$export$f5ae2f144b95ebf4);\n$parcel$export(module.exports, \"VerticalFirst\", () => $2c23f148d58cd887$export$31ac8f65680039dd);\n$parcel$export(module.exports, \"VisibleEvent\", () => $2c23f148d58cd887$export$d5c6f73f7a77b9d);\n$parcel$export(module.exports, \"WebAudio\", () => $2c23f148d58cd887$export$8bfbf00b5dba81f6);\n$parcel$export(module.exports, \"WebAudioInstance\", () => $2c23f148d58cd887$export$2af5ef044257da25);\n$parcel$export(module.exports, \"WheelDeltaMode\", () => $2c23f148d58cd887$export$8c3375c231593a9d);\n$parcel$export(module.exports, \"WheelEvent\", () => $2c23f148d58cd887$export$9a4eae43f302c46e);\n$parcel$export(module.exports, \"World\", () => $2c23f148d58cd887$export$812cd9544993280d);\n$parcel$export(module.exports, \"canonicalizeAngle\", () => $2c23f148d58cd887$export$a4913eafbb02ceb4);\n$parcel$export(module.exports, \"clamp\", () => $2c23f148d58cd887$export$7d15b64cf5a3a4c4);\n$parcel$export(module.exports, \"coroutine\", () => $2c23f148d58cd887$export$c372a5d5a3996cbf);\n$parcel$export(module.exports, \"createId\", () => $2c23f148d58cd887$export$7149c6ffc9994c32);\n$parcel$export(module.exports, \"frac\", () => $2c23f148d58cd887$export$d436988b04cb99a5);\n$parcel$export(module.exports, \"hasGraphicsTick\", () => $2c23f148d58cd887$export$3ba9f2e94585ecc6);\n$parcel$export(module.exports, \"hasOnInitialize\", () => $2c23f148d58cd887$export$25dac40984956196);\n$parcel$export(module.exports, \"hasOnPostUpdate\", () => $2c23f148d58cd887$export$57932b71da6538b7);\n$parcel$export(module.exports, \"hasOnPreUpdate\", () => $2c23f148d58cd887$export$a17402ef5f32064d);\n$parcel$export(module.exports, \"hasPostDraw\", () => $2c23f148d58cd887$export$d5dea09620a858fd);\n$parcel$export(module.exports, \"hasPreDraw\", () => $2c23f148d58cd887$export$1377812d73ae3cab);\n$parcel$export(module.exports, \"has_initialize\", () => $2c23f148d58cd887$export$331f4c7ef74a9752);\n$parcel$export(module.exports, \"has_postupdate\", () => $2c23f148d58cd887$export$5f4e18965661d41f);\n$parcel$export(module.exports, \"has_preupdate\", () => $2c23f148d58cd887$export$817667946f51142b);\n$parcel$export(module.exports, \"isAddedComponent\", () => $2c23f148d58cd887$export$adc479603c39b28);\n$parcel$export(module.exports, \"isComponentCtor\", () => $2c23f148d58cd887$export$ba30ba18962891e7);\n$parcel$export(module.exports, \"isLoaderConstructor\", () => $2c23f148d58cd887$export$bcf8f1355133000b);\n$parcel$export(module.exports, \"isRemovedComponent\", () => $2c23f148d58cd887$export$256576ea924e6c90);\n$parcel$export(module.exports, \"isSceneConstructor\", () => $2c23f148d58cd887$export$786d9ab531bddbaa);\n$parcel$export(module.exports, \"isScreenElement\", () => $2c23f148d58cd887$export$e87630d8ef35465d);\n$parcel$export(module.exports, \"isSystemConstructor\", () => $2c23f148d58cd887$export$c3cedacda2d7ce48);\n$parcel$export(module.exports, \"maxMessages\", () => $2c23f148d58cd887$export$5a62d8eea226ddc);\n$parcel$export(module.exports, \"obsolete\", () => $2c23f148d58cd887$export$640d107500a3202a);\n$parcel$export(module.exports, \"pixelSnapEpsilon\", () => $2c23f148d58cd887$export$506bf22710a79182);\n$parcel$export(module.exports, \"randomInRange\", () => $2c23f148d58cd887$export$8b958c8ecd94a804);\n$parcel$export(module.exports, \"randomIntInRange\", () => $2c23f148d58cd887$export$816343276f749e02);\n$parcel$export(module.exports, \"range\", () => $2c23f148d58cd887$export$d02631cccf789723);\n$parcel$export(module.exports, \"resetObsoleteCounter\", () => $2c23f148d58cd887$export$5dc5812d8b390c43);\n$parcel$export(module.exports, \"sign\", () => $2c23f148d58cd887$export$c5552dfdbc7cec71);\n$parcel$export(module.exports, \"toDegrees\", () => $2c23f148d58cd887$export$56cb859c01fa134d);\n$parcel$export(module.exports, \"toRadians\", () => $2c23f148d58cd887$export$cba01ba138429a1d);\n$parcel$export(module.exports, \"vec\", () => $2c23f148d58cd887$export$202e0172ed3c7be0);\n$parcel$export(module.exports, \"webgl\", () => $2c23f148d58cd887$export$d55298c9efc5ed14);\n/*!\n * excalibur - 0.29.0 - 2024-2-20\n * https://github.com/excaliburjs/Excalibur\n * Copyright (c) 2024 Excalibur.js \n * Licensed BSD-2-Clause\n * @preserve\n */ /******/ var $2c23f148d58cd887$var$__webpack_modules__ = {\n /***/ 7835: /***/ (module, __webpack_exports__, __webpack_require__)=>{\n /* harmony export */ __webpack_require__.d(__webpack_exports__, {\n /* harmony export */ Z: ()=>__WEBPACK_DEFAULT_EXPORT__\n });\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n // Imports\n var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default());\n // Module\n ___CSS_LOADER_EXPORT___.push([\n module.id,\n `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`,\n \"\",\n {\n \"version\": 3,\n \"sources\": [\n \"webpack://./Director/Loader.css\"\n ],\n \"names\": [],\n \"mappings\": \"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\n \"sourcesContent\": [\n \"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"\n ],\n \"sourceRoot\": \"\"\n }\n ]);\n // Exports\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ___CSS_LOADER_EXPORT___;\n /***/ },\n /***/ 7379: /***/ (module, __webpack_exports__, __webpack_require__)=>{\n /* harmony export */ __webpack_require__.d(__webpack_exports__, {\n /* harmony export */ Z: ()=>__WEBPACK_DEFAULT_EXPORT__\n });\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n // Imports\n var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default());\n // Module\n ___CSS_LOADER_EXPORT___.push([\n module.id,\n `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`,\n \"\",\n {\n \"version\": 3,\n \"sources\": [\n \"webpack://./Util/Toaster.css\"\n ],\n \"names\": [],\n \"mappings\": \";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\n \"sourcesContent\": [\n \"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"\n ],\n \"sourceRoot\": \"\"\n }\n ]);\n // Exports\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ___CSS_LOADER_EXPORT___;\n /***/ },\n /***/ 2609: /***/ (module)=>{\n /*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/ module.exports = function(cssWithMappingToString) {\n var list = [];\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function(item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) content += \"@supports (\".concat(item[4], \") {\");\n if (item[2]) content += \"@media \".concat(item[2], \" {\");\n if (needLayer) content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n content += cssWithMappingToString(item);\n if (needLayer) content += \"}\";\n if (item[2]) content += \"}\";\n if (item[4]) content += \"}\";\n return content;\n }).join(\"\");\n };\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") modules = [\n [\n null,\n modules,\n undefined\n ]\n ];\n var alreadyImportedModules = {};\n if (dedupe) for(var k = 0; k < this.length; k++){\n var id = this[k][0];\n if (id != null) alreadyImportedModules[id] = true;\n }\n for(var _k = 0; _k < modules.length; _k++){\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) continue;\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") item[5] = layer;\n else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) item[2] = media;\n else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) item[4] = \"\".concat(supports);\n else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n };\n /***/ },\n /***/ 272: /***/ (module)=>{\n module.exports = function(item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) return content;\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [\n content\n ].concat([\n sourceMapping\n ]).join(\"\\n\");\n }\n return [\n content\n ].join(\"\\n\");\n };\n /***/ },\n /***/ 1324: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n __webpack_require__(7206);\n var entryUnbind = __webpack_require__(8193);\n module.exports = entryUnbind(\"Array\", \"sort\");\n /***/ },\n /***/ 3571: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n __webpack_require__(9867);\n var path = __webpack_require__(8588);\n module.exports = path.Object.keys;\n /***/ },\n /***/ 1052: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(688);\n var tryToString = __webpack_require__(3397);\n var $TypeError = TypeError;\n // `Assert: IsCallable(argument) is true`\n module.exports = function(argument) {\n if (isCallable(argument)) return argument;\n throw new $TypeError(tryToString(argument) + \" is not a function\");\n };\n /***/ },\n /***/ 9175: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isObject = __webpack_require__(5309);\n var $String = String;\n var $TypeError = TypeError;\n // `Assert: Type(argument) is Object`\n module.exports = function(argument) {\n if (isObject(argument)) return argument;\n throw new $TypeError($String(argument) + \" is not an object\");\n };\n /***/ },\n /***/ 1138: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIndexedObject = __webpack_require__(6854);\n var toAbsoluteIndex = __webpack_require__(7352);\n var lengthOfArrayLike = __webpack_require__(8344);\n // `Array.prototype.{ indexOf, includes }` methods implementation\n var createMethod = function(IS_INCLUDES) {\n return function($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el !== el) while(length > index){\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value !== value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n }\n else for(; length > index; index++){\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n }\n return !IS_INCLUDES && -1;\n };\n };\n module.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n };\n /***/ },\n /***/ 567: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4694);\n module.exports = function(METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function() {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function() {\n return 1;\n }, 1);\n });\n };\n /***/ },\n /***/ 7686: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n module.exports = uncurryThis([].slice);\n /***/ },\n /***/ 3097: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var arraySlice = __webpack_require__(7686);\n var floor = Math.floor;\n var sort = function(array, comparefn) {\n var length = array.length;\n if (length < 8) {\n // insertion sort\n var i = 1;\n var element, j;\n while(i < length){\n j = i;\n element = array[i];\n while(j && comparefn(array[j - 1], element) > 0)array[j] = array[--j];\n if (j !== i++) array[j] = element;\n }\n } else {\n // merge sort\n var middle = floor(length / 2);\n var left = sort(arraySlice(array, 0, middle), comparefn);\n var right = sort(arraySlice(array, middle), comparefn);\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n while(lindex < llength || rindex < rlength)array[lindex + rindex] = lindex < llength && rindex < rlength ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++] : lindex < llength ? left[lindex++] : right[rindex++];\n }\n return array;\n };\n module.exports = sort;\n /***/ },\n /***/ 2177: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var toString = uncurryThis({}.toString);\n var stringSlice = uncurryThis(\"\".slice);\n module.exports = function(it) {\n return stringSlice(toString(it), 8, -1);\n };\n /***/ },\n /***/ 1566: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var TO_STRING_TAG_SUPPORT = __webpack_require__(2522);\n var isCallable = __webpack_require__(688);\n var classofRaw = __webpack_require__(2177);\n var wellKnownSymbol = __webpack_require__(2032);\n var TO_STRING_TAG = wellKnownSymbol(\"toStringTag\");\n var $Object = Object;\n // ES3 wrong here\n var CORRECT_ARGUMENTS = classofRaw(function() {\n return arguments;\n }()) === \"Arguments\";\n // fallback for IE11 Script Access Denied error\n var tryGet = function(it, key) {\n try {\n return it[key];\n } catch (error) {}\n };\n // getting tag from ES6+ `Object.prototype.toString`\n module.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) {\n var O, tag, result;\n return it === undefined ? \"Undefined\" : it === null ? \"Null\" : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == \"string\" ? tag : CORRECT_ARGUMENTS ? classofRaw(O) : (result = classofRaw(O)) === \"Object\" && isCallable(O.callee) ? \"Arguments\" : result;\n };\n /***/ },\n /***/ 3891: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var hasOwn = __webpack_require__(4678);\n var ownKeys = __webpack_require__(990);\n var getOwnPropertyDescriptorModule = __webpack_require__(7537);\n var definePropertyModule = __webpack_require__(2131);\n module.exports = function(target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for(var i = 0; i < keys.length; i++){\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n };\n /***/ },\n /***/ 2385: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var definePropertyModule = __webpack_require__(2131);\n var createPropertyDescriptor = __webpack_require__(7781);\n module.exports = DESCRIPTORS ? function(object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n } : function(object, key, value) {\n object[key] = value;\n return object;\n };\n /***/ },\n /***/ 7781: /***/ (module)=>{\n module.exports = function(bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n };\n /***/ },\n /***/ 2470: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(688);\n var definePropertyModule = __webpack_require__(2131);\n var makeBuiltIn = __webpack_require__(1135);\n var defineGlobalProperty = __webpack_require__(1604);\n module.exports = function(O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) {}\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n }\n return O;\n };\n /***/ },\n /***/ 1604: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var defineProperty = Object.defineProperty;\n module.exports = function(key, value) {\n try {\n defineProperty(global, key, {\n value: value,\n configurable: true,\n writable: true\n });\n } catch (error) {\n global[key] = value;\n }\n return value;\n };\n /***/ },\n /***/ 955: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var tryToString = __webpack_require__(3397);\n var $TypeError = TypeError;\n module.exports = function(O, P) {\n if (!delete O[P]) throw new $TypeError(\"Cannot delete property \" + tryToString(P) + \" of \" + tryToString(O));\n };\n /***/ },\n /***/ 9924: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4694);\n // Detect IE8's incomplete defineProperty implementation\n module.exports = !fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, {\n get: function() {\n return 7;\n }\n })[1] !== 7;\n });\n /***/ },\n /***/ 1442: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var isObject = __webpack_require__(5309);\n var document1 = global.document;\n // typeof document.createElement is 'object' in old IE\n var EXISTS = isObject(document1) && isObject(document1.createElement);\n module.exports = function(it) {\n return EXISTS ? document1.createElement(it) : {};\n };\n /***/ },\n /***/ 9016: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var userAgent = __webpack_require__(1370);\n var firefox = userAgent.match(/firefox\\/(\\d+)/i);\n module.exports = !!firefox && +firefox[1];\n /***/ },\n /***/ 821: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var UA = __webpack_require__(1370);\n module.exports = /MSIE|Trident/.test(UA);\n /***/ },\n /***/ 1370: /***/ (module)=>{\n module.exports = typeof navigator != \"undefined\" && String(navigator.userAgent) || \"\";\n /***/ },\n /***/ 7067: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var userAgent = __webpack_require__(1370);\n var process = global.process;\n var Deno = global.Deno;\n var versions = process && process.versions || Deno && Deno.version;\n var v8 = versions && versions.v8;\n var match, version;\n if (v8) {\n match = v8.split(\".\");\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n }\n // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n // so check `userAgent` even if `.v8` exists, but 0\n if (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n }\n module.exports = version;\n /***/ },\n /***/ 4389: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var userAgent = __webpack_require__(1370);\n var webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n module.exports = !!webkit && +webkit[1];\n /***/ },\n /***/ 8193: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var uncurryThis = __webpack_require__(9668);\n module.exports = function(CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n };\n /***/ },\n /***/ 2367: /***/ (module)=>{\n // IE8- don't enum bug keys\n module.exports = [\n \"constructor\",\n \"hasOwnProperty\",\n \"isPrototypeOf\",\n \"propertyIsEnumerable\",\n \"toLocaleString\",\n \"toString\",\n \"valueOf\"\n ];\n /***/ },\n /***/ 5532: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var getOwnPropertyDescriptor = __webpack_require__(7537).f;\n var createNonEnumerableProperty = __webpack_require__(2385);\n var defineBuiltIn = __webpack_require__(2470);\n var defineGlobalProperty = __webpack_require__(1604);\n var copyConstructorProperties = __webpack_require__(3891);\n var isForced = __webpack_require__(1633);\n /*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/ module.exports = function(options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) target = global;\n else if (STATIC) target = global[TARGET] || defineGlobalProperty(TARGET, {});\n else target = global[TARGET] && global[TARGET].prototype;\n if (target) for(key in source){\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? \".\" : \"#\") + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || targetProperty && targetProperty.sham) createNonEnumerableProperty(sourceProperty, \"sham\", true);\n defineBuiltIn(target, key, sourceProperty, options);\n }\n };\n /***/ },\n /***/ 4694: /***/ (module)=>{\n module.exports = function(exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n };\n /***/ },\n /***/ 6398: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4694);\n module.exports = !fails(function() {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function() {}).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != \"function\" || test.hasOwnProperty(\"prototype\");\n });\n /***/ },\n /***/ 8724: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_BIND = __webpack_require__(6398);\n var call = Function.prototype.call;\n module.exports = NATIVE_BIND ? call.bind(call) : function() {\n return call.apply(call, arguments);\n };\n /***/ },\n /***/ 453: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var hasOwn = __webpack_require__(4678);\n var FunctionPrototype = Function.prototype;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n var EXISTS = hasOwn(FunctionPrototype, \"name\");\n // additional protection from minified / mangled / dropped function names\n var PROPER = EXISTS && (function something() {}).name === \"something\";\n var CONFIGURABLE = EXISTS && (!DESCRIPTORS || DESCRIPTORS && getDescriptor(FunctionPrototype, \"name\").configurable);\n module.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n };\n /***/ },\n /***/ 9668: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_BIND = __webpack_require__(6398);\n var FunctionPrototype = Function.prototype;\n var call = FunctionPrototype.call;\n var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n module.exports = NATIVE_BIND ? uncurryThisWithBind : function(fn) {\n return function() {\n return call.apply(fn, arguments);\n };\n };\n /***/ },\n /***/ 2160: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var isCallable = __webpack_require__(688);\n var aFunction = function(argument) {\n return isCallable(argument) ? argument : undefined;\n };\n module.exports = function(namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n };\n /***/ },\n /***/ 5383: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var aCallable = __webpack_require__(1052);\n var isNullOrUndefined = __webpack_require__(5268);\n // `GetMethod` abstract operation\n // https://tc39.es/ecma262/#sec-getmethod\n module.exports = function(V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n };\n /***/ },\n /***/ 2150: /***/ function(module, __unused_webpack_exports, __webpack_require__) {\n var check = function(it) {\n return it && it.Math === Math && it;\n };\n // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\n module.exports = // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == \"object\" && globalThis) || check(typeof window == \"object\" && window) || // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == \"object\" && self) || check(typeof __webpack_require__.g == \"object\" && __webpack_require__.g) || check(typeof this == \"object\" && this) || // eslint-disable-next-line no-new-func -- fallback\n function() {\n return this;\n }() || Function(\"return this\")();\n /***/ },\n /***/ 4678: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var toObject = __webpack_require__(298);\n var hasOwnProperty = uncurryThis({}.hasOwnProperty);\n // `HasOwnProperty` abstract operation\n // https://tc39.es/ecma262/#sec-hasownproperty\n // eslint-disable-next-line es/no-object-hasown -- safe\n module.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n };\n /***/ },\n /***/ 7390: /***/ (module)=>{\n module.exports = {};\n /***/ },\n /***/ 7913: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var fails = __webpack_require__(4694);\n var createElement = __webpack_require__(1442);\n // Thanks to IE8 for its funny defineProperty\n module.exports = !DESCRIPTORS && !fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement(\"div\"), \"a\", {\n get: function() {\n return 7;\n }\n }).a !== 7;\n });\n /***/ },\n /***/ 4347: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var fails = __webpack_require__(4694);\n var classof = __webpack_require__(2177);\n var $Object = Object;\n var split = uncurryThis(\"\".split);\n // fallback for non-array-like ES3 and non-enumerable old V8 strings\n module.exports = fails(function() {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object(\"z\").propertyIsEnumerable(0);\n }) ? function(it) {\n return classof(it) === \"String\" ? split(it, \"\") : $Object(it);\n } : $Object;\n /***/ },\n /***/ 1881: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var isCallable = __webpack_require__(688);\n var store = __webpack_require__(6762);\n var functionToString = uncurryThis(Function.toString);\n // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\n if (!isCallable(store.inspectSource)) store.inspectSource = function(it) {\n return functionToString(it);\n };\n module.exports = store.inspectSource;\n /***/ },\n /***/ 7804: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_WEAK_MAP = __webpack_require__(4724);\n var global = __webpack_require__(2150);\n var isObject = __webpack_require__(5309);\n var createNonEnumerableProperty = __webpack_require__(2385);\n var hasOwn = __webpack_require__(4678);\n var shared = __webpack_require__(6762);\n var sharedKey = __webpack_require__(1962);\n var hiddenKeys = __webpack_require__(7390);\n var OBJECT_ALREADY_INITIALIZED = \"Object already initialized\";\n var TypeError1 = global.TypeError;\n var WeakMap1 = global.WeakMap;\n var set, get, has;\n var enforce = function(it) {\n return has(it) ? get(it) : set(it, {});\n };\n var getterFor = function(TYPE) {\n return function(it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) throw new TypeError1(\"Incompatible receiver, \" + TYPE + \" required\");\n return state;\n };\n };\n if (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap1());\n /* eslint-disable no-self-assign -- prototype methods protection */ store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */ set = function(it, metadata) {\n if (store.has(it)) throw new TypeError1(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function(it) {\n return store.get(it) || {};\n };\n has = function(it) {\n return store.has(it);\n };\n } else {\n var STATE = sharedKey(\"state\");\n hiddenKeys[STATE] = true;\n set = function(it, metadata) {\n if (hasOwn(it, STATE)) throw new TypeError1(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function(it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function(it) {\n return hasOwn(it, STATE);\n };\n }\n module.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n };\n /***/ },\n /***/ 688: /***/ (module)=>{\n // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\n var documentAll = typeof document == \"object\" && document.all;\n // `IsCallable` abstract operation\n // https://tc39.es/ecma262/#sec-iscallable\n // eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\n module.exports = typeof documentAll == \"undefined\" && documentAll !== undefined ? function(argument) {\n return typeof argument == \"function\" || argument === documentAll;\n } : function(argument) {\n return typeof argument == \"function\";\n };\n /***/ },\n /***/ 1633: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4694);\n var isCallable = __webpack_require__(688);\n var replacement = /#|\\.prototype\\./;\n var isForced = function(feature, detection) {\n var value = data[normalize(feature)];\n return value === POLYFILL ? true : value === NATIVE ? false : isCallable(detection) ? fails(detection) : !!detection;\n };\n var normalize = isForced.normalize = function(string) {\n return String(string).replace(replacement, \".\").toLowerCase();\n };\n var data = isForced.data = {};\n var NATIVE = isForced.NATIVE = \"N\";\n var POLYFILL = isForced.POLYFILL = \"P\";\n module.exports = isForced;\n /***/ },\n /***/ 5268: /***/ (module)=>{\n // we can't use just `it == null` since of `document.all` special case\n // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\n module.exports = function(it) {\n return it === null || it === undefined;\n };\n /***/ },\n /***/ 5309: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(688);\n module.exports = function(it) {\n return typeof it == \"object\" ? it !== null : isCallable(it);\n };\n /***/ },\n /***/ 6555: /***/ (module)=>{\n module.exports = false;\n /***/ },\n /***/ 7935: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var getBuiltIn = __webpack_require__(2160);\n var isCallable = __webpack_require__(688);\n var isPrototypeOf = __webpack_require__(6148);\n var USE_SYMBOL_AS_UID = __webpack_require__(4866);\n var $Object = Object;\n module.exports = USE_SYMBOL_AS_UID ? function(it) {\n return typeof it == \"symbol\";\n } : function(it) {\n var $Symbol = getBuiltIn(\"Symbol\");\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n };\n /***/ },\n /***/ 8344: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toLength = __webpack_require__(7331);\n // `LengthOfArrayLike` abstract operation\n // https://tc39.es/ecma262/#sec-lengthofarraylike\n module.exports = function(obj) {\n return toLength(obj.length);\n };\n /***/ },\n /***/ 1135: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var fails = __webpack_require__(4694);\n var isCallable = __webpack_require__(688);\n var hasOwn = __webpack_require__(4678);\n var DESCRIPTORS = __webpack_require__(9924);\n var CONFIGURABLE_FUNCTION_NAME = __webpack_require__(453).CONFIGURABLE;\n var inspectSource = __webpack_require__(1881);\n var InternalStateModule = __webpack_require__(7804);\n var enforceInternalState = InternalStateModule.enforce;\n var getInternalState = InternalStateModule.get;\n var $String = String;\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var defineProperty = Object.defineProperty;\n var stringSlice = uncurryThis(\"\".slice);\n var replace = uncurryThis(\"\".replace);\n var join = uncurryThis([].join);\n var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {\n return defineProperty(function() {}, \"length\", {\n value: 8\n }).length !== 8;\n });\n var TEMPLATE = String(String).split(\"String\");\n var makeBuiltIn = module.exports = function(value, name, options) {\n if (stringSlice($String(name), 0, 7) === \"Symbol(\") name = \"[\" + replace($String(name), /^Symbol\\(([^)]*)\\).*$/, \"$1\") + \"]\";\n if (options && options.getter) name = \"get \" + name;\n if (options && options.setter) name = \"set \" + name;\n if (!hasOwn(value, \"name\") || CONFIGURABLE_FUNCTION_NAME && value.name !== name) {\n if (DESCRIPTORS) defineProperty(value, \"name\", {\n value: name,\n configurable: true\n });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, \"arity\") && value.length !== options.arity) defineProperty(value, \"length\", {\n value: options.arity\n });\n try {\n if (options && hasOwn(options, \"constructor\") && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, \"prototype\", {\n writable: false\n });\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) {}\n var state = enforceInternalState(value);\n if (!hasOwn(state, \"source\")) state.source = join(TEMPLATE, typeof name == \"string\" ? name : \"\");\n return value;\n };\n // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n // eslint-disable-next-line no-extend-native -- required\n Function.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n }, \"toString\");\n /***/ },\n /***/ 1787: /***/ (module)=>{\n var ceil = Math.ceil;\n var floor = Math.floor;\n // `Math.trunc` method\n // https://tc39.es/ecma262/#sec-math.trunc\n // eslint-disable-next-line es/no-math-trunc -- safe\n module.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n };\n /***/ },\n /***/ 2131: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var IE8_DOM_DEFINE = __webpack_require__(7913);\n var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(2666);\n var anObject = __webpack_require__(9175);\n var toPropertyKey = __webpack_require__(2358);\n var $TypeError = TypeError;\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var $defineProperty = Object.defineProperty;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n var ENUMERABLE = \"enumerable\";\n var CONFIGURABLE = \"configurable\";\n var WRITABLE = \"writable\";\n // `Object.defineProperty` method\n // https://tc39.es/ecma262/#sec-object.defineproperty\n exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === \"function\" && P === \"prototype\" && \"value\" in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n }\n return $defineProperty(O, P, Attributes);\n } : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) {}\n if (\"get\" in Attributes || \"set\" in Attributes) throw new $TypeError(\"Accessors not supported\");\n if (\"value\" in Attributes) O[P] = Attributes.value;\n return O;\n };\n /***/ },\n /***/ 7537: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var call = __webpack_require__(8724);\n var propertyIsEnumerableModule = __webpack_require__(8208);\n var createPropertyDescriptor = __webpack_require__(7781);\n var toIndexedObject = __webpack_require__(6854);\n var toPropertyKey = __webpack_require__(2358);\n var hasOwn = __webpack_require__(4678);\n var IE8_DOM_DEFINE = __webpack_require__(7913);\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n // `Object.getOwnPropertyDescriptor` method\n // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\n exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) {}\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n };\n /***/ },\n /***/ 6217: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var internalObjectKeys = __webpack_require__(1528);\n var enumBugKeys = __webpack_require__(2367);\n var hiddenKeys = enumBugKeys.concat(\"length\", \"prototype\");\n // `Object.getOwnPropertyNames` method\n // https://tc39.es/ecma262/#sec-object.getownpropertynames\n // eslint-disable-next-line es/no-object-getownpropertynames -- safe\n exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n };\n /***/ },\n /***/ 5168: /***/ (__unused_webpack_module, exports)=>{\n // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\n exports.f = Object.getOwnPropertySymbols;\n /***/ },\n /***/ 6148: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n module.exports = uncurryThis({}.isPrototypeOf);\n /***/ },\n /***/ 1528: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var hasOwn = __webpack_require__(4678);\n var toIndexedObject = __webpack_require__(6854);\n var indexOf = __webpack_require__(1138).indexOf;\n var hiddenKeys = __webpack_require__(7390);\n var push = uncurryThis([].push);\n module.exports = function(object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for(key in O)!hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while(names.length > i)if (hasOwn(O, key = names[i++])) ~indexOf(result, key) || push(result, key);\n return result;\n };\n /***/ },\n /***/ 1728: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var internalObjectKeys = __webpack_require__(1528);\n var enumBugKeys = __webpack_require__(2367);\n // `Object.keys` method\n // https://tc39.es/ecma262/#sec-object.keys\n // eslint-disable-next-line es/no-object-keys -- safe\n module.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n };\n /***/ },\n /***/ 8208: /***/ (__unused_webpack_module, exports)=>{\n var $propertyIsEnumerable = {}.propertyIsEnumerable;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n // Nashorn ~ JDK8 bug\n var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({\n 1: 2\n }, 1);\n // `Object.prototype.propertyIsEnumerable` method implementation\n // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\n exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n } : $propertyIsEnumerable;\n /***/ },\n /***/ 110: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var call = __webpack_require__(8724);\n var isCallable = __webpack_require__(688);\n var isObject = __webpack_require__(5309);\n var $TypeError = TypeError;\n // `OrdinaryToPrimitive` abstract operation\n // https://tc39.es/ecma262/#sec-ordinarytoprimitive\n module.exports = function(input, pref) {\n var fn, val;\n if (pref === \"string\" && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== \"string\" && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw new $TypeError(\"Can't convert object to primitive value\");\n };\n /***/ },\n /***/ 990: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var getBuiltIn = __webpack_require__(2160);\n var uncurryThis = __webpack_require__(9668);\n var getOwnPropertyNamesModule = __webpack_require__(6217);\n var getOwnPropertySymbolsModule = __webpack_require__(5168);\n var anObject = __webpack_require__(9175);\n var concat = uncurryThis([].concat);\n // all object keys, includes non-enumerable and symbols\n module.exports = getBuiltIn(\"Reflect\", \"ownKeys\") || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n };\n /***/ },\n /***/ 8588: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n module.exports = global;\n /***/ },\n /***/ 1166: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isNullOrUndefined = __webpack_require__(5268);\n var $TypeError = TypeError;\n // `RequireObjectCoercible` abstract operation\n // https://tc39.es/ecma262/#sec-requireobjectcoercible\n module.exports = function(it) {\n if (isNullOrUndefined(it)) throw new $TypeError(\"Can't call method on \" + it);\n return it;\n };\n /***/ },\n /***/ 1962: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var shared = __webpack_require__(2645);\n var uid = __webpack_require__(5736);\n var keys = shared(\"keys\");\n module.exports = function(key) {\n return keys[key] || (keys[key] = uid(key));\n };\n /***/ },\n /***/ 6762: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var defineGlobalProperty = __webpack_require__(1604);\n var SHARED = \"__core-js_shared__\";\n var store = global[SHARED] || defineGlobalProperty(SHARED, {});\n module.exports = store;\n /***/ },\n /***/ 2645: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var IS_PURE = __webpack_require__(6555);\n var store = __webpack_require__(6762);\n (module.exports = function(key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n })(\"versions\", []).push({\n version: \"3.35.1\",\n mode: IS_PURE ? \"pure\" : \"global\",\n copyright: \"\\xa9 2014-2024 Denis Pushkarev (zloirock.ru)\",\n license: \"https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE\",\n source: \"https://github.com/zloirock/core-js\"\n });\n /***/ },\n /***/ 4112: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n /* eslint-disable es/no-symbol -- required for testing */ var V8_VERSION = __webpack_require__(7067);\n var fails = __webpack_require__(4694);\n var global = __webpack_require__(2150);\n var $String = global.String;\n // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\n module.exports = !!Object.getOwnPropertySymbols && !fails(function() {\n var symbol = Symbol(\"symbol detection\");\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n });\n /***/ },\n /***/ 7352: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIntegerOrInfinity = __webpack_require__(1680);\n var max = Math.max;\n var min = Math.min;\n // Helper for a popular repeating case of the spec:\n // Let integer be ? ToInteger(index).\n // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\n module.exports = function(index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n };\n /***/ },\n /***/ 6854: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n // toObject with fallback for non-array-like ES3 strings\n var IndexedObject = __webpack_require__(4347);\n var requireObjectCoercible = __webpack_require__(1166);\n module.exports = function(it) {\n return IndexedObject(requireObjectCoercible(it));\n };\n /***/ },\n /***/ 1680: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var trunc = __webpack_require__(1787);\n // `ToIntegerOrInfinity` abstract operation\n // https://tc39.es/ecma262/#sec-tointegerorinfinity\n module.exports = function(argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n };\n /***/ },\n /***/ 7331: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIntegerOrInfinity = __webpack_require__(1680);\n var min = Math.min;\n // `ToLength` abstract operation\n // https://tc39.es/ecma262/#sec-tolength\n module.exports = function(argument) {\n var len = toIntegerOrInfinity(argument);\n return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n };\n /***/ },\n /***/ 298: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var requireObjectCoercible = __webpack_require__(1166);\n var $Object = Object;\n // `ToObject` abstract operation\n // https://tc39.es/ecma262/#sec-toobject\n module.exports = function(argument) {\n return $Object(requireObjectCoercible(argument));\n };\n /***/ },\n /***/ 1272: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var call = __webpack_require__(8724);\n var isObject = __webpack_require__(5309);\n var isSymbol = __webpack_require__(7935);\n var getMethod = __webpack_require__(5383);\n var ordinaryToPrimitive = __webpack_require__(110);\n var wellKnownSymbol = __webpack_require__(2032);\n var $TypeError = TypeError;\n var TO_PRIMITIVE = wellKnownSymbol(\"toPrimitive\");\n // `ToPrimitive` abstract operation\n // https://tc39.es/ecma262/#sec-toprimitive\n module.exports = function(input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = \"default\";\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw new $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = \"number\";\n return ordinaryToPrimitive(input, pref);\n };\n /***/ },\n /***/ 2358: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toPrimitive = __webpack_require__(1272);\n var isSymbol = __webpack_require__(7935);\n // `ToPropertyKey` abstract operation\n // https://tc39.es/ecma262/#sec-topropertykey\n module.exports = function(argument) {\n var key = toPrimitive(argument, \"string\");\n return isSymbol(key) ? key : key + \"\";\n };\n /***/ },\n /***/ 2522: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var wellKnownSymbol = __webpack_require__(2032);\n var TO_STRING_TAG = wellKnownSymbol(\"toStringTag\");\n var test = {};\n test[TO_STRING_TAG] = \"z\";\n module.exports = String(test) === \"[object z]\";\n /***/ },\n /***/ 599: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var classof = __webpack_require__(1566);\n var $String = String;\n module.exports = function(argument) {\n if (classof(argument) === \"Symbol\") throw new TypeError(\"Cannot convert a Symbol value to a string\");\n return $String(argument);\n };\n /***/ },\n /***/ 3397: /***/ (module)=>{\n var $String = String;\n module.exports = function(argument) {\n try {\n return $String(argument);\n } catch (error) {\n return \"Object\";\n }\n };\n /***/ },\n /***/ 5736: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(9668);\n var id = 0;\n var postfix = Math.random();\n var toString = uncurryThis(1.0.toString);\n module.exports = function(key) {\n return \"Symbol(\" + (key === undefined ? \"\" : key) + \")_\" + toString(++id + postfix, 36);\n };\n /***/ },\n /***/ 4866: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n /* eslint-disable es/no-symbol -- required for testing */ var NATIVE_SYMBOL = __webpack_require__(4112);\n module.exports = NATIVE_SYMBOL && !Symbol.sham && typeof Symbol.iterator == \"symbol\";\n /***/ },\n /***/ 2666: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(9924);\n var fails = __webpack_require__(4694);\n // V8 ~ Chrome 36-\n // https://bugs.chromium.org/p/v8/issues/detail?id=3334\n module.exports = DESCRIPTORS && fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function() {}, \"prototype\", {\n value: 42,\n writable: false\n }).prototype !== 42;\n });\n /***/ },\n /***/ 4724: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var isCallable = __webpack_require__(688);\n var WeakMap1 = global.WeakMap;\n module.exports = isCallable(WeakMap1) && /native code/.test(String(WeakMap1));\n /***/ },\n /***/ 2032: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(2150);\n var shared = __webpack_require__(2645);\n var hasOwn = __webpack_require__(4678);\n var uid = __webpack_require__(5736);\n var NATIVE_SYMBOL = __webpack_require__(4112);\n var USE_SYMBOL_AS_UID = __webpack_require__(4866);\n var Symbol1 = global.Symbol;\n var WellKnownSymbolsStore = shared(\"wks\");\n var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol1[\"for\"] || Symbol1 : Symbol1 && Symbol1.withoutSetter || uid;\n module.exports = function(name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol1, name) ? Symbol1[name] : createWellKnownSymbol(\"Symbol.\" + name);\n return WellKnownSymbolsStore[name];\n };\n /***/ },\n /***/ 7206: /***/ (__unused_webpack_module, __unused_webpack_exports, __webpack_require__)=>{\n var $ = __webpack_require__(5532);\n var uncurryThis = __webpack_require__(9668);\n var aCallable = __webpack_require__(1052);\n var toObject = __webpack_require__(298);\n var lengthOfArrayLike = __webpack_require__(8344);\n var deletePropertyOrThrow = __webpack_require__(955);\n var toString = __webpack_require__(599);\n var fails = __webpack_require__(4694);\n var internalSort = __webpack_require__(3097);\n var arrayMethodIsStrict = __webpack_require__(567);\n var FF = __webpack_require__(9016);\n var IE_OR_EDGE = __webpack_require__(821);\n var V8 = __webpack_require__(7067);\n var WEBKIT = __webpack_require__(4389);\n var test = [];\n var nativeSort = uncurryThis(test.sort);\n var push = uncurryThis(test.push);\n // IE8-\n var FAILS_ON_UNDEFINED = fails(function() {\n test.sort(undefined);\n });\n // V8 bug\n var FAILS_ON_NULL = fails(function() {\n test.sort(null);\n });\n // Old WebKit\n var STRICT_METHOD = arrayMethodIsStrict(\"sort\");\n var STABLE_SORT = !fails(function() {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n var result = \"\";\n var code, chr, value, index;\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for(code = 65; code < 76; code++){\n chr = String.fromCharCode(code);\n switch(code){\n case 66:\n case 69:\n case 70:\n case 72:\n value = 3;\n break;\n case 68:\n case 71:\n value = 4;\n break;\n default:\n value = 2;\n }\n for(index = 0; index < 47; index++)test.push({\n k: chr + index,\n v: value\n });\n }\n test.sort(function(a, b) {\n return b.v - a.v;\n });\n for(index = 0; index < test.length; index++){\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n return result !== \"DGBEFHACIJK\";\n });\n var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n var getSortCompare = function(comparefn) {\n return function(x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n };\n // `Array.prototype.sort` method\n // https://tc39.es/ecma262/#sec-array.prototype.sort\n $({\n target: \"Array\",\n proto: true,\n forced: FORCED\n }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n var array = toObject(this);\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n for(index = 0; index < arrayLength; index++)if (index in array) push(items, array[index]);\n internalSort(items, getSortCompare(comparefn));\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n while(index < itemsLength)array[index] = items[index++];\n while(index < arrayLength)deletePropertyOrThrow(array, index++);\n return array;\n }\n });\n /***/ },\n /***/ 9867: /***/ (__unused_webpack_module, __unused_webpack_exports, __webpack_require__)=>{\n var $ = __webpack_require__(5532);\n var toObject = __webpack_require__(298);\n var nativeKeys = __webpack_require__(1728);\n var fails = __webpack_require__(4694);\n var FAILS_ON_PRIMITIVES = fails(function() {\n nativeKeys(1);\n });\n // `Object.keys` method\n // https://tc39.es/ecma262/#sec-object.keys\n $({\n target: \"Object\",\n stat: true,\n forced: FAILS_ON_PRIMITIVES\n }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n });\n /***/ }\n};\n/************************************************************************/ /******/ // The module cache\n/******/ var $2c23f148d58cd887$var$__webpack_module_cache__ = {};\n/******/ /******/ // The require function\n/******/ function $2c23f148d58cd887$var$__webpack_require__(moduleId) {\n /******/ // Check if module is in cache\n /******/ var cachedModule = $2c23f148d58cd887$var$__webpack_module_cache__[moduleId];\n /******/ if (cachedModule !== undefined) /******/ return cachedModule.exports;\n /******/ // Create a new module (and put it into the cache)\n /******/ var module = $2c23f148d58cd887$var$__webpack_module_cache__[moduleId] = {\n /******/ id: moduleId,\n /******/ // no module.loaded needed\n /******/ exports: {}\n };\n /******/ /******/ // Execute the module function\n /******/ $2c23f148d58cd887$var$__webpack_modules__[moduleId].call(module.exports, module, module.exports, $2c23f148d58cd887$var$__webpack_require__);\n /******/ /******/ // Return the exports of the module\n /******/ return module.exports;\n/******/ }\n/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (()=>{\n /******/ // getDefaultExport function for compatibility with non-harmony modules\n /******/ $2c23f148d58cd887$var$__webpack_require__.n = (module)=>{\n /******/ var getter = module && module.__esModule ? /******/ ()=>module[\"default\"] : /******/ ()=>module;\n /******/ $2c23f148d58cd887$var$__webpack_require__.d(getter, {\n a: getter\n });\n /******/ return getter;\n /******/ };\n/******/ })();\n/******/ /******/ /* webpack/runtime/define property getters */ /******/ (()=>{\n /******/ // define getter functions for harmony exports\n /******/ $2c23f148d58cd887$var$__webpack_require__.d = (exports, definition)=>{\n /******/ for(var key in definition)/******/ if ($2c23f148d58cd887$var$__webpack_require__.o(definition, key) && !$2c23f148d58cd887$var$__webpack_require__.o(exports, key)) /******/ Object.defineProperty(exports, key, {\n enumerable: true,\n get: definition[key]\n });\n /******/ };\n/******/ })();\n/******/ /******/ /* webpack/runtime/global */ /******/ (()=>{\n /******/ $2c23f148d58cd887$var$__webpack_require__.g = function() {\n /******/ if (typeof globalThis === \"object\") return globalThis;\n /******/ try {\n /******/ return this || new Function(\"return this\")();\n /******/ } catch (e) {\n /******/ if (typeof window === \"object\") return window;\n /******/ }\n /******/ }();\n/******/ })();\n/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (()=>{\n /******/ $2c23f148d58cd887$var$__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);\n/******/ })();\n/******/ /******/ /* webpack/runtime/make namespace object */ /******/ (()=>{\n /******/ // define __esModule on exports\n /******/ $2c23f148d58cd887$var$__webpack_require__.r = (exports)=>{\n /******/ if (typeof Symbol !== \"undefined\" && Symbol.toStringTag) /******/ Object.defineProperty(exports, Symbol.toStringTag, {\n value: \"Module\"\n });\n /******/ Object.defineProperty(exports, \"__esModule\", {\n value: true\n });\n /******/ };\n/******/ })();\n/******/ /************************************************************************/ var $2c23f148d58cd887$var$__webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(()=>{\n // EXPORTS\n $2c23f148d58cd887$var$__webpack_require__.d($2c23f148d58cd887$var$__webpack_exports__, {\n y1j: ()=>/* reexport */ ActionCompleteEvent,\n fWn: ()=>/* reexport */ ActionContext,\n Ia8: ()=>/* reexport */ ActionQueue,\n rqv: ()=>/* reexport */ ActionSequence,\n zH6: ()=>/* reexport */ ActionStartEvent,\n hLI: ()=>/* reexport */ ActionsComponent,\n yyv: ()=>/* reexport */ ActionsSystem,\n tX5: ()=>/* reexport */ ActivateEvent,\n vtX: ()=>/* reexport */ Actor,\n r7K: ()=>/* reexport */ AddedComponent,\n cE4: ()=>/* reexport */ AffineMatrix,\n fwF: ()=>/* reexport */ Animation,\n sce: ()=>/* reexport */ AnimationDirection,\n AQ6: ()=>/* reexport */ AnimationEvents,\n _c7: ()=>/* reexport */ AnimationStrategy,\n KUs: ()=>/* reexport */ ArcadeSolver,\n Ajp: ()=>/* reexport */ AudioContextFactory,\n dkO: ()=>/* reexport */ Axes,\n RDh: ()=>/* reexport */ Axis,\n _H9: ()=>/* reexport */ BaseAlign,\n mxs: ()=>/* reexport */ Blink,\n OmD: ()=>/* reexport */ BodyComponent,\n kBf: ()=>/* reexport */ BoundingBox,\n C4F: ()=>/* reexport */ BroadphaseStrategy,\n NQt: ()=>/* reexport */ BrowserComponent,\n JjN: ()=>/* reexport */ BrowserEvents,\n EK_: ()=>/* reexport */ Buttons,\n V1s: ()=>/* reexport */ Camera,\n xHm: ()=>/* reexport */ CameraEvents,\n Xz7: ()=>/* reexport */ Canvas,\n Cdc: ()=>/* reexport */ Circle,\n FKn: ()=>/* reexport */ CircleCollider,\n SUY: ()=>/* reexport */ Clock,\n ab2: ()=>/* reexport */ ClosestLine,\n GfZ: ()=>/* reexport */ ClosestLineJumpTable,\n YMS: ()=>/* reexport */ Collider,\n oyv: ()=>/* reexport */ ColliderComponent,\n aUb: ()=>/* reexport */ CollisionContact,\n SdD: ()=>/* reexport */ CollisionEndEvent,\n JUv: ()=>/* reexport */ CollisionGroup,\n jEj: ()=>/* reexport */ CollisionGroupManager,\n TFq: ()=>/* reexport */ CollisionJumpTable,\n HDU: ()=>/* reexport */ CollisionPostSolveEvent,\n R_y: ()=>/* reexport */ CollisionPreSolveEvent,\n t50: ()=>/* reexport */ CollisionStartEvent,\n s$$: ()=>/* reexport */ CollisionSystem,\n v2G: ()=>/* reexport */ CollisionType,\n Ilk: ()=>/* reexport */ Color,\n s9i: ()=>/* reexport */ ColorBlindFlags,\n dxL: ()=>/* reexport */ ColorBlindnessMode,\n LLX: ()=>/* reexport */ ColorBlindnessPostProcessor,\n wA2: ()=>/* reexport */ Component,\n R_p: ()=>/* reexport */ CompositeCollider,\n IQ$: ()=>/* reexport */ Configurable,\n I5F: ()=>/* reexport */ ConsoleAppender,\n X8$: ()=>/* reexport */ ContactConstraintPoint,\n FR6: ()=>/* reexport */ ContactEndEvent,\n pTZ: ()=>/* reexport */ ContactSolveBias,\n U8o: ()=>/* reexport */ ContactStartEvent,\n kbG: ()=>/* reexport */ CoordPlane,\n FEv: ()=>/* reexport */ CrossFade,\n iS_: ()=>/* reexport */ DeactivateEvent,\n cGG: ()=>/* reexport */ Debug,\n ETM: ()=>/* reexport */ DebugConfig,\n RPN: ()=>/* reexport */ DebugGraphicsComponent,\n skb: ()=>/* reexport */ DebugSystem,\n SLU: ()=>/* reexport */ DebugText,\n Q3w: ()=>/* reexport */ DefaultAntialiasOptions,\n xK2: ()=>/* reexport */ DefaultLoader,\n vrO: ()=>/* reexport */ DefaultPhysicsConfig,\n EA2: ()=>/* reexport */ DefaultPixelArtOptions,\n RdJ: ()=>/* reexport */ DegreeOfFreedom,\n cNu: ()=>/* reexport */ Delay,\n wtG: ()=>/* reexport */ DeprecatedStaticToConfig,\n gU7: ()=>/* reexport */ Detector,\n LSk: ()=>/* reexport */ Die,\n Nmp: ()=>/* reexport */ Direction,\n twX: ()=>/* reexport */ Director,\n UND: ()=>/* reexport */ DirectorEvents,\n d1Y: ()=>/* reexport */ DisplayMode,\n xrL: ()=>/* reexport */ DynamicTree,\n sRW: ()=>/* reexport */ DynamicTreeCollisionProcessor,\n cmV: ()=>/* binding */ EX_VERSION,\n qWz: ()=>/* reexport */ EaseBy,\n N0Q: ()=>/* reexport */ EaseTo,\n q8b: ()=>/* reexport */ EasingFunctions,\n ynB: ()=>/* reexport */ EdgeCollider,\n jT9: ()=>/* reexport */ ElasticToActorStrategy,\n wAz: ()=>/* reexport */ EmitterType,\n D4V: ()=>/* reexport */ Engine,\n NLr: ()=>/* reexport */ EngineEvents,\n N6H: ()=>/* reexport */ EnterTriggerEvent,\n W1A: ()=>/* reexport */ EnterViewPortEvent,\n JHW: ()=>/* reexport */ Entity,\n ZZ$: ()=>/* reexport */ EntityEvents,\n v2K: ()=>/* reexport */ EntityManager,\n pBf: ()=>/* reexport */ EventDispatcher,\n vpe: ()=>/* reexport */ EventEmitter,\n GMl: ()=>/* reexport */ EventTypes,\n zW2: ()=>/* reexport */ Events_namespaceObject,\n B0K: ()=>/* reexport */ ExResponse,\n Nv7: ()=>/* reexport */ ExcaliburGraphicsContext2DCanvas,\n C_p: ()=>/* reexport */ ExcaliburGraphicsContextWebGL,\n MUA: ()=>/* reexport */ ExitTriggerEvent,\n xqU: ()=>/* reexport */ ExitViewPortEvent,\n pTp: ()=>/* reexport */ Fade,\n trb: ()=>/* reexport */ FadeInOut,\n vUK: ()=>/* reexport */ Flags,\n j9l: ()=>/* reexport */ Follow,\n Zxw: ()=>/* reexport */ Font,\n v51: ()=>/* reexport */ FontCache,\n gYv: ()=>/* reexport */ FontSource,\n Hdx: ()=>/* reexport */ FontStyle,\n Z$d: ()=>/* reexport */ FontUnit,\n iqV: ()=>/* reexport */ FpsSampler,\n o$7: ()=>/* reexport */ FrameStats,\n olM: ()=>/* reexport */ Future,\n Zm$: ()=>/* reexport */ GameEvent,\n $QH: ()=>/* reexport */ GameStartEvent,\n i78: ()=>/* reexport */ GameStopEvent,\n nJg: ()=>/* reexport */ Gamepad,\n h6u: ()=>/* reexport */ GamepadAxisEvent,\n hts: ()=>/* reexport */ GamepadButtonEvent,\n j88: ()=>/* reexport */ GamepadConnectEvent,\n VME: ()=>/* reexport */ GamepadDisconnectEvent,\n fy2: ()=>/* reexport */ Gamepads,\n nt: ()=>/* reexport */ Gif,\n Ukr: ()=>/* reexport */ GlobalCoordinates,\n zsu: ()=>/* reexport */ Graphic,\n oA6: ()=>/* reexport */ GraphicsComponent,\n TVh: ()=>/* reexport */ GraphicsGroup,\n xxj: ()=>/* reexport */ GraphicsSystem,\n XdK: ()=>/* reexport */ HiddenEvent,\n fBD: ()=>/* reexport */ HorizontalFirst,\n Jmb: ()=>/* reexport */ ImageFiltering,\n cXo: ()=>/* reexport */ ImageSource,\n Dm5: ()=>/* reexport */ InitializeEvent,\n IIB: ()=>/* reexport */ Input_Index_namespaceObject,\n IX$: ()=>/* reexport */ InputHost,\n ebW: ()=>/* reexport */ InputMapper,\n zI0: ()=>/* reexport */ Integrator,\n LYD: ()=>/* reexport */ IsometricEntityComponent,\n cEG: ()=>/* reexport */ IsometricEntitySystem,\n SEl: ()=>/* reexport */ IsometricMap,\n t9V: ()=>/* reexport */ IsometricTile,\n ez5: ()=>/* reexport */ KeyEvent,\n N1d: ()=>/* reexport */ Keyboard,\n R8U: ()=>/* reexport */ Keys,\n SKZ: ()=>/* reexport */ KillEvent,\n __J: ()=>/* reexport */ Label,\n RI$: ()=>/* reexport */ LimitCameraBoundsStrategy,\n x12: ()=>/* reexport */ Line,\n ccz: ()=>/* reexport */ LineSegment,\n aNw: ()=>/* reexport */ Loader,\n XrL: ()=>/* reexport */ LoaderEvents,\n xwn: ()=>/* reexport */ LockCameraToActorAxisStrategy,\n dNK: ()=>/* reexport */ LockCameraToActorStrategy,\n ini: ()=>/* reexport */ LogLevel,\n YdH: ()=>/* reexport */ Logger,\n F5T: ()=>/* reexport */ Material,\n y3G: ()=>/* reexport */ Matrix,\n l57: ()=>/* reexport */ MatrixLocations,\n xn0: ()=>/* reexport */ MediaEvent,\n t2V: ()=>/* reexport */ Meet,\n uxB: ()=>/* reexport */ MotionComponent,\n cpd: ()=>/* reexport */ MotionSystem,\n fiy: ()=>/* reexport */ MoveBy,\n $XZ: ()=>/* reexport */ MoveTo,\n UG6: ()=>/* reexport */ NativePointerButton,\n uqK: ()=>/* reexport */ NativeSoundEvent,\n STE: ()=>/* reexport */ NativeSoundProcessedEvent,\n Hq9: ()=>/* reexport */ None,\n y$z: ()=>/* reexport */ Observable,\n mAD: ()=>/* reexport */ OffscreenSystem,\n sOq: ()=>/* reexport */ Pair,\n hUw: ()=>/* reexport */ ParallaxComponent,\n _0G: ()=>/* reexport */ ParallelActions,\n Sqs: ()=>/* reexport */ ParseGif,\n hpZ: ()=>/* reexport */ Particle,\n Vol: ()=>/* reexport */ ParticleEmitter,\n vYX: ()=>/* reexport */ ParticleTransform,\n wIZ: ()=>/* reexport */ Physics,\n cBi: ()=>/* reexport */ PhysicsStats,\n c30: ()=>/* reexport */ PhysicsWorld,\n PGK: ()=>/* reexport */ PointerAbstraction,\n MPV: ()=>/* reexport */ PointerButton,\n RFv: ()=>/* reexport */ PointerComponent,\n Ux6: ()=>/* reexport */ PointerEvent,\n rxy: ()=>/* reexport */ PointerEventReceiver,\n I$c: ()=>/* reexport */ PointerScope,\n kfC: ()=>/* reexport */ PointerSystem,\n VjY: ()=>/* reexport */ PointerType,\n mgq: ()=>/* reexport */ Polygon,\n YVA: ()=>/* reexport */ PolygonCollider,\n Kgp: ()=>/* reexport */ Pool,\n HH$: ()=>/* reexport */ PostCollisionEvent,\n M_d: ()=>/* reexport */ PostDebugDrawEvent,\n rgh: ()=>/* reexport */ PostDrawEvent,\n Ra6: ()=>/* reexport */ PostFrameEvent,\n KhR: ()=>/* reexport */ PostKillEvent,\n gvQ: ()=>/* reexport */ PostTransformDrawEvent,\n BS5: ()=>/* reexport */ PostUpdateEvent,\n xhz: ()=>/* reexport */ PreCollisionEvent,\n xOq: ()=>/* reexport */ PreDebugDrawEvent,\n a9j: ()=>/* reexport */ PreDrawEvent,\n bHk: ()=>/* reexport */ PreFrameEvent,\n CgK: ()=>/* reexport */ PreKillEvent,\n A0M: ()=>/* reexport */ PreLoadEvent,\n cEd: ()=>/* reexport */ PreTransformDrawEvent,\n cuY: ()=>/* reexport */ PreUpdateEvent,\n kvE: ()=>/* reexport */ Projection,\n SBu: ()=>/* reexport */ QuadIndexBuffer,\n PsT: ()=>/* reexport */ QuadTree,\n AE_: ()=>/* reexport */ Query,\n ctO: ()=>/* reexport */ QueryManager,\n OLH: ()=>/* reexport */ RadiusAroundActorStrategy,\n kky: ()=>/* reexport */ Random,\n nSF: ()=>/* reexport */ Raster,\n zHn: ()=>/* reexport */ Ray,\n zwx: ()=>/* reexport */ RealisticSolver,\n AeJ: ()=>/* reexport */ Rectangle,\n hLz: ()=>/* reexport */ RemovedComponent,\n wA: ()=>/* reexport */ Repeat,\n jhr: ()=>/* reexport */ RepeatForever,\n GVs: ()=>/* reexport */ Resolution,\n _zO: ()=>/* reexport */ Resource,\n LXZ: ()=>/* reexport */ ResourceEvents,\n w6$: ()=>/* reexport */ RotateBy,\n mhV: ()=>/* reexport */ RotateTo,\n MOD: ()=>/* reexport */ RotationType,\n kwd: ()=>/* reexport */ ScaleBy,\n Lmr: ()=>/* reexport */ ScaleTo,\n xsS: ()=>/* reexport */ Scene,\n K5l: ()=>/* reexport */ SceneEvents,\n lLr: ()=>/* reexport */ Screen,\n Z$r: ()=>/* reexport */ ScreenAppender,\n IXb: ()=>/* reexport */ ScreenElement,\n Xsu: ()=>/* reexport */ ScreenEvents,\n SGH: ()=>/* reexport */ ScreenShader,\n SMj: ()=>/* reexport */ ScrollPreventionMode,\n L34: ()=>/* reexport */ Semaphore,\n exe: ()=>/* reexport */ Shader,\n bnF: ()=>/* reexport */ Shape,\n MFA: ()=>/* reexport */ Side,\n kPj: ()=>/* reexport */ SolverStrategy,\n $uU: ()=>/* reexport */ Sound,\n Sap: ()=>/* reexport */ SoundEvents,\n jyi: ()=>/* reexport */ Sprite,\n E03: ()=>/* reexport */ SpriteFont,\n V6q: ()=>/* reexport */ SpriteSheet,\n rg2: ()=>/* reexport */ StandardClock,\n DVW: ()=>/* reexport */ StateMachine,\n nVo: ()=>/* reexport */ StrategyContainer,\n F6N: ()=>/* reexport */ Stream,\n xP7: ()=>/* reexport */ System,\n Odq: ()=>/* reexport */ SystemManager,\n uY9: ()=>/* reexport */ SystemPriority,\n Zif: ()=>/* reexport */ SystemType,\n c_d: ()=>/* reexport */ TagQuery,\n MJk: ()=>/* reexport */ TestClock,\n xvT: ()=>/* reexport */ Text,\n PHM: ()=>/* reexport */ TextAlign,\n dpR: ()=>/* reexport */ TextureLoader,\n n9L: ()=>/* reexport */ Tile,\n KwO: ()=>/* reexport */ TileMap,\n SxM: ()=>/* reexport */ TileMapEvents,\n B7y: ()=>/* reexport */ Timer,\n x7r: ()=>/* reexport */ Toaster,\n wx7: ()=>/* reexport */ transform_Transform,\n Uvn: ()=>/* reexport */ TransformComponent,\n uTP: ()=>/* reexport */ Transition,\n OFT: ()=>/* reexport */ TreeNode,\n xzN: ()=>/* reexport */ Trigger,\n CcZ: ()=>/* reexport */ TriggerEvents,\n M5Z: ()=>/* reexport */ TwoPI,\n ZrN: ()=>/* reexport */ Util_Index_namespaceObject,\n OWs: ()=>/* reexport */ Vector,\n dF9: ()=>/* reexport */ VectorView,\n oZy: ()=>/* reexport */ VertexBuffer,\n rD2: ()=>/* reexport */ VertexLayout,\n KmN: ()=>/* reexport */ VerticalFirst,\n VHo: ()=>/* reexport */ VisibleEvent,\n ohE: ()=>/* reexport */ WebAudio,\n R$E: ()=>/* reexport */ WebAudioInstance,\n xQN: ()=>/* reexport */ WheelDeltaMode,\n AdJ: ()=>/* reexport */ WheelEvent,\n q3I: ()=>/* reexport */ World,\n Pab: ()=>/* reexport */ canonicalizeAngle,\n uZ5: ()=>/* reexport */ clamp,\n TAE: ()=>/* reexport */ coroutine,\n McK: ()=>/* reexport */ createId,\n F9c: ()=>/* reexport */ frac,\n k0b: ()=>/* reexport */ hasGraphicsTick,\n hnT: ()=>/* reexport */ hasOnInitialize,\n RSJ: ()=>/* reexport */ hasOnPostUpdate,\n Mku: ()=>/* reexport */ hasOnPreUpdate,\n h90: ()=>/* reexport */ hasPostDraw,\n rms: ()=>/* reexport */ hasPreDraw,\n ErP: ()=>/* reexport */ has_initialize,\n aVg: ()=>/* reexport */ has_postupdate,\n lPc: ()=>/* reexport */ has_preupdate,\n Z8E: ()=>/* reexport */ isAddedComponent,\n k15: ()=>/* reexport */ isComponentCtor,\n YsU: ()=>/* reexport */ isLoaderConstructor,\n lNv: ()=>/* reexport */ isRemovedComponent,\n Xyg: ()=>/* reexport */ isSceneConstructor,\n cu9: ()=>/* reexport */ isScreenElement,\n p88: ()=>/* reexport */ isSystemConstructor,\n MZQ: ()=>/* reexport */ maxMessages,\n FUM: ()=>/* reexport */ obsolete,\n BxR: ()=>/* reexport */ pixelSnapEpsilon,\n vdf: ()=>/* reexport */ randomInRange,\n iaL: ()=>/* reexport */ randomIntInRange,\n w6H: ()=>/* reexport */ range,\n Q4c: ()=>/* reexport */ resetObsoleteCounter,\n Xxe: ()=>/* reexport */ sign,\n Uxb: ()=>/* reexport */ toDegrees,\n Yr5: ()=>/* reexport */ toRadians,\n Bhw: ()=>/* reexport */ vec,\n yOA: ()=>/* reexport */ webgl_util_namespaceObject\n });\n // NAMESPACE OBJECT: ./Graphics/Context/webgl-util.ts\n var webgl_util_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(webgl_util_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(webgl_util_namespaceObject, {\n getAttributeComponentSize: ()=>getAttributeComponentSize,\n getAttributePointerType: ()=>getAttributePointerType,\n getGlTypeSizeBytes: ()=>getGlTypeSizeBytes\n });\n // NAMESPACE OBJECT: ./Events.ts\n var Events_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Events_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Events_namespaceObject, {\n ActionCompleteEvent: ()=>ActionCompleteEvent,\n ActionStartEvent: ()=>ActionStartEvent,\n ActivateEvent: ()=>ActivateEvent,\n CollisionEndEvent: ()=>CollisionEndEvent,\n CollisionPostSolveEvent: ()=>CollisionPostSolveEvent,\n CollisionPreSolveEvent: ()=>CollisionPreSolveEvent,\n CollisionStartEvent: ()=>CollisionStartEvent,\n ContactEndEvent: ()=>ContactEndEvent,\n ContactStartEvent: ()=>ContactStartEvent,\n DeactivateEvent: ()=>DeactivateEvent,\n EnterTriggerEvent: ()=>EnterTriggerEvent,\n EnterViewPortEvent: ()=>EnterViewPortEvent,\n EventTypes: ()=>EventTypes,\n ExitTriggerEvent: ()=>ExitTriggerEvent,\n ExitViewPortEvent: ()=>ExitViewPortEvent,\n GameEvent: ()=>GameEvent,\n GameStartEvent: ()=>GameStartEvent,\n GameStopEvent: ()=>GameStopEvent,\n GamepadAxisEvent: ()=>GamepadAxisEvent,\n GamepadButtonEvent: ()=>GamepadButtonEvent,\n GamepadConnectEvent: ()=>GamepadConnectEvent,\n GamepadDisconnectEvent: ()=>GamepadDisconnectEvent,\n HiddenEvent: ()=>HiddenEvent,\n InitializeEvent: ()=>InitializeEvent,\n KillEvent: ()=>KillEvent,\n PostCollisionEvent: ()=>PostCollisionEvent,\n PostDebugDrawEvent: ()=>PostDebugDrawEvent,\n PostDrawEvent: ()=>PostDrawEvent,\n PostFrameEvent: ()=>PostFrameEvent,\n PostKillEvent: ()=>PostKillEvent,\n PostTransformDrawEvent: ()=>PostTransformDrawEvent,\n PostUpdateEvent: ()=>PostUpdateEvent,\n PreCollisionEvent: ()=>PreCollisionEvent,\n PreDebugDrawEvent: ()=>PreDebugDrawEvent,\n PreDrawEvent: ()=>PreDrawEvent,\n PreFrameEvent: ()=>PreFrameEvent,\n PreKillEvent: ()=>PreKillEvent,\n PreTransformDrawEvent: ()=>PreTransformDrawEvent,\n PreUpdateEvent: ()=>PreUpdateEvent,\n VisibleEvent: ()=>VisibleEvent\n });\n // NAMESPACE OBJECT: ./Util/DrawUtil.ts\n var DrawUtil_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(DrawUtil_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(DrawUtil_namespaceObject, {\n circle: ()=>circle,\n line: ()=>line,\n point: ()=>point,\n roundRect: ()=>roundRect,\n vector: ()=>vector\n });\n // NAMESPACE OBJECT: ./Input/Index.ts\n var Input_Index_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Input_Index_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Input_Index_namespaceObject, {\n Axes: ()=>Axes,\n Buttons: ()=>Buttons,\n Gamepad: ()=>Gamepad,\n Gamepads: ()=>Gamepads,\n KeyEvent: ()=>KeyEvent,\n Keyboard: ()=>Keyboard,\n Keys: ()=>Keys,\n NativePointerButton: ()=>NativePointerButton,\n PointerButton: ()=>PointerButton,\n PointerComponent: ()=>PointerComponent,\n PointerEvent: ()=>PointerEvent,\n PointerEventReceiver: ()=>PointerEventReceiver,\n PointerScope: ()=>PointerScope,\n PointerSystem: ()=>PointerSystem,\n PointerType: ()=>PointerType,\n WheelDeltaMode: ()=>WheelDeltaMode,\n WheelEvent: ()=>WheelEvent\n });\n // NAMESPACE OBJECT: ./Util/Index.ts\n var Util_Index_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Util_Index_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Util_Index_namespaceObject, {\n ConsoleAppender: ()=>ConsoleAppender,\n DrawUtil: ()=>DrawUtil_namespaceObject,\n EasingFunctions: ()=>EasingFunctions,\n LogLevel: ()=>LogLevel,\n Logger: ()=>Logger,\n Observable: ()=>Observable,\n ScreenAppender: ()=>ScreenAppender,\n addItemToArray: ()=>addItemToArray,\n contains: ()=>contains,\n delay: ()=>delay,\n fail: ()=>fail,\n getPosition: ()=>getPosition,\n omit: ()=>omit,\n removeItemFromArray: ()=>removeItemFromArray\n });\n // EXTERNAL MODULE: ../../node_modules/core-js/es/array/sort.js\n var sort = $2c23f148d58cd887$var$__webpack_require__(1324);\n // EXTERNAL MODULE: ../../node_modules/core-js/es/object/keys.js\n var keys = $2c23f148d58cd887$var$__webpack_require__(3571);\n /**\n * Polyfill adding function\n */ function polyfill() {\n /* istanbul ignore next */ if (typeof window === \"undefined\") window = {\n audioContext: function() {\n return;\n }\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.requestAnimationFrame) window.requestAnimationFrame = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {\n window.setInterval(callback, 1000 / 60);\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.cancelAnimationFrame) window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function() {\n return;\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.AudioContext) {\n if (window.webkitAudioContext) {\n const ctx = window.webkitAudioContext;\n const replaceMe = ctx.prototype.decodeAudioData;\n window.webkitAudioContext.prototype.decodeAudioData = function(arrayBuffer) {\n return new Promise((resolve, reject)=>{\n replaceMe.call(this, arrayBuffer, resolve, reject);\n });\n };\n }\n window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext || window.oAudioContext;\n }\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.devicePixelRatio) window.devicePixelRatio = window.devicePixelRatio || 1;\n }\n /**\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\n * after which they are frozen and are read-only.\n *\n * Flags are used to enable experimental or preview features in Excalibur.\n */ class Flags {\n /**\n * Force excalibur to load the Canvas 2D graphics context fallback\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\n */ static useCanvasGraphicsContext() {\n Flags.enable(\"use-canvas-context\");\n }\n /**\n * Freeze all flag modifications making them readonly\n */ static freeze() {\n Flags._FROZEN = true;\n }\n /**\n * Resets internal flag state, not meant to be called by users. Only used for testing.\n *\n * Calling this in your game is UNSUPPORTED\n * @internal\n */ static _reset() {\n Flags._FROZEN = false;\n Flags._FLAGS = {};\n }\n /**\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\n * @param flagName\n */ static enable(flagName) {\n if (this._FROZEN) throw Error(\"Feature flags can only be enabled before Engine constructor time\");\n Flags._FLAGS[flagName] = true;\n }\n /**\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\n * @param flagName\n */ static disable(flagName) {\n if (this._FROZEN) throw Error(\"Feature flags can only be disabled before Engine constructor time\");\n Flags._FLAGS[flagName] = false;\n }\n /**\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\n * @param flagName\n */ static isEnabled(flagName) {\n return !!Flags._FLAGS[flagName];\n }\n /**\n * Show a list of currently known flags\n */ static show() {\n return Object.keys(Flags._FLAGS);\n }\n }\n Flags._FROZEN = false;\n Flags._FLAGS = {};\n /**\n * Create a branded ID type from a number\n */ function createId(type, value) {\n return {\n type: type,\n value: value\n };\n }\n /**\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\n */ class Future {\n constructor(){\n this._isCompleted = false;\n this.promise = new Promise((resolve, reject)=>{\n this._resolver = resolve;\n this._rejecter = reject;\n });\n }\n get isCompleted() {\n return this._isCompleted;\n }\n resolve(value) {\n if (this._isCompleted) return;\n this._isCompleted = true;\n this._resolver(value);\n }\n reject(error) {\n if (this._isCompleted) return;\n this._isCompleted = true;\n this._rejecter(error);\n }\n }\n /**\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\n */ class EventEmitter {\n constructor(){\n this._paused = false;\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes = [];\n }\n clear() {\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes.length = 0;\n }\n on(eventName, handler) {\n var _a;\n this._listeners[eventName] = (_a = this._listeners[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listeners[eventName].push(handler);\n return {\n close: ()=>this.off(eventName, handler)\n };\n }\n once(eventName, handler) {\n var _a;\n this._listenersOnce[eventName] = (_a = this._listenersOnce[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listenersOnce[eventName].push(handler);\n return {\n close: ()=>this.off(eventName, handler)\n };\n }\n off(eventName, handler) {\n var _a, _b;\n if (handler) {\n const newListeners = (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.filter((h)=>h !== handler);\n this._listeners[eventName] = newListeners;\n const newOnceListeners = (_b = this._listenersOnce[eventName]) === null || _b === void 0 ? void 0 : _b.filter((h)=>h !== handler);\n this._listenersOnce[eventName] = newOnceListeners;\n } else delete this._listeners[eventName];\n }\n emit(eventName, event) {\n var _a;\n if (this._paused) return;\n (_a = this._listeners[eventName]) === null || _a === void 0 || _a.forEach((fn)=>fn(event));\n const onces = this._listenersOnce[eventName];\n this._listenersOnce[eventName] = [];\n if (onces) onces.forEach((fn)=>fn(event));\n this._pipes.forEach((pipe)=>{\n pipe.emit(eventName, event);\n });\n }\n pipe(emitter) {\n if (this === emitter) throw Error(\"Cannot pipe to self\");\n this._pipes.push(emitter);\n return {\n close: ()=>{\n const i = this._pipes.indexOf(emitter);\n if (i > -1) this._pipes.splice(i, 1);\n }\n };\n }\n unpipe(emitter) {\n const i = this._pipes.indexOf(emitter);\n if (i > -1) this._pipes.splice(i, 1);\n }\n pause() {\n this._paused = true;\n }\n unpause() {\n this._paused = false;\n }\n }\n /**\n * Determines the scope of handling mouse/touch events.\n */ var PointerScope;\n (function(PointerScope) {\n /**\n * Handle events on the `canvas` element only. Events originating outside the\n * `canvas` will not be handled.\n */ PointerScope[\"Canvas\"] = \"Canvas\";\n /**\n * Handles events on the entire document. All events will be handled by Excalibur.\n */ PointerScope[\"Document\"] = \"Document\";\n })(PointerScope || (PointerScope = {}));\n /**\n * @module\n * Pseudo-Random Utility\n *\n * A pseudo-random utility to add seeded random support for help in\n * generating things like terrain or reproducible randomness. Uses the\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\n */ /**\n * 32-bit mask\n */ const BITMASK32 = 0xffffffff;\n /**\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\n * of numbers each time it is called.\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\n *\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\n */ class Random {\n /**\n * If no seed is specified, the Date.now() is used\n */ constructor(seed){\n this.seed = seed;\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\n this._lowerMask = 0x7fffffff; // 31 bits same as _r\n this._upperMask = 0x80000000; // 34 high bits\n // Word size, 64 bits\n this._w = 32;\n // Degree of recurrence\n this._n = 624;\n // Middle word, an offset used in the recurrence defining the series x, 1<=m>> 0;\n for(let i = 1; i < this._n; i++){\n const s = this._mt[i - 1] ^ this._mt[i - 1] >>> this._w - 2;\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\n this._mt[i] = (this._f * ((s & 0xffff0000) >>> 16) << 16) + this._f * (s & 0xffff) + i >>> 0;\n }\n this._index = this._n;\n }\n /**\n * Apply the twist\n */ _twist() {\n const mag01 = [\n 0x0,\n this._a\n ];\n let y = 0, i = 0;\n for(; i < this._n - this._m; i++){\n y = this._mt[i] & this._upperMask | this._mt[i + 1] & this._lowerMask;\n this._mt[i] = this._mt[i + this._m] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n }\n for(; i < this._n - 1; i++){\n y = this._mt[i] & this._upperMask | this._mt[i + 1] & this._lowerMask;\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n }\n y = this._mt[this._n - 1] & this._upperMask | this._mt[0] & this._lowerMask;\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n this._index = 0;\n }\n /**\n * Return next 32 bit integer number in sequence\n */ nextInt() {\n if (this._index >= this._n) this._twist();\n let y = this._mt[this._index++];\n y ^= y >>> this._u;\n y ^= y << this._s & this._b;\n y ^= y << this._t & this._c;\n y ^= y >>> this._l;\n return y >>> 0;\n }\n /**\n * Return a random floating point number between [0, 1)\n */ next() {\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\n }\n /**\n * Return a random floating point in range [min, max) min is included, max is not included\n */ floating(min, max) {\n return (max - min) * this.next() + min;\n }\n /**\n * Return a random integer in range [min, max] min is included, max is included.\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\n */ integer(min, max) {\n return Math.floor((max - min + 1) * this.next() + min);\n }\n /**\n * Returns true or false randomly with 50/50 odds by default.\n * By default the likelihood of returning a true is .5 (50%).\n * @param likelihood takes values between [0, 1]\n */ bool(likelihood = 0.5) {\n return this.next() <= likelihood;\n }\n /**\n * Returns one element from an array at random\n */ pickOne(array) {\n return array[this.integer(0, array.length - 1)];\n }\n /**\n * Returns a new array random picking elements from the original\n * @param array Original array to pick from\n * @param numPicks can be any positive number\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\n * just that it is possible)\n */ pickSet(array, numPicks, allowDuplicates = false) {\n if (allowDuplicates) return this._pickSetWithDuplicates(array, numPicks);\n else return this._pickSetWithoutDuplicates(array, numPicks);\n }\n /**\n * Returns a new array randomly picking elements in the original (not reused)\n * @param array Array to pick elements out of\n * @param numPicks must be less than or equal to the number of elements in the array.\n */ _pickSetWithoutDuplicates(array, numPicks) {\n if (numPicks > array.length || numPicks < 0) throw new Error(\"Invalid number of elements to pick, must pick a value 0 < n <= length\");\n if (numPicks === array.length) return array;\n const result = new Array(numPicks);\n let currentPick = 0;\n const tempArray = array.slice(0);\n while(currentPick < numPicks){\n const index = this.integer(0, tempArray.length - 1);\n result[currentPick++] = tempArray[index];\n tempArray.splice(index, 1);\n }\n return result;\n }\n /**\n * Returns a new array random picking elements from the original allowing duplicates\n * @param array Array to pick elements out of\n * @param numPicks can be any positive number\n */ _pickSetWithDuplicates(array, numPicks) {\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\n if (numPicks < 0) throw new Error(\"Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT\");\n const result = new Array(numPicks);\n for(let i = 0; i < numPicks; i++)result[i] = this.pickOne(array);\n return result;\n }\n /**\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\n */ shuffle(array) {\n const tempArray = array.slice(0);\n let swap = null;\n for(let i = 0; i < tempArray.length - 2; i++){\n const randomIndex = this.integer(i, tempArray.length - 1);\n swap = tempArray[i];\n tempArray[i] = tempArray[randomIndex];\n tempArray[randomIndex] = swap;\n }\n return tempArray;\n }\n /**\n * Generate a list of random integer numbers\n * @param length the length of the final array\n * @param min the minimum integer number to generate inclusive\n * @param max the maximum integer number to generate inclusive\n */ range(length, min, max) {\n const result = new Array(length);\n for(let i = 0; i < length; i++)result[i] = this.integer(min, max);\n return result;\n }\n /**\n * Returns the result of a d4 dice roll\n */ d4() {\n return this.integer(1, 4);\n }\n /**\n * Returns the result of a d6 dice roll\n */ d6() {\n return this.integer(1, 6);\n }\n /**\n * Returns the result of a d8 dice roll\n */ d8() {\n return this.integer(1, 8);\n }\n /**\n * Returns the result of a d10 dice roll\n */ d10() {\n return this.integer(1, 10);\n }\n /**\n * Returns the result of a d12 dice roll\n */ d12() {\n return this.integer(1, 12);\n }\n /**\n * Returns the result of a d20 dice roll\n */ d20() {\n return this.integer(1, 20);\n }\n }\n /**\n * Two PI constant\n */ const TwoPI = Math.PI * 2;\n /**\n * Returns the fractional part of a number\n * @param x\n */ function frac(x) {\n if (x >= 0) return x - Math.floor(x);\n else return x - Math.ceil(x);\n }\n /**\n * Returns the sign of a number, if 0 returns 0\n */ function sign(val) {\n if (val === 0) return 0;\n return val < 0 ? -1 : 1;\n }\n /**\n * Clamps a value between a min and max inclusive\n */ function clamp(val, min, max) {\n return Math.min(Math.max(min, val), max);\n }\n /**\n * Convert an angle to be the equivalent in the range [0, 2PI]\n */ function canonicalizeAngle(angle) {\n let tmpAngle = angle;\n if (angle > TwoPI) while(tmpAngle > TwoPI)tmpAngle -= TwoPI;\n if (angle < 0) while(tmpAngle < 0)tmpAngle += TwoPI;\n return tmpAngle;\n }\n /**\n * Convert radians to degrees\n */ function toDegrees(radians) {\n return 180 / Math.PI * radians;\n }\n /**\n * Convert degrees to radians\n */ function toRadians(degrees) {\n return degrees / 180 * Math.PI;\n }\n /**\n * Generate a range of numbers\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\n * @param from inclusive\n * @param to inclusive\n */ const range = (from, to)=>Array.from(new Array(to - from + 1), (_x, i)=>i + from);\n /**\n * Find a random floating point number in range\n */ function randomInRange(min, max, random = new Random()) {\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\n }\n /**\n * Find a random integer in a range\n */ function randomIntInRange(min, max, random = new Random()) {\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\n }\n /**\n * A 2D vector on a plane.\n */ class Vector {\n /**\n * A (0, 0) vector\n */ static get Zero() {\n return new Vector(0, 0);\n }\n /**\n * A (1, 1) vector\n */ static get One() {\n return new Vector(1, 1);\n }\n /**\n * A (0.5, 0.5) vector\n */ static get Half() {\n return new Vector(0.5, 0.5);\n }\n /**\n * A unit vector pointing up (0, -1)\n */ static get Up() {\n return new Vector(0, -1);\n }\n /**\n * A unit vector pointing down (0, 1)\n */ static get Down() {\n return new Vector(0, 1);\n }\n /**\n * A unit vector pointing left (-1, 0)\n */ static get Left() {\n return new Vector(-1, 0);\n }\n /**\n * A unit vector pointing right (1, 0)\n */ static get Right() {\n return new Vector(1, 0);\n }\n /**\n * Returns a vector of unit length in the direction of the specified angle in Radians.\n * @param angle The angle to generate the vector\n */ static fromAngle(angle) {\n return new Vector(Math.cos(angle), Math.sin(angle));\n }\n /**\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\n */ static isValid(vec) {\n if (vec === null || vec === undefined) return false;\n if (isNaN(vec.x) || isNaN(vec.y)) return false;\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) return false;\n return true;\n }\n /**\n * Calculates distance between two Vectors\n * @param vec1\n * @param vec2\n */ static distance(vec1, vec2) {\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\n }\n static min(vec1, vec2) {\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\n }\n static max(vec1, vec2) {\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\n }\n /**\n * @param x X component of the Vector\n * @param y Y component of the Vector\n */ constructor(x, y){\n this._x = 0;\n this._y = 0;\n this._x = x;\n this._y = y;\n }\n /**\n * Get the x component of the vector\n */ get x() {\n return this._x;\n }\n /**\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\n */ set x(val) {\n this._x = val;\n }\n /**\n * Get the y component of the vector\n */ get y() {\n return this._y;\n }\n /**\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\n */ set y(val) {\n this._y = val;\n }\n /**\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\n */ setTo(x, y) {\n this.x = x;\n this.y = y;\n }\n /**\n * Compares this point against another and tests for equality\n * @param vector The other point to compare to\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\n */ equals(vector, tolerance = 0.001) {\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\n }\n /**\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\n * @param v The other vector. Leave blank to use origin vector.\n */ distance(v) {\n if (!v) return Math.sqrt(this.x * this.x + this.y * this.y);\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n }\n squareDistance(v) {\n if (!v) v = Vector.Zero;\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return deltaX * deltaX + deltaY * deltaY;\n }\n /**\n * Clamps the current vector's magnitude mutating it\n * @param magnitude\n */ clampMagnitude(magnitude) {\n const size = this.size;\n const newSize = clamp(size, 0, magnitude);\n this.size = newSize;\n return this;\n }\n /**\n * The size (magnitude) of the Vector\n */ get size() {\n return this.distance();\n }\n /**\n * Setting the size mutates the current vector\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\n */ set size(newLength) {\n const v = this.normalize().scale(newLength);\n this.setTo(v.x, v.y);\n }\n /**\n * Normalizes a vector to have a magnitude of 1.\n */ normalize() {\n const d = this.distance();\n if (d > 0) return new Vector(this.x / d, this.y / d);\n else return new Vector(0, 1);\n }\n /**\n * Returns the average (midpoint) between the current point and the specified\n */ average(vec) {\n return this.add(vec).scale(0.5);\n }\n scale(sizeOrScale, dest) {\n const result = dest || new Vector(0, 0);\n if (sizeOrScale instanceof Vector) {\n result.x = this.x * sizeOrScale.x;\n result.y = this.y * sizeOrScale.y;\n } else {\n result.x = this.x * sizeOrScale;\n result.y = this.y * sizeOrScale;\n }\n return result;\n }\n /**\n * Adds one vector to another\n * @param v The vector to add\n * @param dest Optionally copy the result into a provided vector\n */ add(v, dest) {\n if (dest) {\n dest.x = this.x + v.x;\n dest.y = this.y + v.y;\n return dest;\n }\n return new Vector(this.x + v.x, this.y + v.y);\n }\n /**\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\n * @param v The vector to subtract\n */ sub(v) {\n return new Vector(this.x - v.x, this.y - v.y);\n }\n /**\n * Adds one vector to this one modifying the original\n * @param v The vector to add\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */ addEqual(v) {\n this.setTo(this.x + v.x, this.y + v.y);\n return this;\n }\n /**\n * Subtracts a vector from this one modifying the original\n * @param v The vector to subtract\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */ subEqual(v) {\n this.setTo(this.x - v.x, this.y - v.y);\n return this;\n }\n /**\n * Scales this vector by a factor of size and modifies the original\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */ scaleEqual(size) {\n this.setTo(this.x * size, this.y * size);\n return this;\n }\n /**\n * Performs a dot product with another vector\n * @param v The vector to dot\n */ dot(v) {\n return this.x * v.x + this.y * v.y;\n }\n cross(v) {\n if (v instanceof Vector) return this.x * v.y - this.y * v.x;\n else if (typeof v === \"number\") return new Vector(v * this.y, -v * this.x);\n }\n static cross(num, vec) {\n return new Vector(-num * vec.y, num * vec.x);\n }\n /**\n * Returns the perpendicular vector to this one\n */ perpendicular() {\n return new Vector(this.y, -this.x);\n }\n /**\n * Returns the normal vector to this one, same as the perpendicular of length 1\n */ normal() {\n return this.perpendicular().normalize();\n }\n /**\n * Negate the current vector\n */ negate() {\n return this.scale(-1);\n }\n /**\n * Returns the angle of this vector.\n */ toAngle() {\n return Math.atan2(this.y, this.x);\n }\n /**\n * Rotates the current vector around a point by a certain number of\n * degrees in radians\n */ rotate(angle, anchor) {\n if (!anchor) anchor = new Vector(0, 0);\n const sinAngle = Math.sin(angle);\n const cosAngle = Math.cos(angle);\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\n return new Vector(x, y);\n }\n /**\n * Creates new vector that has the same values as the previous.\n */ clone(dest) {\n const v = dest !== null && dest !== void 0 ? dest : new Vector(0, 0);\n v.x = this.x;\n v.y = this.y;\n return v;\n }\n /**\n * Returns a string representation of the vector.\n */ toString(fixed) {\n if (fixed) return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\n return `(${this.x}, ${this.y})`;\n }\n }\n /**\n * Shorthand for creating new Vectors - returns a new Vector instance with the\n * provided X and Y components.\n * @param x X component of the Vector\n * @param y Y component of the Vector\n */ function vec(x, y) {\n return new Vector(x, y);\n }\n /**\n * Provides standard colors (e.g. [[Color.Black]])\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\n */ class Color {\n /**\n * Creates a new instance of Color from an r, g, b, a\n * @param r The red component of color (0-255)\n * @param g The green component of color (0-255)\n * @param b The blue component of color (0-255)\n * @param a The alpha component of color (0-1.0)\n */ constructor(r, g, b, a){\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a != null ? a : 1;\n }\n /**\n * Creates a new instance of Color from an r, g, b, a\n * @param r The red component of color (0-255)\n * @param g The green component of color (0-255)\n * @param b The blue component of color (0-255)\n * @param a The alpha component of color (0-1.0)\n */ static fromRGB(r, g, b, a) {\n return new Color(r, g, b, a);\n }\n /**\n * Creates a new instance of Color from a rgb string\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\n */ static fromRGBString(string) {\n const rgbaRegEx = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\n let match = null;\n if (match = string.match(rgbaRegEx)) {\n const r = parseInt(match[1], 10);\n const g = parseInt(match[2], 10);\n const b = parseInt(match[3], 10);\n let a = 1;\n if (match[4]) a = parseFloat(match[4]);\n return new Color(r, g, b, a);\n } else throw new Error(\"Invalid rgb/a string: \" + string);\n }\n /**\n * Creates a new instance of Color from a hex string\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\n */ static fromHex(hex) {\n const hexRegEx = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\n let match = null;\n if (match = hex.match(hexRegEx)) {\n const r = parseInt(match[1], 16);\n const g = parseInt(match[2], 16);\n const b = parseInt(match[3], 16);\n let a = 1;\n if (match[4]) a = parseInt(match[4], 16) / 255;\n return new Color(r, g, b, a);\n } else throw new Error(\"Invalid hex string: \" + hex);\n }\n /**\n * Creates a new instance of Color from hsla values\n * @param h Hue is represented [0-1]\n * @param s Saturation is represented [0-1]\n * @param l Luminance is represented [0-1]\n * @param a Alpha is represented [0-1]\n */ static fromHSL(h, s, l, a = 1.0) {\n const temp = new HSLColor(h, s, l, a);\n return temp.toRGBA();\n }\n /**\n * Lightens the current color by a specified amount\n * @param factor The amount to lighten by [0-1]\n */ lighten(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l += (1 - temp.l) * factor;\n return temp.toRGBA();\n }\n /**\n * Darkens the current color by a specified amount\n * @param factor The amount to darken by [0-1]\n */ darken(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l -= temp.l * factor;\n return temp.toRGBA();\n }\n /**\n * Saturates the current color by a specified amount\n * @param factor The amount to saturate by [0-1]\n */ saturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s += temp.s * factor;\n return temp.toRGBA();\n }\n /**\n * Desaturates the current color by a specified amount\n * @param factor The amount to desaturate by [0-1]\n */ desaturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s -= temp.s * factor;\n return temp.toRGBA();\n }\n /**\n * Multiplies a color by another, results in a darker color\n * @param color The other color\n */ multiply(color) {\n const newR = color.r / 255 * this.r / 255 * 255;\n const newG = color.g / 255 * this.g / 255 * 255;\n const newB = color.b / 255 * this.b / 255 * 255;\n const newA = color.a * this.a;\n return new Color(newR, newG, newB, newA);\n }\n /**\n * Screens a color by another, results in a lighter color\n * @param color The other color\n */ screen(color) {\n const color1 = color.invert();\n const color2 = color.invert();\n return color1.multiply(color2).invert();\n }\n /**\n * Inverts the current color\n */ invert() {\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\n }\n /**\n * Averages the current color with another\n * @param color The other color\n */ average(color) {\n const newR = (color.r + this.r) / 2;\n const newG = (color.g + this.g) / 2;\n const newB = (color.b + this.b) / 2;\n const newA = (color.a + this.a) / 2;\n return new Color(newR, newG, newB, newA);\n }\n equal(color) {\n return this.toString() === color.toString();\n }\n /**\n * Returns a CSS string representation of a color.\n * @param format Color representation, accepts: rgb, hsl, or hex\n */ toString(format = \"rgb\") {\n switch(format){\n case \"rgb\":\n return this.toRGBA();\n case \"hsl\":\n return this.toHSLA();\n case \"hex\":\n return this.toHex();\n default:\n throw new Error(\"Invalid Color format\");\n }\n }\n /**\n * Returns Hex Value of a color component\n * @param c color component\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\n */ _componentToHex(c) {\n const hex = c.toString(16);\n return hex.length === 1 ? \"0\" + hex : hex;\n }\n /**\n * Return Hex representation of a color.\n */ toHex() {\n return \"#\" + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\n }\n /**\n * Return RGBA representation of a color.\n */ toRGBA() {\n const result = String(this.r.toFixed(0)) + \", \" + String(this.g.toFixed(0)) + \", \" + String(this.b.toFixed(0));\n if (this.a !== undefined || this.a !== null) return \"rgba(\" + result + \", \" + String(this.a) + \")\";\n return \"rgb(\" + result + \")\";\n }\n /**\n * Return HSLA representation of a color.\n */ toHSLA() {\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\n }\n /**\n * Returns a CSS string representation of a color.\n */ fillStyle() {\n return this.toString();\n }\n /**\n * Returns a clone of the current color.\n */ clone() {\n return new Color(this.r, this.g, this.b, this.a);\n }\n /**\n * Black (#000000)\n */ static get Black() {\n return Color.fromHex(\"#000000\");\n }\n /**\n * White (#FFFFFF)\n */ static get White() {\n return Color.fromHex(\"#FFFFFF\");\n }\n /**\n * Gray (#808080)\n */ static get Gray() {\n return Color.fromHex(\"#808080\");\n }\n /**\n * Light gray (#D3D3D3)\n */ static get LightGray() {\n return Color.fromHex(\"#D3D3D3\");\n }\n /**\n * Dark gray (#A9A9A9)\n */ static get DarkGray() {\n return Color.fromHex(\"#A9A9A9\");\n }\n /**\n * Yellow (#FFFF00)\n */ static get Yellow() {\n return Color.fromHex(\"#FFFF00\");\n }\n /**\n * Orange (#FFA500)\n */ static get Orange() {\n return Color.fromHex(\"#FFA500\");\n }\n /**\n * Red (#FF0000)\n */ static get Red() {\n return Color.fromHex(\"#FF0000\");\n }\n /**\n * Vermilion (#FF5B31)\n */ static get Vermilion() {\n return Color.fromHex(\"#FF5B31\");\n }\n /**\n * Rose (#FF007F)\n */ static get Rose() {\n return Color.fromHex(\"#FF007F\");\n }\n /**\n * Magenta (#FF00FF)\n */ static get Magenta() {\n return Color.fromHex(\"#FF00FF\");\n }\n /**\n * Violet (#7F00FF)\n */ static get Violet() {\n return Color.fromHex(\"#7F00FF\");\n }\n /**\n * Blue (#0000FF)\n */ static get Blue() {\n return Color.fromHex(\"#0000FF\");\n }\n /**\n * Azure (#007FFF)\n */ static get Azure() {\n return Color.fromHex(\"#007FFF\");\n }\n /**\n * Cyan (#00FFFF)\n */ static get Cyan() {\n return Color.fromHex(\"#00FFFF\");\n }\n /**\n * Viridian (#59978F)\n */ static get Viridian() {\n return Color.fromHex(\"#59978F\");\n }\n /**\n * Green (#00FF00)\n */ static get Green() {\n return Color.fromHex(\"#00FF00\");\n }\n /**\n * Chartreuse (#7FFF00)\n */ static get Chartreuse() {\n return Color.fromHex(\"#7FFF00\");\n }\n /**\n * Transparent (#FFFFFF00)\n */ static get Transparent() {\n return Color.fromHex(\"#FFFFFF00\");\n }\n /**\n * ExcaliburBlue (#176BAA)\n */ static get ExcaliburBlue() {\n return Color.fromHex(\"#176BAA\");\n }\n }\n /**\n * Internal HSL Color representation\n *\n * http://en.wikipedia.org/wiki/HSL_and_HSV\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\n */ class HSLColor {\n constructor(h, s, l, a){\n this.h = h;\n this.s = s;\n this.l = l;\n this.a = a;\n }\n static hue2rgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 0.5) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n }\n static fromRGBA(r, g, b, a) {\n r /= 255;\n g /= 255;\n b /= 255;\n const max = Math.max(r, g, b), min = Math.min(r, g, b);\n let h, s;\n const l = (max + min) / 2;\n if (max === min) h = s = 0; // achromatic\n else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch(max){\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n return new HSLColor(h, s, l, a);\n }\n toRGBA() {\n let r, g, b;\n if (this.s === 0) r = g = b = this.l; // achromatic\n else {\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\n const p = 2 * this.l - q;\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\n g = HSLColor.hue2rgb(p, q, this.h);\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\n }\n return new Color(r * 255, g * 255, b * 255, this.a);\n }\n toString() {\n const h = this.h.toFixed(0), s = this.s.toFixed(0), l = this.l.toFixed(0), a = this.a.toFixed(0);\n return `hsla(${h}, ${s}, ${l}, ${a})`;\n }\n }\n /* eslint-disable no-console */ /**\n * Logging level that Excalibur will tag\n */ var LogLevel;\n (function(LogLevel) {\n LogLevel[LogLevel[\"Debug\"] = 0] = \"Debug\";\n LogLevel[LogLevel[\"Info\"] = 1] = \"Info\";\n LogLevel[LogLevel[\"Warn\"] = 2] = \"Warn\";\n LogLevel[LogLevel[\"Error\"] = 3] = \"Error\";\n LogLevel[LogLevel[\"Fatal\"] = 4] = \"Fatal\";\n })(LogLevel || (LogLevel = {}));\n /**\n * Static singleton that represents the logging facility for Excalibur.\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\n * Derive from [[Appender]] to create your own logging appenders.\n */ class Logger {\n constructor(){\n this._appenders = [];\n /**\n * Gets or sets the default logging level. Excalibur will only log\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\n */ this.defaultLevel = LogLevel.Info;\n this._logOnceSet = new Set();\n if (Logger._INSTANCE) throw new Error(\"Logger is a singleton\");\n Logger._INSTANCE = this;\n // Default console appender\n Logger._INSTANCE.addAppender(new ConsoleAppender());\n return Logger._INSTANCE;\n }\n /**\n * Gets the current static instance of Logger\n */ static getInstance() {\n if (Logger._INSTANCE == null) Logger._INSTANCE = new Logger();\n return Logger._INSTANCE;\n }\n /**\n * Adds a new [[Appender]] to the list of appenders to write to\n */ addAppender(appender) {\n this._appenders.push(appender);\n }\n /**\n * Clears all appenders from the logger\n */ clearAppenders() {\n this._appenders.length = 0;\n }\n /**\n * Logs a message at a given LogLevel\n * @param level The LogLevel`to log the message at\n * @param args An array of arguments to write to an appender\n */ _log(level, args) {\n if (level == null) level = this.defaultLevel;\n const len = this._appenders.length;\n for(let i = 0; i < len; i++)if (level >= this.defaultLevel) this._appenders[i].log(level, args);\n }\n _logOnce(level, args) {\n const serialized = level + args.join(\"+\");\n if (this._logOnceSet.has(serialized)) return;\n else {\n this._logOnceSet.add(serialized);\n this._log(level, args);\n }\n }\n /**\n * Writes a log message at the [[LogLevel.Debug]] level\n * @param args Accepts any number of arguments\n */ debug(...args) {\n this._log(LogLevel.Debug, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it wont log\n * @param args Accepts any number of arguments\n */ debugOnce(...args) {\n this._logOnce(LogLevel.Debug, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Info]] level\n * @param args Accepts any number of arguments\n */ info(...args) {\n this._log(LogLevel.Info, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Info]] level, if it sees the same args again it wont log\n * @param args Accepts any number of arguments\n */ infoOnce(...args) {\n this._logOnce(LogLevel.Info, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Warn]] level\n * @param args Accepts any number of arguments\n */ warn(...args) {\n this._log(LogLevel.Warn, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Warn]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */ warnOnce(...args) {\n this._logOnce(LogLevel.Warn, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Error]] level\n * @param args Accepts any number of arguments\n */ error(...args) {\n this._log(LogLevel.Error, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Error]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */ errorOnce(...args) {\n this._logOnce(LogLevel.Error, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Fatal]] level\n * @param args Accepts any number of arguments\n */ fatal(...args) {\n this._log(LogLevel.Fatal, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */ fatalOnce(...args) {\n this._logOnce(LogLevel.Fatal, args);\n }\n }\n Logger._INSTANCE = null;\n /**\n * Console appender for browsers (i.e. `console.log`)\n */ class ConsoleAppender {\n /**\n * Logs a message at the given [[LogLevel]]\n * @param level Level to log at\n * @param args Arguments to log\n */ log(level, args) {\n // Check for console support\n if (!console && !console.log && console.warn && console.error) // todo maybe do something better than nothing\n return;\n // Create a new console args array\n const consoleArgs = [];\n consoleArgs.unshift.apply(consoleArgs, args);\n consoleArgs.unshift(\"[\" + LogLevel[level] + \"] : \");\n if (level < LogLevel.Warn) {\n // Call .log for Debug/Info\n if (console.log.apply) // this is required on some older browsers that don't support apply on console.log :(\n console.log.apply(console, consoleArgs);\n else console.log(consoleArgs.join(\" \"));\n } else if (level < LogLevel.Error) {\n // Call .warn for Warn\n if (console.warn.apply) console.warn.apply(console, consoleArgs);\n else console.warn(consoleArgs.join(\" \"));\n } else // Call .error for Error/Fatal\n if (console.error.apply) console.error.apply(console, consoleArgs);\n else console.error(consoleArgs.join(\" \"));\n }\n }\n /**\n * On-screen (canvas) appender\n */ class ScreenAppender {\n constructor(options){\n var _a, _b;\n this._messages = [];\n this._pos = 10;\n this._color = Color.Black;\n this._options = options;\n this.canvas = document.createElement(\"canvas\");\n this._ctx = this.canvas.getContext(\"2d\");\n this.canvas.style.position = \"absolute\";\n this.canvas.style.zIndex = (_b = (_a = options.zIndex) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : \"99\";\n document.body.appendChild(this.canvas);\n this._positionScreenAppenderCanvas();\n options.engine.screen.events.on(\"resize\", ()=>{\n this._positionScreenAppenderCanvas();\n });\n }\n _positionScreenAppenderCanvas() {\n var _a, _b, _c, _d;\n const options = this._options;\n this.canvas.width = (_a = options.width) !== null && _a !== void 0 ? _a : options.engine.screen.resolution.width;\n this.canvas.height = (_b = options.height) !== null && _b !== void 0 ? _b : options.engine.screen.resolution.height;\n this.canvas.style.position = \"absolute\";\n const pagePos = options.engine.screen.screenToPageCoordinates(vec(0, 0));\n this.canvas.style.left = pagePos.x + \"px\";\n this.canvas.style.top = pagePos.y + \"px\";\n this._pos = (_c = options.xPos) !== null && _c !== void 0 ? _c : this._pos;\n this._color = (_d = options.color) !== null && _d !== void 0 ? _d : this._color;\n }\n /**\n * Logs a message at the given [[LogLevel]]\n * @param level Level to log at\n * @param args Arguments to log\n */ log(level, args) {\n const message = args.join(\",\");\n this._ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this._messages.unshift(\"[\" + LogLevel[level] + \"] : \" + message);\n let pos = 10;\n this._messages = this._messages.slice(0, 1000);\n for(let i = 0; i < this._messages.length; i++){\n this._ctx.fillStyle = this._color.toRGBA();\n this._ctx.fillText(this._messages[i], this._pos, pos);\n pos += 10;\n }\n }\n }\n /**\n * An enum that describes the sides of an axis aligned box for collision\n */ var Side;\n (function(Side) {\n Side[\"None\"] = \"None\";\n Side[\"Top\"] = \"Top\";\n Side[\"Bottom\"] = \"Bottom\";\n Side[\"Left\"] = \"Left\";\n Side[\"Right\"] = \"Right\";\n })(Side || (Side = {}));\n (function(Side) {\n /**\n * Returns the opposite side from the current\n */ function getOpposite(side) {\n if (side === Side.Top) return Side.Bottom;\n if (side === Side.Bottom) return Side.Top;\n if (side === Side.Left) return Side.Right;\n if (side === Side.Right) return Side.Left;\n return Side.None;\n }\n Side.getOpposite = getOpposite;\n /**\n * Given a vector, return the Side most in that direction (via dot product)\n */ function fromDirection(direction) {\n const directions = [\n Vector.Left,\n Vector.Right,\n Vector.Up,\n Vector.Down\n ];\n const directionEnum = [\n Side.Left,\n Side.Right,\n Side.Top,\n Side.Bottom\n ];\n let max = -Number.MAX_VALUE;\n let maxIndex = -1;\n for(let i = 0; i < directions.length; i++)if (directions[i].dot(direction) > max) {\n max = directions[i].dot(direction);\n maxIndex = i;\n }\n return directionEnum[maxIndex];\n }\n Side.fromDirection = fromDirection;\n })(Side || (Side = {}));\n /**\n * Axis Aligned collision primitive for Excalibur.\n */ class BoundingBox {\n /**\n * Constructor allows passing of either an object with all coordinate components,\n * or the coordinate components passed separately.\n * @param leftOrOptions Either x coordinate of the left edge or an options object\n * containing the four coordinate components.\n * @param top y coordinate of the top edge\n * @param right x coordinate of the right edge\n * @param bottom y coordinate of the bottom edge\n */ constructor(leftOrOptions = 0, top = 0, right = 0, bottom = 0){\n // Cache bounding box point returns\n this._points = [];\n if (typeof leftOrOptions === \"object\") {\n this.left = leftOrOptions.left;\n this.top = leftOrOptions.top;\n this.right = leftOrOptions.right;\n this.bottom = leftOrOptions.bottom;\n } else if (typeof leftOrOptions === \"number\") {\n this.left = leftOrOptions;\n this.top = top;\n this.right = right;\n this.bottom = bottom;\n }\n }\n /**\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\n */ clone() {\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\n }\n /**\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\n * @param intersection Intersection vector between 2 bounding boxes\n */ static getSideFromIntersection(intersection) {\n if (!intersection) return Side.None;\n if (intersection) {\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\n if (intersection.x < 0) return Side.Right;\n return Side.Left;\n } else {\n if (intersection.y < 0) return Side.Bottom;\n return Side.Top;\n }\n }\n return Side.None;\n }\n static fromPoints(points) {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for(let i = 0; i < points.length; i++){\n if (points[i].x < minX) minX = points[i].x;\n if (points[i].x > maxX) maxX = points[i].x;\n if (points[i].y < minY) minY = points[i].y;\n if (points[i].y > maxY) maxY = points[i].y;\n }\n return new BoundingBox(minX, minY, maxX, maxY);\n }\n /**\n * Creates a bounding box from a width and height\n * @param width\n * @param height\n * @param anchor Default Vector.Half\n * @param pos Default Vector.Zero\n */ static fromDimension(width, height, anchor = Vector.Half, pos = Vector.Zero) {\n return new BoundingBox(-width * anchor.x + pos.x, -height * anchor.y + pos.y, width - width * anchor.x + pos.x, height - height * anchor.y + pos.y);\n }\n /**\n * Returns the calculated width of the bounding box\n */ get width() {\n return this.right - this.left;\n }\n /**\n * Returns the calculated height of the bounding box\n */ get height() {\n return this.bottom - this.top;\n }\n /**\n * Return whether the bounding box has zero dimensions in height,width or both\n */ hasZeroDimensions() {\n return this.width === 0 || this.height === 0;\n }\n /**\n * Returns the center of the bounding box\n */ get center() {\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\n }\n get topLeft() {\n return new Vector(this.left, this.top);\n }\n get bottomRight() {\n return new Vector(this.right, this.bottom);\n }\n get topRight() {\n return new Vector(this.right, this.top);\n }\n get bottomLeft() {\n return new Vector(this.left, this.bottom);\n }\n translate(pos) {\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\n }\n /**\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\n */ rotate(angle, point = Vector.Zero) {\n const points = this.getPoints().map((p)=>p.rotate(angle, point));\n return BoundingBox.fromPoints(points);\n }\n /**\n * Scale a bounding box by a scale factor, optionally provide a point\n * @param scale\n * @param point\n */ scale(scale, point = Vector.Zero) {\n const shifted = this.translate(point);\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\n }\n /**\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\n * @param matrix\n */ transform(matrix) {\n // inlined these calculations to not use vectors would speed it up slightly\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\n // const xa = matFirstColumn.scale(this.left);\n const xa1 = matrix.data[0] * this.left;\n const xa2 = matrix.data[1] * this.left;\n // const xb = matFirstColumn.scale(this.right);\n const xb1 = matrix.data[0] * this.right;\n const xb2 = matrix.data[1] * this.right;\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\n // const ya = matSecondColumn.scale(this.top);\n const ya1 = matrix.data[2] * this.top;\n const ya2 = matrix.data[3] * this.top;\n // const yb = matSecondColumn.scale(this.bottom);\n const yb1 = matrix.data[2] * this.bottom;\n const yb2 = matrix.data[3] * this.bottom;\n const matrixPos = matrix.getPosition();\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\n return new BoundingBox({\n left: left,\n top: top,\n right: right,\n bottom: bottom //: bottomRight.y\n });\n }\n /**\n * Returns the perimeter of the bounding box\n */ getPerimeter() {\n const wx = this.width;\n const wy = this.height;\n return 2 * (wx + wy);\n }\n /**\n * Returns the world space points that make up the corners of the bounding box as a polygon\n */ getPoints() {\n if (this._left !== this.left || this._right !== this.right || this._top !== this.top || this._bottom !== this.bottom) {\n this._points.length = 0;\n this._points.push(new Vector(this.left, this.top));\n this._points.push(new Vector(this.right, this.top));\n this._points.push(new Vector(this.right, this.bottom));\n this._points.push(new Vector(this.left, this.bottom));\n this._left = this.left;\n this._right = this.right;\n this._top = this.top;\n this._bottom = this.bottom;\n }\n return this._points;\n }\n /**\n * Determines whether a ray intersects with a bounding box\n */ rayCast(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\n }\n rayCastTime(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) return tmin;\n return -1;\n }\n contains(val) {\n if (val instanceof Vector) return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\n else if (val instanceof BoundingBox) {\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) return true;\n return false;\n }\n return false;\n }\n /**\n * Combines this bounding box and another together returning a new bounding box\n * @param other The bounding box to combine\n */ combine(other) {\n const compositeBB = new BoundingBox(Math.min(this.left, other.left), Math.min(this.top, other.top), Math.max(this.right, other.right), Math.max(this.bottom, other.bottom));\n return compositeBB;\n }\n get dimensions() {\n return new Vector(this.width, this.height);\n }\n /**\n * Returns true if the bounding boxes overlap.\n * @param other\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\n * This epsilon is useful in stable collision simulations.\n */ overlaps(other, epsilon) {\n const e = epsilon || 0;\n if (other.hasZeroDimensions()) return this.contains(other);\n if (this.hasZeroDimensions()) return other.contains(this);\n const totalBoundingBox = this.combine(other);\n return totalBoundingBox.width + e < other.width + this.width && totalBoundingBox.height + e < other.height + this.height;\n }\n /**\n * Test wether this bounding box intersects with another returning\n * the intersection vector that can be used to resolve the collision. If there\n * is no intersection null is returned.\n * @param other Other [[BoundingBox]] to test intersection with\n * @returns A Vector in the direction of the current BoundingBox, this <- other\n */ intersect(other) {\n const totalBoundingBox = this.combine(other);\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\n if (totalBoundingBox.width < other.width + this.width && totalBoundingBox.height < other.height + this.height && !totalBoundingBox.dimensions.equals(other.dimensions) && !totalBoundingBox.dimensions.equals(this.dimensions)) {\n // collision\n let overlapX = 0;\n // right edge is between the other's left and right edge\n /**\n * +-this-+\n * | |\n * | +-other-+\n * +----|-+ |\n * | |\n * +-------+\n * <---\n * ^ overlap\n */ if (this.right >= other.left && this.right <= other.right) overlapX = other.left - this.right;\n else overlapX = other.right - this.left;\n let overlapY = 0;\n // top edge is between the other's top and bottom edge\n /**\n * +-other-+\n * | |\n * | +-this-+ | <- overlap\n * +----|--+ | |\n * | | \\ /\n * +------+ '\n */ if (this.top <= other.bottom && this.top >= other.top) overlapY = other.bottom - this.top;\n else overlapY = other.top - this.bottom;\n if (Math.abs(overlapX) < Math.abs(overlapY)) return new Vector(overlapX, 0);\n else return new Vector(0, overlapY);\n // Case of total containment of one bounding box by another\n } else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\n let overlapX = 0;\n // this is wider than the other\n if (this.width - other.width >= 0) {\n // This right edge is closest to the others right edge\n if (this.right - other.right <= other.left - this.left) overlapX = other.left - this.right;\n else overlapX = other.right - this.left;\n } else // This right edge is closest to the others right edge\n if (other.right - this.right <= this.left - other.left) overlapX = this.left - other.right;\n else overlapX = this.right - other.left;\n let overlapY = 0;\n // this is taller than other\n if (this.height - other.height >= 0) {\n // The bottom edge is closest to the others bottom edge\n if (this.bottom - other.bottom <= other.top - this.top) overlapY = other.top - this.bottom;\n else overlapY = other.bottom - this.top;\n } else // The bottom edge is closest to the others bottom edge\n if (other.bottom - this.bottom <= this.top - other.top) overlapY = this.top - other.bottom;\n else overlapY = this.bottom - other.top;\n if (Math.abs(overlapX) < Math.abs(overlapY)) return new Vector(overlapX, 0);\n else return new Vector(0, overlapY);\n } else return null;\n }\n /**\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\n * @param bb The other actor to test\n */ intersectWithSide(bb) {\n const intersect = this.intersect(bb);\n return BoundingBox.getSideFromIntersection(intersect);\n }\n /**\n * Draw a debug bounding box\n * @param ex\n * @param color\n */ draw(ex, color = Color.Yellow) {\n ex.debug.drawRect(this.left, this.top, this.width, this.height, {\n color: color\n });\n }\n }\n /**\n * Find the screen position of an HTML element\n */ function getPosition(el) {\n // do we need the scroll too? technically the offset method before did that\n const rect = el.getBoundingClientRect();\n return vec(rect.x + window.scrollX, rect.y + window.scrollY);\n }\n /**\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\n * @deprecated Will be removed in v0.26.0\n */ function addItemToArray(item, array) {\n if (array.indexOf(item) === -1) {\n array.push(item);\n return true;\n }\n return false;\n }\n /**\n * Remove an item from an list\n * @deprecated Will be removed in v0.26.0\n */ function removeItemFromArray(item, array) {\n let index = -1;\n if ((index = array.indexOf(item)) > -1) {\n array.splice(index, 1);\n return true;\n }\n return false;\n }\n /**\n * See if an array contains something\n */ function contains(array, obj) {\n for(let i = 0; i < array.length; i++){\n if (array[i] === obj) return true;\n }\n return false;\n }\n /**\n * Used for exhaustive checks at compile time\n */ function fail(message) {\n throw new Error(message);\n }\n /**\n * Create a promise that resolves after a certain number of milliseconds\n *\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\n * excalibur clock which would be unaffected by stop/pause.\n * @param milliseconds\n * @param clock\n */ function delay(milliseconds, clock) {\n var _a;\n const future = new Future();\n const schedule = (_a = clock === null || clock === void 0 ? void 0 : clock.schedule.bind(clock)) !== null && _a !== void 0 ? _a : setTimeout;\n schedule(()=>{\n future.resolve();\n }, milliseconds);\n return future.promise;\n }\n /**\n * Remove keys from object literals\n * @param object\n * @param keys\n */ function omit(object, keys) {\n const newObj = {};\n for(const key in object)if (!keys.includes(key)) newObj[key] = object[key];\n return newObj;\n }\n var MatrixLocations;\n (function(MatrixLocations) {\n MatrixLocations[MatrixLocations[\"X\"] = 12] = \"X\";\n MatrixLocations[MatrixLocations[\"Y\"] = 13] = \"Y\";\n })(MatrixLocations || (MatrixLocations = {}));\n /**\n * Excalibur Matrix helper for 4x4 matrices\n *\n * Useful for webgl 4x4 matrices\n */ class Matrix {\n constructor(){\n /**\n * 4x4 matrix in column major order\n *\n * | | | | |\n * | ------- | ------- | -------- | -------- |\n * | data[0] | data[4] | data[8] | data[12] |\n * | data[1] | data[5] | data[9] | data[13] |\n * | data[2] | data[6] | data[10] | data[14] |\n * | data[3] | data[7] | data[11] | data[15] |\n *\n */ this.data = new Float32Array(16);\n this._scaleX = 1;\n this._scaleSignX = 1;\n this._scaleY = 1;\n this._scaleSignY = 1;\n }\n /**\n * Creates an orthographic (flat non-perspective) projection\n * https://en.wikipedia.org/wiki/Orthographic_projection\n * @param left\n * @param right\n * @param bottom\n * @param top\n * @param near\n * @param far\n */ static ortho(left, right, bottom, top, near, far) {\n const mat = new Matrix();\n mat.data[0] = 2 / (right - left);\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 2 / (top - bottom);\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = -2 / (far - near);\n mat.data[11] = 0;\n mat.data[12] = -(right + left) / (right - left);\n mat.data[13] = -(top + bottom) / (top - bottom);\n mat.data[14] = -(far + near) / (far - near);\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a new Matrix with the same data as the current 4x4\n */ clone(dest) {\n const mat = dest || new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n mat.data[6] = this.data[6];\n mat.data[7] = this.data[7];\n mat.data[8] = this.data[8];\n mat.data[9] = this.data[9];\n mat.data[10] = this.data[10];\n mat.data[11] = this.data[11];\n mat.data[12] = this.data[12];\n mat.data[13] = this.data[13];\n mat.data[14] = this.data[14];\n mat.data[15] = this.data[15];\n return mat;\n }\n /**\n * Converts the current matrix into a DOMMatrix\n *\n * This is useful when working with the browser Canvas context\n * @returns {DOMMatrix} DOMMatrix\n */ toDOMMatrix() {\n return new DOMMatrix([\n ...this.data\n ]);\n }\n static fromFloat32Array(data) {\n const matrix = new Matrix();\n matrix.data = data;\n return matrix;\n }\n /**\n * Creates a new identity matrix (a matrix that when applied does nothing)\n */ static identity() {\n const mat = new Matrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Resets the current matrix to the identity matrix, mutating it\n * @returns {Matrix} Current matrix as identity\n */ reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a brand new translation matrix at the specified 3d point\n * @param x\n * @param y\n */ static translation(x, y) {\n const mat = Matrix.identity();\n mat.data[12] = x;\n mat.data[13] = y;\n return mat;\n }\n /**\n * Creates a brand new scaling matrix with the specified scaling factor\n * @param sx\n * @param sy\n */ static scale(sx, sy) {\n const mat = Matrix.identity();\n mat.data[0] = sx;\n mat.data[5] = sy;\n mat.data[10] = 1;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a brand new rotation matrix with the specified angle\n * @param angleRadians\n */ static rotation(angleRadians) {\n const mat = Matrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[4] = -Math.sin(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[5] = Math.cos(angleRadians);\n return mat;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\n result.x = resultX;\n result.y = resultY;\n return result;\n } else {\n const result = dest || new Matrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n const b11 = other.data[0];\n const b21 = other.data[1];\n const b31 = other.data[2];\n const b41 = other.data[3];\n const b12 = other.data[4];\n const b22 = other.data[5];\n const b32 = other.data[6];\n const b42 = other.data[7];\n const b13 = other.data[8];\n const b23 = other.data[9];\n const b33 = other.data[10];\n const b43 = other.data[11];\n const b14 = other.data[12];\n const b24 = other.data[13];\n const b34 = other.data[14];\n const b44 = other.data[15];\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n /**\n * Applies translation to the current matrix mutating it\n * @param x\n * @param y\n */ translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n // Doesn't change z\n const z = 0;\n const w = 1;\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\n return this;\n }\n setPosition(x, y) {\n this.data[12] = x;\n this.data[13] = y;\n }\n getPosition() {\n return vec(this.data[12], this.data[13]);\n }\n /**\n * Applies rotation to the current matrix mutating it\n * @param angle in Radians\n */ rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a31 + sine * a32;\n this.data[3] = cosine * a41 + sine * a42;\n this.data[4] = cosine * a12 - sine * a11;\n this.data[5] = cosine * a22 - sine * a21;\n this.data[6] = cosine * a32 - sine * a31;\n this.data[7] = cosine * a42 - sine * a41;\n return this;\n }\n /**\n * Applies scaling to the current matrix mutating it\n * @param x\n * @param y\n */ scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a31 * x;\n this.data[3] = a41 * x;\n this.data[4] = a12 * y;\n this.data[5] = a22 * y;\n this.data[6] = a32 * y;\n this.data[7] = a42 * y;\n return this;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[4] = -sine * currentScale.x;\n this.data[5] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[4]).size;\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[5]).size;\n return this._scaleSignY * yscale;\n }\n /**\n * Get the scale of the matrix\n */ getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (this._scaleX === val) return;\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[4] = xscale.y * val;\n this._scaleX = val;\n }\n setScaleY(val) {\n if (this._scaleY === val) return;\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[5] = yscale.y * val;\n this._scaleY = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n /**\n * Determinant of the upper left 2x2 matrix\n */ getBasisDeterminant() {\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\n }\n /**\n * Return the affine inverse, optionally store it in a target matrix.\n *\n * It's recommended you call .reset() the target unless you know what you're doing\n * @param target\n */ getAffineInverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.getBasisDeterminant();\n const inverseDet = 1 / det; // todo zero check\n const a = this.data[0];\n const b = this.data[4];\n const c = this.data[1];\n const d = this.data[5];\n const m = target || Matrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[4] = -b * inverseDet;\n m.data[5] = a * inverseDet;\n const tx = this.data[12];\n const ty = this.data[13];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\n return m;\n }\n isIdentity() {\n return this.data[0] === 1 && this.data[1] === 0 && this.data[2] === 0 && this.data[3] === 0 && this.data[4] === 0 && this.data[5] === 1 && this.data[6] === 0 && this.data[7] === 0 && this.data[8] === 0 && this.data[9] === 0 && this.data[10] === 1 && this.data[11] === 0 && this.data[12] === 0 && this.data[13] === 0 && this.data[14] === 0 && this.data[15] === 1;\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\n }\n }\n class AffineMatrix {\n constructor(){\n /**\n * | | | |\n * | ------- | ------- | -------- |\n * | data[0] | data[2] | data[4] |\n * | data[1] | data[3] | data[5] |\n * | 0 | 0 | 1 |\n */ this.data = new Float64Array(6);\n this._scale = new Float64Array([\n 1,\n 1\n ]);\n this._scaleSignX = 1;\n this._scaleSignY = 1;\n }\n /**\n * Converts the current matrix into a DOMMatrix\n *\n * This is useful when working with the browser Canvas context\n * @returns {DOMMatrix} DOMMatrix\n */ toDOMMatrix() {\n return new DOMMatrix([\n ...this.data\n ]);\n }\n static identity() {\n const mat = new AffineMatrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\n * Creates a brand new translation matrix at the specified 3d point\n * @param x\n * @param y\n */ static translation(x, y) {\n const mat = AffineMatrix.identity();\n mat.data[4] = x;\n mat.data[5] = y;\n return mat;\n }\n /**\n * Creates a brand new scaling matrix with the specified scaling factor\n * @param sx\n * @param sy\n */ static scale(sx, sy) {\n const mat = AffineMatrix.identity();\n mat.data[0] = sx;\n mat.data[3] = sy;\n mat._scale[0] = sx;\n mat._scale[1] = sy;\n return mat;\n }\n /**\n * Creates a brand new rotation matrix with the specified angle\n * @param angleRadians\n */ static rotation(angleRadians) {\n const mat = AffineMatrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[2] = -Math.sin(angleRadians);\n mat.data[3] = Math.cos(angleRadians);\n return mat;\n }\n setPosition(x, y) {\n this.data[4] = x;\n this.data[5] = y;\n }\n getPosition() {\n return vec(this.data[4], this.data[5]);\n }\n /**\n * Applies rotation to the current matrix mutating it\n * @param angle in Radians\n */ rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a12 - sine * a11;\n this.data[3] = cosine * a22 - sine * a21;\n return this;\n }\n /**\n * Applies translation to the current matrix mutating it\n * @param x\n * @param y\n */ translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n // Doesn't change z\n this.data[4] = a11 * x + a12 * y + a13;\n this.data[5] = a21 * x + a22 * y + a23;\n return this;\n }\n /**\n * Applies scaling to the current matrix mutating it\n * @param x\n * @param y\n */ scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a12 * y;\n this.data[3] = a22 * y;\n this._scale[0] = x;\n this._scale[1] = y;\n return this;\n }\n determinant() {\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\n }\n /**\n * Return the affine inverse, optionally store it in a target matrix.\n *\n * It's recommended you call .reset() the target unless you know what you're doing\n * @param target\n */ inverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.determinant();\n const inverseDet = 1 / det; // TODO zero check\n const a = this.data[0];\n const b = this.data[2];\n const c = this.data[1];\n const d = this.data[3];\n const m = target || AffineMatrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[2] = -b * inverseDet;\n m.data[3] = a * inverseDet;\n const tx = this.data[4];\n const ty = this.data[5];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\n return m;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\n result.x = resultX;\n result.y = resultY;\n return result;\n } else {\n const result = dest || new AffineMatrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n const b11 = other.data[0];\n const b21 = other.data[1];\n // const b31 = 0;\n const b12 = other.data[2];\n const b22 = other.data[3];\n // const b32 = 0;\n const b13 = other.data[4];\n const b23 = other.data[5];\n // const b33 = 1;\n result.data[0] = a11 * b11 + a12 * b21; // + a13 * b31; // zero\n result.data[1] = a21 * b11 + a22 * b21; // + a23 * b31; // zero\n result.data[2] = a11 * b12 + a12 * b22; // + a13 * b32; // zero\n result.data[3] = a21 * b12 + a22 * b22; // + a23 * b32; // zero\n result.data[4] = a11 * b13 + a12 * b23 + a13; // * b33; // one\n result.data[5] = a21 * b13 + a22 * b23 + a23; // * b33; // one\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n to4x4() {\n const mat = new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = this.data[2];\n mat.data[5] = this.data[3];\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = this.data[4];\n mat.data[13] = this.data[5];\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[2] = -sine * currentScale.x;\n this.data[3] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[2]).distance();\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[3]).distance();\n return this._scaleSignY * yscale;\n }\n /**\n * Get the scale of the matrix\n */ getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (val === this._scale[0]) return;\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[2] = xscale.y * val;\n this._scale[0] = val;\n }\n setScaleY(val) {\n if (val === this._scale[1]) return;\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[3] = yscale.y * val;\n this._scale[1] = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n isIdentity() {\n return this.data[0] === 1 && this.data[1] === 0 && this.data[2] === 0 && this.data[3] === 1 && this.data[4] === 0 && this.data[5] === 0;\n }\n /**\n * Resets the current matrix to the identity matrix, mutating it\n * @returns {AffineMatrix} Current matrix as identity\n */ reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\n * Creates a new Matrix with the same data as the current 4x4\n */ clone(dest) {\n const mat = dest || new AffineMatrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n return mat;\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\n }\n }\n class TransformStack {\n constructor(){\n this._transforms = [];\n this._currentTransform = AffineMatrix.identity();\n }\n save() {\n this._transforms.push(this._currentTransform);\n this._currentTransform = this._currentTransform.clone();\n }\n restore() {\n this._currentTransform = this._transforms.pop();\n }\n translate(x, y) {\n return this._currentTransform.translate(x, y);\n }\n rotate(angle) {\n return this._currentTransform.rotate(angle);\n }\n scale(x, y) {\n return this._currentTransform.scale(x, y);\n }\n set current(matrix) {\n this._currentTransform = matrix;\n }\n get current() {\n return this._currentTransform;\n }\n }\n class StateStack {\n constructor(){\n this._states = [];\n this._currentState = this._getDefaultState();\n }\n _getDefaultState() {\n return {\n opacity: 1,\n z: 0,\n tint: Color.White,\n material: null\n };\n }\n _cloneState() {\n return {\n opacity: this._currentState.opacity,\n z: this._currentState.z,\n tint: this._currentState.tint.clone(),\n material: this._currentState.material // TODO is this going to cause problems when cloning\n };\n }\n save() {\n this._states.push(this._currentState);\n this._currentState = this._cloneState();\n }\n restore() {\n this._currentState = this._states.pop();\n }\n get current() {\n return this._currentState;\n }\n set current(val) {\n this._currentState = val;\n }\n }\n const ResourceEvents = {\n Complete: \"complete\",\n Load: \"load\",\n LoadStart: \"loadstart\",\n Progress: \"progress\",\n Error: \"error\"\n };\n /**\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\n */ class Resource {\n /**\n * @param path Path to the remote resource\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\n * @param bustCache Whether or not to cache-bust requests\n */ constructor(path, responseType, bustCache = false){\n this.path = path;\n this.responseType = responseType;\n this.bustCache = bustCache;\n this.data = null;\n this.logger = Logger.getInstance();\n this.events = new EventEmitter();\n }\n /**\n * Returns true if the Resource is completely loaded and is ready\n * to be drawn.\n */ isLoaded() {\n return this.data !== null;\n }\n _cacheBust(uri) {\n const query = /\\?\\w*=\\w*/;\n if (query.test(uri)) uri += \"&__=\" + Date.now();\n else uri += \"?__=\" + Date.now();\n return uri;\n }\n /**\n * Begin loading the resource and returns a promise to be resolved on completion\n */ load() {\n return new Promise((resolve, reject)=>{\n // Exit early if we already have data\n if (this.data !== null) {\n this.logger.debug(\"Already have data for resource\", this.path);\n this.events.emit(\"complete\", this.data);\n resolve(this.data);\n return;\n }\n const request = new XMLHttpRequest();\n request.open(\"GET\", this.bustCache ? this._cacheBust(this.path) : this.path, true);\n request.responseType = this.responseType;\n request.addEventListener(\"loadstart\", (e)=>this.events.emit(\"loadstart\", e));\n request.addEventListener(\"progress\", (e)=>this.events.emit(\"progress\", e));\n request.addEventListener(\"error\", (e)=>this.events.emit(\"error\", e));\n request.addEventListener(\"load\", (e)=>this.events.emit(\"load\", e));\n request.addEventListener(\"load\", ()=>{\n // XHR on file:// success status is 0, such as with PhantomJS\n if (request.status !== 0 && request.status !== 200) {\n this.logger.error(\"Failed to load resource \", this.path, \" server responded with error code\", request.status);\n this.events.emit(\"error\", request.response);\n reject(new Error(request.statusText));\n return;\n }\n this.data = request.response;\n this.events.emit(\"complete\", this.data);\n this.logger.debug(\"Completed loading resource\", this.path);\n resolve(this.data);\n });\n request.send();\n });\n }\n }\n /**\n * Watch an object with a proxy, only fires if property value is different\n */ function watch(type, change) {\n if (!type) return type;\n if (type.__isProxy === undefined) // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value)=>{\n // The default behavior to store the value\n if (obj[prop] !== value) {\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === \"string\") {\n if (prop[0] !== \"_\") change(obj);\n }\n }\n // Indicate success\n return true;\n },\n get: (obj, prop)=>{\n if (prop !== \"__isProxy\") return obj[prop];\n return true;\n }\n });\n return type;\n }\n const createHandler = (path = [], change, typeType)=>({\n get: (target, key)=>{\n if (key === \"__isProxy\") return true;\n if (typeof target[key] === \"object\" && target[key] != null) return new Proxy(target[key], createHandler([\n ...path,\n key\n ], change, typeType));\n return target[key];\n },\n set: (target, key, value)=>{\n if (typeof key === \"string\") {\n if (key[0] !== \"_\") change(typeType);\n }\n target[key] = value;\n return true;\n }\n });\n /**\n *\n */ function watchDeep(type, change) {\n if (!type) return type;\n if (type.__isProxy === undefined) // expando hack to mark a proxy\n return new Proxy(type, createHandler([], change, type));\n return type;\n }\n /**\n * Watch an object with a proxy, fires change on any property value change\n */ function watchAny(type, change) {\n if (!type) return type;\n if (type.__isProxy === undefined) // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value)=>{\n // The default behavior to store the value\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === \"string\") {\n if (prop[0] !== \"_\") change(obj);\n }\n // Indicate success\n return true;\n },\n get: (obj, prop)=>{\n if (prop !== \"__isProxy\") return obj[prop];\n return true;\n }\n });\n return type;\n }\n /**\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\n * [[Graphic]] abstract class.\n *\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\n */ class Graphic {\n isStale() {\n return this._transformStale;\n }\n /**\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\n */ get flipHorizontal() {\n return this._flipHorizontal;\n }\n set flipHorizontal(value) {\n this._flipHorizontal = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\n */ get flipVertical() {\n return this._flipVertical;\n }\n set flipVertical(value) {\n this._flipVertical = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the rotation of the graphic\n */ get rotation() {\n return this._rotation;\n }\n set rotation(value) {\n this._rotation = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the scale of the graphic, this affects the width and\n */ get scale() {\n return this._scale;\n }\n set scale(value) {\n this._scale = watch(value, ()=>{\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n /**\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\n */ get origin() {\n return this._origin;\n }\n set origin(value) {\n this._origin = watch(value, ()=>{\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n constructor(options){\n var _a, _b, _c, _d, _e, _f, _g;\n this.id = Graphic._ID++;\n this.transform = AffineMatrix.identity();\n this.tint = null;\n this._transformStale = true;\n /**\n * Gets or sets wether to show debug information about the graphic\n */ this.showDebug = false;\n this._flipHorizontal = false;\n this._flipVertical = false;\n this._rotation = 0;\n /**\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\n */ this.opacity = 1;\n this._scale = Vector.One;\n this._origin = null;\n this._width = 0;\n this._height = 0;\n if (options) {\n this.origin = (_a = options.origin) !== null && _a !== void 0 ? _a : this.origin;\n this.flipHorizontal = (_b = options.flipHorizontal) !== null && _b !== void 0 ? _b : this.flipHorizontal;\n this.flipVertical = (_c = options.flipVertical) !== null && _c !== void 0 ? _c : this.flipVertical;\n this.rotation = (_d = options.rotation) !== null && _d !== void 0 ? _d : this.rotation;\n this.opacity = (_e = options.opacity) !== null && _e !== void 0 ? _e : this.opacity;\n this.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : this.scale;\n this.tint = (_g = options.tint) !== null && _g !== void 0 ? _g : this.tint;\n }\n }\n cloneGraphicOptions() {\n return {\n width: this.width / this.scale.x,\n height: this.height / this.scale.y,\n origin: this.origin ? this.origin.clone() : null,\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n rotation: this.rotation,\n opacity: this.opacity,\n scale: this.scale ? this.scale.clone() : null,\n tint: this.tint ? this.tint.clone() : null\n };\n }\n /**\n * Gets or sets the width of the graphic (always positive)\n */ get width() {\n return Math.abs(this._width * this.scale.x);\n }\n /**\n * Gets or sets the height of the graphic (always positive)\n */ get height() {\n return Math.abs(this._height * this.scale.y);\n }\n set width(value) {\n this._width = value;\n this._transformStale = true;\n }\n set height(value) {\n this._height = value;\n this._transformStale = true;\n }\n /**\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\n */ get localBounds() {\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\n }\n /**\n * Draw the whole graphic to the context including transform\n * @param ex The excalibur graphics context\n * @param x\n * @param y\n */ draw(ex, x, y) {\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0);\n this._postDraw(ex);\n }\n /**\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\n * @param ex\n * @param x\n * @param y\n */ _preDraw(ex, x, y) {\n ex.save();\n ex.translate(x, y);\n if (this._transformStale) {\n this.transform.reset();\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\n this._rotate(this.transform);\n this._flip(this.transform);\n this._transformStale = false;\n }\n ex.multiply(this.transform);\n // it is important to multiply alphas so graphics respect the current context\n ex.opacity = ex.opacity * this.opacity;\n if (this.tint) ex.tint = this.tint;\n }\n _rotate(ex) {\n var _a;\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : vec(this.width / 2, this.height / 2);\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\n ex.scale(scaleDirX, scaleDirY);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, this.height / this.scale.y);\n ex.scale(1, -1);\n }\n }\n /**\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\n * @param ex\n */ _postDraw(ex) {\n if (this.showDebug) ex.debug.drawRect(0, 0, this.width, this.height);\n ex.restore();\n }\n }\n Graphic._ID = 0;\n class Sprite extends Graphic {\n static from(image) {\n return new Sprite({\n image: image\n });\n }\n constructor(options){\n var _a, _b;\n super(options);\n this._logger = Logger.getInstance();\n this._dirty = true;\n this.image = options.image;\n const { width: width, height: height } = options;\n this.sourceView = (_a = options.sourceView) !== null && _a !== void 0 ? _a : {\n x: 0,\n y: 0,\n width: width !== null && width !== void 0 ? width : 0,\n height: height !== null && height !== void 0 ? height : 0\n };\n this.destSize = (_b = options.destSize) !== null && _b !== void 0 ? _b : {\n width: width !== null && width !== void 0 ? width : 0,\n height: height !== null && height !== void 0 ? height : 0\n };\n this._updateSpriteDimensions();\n // Fire when loaded\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.image.ready.then(()=>{\n this._updateSpriteDimensions();\n });\n }\n get width() {\n return Math.abs(this.destSize.width * this.scale.x);\n }\n get height() {\n return Math.abs(this.destSize.height * this.scale.y);\n }\n set width(newWidth) {\n newWidth /= Math.abs(this.scale.x);\n this.destSize.width = newWidth;\n super.width = Math.ceil(this.destSize.width);\n }\n set height(newHeight) {\n newHeight /= Math.abs(this.scale.y);\n this.destSize.height = newHeight;\n super.height = Math.ceil(this.destSize.height);\n }\n _updateSpriteDimensions() {\n var _a, _b, _c, _d, _e, _f;\n const { width: nativeWidth, height: nativeHeight } = this.image;\n // This code uses || to avoid 0's\n // If the source is not specified, use the native dimension\n this.sourceView.width = ((_a = this.sourceView) === null || _a === void 0 ? void 0 : _a.width) || nativeWidth;\n this.sourceView.height = ((_b = this.sourceView) === null || _b === void 0 ? void 0 : _b.height) || nativeHeight;\n // If the destination is not specified, use the source if specified, then native\n this.destSize.width = ((_c = this.destSize) === null || _c === void 0 ? void 0 : _c.width) || ((_d = this.sourceView) === null || _d === void 0 ? void 0 : _d.width) || nativeWidth;\n this.destSize.height = ((_e = this.destSize) === null || _e === void 0 ? void 0 : _e.height) || ((_f = this.sourceView) === null || _f === void 0 ? void 0 : _f.height) || nativeHeight;\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\n }\n _preDraw(ex, x, y) {\n if (this.image.isLoaded() && this._dirty) {\n this._dirty = false;\n this._updateSpriteDimensions();\n }\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n if (this.image.isLoaded()) ex.drawImage(this.image.image, this.sourceView.x, this.sourceView.y, this.sourceView.width, this.sourceView.height, x, y, this.destSize.width, this.destSize.height);\n else this._logger.warnOnce(`ImageSource ${this.image.path}` + ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` + `Read https://excaliburjs.com/docs/imagesource for more information.`);\n }\n clone() {\n return new Sprite({\n image: this.image,\n sourceView: {\n ...this.sourceView\n },\n destSize: {\n ...this.destSize\n },\n ...this.cloneGraphicOptions()\n });\n }\n }\n /**\n * Describes the different image filtering modes\n */ var ImageFiltering;\n (function(ImageFiltering) {\n /**\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\n *\n * Useful for Pixel art aesthetics.\n */ ImageFiltering[\"Pixel\"] = \"Pixel\";\n /**\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\n */ ImageFiltering[\"Blended\"] = \"Blended\";\n })(ImageFiltering || (ImageFiltering = {}));\n /**\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\n */ class TextureLoader {\n constructor(gl){\n this._textureMap = new Map();\n this._gl = gl;\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n dispose() {\n for (const [image] of this._textureMap)this.delete(image);\n this._textureMap.clear();\n this._gl = null;\n }\n /**\n * Get the WebGL Texture from a source image\n * @param image\n */ get(image) {\n return this._textureMap.get(image);\n }\n /**\n * Returns whether a source image has been loaded as a texture\n * @param image\n */ has(image) {\n return this._textureMap.has(image);\n }\n /**\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\n * @param image Source graphic\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\n */ load(image, filtering, forceUpdate = false) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) return null;\n let tex = null;\n // If reuse the texture if it's from the same source\n if (this.has(image)) tex = this.get(image);\n // Update existing webgl texture and return early\n if (tex) {\n if (forceUpdate) {\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n }\n return tex;\n }\n // No texture exists create a new one\n tex = gl.createTexture();\n // TODO implement texture gc with weakmap and timer\n TextureLoader.checkImageSizeSupportedAndLog(image);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n // TODO make configurable\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // NEAREST for pixel art, LINEAR for hi-res\n const filterMode = filtering !== null && filtering !== void 0 ? filtering : TextureLoader.filtering;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n this._textureMap.set(image, tex);\n return tex;\n }\n delete(image) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) return null;\n let tex = null;\n if (this.has(image)) {\n tex = this.get(image);\n gl.deleteTexture(tex);\n }\n }\n /**\n * Takes an image and returns if it meets size criteria for hardware\n * @param image\n * @returns if the image will be supported at runtime\n */ static checkImageSizeSupportedAndLog(image) {\n var _a;\n const originalSrc = (_a = image.dataset.originalSrc) !== null && _a !== void 0 ? _a : \"internal canvas bitmap\";\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\n TextureLoader._LOGGER.error(`The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of ` + `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image ` + `for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n` + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n return false;\n } else if (image.width > 4096 || image.height > 4096) // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\n TextureLoader._LOGGER.warn(`The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, ` + `it is recommended you resize images to a maximum (4096x4096).\\n\\n` + `Images will likely render as black rectangles on some mobile platforms.\\n\\n` + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n return true;\n }\n }\n TextureLoader._LOGGER = Logger.getInstance();\n /**\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\n */ TextureLoader.filtering = ImageFiltering.Blended;\n TextureLoader._MAX_TEXTURE_SIZE = 4096;\n class ImageSource {\n /**\n * The original size of the source image in pixels\n */ get width() {\n return this.image.naturalWidth;\n }\n /**\n * The original height of the source image in pixels\n */ get height() {\n return this.image.naturalHeight;\n }\n /**\n * Returns true if the Texture is completely loaded and is ready\n * to be drawn.\n */ isLoaded() {\n if (!this._src) // this boosts speed of access\n this._src = this.data.src;\n return !!this._src;\n }\n get image() {\n return this.data;\n }\n /**\n * The path to the image, can also be a data url like 'data:image/'\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\n */ constructor(path, bustCache = false, filtering){\n this.path = path;\n this._logger = Logger.getInstance();\n /**\n * Access to the underlying html image element\n */ this.data = new Image();\n this._readyFuture = new Future();\n /**\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\n */ this.ready = this._readyFuture.promise;\n this._resource = new Resource(path, \"blob\", bustCache);\n this.filtering = filtering;\n if (path.endsWith(\".svg\") || path.endsWith(\".gif\")) this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\n }\n /**\n * Create an ImageSource from and HTML tag element\n * @param image\n */ static fromHtmlImageElement(image, options) {\n const imageSource = new ImageSource(\"\");\n imageSource._src = \"image-element\";\n imageSource.data = image;\n imageSource.data.setAttribute(\"data-original-src\", \"image-element\");\n if (options === null || options === void 0 ? void 0 : options.filtering) imageSource.data.setAttribute(\"filtering\", options === null || options === void 0 ? void 0 : options.filtering);\n else imageSource.data.setAttribute(\"filtering\", ImageFiltering.Blended);\n TextureLoader.checkImageSizeSupportedAndLog(image);\n imageSource._readyFuture.resolve(image);\n return imageSource;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * Begins loading the image and returns a promise that resolves when the image is loaded\n */ async load() {\n if (this.isLoaded()) return this.data;\n try {\n // Load base64 or blob if needed\n let url;\n if (!this.path.includes(\"data:image/\")) {\n const blob = await this._resource.load();\n url = URL.createObjectURL(blob);\n } else url = this.path;\n // Decode the image\n const image = new Image();\n // Use Image.onload over Image.decode()\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\n // Otherwise chrome will throw still Image.decode() failures for large textures\n const loadedFuture = new Future();\n image.onload = ()=>loadedFuture.resolve();\n image.src = url;\n image.setAttribute(\"data-original-src\", this.path);\n await loadedFuture.promise;\n // Set results\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\n // See image-renderer.ts draw()\n this.data = image;\n // emit warning if potentially too big\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\n } catch (error) {\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\n }\n // Do a bad thing to pass the filtering as an attribute\n this.data.setAttribute(\"filtering\", this.filtering);\n // todo emit complete\n this._readyFuture.resolve(this.data);\n return this.data;\n }\n /**\n * Build a sprite from this ImageSource\n */ toSprite() {\n return Sprite.from(this);\n }\n /**\n * Unload images from memory\n */ unload() {\n this.data = new Image();\n }\n }\n class SpriteFont extends Graphic {\n constructor(options){\n super(options);\n this._text = \"\";\n this.alphabet = \"\";\n this.shadow = null;\n this.caseInsensitive = false;\n this.spacing = 0;\n this.lineHeight = undefined;\n this._logger = Logger.getInstance();\n const { alphabet: alphabet, spriteSheet: spriteSheet, caseInsensitive: caseInsensitive, spacing: spacing, shadow: shadow, lineHeight: lineHeight } = options;\n this.alphabet = alphabet;\n this.spriteSheet = spriteSheet;\n this.caseInsensitive = caseInsensitive !== null && caseInsensitive !== void 0 ? caseInsensitive : this.caseInsensitive;\n this.spacing = spacing !== null && spacing !== void 0 ? spacing : this.spacing;\n this.shadow = shadow !== null && shadow !== void 0 ? shadow : this.shadow;\n this.lineHeight = lineHeight !== null && lineHeight !== void 0 ? lineHeight : this.lineHeight;\n }\n _getCharacterSprites(text) {\n const results = [];\n // handle case insensitive\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\n // for each letter in text\n for(let letterIndex = 0; letterIndex < textToRender.length; letterIndex++){\n // find the sprite index in alphabet , if there is an error pick the first\n const letter = textToRender[letterIndex];\n let spriteIndex = alphabet.indexOf(letter);\n if (spriteIndex === -1) {\n spriteIndex = 0;\n this._logger.warnOnce(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\n this._logger.warnOnce(\"There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.\");\n }\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\n if (letterSprite) results.push(letterSprite);\n else {\n this._logger.warnOnce(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\n this._logger.warnOnce(\"There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.\");\n }\n }\n return results;\n }\n measureText(text, maxWidth) {\n const lines = this._getLinesFromText(text, maxWidth);\n const maxWidthLine = lines.reduce((a, b)=>{\n return a.length > b.length ? a : b;\n });\n const sprites = this._getCharacterSprites(maxWidthLine);\n let width = 0;\n let height = 0;\n for (const sprite of sprites){\n width += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\n }\n _drawImage(ex, x, y, maxWidth) {\n var _a;\n let xCursor = 0;\n let yCursor = 0;\n let height = 0;\n const lines = this._getLinesFromText(this._text, maxWidth);\n for (const line of lines){\n for (const sprite of this._getCharacterSprites(line)){\n // draw it in the right spot and increase the cursor by sprite width\n sprite.draw(ex, x + xCursor, y + yCursor);\n xCursor += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n xCursor = 0;\n yCursor += (_a = this.lineHeight) !== null && _a !== void 0 ? _a : height;\n }\n }\n render(ex, text, _color, x, y, maxWidth) {\n // SpriteFont doesn't support _color, yet...\n this._text = text;\n const bounds = this.measureText(text, maxWidth);\n this.width = bounds.width;\n this.height = bounds.height;\n if (this.shadow) {\n ex.save();\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n ex.restore();\n }\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n }\n clone() {\n return new SpriteFont({\n alphabet: this.alphabet,\n spriteSheet: this.spriteSheet,\n spacing: this.spacing\n });\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) return this._cachedLines;\n const lines = text.split(\"\\n\");\n if (maxWidth == null) return lines;\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for(let i = 0; i < lines.length; i++){\n let line = lines[i];\n let newLine = \"\";\n // Note: we subtract the spacing to counter the initial padding on the left side.\n if (this.measureText(line).width > maxWidth) {\n while(this.measureText(line).width > maxWidth){\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n }\n /**\n * Represents a collection of sprites from a source image with some organization in a grid\n */ class SpriteSheet {\n /**\n * Build a new sprite sheet from a list of sprites\n *\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\n * @param options\n */ constructor(options){\n this.sprites = [];\n const { sprites: sprites, rows: rows, columns: columns } = options;\n this.sprites = sprites;\n this.rows = rows !== null && rows !== void 0 ? rows : 1;\n this.columns = columns !== null && columns !== void 0 ? columns : this.sprites.length;\n }\n /**\n * Find a sprite by their x/y integer coordinates in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\n * and `getSprite(1, 0)` is the sprite one to the right.\n * @param x\n * @param y\n */ getSprite(x, y, options) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n if (x >= this.columns || x < 0) throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\n if (y >= this.rows || y < 0) throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\n const spriteIndex = x + y * this.columns;\n const sprite = this.sprites[spriteIndex];\n if (sprite) {\n if (options) {\n const spriteWithOptions = sprite.clone();\n spriteWithOptions.flipHorizontal = (_a = options.flipHorizontal) !== null && _a !== void 0 ? _a : spriteWithOptions.flipHorizontal;\n spriteWithOptions.flipVertical = (_b = options.flipVertical) !== null && _b !== void 0 ? _b : spriteWithOptions.flipVertical;\n spriteWithOptions.width = (_c = options.width) !== null && _c !== void 0 ? _c : spriteWithOptions.width;\n spriteWithOptions.height = (_d = options.height) !== null && _d !== void 0 ? _d : spriteWithOptions.height;\n spriteWithOptions.rotation = (_e = options.rotation) !== null && _e !== void 0 ? _e : spriteWithOptions.rotation;\n spriteWithOptions.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : spriteWithOptions.scale;\n spriteWithOptions.opacity = (_g = options.opacity) !== null && _g !== void 0 ? _g : spriteWithOptions.opacity;\n spriteWithOptions.tint = (_h = options.tint) !== null && _h !== void 0 ? _h : spriteWithOptions.tint;\n spriteWithOptions.origin = (_j = options.origin) !== null && _j !== void 0 ? _j : spriteWithOptions.origin;\n return spriteWithOptions;\n }\n return sprite;\n }\n throw Error(`Invalid sprite coordinates (${x}, ${y}`);\n }\n /**\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\n * @param options\n */ static fromImageSourceWithSourceViews(options) {\n const sprites = options.sourceViews.map((sourceView)=>{\n return new Sprite({\n image: options.image,\n sourceView: sourceView\n });\n });\n return new SpriteSheet({\n sprites: sprites\n });\n }\n /**\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\n *\n * Example:\n * ```\n * const spriteSheet = SpriteSheet.fromImageSource({\n * image: imageSource,\n * grid: {\n * rows: 5,\n * columns: 2,\n * spriteWidth: 32, // pixels\n * spriteHeight: 32 // pixels\n * },\n * // Optionally specify spacing\n * spacing: {\n * // pixels from the top left to start the sprite parsing\n * originOffset: {\n * x: 5,\n * y: 5\n * },\n * // pixels between each sprite while parsing\n * margin: {\n * x: 1,\n * y: 1\n * }\n * }\n * })\n * ```\n * @param options\n */ static fromImageSource(options) {\n var _a;\n const sprites = [];\n options.spacing = (_a = options.spacing) !== null && _a !== void 0 ? _a : {};\n const { image: image, grid: { rows: rows, columns: cols, spriteWidth: spriteWidth, spriteHeight: spriteHeight }, spacing: { originOffset: originOffset, margin: margin } } = options;\n const offsetDefaults = {\n x: 0,\n y: 0,\n ...originOffset\n };\n const marginDefaults = {\n x: 0,\n y: 0,\n ...margin\n };\n for(let x = 0; x < cols; x++)for(let y = 0; y < rows; y++)sprites[x + y * cols] = new Sprite({\n image: image,\n sourceView: {\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\n width: spriteWidth,\n height: spriteHeight\n },\n destSize: {\n height: spriteHeight,\n width: spriteWidth\n }\n });\n return new SpriteSheet({\n sprites: sprites,\n rows: rows,\n columns: cols\n });\n }\n clone() {\n return new SpriteSheet({\n sprites: this.sprites.map((sprite)=>sprite.clone()),\n rows: this.rows,\n columns: this.columns\n });\n }\n }\n /* harmony default export */ const debug_font = \"data:image/png;base64,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\";\n /**\n * Internal debugtext helper\n */ class DebugText {\n constructor(){\n /**\n * base64 font\n */ this.fontSheet = debug_font;\n this.size = 16;\n // We fire and forget, we don't care if it's loaded or not\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.load();\n }\n load() {\n this._imageSource = new ImageSource(this.fontSheet);\n return this._imageSource.load().then(()=>{\n this._spriteSheet = SpriteSheet.fromImageSource({\n image: this._imageSource,\n grid: {\n rows: 4,\n columns: 16,\n spriteWidth: 16,\n spriteHeight: 16\n }\n });\n this._spriteFont = new SpriteFont({\n alphabet: \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!'&.\\\"?-()+# \",\n caseInsensitive: true,\n spriteSheet: this._spriteSheet,\n spacing: -6\n });\n });\n }\n /**\n * Writes debug text using the built in sprint font\n * @param ctx\n * @param text\n * @param pos\n */ write(ctx, text, pos) {\n if (this._imageSource.isLoaded()) this._spriteFont.render(ctx, text, null, pos.x, pos.y);\n }\n }\n class RenderSource {\n constructor(_gl, _texture){\n this._gl = _gl;\n this._texture = _texture;\n }\n use() {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\n }\n disable() {\n const gl = this._gl;\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n }\n class RenderTarget {\n constructor(options){\n var _a, _b;\n this.antialias = false;\n this.samples = 1;\n this._gl = options.gl;\n this.width = options.width;\n this.height = options.height;\n this.transparency = options.transparency;\n this.antialias = (_a = options.antialias) !== null && _a !== void 0 ? _a : this.antialias;\n this.samples = (_b = options.samples) !== null && _b !== void 0 ? _b : this._gl.getParameter(this._gl.MAX_SAMPLES);\n const gl = this._gl;\n // Determine current context format for blitting later needs to match\n if (gl.drawingBufferFormat) this.bufferFormat = gl.drawingBufferFormat;\n else // Documented in webgl spec\n // https://registry.khronos.org/webgl/specs/latest/1.0/\n if (this.transparency) this.bufferFormat = gl.RGBA8;\n else this.bufferFormat = gl.RGB8;\n this._setupRenderBuffer();\n this._setupFramebuffer();\n }\n setResolution(width, height) {\n const gl = this._gl;\n this.width = width;\n this.height = height;\n // update backing texture size\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // update render buffer size\n if (this._renderBuffer) {\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\n gl.renderbufferStorageMultisample(gl.RENDERBUFFER, Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, this.height);\n }\n }\n get renderBuffer() {\n return this._renderBuffer;\n }\n get renderFrameBuffer() {\n return this._renderFrameBuffer;\n }\n get frameBuffer() {\n return this._frameBuffer;\n }\n get frameTexture() {\n return this._frameTexture;\n }\n _setupRenderBuffer() {\n if (this.antialias) {\n const gl = this._gl;\n // Render buffers can be used as an input to a shader\n this._renderBuffer = gl.createRenderbuffer();\n this._renderFrameBuffer = gl.createFramebuffer();\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\n gl.renderbufferStorageMultisample(gl.RENDERBUFFER, Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, this.height);\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\n gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._renderBuffer);\n }\n }\n _setupFramebuffer() {\n // Allocates frame buffer\n const gl = this._gl;\n this._frameTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // set the filtering so we don't need mips\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // attach the texture as the first color attachment\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\n // After this bind all draw calls will draw to this framebuffer texture\n this._frameBuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\n // Reset after initialized\n this.disable();\n }\n toRenderSource() {\n if (this.renderBuffer) this.blitRenderBufferToFrameBuffer();\n const source = new RenderSource(this._gl, this._frameTexture);\n return source;\n }\n blitToScreen() {\n const gl = this._gl;\n // set to size of canvas's drawingBuffer\n if (this._renderBuffer) {\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.clearBufferfv(gl.COLOR, 0, [\n 0.0,\n 0.0,\n 1.0,\n 1.0\n ]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n } else {\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.frameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.clearBufferfv(gl.COLOR, 0, [\n 0.0,\n 0.0,\n 1.0,\n 1.0\n ]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n }\n blitRenderBufferToFrameBuffer() {\n if (this._renderBuffer) {\n const gl = this._gl;\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.frameBuffer);\n gl.clearBufferfv(gl.COLOR, 0, [\n 0.0,\n 0.0,\n 1.0,\n 1.0\n ]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n }\n copyToTexture(texture) {\n const gl = this._gl;\n if (this._renderBuffer) this.blitRenderBufferToFrameBuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, this.width, this.height, 0);\n }\n /**\n * When called, all drawing gets redirected to this render target\n */ use() {\n const gl = this._gl;\n if (this.antialias) gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\n else gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n // very important to set the viewport to the size of the framebuffer texture\n gl.viewport(0, 0, this.width, this.height);\n }\n /**\n * When called, all drawing is sent back to the canvas\n */ disable() {\n const gl = this._gl;\n // passing null switches rendering back to the canvas\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n }\n /* harmony default export */ const line_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\";\n /* harmony default export */ const line_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\";\n /**\n * Return the size of the GlType in bytes\n * @param gl\n * @param type\n */ function getGlTypeSizeBytes(gl, type) {\n switch(type){\n case gl.FLOAT:\n return 4;\n case gl.SHORT:\n return 2;\n case gl.UNSIGNED_SHORT:\n return 2;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n default:\n return 1;\n }\n }\n /**\n * Based on the type return the number of attribute components\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\n * @param gl\n * @param type\n */ function getAttributeComponentSize(gl, type) {\n switch(type){\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n return 1;\n case gl.FLOAT_VEC2:\n return 2;\n case gl.FLOAT_VEC3:\n return 3;\n case gl.FLOAT_VEC4:\n return 4;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n case gl.UNSIGNED_SHORT:\n case gl.SHORT:\n return 1;\n default:\n return 1;\n }\n }\n /**\n * Based on the attribute return the corresponding supported attrib pointer type\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\n * @param gl\n * @param type\n */ function getAttributePointerType(gl, type) {\n switch(type){\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n case gl.FLOAT_VEC2:\n case gl.FLOAT_VEC3:\n case gl.FLOAT_VEC4:\n return gl.FLOAT;\n case gl.BYTE:\n return gl.BYTE;\n case gl.UNSIGNED_BYTE:\n return gl.UNSIGNED_BYTE;\n case gl.SHORT:\n return gl.SHORT;\n case gl.UNSIGNED_SHORT:\n return gl.UNSIGNED_SHORT;\n default:\n return gl.FLOAT;\n }\n }\n class Shader {\n get compiled() {\n return this._compiled;\n }\n /**\n * Create a shader program in excalibur\n * @param options specify shader vertex and fragment source\n */ constructor(options){\n this._logger = Logger.getInstance();\n this.uniforms = {};\n this.attributes = {};\n this._compiled = false;\n const { gl: gl, vertexSource: vertexSource, fragmentSource: fragmentSource } = options;\n this._gl = gl;\n this.vertexSource = vertexSource;\n this.fragmentSource = fragmentSource;\n }\n dispose() {\n const gl = this._gl;\n gl.deleteProgram(this.program);\n this._gl = null;\n }\n /**\n * Binds the shader program\n */ use() {\n const gl = this._gl;\n gl.useProgram(this.program);\n Shader._ACTIVE_SHADER_INSTANCE = this;\n }\n isCurrentlyBound() {\n return Shader._ACTIVE_SHADER_INSTANCE === this;\n }\n /**\n * Compile the current shader against a webgl context\n */ compile() {\n const gl = this._gl;\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\n const attributes = this.getAttributes();\n for (const attribute of attributes)this.attributes[attribute.name] = attribute;\n const uniforms = this.getUniforms();\n for (const uniform of uniforms)this.uniforms[uniform.name] = uniform;\n this._compiled = true;\n return this.program;\n }\n getUniforms() {\n const gl = this._gl;\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\n const uniforms = [];\n for(let i = 0; i < uniformCount; i++){\n const uniform = gl.getActiveUniform(this.program, i);\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\n uniforms.push({\n name: uniform.name,\n glType: uniform.type,\n location: uniformLocation\n });\n }\n return uniforms;\n }\n getAttributes() {\n const gl = this._gl;\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\n const attributes = [];\n for(let i = 0; i < attributeCount; i++){\n const attribute = gl.getActiveAttrib(this.program, i);\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\n attributes.push({\n name: attribute.name,\n glType: getAttributePointerType(gl, attribute.type),\n size: getAttributeComponentSize(gl, attribute.type),\n location: attributeLocation,\n normalized: false\n });\n }\n return attributes;\n }\n /**\n * Set a texture in a gpu texture slot\n * @param slotNumber\n * @param texture\n */ setTexture(slotNumber, texture) {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n }\n /**\n * Set an integer uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformInt(name, value) {\n this.setUniform(\"uniform1i\", name, ~~value);\n }\n /**\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformInt(name, value) {\n return this.trySetUniform(\"uniform1i\", name, ~~value);\n }\n /**\n * Set an integer array uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformIntArray(name, value) {\n this.setUniform(\"uniform1iv\", name, value);\n }\n /**\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformIntArray(name, value) {\n return this.trySetUniform(\"uniform1iv\", name, value);\n }\n /**\n * Set a boolean uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformBoolean(name, value) {\n this.setUniform(\"uniform1i\", name, value ? 1 : 0);\n }\n /**\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformBoolean(name, value) {\n return this.trySetUniform(\"uniform1i\", name, value ? 1 : 0);\n }\n /**\n * Set a float uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformFloat(name, value) {\n this.setUniform(\"uniform1f\", name, value);\n }\n /**\n * Set a float uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformFloat(name, value) {\n return this.trySetUniform(\"uniform1f\", name, value);\n }\n /**\n * Set a float array uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformFloatArray(name, value) {\n this.setUniform(\"uniform1fv\", name, value);\n }\n /**\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformFloatArray(name, value) {\n return this.trySetUniform(\"uniform1fv\", name, value);\n }\n /**\n * Set a [[Vector]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformFloatVector(name, value) {\n this.setUniform(\"uniform2f\", name, value.x, value.y);\n }\n /**\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformFloatVector(name, value) {\n return this.trySetUniform(\"uniform2f\", name, value.x, value.y);\n }\n /**\n * Set a [[Color]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformFloatColor(name, value) {\n this.setUniform(\"uniform4f\", name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformFloatColor(name, value) {\n return this.trySetUniform(\"uniform4f\", name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\n * Set an [[Matrix]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ setUniformMatrix(name, value) {\n this.setUniform(\"uniformMatrix4fv\", name, false, value.data);\n }\n /**\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */ trySetUniformMatrix(name, value) {\n return this.trySetUniform(\"uniformMatrix4fv\", name, false, value.data);\n }\n /**\n * Set any available uniform type in webgl\n *\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\n */ setUniform(uniformType, name, ...value) {\n if (!this._compiled) throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n if (!this.isCurrentlyBound()) throw Error(\"Currently accessed shader instance is not the current active shader in WebGL, must call `shader.use()` before setting uniforms\");\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [\n location,\n ...value\n ];\n this._gl[uniformType].apply(this._gl, args);\n } else throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,` + \" unused uniforms are optimized away by most browsers\");\n }\n /**\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\n * true if it was set.\n *\n * WILL NOT THROW on error\n *\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\n *\n */ trySetUniform(uniformType, name, ...value) {\n if (!this._compiled) {\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n return false;\n }\n if (!this.isCurrentlyBound()) {\n this._logger.warn(\"Currently accessed shader instance is not the current active shader in WebGL, must call `shader.use()` before setting uniforms\");\n return false;\n }\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [\n location,\n ...value\n ];\n this._gl[uniformType].apply(this._gl, args);\n } else return false;\n return true;\n }\n _createProgram(gl, vertexShader, fragmentShader) {\n const program = gl.createProgram();\n if (program === null) throw Error(\"Could not create graphics shader program\");\n // attach the shaders.\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n // link the program.\n gl.linkProgram(program);\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n if (!success) throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\n return program;\n }\n _compileShader(gl, source, type) {\n const typeName = gl.VERTEX_SHADER === type ? \"vertex\" : \"fragment\";\n const shader = gl.createShader(type);\n if (shader === null) throw Error(`Could not build shader: [${source}]`);\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (!success) {\n const errorInfo = gl.getShaderInfoLog(shader);\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\n }\n return shader;\n }\n _processSourceForError(source, errorInfo) {\n if (!source) return errorInfo;\n const lines = source.split(\"\\n\");\n const errorLineStart = errorInfo.search(/\\d:\\d/);\n const errorLineEnd = errorInfo.indexOf(\" \", errorLineStart);\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(\":\").map((v)=>Number(v));\n for(let i = 0; i < lines.length; i++)lines[i] = `${i + 1}: ${lines[i]}${error2 === i + 1 ? \" <----- ERROR!\" : \"\"}`;\n return \"\\n\\nSource:\\n\" + lines.join(\"\\n\");\n }\n }\n Shader._ACTIVE_SHADER_INSTANCE = null;\n /**\n * Helper around vertex buffer to simplify creating and uploading geometry\n *\n * Under the hood uses Float32Array\n */ class VertexBuffer {\n constructor(options){\n /**\n * If the vertices never change switching 'static' can be more efficient on the gpu\n *\n * Default is 'dynamic'\n */ this.type = \"dynamic\";\n const { gl: gl, size: size, type: type, data: data } = options;\n this._gl = gl;\n this.buffer = this._gl.createBuffer();\n if (!data && !size) throw Error(\"Must either provide data or a size to the VertexBuffer\");\n if (!data) this.bufferData = new Float32Array(size);\n else this.bufferData = data;\n this.type = type !== null && type !== void 0 ? type : this.type;\n // Allocate buffer\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === \"static\" ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n /**\n * Bind this vertex buffer\n */ bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n }\n /**\n * Upload vertex buffer geometry to the GPU\n */ upload(count) {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n if (count) gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\n else // TODO always use bufferSubData? need to perf test it\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === \"static\" ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n dispose() {\n const gl = this._gl;\n gl.deleteBuffer(this.buffer);\n this._gl = null;\n }\n }\n /**\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\n * the memory layout for your vertices inside a particular buffer\n *\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\n *\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\n */ class VertexLayout {\n get vertexBuffer() {\n return this._vertexBuffer;\n }\n get attributes() {\n return this._attributes;\n }\n constructor(options){\n this._logger = Logger.getInstance();\n this._layout = [];\n this._attributes = [];\n this._vertexTotalSizeBytes = 0;\n const { gl: gl, shader: shader, vertexBuffer: vertexBuffer, attributes: attributes } = options;\n this._gl = gl;\n this._vertexBuffer = vertexBuffer;\n this._attributes = attributes;\n this._shader = shader;\n if (shader) this.initialize();\n }\n /**\n * Total number of bytes that the vertex will take up\n */ get totalVertexSizeBytes() {\n return this._vertexTotalSizeBytes;\n }\n set shader(shader) {\n if (shader && this._shader !== shader) {\n this._shader = shader;\n this.initialize();\n }\n }\n get shader() {\n return this._shader;\n }\n /**\n * Layouts need shader locations and must be bound to a shader\n */ initialize() {\n if (!this._shader) return;\n if (!this._shader.compiled) throw Error(\"Shader not compiled, shader must be compiled before defining a vertex layout\");\n this._vertexTotalSizeBytes = 0;\n this._layout.length = 0;\n const shaderAttributes = this._shader.attributes;\n for (const attribute of this._attributes){\n const attrib = shaderAttributes[attribute[0]];\n if (!attrib) throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}` + ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\n if (attrib.size !== attribute[1]) throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],` + ` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\n this._layout.push(attrib);\n }\n // calc size\n let componentsPerVertex = 0;\n for (const vertAttribute of this._layout){\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\n componentsPerVertex += vertAttribute.size;\n }\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) this._logger.warn(`The vertex component size (${componentsPerVertex}) does NOT divide evenly into the specified vertex buffer` + ` (${this._vertexBuffer.bufferData.length})`);\n }\n /**\n * Bind this layout with it's associated vertex buffer\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\n */ use(uploadBuffer = false, count) {\n if (!this._shader) throw Error(\"No shader is associated with this vertex layout, a shader must be set\");\n const gl = this._gl;\n if (!this._shader.isCurrentlyBound()) throw Error(\"Shader associated with this vertex layout is not active! Call shader.use() before layout.use()\");\n this._vertexBuffer.bind();\n if (uploadBuffer) this._vertexBuffer.upload(count);\n let offset = 0;\n // TODO switch to VAOs if the extension is\n for (const vert of this._layout){\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\n gl.enableVertexAttribArray(vert.location);\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\n }\n }\n }\n class GraphicsDiagnostics {\n static clear() {\n GraphicsDiagnostics.DrawCallCount = 0;\n GraphicsDiagnostics.DrawnImagesCount = 0;\n }\n }\n GraphicsDiagnostics.DrawCallCount = 0;\n GraphicsDiagnostics.DrawnImagesCount = 0;\n class LineRenderer {\n constructor(){\n this.type = \"ex.line\";\n this.priority = 0;\n this._maxLines = 10922;\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n vertexSource: line_vertex,\n fragmentSource: line_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n this._vertexBuffer = new VertexBuffer({\n gl: gl,\n size: 12 * this._maxLines,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n vertexBuffer: this._vertexBuffer,\n shader: this._shader,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_color\",\n 4\n ]\n ]\n });\n }\n dispose() {\n this._vertexBuffer.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n draw(start, end, color) {\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._lineCount++;\n const transform = this._context.getTransform();\n const finalStart = transform.multiply(start);\n const finalEnd = transform.multiply(end);\n const vertexBuffer = this._vertexBuffer.bufferData;\n // Start\n vertexBuffer[this._vertexIndex++] = finalStart.x;\n vertexBuffer[this._vertexIndex++] = finalStart.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n // End\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n }\n _isFull() {\n if (this._lineCount >= this._maxLines) return true;\n return false;\n }\n hasPendingDraws() {\n return this._lineCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._lineCount === 0) return;\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\n GraphicsDiagnostics.DrawCallCount++;\n // reset\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n }\n /* harmony default export */ const point_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\";\n /* harmony default export */ const point_fragment = '#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \"premultiply\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}';\n class PointRenderer {\n constructor(){\n this.type = \"ex.point\";\n this.priority = 0;\n this._maxPoints = 10922;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n vertexSource: point_vertex,\n fragmentSource: point_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 7 * this._maxPoints,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_size\",\n 1\n ]\n ]\n });\n }\n dispose() {\n this._buffer.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n draw(point, color, size) {\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._pointCount++;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const finalPoint = transform.multiply(point);\n if (snapToPixel) {\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\n }\n const vertexBuffer = this._buffer.bufferData;\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\n }\n _isFull() {\n if (this._pointCount >= this._maxPoints) return true;\n return false;\n }\n hasPendingDraws() {\n return this._pointCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._pointCount === 0) return;\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\n GraphicsDiagnostics.DrawCallCount++;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n }\n /* harmony default export */ const screen_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\";\n /* harmony default export */ const screen_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\";\n /**\n * This is responsible for painting the entire screen during the render passes\n */ class ScreenPassPainter {\n constructor(gl){\n this._gl = gl;\n this._shader = new Shader({\n gl: gl,\n vertexSource: screen_vertex,\n fragmentSource: screen_fragment\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n type: \"static\",\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1,\n -1,\n 0,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n -1,\n 1,\n 0,\n 1,\n -1,\n 1,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n 1,\n 1,\n 1\n ])\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_texcoord\",\n 2\n ]\n ]\n });\n this._buffer.upload();\n }\n renderWithPostProcessor(postprocessor) {\n const gl = this._gl;\n postprocessor.getShader().use();\n postprocessor.getLayout().use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n renderToScreen() {\n const gl = this._gl;\n this._shader.use();\n this._layout.use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n }\n /**\n * Helper that defines and index buffer for quad geometry\n *\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\n * it is almost always worth it in terms of performance to use an index buffer.\n */ class QuadIndexBuffer {\n /**\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\n * @param numberOfQuads Specify the max number of quads you want to draw\n * @param useUint16 Optionally force a uint16 buffer\n */ constructor(gl, numberOfQuads, useUint16){\n this._logger = Logger.getInstance();\n this._gl = gl;\n this.buffer = gl.createBuffer();\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n const totalVertices = numberOfQuads * 6;\n if (!useUint16) this.bufferData = new Uint32Array(totalVertices);\n else {\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\n const maxUint16 = 65535;\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\n this.bufferGlType = gl.UNSIGNED_SHORT;\n this.bufferData = new Uint16Array(totalVertices);\n // TODO Should we error if this happens?? maybe not might crash mid game\n if (numberOfQuads > maxUint16Index) this._logger.warn(`Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\n }\n let currentQuad = 0;\n for(let i = 0; i < totalVertices; i += 6){\n // first triangle\n this.bufferData[i + 0] = currentQuad + 0;\n this.bufferData[i + 1] = currentQuad + 1;\n this.bufferData[i + 2] = currentQuad + 2;\n // second triangle\n this.bufferData[i + 3] = currentQuad + 2;\n this.bufferData[i + 4] = currentQuad + 1;\n this.bufferData[i + 5] = currentQuad + 3;\n currentQuad += 4;\n }\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n get size() {\n return this.bufferData.length;\n }\n /**\n * Upload data to the GPU\n */ upload() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n /**\n * Bind this index buffer\n */ bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n }\n dispose() {\n const gl = this._gl;\n gl.deleteBuffer(this.buffer);\n this._gl = null;\n }\n }\n /* harmony default export */ const image_renderer_frag = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\nuniform bool u_pixelart;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nin vec2 v_res;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\n// Inigo Quilez pixel art filter https://jorenjoestar.github.io/post/pixel_art_filtering/\\r\\nvec2 uv_iq(in vec2 uv, in vec2 texture_size) {\\r\\n vec2 pixel = uv * texture_size;\\r\\n \\r\\n vec2 seam=floor(pixel+.5);\\r\\n vec2 dudv=fwidth(pixel);\\r\\n pixel=seam+clamp((pixel-seam)/dudv,-.5,.5);\\r\\n \\r\\n return pixel/texture_size;\\r\\n}\\r\\n\\r\\nvoid main(){\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n \\r\\n vec4 color=vec4(1.,0,0,1.);\\r\\n \\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n \\r\\n color.rgb=color.rgb*v_opacity;\\r\\n color.a=color.a*v_opacity;\\r\\n fragColor=color*v_tint;\\r\\n}\";\n /* harmony default export */ const image_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity\\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture res\\r\\nin vec2 a_res;\\r\\nout vec2 v_res;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main(){\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position=u_matrix*vec4(a_position,0.,1.);\\r\\n \\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity=a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord=a_texcoord;\\r\\n\\r\\n v_res = a_res;\\r\\n\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex=a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint=a_tint;\\r\\n}\";\n class ImageRenderer {\n constructor(options){\n this.type = \"ex.image\";\n this.priority = 0;\n this._maxImages = 10922; // max(uint16) / 6 verts\n this._maxTextures = 0;\n // Per flush vars\n this._imageCount = 0;\n this._textures = [];\n this._vertexIndex = 0;\n this.pixelArtSampler = options.pixelArtSampler;\n this.uvPadding = options.uvPadding;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Transform shader source\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\n const transformedFrag = this._transformFragmentSource(image_renderer_frag, this._maxTextures);\n // Compile shader\n this._shader = new Shader({\n gl: gl,\n fragmentSource: transformedFrag,\n vertexSource: image_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\n this._shader.setUniformIntArray(\"u_textures\", [\n ...Array(this._maxTextures)\n ].map((_, i)=>i));\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 48 * this._maxImages,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_res\",\n 2\n ],\n [\n \"a_texcoord\",\n 2\n ],\n [\n \"a_textureIndex\",\n 1\n ],\n [\n \"a_tint\",\n 4\n ]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._textures.length = 0;\n this._context = null;\n this._gl = null;\n }\n _transformFragmentSource(source, maxTextures) {\n let newSource = source.replace(\"%%count%%\", maxTextures.toString());\n let texturePickerBuilder = \"\";\n for(let i = 0; i < maxTextures; i++){\n if (i === 0) texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\n else texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\n texturePickerBuilder += ` vec2 uv = u_pixelart ? uv_iq(v_texcoord, v_res) : v_texcoord;\\n`;\n texturePickerBuilder += ` color = texture(u_textures[${i}], uv);\\n`;\n texturePickerBuilder += ` }\\n`;\n }\n newSource = newSource.replace(\"%%texture_picker%%\", texturePickerBuilder);\n return newSource;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute(\"filtering\");\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended || maybeFiltering === ImageFiltering.Pixel) filtering = maybeFiltering;\n const force = image.getAttribute(\"forceUpload\") === \"true\" ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute(\"forceUpload\");\n if (this._textures.indexOf(texture) === -1) this._textures.push(texture);\n }\n _bindTextures(gl) {\n // Bind textures in the correct order\n for(let i = 0; i < this._maxTextures; i++){\n gl.activeTexture(gl.TEXTURE0 + i);\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\n }\n }\n _getTextureIdForImage(image) {\n if (image) {\n const maybeTexture = this._context.textureLoader.get(image);\n return this._textures.indexOf(maybeTexture);\n }\n return -1;\n }\n _isFull() {\n if (this._imageCount >= this._maxImages) return true;\n if (this._textures.length >= this._maxTextures) return true;\n return false;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._imageCount++;\n // This creates and uploads the texture if not already done\n this._addImageAsTexture(image);\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [\n 0,\n 0,\n (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0,\n (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0\n ];\n let dest = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1\n ];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1,\n (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0,\n (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0\n ];\n dest = [\n dx,\n dy\n ];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n let topLeft = vec(dest[0], dest[1]);\n let topRight = vec(dest[0] + width, dest[1]);\n let bottomLeft = vec(dest[0], dest[1] + height);\n let bottomRight = vec(dest[0] + width, dest[1] + height);\n topLeft = transform.multiply(topLeft);\n topRight = transform.multiply(topRight);\n bottomLeft = transform.multiply(bottomLeft);\n bottomRight = transform.multiply(bottomRight);\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + sign(topLeft.x) * pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + sign(topLeft.y) * pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + sign(topRight.x) * pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + sign(topRight.y) * pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + sign(bottomLeft.x) * pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + sign(bottomLeft.y) * pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + sign(bottomRight.x) * pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + sign(bottomRight.y) * pixelSnapEpsilon);\n }\n const tint = this._context.tint;\n const textureId = this._getTextureIdForImage(image);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = (sx + this.uvPadding) / imageWidth;\n const uvy0 = (sy + this.uvPadding) / imageHeight;\n const uvx1 = (sx + sw - this.uvPadding) / imageWidth;\n const uvy1 = (sy + sh - this.uvPadding) / imageHeight;\n const txWidth = image.width;\n const txHeight = image.height;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n }\n hasPendingDraws() {\n return this._imageCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._imageCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true, 48 * this._imageCount); // 4 verts * 12 components\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Turn on pixel art aa sampler\n this._shader.setUniformBoolean(\"u_pixelart\", this.pixelArtSampler);\n // Bind textures to\n this._bindTextures(gl);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._imageCount = 0;\n this._vertexIndex = 0;\n this._textures.length = 0;\n }\n }\n /* harmony default export */ const rectangle_renderer_frag = \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\";\n /* harmony default export */ const rectangle_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";\n class RectangleRenderer {\n constructor(){\n this.type = \"ex.rectangle\";\n this.priority = 0;\n this._maxRectangles = 10922; // max(uint16) / 6 verts\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\n this._shader = new Shader({\n gl: gl,\n fragmentSource: rectangle_renderer_frag,\n vertexSource: rectangle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 64 * this._maxRectangles,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ],\n [\n \"a_size\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_strokeColor\",\n 4\n ],\n [\n \"a_strokeThickness\",\n 1\n ]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n _isFull() {\n if (this._rectangleCount >= this._maxRectangles) return true;\n return false;\n }\n draw(...args) {\n if (args[0] instanceof Vector && args[1] instanceof Vector) this.drawLine.apply(this, args);\n else this.drawRectangle.apply(this, args);\n }\n drawLine(start, end, color, thickness = 1) {\n if (this._isFull()) this.flush();\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const dir = end.sub(start);\n const length = dir.size;\n const normal = dir.normalize().perpendicular();\n const halfThick = thickness / 2;\n /**\n * +---------------------^----------------------+\n * | | (normal) |\n * (startx, starty)------------------>(endx, endy)\n * | |\n * + -------------------------------------------+\n */ const startTop = transform.multiply(normal.scale(halfThick).add(start));\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\n if (snapToPixel) {\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n const stroke = Color.Transparent;\n const strokeThickness = 0;\n const width = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = startTop.x;\n vertexBuffer[this._vertexIndex++] = startTop.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = startBottom.x;\n vertexBuffer[this._vertexIndex++] = startBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = endTop.x;\n vertexBuffer[this._vertexIndex++] = endTop.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = endBottom.x;\n vertexBuffer[this._vertexIndex++] = endBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n }\n drawRectangle(pos, width, height, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) this.flush();\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\n const topRight = transform.multiply(pos.add(vec(width, 0)));\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n }\n hasPendingDraws() {\n return this._rectangleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._rectangleCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n }\n /* harmony default export */ const circle_renderer_frag = \"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\";\n /* harmony default export */ const circle_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";\n class CircleRenderer {\n constructor(){\n this.type = \"ex.circle\";\n this.priority = 0;\n this._maxCircles = 10922; // max(uint16) / 6 verts\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n fragmentSource: circle_renderer_frag,\n vertexSource: circle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 56 * this._maxCircles,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_strokeColor\",\n 4\n ],\n [\n \"a_strokeThickness\",\n 1\n ]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n _isFull() {\n if (this._circleCount >= this._maxCircles) return true;\n return false;\n }\n draw(pos, radius, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) this.flush();\n this._circleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO UV could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n }\n hasPendingDraws() {\n return this._circleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._circleCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n }\n class Pool {\n constructor(builder, recycler, maxObjects = 100){\n this.builder = builder;\n this.recycler = recycler;\n this.maxObjects = maxObjects;\n this.totalAllocations = 0;\n this.index = 0;\n this.objects = [];\n this.disableWarnings = false;\n this._logger = Logger.getInstance();\n }\n dispose() {\n this.objects.length = 0;\n }\n preallocate() {\n for(let i = 0; i < this.maxObjects; i++)this.objects[i] = this.builder();\n }\n /**\n * Use many instances out of the in the context and return all to the pool.\n *\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\n * @param context\n */ using(context) {\n const result = context(this);\n if (result) return this.done(...result);\n return this.done();\n }\n /**\n * Use a single instance out of th pool and immediately return it to the pool\n * @param context\n */ borrow(context) {\n const object = this.get();\n context(object);\n this.index--;\n }\n /**\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\n * @param args\n */ get(...args) {\n if (this.index === this.maxObjects) {\n if (!this.disableWarnings) this._logger.warn(\"Max pooled objects reached, possible memory leak? Doubling\");\n this.maxObjects = this.maxObjects * 2;\n }\n if (this.objects[this.index]) // Pool has an available object already constructed\n return this.recycler(this.objects[this.index++], ...args);\n else {\n // New allocation\n this.totalAllocations++;\n const object = this.objects[this.index++] = this.builder(...args);\n return object;\n }\n }\n done(...objects) {\n // All objects in pool now considered \"free\"\n this.index = 0;\n for (const object of objects){\n const poolIndex = this.objects.indexOf(object);\n // Build a new object to take the pool place\n this.objects[poolIndex] = this.builder(); // TODO problematic 0-arg only support\n this.totalAllocations++;\n }\n return objects;\n }\n }\n class DrawCall {\n constructor(){\n this.z = 0;\n this.priority = 0;\n this.transform = AffineMatrix.identity();\n this.state = {\n z: 0,\n opacity: 1,\n tint: Color.White,\n material: null\n };\n }\n }\n const defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nin vec2 a_screenuv;\r\nout vec2 v_screenuv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n v_screenuv = a_screenuv;\r\n}\r\n`;\n class Material {\n constructor(options){\n this._logger = Logger.getInstance();\n this._color = Color.Transparent;\n this._initialized = false;\n this._images = new Map();\n this._textures = new Map();\n const { color: color, name: name, vertexSource: vertexSource, fragmentSource: fragmentSource, graphicsContext: graphicsContext, images: images } = options;\n this._name = name !== null && name !== void 0 ? name : \"anonymous material\";\n this._vertexSource = vertexSource !== null && vertexSource !== void 0 ? vertexSource : defaultVertexSource;\n this._fragmentSource = fragmentSource;\n this._color = color !== null && color !== void 0 ? color : this._color;\n if (!graphicsContext) throw Error(`Material ${name} must be provided an excalibur webgl graphics context`);\n if (graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this._graphicsContext = graphicsContext;\n this._initialize(graphicsContext);\n } else this._logger.warn(`Material ${name} was created in 2D Canvas mode, currently only WebGL is supported`);\n if (images) for(const key in images)this.addImageSource(key, images[key]);\n }\n _initialize(graphicsContextWebGL) {\n if (this._initialized) return;\n const gl = graphicsContextWebGL.__gl;\n // max texture slots - 2 for the graphic texture and screen texture\n this._maxTextureSlots = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) - 2;\n this._shader = graphicsContextWebGL.createShader({\n vertexSource: this._vertexSource,\n fragmentSource: this._fragmentSource\n });\n this._shader.compile();\n this._initialized = true;\n }\n get name() {\n var _a;\n return (_a = this._name) !== null && _a !== void 0 ? _a : \"anonymous material\";\n }\n get isUsingScreenTexture() {\n return this._fragmentSource.includes(\"u_screen_texture\");\n }\n update(callback) {\n if (this._shader) {\n this._shader.use();\n callback(this._shader);\n }\n }\n getShader() {\n return this._shader;\n }\n addImageSource(textureUniformName, image) {\n if (this._images.size < this._maxTextureSlots) this._images.set(textureUniformName, image);\n else this._logger.warn(`Max number texture slots ${this._maxTextureSlots} have been reached for material \"${this.name}\", ` + `no more textures will be uploaded due to hardware constraints.`);\n }\n removeImageSource(textureName) {\n const image = this._images.get(textureName);\n this._graphicsContext.textureLoader.delete(image.image);\n this._images.delete(textureName);\n }\n _loadImageSource(image) {\n const imageElement = image.image;\n const maybeFiltering = imageElement.getAttribute(\"filtering\");\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended || maybeFiltering === ImageFiltering.Pixel) filtering = maybeFiltering;\n const force = imageElement.getAttribute(\"forceUpload\") === \"true\" ? true : false;\n const texture = this._graphicsContext.textureLoader.load(imageElement, filtering, force);\n // remove force attribute after upload\n imageElement.removeAttribute(\"forceUpload\");\n if (!this._textures.has(image)) this._textures.set(image, texture);\n return texture;\n }\n uploadAndBind(gl, startingTextureSlot = 2) {\n let textureSlot = startingTextureSlot;\n for (const [textureName, image] of this._images.entries()){\n if (!image.isLoaded()) {\n this._logger.warnOnce(`Image named ${textureName} in material ${this.name} not loaded, nothing will be uploaded to the shader.` + ` Did you forget to add this to a loader? https://excaliburjs.com/docs/loaders/`);\n continue;\n } // skip unloaded images, maybe warn\n const texture = this._loadImageSource(image);\n gl.activeTexture(gl.TEXTURE0 + textureSlot);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n this._shader.trySetUniformInt(textureName, textureSlot);\n textureSlot++;\n }\n }\n use() {\n if (this._initialized) {\n // bind the shader\n this._shader.use();\n // Apply standard uniforms\n this._shader.trySetUniformFloatColor(\"u_color\", this._color);\n } else throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\n }\n }\n class MaterialRenderer {\n constructor(){\n this.type = \"ex.material\";\n this.priority = 0;\n this._textures = [];\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 24,\n type: \"dynamic\"\n });\n // Setup a vertex layout/buffer to the material\n this._layout = new VertexLayout({\n gl: gl,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ],\n [\n \"a_screenuv\",\n 2\n ]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, 1, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._textures.length = 0;\n this._context = null;\n this._gl = null;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n const gl = this._gl;\n // Extract context info\n const material = this._context.material;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n // material shader\n const shader = material.getShader();\n // construct geometry, or hold on to it in the material?\n // geometry primitive for drawing rectangles?\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n let vertexIndex = 0;\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [\n 0,\n 0,\n (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0,\n (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0\n ];\n let dest = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1\n ];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1,\n (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0,\n (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0\n ];\n dest = [\n dx,\n dy\n ];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n const topLeft = vec(dest[0], dest[1]);\n const topRight = vec(dest[0] + width, dest[1]);\n const bottomLeft = vec(dest[0], dest[1] + height);\n const bottomRight = vec(dest[0] + width, dest[1] + height);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = sx / imageWidth;\n const uvy0 = sy / imageHeight;\n const uvx1 = (sx + sw - 0.01) / imageWidth;\n const uvy1 = (sy + sh - 0.01) / imageHeight;\n const topLeftScreen = transform.getPosition();\n const bottomRightScreen = topLeftScreen.add(bottomRight);\n const screenUVX0 = topLeftScreen.x / this._context.width;\n const screenUVY0 = topLeftScreen.y / this._context.height;\n const screenUVX1 = bottomRightScreen.x / this._context.width;\n const screenUVY1 = bottomRightScreen.y / this._context.height;\n // (0, 0) - 0\n vertexBuffer[vertexIndex++] = topLeft.x;\n vertexBuffer[vertexIndex++] = topLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy0;\n vertexBuffer[vertexIndex++] = screenUVX0;\n vertexBuffer[vertexIndex++] = screenUVY0;\n // (0, 1) - 1\n vertexBuffer[vertexIndex++] = bottomLeft.x;\n vertexBuffer[vertexIndex++] = bottomLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy1;\n vertexBuffer[vertexIndex++] = screenUVX0;\n vertexBuffer[vertexIndex++] = screenUVY1;\n // (1, 0) - 2\n vertexBuffer[vertexIndex++] = topRight.x;\n vertexBuffer[vertexIndex++] = topRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy0;\n vertexBuffer[vertexIndex++] = screenUVX1;\n vertexBuffer[vertexIndex++] = screenUVY0;\n // (1, 1) - 3\n vertexBuffer[vertexIndex++] = bottomRight.x;\n vertexBuffer[vertexIndex++] = bottomRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy1;\n vertexBuffer[vertexIndex++] = screenUVX1;\n vertexBuffer[vertexIndex++] = screenUVY1;\n // This creates and uploads the texture if not already done\n const texture = this._addImageAsTexture(image);\n // apply material\n material.use();\n this._layout.shader = shader;\n // apply layout and geometry\n this._layout.use(true);\n // apply time in ms since the page (performance.now())\n shader.trySetUniformFloat(\"u_time_ms\", performance.now());\n // apply opacity\n shader.trySetUniformFloat(\"u_opacity\", opacity);\n // apply resolution\n shader.trySetUniformFloatVector(\"u_resolution\", vec(this._context.width, this._context.height));\n // apply graphic resolution\n shader.trySetUniformFloatVector(\"u_graphic_resolution\", vec(imageWidth, imageHeight));\n // apply size\n shader.trySetUniformFloatVector(\"u_size\", vec(sw, sh));\n // apply orthographic projection\n shader.trySetUniformMatrix(\"u_matrix\", this._context.ortho);\n // apply geometry transform\n shader.trySetUniformMatrix(\"u_transform\", transform.to4x4());\n // bind graphic image texture 'uniform sampler2D u_graphic;'\n gl.activeTexture(gl.TEXTURE0 + 0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n shader.trySetUniformInt(\"u_graphic\", 0);\n // bind the screen texture\n gl.activeTexture(gl.TEXTURE0 + 1);\n gl.bindTexture(gl.TEXTURE_2D, this._context.materialScreenTexture);\n shader.trySetUniformInt(\"u_screen_texture\", 1);\n // bind any additional textures in the material\n material.uploadAndBind(gl);\n // bind quad index buffer\n this._quads.bind();\n // Draw a single quad\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount++;\n GraphicsDiagnostics.DrawCallCount++;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute(\"filtering\");\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended || maybeFiltering === ImageFiltering.Pixel) filtering = maybeFiltering;\n const force = image.getAttribute(\"forceUpload\") === \"true\" ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute(\"forceUpload\");\n if (this._textures.indexOf(texture) === -1) this._textures.push(texture);\n return texture;\n }\n hasPendingDraws() {\n return false;\n }\n flush() {\n // flush does not do anything, material renderer renders immediately per draw\n }\n }\n // renderers\n const pixelSnapEpsilon = 0.0001;\n class ExcaliburGraphicsContextWebGLDebug {\n constructor(_webglCtx){\n this._webglCtx = _webglCtx;\n this._debugText = new DebugText();\n }\n /**\n * Draw a debugging rectangle to the context\n * @param x\n * @param y\n * @param width\n * @param height\n */ drawRect(x, y, width, height, rectOptions = {\n color: Color.Black\n }) {\n this.drawLine(vec(x, y), vec(x + width, y), {\n ...rectOptions\n });\n this.drawLine(vec(x + width, y), vec(x + width, y + height), {\n ...rectOptions\n });\n this.drawLine(vec(x + width, y + height), vec(x, y + height), {\n ...rectOptions\n });\n this.drawLine(vec(x, y + height), vec(x, y), {\n ...rectOptions\n });\n }\n /**\n * Draw a debugging line to the context\n * @param start\n * @param end\n * @param lineOptions\n */ drawLine(start, end, lineOptions = {\n color: Color.Black\n }) {\n this._webglCtx.draw(\"ex.line\", start, end, lineOptions.color);\n }\n /**\n * Draw a debugging point to the context\n * @param point\n * @param pointOptions\n */ drawPoint(point, pointOptions = {\n color: Color.Black,\n size: 5\n }) {\n this._webglCtx.draw(\"ex.point\", point, pointOptions.color, pointOptions.size);\n }\n drawText(text, pos) {\n this._debugText.write(this._webglCtx, text, pos);\n }\n }\n class ExcaliburGraphicsContextWebGL {\n get z() {\n return this._state.current.z;\n }\n set z(value) {\n this._state.current.z = value;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get width() {\n return this.__gl.canvas.width;\n }\n get height() {\n return this.__gl.canvas.height;\n }\n get ortho() {\n return this._ortho;\n }\n /**\n * Checks the underlying webgl implementation if the requested internal resolution is supported\n * @param dim\n */ checkIfResolutionSupported(dim) {\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\n let supported = true;\n if (dim.width > 4096 || dim.height > 4096) supported = false;\n return supported;\n }\n constructor(options){\n this._logger = Logger.getInstance();\n this._renderers = new Map();\n this._isDrawLifecycle = false;\n this.useDrawSorting = true;\n this._drawCallPool = new Pool(()=>new DrawCall(), (instance)=>{\n instance.priority = 0;\n instance.z = 0;\n instance.renderer = undefined;\n instance.args = undefined;\n return instance;\n }, 4000);\n this._drawCalls = [];\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\n this._postProcessTargets = [];\n this._postprocessors = [];\n this._transform = new TransformStack();\n this._state = new StateStack();\n /**\n * Snaps the drawing x/y coordinate to the nearest whole pixel\n */ this.snapToPixel = false;\n /**\n * Native context smoothing\n */ this.smoothing = false;\n /**\n * Whether the pixel art sampler is enabled for smooth sub pixel anti-aliasing\n */ this.pixelArtSampler = false;\n /**\n * UV padding in pixels to use in internal image rendering to prevent texture bleed\n *\n */ this.uvPadding = .01;\n this.backgroundColor = Color.ExcaliburBlue;\n this.multiSampleAntialiasing = true;\n this.transparency = true;\n this._disposed = false;\n this.debug = new ExcaliburGraphicsContextWebGLDebug(this);\n this._totalPostProcessorTime = 0;\n const { canvasElement: canvasElement, context: context, enableTransparency: enableTransparency, antialiasing: antialiasing, uvPadding: uvPadding, multiSampleAntialiasing: multiSampleAntialiasing, pixelArtSampler: pixelArtSampler, powerPreference: powerPreference, snapToPixel: snapToPixel, backgroundColor: backgroundColor, useDrawSorting: useDrawSorting } = options;\n this.__gl = context !== null && context !== void 0 ? context : canvasElement.getContext(\"webgl2\", {\n antialias: antialiasing !== null && antialiasing !== void 0 ? antialiasing : this.smoothing,\n premultipliedAlpha: false,\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : this.transparency,\n depth: false,\n powerPreference: powerPreference !== null && powerPreference !== void 0 ? powerPreference : \"high-performance\"\n });\n if (!this.__gl) throw Error(\"Failed to retrieve webgl context from browser\");\n this.textureLoader = new TextureLoader(this.__gl);\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = antialiasing !== null && antialiasing !== void 0 ? antialiasing : this.smoothing;\n this.transparency = enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : this.transparency;\n this.pixelArtSampler = pixelArtSampler !== null && pixelArtSampler !== void 0 ? pixelArtSampler : this.pixelArtSampler;\n this.uvPadding = uvPadding !== null && uvPadding !== void 0 ? uvPadding : this.uvPadding;\n this.multiSampleAntialiasing = typeof multiSampleAntialiasing === \"boolean\" ? multiSampleAntialiasing : this.multiSampleAntialiasing;\n this.samples = typeof multiSampleAntialiasing === \"object\" ? multiSampleAntialiasing.samples : undefined;\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.useDrawSorting = useDrawSorting !== null && useDrawSorting !== void 0 ? useDrawSorting : this.useDrawSorting;\n this._drawCallPool.disableWarnings = true;\n this._drawCallPool.preallocate();\n this._init();\n }\n dispose() {\n if (!this._disposed) {\n this._disposed = true;\n this.textureLoader.dispose();\n for (const renderer of this._renderers.values())renderer.dispose();\n this._renderers.clear();\n this._drawCallPool.dispose();\n this._drawCalls.length = 0;\n this.__gl = null;\n }\n }\n _init() {\n const gl = this.__gl;\n // Setup viewport and view matrix\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\n // Clear background\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n // Enable alpha blending\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n // Setup builtin renderers\n this.register(new ImageRenderer({\n uvPadding: this.uvPadding,\n pixelArtSampler: this.pixelArtSampler\n }));\n this.register(new MaterialRenderer());\n this.register(new RectangleRenderer());\n this.register(new CircleRenderer());\n this.register(new PointRenderer());\n this.register(new LineRenderer());\n this.materialScreenTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this.materialScreenTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n gl.bindTexture(gl.TEXTURE_2D, null);\n this._screenRenderer = new ScreenPassPainter(gl);\n this._renderTarget = new RenderTarget({\n gl: gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n });\n this._postProcessTargets = [\n new RenderTarget({\n gl: gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n }),\n new RenderTarget({\n gl: gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n })\n ];\n this._msaaTarget = new RenderTarget({\n gl: gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height,\n antialias: this.multiSampleAntialiasing,\n samples: this.samples\n });\n }\n register(renderer) {\n this._renderers.set(renderer.type, renderer);\n renderer.initialize(this.__gl, this);\n }\n get(rendererName) {\n return this._renderers.get(rendererName);\n }\n _isCurrentRenderer(renderer) {\n if (!this._currentRenderer || this._currentRenderer === renderer) return true;\n return false;\n }\n beginDrawLifecycle() {\n this._isDrawLifecycle = true;\n }\n endDrawLifecycle() {\n this._isDrawLifecycle = false;\n }\n draw(rendererName, ...args) {\n if (!this._isDrawLifecycle) this._logger.warnOnce(`Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` + `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\n const renderer = this._renderers.get(rendererName);\n if (renderer) {\n if (this.useDrawSorting) {\n const drawCall = this._drawCallPool.get();\n drawCall.z = this._state.current.z;\n drawCall.priority = renderer.priority;\n drawCall.renderer = rendererName;\n this.getTransform().clone(drawCall.transform);\n drawCall.state.z = this._state.current.z;\n drawCall.state.opacity = this._state.current.opacity;\n drawCall.state.tint = this._state.current.tint;\n drawCall.state.material = this._state.current.material;\n drawCall.args = args;\n this._drawCalls.push(drawCall);\n } else {\n // Set the current renderer if not defined\n if (!this._currentRenderer) this._currentRenderer = renderer;\n if (!this._isCurrentRenderer(renderer)) // switching graphics means we must flush the previous\n this._currentRenderer.flush();\n // If we are still using the same renderer we can add to the current batch\n renderer.draw(...args);\n this._currentRenderer = renderer;\n }\n } else throw Error(`No renderer with name ${rendererName} has been registered`);\n }\n resetTransform() {\n this._transform.current = AffineMatrix.identity();\n }\n updateViewport(resolution) {\n const gl = this.__gl;\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._msaaTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) return; // zero dimension dest exit early\n else if (dwidth === 0 || dheight === 0) return; // zero dimension dest exit early\n else if (image.width === 0 || image.height === 0) return; // zero dimension source exit early\n if (!image) {\n Logger.getInstance().warn(\"Cannot draw a null or undefined image\");\n // tslint:disable-next-line: no-console\n if (console.trace) // tslint:disable-next-line: no-console\n console.trace();\n return;\n }\n if (this._state.current.material) this.draw(\"ex.material\", image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n else this.draw(\"ex.image\", image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n }\n drawLine(start, end, color, thickness = 1) {\n this.draw(\"ex.rectangle\", start, end, color, thickness);\n }\n drawRectangle(pos, width, height, color, stroke, strokeThickness) {\n this.draw(\"ex.rectangle\", pos, width, height, color, stroke, strokeThickness);\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.draw(\"ex.circle\", pos, radius, color, stroke, thickness);\n }\n save() {\n this._transform.save();\n this._state.save();\n }\n restore() {\n this._transform.restore();\n this._state.restore();\n }\n translate(x, y) {\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\n }\n rotate(angle) {\n this._transform.rotate(angle);\n }\n scale(x, y) {\n this._transform.scale(x, y);\n }\n transform(matrix) {\n this._transform.current = matrix;\n }\n getTransform() {\n return this._transform.current;\n }\n multiply(m) {\n this._transform.current.multiply(m, this._transform.current);\n }\n addPostProcessor(postprocessor) {\n this._postprocessors.push(postprocessor);\n postprocessor.initialize(this.__gl);\n }\n removePostProcessor(postprocessor) {\n const index = this._postprocessors.indexOf(postprocessor);\n if (index !== -1) this._postprocessors.splice(index, 1);\n }\n clearPostProcessors() {\n this._postprocessors.length = 0;\n }\n updatePostProcessors(delta) {\n for (const postprocessor of this._postprocessors){\n const shader = postprocessor.getShader();\n shader.use();\n const uniforms = shader.getUniforms();\n this._totalPostProcessorTime += delta;\n if (uniforms.find((u)=>u.name === \"u_time_ms\")) shader.setUniformFloat(\"u_time_ms\", this._totalPostProcessorTime);\n if (uniforms.find((u)=>u.name === \"u_elapsed_ms\")) shader.setUniformFloat(\"u_elapsed_ms\", delta);\n if (uniforms.find((u)=>u.name === \"u_resolution\")) shader.setUniformFloatVector(\"u_resolution\", vec(this.width, this.height));\n if (postprocessor.onUpdate) postprocessor.onUpdate(delta);\n }\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n /**\n * Creates and initializes the material which compiles the internal shader\n * @param options\n * @returns Material\n */ createMaterial(options) {\n const material = new Material({\n ...options,\n graphicsContext: this\n });\n return material;\n }\n createShader(options) {\n const gl = this.__gl;\n const { vertexSource: vertexSource, fragmentSource: fragmentSource } = options;\n const shader = new Shader({\n gl: gl,\n vertexSource: vertexSource,\n fragmentSource: fragmentSource\n });\n shader.compile();\n return shader;\n }\n clear() {\n const gl = this.__gl;\n const currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\n currentTarget.use();\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n // Clear the context with the newly set color. This is\n // the function call that actually does the drawing.\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n /**\n * Flushes all batched rendering to the screen\n */ flush() {\n // render target captures all draws and redirects to the render target\n let currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\n currentTarget.use();\n if (this.useDrawSorting) {\n // sort draw calls\n // Find the original order of the first instance of the draw call\n const originalSort = new Map();\n for (const [name] of this._renderers){\n const firstIndex = this._drawCalls.findIndex((dc)=>dc.renderer === name);\n originalSort.set(name, firstIndex);\n }\n this._drawCalls.sort((a, b)=>{\n const zIndex = a.z - b.z;\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\n const priority = a.priority - b.priority;\n if (zIndex === 0) {\n if (priority === 0) return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\n return priority;\n }\n return zIndex;\n });\n const oldTransform = this._transform.current;\n const oldState = this._state.current;\n if (this._drawCalls.length) {\n let currentRendererName = this._drawCalls[0].renderer;\n let currentRenderer = this._renderers.get(currentRendererName);\n for(let i = 0; i < this._drawCalls.length; i++){\n // hydrate the state for renderers\n this._transform.current = this._drawCalls[i].transform;\n this._state.current = this._drawCalls[i].state;\n if (this._drawCalls[i].renderer !== currentRendererName) {\n // switching graphics renderer means we must flush the previous\n currentRenderer.flush();\n currentRendererName = this._drawCalls[i].renderer;\n currentRenderer = this._renderers.get(currentRendererName);\n }\n // ! hack to grab screen texture before materials run because they might want it\n if (currentRenderer instanceof MaterialRenderer && this.material.isUsingScreenTexture) {\n currentTarget.copyToTexture(this.materialScreenTexture);\n currentTarget.use();\n }\n // If we are still using the same renderer we can add to the current batch\n currentRenderer.draw(...this._drawCalls[i].args);\n }\n if (currentRenderer.hasPendingDraws()) currentRenderer.flush();\n }\n // reset state\n this._transform.current = oldTransform;\n this._state.current = oldState;\n // reclaim draw calls\n this._drawCallPool.done();\n this._drawCalls.length = 0;\n } else {\n // This is the final flush at the moment to draw any leftover pending draw\n for (const renderer of this._renderers.values())if (renderer.hasPendingDraws()) renderer.flush();\n }\n currentTarget.disable();\n // post process step\n if (this._postprocessors.length > 0) {\n const source = currentTarget.toRenderSource();\n source.use();\n }\n // flip flop render targets for post processing\n for(let i = 0; i < this._postprocessors.length; i++){\n currentTarget = this._postProcessTargets[i % 2];\n this._postProcessTargets[i % 2].use();\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\n this._postProcessTargets[i % 2].toRenderSource().use();\n }\n // Final blit to the screen\n currentTarget.blitToScreen();\n }\n }\n const ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon = 0.0001;\n class ExcaliburGraphicsContext2DCanvasDebug {\n constructor(_ex){\n this._ex = _ex;\n this._debugText = new DebugText();\n }\n /**\n * Draw a debug rectangle to the context\n * @param x\n * @param y\n * @param width\n * @param height\n */ drawRect(x, y, width, height) {\n this._ex.__ctx.save();\n this._ex.__ctx.strokeStyle = \"red\";\n this._ex.__ctx.strokeRect(this._ex.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this._ex.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y, this._ex.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this._ex.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this._ex.__ctx.restore();\n }\n drawLine(start, end, lineOptions = {\n color: Color.Black\n }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\n this._ex.__ctx.moveTo(this._ex.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this._ex.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this._ex.__ctx.lineTo(this._ex.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this._ex.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this._ex.__ctx.lineWidth = 2;\n this._ex.__ctx.stroke();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawPoint(point, pointOptions = {\n color: Color.Black,\n size: 5\n }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\n this._ex.__ctx.arc(this._ex.snapToPixel ? ~~(point.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.x, this._ex.snapToPixel ? ~~(point.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.y, pointOptions.size, 0, Math.PI * 2);\n this._ex.__ctx.fill();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawText(text, pos) {\n this._debugText.write(this._ex, text, pos);\n }\n }\n class ExcaliburGraphicsContext2DCanvas {\n get width() {\n return this.__ctx.canvas.width;\n }\n get height() {\n return this.__ctx.canvas.height;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get smoothing() {\n return this.__ctx.imageSmoothingEnabled;\n }\n set smoothing(value) {\n this.__ctx.imageSmoothingEnabled = value;\n }\n constructor(options){\n /**\n * Unused in Canvas implementation\n */ this.useDrawSorting = false;\n /**\n * Unused in Canvas implementation\n */ this.z = 0;\n this.backgroundColor = Color.ExcaliburBlue;\n this._state = new StateStack();\n this.snapToPixel = false;\n this.debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\n const { canvasElement: canvasElement, context: context, enableTransparency: enableTransparency, snapToPixel: snapToPixel, antialiasing: smoothing, backgroundColor: backgroundColor } = options;\n this.__ctx = context !== null && context !== void 0 ? context : canvasElement.getContext(\"2d\", {\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : true\n });\n if (!this.__ctx) throw new Error(\"Cannot build new ExcaliburGraphicsContext2D for some reason!\");\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing;\n }\n resetTransform() {\n this.__ctx.resetTransform();\n }\n updateViewport(_resolution) {\n // pass\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) return; // zero dimension dest exit early\n else if (dwidth === 0 || dheight === 0) return; // zero dimension dest exit early\n else if (image.width === 0 || image.height === 0) return; // zero dimension source exit early\n this.__ctx.globalAlpha = this.opacity;\n const args = [\n image,\n sx,\n sy,\n swidth,\n sheight,\n dx,\n dy,\n dwidth,\n dheight\n ].filter((a)=>a !== undefined).map((a)=>typeof a === \"number\" && this.snapToPixel ? ~~a : a);\n this.__ctx.drawImage.apply(this.__ctx, args);\n GraphicsDiagnostics.DrawCallCount++;\n GraphicsDiagnostics.DrawnImagesCount = 1;\n }\n drawLine(start, end, color, thickness = 1) {\n this.__ctx.save();\n this.__ctx.beginPath();\n this.__ctx.strokeStyle = color.toString();\n this.__ctx.moveTo(this.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this.__ctx.lineTo(this.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this.__ctx.lineWidth = thickness;\n this.__ctx.stroke();\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n drawRectangle(pos, width, height, color) {\n this.__ctx.save();\n this.__ctx.fillStyle = color.toString();\n this.__ctx.fillRect(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, this.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this.__ctx.restore();\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.__ctx.save();\n this.__ctx.beginPath();\n if (stroke) this.__ctx.strokeStyle = stroke.toString();\n if (thickness) this.__ctx.lineWidth = thickness;\n this.__ctx.fillStyle = color.toString();\n this.__ctx.arc(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2);\n this.__ctx.fill();\n if (stroke) this.__ctx.stroke();\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n /**\n * Save the current state of the canvas to the stack (transforms and opacity)\n */ save() {\n this.__ctx.save();\n this._state.save();\n }\n /**\n * Restore the state of the canvas from the stack\n */ restore() {\n this.__ctx.restore();\n this._state.restore();\n }\n /**\n * Translate the origin of the context by an x and y\n * @param x\n * @param y\n */ translate(x, y) {\n this.__ctx.translate(this.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y);\n }\n /**\n * Rotate the context about the current origin\n */ rotate(angle) {\n this.__ctx.rotate(angle);\n }\n /**\n * Scale the context by an x and y factor\n * @param x\n * @param y\n */ scale(x, y) {\n this.__ctx.scale(x, y);\n }\n getTransform() {\n throw new Error(\"Not implemented\");\n }\n multiply(_m) {\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\n }\n addPostProcessor(_postprocessor) {\n // pass\n }\n removePostProcessor(_postprocessor) {\n // pass\n }\n clearPostProcessors() {\n // pass\n }\n updatePostProcessors(delta) {\n // pass\n }\n beginDrawLifecycle() {\n // pass\n }\n endDrawLifecycle() {\n // pass\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n createMaterial(options) {\n // pass\n return null;\n }\n clear() {\n // Clear frame\n this.__ctx.clearRect(0, 0, this.width, this.height);\n this.__ctx.fillStyle = this.backgroundColor.toString();\n this.__ctx.fillRect(0, 0, this.width, this.height);\n GraphicsDiagnostics.clear();\n }\n /**\n * Flushes the batched draw calls to the screen\n */ flush() {\n // pass\n }\n dispose() {\n this.__ctx = null;\n }\n }\n /**\n * Enum representing the different display modes available to Excalibur.\n */ var DisplayMode;\n (function(DisplayMode) {\n /**\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\n */ DisplayMode[\"Fixed\"] = \"Fixed\";\n /**\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\n * is guaranteed to be on screen.\n */ DisplayMode[\"FitContainerAndFill\"] = \"FitContainerAndFill\";\n /**\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\n * is guaranteed to be on screen.\n */ DisplayMode[\"FitScreenAndFill\"] = \"FitScreenAndFill\";\n /**\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\n * (letterbox) that would otherwise be present in [[FitContainer]].\n *\n * **warning** This will clip some drawable area from the user because of the zoom,\n * use [[Screen.contentArea]] to know the safe to draw area.\n */ DisplayMode[\"FitContainerAndZoom\"] = \"FitContainerAndZoom\";\n /**\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\n * (letterbox) that would otherwise be present in [[FitScreen]].\n *\n * **warning** This will clip some drawable area from the user because of the zoom,\n * use [[Screen.contentArea]] to know the safe to draw area.\n */ DisplayMode[\"FitScreenAndZoom\"] = \"FitScreenAndZoom\";\n /**\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\n *\n * You may want to center your game here is an example\n * ```html\n * \n * \n *
\n * \n *
\n * \n * ```\n *\n * ```css\n * // css\n * main {\n * display: flex;\n * align-items: center;\n * justify-content: center;\n * height: 100%;\n * width: 100%;\n * }\n * ```\n */ DisplayMode[\"FitScreen\"] = \"FitScreen\";\n /**\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\n */ DisplayMode[\"FillScreen\"] = \"FillScreen\";\n /**\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\n */ DisplayMode[\"FitContainer\"] = \"FitContainer\";\n /**\n * Use the parent DOM container's css width/height for the game resolution dynamically\n */ DisplayMode[\"FillContainer\"] = \"FillContainer\";\n })(DisplayMode || (DisplayMode = {}));\n /**\n * Convenience class for quick resolutions\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\n */ class Resolution {\n /* istanbul ignore next */ static get SVGA() {\n return {\n width: 800,\n height: 600\n };\n }\n /* istanbul ignore next */ static get Standard() {\n return {\n width: 1920,\n height: 1080\n };\n }\n /* istanbul ignore next */ static get Atari2600() {\n return {\n width: 160,\n height: 192\n };\n }\n /* istanbul ignore next */ static get GameBoy() {\n return {\n width: 160,\n height: 144\n };\n }\n /* istanbul ignore next */ static get GameBoyAdvance() {\n return {\n width: 240,\n height: 160\n };\n }\n /* istanbul ignore next */ static get NintendoDS() {\n return {\n width: 256,\n height: 192\n };\n }\n /* istanbul ignore next */ static get NES() {\n return {\n width: 256,\n height: 224\n };\n }\n /* istanbul ignore next */ static get SNES() {\n return {\n width: 256,\n height: 244\n };\n }\n }\n const ScreenEvents = {\n ScreenResize: \"resize\",\n PixelRatioChange: \"pixelratio\",\n FullScreenChange: \"fullscreen\"\n };\n /**\n * The Screen handles all aspects of interacting with the screen for Excalibur.\n */ class Screen {\n constructor(options){\n var _a, _b, _c, _d;\n /**\n * Listen to screen events [[ScreenEvents]]\n */ this.events = new EventEmitter();\n this._antialiasing = true;\n this._canvasImageRendering = \"auto\";\n this._resolutionStack = [];\n this._viewportStack = [];\n this._pixelRatioOverride = null;\n this._isFullScreen = false;\n this._isDisposed = false;\n this._logger = Logger.getInstance();\n this._fullscreenChangeHandler = ()=>{\n if (this._isDisposed) return;\n this._isFullScreen = !this._isFullScreen;\n this._logger.debug(\"Fullscreen Change\", this._isFullScreen);\n this.events.emit(\"fullscreen\", {\n fullscreen: this.isFullScreen\n });\n };\n this._pixelRatioChangeHandler = ()=>{\n if (this._isDisposed) return;\n this._logger.debug(\"Pixel Ratio Change\", window.devicePixelRatio);\n this._listenForPixelRatio();\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this.applyResolutionAndViewport();\n this.events.emit(\"pixelratio\", {\n pixelRatio: this.pixelRatio\n });\n };\n this._resizeHandler = ()=>{\n if (this._isDisposed) return;\n const parent = this.parent;\n this._logger.debug(\"View port resized\");\n this._setResolutionAndViewportByDisplayMode(parent);\n this.applyResolutionAndViewport();\n // Emit resize event\n this.events.emit(\"resize\", {\n resolution: this.resolution,\n viewport: this.viewport\n });\n };\n // Asking the window.devicePixelRatio is expensive we do it once\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this._contentArea = new BoundingBox();\n this.viewport = options.viewport;\n this.resolution = (_a = options.resolution) !== null && _a !== void 0 ? _a : {\n ...this.viewport\n };\n this._contentResolution = this.resolution;\n this._displayMode = (_b = options.displayMode) !== null && _b !== void 0 ? _b : DisplayMode.Fixed;\n this._canvas = options.canvas;\n this.graphicsContext = options.context;\n this._antialiasing = (_c = options.antialiasing) !== null && _c !== void 0 ? _c : this._antialiasing;\n this._canvasImageRendering = (_d = options.canvasImageRendering) !== null && _d !== void 0 ? _d : this._canvasImageRendering;\n this._browser = options.browser;\n this._pixelRatioOverride = options.pixelRatio;\n this._applyDisplayMode();\n this._listenForPixelRatio();\n this._canvas.addEventListener(\"fullscreenchange\", this._fullscreenChangeHandler);\n this.applyResolutionAndViewport();\n }\n _listenForPixelRatio() {\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) // Safari <=13.1 workaround, remove any existing handlers\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.addEventListener) this._mediaQueryList.addEventListener(\"change\", this._pixelRatioChangeHandler, {\n once: true\n });\n else this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\n }\n dispose() {\n if (!this._isDisposed) {\n // Clean up handlers\n this._isDisposed = true;\n this.events.clear();\n this._browser.window.off(\"resize\", this._resizeHandler);\n this._browser.window.clear();\n if (this._resizeObserver) this._resizeObserver.disconnect();\n this.parent.removeEventListener(\"resize\", this._resizeHandler);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.removeEventListener) this._mediaQueryList.removeEventListener(\"change\", this._pixelRatioChangeHandler);\n else this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n this._canvas.removeEventListener(\"fullscreenchange\", this._fullscreenChangeHandler);\n this._canvas = null;\n }\n }\n _calculateDevicePixelRatio() {\n if (window.devicePixelRatio < 1) return 1;\n const devicePixelRatio = window.devicePixelRatio || 1;\n return devicePixelRatio;\n }\n /**\n * Returns the computed pixel ratio, first using any override, then the device pixel ratio\n */ get pixelRatio() {\n if (this._pixelRatioOverride) return this._pixelRatioOverride;\n return this._devicePixelRatio;\n }\n /**\n * Get or set the pixel ratio override\n *\n * You will need to call applyResolutionAndViewport() affect change on the screen\n */ get pixelRatioOverride() {\n return this._pixelRatioOverride;\n }\n set pixelRatioOverride(value) {\n this._pixelRatioOverride = value;\n }\n get isHiDpi() {\n return this.pixelRatio !== 1;\n }\n get displayMode() {\n return this._displayMode;\n }\n get canvas() {\n return this._canvas;\n }\n get parent() {\n switch(this.displayMode){\n case DisplayMode.FillContainer:\n case DisplayMode.FitContainer:\n case DisplayMode.FitContainerAndFill:\n case DisplayMode.FitContainerAndZoom:\n return this.canvas.parentElement || document.body;\n default:\n return window;\n }\n }\n get resolution() {\n return this._resolution;\n }\n set resolution(resolution) {\n this._resolution = resolution;\n }\n get viewport() {\n if (this._viewport) return this._viewport;\n return this._resolution;\n }\n set viewport(viewport) {\n this._viewport = viewport;\n }\n get aspectRatio() {\n return this._resolution.width / this._resolution.height;\n }\n get scaledWidth() {\n return this._resolution.width * this.pixelRatio;\n }\n get scaledHeight() {\n return this._resolution.height * this.pixelRatio;\n }\n setCurrentCamera(camera) {\n this._camera = camera;\n }\n pushResolutionAndViewport() {\n this._resolutionStack.push(this.resolution);\n this._viewportStack.push(this.viewport);\n this.resolution = {\n ...this.resolution\n };\n this.viewport = {\n ...this.viewport\n };\n }\n peekViewport() {\n return this._viewportStack[this._viewportStack.length - 1];\n }\n peekResolution() {\n return this._resolutionStack[this._resolutionStack.length - 1];\n }\n popResolutionAndViewport() {\n if (this._resolutionStack.length && this._viewportStack.length) {\n this.resolution = this._resolutionStack.pop();\n this.viewport = this._viewportStack.pop();\n }\n }\n applyResolutionAndViewport() {\n this._canvas.width = this.scaledWidth;\n this._canvas.height = this.scaledHeight;\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n const supported = this.graphicsContext.checkIfResolutionSupported({\n width: this.scaledWidth,\n height: this.scaledHeight\n });\n if (!supported) this._logger.warnOnce(`The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` + \" are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.\" + \" Try reducing the resolution or disabling Hi DPI scaling to avoid this\" + \" (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).\");\n }\n if (this._canvasImageRendering === \"auto\") this._canvas.style.imageRendering = \"auto\";\n else {\n this._canvas.style.imageRendering = \"pixelated\";\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\n if (this._canvas.style.imageRendering === \"\") this._canvas.style.imageRendering = \"crisp-edges\";\n }\n this._canvas.style.width = this.viewport.width + \"px\";\n this._canvas.style.height = this.viewport.height + \"px\";\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\n this.graphicsContext.updateViewport(this.resolution);\n this.graphicsContext.resetTransform();\n this.graphicsContext.smoothing = this._antialiasing;\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\n }\n get antialiasing() {\n return this._antialiasing;\n }\n set antialiasing(isSmooth) {\n this._antialiasing = isSmooth;\n this.graphicsContext.smoothing = this._antialiasing;\n }\n /**\n * Returns true if excalibur is fullscreen using the browser fullscreen api\n */ get isFullScreen() {\n return this._isFullScreen;\n }\n /**\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\n * For example, wire this to a user click handler.\n *\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\n * @param elementId\n */ goFullScreen(elementId) {\n if (elementId) {\n const maybeElement = document.getElementById(elementId);\n if (maybeElement) {\n if (!maybeElement.getAttribute(\"ex-fullscreen-listener\")) {\n maybeElement.setAttribute(\"ex-fullscreen-listener\", \"true\");\n maybeElement.addEventListener(\"fullscreenchange\", this._fullscreenChangeHandler);\n }\n const fullscreenPromise = maybeElement.requestFullscreen();\n return fullscreenPromise;\n }\n }\n return this._canvas.requestFullscreen();\n }\n /**\n * Requests to exit fullscreen using the browser fullscreen api\n */ exitFullScreen() {\n return document.exitFullscreen();\n }\n /**\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\n * Excalibur screen space.\n *\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\n * bottom right corner (resolutionX, resolutionY). When using *AndFill suffixed display modes screen space\n * (0, 0) is the top left of the safe content area bounding box not the viewport.\n * @param point\n */ pageToScreenCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n if (!this._isFullScreen) {\n newX -= getPosition(this._canvas).x;\n newY -= getPosition(this._canvas).y;\n }\n // if fullscreen api on it centers with black bars\n // we need to adjust the screen to world coordinates in this case\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = (newY - screenMarginY) / screenHeight * this.viewport.height;\n newX = newX / window.innerWidth * this.viewport.width;\n } else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = (newX - screenMarginX) / screenWidth * this.viewport.width;\n newY = newY / window.innerHeight * this.viewport.height;\n }\n }\n newX = newX / this.viewport.width * this.resolution.width;\n newY = newY / this.viewport.height * this.resolution.height;\n // offset by content area\n newX = newX - this.contentArea.left;\n newY = newY - this.contentArea.top;\n return new Vector(newX, newY);\n }\n /**\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\n * this is where html elements might live if you want to position them relative to Excalibur.\n *\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\n * bottom right corner (resolutionX, resolutionY)\n * @param point\n */ screenToPageCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n // no need to offset by content area, drawing is already offset by this\n newX = newX / this.resolution.width * this.viewport.width;\n newY = newY / this.resolution.height * this.viewport.height;\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = newY / this.viewport.height * screenHeight + screenMarginY;\n newX = newX / this.viewport.width * window.innerWidth;\n } else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = newX / this.viewport.width * screenWidth + screenMarginX;\n newY = newY / this.viewport.height * window.innerHeight;\n }\n }\n if (!this._isFullScreen) {\n newX += getPosition(this._canvas).x;\n newY += getPosition(this._canvas).y;\n }\n return new Vector(newX, newY);\n }\n /**\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\n *\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\n * and extends infinitely out relative from the [[Camera]].\n * @param point Screen coordinate to convert\n */ screenToWorldCoordinates(point) {\n // offset by content area\n point = point.add(vec(this.contentArea.left, this.contentArea.top));\n // the only difference between screen & world is the camera transform\n if (this._camera) return this._camera.inverse.multiply(point);\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n /**\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\n *\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\n * @param point World coordinate to convert\n */ worldToScreenCoordinates(point) {\n if (this._camera) return this._camera.transform.multiply(point);\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n pageToWorldCoordinates(point) {\n const screen = this.pageToScreenCoordinates(point);\n return this.screenToWorldCoordinates(screen);\n }\n worldToPageCoordinates(point) {\n const screen = this.worldToScreenCoordinates(point);\n return this.screenToPageCoordinates(screen);\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen\n * and the bottom right corner of the screen.\n *\n * World bounds are in world coordinates, useful for culling objects offscreen that are in world space\n */ getWorldBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Half).scale(vec(1 / this._camera.zoom, 1 / this._camera.zoom)).rotate(this._camera.rotation).translate(this._camera.pos);\n return bounds;\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen and the bottom right corner of the screen.\n *\n * Screen bounds are in screen coordinates, useful for culling objects offscreen that are in screen space\n */ getScreenBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero, Vector.Zero);\n return bounds;\n }\n /**\n * The width of the game canvas in pixels (physical width component of the\n * resolution of the canvas element)\n */ get canvasWidth() {\n return this.canvas.width;\n }\n /**\n * Returns half width of the game canvas in pixels (half physical width component)\n */ get halfCanvasWidth() {\n return this.canvas.width / 2;\n }\n /**\n * The height of the game canvas in pixels, (physical height component of\n * the resolution of the canvas element)\n */ get canvasHeight() {\n return this.canvas.height;\n }\n /**\n * Returns half height of the game canvas in pixels (half physical height component)\n */ get halfCanvasHeight() {\n return this.canvas.height / 2;\n }\n /**\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get drawWidth() {\n if (this._camera) return this.resolution.width / this._camera.zoom;\n return this.resolution.width;\n }\n /**\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get halfDrawWidth() {\n return this.drawWidth / 2;\n }\n /**\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get drawHeight() {\n if (this._camera) return this.resolution.height / this._camera.zoom;\n return this.resolution.height;\n }\n /**\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get halfDrawHeight() {\n return this.drawHeight / 2;\n }\n /**\n * Returns screen center coordinates including zoom and device pixel ratio.\n */ get center() {\n return vec(this.halfDrawWidth, this.halfDrawHeight);\n }\n /**\n * Returns the content area in screen space where it is safe to place content\n */ get contentArea() {\n return this._contentArea;\n }\n _computeFit() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (window.innerWidth / aspect < window.innerHeight) {\n adjustedWidth = window.innerWidth;\n adjustedHeight = window.innerWidth / aspect;\n } else {\n adjustedWidth = window.innerHeight * aspect;\n adjustedHeight = window.innerHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _computeFitScreenAndFill() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitContainerAndFill() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const parent = this.canvas.parentElement;\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitAndFill(vw, vh) {\n this.viewport = {\n width: vw,\n height: vh\n };\n // if the current screen aspectRatio is less than the original aspectRatio\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\n // compute new resolution to match the original aspect ratio\n this.resolution = {\n width: vw * this._contentResolution.width / vw,\n height: vw * this._contentResolution.width / vw * vh / vw\n };\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\n this._contentArea = new BoundingBox({\n top: clip,\n left: 0,\n right: this._contentResolution.width,\n bottom: this.resolution.height - clip\n });\n } else {\n this.resolution = {\n width: vh * this._contentResolution.height / vh * vw / vh,\n height: vh * this._contentResolution.height / vh\n };\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\n this._contentArea = new BoundingBox({\n top: 0,\n left: clip,\n right: this.resolution.width - clip,\n bottom: this._contentResolution.height\n });\n }\n }\n _computeFitScreenAndZoom() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.canvas.style.position = \"absolute\";\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitContainerAndZoom() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.canvas.style.position = \"absolute\";\n const parent = this.canvas.parentElement;\n parent.style.position = \"relative\";\n parent.style.overflow = \"hidden\";\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitAndZoom(vw, vh) {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (vw / aspect < vh) {\n adjustedWidth = vw;\n adjustedHeight = vw / aspect;\n } else {\n adjustedWidth = vh * aspect;\n adjustedHeight = vh;\n }\n const scaleX = vw / adjustedWidth;\n const scaleY = vh / adjustedHeight;\n const maxScaleFactor = Math.max(scaleX, scaleY);\n const zoomedWidth = adjustedWidth * maxScaleFactor;\n const zoomedHeight = adjustedHeight * maxScaleFactor;\n // Center zoomed dimension if bigger than the screen\n if (zoomedWidth > vw) this.canvas.style.left = -(zoomedWidth - vw) / 2 + \"px\";\n else this.canvas.style.left = \"\";\n if (zoomedHeight > vh) this.canvas.style.top = -(zoomedHeight - vh) / 2 + \"px\";\n else this.canvas.style.top = \"\";\n this.viewport = {\n width: zoomedWidth,\n height: zoomedHeight\n };\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\n // return safe area\n if (this.viewport.width > vw) {\n const clip = (this.viewport.width - vw) / this.viewport.width * this.resolution.width;\n bounds.top = 0;\n bounds.left = clip / 2;\n bounds.right = this.resolution.width - clip / 2;\n bounds.bottom = this.resolution.height;\n }\n if (this.viewport.height > vh) {\n const clip = (this.viewport.height - vh) / this.viewport.height * this.resolution.height;\n bounds.top = clip / 2;\n bounds.left = 0;\n bounds.bottom = this.resolution.height - clip / 2;\n bounds.right = this.resolution.width;\n }\n this._contentArea = bounds;\n }\n _computeFitContainer() {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n const parent = this.canvas.parentElement;\n if (parent.clientWidth / aspect < parent.clientHeight) {\n adjustedWidth = parent.clientWidth;\n adjustedHeight = parent.clientWidth / aspect;\n } else {\n adjustedWidth = parent.clientHeight * aspect;\n adjustedHeight = parent.clientHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _applyDisplayMode() {\n this._setResolutionAndViewportByDisplayMode(this.parent);\n // watch resizing\n if (this.parent instanceof Window) this._browser.window.on(\"resize\", this._resizeHandler);\n else {\n this._resizeObserver = new ResizeObserver(()=>{\n this._resizeHandler();\n });\n this._resizeObserver.observe(this.parent);\n }\n this.parent.addEventListener(\"resize\", this._resizeHandler);\n }\n /**\n * Sets the resolution and viewport based on the selected display mode.\n */ _setResolutionAndViewportByDisplayMode(parent) {\n if (this.displayMode === DisplayMode.FillContainer) {\n this.resolution = {\n width: parent.clientWidth,\n height: parent.clientHeight\n };\n this.viewport = this.resolution;\n }\n if (this.displayMode === DisplayMode.FillScreen) {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.resolution = {\n width: parent.innerWidth,\n height: parent.innerHeight\n };\n this.viewport = this.resolution;\n }\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n if (this.displayMode === DisplayMode.FitScreen) this._computeFit();\n if (this.displayMode === DisplayMode.FitContainer) this._computeFitContainer();\n if (this.displayMode === DisplayMode.FitScreenAndFill) this._computeFitScreenAndFill();\n if (this.displayMode === DisplayMode.FitContainerAndFill) this._computeFitContainerAndFill();\n if (this.displayMode === DisplayMode.FitScreenAndZoom) this._computeFitScreenAndZoom();\n if (this.displayMode === DisplayMode.FitContainerAndZoom) this._computeFitContainerAndZoom();\n }\n }\n /**\n * Internal class used to build instances of AudioContext\n */ /* istanbul ignore next */ class AudioContextFactory {\n static create() {\n if (!this._INSTANCE) {\n if (window.AudioContext || window.webkitAudioContext) this._INSTANCE = new AudioContext();\n }\n return this._INSTANCE;\n }\n }\n AudioContextFactory._INSTANCE = null;\n /**\n * Patch for detecting legacy web audio in browsers\n * @internal\n * @param source\n */ function isLegacyWebAudioSource(source) {\n return !!source.playbackState;\n }\n class WebAudio {\n /**\n * Play an empty sound to unlock Safari WebAudio context. Call this function\n * right after a user interaction event.\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\n */ static unlock() {\n const promise = new Promise((resolve, reject)=>{\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) return resolve(true);\n const unlockTimeoutTimer = setTimeout(()=>{\n Logger.getInstance().warn(\"Excalibur was unable to unlock the audio context, audio probably will not play in this browser.\");\n resolve(false);\n }, 200);\n const audioContext = AudioContextFactory.create();\n audioContext.resume().then(()=>{\n // create empty buffer and play it\n const buffer = audioContext.createBuffer(1, 1, 22050);\n const source = audioContext.createBufferSource();\n let ended = false;\n source.buffer = buffer;\n source.connect(audioContext.destination);\n source.onended = ()=>ended = true;\n source.start(0);\n // by checking the play state after some time, we know if we're really unlocked\n setTimeout(()=>{\n if (isLegacyWebAudioSource(source)) {\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) WebAudio._UNLOCKED = true;\n } else if (audioContext.currentTime > 0 || ended) WebAudio._UNLOCKED = true;\n }, 0);\n clearTimeout(unlockTimeoutTimer);\n resolve(true);\n }, ()=>{\n reject();\n });\n });\n return promise;\n }\n static isUnlocked() {\n return this._UNLOCKED;\n }\n }\n WebAudio._UNLOCKED = false;\n /**\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\n *\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\n */ class Raster extends Graphic {\n constructor(options){\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;\n super(omit(options, [\n \"width\",\n \"height\"\n ])); // rasters do some special sauce with width/height\n this.filtering = null;\n this.lineCap = \"butt\";\n this.quality = 1;\n this._dirty = true;\n this._smoothing = false;\n this._color = watch(Color.Black, ()=>this.flagDirty());\n this._lineWidth = 1;\n this._lineDash = [];\n this._padding = 0;\n if (options) {\n this.quality = (_a = options.quality) !== null && _a !== void 0 ? _a : this.quality;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n this.strokeColor = options === null || options === void 0 ? void 0 : options.strokeColor;\n this.smoothing = (_c = options.smoothing) !== null && _c !== void 0 ? _c : this.smoothing;\n this.lineWidth = (_d = options.lineWidth) !== null && _d !== void 0 ? _d : this.lineWidth;\n this.lineDash = (_e = options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineCap = (_f = options.lineCap) !== null && _f !== void 0 ? _f : this.lineCap;\n this.padding = (_g = options.padding) !== null && _g !== void 0 ? _g : this.padding;\n this.filtering = (_h = options.filtering) !== null && _h !== void 0 ? _h : this.filtering;\n }\n this._bitmap = document.createElement(\"canvas\");\n // get the default canvas width/height as a fallback\n const bitmapWidth = (_j = options === null || options === void 0 ? void 0 : options.width) !== null && _j !== void 0 ? _j : this._bitmap.width;\n const bitmapHeight = (_k = options === null || options === void 0 ? void 0 : options.height) !== null && _k !== void 0 ? _k : this._bitmap.height;\n this.width = bitmapWidth;\n this.height = bitmapHeight;\n const maybeCtx = this._bitmap.getContext(\"2d\");\n if (!maybeCtx) /* istanbul ignore next */ throw new Error(\"Browser does not support 2d canvas drawing, cannot create Raster graphic\");\n else this._ctx = maybeCtx;\n }\n cloneRasterOptions() {\n return {\n color: this.color ? this.color.clone() : null,\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\n smoothing: this.smoothing,\n lineWidth: this.lineWidth,\n lineDash: this.lineDash,\n lineCap: this.lineCap,\n quality: this.quality,\n padding: this.padding\n };\n }\n /**\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\n */ get dirty() {\n return this._dirty;\n }\n /**\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\n * This should be called any time the graphics state changes such that it affects the outputted drawing\n */ flagDirty() {\n this._dirty = true;\n }\n /**\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n *\n * Any `padding`s or `quality` set will be factored into the width\n */ get width() {\n return Math.abs(this._getTotalWidth() * this.scale.x);\n }\n set width(value) {\n value /= Math.abs(this.scale.x);\n this._bitmap.width = value;\n this._originalWidth = value;\n this.flagDirty();\n }\n /**\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n *\n * Any `padding` or `quality` set will be factored into the height\n */ get height() {\n return Math.abs(this._getTotalHeight() * this.scale.y);\n }\n set height(value) {\n value /= Math.abs(this.scale.y);\n this._bitmap.height = value;\n this._originalHeight = value;\n this.flagDirty();\n }\n _getTotalWidth() {\n var _a;\n return (((_a = this._originalWidth) !== null && _a !== void 0 ? _a : this._bitmap.width) + this.padding * 2) * 1;\n }\n _getTotalHeight() {\n var _a;\n return (((_a = this._originalHeight) !== null && _a !== void 0 ? _a : this._bitmap.height) + this.padding * 2) * 1;\n }\n /**\n * Returns the local bounds of the Raster including the padding\n */ get localBounds() {\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\n }\n /**\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n */ get smoothing() {\n return this._smoothing;\n }\n set smoothing(value) {\n this._smoothing = value;\n this.flagDirty();\n }\n /**\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */ get color() {\n return this._color;\n }\n set color(value) {\n this.flagDirty();\n this._color = watch(value, ()=>this.flagDirty());\n }\n /**\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */ get strokeColor() {\n return this._strokeColor;\n }\n set strokeColor(value) {\n this.flagDirty();\n this._strokeColor = watch(value, ()=>this.flagDirty());\n }\n /**\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */ get lineWidth() {\n return this._lineWidth;\n }\n set lineWidth(value) {\n this._lineWidth = value;\n this.flagDirty();\n }\n get lineDash() {\n return this._lineDash;\n }\n set lineDash(value) {\n this._lineDash = value;\n this.flagDirty();\n }\n get padding() {\n return this._padding;\n }\n set padding(value) {\n this._padding = value;\n this.flagDirty();\n }\n /**\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\n */ rasterize() {\n this._dirty = false;\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\n this._ctx.save();\n this._applyRasterProperties(this._ctx);\n this.execute(this._ctx);\n this._ctx.restore();\n }\n _applyRasterProperties(ctx) {\n var _a, _b, _c;\n this._bitmap.width = this._getTotalWidth() * this.quality;\n this._bitmap.height = this._getTotalHeight() * this.quality;\n // Do a bad thing to pass the filtering as an attribute\n this._bitmap.setAttribute(\"filtering\", this.filtering);\n this._bitmap.setAttribute(\"forceUpload\", \"true\");\n ctx.scale(this.quality, this.quality);\n ctx.translate(this.padding, this.padding);\n ctx.imageSmoothingEnabled = this.smoothing;\n ctx.lineWidth = this.lineWidth;\n ctx.setLineDash((_a = this.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.lineCap = this.lineCap;\n ctx.strokeStyle = (_b = this.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = (_c = this.color) === null || _c === void 0 ? void 0 : _c.toString();\n }\n _drawImage(ex, x, y) {\n if (this._dirty) this.rasterize();\n ex.scale(1 / this.quality, 1 / this.quality);\n ex.drawImage(this._bitmap, x, y);\n }\n }\n /**\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\n *\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\n *\n * **Low performance API**\n */ class Canvas extends Raster {\n /**\n * Return the 2D graphics context of this canvas\n */ get ctx() {\n return this._ctx;\n }\n constructor(_options){\n super(_options);\n this._options = _options;\n }\n clone() {\n return new Canvas({\n ...this._options,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n var _a, _b;\n if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.draw) (_b = this._options) === null || _b === void 0 || _b.draw(ctx);\n if (!this._options.cache) this.flagDirty();\n }\n }\n class ExResponse {\n }\n ExResponse.type = {\n any: \"\",\n blob: \"blob\",\n json: \"json\",\n text: \"text\",\n document: \"document\",\n arraybuffer: \"arraybuffer\"\n };\n class StateMachine {\n constructor(){\n this.states = new Map();\n }\n get currentState() {\n return this._currentState;\n }\n set currentState(state) {\n this._currentState = state;\n }\n static create(machineDescription, data) {\n const machine = new StateMachine();\n machine.data = data;\n for(const stateName in machineDescription.states)machine.states.set(stateName, {\n name: stateName,\n ...machineDescription.states[stateName]\n });\n // validate transitions are states\n for (const state of machine.states.values())for (const transitionState of state.transitions){\n if (transitionState === \"*\") continue;\n if (!machine.states.has(transitionState)) throw Error(`Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`);\n }\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\n return machine;\n }\n in(state) {\n return this.currentState.name === state;\n }\n go(stateName, eventData) {\n var _a, _b;\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes(\"*\")) {\n const potentialNewState = this.states.get(stateName);\n if (this.currentState.onExit) {\n const canExit = (_a = this.currentState) === null || _a === void 0 ? void 0 : _a.onExit({\n to: potentialNewState.name,\n data: this.data\n });\n if (canExit === false) return false;\n }\n if (potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter) {\n const canEnter = potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter({\n from: this.currentState.name,\n eventData: eventData,\n data: this.data\n });\n if (canEnter === false) return false;\n }\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\n this.currentState = potentialNewState;\n if ((_b = this.currentState) === null || _b === void 0 ? void 0 : _b.onState) this.currentState.onState();\n return true;\n }\n return false;\n }\n update(elapsedMs) {\n if (this.currentState.onUpdate) this.currentState.onUpdate(this.data, elapsedMs);\n }\n save(saveKey) {\n localStorage.setItem(saveKey, JSON.stringify({\n currentState: this.currentState.name,\n data: this.data\n }));\n }\n restore(saveKey) {\n const state = JSON.parse(localStorage.getItem(saveKey));\n this.currentState = this.states.get(state.currentState);\n this.data = state.data;\n }\n }\n /**\n * Internal class representing a Web Audio AudioBufferSourceNode instance\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\n */ class WebAudioInstance {\n _createNewBufferSource() {\n this._instance = this._audioContext.createBufferSource();\n this._instance.buffer = this._src;\n this._instance.loop = this.loop;\n this._instance.playbackRate.value = this._playbackRate;\n this._instance.connect(this._volumeNode);\n this._volumeNode.connect(this._audioContext.destination);\n }\n _handleEnd() {\n if (!this.loop) this._instance.onended = ()=>{\n this._playingFuture.resolve(true);\n };\n }\n set loop(value) {\n this._loop = value;\n if (this._instance) {\n this._instance.loop = value;\n if (!this.loop) this._instance.onended = ()=>{\n this._playingFuture.resolve(true);\n };\n }\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n value = clamp(value, 0, 1.0);\n this._volume = value;\n if (this._stateMachine.in(\"PLAYING\") && this._volumeNode.gain.setTargetAtTime) // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\n // This exponential ramp provides a more pleasant transition in gain\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\n else this._volumeNode.gain.value = value;\n }\n get volume() {\n return this._volume;\n }\n /**\n * Returns the set duration to play, otherwise returns the total duration if unset\n */ get duration() {\n var _a;\n return (_a = this._duration) !== null && _a !== void 0 ? _a : this.getTotalPlaybackDuration();\n }\n /**\n * Set the duration that this audio should play.\n *\n * Note: if you seek to a specific point the duration will start from that point, for example\n *\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\n */ set duration(duration) {\n this._duration = duration;\n }\n constructor(_src){\n this._src = _src;\n this._audioContext = AudioContextFactory.create();\n this._volumeNode = this._audioContext.createGain();\n this._playingFuture = new Future();\n this._stateMachine = StateMachine.create({\n start: \"STOPPED\",\n states: {\n PLAYING: {\n onEnter: ({ data: data })=>{\n // Buffer nodes are single use\n this._createNewBufferSource();\n this._handleEnd();\n if (this.loop) // when looping don't set a duration\n this._instance.start(0, data.pausedAt * this._playbackRate);\n else this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\n data.startedAt = this._audioContext.currentTime - data.pausedAt;\n data.pausedAt = 0;\n },\n onState: ()=>this._playStarted(),\n onExit: ({ to: to })=>{\n // If you've exited early only resolve if explicitly STOPPED\n if (to === \"STOPPED\") this._playingFuture.resolve(true);\n // Whenever you're not playing... you stop!\n this._instance.onended = null; // disconnect the wired on-end handler\n this._instance.disconnect();\n this._instance.stop(0);\n this._instance = null;\n },\n transitions: [\n \"STOPPED\",\n \"PAUSED\",\n \"SEEK\"\n ]\n },\n SEEK: {\n onEnter: ({ eventData: position, data: data })=>{\n data.pausedAt = (position !== null && position !== void 0 ? position : 0) / this._playbackRate;\n data.startedAt = 0;\n },\n transitions: [\n \"*\"\n ]\n },\n STOPPED: {\n onEnter: ({ data: data })=>{\n data.pausedAt = 0;\n data.startedAt = 0;\n this._playingFuture.resolve(true);\n },\n transitions: [\n \"PLAYING\",\n \"PAUSED\",\n \"SEEK\"\n ]\n },\n PAUSED: {\n onEnter: ({ data: data })=>{\n // Playback rate will be a scale factor of how fast/slow the audio is being played\n // default is 1.0\n // we need to invert it to get the time scale\n data.pausedAt = this._audioContext.currentTime - data.startedAt;\n },\n transitions: [\n \"PLAYING\",\n \"STOPPED\",\n \"SEEK\"\n ]\n }\n }\n }, {\n startedAt: 0,\n pausedAt: 0\n });\n this._volume = 1;\n this._loop = false;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n this._playStarted = ()=>{};\n this._playbackRate = 1.0;\n this._createNewBufferSource();\n }\n isPlaying() {\n return this._stateMachine.in(\"PLAYING\");\n }\n isPaused() {\n return this._stateMachine.in(\"PAUSED\") || this._stateMachine.in(\"SEEK\");\n }\n isStopped() {\n return this._stateMachine.in(\"STOPPED\");\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n play(playStarted = ()=>{}) {\n this._playStarted = playStarted;\n this._stateMachine.go(\"PLAYING\");\n return this._playingFuture.promise;\n }\n pause() {\n this._stateMachine.go(\"PAUSED\");\n }\n stop() {\n this._stateMachine.go(\"STOPPED\");\n }\n seek(position) {\n this._stateMachine.go(\"PAUSED\");\n this._stateMachine.go(\"SEEK\", position);\n }\n getTotalPlaybackDuration() {\n return this._src.duration;\n }\n getPlaybackPosition() {\n const { pausedAt: pausedAt, startedAt: startedAt } = this._stateMachine.data;\n if (pausedAt) return pausedAt * this._playbackRate;\n if (startedAt) return (this._audioContext.currentTime - startedAt) * this._playbackRate;\n return 0;\n }\n set playbackRate(playbackRate) {\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\n }\n get playbackRate() {\n return this._instance.playbackRate.value;\n }\n }\n var EventTypes;\n (function(EventTypes) {\n EventTypes[\"Kill\"] = \"kill\";\n EventTypes[\"PreKill\"] = \"prekill\";\n EventTypes[\"PostKill\"] = \"postkill\";\n EventTypes[\"PreDraw\"] = \"predraw\";\n EventTypes[\"PostDraw\"] = \"postdraw\";\n EventTypes[\"PreDebugDraw\"] = \"predebugdraw\";\n EventTypes[\"PostDebugDraw\"] = \"postdebugdraw\";\n EventTypes[\"PreUpdate\"] = \"preupdate\";\n EventTypes[\"PostUpdate\"] = \"postupdate\";\n EventTypes[\"PreFrame\"] = \"preframe\";\n EventTypes[\"PostFrame\"] = \"postframe\";\n EventTypes[\"PreCollision\"] = \"precollision\";\n EventTypes[\"CollisionStart\"] = \"collisionstart\";\n EventTypes[\"CollisionEnd\"] = \"collisionend\";\n EventTypes[\"PostCollision\"] = \"postcollision\";\n EventTypes[\"Initialize\"] = \"initialize\";\n EventTypes[\"Activate\"] = \"activate\";\n EventTypes[\"Deactivate\"] = \"deactivate\";\n EventTypes[\"ExitViewport\"] = \"exitviewport\";\n EventTypes[\"EnterViewport\"] = \"enterviewport\";\n EventTypes[\"ExitTrigger\"] = \"exit\";\n EventTypes[\"EnterTrigger\"] = \"enter\";\n EventTypes[\"Connect\"] = \"connect\";\n EventTypes[\"Disconnect\"] = \"disconnect\";\n EventTypes[\"Button\"] = \"button\";\n EventTypes[\"Axis\"] = \"axis\";\n EventTypes[\"Visible\"] = \"visible\";\n EventTypes[\"Hidden\"] = \"hidden\";\n EventTypes[\"Start\"] = \"start\";\n EventTypes[\"Stop\"] = \"stop\";\n EventTypes[\"PointerUp\"] = \"pointerup\";\n EventTypes[\"PointerDown\"] = \"pointerdown\";\n EventTypes[\"PointerMove\"] = \"pointermove\";\n EventTypes[\"PointerEnter\"] = \"pointerenter\";\n EventTypes[\"PointerLeave\"] = \"pointerleave\";\n EventTypes[\"PointerCancel\"] = \"pointercancel\";\n EventTypes[\"PointerWheel\"] = \"pointerwheel\";\n EventTypes[\"Up\"] = \"up\";\n EventTypes[\"Down\"] = \"down\";\n EventTypes[\"Move\"] = \"move\";\n EventTypes[\"Enter\"] = \"enter\";\n EventTypes[\"Leave\"] = \"leave\";\n EventTypes[\"Cancel\"] = \"cancel\";\n EventTypes[\"Wheel\"] = \"wheel\";\n EventTypes[\"Press\"] = \"press\";\n EventTypes[\"Release\"] = \"release\";\n EventTypes[\"Hold\"] = \"hold\";\n EventTypes[\"PointerDragStart\"] = \"pointerdragstart\";\n EventTypes[\"PointerDragEnd\"] = \"pointerdragend\";\n EventTypes[\"PointerDragEnter\"] = \"pointerdragenter\";\n EventTypes[\"PointerDragLeave\"] = \"pointerdragleave\";\n EventTypes[\"PointerDragMove\"] = \"pointerdragmove\";\n EventTypes[\"ActionStart\"] = \"actionstart\";\n EventTypes[\"ActionComplete\"] = \"actioncomplete\";\n })(EventTypes || (EventTypes = {}));\n /**\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\n * some events are unique to a type, others are not.\n *\n */ class GameEvent {\n constructor(){\n this._bubbles = true;\n }\n /**\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\n * to all actors that apply.\n */ get bubbles() {\n return this._bubbles;\n }\n set bubbles(value) {\n this._bubbles = value;\n }\n /**\n * Prevents event from bubbling\n */ stopPropagation() {\n this.bubbles = false;\n }\n }\n /**\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\n */ class KillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'prekill' event is emitted directly before an actor is killed.\n */ class PreKillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'postkill' event is emitted directly after the actor is killed.\n */ class PostKillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'start' event is emitted on engine when has started and is ready for interaction.\n */ class GameStartEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\n */ class GameStopEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\n * transform so that all drawing takes place with the actor as the origin.\n *\n */ class PreDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\n * transform so that all drawing takes place with the actor as the origin.\n *\n */ class PostDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'pretransformdraw' event is emitted on actors/entities before any graphics transforms have taken place.\n * Useful if you need to completely customize the draw or modify the transform before drawing in the draw step (for example needing\n * latest camera positions)\n *\n */ class PreTransformDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'posttransformdraw' event is emitted on actors/entities after all graphics have been draw and transforms reset.\n * Useful if you need to completely custom the draw after everything is done.\n *\n */ class PostTransformDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\n */ class PreDebugDrawEvent extends GameEvent {\n constructor(ctx, target){\n super();\n this.ctx = ctx;\n this.target = target;\n }\n }\n /**\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\n */ class PostDebugDrawEvent extends GameEvent {\n constructor(ctx, target){\n super();\n this.ctx = ctx;\n this.target = target;\n }\n }\n /**\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\n */ class PreUpdateEvent extends GameEvent {\n constructor(engine, delta, target){\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\n */ class PostUpdateEvent extends GameEvent {\n constructor(engine, delta, target){\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\n * The 'preframe' event is emitted on the engine, before the frame begins.\n */ class PreFrameEvent extends GameEvent {\n constructor(engine, prevStats){\n super();\n this.engine = engine;\n this.prevStats = prevStats;\n this.target = engine;\n }\n }\n /**\n * The 'postframe' event is emitted on the engine, after a frame ends.\n */ class PostFrameEvent extends GameEvent {\n constructor(engine, stats){\n super();\n this.engine = engine;\n this.stats = stats;\n this.target = engine;\n }\n }\n /**\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\n */ class GamepadConnectEvent extends GameEvent {\n constructor(index, gamepad){\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n }\n /**\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\n */ class GamepadDisconnectEvent extends GameEvent {\n constructor(index, gamepad){\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n }\n /**\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\n */ class GamepadButtonEvent extends GameEvent {\n /**\n * @param button The Gamepad button\n * @param value A numeric value between 0 and 1\n */ constructor(button, value, target){\n super();\n this.button = button;\n this.value = value;\n this.target = target;\n }\n }\n /**\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\n */ class GamepadAxisEvent extends GameEvent {\n /**\n * @param axis The Gamepad axis\n * @param value A numeric value between -1 and 1\n */ constructor(axis, value, target){\n super();\n this.axis = axis;\n this.value = value;\n this.target = target;\n }\n }\n /**\n * Event received by the [[Engine]] when the browser window is visible on a screen.\n */ class VisibleEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\n */ class HiddenEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\n */ class PreCollisionEvent extends GameEvent {\n /**\n * @param actor The actor the event was thrown on\n * @param other The actor that will collided with the current actor\n * @param side The side that will be collided with the current actor\n * @param intersection Intersection vector\n */ constructor(actor, other, side, intersection, contact){\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n this.target = actor;\n }\n }\n /**\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\n */ class PostCollisionEvent extends GameEvent {\n /**\n * @param actor The actor the event was thrown on\n * @param other The actor that did collide with the current actor\n * @param side The side that did collide with the current actor\n * @param intersection Intersection vector\n */ constructor(actor, other, side, intersection, contact){\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n class ContactStartEvent {\n constructor(target, other, side, contact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.contact = contact;\n }\n }\n class ContactEndEvent {\n constructor(target, other, side, lastContact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.lastContact = lastContact;\n }\n }\n class CollisionPreSolveEvent {\n constructor(target, other, side, intersection, contact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n }\n class CollisionPostSolveEvent {\n constructor(target, other, side, intersection, contact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n }\n /**\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\n */ class CollisionStartEvent extends GameEvent {\n /**\n *\n * @param actor\n * @param other\n * @param side\n * @param contact\n */ constructor(actor, other, side, contact){\n super();\n this.other = other;\n this.side = side;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n /**\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\n */ class CollisionEndEvent extends GameEvent {\n /**\n *\n */ constructor(actor, other, side, lastContact){\n super();\n this.other = other;\n this.side = side;\n this.lastContact = lastContact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n /**\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\n */ class InitializeEvent extends GameEvent {\n /**\n * @param engine The reference to the current engine\n */ constructor(engine, target){\n super();\n this.engine = engine;\n this.target = target;\n }\n }\n /**\n * Event thrown on a [[Scene]] on activation\n */ class ActivateEvent extends GameEvent {\n /**\n * @param context The context for the scene activation\n */ constructor(context, target){\n super();\n this.context = context;\n this.target = target;\n }\n }\n /**\n * Event thrown on a [[Scene]] on deactivation\n */ class DeactivateEvent extends GameEvent {\n /**\n * @param context The context for the scene deactivation\n */ constructor(context, target){\n super();\n this.context = context;\n this.target = target;\n }\n }\n /**\n * Event thrown on an [[Actor]] when the graphics bounds completely leaves the screen.\n */ class ExitViewPortEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\n * Event thrown on an [[Actor]] when any part of the graphics bounds are on screen.\n */ class EnterViewPortEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n class EnterTriggerEvent extends GameEvent {\n constructor(target, actor){\n super();\n this.target = target;\n this.actor = actor;\n }\n }\n class ExitTriggerEvent extends GameEvent {\n constructor(target, actor){\n super();\n this.target = target;\n this.actor = actor;\n }\n }\n /**\n * Event thrown on an [[Actor]] when an action starts.\n */ class ActionStartEvent extends GameEvent {\n constructor(action, target){\n super();\n this.action = action;\n this.target = target;\n }\n }\n /**\n * Event thrown on an [[Actor]] when an action completes.\n */ class ActionCompleteEvent extends GameEvent {\n constructor(action, target){\n super();\n this.action = action;\n this.target = target;\n }\n }\n class MediaEvent extends GameEvent {\n /**\n * Media event cannot bubble\n */ set bubbles(_value) {\n // stubbed\n }\n /**\n * Media event cannot bubble\n */ get bubbles() {\n return false;\n }\n /**\n * Media event cannot bubble, so they have no path\n */ get _path() {\n return null;\n }\n /**\n * Media event cannot bubble, so they have no path\n */ set _path(_val) {\n // stubbed\n }\n constructor(target, _name = \"MediaEvent\"){\n super();\n this.target = target;\n this._name = _name;\n }\n /**\n * Prevents event from bubbling\n */ stopPropagation() {\n /**\n * Stub\n */ }\n /**\n * Action, that calls when event happens\n */ action() {\n /**\n * Stub\n */ }\n /**\n * Propagate event further through event path\n */ propagate() {\n /**\n * Stub\n */ }\n layPath(_actor) {\n /**\n * Stub\n */ }\n }\n class NativeSoundEvent extends MediaEvent {\n constructor(target, track){\n super(target, \"NativeSoundEvent\");\n this.track = track;\n }\n }\n class NativeSoundProcessedEvent extends MediaEvent {\n constructor(target, _processedData){\n super(target, \"NativeSoundProcessedEvent\");\n this._processedData = _processedData;\n this.data = this._processedData;\n }\n }\n /**\n * Whether or not the browser can play this file as HTML5 Audio\n */ function canPlayFile(file) {\n try {\n const a = new Audio();\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\n const type = file.match(filetype)[1];\n if (a.canPlayType(\"audio/\" + type)) return true;\n else return false;\n } catch (e) {\n Logger.getInstance().warn(\"Cannot determine audio support, assuming no support for the Audio Tag\", e);\n return false;\n }\n }\n const SoundEvents = {\n VolumeChange: \"volumechange\",\n Processed: \"processed\",\n Pause: \"pause\",\n Stop: \"stop\",\n PlaybackEnd: \"playbackend\",\n Resume: \"resume\",\n PlaybackStart: \"playbackstart\"\n };\n /**\n * The [[Sound]] object allows games built in Excalibur to load audio\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\n */ class Sound {\n /**\n * Indicates whether the clip should loop when complete\n * @param value Set the looping flag\n */ set loop(value) {\n this._loop = value;\n for (const track of this._tracks)track.loop = this._loop;\n this.logger.debug(\"Set loop for all instances of sound\", this.path, \"to\", this._loop);\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n this._volume = value;\n for (const track of this._tracks)track.volume = this._volume;\n this.events.emit(\"volumechange\", new NativeSoundEvent(this));\n this.logger.debug(\"Set loop for all instances of sound\", this.path, \"to\", this._volume);\n }\n get volume() {\n return this._volume;\n }\n /**\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\n */ get duration() {\n return this._duration;\n }\n /**\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\n *\n * Note: if you seek to a specific point the duration will start from that point, for example\n *\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\n */ set duration(duration) {\n this._duration = duration;\n }\n /**\n * Return array of Current AudioInstances playing or being paused\n */ get instances() {\n return this._tracks;\n }\n get path() {\n return this._resource.path;\n }\n set path(val) {\n this._resource.path = val;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\n */ constructor(...paths){\n this.events = new EventEmitter();\n this.logger = Logger.getInstance();\n this._loop = false;\n this._volume = 1;\n this._isStopped = false;\n // private _isPaused = false;\n this._tracks = [];\n this._wasPlayingOnHidden = false;\n this._playbackRate = 1.0;\n this._audioContext = AudioContextFactory.create();\n this._resource = new Resource(\"\", ExResponse.type.arraybuffer);\n /**\n * Chrome : MP3, WAV, Ogg\n * Firefox : WAV, Ogg,\n * IE : MP3, WAV coming soon\n * Safari MP3, WAV, Ogg\n */ for (const path of paths)if (canPlayFile(path)) {\n this.path = path;\n break;\n }\n if (!this.path) {\n this.logger.warn(\"This browser does not support any of the audio files specified:\", paths.join(\", \"));\n this.logger.warn(\"Attempting to use\", paths[0]);\n this.path = paths[0]; // select the first specified\n }\n }\n isLoaded() {\n return !!this.data;\n }\n async load() {\n var _a, _b;\n if (this.data) return this.data;\n const arraybuffer = await this._resource.load();\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\n this._duration = (_b = (_a = this._duration) !== null && _a !== void 0 ? _a : audiobuffer === null || audiobuffer === void 0 ? void 0 : audiobuffer.duration) !== null && _b !== void 0 ? _b : undefined;\n this.events.emit(\"processed\", new NativeSoundProcessedEvent(this, audiobuffer));\n return this.data = audiobuffer;\n }\n async decodeAudio(data) {\n try {\n return await this._audioContext.decodeAudioData(data.slice(0));\n } catch (e) {\n this.logger.error(\"Unable to decode this browser may not fully support this format, or the file may be corrupt, if this is an mp3 try removing id3 tags and album art from the file.\");\n return await Promise.reject();\n }\n }\n wireEngine(engine) {\n if (engine) {\n this._engine = engine;\n this._engine.on(\"hidden\", ()=>{\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\n this._wasPlayingOnHidden = true;\n this.pause();\n }\n });\n this._engine.on(\"visible\", ()=>{\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.play();\n this._wasPlayingOnHidden = false;\n }\n });\n this._engine.on(\"start\", ()=>{\n this._isStopped = false;\n });\n this._engine.on(\"stop\", ()=>{\n this.stop();\n this._isStopped = true;\n });\n }\n }\n /**\n * Returns how many instances of the sound are currently playing\n */ instanceCount() {\n return this._tracks.length;\n }\n /**\n * Whether or not the sound is playing right now\n */ isPlaying() {\n return this._tracks.some((t)=>t.isPlaying());\n }\n isPaused() {\n return this._tracks.some((t)=>t.isPaused());\n }\n isStopped() {\n return this._tracks.some((t)=>t.isStopped());\n }\n /**\n * Play the sound, returns a promise that resolves when the sound is done playing\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\n */ play(volume) {\n if (!this.isLoaded()) {\n this.logger.warn(\"Cannot start playing. Resource\", this.path, \"is not loaded yet\");\n return Promise.resolve(true);\n }\n if (this._isStopped) {\n this.logger.warn(\"Cannot start playing. Engine is in a stopped state.\");\n return Promise.resolve(false);\n }\n this.volume = volume || this.volume;\n if (this.isPaused()) return this._resumePlayback();\n else return this._startPlayback();\n }\n /**\n * Stop the sound, and do not rewind\n */ pause() {\n if (!this.isPlaying()) return;\n for (const track of this._tracks)track.pause();\n this.events.emit(\"pause\", new NativeSoundEvent(this));\n this.logger.debug(\"Paused all instances of sound\", this.path);\n }\n /**\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\n */ stop() {\n for (const track of this._tracks)track.stop();\n this.events.emit(\"stop\", new NativeSoundEvent(this));\n this._tracks.length = 0;\n this.logger.debug(\"Stopped all instances of sound\", this.path);\n }\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(playbackRate) {\n this._playbackRate = playbackRate;\n this._tracks.forEach((t)=>{\n t.playbackRate = this._playbackRate;\n });\n }\n seek(position, trackId = 0) {\n if (this._tracks.length === 0) this._getTrackInstance(this.data);\n this._tracks[trackId].seek(position);\n }\n getTotalPlaybackDuration() {\n if (!this.isLoaded()) {\n this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.` + `Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`);\n return 0;\n }\n return this.data.duration;\n }\n /**\n * Return the current playback time of the playing track in seconds from the start.\n *\n * Optionally specify the track to query if multiple are playing at once.\n * @param trackId\n */ getPlaybackPosition(trackId = 0) {\n if (this._tracks.length) return this._tracks[trackId].getPlaybackPosition();\n return 0;\n }\n /**\n * Get Id of provided AudioInstance in current trackList\n * @param track [[Audio]] which Id is to be given\n */ getTrackId(track) {\n return this._tracks.indexOf(track);\n }\n async _resumePlayback() {\n if (this.isPaused) {\n const resumed = [];\n // ensure we resume *current* tracks (if paused)\n for (const track of this._tracks)resumed.push(track.play().then(()=>{\n this._tracks.splice(this.getTrackId(track), 1);\n return true;\n }));\n this.events.emit(\"resume\", new NativeSoundEvent(this));\n this.logger.debug(\"Resuming paused instances for sound\", this.path, this._tracks);\n // resolve when resumed tracks are done\n await Promise.all(resumed);\n }\n return true;\n }\n /**\n * Starts playback, returns a promise that resolves when playback is complete\n */ async _startPlayback() {\n const track = this._getTrackInstance(this.data);\n const complete = await track.play(()=>{\n this.events.emit(\"playbackstart\", new NativeSoundEvent(this, track));\n this.logger.debug(\"Playing new instance for sound\", this.path);\n });\n this.events.emit(\"playbackend\", new NativeSoundEvent(this, track));\n // cleanup any done tracks\n const trackId = this.getTrackId(track);\n if (trackId !== -1) this._tracks.splice(trackId, 1);\n return complete;\n }\n _getTrackInstance(data) {\n const newTrack = new WebAudioInstance(data);\n newTrack.loop = this.loop;\n newTrack.volume = this.volume;\n newTrack.duration = this.duration;\n newTrack.playbackRate = this._playbackRate;\n this._tracks.push(newTrack);\n return newTrack;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n const LoaderEvents = {\n // Add event types here\n BeforeLoad: \"beforeload\",\n AfterLoad: \"afterload\",\n UserAction: \"useraction\",\n LoadResourceStart: \"loadresourcestart\",\n LoadResourceEnd: \"loadresourceend\"\n };\n /**\n * Returns true if the constructor is for an Excalibur Loader\n */ function isLoaderConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n }\n class DefaultLoader {\n get resources() {\n return this._resources;\n }\n /**\n * @param options Optionally provide the list of resources you want to load at constructor time\n */ constructor(options){\n var _a;\n this.events = new EventEmitter();\n this.canvas = new Canvas({\n filtering: ImageFiltering.Blended,\n smoothing: true,\n cache: false,\n draw: this.onDraw.bind(this)\n });\n this._resources = [];\n this._numLoaded = 0;\n this._totalTimeMs = 0;\n this._loadingFuture = new Future();\n if (options && ((_a = options.loadables) === null || _a === void 0 ? void 0 : _a.length)) this.addResources(options.loadables);\n }\n /**\n * Called by the engine before loading\n * @param engine\n */ onInitialize(engine) {\n this.engine = engine;\n this.canvas.width = this.engine.screen.canvasWidth;\n this.canvas.height = this.engine.screen.canvasHeight;\n }\n /**\n * Return a promise that resolves when the user interacts with the loading screen in some way, usually a click.\n *\n * It's important to implement this in order to unlock the audio context in the browser. Browsers automatically prevent\n * audio from playing until the user performs an action.\n *\n */ async onUserAction() {\n return await Promise.resolve();\n }\n /**\n * Overridable lifecycle method, called directly before loading starts\n */ async onBeforeLoad() {\n // override me\n }\n /**\n * Overridable lifecycle method, called after loading has completed\n */ async onAfterLoad() {\n // override me\n await delay(500, this.engine.clock); // avoid a flicker\n }\n /**\n * Add a resource to the loader to load\n * @param loadable Resource to add\n */ addResource(loadable) {\n this._resources.push(loadable);\n }\n /**\n * Add a list of resources to the loader to load\n * @param loadables The list of resources to load\n */ addResources(loadables) {\n let i = 0;\n const len = loadables.length;\n for(i; i < len; i++)this.addResource(loadables[i]);\n }\n markResourceComplete() {\n this._numLoaded++;\n }\n /**\n * Returns the progress of the loader as a number between [0, 1] inclusive.\n */ get progress() {\n const total = this._resources.length;\n return total > 0 ? clamp(this._numLoaded, 0, total) / total : 1;\n }\n /**\n * Returns true if the loader has completely loaded all resources\n */ isLoaded() {\n return this._numLoaded === this._resources.length;\n }\n /**\n * Optionally override the onUpdate\n * @param engine\n * @param elapsedMilliseconds\n */ onUpdate(engine, elapsedMilliseconds) {\n this._totalTimeMs += elapsedMilliseconds;\n // override me\n }\n /**\n * Optionally override the onDraw\n */ onDraw(ctx) {\n const seconds = this._totalTimeMs / 1000;\n ctx.fillStyle = Color.Black.toRGBA();\n ctx.fillRect(0, 0, this.engine.screen.drawWidth, this.engine.screen.drawHeight);\n ctx.save();\n ctx.translate(this.engine.screen.center.x, this.engine.screen.center.y);\n const speed = seconds * 10;\n ctx.strokeStyle = \"white\";\n ctx.lineWidth = 10;\n ctx.lineCap = \"round\";\n ctx.arc(0, 0, 40, speed, speed + Math.PI * 3 / 2);\n ctx.stroke();\n ctx.fillStyle = \"white\";\n ctx.font = \"16px sans-serif\";\n const text = (this.progress * 100).toFixed(0) + \"%\";\n const textbox = ctx.measureText(text);\n const width = Math.abs(textbox.actualBoundingBoxLeft) + Math.abs(textbox.actualBoundingBoxRight);\n const height = Math.abs(textbox.actualBoundingBoxAscent) + Math.abs(textbox.actualBoundingBoxDescent);\n ctx.fillText(text, -width / 2, height / 2); // center\n ctx.restore();\n }\n areResourcesLoaded() {\n return this._loadingFuture.promise;\n }\n /**\n * Not meant to be overridden\n *\n * Begin loading all of the supplied resources, returning a promise\n * that resolves when loading of all is complete AND the user has interacted with the loading screen\n */ async load() {\n await this.onBeforeLoad();\n this.events.emit(\"beforeload\");\n this.canvas.flagDirty();\n await Promise.all(this._resources.map(async (r)=>{\n this.events.emit(\"loadresourcestart\", r);\n await r.load().finally(()=>{\n // capture progress\n this._numLoaded++;\n this.canvas.flagDirty();\n this.events.emit(\"loadresourceend\", r);\n });\n }));\n // Wire all sound to the engine\n for (const resource of this._resources)if (resource instanceof Sound) resource.wireEngine(this.engine);\n this._loadingFuture.resolve();\n this.canvas.flagDirty();\n // Unlock browser AudioContext in after user gesture\n // See: https://github.com/excaliburjs/Excalibur/issues/262\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\n await this.onUserAction();\n this.events.emit(\"useraction\");\n await WebAudio.unlock();\n await this.onAfterLoad();\n this.events.emit(\"afterload\");\n return this.data = this._resources;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n /* istanbul ignore next */ /**\n * Draw a line on canvas context\n * @param ctx The canvas context\n * @param color The color of the line\n * @param x1 The start x coordinate\n * @param y1 The start y coordinate\n * @param x2 The ending x coordinate\n * @param y2 The ending y coordinate\n * @param thickness The line thickness\n * @param cap The [[LineCapStyle]] (butt, round, or square)\n */ function line(ctx, color = Color.Red, x1, y1, x2, y2, thickness = 1, cap = \"butt\") {\n ctx.save();\n ctx.beginPath();\n ctx.lineWidth = thickness;\n ctx.lineCap = cap;\n ctx.strokeStyle = color.toString();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.closePath();\n ctx.stroke();\n ctx.restore();\n }\n /* istanbul ignore next */ /**\n * Draw the vector as a point onto the canvas.\n */ function point(ctx, color = Color.Red, point) {\n ctx.beginPath();\n ctx.strokeStyle = color.toString();\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\n ctx.closePath();\n ctx.stroke();\n }\n /**\n * Draw the vector as a line onto the canvas starting a origin point.\n */ /* istanbul ignore next */ /**\n *\n */ function vector(ctx, color, origin, vector, scale = 1.0) {\n const c = color ? color.toString() : \"blue\";\n const v = vector.scale(scale);\n ctx.beginPath();\n ctx.strokeStyle = c;\n ctx.moveTo(origin.x, origin.y);\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\n ctx.closePath();\n ctx.stroke();\n }\n /**\n * Draw a round rectangle on a canvas context\n * @param ctx The canvas context\n * @param x The top-left x coordinate\n * @param y The top-left y coordinate\n * @param width The width of the rectangle\n * @param height The height of the rectangle\n * @param radius The border radius of the rectangle\n * @param stroke The [[Color]] to stroke rectangle with\n * @param fill The [[Color]] to fill rectangle with\n */ function roundRect(ctx, x, y, width, height, radius = 5, stroke = Color.White, fill = null) {\n let br;\n if (typeof radius === \"number\") br = {\n tl: radius,\n tr: radius,\n br: radius,\n bl: radius\n };\n else {\n const defaultRadius = {\n tl: 0,\n tr: 0,\n br: 0,\n bl: 0\n };\n for(const prop in defaultRadius)if (defaultRadius.hasOwnProperty(prop)) {\n const side = prop;\n br[side] = radius[side] || defaultRadius[side];\n }\n }\n ctx.beginPath();\n ctx.moveTo(x + br.tl, y);\n ctx.lineTo(x + width - br.tr, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\n ctx.lineTo(x + width, y + height - br.br);\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\n ctx.lineTo(x + br.bl, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\n ctx.lineTo(x, y + br.tl);\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n }\n /**\n *\n */ function circle(ctx, x, y, radius, stroke = Color.White, fill = null) {\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, Math.PI * 2);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n }\n /* harmony default export */ const Loader_logo = \"data:image/png;base64,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\";\n // EXTERNAL MODULE: ./Director/Loader.css\n var Director_Loader = $2c23f148d58cd887$var$__webpack_require__(7835);\n /**\n * Pre-loading assets\n *\n * The loader provides a mechanism to preload multiple resources at\n * one time. The loader must be passed to the engine in order to\n * trigger the loading progress bar.\n *\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\n *\n * ## Example: Pre-loading resources for a game\n *\n * ```js\n * // create a loader\n * var loader = new ex.Loader();\n *\n * // create a resource dictionary (best practice is to keep a separate file)\n * var resources = {\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\n * };\n *\n * // loop through dictionary and add to loader\n * for (var loadable in resources) {\n * if (resources.hasOwnProperty(loadable)) {\n * loader.addResource(resources[loadable]);\n * }\n * }\n *\n * // start game\n * game.start(loader).then(function () {\n * console.log(\"Game started!\");\n * });\n * ```\n *\n * ## Customize the Loader\n *\n * The loader can be customized to show different, text, logo, background color, and button.\n *\n * ```typescript\n * const loader = new ex.Loader([playerTexture]);\n *\n * // The loaders button text can simply modified using this\n * loader.playButtonText = 'Start the best game ever';\n *\n * // The logo can be changed by inserting a base64 image string here\n *\n * loader.logo = 'data:image/png;base64,iVBORw...';\n * loader.logoWidth = 15;\n * loader.logoHeight = 14;\n *\n * // The background color can be changed like so by supplying a valid CSS color string\n *\n * loader.backgroundColor = 'red'\n * loader.backgroundColor = '#176BAA'\n *\n * // To build a completely new button\n * loader.startButtonFactory = () => {\n * let myButton = document.createElement('button');\n * myButton.textContent = 'The best button';\n * return myButton;\n * };\n *\n * engine.start(loader).then(() => {});\n * ```\n */ class Loader extends DefaultLoader {\n get _image() {\n if (!this._imageElement) {\n this._imageElement = new Image();\n this._imageElement.src = this.logo;\n }\n return this._imageElement;\n }\n get playButtonRootElement() {\n return this._playButtonRootElement;\n }\n get playButtonElement() {\n return this._playButtonElement;\n }\n get _playButton() {\n const existingRoot = document.getElementById(\"excalibur-play-root\");\n if (existingRoot) this._playButtonRootElement = existingRoot;\n if (!this._playButtonRootElement) {\n this._playButtonRootElement = document.createElement(\"div\");\n this._playButtonRootElement.id = \"excalibur-play-root\";\n this._playButtonRootElement.style.position = \"absolute\";\n document.body.appendChild(this._playButtonRootElement);\n }\n if (!this._styleBlock) {\n this._styleBlock = document.createElement(\"style\");\n this._styleBlock.textContent = this._playButtonStyles;\n document.head.appendChild(this._styleBlock);\n }\n if (!this._playButtonElement) {\n this._playButtonElement = this.startButtonFactory();\n this._playButtonRootElement.appendChild(this._playButtonElement);\n }\n return this._playButtonElement;\n }\n constructor(loadablesOrOptions){\n const options = Array.isArray(loadablesOrOptions) ? {\n loadables: loadablesOrOptions\n } : loadablesOrOptions;\n super(options);\n this._logger = Logger.getInstance();\n this._originalOptions = {\n loadables: []\n };\n this.events = new EventEmitter();\n this._playButtonShown = false;\n // logo drawing stuff\n // base64 string encoding of the excalibur logo (logo-white.png)\n this.logo = Loader_logo;\n this.logoWidth = 468;\n this.logoHeight = 118;\n /**\n * Gets or sets the color of the loading bar, default is [[Color.White]]\n */ this.loadingBarColor = Color.White;\n /**\n * Gets or sets the background color of the loader as a hex string\n */ this.backgroundColor = \"#176BAA\";\n this.suppressPlayButton = false;\n /** Loads the css from Loader.css */ this._playButtonStyles = Director_Loader /* default */ .Z.toString();\n /**\n * Get/set play button text\n */ this.playButtonText = \"Play game\";\n /**\n * Return a html button element for excalibur to use as a play button\n */ this.startButtonFactory = ()=>{\n let buttonElement = document.getElementById(\"excalibur-play\");\n if (!buttonElement) buttonElement = document.createElement(\"button\");\n buttonElement.id = \"excalibur-play\";\n buttonElement.textContent = this.playButtonText;\n buttonElement.style.display = \"none\";\n return buttonElement;\n };\n this._configuredPixelRatio = null;\n this._originalOptions = {\n ...Loader._DEFAULT_LOADER_OPTIONS,\n ...options\n };\n }\n onInitialize(engine) {\n this.engine = engine;\n this.screen = engine.screen;\n this.canvas.width = this.engine.canvas.width;\n this.canvas.height = this.engine.canvas.height;\n }\n /**\n * Shows the play button and returns a promise that resolves when clicked\n */ async showPlayButton() {\n var _a, _b;\n if (this.suppressPlayButton) {\n this.hidePlayButton();\n // Delay is to give the logo a chance to show, otherwise don't delay\n await delay(500, (_a = this.engine) === null || _a === void 0 ? void 0 : _a.clock);\n } else {\n const resizeHandler = ()=>{\n try {\n this._positionPlayButton();\n } catch (_a) {\n // swallow if can't position\n }\n };\n if ((_b = this.engine) === null || _b === void 0 ? void 0 : _b.browser) this.engine.browser.window.on(\"resize\", resizeHandler);\n this._playButtonShown = true;\n this._playButton.style.display = \"block\";\n document.body.addEventListener(\"keyup\", (evt)=>{\n if (evt.key === \"Enter\") this._playButton.click();\n });\n this._positionPlayButton();\n const playButtonClicked = new Promise((resolve)=>{\n const startButtonHandler = (e)=>{\n var _a;\n // We want to stop propagation to keep bubbling to the engine pointer handlers\n e.stopPropagation();\n // Hide Button after click\n this.hidePlayButton();\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.browser) this.engine.browser.window.off(\"resize\", resizeHandler);\n if (this._originalOptions.fullscreenAfterLoad) try {\n this._logger.info(\"requesting fullscreen\");\n if (this._originalOptions.fullscreenContainer instanceof HTMLElement) this._originalOptions.fullscreenContainer.requestFullscreen();\n else this.engine.screen.goFullScreen(this._originalOptions.fullscreenContainer);\n } catch (error) {\n this._logger.error(\"could not go fullscreen\", error);\n }\n resolve();\n };\n this._playButton.addEventListener(\"click\", startButtonHandler);\n this._playButton.addEventListener(\"touchend\", startButtonHandler);\n this._playButton.addEventListener(\"pointerup\", startButtonHandler);\n });\n return await playButtonClicked;\n }\n }\n hidePlayButton() {\n this._playButtonShown = false;\n this._playButton.style.display = \"none\";\n }\n /**\n * Clean up generated elements for the loader\n */ dispose() {\n if (this._playButtonRootElement.parentElement) {\n this._playButtonRootElement.removeChild(this._playButtonElement);\n document.body.removeChild(this._playButtonRootElement);\n document.head.removeChild(this._styleBlock);\n this._playButtonRootElement = null;\n this._playButtonElement = null;\n this._styleBlock = null;\n }\n }\n async onUserAction() {\n var _a;\n // short delay in showing the button for aesthetics\n await delay(200, (_a = this.engine) === null || _a === void 0 ? void 0 : _a.clock);\n this.canvas.flagDirty();\n // show play button\n await this.showPlayButton();\n }\n async onBeforeLoad() {\n var _a;\n this._configuredPixelRatio = this.screen.pixelRatioOverride;\n // Push the current user entered resolution/viewport\n this.screen.pushResolutionAndViewport();\n // Configure resolution for loader, it expects resolution === viewport\n this.screen.resolution = this.screen.viewport;\n this.screen.pixelRatioOverride = 1;\n this.screen.applyResolutionAndViewport();\n this.canvas.width = this.engine.canvas.width;\n this.canvas.height = this.engine.canvas.height;\n await ((_a = this._image) === null || _a === void 0 ? void 0 : _a.decode()); // decode logo if it exists\n }\n // eslint-disable-next-line require-await\n async onAfterLoad() {\n this.screen.pixelRatioOverride = this._configuredPixelRatio;\n this.screen.popResolutionAndViewport();\n this.screen.applyResolutionAndViewport();\n this.dispose();\n }\n _positionPlayButton() {\n if (this.engine) {\n const screenHeight = this.engine.screen.viewport.height;\n const screenWidth = this.engine.screen.viewport.width;\n if (this._playButtonRootElement) {\n const left = this.engine.canvas.offsetLeft;\n const top = this.engine.canvas.offsetTop;\n const buttonWidth = this._playButton.clientWidth;\n const buttonHeight = this._playButton.clientHeight;\n if (this.playButtonPosition) {\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\n } else {\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\n }\n }\n }\n }\n /**\n * Loader draw function. Draws the default Excalibur loading screen.\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\n * to customize the drawing, or just override entire method.\n */ onDraw(ctx) {\n const canvasHeight = this.engine.canvasHeight / this.engine.pixelRatio;\n const canvasWidth = this.engine.canvasWidth / this.engine.pixelRatio;\n this._positionPlayButton();\n ctx.fillStyle = this.backgroundColor;\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\n let logoY = canvasHeight / 2;\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\n let logoX = canvasWidth / 2 - width / 2;\n if (this.logoPosition) {\n logoX = this.logoPosition.x;\n logoY = this.logoPosition.y;\n }\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\n const oldAntialias = this.engine.getAntialiasing();\n this.engine.setAntialiasing(true);\n if (!this.logoPosition) ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\n else ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\n // loading box\n if (!this.suppressPlayButton && this._playButtonShown) {\n this.engine.setAntialiasing(oldAntialias);\n return;\n }\n let loadingX = logoX;\n let loadingY = logoY;\n if (this.loadingBarPosition) {\n loadingX = this.loadingBarPosition.x;\n loadingY = this.loadingBarPosition.y;\n }\n ctx.lineWidth = 2;\n roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\n const progress = width * this.progress;\n const margin = 5;\n const progressWidth = progress - margin * 2;\n const height = 20 - margin * 2;\n roundRect(ctx, loadingX + margin, loadingY + margin, progressWidth > 10 ? progressWidth : 10, height, 5, null, this.loadingBarColor);\n this.engine.setAntialiasing(oldAntialias);\n }\n }\n Loader._DEFAULT_LOADER_OPTIONS = {\n loadables: [],\n fullscreenAfterLoad: false,\n fullscreenContainer: undefined\n };\n /**\n * This is the list of features that will be used to log the supported\n * features to the console when Detector.logBrowserFeatures() is called.\n */ const REPORTED_FEATURES = {\n webgl: \"WebGL\",\n webaudio: \"WebAudio\",\n gamepadapi: \"Gamepad API\"\n };\n /**\n * Excalibur internal feature detection helper class\n */ class Detector {\n constructor(){\n this._features = null;\n this.failedTests = [];\n // critical browser features required for ex to run\n this._criticalTests = {\n // Test canvas/2d context support\n canvasSupport: function() {\n const elem = document.createElement(\"canvas\");\n return !!(elem.getContext && elem.getContext(\"2d\"));\n },\n // Test array buffer support ex uses for downloading binary data\n arrayBufferSupport: function() {\n const xhr = new XMLHttpRequest();\n xhr.open(\"GET\", \"/\");\n try {\n xhr.responseType = \"arraybuffer\";\n } catch (e) {\n return false;\n }\n return xhr.responseType === \"arraybuffer\";\n },\n // Test data urls ex uses for sprites\n dataUrlSupport: function() {\n const canvas = document.createElement(\"canvas\");\n return canvas.toDataURL(\"image/png\").indexOf(\"data:image/png\") === 0;\n },\n // Test object url support for loading\n objectUrlSupport: function() {\n return \"URL\" in window && \"revokeObjectURL\" in URL && \"createObjectURL\" in URL;\n },\n // RGBA support for colors\n rgbaSupport: function() {\n const style = document.createElement(\"a\").style;\n style.cssText = \"background-color:rgba(150,255,150,.5)\";\n return (\"\" + style.backgroundColor).indexOf(\"rgba\") > -1;\n }\n };\n // warnings excalibur performance will be degraded\n this._warningTest = {\n webAudioSupport: function() {\n return !!(window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext || window.oAudioContext);\n },\n webglSupport: function() {\n const elem = document.createElement(\"canvas\");\n return !!(elem.getContext && elem.getContext(\"webgl\"));\n }\n };\n this._features = this._loadBrowserFeatures();\n }\n /**\n * Returns a map of currently supported browser features. This method\n * treats the features as a singleton and will only calculate feature\n * support if it has not previously been done.\n */ getBrowserFeatures() {\n if (this._features === null) this._features = this._loadBrowserFeatures();\n return this._features;\n }\n /**\n * Report on non-critical browser support for debugging purposes.\n * Use native browser console colors for visibility.\n */ logBrowserFeatures() {\n let msg = \"%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n\";\n const args = [\n \"font-weight: bold; color: navy\",\n \"font-weight: normal; color: inherit\"\n ];\n const supported = this.getBrowserFeatures();\n for (const feature of Object.keys(REPORTED_FEATURES)){\n if (supported[feature]) {\n msg += \"(%c\\u2713%c)\"; // (✓)\n args.push(\"font-weight: bold; color: green\");\n args.push(\"font-weight: normal; color: inherit\");\n } else {\n msg += \"(%c\\u2717%c)\"; // (✗)\n args.push(\"font-weight: bold; color: red\");\n args.push(\"font-weight: normal; color: inherit\");\n }\n msg += \" \" + REPORTED_FEATURES[feature] + \"\\n\";\n }\n args.unshift(msg);\n // eslint-disable-next-line no-console\n console.log.apply(console, args);\n }\n /**\n * Executes several IIFE's to get a constant reference to supported\n * features within the current execution context.\n */ _loadBrowserFeatures() {\n return {\n // IIFE to check canvas support\n canvas: (()=>{\n return this._criticalTests.canvasSupport();\n })(),\n // IIFE to check arraybuffer support\n arraybuffer: (()=>{\n return this._criticalTests.arrayBufferSupport();\n })(),\n // IIFE to check dataurl support\n dataurl: (()=>{\n return this._criticalTests.dataUrlSupport();\n })(),\n // IIFE to check objecturl support\n objecturl: (()=>{\n return this._criticalTests.objectUrlSupport();\n })(),\n // IIFE to check rgba support\n rgba: (()=>{\n return this._criticalTests.rgbaSupport();\n })(),\n // IIFE to check webaudio support\n webaudio: (()=>{\n return this._warningTest.webAudioSupport();\n })(),\n // IIFE to check webgl support\n webgl: (()=>{\n return this._warningTest.webglSupport();\n })(),\n // IIFE to check gamepadapi support\n gamepadapi: (()=>{\n return !!navigator.getGamepads;\n })()\n };\n }\n test() {\n // Critical test will for ex not to run\n let failedCritical = false;\n for(const test in this._criticalTests)if (!this._criticalTests[test].call(this)) {\n this.failedTests.push(test);\n Logger.getInstance().error(\"Critical browser feature missing, Excalibur requires:\", test);\n failedCritical = true;\n }\n if (failedCritical) return false;\n // Warning tests do not for ex to return false to compatibility\n for(const warning in this._warningTest)if (!this._warningTest[warning]()) Logger.getInstance().warn(\"Warning browser feature missing, Excalibur will have reduced performance:\", warning);\n return true;\n }\n }\n /**\n * An enum that describes the types of collisions bodies can participate in\n */ var CollisionType;\n (function(CollisionType) {\n /**\n * Bodies with the `PreventCollision` setting do not participate in any\n * collisions and do not raise collision events.\n */ CollisionType[\"PreventCollision\"] = \"PreventCollision\";\n /**\n * Bodies with the `Passive` setting only raise collision events, but are not\n * influenced or moved by other bodies and do not influence or move other bodies.\n * This is useful for use in trigger type behavior.\n */ CollisionType[\"Passive\"] = \"Passive\";\n /**\n * Bodies with the `Active` setting raise collision events and participate\n * in collisions with other bodies and will be push or moved by bodies sharing\n * the `Active` or `Fixed` setting.\n */ CollisionType[\"Active\"] = \"Active\";\n /**\n * Bodies with the `Fixed` setting raise collision events and participate in\n * collisions with other bodies. Actors with the `Fixed` setting will not be\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\n * not be pushed or moved by each other, they will not interact except to throw\n * collision events.\n */ CollisionType[\"Fixed\"] = \"Fixed\";\n })(CollisionType || (CollisionType = {}));\n /**\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\n */ var CoordPlane;\n (function(CoordPlane) {\n /**\n * The world coordinate plane (default) represents world space, any entities drawn with world\n * space move when the camera moves.\n */ CoordPlane[\"World\"] = \"world\";\n /**\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\n * to screen coordinates ignoring the camera.\n */ CoordPlane[\"Screen\"] = \"screen\";\n })(CoordPlane || (CoordPlane = {}));\n class VectorView extends Vector {\n constructor(options){\n super(0, 0);\n this._getX = options.getX;\n this._getY = options.getY;\n this._setX = options.setX;\n this._setY = options.setY;\n }\n get x() {\n return this._x = this._getX();\n }\n set x(val) {\n this._setX(val);\n this._x = val;\n }\n get y() {\n return this._y = this._getY();\n }\n set y(val) {\n this._setY(val);\n this._y = val;\n }\n }\n /**\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\n */ class WatchVector extends Vector {\n constructor(original, change){\n super(original.x, original.y);\n this.original = original;\n this.change = change;\n }\n get x() {\n return this._x = this.original.x;\n }\n set x(newX) {\n this.change(newX, this._y);\n this._x = this.original.x = newX;\n }\n get y() {\n return this._y = this.original.y;\n }\n set y(newY) {\n this.change(this._x, newY);\n this._y = this.original.y = newY;\n }\n }\n class transform_Transform {\n constructor(){\n this._parent = null;\n this._children = [];\n this._pos = vec(0, 0);\n this._rotation = 0;\n this._scale = vec(1, 1);\n this._isDirty = false;\n this._isInverseDirty = false;\n this._matrix = AffineMatrix.identity();\n this._inverse = AffineMatrix.identity();\n }\n get parent() {\n return this._parent;\n }\n set parent(transform) {\n if (this._parent) {\n const index = this._parent._children.indexOf(this);\n if (index > -1) this._parent._children.splice(index, 1);\n }\n this._parent = transform;\n if (this._parent) this._parent._children.push(this);\n this.flagDirty();\n }\n get children() {\n return this._children;\n }\n set pos(v) {\n if (!v.equals(this._pos)) {\n this._pos.x = v.x;\n this._pos.y = v.y;\n this.flagDirty();\n }\n }\n get pos() {\n return new WatchVector(this._pos, (x, y)=>{\n if (x !== this._pos.x || y !== this._pos.y) this.flagDirty();\n });\n }\n set globalPos(v) {\n let localPos = v.clone();\n if (this.parent) localPos = this.parent.inverse.multiply(v);\n if (!localPos.equals(this._pos)) {\n this._pos = localPos;\n this.flagDirty();\n }\n }\n get globalPos() {\n return new VectorView({\n getX: ()=>this.matrix.data[4],\n getY: ()=>this.matrix.data[5],\n setX: (x)=>{\n if (this.parent) {\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\n this.pos.x = newX;\n } else this.pos.x = x;\n if (x !== this.matrix.data[4]) this.flagDirty();\n },\n setY: (y)=>{\n if (this.parent) {\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\n this.pos.y = newY;\n } else this.pos.y = y;\n if (y !== this.matrix.data[5]) this.flagDirty();\n }\n });\n }\n set rotation(rotation) {\n const canonRotation = canonicalizeAngle(rotation);\n if (canonRotation !== this._rotation) this.flagDirty();\n this._rotation = canonRotation;\n }\n get rotation() {\n return this._rotation;\n }\n set globalRotation(rotation) {\n let inverseRotation = 0;\n if (this.parent) inverseRotation = this.parent.globalRotation;\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\n if (canonRotation !== this._rotation) this.flagDirty();\n this._rotation = canonRotation;\n }\n get globalRotation() {\n if (this.parent) return this.matrix.getRotation();\n return this.rotation;\n }\n set scale(v) {\n if (!v.equals(this._scale)) {\n this._scale.x = v.x;\n this._scale.y = v.y;\n this.flagDirty();\n }\n }\n get scale() {\n return new WatchVector(this._scale, (x, y)=>{\n if (x !== this._scale.x || y !== this._scale.y) this.flagDirty();\n });\n }\n set globalScale(v) {\n let inverseScale = vec(1, 1);\n if (this.parent) inverseScale = this.parent.globalScale;\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\n }\n get globalScale() {\n return new VectorView({\n getX: ()=>this.parent ? this.matrix.getScaleX() : this.scale.x,\n getY: ()=>this.parent ? this.matrix.getScaleY() : this.scale.y,\n setX: (x)=>{\n if (this.parent) {\n const globalScaleX = this.parent.globalScale.x;\n this.scale.x = x / globalScaleX;\n } else this.scale.x = x;\n },\n setY: (y)=>{\n if (this.parent) {\n const globalScaleY = this.parent.globalScale.y;\n this.scale.y = y / globalScaleY;\n } else this.scale.y = y;\n }\n });\n }\n get matrix() {\n if (this._isDirty) {\n if (this.parent === null) this._matrix = this._calculateMatrix();\n else this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\n this._isDirty = false;\n }\n return this._matrix;\n }\n get inverse() {\n if (this._isInverseDirty) {\n this._inverse = this.matrix.inverse();\n this._isInverseDirty = false;\n }\n return this._inverse;\n }\n _calculateMatrix() {\n const matrix = AffineMatrix.identity().translate(this.pos.x, this.pos.y).rotate(this.rotation).scale(this.scale.x, this.scale.y);\n return matrix;\n }\n flagDirty() {\n this._isDirty = true;\n this._isInverseDirty = true;\n for(let i = 0; i < this._children.length; i++)this._children[i].flagDirty();\n }\n apply(point) {\n return this.matrix.multiply(point);\n }\n applyInverse(point) {\n return this.inverse.multiply(point);\n }\n setTransform(pos, rotation, scale) {\n this._pos.x = pos.x;\n this._pos.y = pos.y;\n this._rotation = canonicalizeAngle(rotation);\n this._scale.x = scale.x;\n this._scale.y = scale.y;\n this.flagDirty();\n }\n /**\n * Clones the current transform\n * **Warning does not clone the parent**\n * @param dest\n */ clone(dest) {\n const target = dest !== null && dest !== void 0 ? dest : new transform_Transform();\n this._pos.clone(target._pos);\n target._rotation = this._rotation;\n this._scale.clone(target._scale);\n target.flagDirty();\n return target;\n }\n }\n /**\n *\n */ function isComponentCtor(value) {\n return !!value && !!value.prototype && !!value.prototype.constructor;\n }\n /**\n * Type guard to check if a component implements clone\n * @param x\n */ function hasClone(x) {\n return !!(x === null || x === void 0 ? void 0 : x.clone);\n }\n /**\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\n *\n * Implementations of Component must have a zero-arg constructor to support dependencies\n *\n * ```typescript\n * class MyComponent extends ex.Component {\n * // zero arg support required if you want to use component dependencies\n * constructor(public optionalPos?: ex.Vector) {}\n * }\n * ```\n */ class Component {\n constructor(){\n // TODO maybe generate a unique id?\n /**\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\n */ this.owner = undefined;\n }\n /**\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\n */ clone() {\n const newComponent = new this.constructor();\n for(const prop in this)if (this.hasOwnProperty(prop)) {\n const val = this[prop];\n if (hasClone(val) && prop !== \"owner\" && prop !== \"clone\") newComponent[prop] = val.clone();\n else newComponent[prop] = val;\n }\n return newComponent;\n }\n }\n /**\n * Simple Observable implementation\n * @template T is the typescript Type that defines the data being observed\n */ class Observable {\n constructor(){\n this.observers = [];\n this.subscriptions = [];\n }\n /**\n * Register an observer to listen to this observable\n * @param observer\n */ register(observer) {\n this.observers.push(observer);\n }\n /**\n * Register a callback to listen to this observable\n * @param func\n */ subscribe(func) {\n this.subscriptions.push(func);\n }\n /**\n * Remove an observer from the observable\n * @param observer\n */ unregister(observer) {\n const i = this.observers.indexOf(observer);\n if (i !== -1) this.observers.splice(i, 1);\n }\n /**\n * Remove a callback that is listening to this observable\n * @param func\n */ unsubscribe(func) {\n const i = this.subscriptions.indexOf(func);\n if (i !== -1) this.subscriptions.splice(i, 1);\n }\n /**\n * Broadcasts a message to all observers and callbacks\n * @param message\n */ notifyAll(message) {\n const observersLength = this.observers.length;\n for(let i = 0; i < observersLength; i++)this.observers[i].notify(message);\n const subscriptionsLength = this.subscriptions.length;\n for(let i = 0; i < subscriptionsLength; i++)this.subscriptions[i](message);\n }\n /**\n * Removes all observers and callbacks\n */ clear() {\n this.observers.length = 0;\n this.subscriptions.length = 0;\n }\n }\n class TransformComponent extends Component {\n constructor(){\n super(...arguments);\n this._logger = Logger.getInstance();\n this._parentComponent = null;\n this._transform = new transform_Transform();\n this._addChildTransform = (child)=>{\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) {\n childTxComponent._transform.parent = this._transform;\n childTxComponent._parentComponent = this;\n }\n };\n /**\n * Observable that emits when the z index changes on this component\n */ this.zIndexChanged$ = new Observable();\n this._z = 0;\n this._coordPlane = CoordPlane.World;\n }\n get() {\n return this._transform;\n }\n onAdd(owner) {\n for (const child of owner.children)this._addChildTransform(child);\n owner.childrenAdded$.subscribe((child)=>this._addChildTransform(child));\n owner.childrenRemoved$.subscribe((child)=>{\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) {\n childTxComponent._transform.parent = null;\n childTxComponent._parentComponent = null;\n }\n });\n }\n onRemove(_previousOwner) {\n this._transform.parent = null;\n this._parentComponent = null;\n }\n /**\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\n * For example z=99 would be drawn on top of z=0.\n */ get z() {\n return this._z;\n }\n set z(val) {\n const oldz = this._z;\n this._z = val;\n if (oldz !== val) this.zIndexChanged$.notifyAll(val);\n }\n /**\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\n */ get coordPlane() {\n if (this._parentComponent) return this._parentComponent.coordPlane;\n return this._coordPlane;\n }\n set coordPlane(value) {\n var _a;\n if (!this._parentComponent) this._coordPlane = value;\n else this._logger.warn(`Cannot set coordinate plane on child entity ${(_a = this.owner) === null || _a === void 0 ? void 0 : _a.name}, children inherit their coordinate plane from their parents.`);\n }\n get pos() {\n return this._transform.pos;\n }\n set pos(v) {\n this._transform.pos = v;\n }\n get globalPos() {\n return this._transform.globalPos;\n }\n set globalPos(v) {\n this._transform.globalPos = v;\n }\n get rotation() {\n return this._transform.rotation;\n }\n set rotation(rotation) {\n this._transform.rotation = rotation;\n }\n get globalRotation() {\n return this._transform.globalRotation;\n }\n set globalRotation(rotation) {\n this._transform.globalRotation = rotation;\n }\n get scale() {\n return this._transform.scale;\n }\n set scale(v) {\n this._transform.scale = v;\n }\n get globalScale() {\n return this._transform.globalScale;\n }\n set globalScale(v) {\n this._transform.globalScale = v;\n }\n applyInverse(v) {\n return this._transform.applyInverse(v);\n }\n apply(v) {\n return this._transform.apply(v);\n }\n clone() {\n const component = new TransformComponent();\n component._transform = this._transform.clone();\n component._z = this._z;\n return component;\n }\n }\n class MotionComponent extends Component {\n constructor(){\n super(...arguments);\n /**\n * The velocity of an entity in pixels per second\n */ this.vel = Vector.Zero;\n /**\n * The acceleration of entity in pixels per second^2\n */ this.acc = Vector.Zero;\n /**\n * The scale rate of change in scale units per second\n */ this.scaleFactor = Vector.Zero;\n /**\n * The angular velocity which is how quickly the entity is rotating in radians per second\n */ this.angularVelocity = 0;\n /**\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\n */ this.torque = 0;\n /**\n * Inertia can be thought of as the resistance to motion\n */ this.inertia = 1;\n }\n }\n /**\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\n */ class CollisionGroupManager {\n /**\n * Create a new named collision group up to a max of 32.\n * @param name Name for the collision group\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\n */ static create(name, mask) {\n if (this._CURRENT_GROUP > this._MAX_GROUPS) throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\n if (this._GROUPS.get(name)) {\n const existingGroup = this._GROUPS.get(name);\n if (existingGroup.mask === mask) return existingGroup;\n throw new Error(`Collision group ${name} already exists with a different mask!`);\n }\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\n this._CURRENT_BIT = this._CURRENT_BIT << 1 | 0;\n this._CURRENT_GROUP++;\n this._GROUPS.set(name, group);\n return group;\n }\n /**\n * Get all collision groups currently tracked by excalibur\n */ static get groups() {\n return Array.from(this._GROUPS.values());\n }\n /**\n * Get a collision group by it's name\n * @param name\n */ static groupByName(name) {\n return this._GROUPS.get(name);\n }\n /**\n * Resets the managers internal group management state\n */ static reset() {\n this._GROUPS = new Map();\n this._CURRENT_BIT = this._STARTING_BIT;\n this._CURRENT_GROUP = 1;\n }\n }\n // using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\n CollisionGroupManager._STARTING_BIT = 1;\n CollisionGroupManager._MAX_GROUPS = 32;\n CollisionGroupManager._CURRENT_GROUP = 1;\n CollisionGroupManager._CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\n CollisionGroupManager._GROUPS = new Map();\n /**\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\n *\n * For example:\n *\n * Players have collision group \"player\"\n *\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\n *\n * Enemies have collision group \"enemy\"\n *\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\n *\n * Blocks have collision group \"ground\"\n *\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\n *\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\n * with players and blocks.\n *\n * This is done with bitmasking, see the following pseudo-code\n *\n * PlayerGroup = `0b001`\n * PlayerGroupMask = `0b110`\n *\n * EnemyGroup = `0b010`\n * EnemyGroupMask = `0b101`\n *\n * BlockGroup = `0b100`\n * BlockGroupMask = `0b011`\n *\n * Should Players collide? No because the bitwise mask evaluates to 0\n * `(player1.group & player2.mask) === 0`\n * `(0b001 & 0b110) === 0`\n *\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\n * `(player1.group & enemy1.mask) === 1`\n * `(0b001 & 0b101) === 1`\n *\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\n * `(player1.group & blocks1.mask) === 1`\n * `(0b001 & 0b011) === 1`\n */ class CollisionGroup {\n /**\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\n * @param name Name of the collision group\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\n */ constructor(name, category, mask){\n this._name = name;\n this._category = category;\n this._mask = mask;\n }\n /**\n * Get the name of the collision group\n */ get name() {\n return this._name;\n }\n /**\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\n */ get category() {\n return this._category;\n }\n /**\n * Get the mask for this collision group\n */ get mask() {\n return this._mask;\n }\n /**\n * Evaluates whether 2 collision groups can collide\n *\n * This means the mask has the same bit set the other category and vice versa\n * @param other CollisionGroup\n */ canCollide(other) {\n const overlap1 = this.category & other.mask;\n const overlap2 = this.mask & other.category;\n return overlap1 !== 0 && overlap2 !== 0;\n }\n /**\n * Inverts the collision group. For example, if before the group specified \"players\",\n * inverting would specify all groups except players\n * @returns CollisionGroup\n */ invert() {\n const group = CollisionGroupManager.create(\"~(\" + this.name + \")\", ~this.mask | 0);\n group._category = ~this.category;\n return group;\n }\n /**\n * Combine collision groups with each other. The new group includes all of the previous groups.\n * @param collisionGroups\n */ static combine(collisionGroups) {\n const combinedName = collisionGroups.map((c)=>c.name).join(\"+\");\n const combinedCategory = collisionGroups.reduce((current, g)=>g.category | current, 0);\n const combinedMask = ~combinedCategory;\n return CollisionGroupManager.create(combinedName, combinedMask);\n }\n /**\n * Creates a collision group that collides with the listed groups\n * @param collisionGroups\n */ static collidesWith(collisionGroups) {\n const combinedName = `collidesWith(${collisionGroups.map((c)=>c.name).join(\"+\")})`;\n const combinedMask = collisionGroups.reduce((current, g)=>g.category | current, 0);\n return CollisionGroupManager.create(combinedName, combinedMask);\n }\n toString() {\n return `\r\ncategory: ${this.category.toString(2).padStart(32, \"0\")}\r\nmask: ${(this.mask >>> 0).toString(2).padStart(32, \"0\")}\r\n `;\n }\n }\n /**\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\n * it is the default collision group on colliders.\n */ CollisionGroup.All = new CollisionGroup(\"Collide with all groups\", -1, -1);\n /**\n * Models a potential collision between 2 colliders\n */ class Pair {\n constructor(colliderA, colliderB){\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.id = null;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n }\n /**\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\n * @param colliderA\n * @param colliderB\n */ static canCollide(colliderA, colliderB) {\n var _a, _b;\n const bodyA = (_a = colliderA === null || colliderA === void 0 ? void 0 : colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB === null || colliderB === void 0 ? void 0 : colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n // Prevent self collision\n if (colliderA.id === colliderB.id) return false;\n // Colliders with the same owner do not collide (composite colliders)\n if (colliderA.owner && colliderB.owner && colliderA.owner.id === colliderB.owner.id) return false;\n // if the pair has a member with zero dimension don't collide\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) return false;\n // Body's needed for collision in the current state\n // TODO can we collide without a body?\n if (!bodyA || !bodyB) return false;\n // If both are in the same collision group short circuit\n if (!bodyA.group.canCollide(bodyB.group)) return false;\n // if both are fixed short circuit\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) return false;\n // if the either is prevent collision short circuit\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) return false;\n // if either is dead short circuit\n if (!bodyA.active || !bodyB.active) return false;\n return true;\n }\n /**\n * Returns whether or not it is possible for the pairs to collide\n */ get canCollide() {\n const colliderA = this.colliderA;\n const colliderB = this.colliderB;\n return Pair.canCollide(colliderA, colliderB);\n }\n /**\n * Runs the collision intersection logic on the members of this pair\n */ collide() {\n return this.colliderA.collide(this.colliderB);\n }\n /**\n * Check if the collider is part of the pair\n * @param collider\n */ hasCollider(collider) {\n return collider === this.colliderA || collider === this.colliderB;\n }\n /**\n * Calculates the unique pair hash id for this collision pair (owning id)\n */ static calculatePairHash(idA, idB) {\n if (idA.value < idB.value) return `#${idA.value}+${idB.value}`;\n else return `#${idB.value}+${idA.value}`;\n }\n }\n /**\n * A 1 dimensional projection on an axis, used to test overlaps\n */ class Projection {\n constructor(min, max){\n this.min = min;\n this.max = max;\n }\n overlaps(projection) {\n return this.max > projection.min && projection.max > this.min;\n }\n getOverlap(projection) {\n if (this.overlaps(projection)) {\n if (this.max > projection.max) return projection.max - this.min;\n else return this.max - projection.min;\n }\n return 0;\n }\n }\n /**\n * Dynamic Tree Node used for tracking bounds within the tree\n */ class TreeNode {\n constructor(parent){\n this.parent = parent;\n this.parent = parent || null;\n this.data = null;\n this.bounds = new BoundingBox();\n this.left = null;\n this.right = null;\n this.height = 0;\n }\n isLeaf() {\n return !this.left && !this.right;\n }\n }\n /**\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\n *\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\n * Every non-leaf node is a bounding box that contains child bounding boxes.\n */ class DynamicTree {\n constructor(_config, worldBounds = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)){\n this._config = _config;\n this.worldBounds = worldBounds;\n this.root = null;\n this.nodes = {};\n }\n /**\n * Inserts a node into the dynamic tree\n */ _insert(leaf) {\n // If there are no nodes in the tree, make this the root leaf\n if (this.root === null) {\n this.root = leaf;\n this.root.parent = null;\n return;\n }\n // Search the tree for a node that is not a leaf and find the best place to insert\n const leafAABB = leaf.bounds;\n let currentRoot = this.root;\n while(!currentRoot.isLeaf()){\n const left = currentRoot.left;\n const right = currentRoot.right;\n const area = currentRoot.bounds.getPerimeter();\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\n const combinedArea = combinedAABB.getPerimeter();\n // Calculate cost heuristic for creating a new parent and leaf\n const cost = 2 * combinedArea;\n // Minimum cost of pushing the leaf down the tree\n const inheritanceCost = 2 * (combinedArea - area);\n // Cost of descending\n let leftCost = 0;\n const leftCombined = leafAABB.combine(left.bounds);\n let newArea;\n let oldArea;\n if (left.isLeaf()) leftCost = leftCombined.getPerimeter() + inheritanceCost;\n else {\n oldArea = left.bounds.getPerimeter();\n newArea = leftCombined.getPerimeter();\n leftCost = newArea - oldArea + inheritanceCost;\n }\n let rightCost = 0;\n const rightCombined = leafAABB.combine(right.bounds);\n if (right.isLeaf()) rightCost = rightCombined.getPerimeter() + inheritanceCost;\n else {\n oldArea = right.bounds.getPerimeter();\n newArea = rightCombined.getPerimeter();\n rightCost = newArea - oldArea + inheritanceCost;\n }\n // cost is acceptable\n if (cost < leftCost && cost < rightCost) break;\n // Descend to the depths\n if (leftCost < rightCost) currentRoot = left;\n else currentRoot = right;\n }\n // Create the new parent node and insert into the tree\n const oldParent = currentRoot.parent;\n const newParent = new TreeNode(oldParent);\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\n newParent.height = currentRoot.height + 1;\n if (oldParent !== null) {\n // The sibling node was not the root\n if (oldParent.left === currentRoot) oldParent.left = newParent;\n else oldParent.right = newParent;\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n } else {\n // The sibling node was the root\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n this.root = newParent;\n }\n // Walk up the tree fixing heights and AABBs\n let currentNode = leaf.parent;\n while(currentNode){\n currentNode = this._balance(currentNode);\n if (!currentNode.left) throw new Error(\"Parent of current leaf cannot have a null left child\" + currentNode);\n if (!currentNode.right) throw new Error(\"Parent of current leaf cannot have a null right child\" + currentNode);\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode = currentNode.parent;\n }\n }\n /**\n * Removes a node from the dynamic tree\n */ _remove(leaf) {\n if (leaf === this.root) {\n this.root = null;\n return;\n }\n const parent = leaf.parent;\n const grandParent = parent.parent;\n let sibling;\n if (parent.left === leaf) sibling = parent.right;\n else sibling = parent.left;\n if (grandParent) {\n if (grandParent.left === parent) grandParent.left = sibling;\n else grandParent.right = sibling;\n sibling.parent = grandParent;\n let currentNode = grandParent;\n while(currentNode){\n currentNode = this._balance(currentNode);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode = currentNode.parent;\n }\n } else {\n this.root = sibling;\n sibling.parent = null;\n }\n }\n /**\n * Tracks a body in the dynamic tree\n */ trackCollider(collider) {\n const node = new TreeNode();\n node.data = collider;\n node.bounds = collider.bounds;\n node.bounds.left -= 2;\n node.bounds.top -= 2;\n node.bounds.right += 2;\n node.bounds.bottom += 2;\n this.nodes[collider.id.value] = node;\n this._insert(node);\n }\n /**\n * Updates the dynamic tree given the current bounds of each body being tracked\n */ updateCollider(collider) {\n var _a;\n const node = this.nodes[collider.id.value];\n if (!node) return false;\n const b = collider.bounds;\n // if the body is outside the world no longer update it\n if (!this.worldBounds.contains(b)) {\n Logger.getInstance().warn(\"Collider with id \" + collider.id.value + \" is outside the world bounds and will no longer be tracked for physics\");\n this.untrackCollider(collider);\n return false;\n }\n if (node.bounds.contains(b)) return false;\n this._remove(node);\n b.left -= this._config.boundsPadding;\n b.top -= this._config.boundsPadding;\n b.right += this._config.boundsPadding;\n b.bottom += this._config.boundsPadding;\n // THIS IS CAUSING UNNECESSARY CHECKS\n if (collider.owner) {\n const body = (_a = collider.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n if (body) {\n const multdx = body.vel.x * 32 / 1000 * this._config.velocityMultiplier;\n const multdy = body.vel.y * 32 / 1000 * this._config.velocityMultiplier;\n if (multdx < 0) b.left += multdx;\n else b.right += multdx;\n if (multdy < 0) b.top += multdy;\n else b.bottom += multdy;\n }\n }\n node.bounds = b;\n this._insert(node);\n return true;\n }\n /**\n * Untracks a body from the dynamic tree\n */ untrackCollider(collider) {\n const node = this.nodes[collider.id.value];\n if (!node) return;\n this._remove(node);\n this.nodes[collider.id.value] = null;\n delete this.nodes[collider.id.value];\n }\n /**\n * Balances the tree about a node\n */ _balance(node) {\n if (node === null) throw new Error(\"Cannot balance at null node\");\n if (node.isLeaf() || node.height < 2) return node;\n const left = node.left;\n const right = node.right;\n const a = node;\n const b = left;\n const c = right;\n const d = left.left;\n const e = left.right;\n const f = right.left;\n const g = right.right;\n const balance = c.height - b.height;\n // Rotate c node up\n if (balance > 1) {\n // Swap the right node with it's parent\n c.left = a;\n c.parent = a.parent;\n a.parent = c;\n // The original node's old parent should point to the right node\n // this is mega confusing\n if (c.parent) {\n if (c.parent.left === a) c.parent.left = c;\n else c.parent.right = c;\n } else this.root = c;\n // Rotate\n if (f.height > g.height) {\n c.right = f;\n a.right = g;\n g.parent = a;\n a.bounds = b.bounds.combine(g.bounds);\n c.bounds = a.bounds.combine(f.bounds);\n a.height = 1 + Math.max(b.height, g.height);\n c.height = 1 + Math.max(a.height, f.height);\n } else {\n c.right = g;\n a.right = f;\n f.parent = a;\n a.bounds = b.bounds.combine(f.bounds);\n c.bounds = a.bounds.combine(g.bounds);\n a.height = 1 + Math.max(b.height, f.height);\n c.height = 1 + Math.max(a.height, g.height);\n }\n return c;\n }\n // Rotate left node up\n if (balance < -1) {\n // swap\n b.left = a;\n b.parent = a.parent;\n a.parent = b;\n // node's old parent should point to b\n if (b.parent) {\n if (b.parent.left === a) b.parent.left = b;\n else {\n if (b.parent.right !== a) throw \"Error rotating Dynamic Tree\";\n b.parent.right = b;\n }\n } else this.root = b;\n // rotate\n if (d.height > e.height) {\n b.right = d;\n a.left = e;\n e.parent = a;\n a.bounds = c.bounds.combine(e.bounds);\n b.bounds = a.bounds.combine(d.bounds);\n a.height = 1 + Math.max(c.height, e.height);\n b.height = 1 + Math.max(a.height, d.height);\n } else {\n b.right = e;\n a.left = d;\n d.parent = a;\n a.bounds = c.bounds.combine(d.bounds);\n b.bounds = a.bounds.combine(e.bounds);\n a.height = 1 + Math.max(c.height, d.height);\n b.height = 1 + Math.max(a.height, e.height);\n }\n return b;\n }\n return node;\n }\n /**\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\n */ getHeight() {\n if (this.root === null) return 0;\n return this.root.height;\n }\n /**\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\n *\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\n * the tree until all possible colliders have been returned.\n */ query(collider, callback) {\n const bounds = collider.bounds;\n const helper = (currentNode)=>{\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\n if (currentNode.isLeaf() && currentNode.data !== collider) {\n if (callback.call(collider, currentNode.data)) return true;\n } else return helper(currentNode.left) || helper(currentNode.right);\n }\n return false;\n };\n helper(this.root);\n }\n /**\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\n * long ray to test the tree specified by `max`.\n *\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\n * the tree until all possible bodies that would intersect with the ray have been returned.\n */ rayCastQuery(ray, max = Infinity, callback) {\n const helper = (currentNode)=>{\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\n if (currentNode.isLeaf()) {\n if (callback.call(ray, currentNode.data)) // ray hit a leaf! return the body\n return true;\n } else // ray hit but not at a leaf, recurse deeper\n return helper(currentNode.left) || helper(currentNode.right);\n }\n return false; // ray missed\n };\n helper(this.root);\n }\n getNodes() {\n const helper = (currentNode)=>{\n if (currentNode) return [\n currentNode\n ].concat(helper(currentNode.left), helper(currentNode.right));\n else return [];\n };\n return helper(this.root);\n }\n debug(ex) {\n // draw all the nodes in the Dynamic Tree\n const helper = (currentNode)=>{\n if (currentNode) {\n if (currentNode.isLeaf()) currentNode.bounds.draw(ex, Color.Green);\n else currentNode.bounds.draw(ex, Color.White);\n if (currentNode.left) helper(currentNode.left);\n if (currentNode.right) helper(currentNode.right);\n }\n };\n helper(this.root);\n }\n }\n /**\n * A 2D ray that can be cast into the scene to do collision detection\n */ class Ray {\n /**\n * @param pos The starting position for the ray\n * @param dir The vector indicating the direction of the ray\n */ constructor(pos, dir){\n this.pos = pos;\n this.dir = dir.normalize();\n }\n /**\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\n * This number indicates the mathematical intersection time.\n * @param line The line to test\n */ intersect(line) {\n const numerator = line.begin.sub(this.pos);\n // Test is line and ray are parallel and non intersecting\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) return -1;\n // Lines are parallel\n const divisor = this.dir.cross(line.getSlope());\n if (divisor === 0) return -1;\n const t = numerator.cross(line.getSlope()) / divisor;\n if (t >= 0) {\n const u = numerator.cross(this.dir) / divisor / line.getLength();\n if (u >= 0 && u <= 1) return t;\n }\n return -1;\n }\n intersectPoint(line) {\n const time = this.intersect(line);\n if (time < 0) return null;\n return this.getPoint(time);\n }\n /**\n * Returns the point of intersection given the intersection time\n */ getPoint(time) {\n return this.pos.add(this.dir.scale(time));\n }\n }\n /**\n * Responsible for performing the collision broadphase (locating potential collisions) and\n * the narrowphase (actual collision contacts)\n */ class DynamicTreeCollisionProcessor {\n constructor(_config){\n this._config = _config;\n this._pairs = new Set();\n this._collisionPairCache = [];\n this._colliders = [];\n this._dynamicCollisionTree = new DynamicTree(_config.dynamicTree);\n }\n getColliders() {\n return this._colliders;\n }\n rayCast(ray, options) {\n var _a, _b, _c;\n const results = [];\n const maxDistance = (_a = options === null || options === void 0 ? void 0 : options.maxDistance) !== null && _a !== void 0 ? _a : Infinity;\n const collisionGroup = options === null || options === void 0 ? void 0 : options.collisionGroup;\n const collisionMask = !collisionGroup ? (_b = options === null || options === void 0 ? void 0 : options.collisionMask) !== null && _b !== void 0 ? _b : CollisionGroup.All.category : collisionGroup.category;\n const searchAllColliders = (_c = options === null || options === void 0 ? void 0 : options.searchAllColliders) !== null && _c !== void 0 ? _c : false;\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider)=>{\n const owner = collider.owner;\n const maybeBody = owner.get(BodyComponent);\n if ((options === null || options === void 0 ? void 0 : options.ignoreCollisionGroupAll) && maybeBody.group === CollisionGroup.All) return false;\n const canCollide = (collisionMask & maybeBody.group.category) !== 0;\n // Early exit if not the right group\n if ((maybeBody === null || maybeBody === void 0 ? void 0 : maybeBody.group) && !canCollide) return false;\n const hit = collider.rayCast(ray, maxDistance);\n if (hit) {\n if (options === null || options === void 0 ? void 0 : options.filter) {\n if (options.filter(hit)) {\n results.push(hit);\n if (!searchAllColliders) // returning true exits the search\n return true;\n }\n } else {\n results.push(hit);\n if (!searchAllColliders) // returning true exits the search\n return true;\n }\n }\n return false;\n });\n return results;\n }\n /**\n * Tracks a physics body for collisions\n */ track(target) {\n if (!target) {\n Logger.getInstance().warn(\"Cannot track null collider\");\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders){\n c.owner = target.owner;\n this._colliders.push(c);\n this._dynamicCollisionTree.trackCollider(c);\n }\n } else {\n this._colliders.push(target);\n this._dynamicCollisionTree.trackCollider(target);\n }\n }\n /**\n * Untracks a physics body\n */ untrack(target) {\n if (!target) {\n Logger.getInstance().warn(\"Cannot untrack a null collider\");\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders){\n const index = this._colliders.indexOf(c);\n if (index !== -1) this._colliders.splice(index, 1);\n this._dynamicCollisionTree.untrackCollider(c);\n }\n } else {\n const index = this._colliders.indexOf(target);\n if (index !== -1) this._colliders.splice(index, 1);\n this._dynamicCollisionTree.untrackCollider(target);\n }\n }\n _pairExists(colliderA, colliderB) {\n // if the collision pair has been calculated already short circuit\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\n return this._pairs.has(hash);\n }\n /**\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\n */ broadphase(targets, delta, stats) {\n const seconds = delta / 1000;\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\n const potentialColliders = targets.filter((other)=>{\n var _a, _b;\n const body = (_a = other.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n return ((_b = other.owner) === null || _b === void 0 ? void 0 : _b.active) && body.collisionType !== CollisionType.PreventCollision;\n });\n // clear old list of collision pairs\n this._collisionPairCache = [];\n this._pairs.clear();\n // check for normal collision pairs\n let collider;\n for(let j = 0, l = potentialColliders.length; j < l; j++){\n collider = potentialColliders[j];\n // Query the collision tree for potential colliders\n this._dynamicCollisionTree.query(collider, (other)=>{\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const pair = new Pair(collider, other);\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // Always return false, to query whole tree. Returning true in the query method stops searching\n return false;\n });\n }\n if (stats) stats.physics.pairs = this._collisionPairCache.length;\n // Check dynamic tree for fast moving objects\n // Fast moving objects are those moving at least there smallest bound per frame\n if (this._config.continuous.checkForFastBodies) for (const collider of potentialColliders){\n const body = collider.owner.get(BodyComponent);\n // Skip non-active objects. Does not make sense on other collision types\n if (body.collisionType !== CollisionType.Active) continue;\n // Maximum travel distance next frame\n const updateDistance = body.vel.size * seconds + // velocity term\n body.acc.size * 0.5 * seconds * seconds; // acc term\n // Find the minimum dimension\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\n if (this._config.continuous.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\n if (stats) stats.physics.fastBodies++;\n // start with the oldPos because the integration for actors has already happened\n // objects resting on a surface may be slightly penetrating in the current position\n const updateVec = body.globalPos.sub(body.oldPos);\n const centerPoint = collider.center;\n const furthestPoint = collider.getFurthestPoint(body.vel);\n const origin = furthestPoint.sub(updateVec);\n const ray = new Ray(origin, body.vel);\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\n ray.pos = ray.pos.add(ray.dir.scale(-2 * this._config.continuous.surfaceEpsilon));\n let minCollider;\n let minTranslate = new Vector(Infinity, Infinity);\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + this._config.continuous.surfaceEpsilon * 2, (other)=>{\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const hit = other.rayCast(ray, updateDistance + this._config.continuous.surfaceEpsilon * 10);\n if (hit) {\n const translate = hit.point.sub(origin);\n if (translate.size < minTranslate.size) {\n minTranslate = translate;\n minCollider = other;\n }\n }\n }\n return false;\n });\n if (minCollider && Vector.isValid(minTranslate)) {\n const pair = new Pair(collider, minCollider);\n if (!this._pairs.has(pair.id)) {\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // move the fast moving object to the other body\n // need to push into the surface by ex.Physics.surfaceEpsilon\n const shift = centerPoint.sub(furthestPoint);\n body.globalPos = origin.add(shift).add(minTranslate).add(ray.dir.scale(10 * this._config.continuous.surfaceEpsilon)); // needed to push the shape slightly into contact\n collider.update(body.transform.get());\n if (stats) stats.physics.fastBodyCollisions++;\n }\n }\n }\n // return cache\n return this._collisionPairCache;\n }\n /**\n * Applies narrow phase on collision pairs to find actual area intersections\n * Adds actual colliding pairs to stats' Frame data\n */ narrowphase(pairs, stats) {\n let contacts = [];\n for(let i = 0; i < pairs.length; i++){\n const newContacts = pairs[i].collide();\n contacts = contacts.concat(newContacts);\n if (stats && newContacts.length > 0) for (const c of newContacts)stats.physics.contacts.set(c.id, c);\n }\n if (stats) stats.physics.collisions += contacts.length;\n return contacts;\n }\n /**\n * Update the dynamic tree positions\n */ update(targets) {\n let updated = 0;\n const len = targets.length;\n for(let i = 0; i < len; i++)if (this._dynamicCollisionTree.updateCollider(targets[i])) updated++;\n return updated;\n }\n debug(ex) {\n this._dynamicCollisionTree.debug(ex);\n }\n }\n /**\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\n * for the purposes of colliding 2 objects in excalibur.\n */ class Collider {\n constructor(){\n this.id = createId(\"collider\", Collider._ID++);\n /**\n * Composite collider if any this collider is attached to\n *\n * **WARNING** do not tamper with this property\n */ this.composite = null;\n this.events = new EventEmitter();\n /**\n * Pixel offset of the collision collider relative to the collider, by default (0, 0) meaning the collider is positioned\n * on top of the collider.\n */ this.offset = Vector.Zero;\n }\n /**\n * Returns a boolean indicating whether this body collided with\n * or was in stationary contact with\n * the body of the other [[Collider]]\n */ touching(other) {\n const contact = this.collide(other);\n if (contact) return true;\n return false;\n }\n }\n Collider._ID = 0;\n /**\n * Possible collision resolution strategies\n *\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\n * like platformers or top down games.\n *\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\n * simulated physical interactions.\n */ var SolverStrategy;\n (function(SolverStrategy) {\n SolverStrategy[\"Arcade\"] = \"arcade\";\n SolverStrategy[\"Realistic\"] = \"realistic\";\n })(SolverStrategy || (SolverStrategy = {}));\n /**\n * Possible broadphase collision pair identification strategies\n *\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\n * potential collision pairs which is O(nlog(n)) faster.\n * @deprecated Unused in Excalibur, will be removed in v0.30\n */ var BroadphaseStrategy;\n (function(BroadphaseStrategy) {\n BroadphaseStrategy[BroadphaseStrategy[\"DynamicAABBTree\"] = 0] = \"DynamicAABBTree\";\n })(BroadphaseStrategy || (BroadphaseStrategy = {}));\n /**\n * Possible numerical integrators for position and velocity\n * @deprecated Unused in Excalibur, will be removed in v0.30\n */ var Integrator;\n (function(Integrator) {\n Integrator[Integrator[\"Euler\"] = 0] = \"Euler\";\n })(Integrator || (Integrator = {}));\n /**\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ /* istanbul ignore next */ class Physics {\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ static get gravity() {\n return Physics.acc;\n }\n static set gravity(v) {\n Physics.acc = v;\n }\n /**\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ static useArcadePhysics() {\n Physics.collisionResolutionStrategy = SolverStrategy.Arcade;\n }\n /**\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\n * simulated physical interactions.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ static useRealisticPhysics() {\n Physics.collisionResolutionStrategy = SolverStrategy.Realistic;\n }\n }\n /**\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\n *\n * This is a great way to globally simulate effects like gravity.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.acc = new Vector(0, 0);\n /**\n * Globally switches all Excalibur physics behavior on or off.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.enabled = true;\n /**\n * Gets or sets the broadphase pair identification strategy.\n *\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\n * potential collision pairs which is O(nlog(n)) faster.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.broadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\n /**\n * Gets or sets the global collision resolution strategy (narrowphase).\n *\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics.\n *\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\n * simulated physical interactions.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.collisionResolutionStrategy = SolverStrategy.Arcade;\n /**\n * The default mass to use if none is specified\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.defaultMass = 10;\n /**\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.integrator = Integrator.Euler;\n /**\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.dynamicTreeVelocityMultiplier = 2;\n /**\n * Pad RigidBody BoundingBox by a constant amount\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.boundsPadding = 5;\n /**\n * Number of position iterations (overlap) to run in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.positionIterations = 3;\n /**\n * Number of velocity iteration (response) to run in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.velocityIterations = 8;\n /**\n * Amount of overlap to tolerate in pixels\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.slop = 1;\n /**\n * Amount of positional overlap correction to apply each position iteration of the solver\n * O - meaning no correction, 1 - meaning correct all overlap\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.steeringFactor = 0.2;\n /**\n * Warm start set to true re-uses impulses from previous frames back in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.warmStart = true;\n /**\n * By default bodies do not sleep\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.bodiesCanSleepByDefault = false;\n /**\n * Surface epsilon is used to help deal with surface penetration\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.surfaceEpsilon = 0.1;\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.sleepEpsilon = 0.07;\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.wakeThreshold = Physics.sleepEpsilon * 3;\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.sleepBias = 0.9;\n /**\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\n * bodies from tunneling through one another.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.checkForFastBodies = true;\n /**\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\n * Excalibur will always perform the fast body raycast regardless of speed.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */ Physics.disableMinimumSpeedForFastBody = false;\n /**\n * Tells the Arcade collision solver to prefer certain contacts over others\n */ var ContactSolveBias;\n (function(ContactSolveBias) {\n ContactSolveBias[\"None\"] = \"none\";\n ContactSolveBias[\"VerticalFirst\"] = \"vertical-first\";\n ContactSolveBias[\"HorizontalFirst\"] = \"horizontal-first\";\n })(ContactSolveBias || (ContactSolveBias = {}));\n /**\n * Vertical First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\n */ const VerticalFirst = {\n \"vertical\": 1,\n \"horizontal\": 2\n };\n /**\n * Horizontal First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\n */ const HorizontalFirst = {\n \"horizontal\": 1,\n \"vertical\": 2\n };\n /**\n * None value, [[ArcadeSolver]] sorts contacts using distance by default\n */ const None = {\n \"horizontal\": 0,\n \"vertical\": 0\n };\n const DefaultPhysicsConfig = {\n enabled: true,\n gravity: vec(0, 0),\n solver: SolverStrategy.Arcade,\n colliders: {\n compositeStrategy: \"together\"\n },\n continuous: {\n checkForFastBodies: true,\n disableMinimumSpeedForFastBody: false,\n surfaceEpsilon: 0.1\n },\n bodies: {\n canSleepByDefault: false,\n sleepEpsilon: 0.07,\n wakeThreshold: 0.07 * 3,\n sleepBias: 0.9,\n defaultMass: 10\n },\n dynamicTree: {\n boundsPadding: 5,\n velocityMultiplier: 2\n },\n arcade: {\n contactSolveBias: ContactSolveBias.None\n },\n realistic: {\n positionIterations: 3,\n velocityIterations: 8,\n slop: 1,\n steeringFactor: 0.2,\n warmStart: true\n }\n };\n /**\n * @deprecated will be removed in v0.30\n */ function DeprecatedStaticToConfig() {\n return {\n enabled: Physics.enabled,\n gravity: Physics.gravity,\n solver: Physics.collisionResolutionStrategy,\n continuous: {\n checkForFastBodies: Physics.checkForFastBodies,\n disableMinimumSpeedForFastBody: Physics.disableMinimumSpeedForFastBody,\n surfaceEpsilon: Physics.surfaceEpsilon\n },\n colliders: {\n compositeStrategy: \"together\"\n },\n bodies: {\n canSleepByDefault: Physics.bodiesCanSleepByDefault,\n sleepEpsilon: Physics.sleepEpsilon,\n wakeThreshold: Physics.wakeThreshold,\n sleepBias: Physics.sleepBias,\n defaultMass: Physics.defaultMass\n },\n dynamicTree: {\n boundsPadding: Physics.boundsPadding,\n velocityMultiplier: Physics.dynamicTreeVelocityMultiplier\n },\n arcade: {\n contactSolveBias: ContactSolveBias.None\n },\n realistic: {\n positionIterations: Physics.positionIterations,\n velocityIterations: Physics.velocityIterations,\n slop: Physics.slop,\n steeringFactor: Physics.steeringFactor,\n warmStart: Physics.warmStart\n }\n };\n }\n class CompositeCollider extends Collider {\n /**\n * Treat composite collider's member colliders as either separate colliders for the purposes of onCollisionStart/onCollision\n * or as a single collider together.\n *\n * This property can be overridden on individual [[CompositeColliders]].\n *\n * For composites without gaps or small groups of colliders, you probably want 'together'\n *\n * For composites with deliberate gaps, like a platforming level layout, you probably want 'separate'\n *\n * Default is 'together' if unset\n */ set compositeStrategy(value) {\n this._compositeStrategy = value;\n }\n get compositeStrategy() {\n return this._compositeStrategy;\n }\n constructor(colliders){\n super();\n this._collisionProcessor = new DynamicTreeCollisionProcessor(DefaultPhysicsConfig);\n this._dynamicAABBTree = new DynamicTree(DefaultPhysicsConfig.dynamicTree);\n this._colliders = [];\n for (const c of colliders)this.addCollider(c);\n }\n clearColliders() {\n this._colliders = [];\n }\n addCollider(collider) {\n let colliders;\n if (collider instanceof CompositeCollider) {\n colliders = collider.getColliders();\n colliders.forEach((c)=>c.offset.addEqual(collider.offset));\n } else colliders = [\n collider\n ];\n // Flatten composites\n for (const c of colliders){\n c.events.pipe(this.events);\n c.composite = this;\n this._colliders.push(c);\n this._collisionProcessor.track(c);\n this._dynamicAABBTree.trackCollider(c);\n }\n }\n removeCollider(collider) {\n collider.events.pipe(this.events);\n collider.composite = null;\n removeItemFromArray(collider, this._colliders);\n this._collisionProcessor.untrack(collider);\n this._dynamicAABBTree.untrackCollider(collider);\n }\n getColliders() {\n return this._colliders;\n }\n get worldPos() {\n var _a, _b;\n return ((_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero).add(this.offset);\n }\n get center() {\n var _a, _b;\n return ((_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero).add(this.offset);\n }\n get bounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider)=>acc.combine(collider.bounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox().translate(this.worldPos));\n return results.translate(this.offset);\n }\n get localBounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider)=>acc.combine(collider.localBounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox());\n return results;\n }\n get axes() {\n // TODO cache this\n const colliders = this.getColliders();\n let axes = [];\n for (const collider of colliders)axes = axes.concat(collider.axes);\n return axes;\n }\n getFurthestPoint(direction) {\n const colliders = this.getColliders();\n const furthestPoints = [];\n for (const collider of colliders)furthestPoints.push(collider.getFurthestPoint(direction));\n // Pick best point from all colliders\n let bestPoint = furthestPoints[0];\n let maxDistance = -Number.MAX_VALUE;\n for (const point of furthestPoints){\n const distance = point.dot(direction);\n if (distance > maxDistance) {\n bestPoint = point;\n maxDistance = distance;\n }\n }\n return bestPoint;\n }\n getInertia(mass) {\n const colliders = this.getColliders();\n let totalInertia = 0;\n for (const collider of colliders)totalInertia += collider.getInertia(mass);\n return totalInertia;\n }\n collide(other) {\n let otherColliders = [\n other\n ];\n if (other instanceof CompositeCollider) otherColliders = other.getColliders();\n const pairs = [];\n for (const c of otherColliders)this._dynamicAABBTree.query(c, (potentialCollider)=>{\n pairs.push(new Pair(c, potentialCollider));\n return false;\n });\n let contacts = [];\n for (const p of pairs)contacts = contacts.concat(p.collide());\n return contacts;\n }\n getClosestLineBetween(other) {\n const colliders = this.getColliders();\n const lines = [];\n if (other instanceof CompositeCollider) {\n const otherColliders = other.getColliders();\n for (const colliderA of colliders)for (const colliderB of otherColliders){\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\n if (maybeLine) lines.push(maybeLine);\n }\n } else for (const collider of colliders){\n const maybeLine = other.getClosestLineBetween(collider);\n if (maybeLine) lines.push(maybeLine);\n }\n if (lines.length) {\n let minLength = lines[0].getLength();\n let minLine = lines[0];\n for (const line of lines){\n const length = line.getLength();\n if (length < minLength) {\n minLength = length;\n minLine = line;\n }\n }\n return minLine;\n }\n return null;\n }\n contains(point) {\n const colliders = this.getColliders();\n for (const collider of colliders){\n if (collider.contains(point)) return true;\n }\n return false;\n }\n rayCast(ray, max) {\n const colliders = this.getColliders();\n const hits = [];\n for (const collider of colliders){\n const hit = collider.rayCast(ray, max);\n if (hit) hits.push(hit);\n }\n if (hits.length) {\n let minHit = hits[0];\n let minDistance = minHit.point.dot(ray.dir);\n for (const hit of hits){\n const distance = ray.dir.dot(hit.point);\n if (distance < minDistance) {\n minHit = hit;\n minDistance = distance;\n }\n }\n return minHit;\n }\n return null;\n }\n project(axis) {\n const colliders = this.getColliders();\n const projections = [];\n for (const collider of colliders){\n const proj = collider.project(axis);\n if (proj) projections.push(proj);\n }\n // Merge all proj's on the same axis\n if (projections.length) {\n const newProjection = new Projection(projections[0].min, projections[0].max);\n for (const proj of projections){\n newProjection.min = Math.min(proj.min, newProjection.min);\n newProjection.max = Math.max(proj.max, newProjection.max);\n }\n return newProjection;\n }\n return null;\n }\n update(transform) {\n if (transform) {\n const colliders = this.getColliders();\n for (const collider of colliders){\n collider.owner = this.owner;\n collider.update(transform);\n }\n }\n }\n debug(ex, color, options) {\n const colliders = this.getColliders();\n ex.save();\n ex.translate(this.offset.x, this.offset.y);\n for (const collider of colliders)collider.debug(ex, color, options);\n ex.restore();\n }\n clone() {\n const result = new CompositeCollider(this._colliders.map((c)=>c.clone()));\n result.offset = this.offset.clone();\n return result;\n }\n }\n /**\n * A 2D line segment\n */ class LineSegment {\n /**\n * @param begin The starting point of the line segment\n * @param end The ending point of the line segment\n */ constructor(begin, end){\n this.begin = begin;\n this.end = end;\n }\n /**\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\n */ get slope() {\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\n }\n /**\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\n */ get intercept() {\n return this.begin.y - this.slope * this.begin.x;\n }\n /**\n * Gets the normal of the line\n */ normal() {\n if (this._normal) return this._normal;\n return this._normal = this.end.sub(this.begin).normal();\n }\n dir() {\n if (this._dir) return this._dir;\n return this._dir = this.end.sub(this.begin);\n }\n getPoints() {\n return [\n this.begin,\n this.end\n ];\n }\n /**\n * Returns the slope of the line in the form of a vector of length 1\n */ getSlope() {\n if (this._slope) return this._slope;\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._slope = end.sub(begin).scale(1 / distance);\n }\n /**\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\n */ getEdge() {\n const begin = this.begin;\n const end = this.end;\n return end.sub(begin);\n }\n /**\n * Returns the length of the line segment in pixels\n */ getLength() {\n if (this._length) return this._length;\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._length = distance;\n }\n /**\n * Returns the midpoint of the edge\n */ get midpoint() {\n return this.begin.add(this.end).scale(0.5);\n }\n /**\n * Flips the direction of the line segment\n */ flip() {\n return new LineSegment(this.end, this.begin);\n }\n /**\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\n * @param point\n */ below(point) {\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\n return above2 >= 0;\n }\n /**\n * Returns the clip point\n * @param sideVector Vector that traces the line\n * @param length Length to clip along side\n */ clip(sideVector, length) {\n let dir = sideVector;\n dir = dir.normalize();\n const near = dir.dot(this.begin) - length;\n const far = dir.dot(this.end) - length;\n const results = [];\n if (near <= 0) results.push(this.begin);\n if (far <= 0) results.push(this.end);\n if (near * far < 0) {\n const clipTime = near / (near - far);\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\n }\n if (results.length !== 2) return null;\n return new LineSegment(results[0], results[1]);\n }\n /**\n * Find the perpendicular distance from the line to a point\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\n * @param point\n */ distanceToPoint(point, signed = false) {\n const x0 = point.x;\n const y0 = point.y;\n const l = this.getLength();\n const dy = this.end.y - this.begin.y;\n const dx = this.end.x - this.begin.x;\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\n return signed ? distance : Math.abs(distance);\n }\n /**\n * Find the perpendicular line from the line to a point\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\n * (a - p) - ((a - p) * n)n\n * a is a point on the line\n * p is the arbitrary point above the line\n * n is a unit vector in direction of the line\n * @param point\n */ findVectorToPoint(point) {\n const aMinusP = this.begin.sub(point);\n const n = this.getSlope();\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\n }\n /**\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\n * a new point with the calculated Y value and vice-versa.\n * @param x The known X value of the target point\n * @param y The known Y value of the target point\n * @returns A new point with the other calculated axis value\n */ findPoint(x = null, y = null) {\n const m = this.slope;\n const b = this.intercept;\n if (x !== null) return new Vector(x, m * x + b);\n else if (y !== null) return new Vector((y - b) / m, y);\n else throw new Error(\"You must provide an X or a Y value\");\n }\n /**\n * @see http://stackoverflow.com/a/11908158/109458\n */ hasPoint() {\n let currPoint;\n let threshold = 0;\n if (typeof arguments[0] === \"number\" && typeof arguments[1] === \"number\") {\n currPoint = new Vector(arguments[0], arguments[1]);\n threshold = arguments[2] || 0;\n } else if (arguments[0] instanceof Vector) {\n currPoint = arguments[0];\n threshold = arguments[1] || 0;\n } else throw \"Could not determine the arguments for Vector.hasPoint\";\n const dxc = currPoint.x - this.begin.x;\n const dyc = currPoint.y - this.begin.y;\n const dx1 = this.end.x - this.begin.x;\n const dy1 = this.end.y - this.begin.y;\n const cross = dxc * dy1 - dyc * dx1;\n // check whether point lines on the line\n if (Math.abs(cross) > threshold) return false;\n // check whether point lies in-between start and end\n if (Math.abs(dx1) >= Math.abs(dy1)) return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\n else return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\n }\n }\n /**\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n * @param p0 Point where L1 begins\n * @param u Direction and length of L1\n * @param q0 Point were L2 begins\n * @param v Direction and length of L2\n */ function ClosestLine(p0, u, q0, v) {\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\n // w(s, t) = P(s) - Q(t)\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\n //\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\n //\n // The closest point between 2 lines then satisfies this pair of equations\n // 1: u * wClosest = 0\n // 2: v * wClosest = 0\n //\n // Substituting wClosest into the equations we get\n //\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\n // simplify w0\n const w0 = p0.sub(q0);\n // simplify (u * u);\n const a = u.dot(u);\n // simplify (u * v);\n const b = u.dot(v);\n // simplify (v * v)\n const c = v.dot(v);\n // simplify (u * w0)\n const d = u.dot(w0);\n // simplify (v * w0)\n const e = v.dot(w0);\n // denominator ac - b^2\n const denom = a * c - b * b;\n let sDenom = denom;\n let tDenom = denom;\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\n if (denom === 0 || denom <= 0.01) {\n const tClosestParallel = d / b;\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\n }\n // Solve for sClosest for infinite line\n let sClosest = b * e - c * d; // / denom;\n // Solve for tClosest for infinite line\n let tClosest = a * e - b * d; // / denom;\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\n if (sClosest < 0) {\n sClosest = 0;\n tClosest = e;\n tDenom = c;\n } else if (sClosest > sDenom) {\n sClosest = sDenom;\n tClosest = e + b;\n tDenom = c;\n }\n if (tClosest < 0) {\n tClosest = 0;\n if (-d < 0) sClosest = 0;\n else if (-d > a) sClosest = sDenom;\n else {\n sClosest = -d;\n sDenom = a;\n }\n } else if (tClosest > tDenom) {\n tClosest = tDenom;\n if (-d + b < 0) sClosest = 0;\n else if (-d + b > a) sClosest = sDenom;\n else {\n sClosest = -d + b;\n sDenom = a;\n }\n }\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\n }\n const ClosestLineJumpTable = {\n PolygonPolygonClosestLine (polygonA, polygonB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = polygonB.worldPos;\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\n const thisDirection = otherDirection.negate();\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\n const thisPoint = polygonA.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const otherPoint = polygonB.rayCast(rayTowardsThis).point.add(rayTowardsThis.dir.scale(0.1));\n const thisFace = polygonA.getClosestFace(thisPoint);\n const otherFace = polygonB.getClosestFace(otherPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const q0 = otherFace.face.begin;\n const v = otherFace.face.getEdge();\n return ClosestLine(p0, u, q0, v);\n },\n PolygonEdgeClosestLine (polygon, edge) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = edge.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const q0 = edgeStart;\n const v = edgeVector;\n return ClosestLine(p0, u, q0, v);\n },\n PolygonCircleClosestLine (polygon, circle) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circle.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // Time of minimum distance\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp\n if (t > 1) t = 1;\n else if (t < 0) t = 0;\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\n const circlex = (p0.x + u.x * t - otherWorldPos.x) * circle.radius / (circle.radius + d);\n const circley = (p0.y + u.y * t - otherWorldPos.y) * circle.radius / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\n },\n CircleCircleClosestLine (circleA, circleB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circleB.worldPos;\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\n const thisWorldPos = circleA.worldPos;\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\n const thisPoint = circleA.rayCast(rayTowardsOther);\n const otherPoint = circleB.rayCast(rayTowardsThis);\n return new LineSegment(thisPoint.point, otherPoint.point);\n },\n CircleEdgeClosestLine (circle, edge) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n const circleWorldPos = circle.worldPos;\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const p0 = edgeStart;\n const u = edgeVector;\n // Time of minimum distance\n let t = (u.x * (circleWorldPos.x - p0.x) + u.y * (circleWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp to edge\n if (t > 1) t = 1;\n else if (t < 0) t = 0;\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorldPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorldPos.y, 2)) - circle.radius;\n const circlex = (p0.x + u.x * t - circleWorldPos.x) * circle.radius / (circle.radius + d);\n const circley = (p0.y + u.y * t - circleWorldPos.y) * circle.radius / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorldPos.x + circlex, circleWorldPos.y + circley));\n },\n EdgeEdgeClosestLine (edgeA, edgeB) {\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLineA = edgeA.asLine();\n const edgeStartA = edgeLineA.begin;\n const edgeVectorA = edgeLineA.getEdge();\n const p0 = edgeStartA;\n const u = edgeVectorA;\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLineB = edgeB.asLine();\n const edgeStartB = edgeLineB.begin;\n const edgeVectorB = edgeLineB.getEdge();\n const q0 = edgeStartB;\n const v = edgeVectorB;\n return ClosestLine(p0, u, q0, v);\n }\n };\n /**\n * This is a circle collider for the excalibur rigid body physics simulation\n */ class CircleCollider extends Collider {\n get worldPos() {\n return this._globalMatrix.getPosition();\n }\n /**\n * Get the radius of the circle\n */ get radius() {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n return this._naturalRadius * Math.min(scale.x, scale.y);\n }\n /**\n * Set the radius of the circle\n */ set radius(val) {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n this._naturalRadius = val / Math.min(scale.x, scale.y);\n }\n constructor(options){\n super();\n /**\n * Position of the circle relative to the collider, by default (0, 0).\n */ this.offset = Vector.Zero;\n this._globalMatrix = AffineMatrix.identity();\n this.offset = options.offset || Vector.Zero;\n this.radius = options.radius || 0;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Returns a clone of this shape, not associated with any collider\n */ clone() {\n return new CircleCollider({\n offset: this.offset.clone(),\n radius: this.radius\n });\n }\n /**\n * Get the center of the collider in world coordinates\n */ get center() {\n return this._globalMatrix.getPosition();\n }\n /**\n * Tests if a point is contained in this collider\n */ contains(point) {\n var _a, _b;\n const pos = (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : this.offset;\n const distance = pos.distance(point);\n if (distance <= this.radius) return true;\n return false;\n }\n /**\n * Casts a ray at the Circle collider and returns the nearest point of collision\n * @param ray\n */ rayCast(ray, max = Infinity) {\n var _a, _b;\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\n const c = this.center;\n const dir = ray.dir;\n const orig = ray.pos;\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\n if (discriminant < 0) // no intersection\n return null;\n else {\n let toi = 0;\n // tangent case\n if (discriminant === 0) {\n toi = -dir.dot(orig.sub(c));\n if (toi > 0 && toi < max) {\n const point = ray.getPoint(toi);\n return {\n point: point,\n normal: point.sub(c).normalize(),\n collider: this,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n distance: toi\n };\n }\n return null;\n } else {\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\n const positiveToi = [];\n if (toi1 >= 0) positiveToi.push(toi1);\n if (toi2 >= 0) positiveToi.push(toi2);\n const minToi = Math.min(...positiveToi);\n if (minToi <= max) {\n const point = ray.getPoint(minToi);\n return {\n point: point,\n normal: point.sub(c).normalize(),\n collider: this,\n body: (_b = this.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent),\n distance: minToi\n };\n }\n return null;\n }\n }\n }\n getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\n else if (shape instanceof PolygonCollider) return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\n else if (shape instanceof EdgeCollider) return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\n * @inheritdoc\n */ collide(collider) {\n if (collider instanceof CircleCollider) return CollisionJumpTable.CollideCircleCircle(this, collider);\n else if (collider instanceof PolygonCollider) return CollisionJumpTable.CollideCirclePolygon(this, collider);\n else if (collider instanceof EdgeCollider) return CollisionJumpTable.CollideCircleEdge(this, collider);\n else throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */ getFurthestPoint(direction) {\n return this.center.add(direction.normalize().scale(this.radius));\n }\n /**\n * Find the local point on the shape in the direction specified\n * @param direction\n */ getFurthestLocalPoint(direction) {\n const dir = direction.normalize();\n return dir.scale(this.radius);\n }\n /**\n * Get the axis aligned bounding box for the circle collider in world coordinates\n */ get bounds() {\n var _a, _b, _c;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = (_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero;\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius).rotate(rotation).scale(scale).translate(pos);\n }\n /**\n * Get the axis aligned bounding box for the circle collider in local coordinates\n */ get localBounds() {\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius);\n }\n /**\n * Get axis not implemented on circles, since there are infinite axis in a circle\n */ get axes() {\n return [];\n }\n /**\n * Returns the moment of inertia of a circle given it's mass\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */ getInertia(mass) {\n return mass * this.radius * this.radius / 2;\n }\n /* istanbul ignore next */ update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Project the circle along a specified axis\n */ project(axis) {\n const scalars = [];\n const point = this.center;\n const dotProduct = point.dot(axis);\n scalars.push(dotProduct);\n scalars.push(dotProduct + this.radius);\n scalars.push(dotProduct - this.radius);\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color, options) {\n var _a, _b, _c, _d;\n const { lineWidth: lineWidth } = {\n lineWidth: 1,\n ...options\n };\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = (_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero;\n ex.save();\n ex.translate(pos.x, pos.y);\n ex.rotate(rotation);\n ex.scale(scale.x, scale.y);\n ex.drawCircle((_d = this.offset) !== null && _d !== void 0 ? _d : Vector.Zero, this._naturalRadius, Color.Transparent, color, lineWidth);\n ex.restore();\n }\n }\n /**\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\n * Pair prevents collisions from being evaluated more than one time\n */ class CollisionContact {\n constructor(colliderA, colliderB, mtv, normal, tangent, points, localPoints, info){\n var _a, _b, _c, _d, _e, _f;\n this._canceled = false;\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.mtv = mtv;\n this.normal = normal;\n this.tangent = tangent;\n this.points = points;\n this.localPoints = localPoints;\n this.info = info;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n if (colliderA.composite || colliderB.composite) {\n // Add on the parent composite pair for start/end contact if 'together\n const colliderAId = ((_a = colliderA.composite) === null || _a === void 0 ? void 0 : _a.compositeStrategy) === \"separate\" ? colliderA.id : (_c = (_b = colliderA.composite) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : colliderA.id;\n const colliderBId = ((_d = colliderB.composite) === null || _d === void 0 ? void 0 : _d.compositeStrategy) === \"separate\" ? colliderB.id : (_f = (_e = colliderB.composite) === null || _e === void 0 ? void 0 : _e.id) !== null && _f !== void 0 ? _f : colliderB.id;\n this.id += \"|\" + Pair.calculatePairHash(colliderAId, colliderBId);\n }\n }\n /**\n * Match contact awake state, except if body's are Fixed\n */ matchAwake() {\n const bodyA = this.colliderA.owner.get(BodyComponent);\n const bodyB = this.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.sleeping !== bodyB.sleeping) {\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= bodyA.wakeThreshold) bodyA.setSleeping(false);\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= bodyB.wakeThreshold) bodyB.setSleeping(false);\n }\n }\n }\n isCanceled() {\n return this._canceled;\n }\n cancel() {\n this._canceled = true;\n }\n }\n class SeparatingAxis {\n static findPolygonPolygonSeparation(polyA, polyB) {\n let bestSeparation = -Number.MAX_VALUE;\n let bestSide = null;\n let bestAxis = null;\n let bestSideIndex = -1;\n let bestOtherPoint = null;\n const sides = polyA.getSides();\n const localSides = polyA.getLocalSides();\n for(let i = 0; i < sides.length; i++){\n const side = sides[i];\n const axis = side.normal();\n const vertB = polyB.getFurthestPoint(axis.negate());\n // Separation on side i's axis\n // We are looking for the largest separation between poly A's sides\n const vertSeparation = side.distanceToPoint(vertB, true);\n if (vertSeparation > bestSeparation) {\n bestSeparation = vertSeparation;\n bestSide = side;\n bestAxis = axis;\n bestSideIndex = i;\n bestOtherPoint = vertB;\n }\n }\n return {\n collider: polyA,\n separation: bestAxis ? bestSeparation : 99,\n axis: bestAxis,\n side: bestSide,\n localSide: localSides[bestSideIndex],\n sideId: bestSideIndex,\n point: bestOtherPoint,\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis.negate()) : null\n };\n }\n static findCirclePolygonSeparation(circle, polygon) {\n const axes = polygon.axes;\n const pc = polygon.center;\n // Special SAT with circles\n const polyDir = pc.sub(circle.worldPos);\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\n let minOverlap = Number.MAX_VALUE;\n let minAxis = null;\n let minIndex = -1;\n for(let i = 0; i < axes.length; i++){\n const proj1 = polygon.project(axes[i]);\n const proj2 = circle.project(axes[i]);\n const overlap = proj1.getOverlap(proj2);\n if (overlap <= 0) return null;\n else if (overlap < minOverlap) {\n minOverlap = overlap;\n minAxis = axes[i];\n minIndex = i;\n }\n }\n if (minIndex < 0) return null;\n return minAxis.normalize().scale(minOverlap);\n }\n }\n const CollisionJumpTable = {\n CollideCircleCircle (circleA, circleB) {\n const circleAPos = circleA.worldPos;\n const circleBPos = circleB.worldPos;\n const combinedRadius = circleA.radius + circleB.radius;\n const distance = circleAPos.distance(circleBPos);\n if (distance > combinedRadius) return [];\n // negative means overlap\n const separation = combinedRadius - distance;\n // Normal points from A -> B\n const normal = circleBPos.sub(circleAPos).normalize();\n const tangent = normal.perpendicular();\n const mvt = normal.scale(separation);\n const point = circleA.getFurthestPoint(normal);\n const local = circleA.getFurthestLocalPoint(normal);\n const info = {\n collider: circleA,\n separation: separation,\n axis: normal,\n point: point\n };\n return [\n new CollisionContact(circleA, circleB, mvt, normal, tangent, [\n point\n ], [\n local\n ], info)\n ];\n },\n CollideCirclePolygon (circle, polygon) {\n var _a, _b;\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\n if (!minAxis) return [];\n // make sure that the minAxis is pointing away from circle\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\n const point = circle.getFurthestPoint(minAxis);\n const xf = (_b = (_a = circle.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const local = xf.applyInverse(point);\n const normal = minAxis.normalize();\n const info = {\n collider: circle,\n separation: -minAxis.size,\n axis: normal,\n point: point,\n localPoint: local,\n side: polygon.findSide(normal.negate()),\n localSide: polygon.findLocalSide(normal.negate())\n };\n return [\n new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [\n point\n ], [\n local\n ], info)\n ];\n },\n CollideCircleEdge (circle, edge) {\n // TODO not sure this actually abides by local/world collisions\n // Are edge.begin and edge.end local space or world space? I think they should be local\n // center of the circle in world pos\n const cc = circle.center;\n // vector in the direction of the edge\n const edgeWorld = edge.asLine();\n const e = edgeWorld.end.sub(edgeWorld.begin);\n // amount of overlap with the circle's center along the edge direction\n const u = e.dot(edgeWorld.end.sub(cc));\n const v = e.dot(cc.sub(edgeWorld.begin));\n const side = edge.asLine();\n const localSide = edge.asLocalLine();\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\n if (v <= 0) {\n const da = edgeWorld.begin.sub(cc);\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\n // save some sqrts\n if (dda > circle.radius * circle.radius) return []; // no collision\n const normal = da.normalize();\n const separation = circle.radius - Math.sqrt(dda);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.begin,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [\n side.begin\n ], [\n localSide.begin\n ], info)\n ];\n }\n // Potential region B collision (circle is on the right side of the edge, after the end)\n if (u <= 0) {\n const db = edgeWorld.end.sub(cc);\n const ddb = db.dot(db);\n if (ddb > circle.radius * circle.radius) return [];\n const normal = db.normalize();\n const separation = circle.radius - Math.sqrt(ddb);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.end,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [\n side.end\n ], [\n localSide.end\n ], info)\n ];\n }\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\n const den = e.dot(e);\n const pointOnEdge = edgeWorld.begin.scale(u).add(edgeWorld.end.scale(v)).scale(1 / den);\n const d = cc.sub(pointOnEdge);\n const dd = d.dot(d);\n if (dd > circle.radius * circle.radius) return []; // no collision\n let normal = e.perpendicular();\n // flip correct direction\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\n normal.x = -normal.x;\n normal.y = -normal.y;\n }\n normal = normal.normalize();\n const separation = circle.radius - Math.sqrt(dd);\n const mvt = normal.scale(separation);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: pointOnEdge,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, mvt, normal.negate(), normal.negate().perpendicular(), [\n pointOnEdge\n ], [\n pointOnEdge.sub(edge.worldPos)\n ], info)\n ];\n },\n CollideEdgeEdge () {\n // Edge-edge collision doesn't make sense\n return [];\n },\n CollidePolygonEdge (polygon, edge) {\n var _a;\n const pc = polygon.center;\n const ec = edge.center;\n const dir = ec.sub(pc).normalize();\n // build a temporary polygon from the edge to use SAT\n const linePoly = new PolygonCollider({\n points: [\n edge.begin,\n edge.end,\n edge.end.add(dir.scale(100)),\n edge.begin.add(dir.scale(100))\n ],\n offset: edge.offset\n });\n linePoly.owner = edge.owner;\n const tx = (_a = edge.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (tx) linePoly.update(edge.owner.get(TransformComponent).get());\n // Gross hack but poly-poly works well\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\n if (contact.length) {\n // Fudge the contact back to edge\n contact[0].colliderB = edge;\n contact[0].id = Pair.calculatePairHash(polygon.id, edge.id);\n }\n return contact;\n },\n CollidePolygonPolygon (polyA, polyB) {\n var _a, _b, _c, _d;\n // Multi contact from SAT\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\n // do a SAT test to find a min axis if it exists\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\n // If there is no overlap from boxA's perspective we can end early\n if (separationA.separation > 0) return [];\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\n // If there is no overlap from boxB's perspective exit now\n if (separationB.separation > 0) return [];\n // Separations are both negative, we want to pick the least negative (minimal movement)\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\n // The incident side is the most opposite from the axes of collision on the other collider\n const other = separation.collider === polyA ? polyB : polyA;\n const incident = other.findSide(separation.axis.negate());\n // Clip incident side by the perpendicular lines at each end of the reference side\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\n const reference = separation.side;\n const refDir = reference.dir().normalize();\n // Find our contact points by clipping the incident by the collision side\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\n let clipLeft = null;\n if (clipRight) clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\n // If there is no left there is no collision\n if (clipLeft) {\n // We only want clip points below the reference edge, discard the others\n const points = clipLeft.getPoints().filter((p)=>{\n return reference.below(p);\n });\n let normal = separation.axis;\n let tangent = normal.perpendicular();\n // Point Contact A -> B\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\n normal = normal.negate();\n tangent = normal.perpendicular();\n }\n // Points are clipped from incident which is the other collider\n // Store those as locals\n let localPoints = [];\n if (separation.collider === polyA) {\n const xf = (_b = (_a = polyB.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n localPoints = points.map((p)=>xf.applyInverse(p));\n } else {\n const xf = (_d = (_c = polyA.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n localPoints = points.map((p)=>xf.applyInverse(p));\n }\n return [\n new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)\n ];\n }\n return [];\n },\n FindContactSeparation (contact, localPoint) {\n var _a, _b, _c, _d;\n const shapeA = contact.colliderA;\n const txA = (_b = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const shapeB = contact.colliderB;\n const txB = (_d = (_c = contact.colliderB.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n // both are circles\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\n const combinedRadius = shapeA.radius + shapeB.radius;\n const distance = txA.pos.distance(txB.pos);\n const separation = combinedRadius - distance;\n return -separation;\n }\n // both are polygons\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\n if (contact.info.localSide) {\n let side;\n let worldPoint;\n if (contact.info.collider === shapeA) {\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\n worldPoint = txB.apply(localPoint);\n } else {\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\n worldPoint = txA.apply(localPoint);\n }\n return side.distanceToPoint(worldPoint, true);\n }\n }\n // polygon v circle\n if (shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider || shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider) {\n const worldPoint = txA.apply(localPoint);\n if (contact.info.side) return contact.info.side.distanceToPoint(worldPoint, true);\n }\n // polygon v edge\n if (shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider || shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider) {\n let worldPoint;\n if (contact.info.collider === shapeA) worldPoint = txB.apply(localPoint);\n else worldPoint = txA.apply(localPoint);\n if (contact.info.side) return contact.info.side.distanceToPoint(worldPoint, true);\n }\n // circle v edge\n if (shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider || shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider) {\n // Local point is always on the edge which is always shapeB\n const worldPoint = txB.apply(localPoint);\n let circlePoint;\n if (shapeA instanceof CircleCollider) circlePoint = shapeA.getFurthestPoint(contact.normal);\n const dist = worldPoint.distance(circlePoint);\n if (contact.info.side) return dist > 0 ? -dist : 0;\n }\n return 0;\n }\n };\n /**\n * Edge is a single line collider to create collisions with a single line.\n */ class EdgeCollider extends Collider {\n constructor(options){\n var _a;\n super();\n this._globalMatrix = AffineMatrix.identity();\n this.begin = options.begin || Vector.Zero;\n this.end = options.end || Vector.Zero;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n }\n /**\n * Returns a clone of this Edge, not associated with any collider\n */ clone() {\n return new EdgeCollider({\n begin: this.begin.clone(),\n end: this.end.clone()\n });\n }\n get worldPos() {\n var _a;\n const tx = this._transform;\n return (_a = tx === null || tx === void 0 ? void 0 : tx.globalPos.add(this.offset)) !== null && _a !== void 0 ? _a : this.offset;\n }\n /**\n * Get the center of the collision area in world coordinates\n */ get center() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const pos = begin.average(end);\n return pos;\n }\n _getTransformedBegin() {\n return this._globalMatrix.multiply(this.begin);\n }\n _getTransformedEnd() {\n return this._globalMatrix.multiply(this.end);\n }\n /**\n * Returns the slope of the line in the form of a vector\n */ getSlope() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return end.sub(begin).scale(1 / distance);\n }\n /**\n * Returns the length of the line segment in pixels\n */ getLength() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return distance;\n }\n /**\n * Tests if a point is contained in this collision area\n */ contains() {\n return false;\n }\n /**\n * @inheritdoc\n */ rayCast(ray, max = Infinity) {\n var _a;\n const numerator = this._getTransformedBegin().sub(ray.pos);\n // Test is line and ray are parallel and non intersecting\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) return null;\n // Lines are parallel\n const divisor = ray.dir.cross(this.getSlope());\n if (divisor === 0) return null;\n const t = numerator.cross(this.getSlope()) / divisor;\n if (t >= 0 && t <= max) {\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\n if (u >= 0 && u <= 1) return {\n distance: t,\n normal: this.asLine().normal(),\n collider: this,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n point: ray.getPoint(t)\n };\n }\n return null;\n }\n /**\n * Returns the closes line between this and another collider, from this -> collider\n * @param shape\n */ getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\n else if (shape instanceof PolygonCollider) return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\n else if (shape instanceof EdgeCollider) return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\n * @inheritdoc\n */ collide(shape) {\n if (shape instanceof CircleCollider) return CollisionJumpTable.CollideCircleEdge(shape, this);\n else if (shape instanceof PolygonCollider) return CollisionJumpTable.CollidePolygonEdge(shape, this);\n else if (shape instanceof EdgeCollider) return CollisionJumpTable.CollideEdgeEdge();\n else throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */ getFurthestPoint(direction) {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n if (direction.dot(transformedBegin) > 0) return transformedBegin;\n else return transformedEnd;\n }\n _boundsFromBeginEnd(begin, end, padding = 10) {\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\n // this causes problems for the collision system so we give them some padding\n return new BoundingBox(Math.min(begin.x, end.x) - padding, Math.min(begin.y, end.y) - padding, Math.max(begin.x, end.x) + padding, Math.max(begin.y, end.y) + padding);\n }\n /**\n * Get the axis aligned bounding box for the edge collider in world space\n */ get bounds() {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\n }\n /**\n * Get the axis aligned bounding box for the edge collider in local space\n */ get localBounds() {\n return this._boundsFromBeginEnd(this.begin, this.end);\n }\n /**\n * Returns this edge represented as a line in world coordinates\n */ asLine() {\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\n }\n /**\n * Return this edge as a line in local line coordinates (relative to the position)\n */ asLocalLine() {\n return new LineSegment(this.begin, this.end);\n }\n /**\n * Get the axis associated with the edge\n */ get axes() {\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\n const edgeNormal = e.normal();\n const axes = [];\n axes.push(edgeNormal);\n axes.push(edgeNormal.negate());\n axes.push(edgeNormal.normal());\n axes.push(edgeNormal.normal().negate());\n return axes;\n }\n /**\n * Get the moment of inertia for an edge\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */ getInertia(mass) {\n const length = this.end.sub(this.begin).distance() / 2;\n return mass * length * length;\n }\n /**\n * @inheritdoc\n */ update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Project the edge along a specified axis\n */ project(axis) {\n const scalars = [];\n const points = [\n this._getTransformedBegin(),\n this._getTransformedEnd()\n ];\n const len = points.length;\n for(let i = 0; i < len; i++)scalars.push(points[i].dot(axis));\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color) {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n ex.drawLine(begin, end, color, 2);\n ex.drawCircle(begin, 2, color);\n ex.drawCircle(end, 2, color);\n }\n }\n class Debug {\n static registerGraphicsContext(ctx) {\n Debug._ctx = ctx;\n }\n static draw(debugDrawCall) {\n this._drawCalls.push(debugDrawCall);\n }\n static drawPoint(point, options) {\n Debug.draw((ctx)=>{\n ctx.debug.drawPoint(point, options);\n });\n }\n static drawLine(start, end, options) {\n Debug.draw((ctx)=>{\n ctx.debug.drawLine(start, end, options);\n });\n }\n static drawLines(points, options) {\n if (points.length > 1) Debug.draw((ctx)=>{\n for(let i = 0; i < points.length - 1; i++)ctx.debug.drawLine(points[i], points[i + 1], options);\n });\n }\n static drawText(text, pos) {\n Debug.draw((ctx)=>{\n ctx.debug.drawText(text, pos);\n });\n }\n static drawPolygon(points, options) {\n if (points.length > 1) Debug.draw((ctx)=>{\n const firstPoint = points[0];\n const polygon = [\n ...points,\n firstPoint\n ];\n for(let i = 0; i < polygon.length - 1; i++)ctx.debug.drawLine(polygon[i], polygon[i + 1], options);\n });\n }\n static drawCircle(center, radius, options) {\n const { color: color, strokeColor: strokeColor, width: width } = {\n color: Color.Black,\n strokeColor: undefined,\n width: undefined,\n ...options\n };\n Debug.draw((ctx)=>{\n ctx.drawCircle(center, radius, color, strokeColor, width);\n });\n }\n static drawBounds(boundingBox, options) {\n Debug.draw((ctx)=>{\n ctx.debug.drawRect(boundingBox.left, boundingBox.top, boundingBox.width, boundingBox.height, options);\n });\n }\n static drawRay(ray, options) {\n const { distance: distance, color: color } = {\n color: Color.Blue,\n distance: 10,\n ...options\n };\n Debug.draw((ctx)=>{\n const start = ray.pos;\n const end = ray.pos.add(ray.dir.scale(distance));\n ctx.debug.drawLine(start, end, {\n color: color\n });\n });\n }\n static flush(ctx) {\n ctx.save();\n ctx.z = Debug.z;\n for (const drawCall of Debug._drawCalls)drawCall(ctx);\n ctx.restore();\n Debug.clear();\n }\n static clear() {\n Debug._drawCalls.length = 0;\n }\n }\n Debug._drawCalls = [];\n Debug.z = Infinity;\n /**\n * Polygon collider for detecting collisions\n */ class PolygonCollider extends Collider {\n flagDirty() {\n this._localBoundsDirty = true;\n this._localSidesDirty = true;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n }\n /**\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\n * Excalibur stores these in counter-clockwise order\n */ set points(points) {\n this._points = points;\n this.flagDirty();\n }\n /**\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\n * Excalibur stores these in counter-clockwise order\n */ get points() {\n return this._points;\n }\n constructor(options){\n var _a, _b;\n super();\n this._logger = Logger.getInstance();\n this._transformedPoints = [];\n this._sides = [];\n this._localSides = [];\n this._globalMatrix = AffineMatrix.identity();\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n this._localSidesDirty = true;\n this._localBoundsDirty = true;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n this.points = (_b = options.points) !== null && _b !== void 0 ? _b : [];\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\n if (!counterClockwise) this.points.reverse();\n if (!this.isConvex()) {\n if (!options.suppressConvexWarning) this._logger.warn(\"Excalibur only supports convex polygon colliders and will not behave properly.Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles\");\n }\n // calculate initial transformation\n this._calculateTransformation();\n }\n _isCounterClockwiseWinding(points) {\n // https://stackoverflow.com/a/1165943\n let sum = 0;\n for(let i = 0; i < points.length; i++)sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\n return sum < 0;\n }\n /**\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\n */ isConvex() {\n // From SO: https://stackoverflow.com/a/45372025\n if (this.points.length < 3) return false;\n let oldPoint = this.points[this.points.length - 2];\n let newPoint = this.points[this.points.length - 1];\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n let oldDirection = 0;\n let orientation = 0;\n let angleSum = 0;\n for (const [i, point] of this.points.entries()){\n oldPoint = newPoint;\n oldDirection = direction;\n newPoint = point;\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n if (oldPoint.equals(newPoint)) return false; // repeat point\n let angle = direction - oldDirection;\n if (angle <= -Math.PI) angle += Math.PI * 2;\n else if (angle > Math.PI) angle -= Math.PI * 2;\n if (i === 0) {\n if (angle === 0.0) return false;\n orientation = angle > 0 ? 1 : -1;\n } else {\n if (orientation * angle <= 0) return false;\n }\n angleSum += angle;\n }\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\n }\n /**\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\n */ tessellate() {\n const polygons = [];\n for(let i = 1; i < this.points.length - 2; i++)polygons.push([\n this.points[0],\n this.points[i + 1],\n this.points[i + 2]\n ]);\n polygons.push([\n this.points[0],\n this.points[1],\n this.points[2]\n ]);\n return new CompositeCollider(polygons.map((points)=>Shape.Polygon(points)));\n }\n /**\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\n */ triangulate() {\n // https://www.youtube.com/watch?v=hTJFcHutls8\n if (this.points.length < 3) throw Error(\"Invalid polygon\");\n const triangles = [];\n // algorithm likes clockwise\n const vertices = [\n ...this.points\n ].reverse();\n let vertexCount = vertices.length;\n /**\n * Returns the previous index based on the current vertex\n */ function getPrevIndex(index) {\n return index === 0 ? vertexCount - 1 : index - 1;\n }\n /**\n * Retrieves the next index based on the current vertex\n */ function getNextIndex(index) {\n return index === vertexCount - 1 ? 0 : index + 1;\n }\n /**\n * Whether or not the angle at this vertex index is convex\n */ function isConvex(index) {\n const prev = getPrevIndex(index);\n const next = getNextIndex(index);\n const va = vertices[prev];\n const vb = vertices[index];\n const vc = vertices[next];\n // Check convexity\n const leftArm = va.sub(vb);\n const rightArm = vc.sub(vb);\n // Positive cross product is convex\n if (leftArm.cross(rightArm) < 0) return false;\n return true;\n }\n const convexVertices = vertices.map((_, i)=>isConvex(i));\n /**\n * Quick test for point in triangle\n */ function isPointInTriangle(point, a, b, c) {\n const ab = b.sub(a);\n const bc = c.sub(b);\n const ca = a.sub(c);\n const ap = point.sub(a);\n const bp = point.sub(b);\n const cp = point.sub(c);\n const cross1 = ab.cross(ap);\n const cross2 = bc.cross(bp);\n const cross3 = ca.cross(cp);\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) return false;\n return true;\n }\n /**\n * Calculate the area of the triangle\n */ // function triangleArea(a: Vector, b: Vector, c: Vector) {\n // return Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - c.y))/2;\n // }\n /**\n * Find the next suitable ear tip\n */ function findEarTip() {\n for(let i = 0; i < vertexCount; i++)if (convexVertices[i]) {\n const prev = getPrevIndex(i);\n const next = getNextIndex(i);\n const va = vertices[prev];\n const vb = vertices[i];\n const vc = vertices[next];\n let isEar = true;\n // Check that if any vertices are in the triangle a, b, c\n for(let j = 0; j < vertexCount; j++){\n // We can skip these verts because they are the triangle we are testing\n if (j === i || j === prev || j === next) continue;\n const point = vertices[j];\n if (isPointInTriangle(point, va, vb, vc)) {\n isEar = false;\n break;\n }\n }\n // Add ear to polygon list and remove from list\n if (isEar) return i;\n }\n // Fall back to any convex vertex\n for(let i = 0; i < vertexCount; i++){\n if (convexVertices[i]) return i;\n }\n // bail and return the first one?\n return 0;\n }\n /**\n * Cut the ear and produce a triangle, update internal state\n */ function cutEarTip(index) {\n const prev = getPrevIndex(index);\n const next = getNextIndex(index);\n const va = vertices[prev];\n const vb = vertices[index];\n const vc = vertices[next];\n // Clockwise winding\n // if (triangleArea(va, vb, vc) > 0) {\n triangles.push([\n va,\n vb,\n vc\n ]);\n // }\n vertices.splice(index, 1);\n convexVertices.splice(index, 1);\n vertexCount--;\n }\n // Loop over all the vertices finding ears\n while(vertexCount > 3){\n const earIndex = findEarTip();\n cutEarTip(earIndex);\n // reclassify vertices\n for(let i = 0; i < vertexCount; i++)convexVertices[i] = isConvex(i);\n }\n // Last triangle after the loop\n triangles.push([\n vertices[0],\n vertices[1],\n vertices[2]\n ]);\n // FIXME: there is a colinear triangle that sneaks in here sometimes\n return new CompositeCollider(triangles.map((points)=>Shape.Polygon(points, Vector.Zero, true)));\n }\n /**\n * Returns a clone of this ConvexPolygon, not associated with any collider\n */ clone() {\n return new PolygonCollider({\n offset: this.offset.clone(),\n points: this.points.map((p)=>p.clone())\n });\n }\n /**\n * Returns the world position of the collider, which is the current body transform plus any defined offset\n */ get worldPos() {\n if (this._transform) return this._transform.pos.add(this.offset);\n return this.offset;\n }\n /**\n * Get the center of the collider in world coordinates\n */ get center() {\n return this.bounds.center;\n }\n /**\n * Calculates the underlying transformation from the body relative space to world space\n */ _calculateTransformation() {\n const points = this.points;\n const len = points.length;\n this._transformedPoints.length = 0; // clear out old transform\n for(let i = 0; i < len; i++)this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\n }\n /**\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\n */ getTransformedPoints() {\n if (this._transformedPointsDirty) {\n this._calculateTransformation();\n this._transformedPointsDirty = false;\n }\n return this._transformedPoints;\n }\n /**\n * Gets the sides of the polygon in world space\n */ getSides() {\n if (this._sidesDirty) {\n const lines = [];\n const points = this.getTransformedPoints();\n const len = points.length;\n for(let i = 0; i < len; i++)// This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n this._sides = lines;\n this._sidesDirty = false;\n }\n return this._sides;\n }\n /**\n * Returns the local coordinate space sides\n */ getLocalSides() {\n if (this._localSidesDirty) {\n const lines = [];\n const points = this.points;\n const len = points.length;\n for(let i = 0; i < len; i++)// This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n this._localSides = lines;\n this._localSidesDirty = false;\n }\n return this._localSides;\n }\n /**\n * Given a direction vector find the world space side that is most in that direction\n * @param direction\n */ findSide(direction) {\n const sides = this.getSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let side = 0; side < sides.length; side++){\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\n * Given a direction vector find the local space side that is most in that direction\n * @param direction\n */ findLocalSide(direction) {\n const sides = this.getLocalSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let side = 0; side < sides.length; side++){\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\n * Get the axis associated with the convex polygon\n */ get axes() {\n const axes = [];\n const sides = this.getSides();\n for(let i = 0; i < sides.length; i++)axes.push(sides[i].normal());\n return axes;\n }\n /**\n * Updates the transform for the collision geometry\n *\n * Collision geometry (points/bounds) will not change until this is called.\n * @param transform\n */ update(transform) {\n var _a;\n if (transform) {\n this._transform = transform;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n // This change means an update must be performed in order for geometry to update\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n }\n /**\n * Tests if a point is contained in this collider in world space\n */ contains(point) {\n // Always cast to the right, as long as we cast in a consistent fixed direction we\n // will be fine\n const testRay = new Ray(point, new Vector(1, 0));\n const intersectCount = this.getSides().reduce(function(accum, side) {\n if (testRay.intersect(side) >= 0) return accum + 1;\n return accum;\n }, 0);\n if (intersectCount % 2 === 0) return false;\n return true;\n }\n getClosestLineBetween(collider) {\n if (collider instanceof CircleCollider) return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\n else if (collider instanceof PolygonCollider) return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\n else if (collider instanceof EdgeCollider) return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\n * return null.\n * @param collider\n */ collide(collider) {\n if (collider instanceof CircleCollider) return CollisionJumpTable.CollideCirclePolygon(collider, this);\n else if (collider instanceof PolygonCollider) return CollisionJumpTable.CollidePolygonPolygon(this, collider);\n else if (collider instanceof EdgeCollider) return CollisionJumpTable.CollidePolygonEdge(this, collider);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */ getFurthestPoint(direction) {\n const pts = this.getTransformedPoints();\n let furthestPoint = null;\n let maxDistance = -Number.MAX_VALUE;\n for(let i = 0; i < pts.length; i++){\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\n * Find the local point on the collider furthest in the direction specified\n * @param direction\n */ getFurthestLocalPoint(direction) {\n const pts = this.points;\n let furthestPoint = pts[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let i = 0; i < pts.length; i++){\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\n * Finds the closes face to the point using perpendicular distance\n * @param point point to test against polygon\n */ getClosestFace(point) {\n const sides = this.getSides();\n let min = Number.POSITIVE_INFINITY;\n let faceIndex = -1;\n let distance = -1;\n for(let i = 0; i < sides.length; i++){\n const dist = sides[i].distanceToPoint(point);\n if (dist < min) {\n min = dist;\n faceIndex = i;\n distance = dist;\n }\n }\n if (faceIndex !== -1) return {\n distance: sides[faceIndex].normal().scale(distance),\n face: sides[faceIndex]\n };\n return null;\n }\n /**\n * Get the axis aligned bounding box for the polygon collider in world coordinates\n */ get bounds() {\n return this.localBounds.transform(this._globalMatrix);\n }\n /**\n * Get the axis aligned bounding box for the polygon collider in local coordinates\n */ get localBounds() {\n if (this._localBoundsDirty) {\n this._localBounds = BoundingBox.fromPoints(this.points);\n this._localBoundsDirty = false;\n }\n return this._localBounds;\n }\n /**\n * Get the moment of inertia for an arbitrary polygon\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */ getInertia(mass) {\n if (this._cachedMass === mass && this._cachedInertia) return this._cachedInertia;\n let numerator = 0;\n let denominator = 0;\n const points = this.points;\n for(let i = 0; i < points.length; i++){\n const iplusone = (i + 1) % points.length;\n const crossTerm = points[iplusone].cross(points[i]);\n numerator += crossTerm * (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\n denominator += crossTerm;\n }\n this._cachedMass = mass;\n return this._cachedInertia = mass / 6 * (numerator / denominator);\n }\n /**\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\n */ rayCast(ray, max = Infinity) {\n var _a;\n // find the minimum contact time greater than 0\n // contact times less than 0 are behind the ray and we don't want those\n const sides = this.getSides();\n const len = sides.length;\n let minContactTime = Number.MAX_VALUE;\n let contactSide;\n let contactIndex = -1;\n for(let i = 0; i < len; i++){\n const contactTime = ray.intersect(sides[i]);\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\n minContactTime = contactTime;\n contactSide = sides[i];\n contactIndex = i;\n }\n }\n // contact was found\n if (contactIndex >= 0) return {\n collider: this,\n distance: minContactTime,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n point: ray.getPoint(minContactTime),\n normal: contactSide.normal()\n };\n // no contact found\n return null;\n }\n /**\n * Project the edges of the polygon along a specified axis\n */ project(axis) {\n const points = this.getTransformedPoints();\n const len = points.length;\n let min = Number.MAX_VALUE;\n let max = -Number.MAX_VALUE;\n for(let i = 0; i < len; i++){\n const scalar = points[i].dot(axis);\n min = Math.min(min, scalar);\n max = Math.max(max, scalar);\n }\n return new Projection(min, max);\n }\n debug(ex, color, options) {\n const points = this.getTransformedPoints();\n Debug.drawPolygon(points, {\n color: color\n });\n }\n }\n /**\n * Excalibur helper for defining colliders quickly\n */ class Shape {\n /**\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\n * @param width Width of the box\n * @param height Height of the box\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\n * @param offset Optional offset relative to the collider in local coordinates\n */ static Box(width, height, anchor = Vector.Half, offset = Vector.Zero) {\n return new PolygonCollider({\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\n offset: offset\n });\n }\n /**\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\n *\n * PolygonColliders are useful for creating convex polygon shapes\n * @param points Points specified in counter clockwise\n * @param offset Optional offset relative to the collider in local coordinates\n */ static Polygon(points, offset = Vector.Zero, suppressConvexWarning = false) {\n return new PolygonCollider({\n points: points,\n offset: offset,\n suppressConvexWarning: suppressConvexWarning\n });\n }\n /**\n * Creates a new [[CircleCollider|circle]] collider\n *\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\n * @param radius Radius of the circle collider\n * @param offset Optional offset relative to the collider in local coordinates\n */ static Circle(radius, offset = Vector.Zero) {\n return new CircleCollider({\n radius: radius,\n offset: offset\n });\n }\n /**\n * Creates a new [[EdgeCollider|edge]] collider\n *\n * Edge colliders are useful for floors, walls, and other barriers\n * @param begin Beginning of the edge in local coordinates to the collider\n * @param end Ending of the edge in local coordinates to the collider\n */ static Edge(begin, end) {\n return new EdgeCollider({\n begin: begin,\n end: end\n });\n }\n /**\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\n *\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\n * player experience.\n * @param width\n * @param height\n * @param offset Optional offset\n */ static Capsule(width, height, offset = Vector.Zero) {\n const logger = Logger.getInstance();\n if (width === height) logger.warn(\"A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider\");\n const vertical = height >= width;\n if (vertical) {\n // height > width, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\n Shape.Box(width, height - width, Vector.Half, offset),\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\n ]);\n return capsule;\n } else {\n // width > height, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\n Shape.Box(width - height, height, Vector.Half, offset),\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\n ]);\n return capsule;\n }\n }\n }\n class ColliderComponent extends Component {\n constructor(collider){\n super();\n this.events = new EventEmitter();\n /**\n * Observable that notifies when a collider is added to the body\n */ this.$colliderAdded = new Observable();\n /**\n * Observable that notifies when a collider is removed from the body\n */ this.$colliderRemoved = new Observable();\n this._collidersToRemove = [];\n this.set(collider);\n }\n /**\n * Get the current collider geometry\n */ get() {\n return this._collider;\n }\n /**\n * Set the collider geometry\n * @param collider\n * @returns the collider you set\n */ set(collider) {\n this.clear();\n if (collider) {\n this._collider = collider;\n this._collider.owner = this.owner;\n collider.events.pipe(this.events);\n this.$colliderAdded.notifyAll(collider);\n this.update();\n }\n return collider;\n }\n /**\n * Remove collider geometry from collider component\n */ clear() {\n if (this._collider) {\n this._collidersToRemove.push(this._collider);\n this._collider = null;\n }\n }\n processColliderRemoval() {\n for (const collider of this._collidersToRemove){\n collider.events.unpipe(this.events);\n this.$colliderRemoved.notifyAll(collider);\n collider.owner = null;\n }\n }\n clone() {\n const clone = new ColliderComponent(this._collider.clone());\n return clone;\n }\n /**\n * Return world space bounds\n */ get bounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\n * Return local space bounds\n */ get localBounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\n * Update the collider's transformed geometry\n */ update() {\n var _a;\n const tx = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (this._collider) {\n this._collider.owner = this.owner;\n if (tx) this._collider.update(tx.get());\n }\n }\n /**\n * Collide component with another\n * @param other\n */ collide(other) {\n let colliderA = this._collider;\n let colliderB = other._collider;\n if (!colliderA || !colliderB) return [];\n // If we have a composite left hand side :(\n // Might bite us, but to avoid updating all the handlers make composite always left side\n let flipped = false;\n if (colliderB instanceof CompositeCollider) {\n colliderA = colliderB;\n colliderB = this._collider;\n flipped = true;\n }\n if (this._collider) {\n const contacts = colliderA.collide(colliderB);\n if (contacts) {\n if (flipped) contacts.forEach((contact)=>{\n contact.mtv = contact.mtv.negate();\n contact.normal = contact.normal.negate();\n contact.tangent = contact.normal.perpendicular();\n contact.colliderA = this._collider;\n contact.colliderB = other._collider;\n });\n return contacts;\n }\n return [];\n }\n return [];\n }\n onAdd(entity) {\n if (this._collider) this.update();\n // Wire up the collider events to the owning entity\n this.events.on(\"precollision\", (evt)=>{\n const precollision = evt;\n entity.events.emit(\"precollision\", new PreCollisionEvent(precollision.target.owner, precollision.other.owner, precollision.side, precollision.intersection, precollision.contact));\n if (entity instanceof Actor) entity.onPreCollisionResolve(precollision.target, precollision.other, precollision.side, precollision.contact);\n });\n this.events.on(\"postcollision\", (evt)=>{\n const postcollision = evt;\n entity.events.emit(\"postcollision\", new PostCollisionEvent(postcollision.target.owner, postcollision.other.owner, postcollision.side, postcollision.intersection, postcollision.contact));\n if (entity instanceof Actor) entity.onPostCollisionResolve(postcollision.target, postcollision.other, postcollision.side, postcollision.contact);\n });\n this.events.on(\"collisionstart\", (evt)=>{\n const start = evt;\n entity.events.emit(\"collisionstart\", new CollisionStartEvent(start.target.owner, start.other.owner, start.side, start.contact));\n if (entity instanceof Actor) entity.onCollisionStart(start.target, start.other, start.side, start.contact);\n });\n this.events.on(\"collisionend\", (evt)=>{\n const end = evt;\n entity.events.emit(\"collisionend\", new CollisionEndEvent(end.target.owner, end.other.owner, end.side, end.lastContact));\n if (entity instanceof Actor) entity.onCollisionEnd(end.target, end.other, end.side, end.lastContact);\n });\n }\n onRemove() {\n this.events.clear();\n this.$colliderRemoved.notifyAll(this._collider);\n }\n /**\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\n *\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */ useBoxCollider(width, height, anchor = Vector.Half, center = Vector.Zero) {\n const collider = Shape.Box(width, height, anchor, center);\n return this.set(collider);\n }\n /**\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\n * to the anchor of the associated actor\n * of this physics body.\n *\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */ usePolygonCollider(points, center = Vector.Zero) {\n const poly = Shape.Polygon(points, center);\n return this.set(poly);\n }\n /**\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */ useCircleCollider(radius, center = Vector.Zero) {\n const collider = Shape.Circle(radius, center);\n return this.set(collider);\n }\n /**\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\n * of this physics body.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */ useEdgeCollider(begin, end) {\n const collider = Shape.Edge(begin, end);\n return this.set(collider);\n }\n /**\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\n * @param colliders\n */ useCompositeCollider(colliders) {\n return this.set(new CompositeCollider(colliders));\n }\n }\n var DegreeOfFreedom;\n (function(DegreeOfFreedom) {\n DegreeOfFreedom[\"Rotation\"] = \"rotation\";\n DegreeOfFreedom[\"X\"] = \"x\";\n DegreeOfFreedom[\"Y\"] = \"y\";\n })(DegreeOfFreedom || (DegreeOfFreedom = {}));\n /**\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\n * of physics simulation.\n */ class BodyComponent extends Component {\n constructor(options){\n var _a, _b, _c;\n super();\n this.dependencies = [\n TransformComponent,\n MotionComponent\n ];\n this.id = createId(\"body\", BodyComponent._ID++);\n this.events = new EventEmitter();\n this.oldTransform = new transform_Transform();\n /**\n * Indicates whether the old transform has been captured at least once for interpolation\n * @internal\n */ this.__oldTransformCaptured = false;\n /**\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\n */ this.enableFixedUpdateInterpolate = true;\n /**\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\n */ this.collisionType = CollisionType.PreventCollision;\n /**\n * The collision group for the body's colliders, by default body colliders collide with everything\n */ this.group = CollisionGroup.All;\n this._sleeping = false;\n /**\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\n */ this.bounciness = 0.2;\n /**\n * The coefficient of friction on this actor\n */ this.friction = 0.99;\n /**\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\n */ this.useGravity = true;\n /**\n * Degrees of freedom to limit\n *\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\n */ this.limitDegreeOfFreedom = [];\n /**\n * The velocity of the actor last frame (vx, vy) in pixels/second\n */ this.oldVel = new Vector(0, 0);\n /**\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */ this.oldAcc = Vector.Zero;\n if (options) {\n this.collisionType = (_a = options.type) !== null && _a !== void 0 ? _a : this.collisionType;\n this.group = (_b = options.group) !== null && _b !== void 0 ? _b : this.group;\n this.useGravity = (_c = options.useGravity) !== null && _c !== void 0 ? _c : this.useGravity;\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies,\n ...options.config\n };\n } else this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies\n };\n this.updatePhysicsConfig(this._bodyConfig);\n this._mass = BodyComponent._DEFAULT_CONFIG.defaultMass;\n }\n get matrix() {\n return this.transform.get().matrix;\n }\n /**\n * Called by excalibur to update physics config defaults if they change\n * @param config\n */ updatePhysicsConfig(config) {\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies,\n ...config\n };\n this.canSleep = this._bodyConfig.canSleepByDefault;\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\n this.wakeThreshold = this._bodyConfig.wakeThreshold;\n }\n /**\n * Called by excalibur to update defaults\n * @param config\n */ static updateDefaultPhysicsConfig(config) {\n BodyComponent._DEFAULT_CONFIG = config;\n }\n get mass() {\n return this._mass;\n }\n set mass(newMass) {\n this._mass = newMass;\n this._cachedInertia = undefined;\n this._cachedInverseInertia = undefined;\n }\n /**\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\n */ get inverseMass() {\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\n }\n /**\n * Whether this body is sleeping or not\n */ get sleeping() {\n return this._sleeping;\n }\n /**\n * Set the sleep state of the body\n * @param sleeping\n */ setSleeping(sleeping) {\n this._sleeping = sleeping;\n if (!sleeping) // Give it a kick to keep it from falling asleep immediately\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\n else {\n this.vel = Vector.Zero;\n this.acc = Vector.Zero;\n this.angularVelocity = 0;\n this.sleepMotion = 0;\n }\n }\n /**\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\n */ updateMotion() {\n if (this._sleeping) this.setSleeping(true);\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\n const bias = this._bodyConfig.sleepBias;\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * this._bodyConfig.sleepEpsilon);\n if (this.canSleep && this.sleepMotion < this._bodyConfig.sleepEpsilon) this.setSleeping(true);\n }\n /**\n * Get the moment of inertia from the [[ColliderComponent]]\n */ get inertia() {\n if (this._cachedInertia) return this._cachedInertia;\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\n const collider = this.owner.get(ColliderComponent);\n if (collider) {\n collider.$colliderAdded.subscribe(()=>{\n this._cachedInertia = null;\n });\n collider.$colliderRemoved.subscribe(()=>{\n this._cachedInertia = null;\n });\n const maybeCollider = collider.get();\n if (maybeCollider) return this._cachedInertia = maybeCollider.getInertia(this.mass);\n }\n return 0;\n }\n /**\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\n */ get inverseInertia() {\n if (this._cachedInverseInertia) return this._cachedInverseInertia;\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\n }\n /**\n * Returns if the owner is active\n */ get active() {\n var _a;\n return !!((_a = this.owner) === null || _a === void 0 ? void 0 : _a.active);\n }\n /**\n * @deprecated Use globalP0s\n */ get center() {\n return this.globalPos;\n }\n get transform() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n }\n get motion() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(MotionComponent);\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n /**\n * The (x, y) position of the actor this will be in the middle of the actor if the\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\n */ get globalPos() {\n return this.transform.globalPos;\n }\n set globalPos(val) {\n this.transform.globalPos = val;\n }\n /**\n * The position of the actor last frame (x, y) in pixels\n */ get oldPos() {\n return this.oldTransform.pos;\n }\n /**\n * The current velocity vector (vx, vy) of the actor in pixels/second\n */ get vel() {\n return this.motion.vel;\n }\n set vel(val) {\n this.motion.vel = val;\n }\n /**\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\n * be useful to simulate a gravitational effect.\n */ get acc() {\n return this.motion.acc;\n }\n set acc(val) {\n this.motion.acc = val;\n }\n /**\n * The current torque applied to the actor\n */ get torque() {\n return this.motion.torque;\n }\n set torque(val) {\n this.motion.torque = val;\n }\n /**\n * Gets/sets the rotation of the body from the last frame.\n */ get oldRotation() {\n return this.oldTransform.rotation;\n }\n /**\n * The rotation of the body in radians\n */ get rotation() {\n return this.transform.globalRotation;\n }\n set rotation(val) {\n this.transform.globalRotation = val;\n }\n /**\n * The scale vector of the actor\n */ get scale() {\n return this.transform.globalScale;\n }\n set scale(val) {\n this.transform.globalScale = val;\n }\n /**\n * The scale of the actor last frame\n */ get oldScale() {\n return this.oldTransform.scale;\n }\n /**\n * The scale rate of change of the actor in scale/second\n */ get scaleFactor() {\n return this.motion.scaleFactor;\n }\n set scaleFactor(scaleFactor) {\n this.motion.scaleFactor = scaleFactor;\n }\n /**\n * Get the angular velocity in radians/second\n */ get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\n * Set the angular velocity in radians/second\n */ set angularVelocity(value) {\n this.motion.angularVelocity = value;\n }\n /**\n * Apply a specific impulse to the body\n * @param point\n * @param impulse\n */ applyImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) finalImpulse.x = 0;\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) finalImpulse.y = 0;\n this.vel.addEqual(finalImpulse);\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\n * Apply only linear impulse to the body\n * @param impulse\n */ applyLinearImpulse(impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) finalImpulse.x = 0;\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) finalImpulse.y = 0;\n this.vel = this.vel.add(finalImpulse);\n }\n /**\n * Apply only angular impulse to the body\n * @param point\n * @param impulse\n */ applyAngularImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\n * Sets the old versions of pos, vel, acc, and scale.\n */ captureOldTransform() {\n // Capture old values before integration step updates them\n this.__oldTransformCaptured = true;\n const tx = this.transform.get();\n tx.clone(this.oldTransform);\n this.oldTransform.parent = tx.parent; // also grab parent\n this.oldVel.setTo(this.vel.x, this.vel.y);\n this.oldAcc.setTo(this.acc.x, this.acc.y);\n }\n clone() {\n const component = super.clone();\n return component;\n }\n }\n BodyComponent._ID = 0;\n BodyComponent._DEFAULT_CONFIG = {\n ...DefaultPhysicsConfig.bodies\n };\n /**\n * AddedComponent message\n */ class AddedComponent {\n constructor(data){\n this.data = data;\n this.type = \"Component Added\";\n }\n }\n /**\n * Type guard to know if message is f an Added Component\n */ function isAddedComponent(x) {\n return !!x && x.type === \"Component Added\";\n }\n /**\n * RemovedComponent message\n */ class RemovedComponent {\n constructor(data){\n this.data = data;\n this.type = \"Component Removed\";\n }\n }\n /**\n * Type guard to know if message is for a Removed Component\n */ function isRemovedComponent(x) {\n return !!x && x.type === \"Component Removed\";\n }\n const EntityEvents = {\n Initialize: \"initialize\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n Kill: \"kill\"\n };\n /**\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\n *\n * Entities can be strongly typed with the components they contain\n *\n * ```typescript\n * const entity = new Entity();\n * entity.components.a; // Type ComponentA\n * entity.components.b; // Type ComponentB\n * ```\n */ class Entity {\n constructor(componentsOrOptions, name){\n /**\n * The unique identifier for the entity\n */ this.id = Entity._ID++;\n this.name = `Entity#${this.id}`;\n /**\n * Listen to or emit events for an entity\n */ this.events = new EventEmitter();\n this._tags = new Set();\n this.componentAdded$ = new Observable;\n this.componentRemoved$ = new Observable;\n this.tagAdded$ = new Observable;\n this.tagRemoved$ = new Observable;\n /**\n * Current components on the entity\n *\n * **Do not modify**\n *\n * Use addComponent/removeComponent otherwise the ECS will not be notified of changes.\n */ this.components = new Map();\n this._componentsToRemove = [];\n this._instanceOfComponentCacheDirty = true;\n this._instanceOfComponentCache = new Map();\n /**\n * The current scene that the entity is in, if any\n */ this.scene = null;\n /**\n * Whether this entity is active, if set to false it will be reclaimed\n */ this.active = true;\n this._parent = null;\n this.childrenAdded$ = new Observable();\n this.childrenRemoved$ = new Observable();\n this._children = [];\n this._isInitialized = false;\n let componentsToAdd;\n let nameToAdd;\n if (Array.isArray(componentsOrOptions)) {\n componentsToAdd = componentsOrOptions;\n nameToAdd = name;\n } else if (componentsOrOptions && typeof componentsOrOptions === \"object\") {\n const { components: components, name: name } = componentsOrOptions;\n componentsToAdd = components;\n nameToAdd = name;\n }\n if (nameToAdd) this.name = nameToAdd;\n if (componentsToAdd) for (const component of componentsToAdd)this.addComponent(component);\n // this.addComponent(this.tagsComponent);\n }\n /**\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\n * If parented it will be removed from the parent when killed.\n */ kill() {\n if (this.active) {\n this.active = false;\n this.unparent();\n }\n this.emit(\"kill\", new KillEvent(this));\n }\n isKilled() {\n return !this.active;\n }\n /**\n * Specifically get the tags on the entity from [[TagsComponent]]\n */ get tags() {\n return this._tags;\n }\n /**\n * Check if a tag exists on the entity\n * @param tag name to check for\n */ hasTag(tag) {\n return this._tags.has(tag);\n }\n /**\n * Adds a tag to an entity\n * @param tag\n */ addTag(tag) {\n this._tags.add(tag);\n this.tagAdded$.notifyAll(tag);\n }\n /**\n * Removes a tag on the entity\n *\n * Removals are deferred until the end of update\n * @param tag\n */ removeTag(tag) {\n this._tags.delete(tag);\n this.tagRemoved$.notifyAll(tag);\n }\n /**\n * The types of the components on the Entity\n */ get types() {\n return Array.from(this.components.keys());\n }\n /**\n * Returns all component instances on entity\n */ getComponents() {\n return Array.from(this.components.values());\n }\n /**\n * Verifies that an entity has all the required types\n * @param requiredTypes\n */ hasAll(requiredTypes) {\n for(let i = 0; i < requiredTypes.length; i++){\n if (!this.components.has(requiredTypes[i])) return false;\n }\n return true;\n }\n /**\n * Verifies that an entity has all the required tags\n * @param requiredTags\n */ hasAllTags(requiredTags) {\n for(let i = 0; i < requiredTags.length; i++){\n if (!this.tags.has(requiredTags[i])) return false;\n }\n return true;\n }\n _getCachedInstanceOfType(type) {\n if (this._instanceOfComponentCacheDirty) {\n this._instanceOfComponentCacheDirty = false;\n this._instanceOfComponentCache.clear();\n }\n if (this._instanceOfComponentCache.has(type)) return this._instanceOfComponentCache.get(type);\n for (const instance of this.components.values())if (instance instanceof type) {\n this._instanceOfComponentCache.set(type, instance);\n return instance;\n }\n return undefined;\n }\n get(type) {\n const maybeComponent = this._getCachedInstanceOfType(type);\n return maybeComponent !== null && maybeComponent !== void 0 ? maybeComponent : this.components.get(type);\n }\n get parent() {\n return this._parent;\n }\n /**\n * Get the direct children of this entity\n */ get children() {\n return this._children;\n }\n /**\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\n */ unparent() {\n if (this._parent) {\n this._parent.removeChild(this);\n this._parent = null;\n }\n }\n /**\n * Adds an entity to be a child of this entity\n * @param entity\n */ addChild(entity) {\n if (entity.parent === null) {\n if (this.getAncestors().includes(entity)) throw new Error(\"Cycle detected, cannot add entity\");\n this._children.push(entity);\n entity._parent = this;\n this.childrenAdded$.notifyAll(entity);\n } else throw new Error(\"Entity already has a parent, cannot add without unparenting\");\n return this;\n }\n /**\n * Remove an entity from children if it exists\n * @param entity\n */ removeChild(entity) {\n if (entity.parent === this) {\n removeItemFromArray(entity, this._children);\n entity._parent = null;\n this.childrenRemoved$.notifyAll(entity);\n }\n return this;\n }\n /**\n * Removes all children from this entity\n */ removeAllChildren() {\n // Avoid modifying the array issue by walking backwards\n for(let i = this.children.length - 1; i >= 0; i--)this.removeChild(this.children[i]);\n return this;\n }\n /**\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\n */ getAncestors() {\n const result = [\n this\n ];\n let current = this.parent;\n while(current){\n result.push(current);\n current = current.parent;\n }\n return result.reverse();\n }\n /**\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\n */ getDescendants() {\n let result = [\n this\n ];\n let queue = [\n this\n ];\n while(queue.length > 0){\n const curr = queue.pop();\n if (curr) {\n queue = queue.concat(curr.children);\n result = result.concat(curr.children);\n }\n }\n return result;\n }\n /**\n * Creates a deep copy of the entity and a copy of all its components\n */ clone() {\n const newEntity = new Entity();\n for (const c of this.types){\n const componentInstance = this.get(c);\n if (componentInstance) newEntity.addComponent(componentInstance.clone());\n }\n for (const child of this.children)newEntity.addChild(child.clone());\n return newEntity;\n }\n /**\n * Adds a copy of all the components from another template entity as a \"prefab\"\n * @param templateEntity Entity to use as a template\n * @param force Force component replacement if it already exists on the target entity\n */ addTemplate(templateEntity, force = false) {\n for (const c of templateEntity.getComponents())this.addComponent(c.clone(), force);\n for (const child of templateEntity.children)this.addChild(child.clone().addTemplate(child));\n return this;\n }\n /**\n * Adds a component to the entity\n * @param component Component or Entity to add copy of components from\n * @param force Optionally overwrite any existing components of the same type\n */ addComponent(component, force = false) {\n this._instanceOfComponentCacheDirty = true;\n // if component already exists, skip if not forced\n if (this.has(component.constructor)) {\n if (force) // Remove existing component type if exists when forced\n this.removeComponent(component.constructor, true);\n else // early exit component exits\n return this;\n }\n // TODO circular dependencies will be a problem\n if (component.dependencies && component.dependencies.length) for (const ctor of component.dependencies)this.addComponent(new ctor());\n component.owner = this;\n this.components.set(component.constructor, component);\n if (component.onAdd) component.onAdd(this);\n this.componentAdded$.notifyAll(component);\n return this;\n }\n /**\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\n *\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\n * @param typeOrInstance\n * @param force\n */ removeComponent(typeOrInstance, force = false) {\n let type;\n if (isComponentCtor(typeOrInstance)) type = typeOrInstance;\n else type = typeOrInstance.constructor;\n if (force) {\n const componentToRemove = this.components.get(type);\n if (componentToRemove) {\n this.componentRemoved$.notifyAll(componentToRemove);\n componentToRemove.owner = undefined;\n if (componentToRemove.onRemove) componentToRemove.onRemove(this);\n }\n this.components.delete(type); // remove after the notify to preserve typing\n this._instanceOfComponentCacheDirty = true;\n } else this._componentsToRemove.push(type);\n return this;\n }\n clearComponents() {\n const components = this.types;\n for (const c of components)this.removeComponent(c);\n }\n /**\n * @hidden\n * @internal\n */ processComponentRemoval() {\n for (const type of this._componentsToRemove)this.removeComponent(type, true);\n this._componentsToRemove.length = 0;\n }\n /**\n * Check if a component type exists\n * @param type\n */ has(type) {\n return this.components.has(type);\n }\n /**\n * Gets whether the actor is Initialized\n */ get isInitialized() {\n return this._isInitialized;\n }\n /**\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\n *\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n * @internal\n */ _initialize(engine) {\n if (!this.isInitialized) {\n this.onInitialize(engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * `onInitialize` is called before the first update of the entity. This method is meant to be\n * overridden.\n *\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\n */ onInitialize(engine) {\n // Override me\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before an entity is updated.\n */ onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after an entity is updated.\n */ onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n *\n * Entity update lifecycle, called internally\n * @internal\n * @param engine\n * @param delta\n */ update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n for (const child of this.children)child.update(engine, delta);\n this._postupdate(engine, delta);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n if (handler) this.events.off(eventName, handler);\n else this.events.off(eventName);\n }\n }\n Entity._ID = 0;\n /**\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\n * @param graphic\n */ function hasGraphicsTick(graphic) {\n return !!graphic.tick;\n }\n /**\n * Component to manage drawings, using with the position component\n */ class GraphicsComponent extends Component {\n /**\n * Offset to apply to graphics by default\n */ get offset() {\n return new WatchVector(this._offset, ()=>{\n this.recalculateBounds();\n });\n }\n set offset(value) {\n this._offset = value;\n this.recalculateBounds();\n }\n /**\n * Anchor to apply to graphics by default\n */ get anchor() {\n return new WatchVector(this._anchor, ()=>{\n this.recalculateBounds();\n });\n }\n set anchor(value) {\n this._anchor = value;\n this.recalculateBounds();\n }\n constructor(options){\n super();\n this._logger = Logger.getInstance();\n this._current = \"default\";\n this._graphics = {};\n this._options = {};\n this.material = null;\n /**\n * Sets or gets wether any drawing should be visible in this component\n */ this.visible = true;\n /**\n * Sets or gets wither all drawings should have an opacity applied\n */ this.opacity = 1;\n this._offset = Vector.Zero;\n this._anchor = Vector.Half;\n /**\n * Flip all graphics horizontally along the y-axis\n */ this.flipHorizontal = false;\n /**\n * Flip all graphics vertically along the x-axis\n */ this.flipVertical = false;\n /**\n * If set to true graphics added to the component will be copied. This can effect performance, but is useful if you don't want\n * changes to a graphic to effect all the places it is used.\n */ this.copyGraphics = false;\n this._localBounds = null;\n // Defaults\n options = {\n visible: this.visible,\n graphics: {},\n ...options\n };\n const { current: current, anchor: anchor, opacity: opacity, visible: visible, graphics: graphics, offset: offset, copyGraphics: copyGraphics, onPreDraw: onPreDraw, onPostDraw: onPostDraw, onPreTransformDraw: onPreTransformDraw, onPostTransformDraw: onPostTransformDraw } = options;\n for (const [key, graphicOrOptions] of Object.entries(graphics))if (graphicOrOptions instanceof Graphic) this._graphics[key] = graphicOrOptions;\n else {\n this._graphics[key] = graphicOrOptions.graphic;\n this._options[key] = graphicOrOptions.options;\n }\n this.offset = offset !== null && offset !== void 0 ? offset : this.offset;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : this.anchor;\n this.copyGraphics = copyGraphics !== null && copyGraphics !== void 0 ? copyGraphics : this.copyGraphics;\n this.onPreDraw = onPreDraw !== null && onPreDraw !== void 0 ? onPreDraw : this.onPreDraw;\n this.onPostDraw = onPostDraw !== null && onPostDraw !== void 0 ? onPostDraw : this.onPostDraw;\n this.onPreDraw = onPreTransformDraw !== null && onPreTransformDraw !== void 0 ? onPreTransformDraw : this.onPreTransformDraw;\n this.onPostTransformDraw = onPostTransformDraw !== null && onPostTransformDraw !== void 0 ? onPostTransformDraw : this.onPostTransformDraw;\n this.visible = !!visible;\n this._current = current !== null && current !== void 0 ? current : this._current;\n if (current && this._graphics[current]) this.use(current);\n }\n getGraphic(name) {\n return this._graphics[name];\n }\n getOptions(name) {\n return this._options[name];\n }\n /**\n * Get registered graphics names\n */ getNames() {\n return Object.keys(this._graphics);\n }\n /**\n * Returns the currently displayed graphic\n */ get current() {\n return this._graphics[this._current];\n }\n /**\n * Returns the currently displayed graphic offsets\n */ get currentOptions() {\n return this._options[this._current];\n }\n /**\n * Returns all graphics associated with this component\n */ get graphics() {\n return this._graphics;\n }\n /**\n * Returns all graphics options associated with this component\n */ get options() {\n return this._options;\n }\n add(nameOrGraphic, graphicOrOptions, options) {\n let name = \"default\";\n let graphicToSet = null;\n let optionsToSet = undefined;\n if (typeof nameOrGraphic === \"string\" && graphicOrOptions instanceof Graphic) {\n name = nameOrGraphic;\n graphicToSet = graphicOrOptions;\n optionsToSet = options;\n }\n if (nameOrGraphic instanceof Graphic && !(graphicOrOptions instanceof Graphic)) {\n graphicToSet = nameOrGraphic;\n optionsToSet = graphicOrOptions;\n }\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\n this._options[name] = this.copyGraphics ? {\n ...optionsToSet\n } : optionsToSet;\n if (name === \"default\") this.use(\"default\");\n return graphicToSet;\n }\n /**\n * Removes a registered graphic, if the removed graphic is the current it will switch to the default\n * @param name\n */ remove(name) {\n delete this._graphics[name];\n delete this._options[name];\n if (this._current === name) {\n this._current = \"default\";\n this.recalculateBounds();\n }\n }\n /**\n * Shows a graphic, will be removed\n * @param nameOrGraphic\n * @param options\n * @deprecated will be removed in v0.30.0, use `graphics.use(...)`\n */ show(nameOrGraphic, options) {\n return this.use(nameOrGraphic, options);\n }\n /**\n * Use a graphic only, will set the default graphic. Returns the new [[Graphic]]\n *\n * Optionally override the stored options\n * @param nameOrGraphic\n * @param options\n */ use(nameOrGraphic, options) {\n var _a;\n if (nameOrGraphic instanceof Graphic) {\n let graphic = nameOrGraphic;\n if (this.copyGraphics) graphic = nameOrGraphic.clone();\n this._current = \"default\";\n this._graphics[this._current] = graphic;\n this._options[this._current] = options;\n } else {\n this._current = nameOrGraphic;\n this._options[this._current] = options;\n if (!(this._current in this._graphics)) this._logger.warn(`Graphic ${this._current} is not registered with the graphics component owned by ${(_a = this.owner) === null || _a === void 0 ? void 0 : _a.name}. Nothing will be drawn.`);\n }\n this.recalculateBounds();\n return this.current;\n }\n /**\n * Hide currently shown graphic\n */ hide() {\n this._current = \"ex.none\";\n }\n set localBounds(bounds) {\n this._localBounds = bounds;\n }\n recalculateBounds() {\n let bb = new BoundingBox();\n const graphic = this._graphics[this._current];\n const options = this._options[this._current];\n if (!graphic) {\n this._localBounds = bb;\n return;\n }\n let anchor = this.anchor;\n let offset = this.offset;\n if (options === null || options === void 0 ? void 0 : options.anchor) anchor = options.anchor;\n if (options === null || options === void 0 ? void 0 : options.offset) offset = options.offset;\n const bounds = graphic.localBounds;\n const offsetX = -bounds.width * anchor.x + offset.x;\n const offsetY = -bounds.height * anchor.y + offset.y;\n bb = graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(vec(offsetX, offsetY)).combine(bb);\n this._localBounds = bb;\n }\n get localBounds() {\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) this.recalculateBounds();\n return this._localBounds;\n }\n /**\n * Update underlying graphics if necessary, called internally\n * @param elapsed\n * @internal\n */ update(elapsed, idempotencyToken = 0) {\n const graphic = this.current;\n if (graphic && hasGraphicsTick(graphic)) graphic.tick(elapsed, idempotencyToken);\n }\n clone() {\n const graphics = new GraphicsComponent();\n graphics._graphics = {\n ...this._graphics\n };\n graphics._options = {\n ...this._options\n };\n graphics.offset = this.offset.clone();\n graphics.opacity = this.opacity;\n graphics.anchor = this.anchor.clone();\n graphics.copyGraphics = this.copyGraphics;\n graphics.onPreDraw = this.onPreDraw;\n graphics.onPostDraw = this.onPostDraw;\n graphics.visible = this.visible;\n return graphics;\n }\n }\n /**\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\n */ class Rectangle extends Raster {\n constructor(options){\n super(options);\n this.width = options.width;\n this.height = options.height;\n this.rasterize();\n }\n clone() {\n return new Rectangle({\n width: this.width,\n height: this.height,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.color) ctx.fillRect(0, 0, this.width, this.height);\n if (this.strokeColor) ctx.strokeRect(0, 0, this.width, this.height);\n }\n }\n /**\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\n *\n * Circles default to [[ImageFiltering.Blended]]\n */ class Circle extends Raster {\n get radius() {\n return this._radius;\n }\n set radius(value) {\n this._radius = value;\n this.width = this._radius * 2;\n this.height = this._radius * 2;\n this.flagDirty();\n }\n constructor(options){\n var _a, _b, _c;\n super(options);\n this._radius = 0;\n const lineWidth = (_a = options.lineWidth) !== null && _a !== void 0 ? _a : options.strokeColor ? 1 : 0; // default lineWidth in canvas is 1px\n this.padding = (_b = options.padding) !== null && _b !== void 0 ? _b : 2 + lineWidth / 2; // default 2 padding for circles looks nice\n this.radius = options.radius;\n this.filtering = (_c = options.filtering) !== null && _c !== void 0 ? _c : ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Circle({\n radius: this.radius,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.radius > 0) {\n ctx.beginPath();\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\n if (this.color) ctx.fill();\n if (this.strokeColor) ctx.stroke();\n }\n }\n }\n /**\n * Add this component to optionally configure how the pointer\n * system detects pointer events.\n *\n * By default the collider shape is used and graphics bounds is not.\n *\n * If both collider shape and graphics bounds are enabled it will fire events if either or\n * are intersecting the pointer.\n */ class PointerComponent extends Component {\n constructor(){\n super(...arguments);\n /**\n * Use any existing Collider component geometry for pointer events. This is useful if you want\n * user pointer events only to trigger on the same collision geometry used in the collider component\n * for collision resolution. Default is `true`.\n */ this.useColliderShape = true;\n /**\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\n * bounds around the graphic to trigger pointer events. Default is `true`.\n */ this.useGraphicsBounds = true;\n }\n }\n /**\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\n * Given a time, the function will return a value from positive startValue to positive endValue.\n *\n * ```js\n * function Linear (t) {\n * return t * t;\n * }\n *\n * // accelerating from zero velocity\n * function EaseInQuad (t) {\n * return t * t;\n * }\n *\n * // decelerating to zero velocity\n * function EaseOutQuad (t) {\n * return t * (2 - t);\n * }\n *\n * // acceleration until halfway, then deceleration\n * function EaseInOutQuad (t) {\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n * }\n *\n * // accelerating from zero velocity\n * function EaseInCubic (t) {\n * return t * t * t;\n * }\n *\n * // decelerating to zero velocity\n * function EaseOutCubic (t) {\n * return (--t) * t * t + 1;\n * }\n *\n * // acceleration until halfway, then deceleration\n * function EaseInOutCubic (t) {\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n * }\n * ```\n */ class EasingFunctions {\n static CreateReversibleEasingFunction(easing) {\n return (time, start, end, duration)=>{\n if (end < start) return start - (easing(time, end, start, duration) - end);\n else return easing(time, start, end, duration);\n };\n }\n static CreateVectorEasingFunction(easing) {\n return (time, start, end, duration)=>{\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\n };\n }\n }\n EasingFunctions.Linear = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n return endValue * currentTime / duration + startValue;\n });\n EasingFunctions.EaseInQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime + startValue;\n });\n EasingFunctions.EaseOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return -endValue * currentTime * (currentTime - 2) + startValue;\n });\n EasingFunctions.EaseInOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) return endValue / 2 * currentTime * currentTime + startValue;\n currentTime--;\n return -endValue / 2 * (currentTime * (currentTime - 2) - 1) + startValue;\n });\n EasingFunctions.EaseInCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime * currentTime + startValue;\n });\n EasingFunctions.EaseOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n currentTime--;\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\n });\n EasingFunctions.EaseInOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) return endValue / 2 * currentTime * currentTime * currentTime + startValue;\n currentTime -= 2;\n return endValue / 2 * (currentTime * currentTime * currentTime + 2) + startValue;\n });\n /**\n * Action Queues represent an ordered sequence of actions\n *\n * Action queues are part of the [[ActionContext|Action API]] and\n * store the list of actions to be executed for an [[Actor]].\n *\n * Actors implement [[Actor.actions]] which can be manipulated by\n * advanced users to adjust the actions currently being executed in the\n * queue.\n */ class ActionQueue {\n constructor(entity){\n this._actions = [];\n this._currentAction = null;\n this._completedActions = [];\n this._entity = entity;\n }\n /**\n * Add an action to the sequence\n * @param action\n */ add(action) {\n this._actions.push(action);\n }\n /**\n * Remove an action by reference from the sequence\n * @param action\n */ remove(action) {\n const index = this._actions.indexOf(action);\n this._actions.splice(index, 1);\n }\n /**\n * Removes all actions from this sequence\n */ clearActions() {\n this._actions.length = 0;\n this._completedActions.length = 0;\n if (this._currentAction) this._currentAction.stop();\n }\n /**\n *\n * @returns The total list of actions in this sequence complete or not\n */ getActions() {\n return this._actions.concat(this._completedActions);\n }\n /**\n *\n * @returns `true` if there are more actions to process in the sequence\n */ hasNext() {\n return this._actions.length > 0;\n }\n /**\n * @returns `true` if the current sequence of actions is done\n */ isComplete() {\n return this._actions.length === 0;\n }\n /**\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\n */ reset() {\n this._actions = this.getActions();\n const len = this._actions.length;\n for(let i = 0; i < len; i++)this._actions[i].reset();\n this._completedActions = [];\n }\n /**\n * Update the queue which updates actions and handles completing actions\n * @param elapsedMs\n */ update(elapsedMs) {\n if (this._actions.length > 0) {\n if (this._currentAction !== this._actions[0]) {\n this._currentAction = this._actions[0];\n this._entity.emit(\"actionstart\", new ActionStartEvent(this._currentAction, this._entity));\n }\n this._currentAction.update(elapsedMs);\n if (this._currentAction.isComplete(this._entity)) {\n this._entity.emit(\"actioncomplete\", new ActionCompleteEvent(this._currentAction, this._entity));\n const complete = this._actions.shift();\n if (complete) this._completedActions.push(complete);\n }\n }\n }\n }\n class Repeat {\n constructor(entity, repeatBuilder, repeat){\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeat = repeat;\n this._originalRepeat = repeat;\n this._repeatBuilder(this._repeatContext);\n this._repeat--; // current execution is the first repeat\n }\n update(delta) {\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n this._repeat--;\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || this._repeat <= 0 && this._actionQueue.isComplete();\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._repeat = this._originalRepeat;\n }\n }\n /**\n * RepeatForever Action implementation, it is recommended you use the fluent action\n * context API.\n *\n *\n */ class RepeatForever {\n constructor(entity, repeatBuilder){\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeatBuilder(this._repeatContext);\n }\n update(delta) {\n if (this._stopped) return;\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n this._stopped = true;\n this._actionQueue.clearActions();\n }\n reset() {\n return;\n }\n }\n class MoveBy {\n constructor(entity, offsetX, offsetY, speed){\n this._started = false;\n this._stopped = false;\n this._entity = entity;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = new Vector(offsetX, offsetY);\n if (speed <= 0) {\n Logger.getInstance().error(\"Attempted to moveBy with speed less than or equal to zero : \" + speed);\n throw new Error(\"Speed must be greater than 0 pixels per second\");\n }\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = this._start.add(this._offset);\n this._distance = this._offset.size;\n this._dir = this._end.sub(this._start).normalize();\n }\n if (this.isComplete(this._entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n } else this._motion.vel = this._dir.scale(this._speed);\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class MoveTo {\n constructor(entity, destx, desty, speed){\n this.entity = entity;\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = new Vector(destx, desty);\n this._speed = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._distance = this._start.distance(this._end);\n this._dir = this._end.sub(this._start).normalize();\n }\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete(this.entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n /**\n * An enum that describes the strategies that rotation actions can use\n */ var RotationType;\n (function(RotationType) {\n /**\n * Rotation via `ShortestPath` will use the smallest angle\n * between the starting and ending points. This strategy is the default behavior.\n */ RotationType[RotationType[\"ShortestPath\"] = 0] = \"ShortestPath\";\n /**\n * Rotation via `LongestPath` will use the largest angle\n * between the starting and ending points.\n */ RotationType[RotationType[\"LongestPath\"] = 1] = \"LongestPath\";\n /**\n * Rotation via `Clockwise` will travel in a clockwise direction,\n * regardless of the starting and ending points.\n */ RotationType[RotationType[\"Clockwise\"] = 2] = \"Clockwise\";\n /**\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\n * regardless of the starting and ending points.\n */ RotationType[RotationType[\"CounterClockwise\"] = 3] = \"CounterClockwise\";\n })(RotationType || (RotationType = {}));\n class RotateTo {\n constructor(entity, angleRadians, speed, rotationType){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = angleRadians;\n this._speed = speed;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n } else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch(this._rotationType){\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) this._direction = 1;\n else this._direction = -1;\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) this._direction = -1;\n else this._direction = 1;\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortestPathIsPositive) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (!this._shortestPathIsPositive) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class RotateBy {\n constructor(entity, angleRadiansOffset, speed, rotationType){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = angleRadiansOffset;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n this._end = this._start + this._offset;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n } else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch(this._rotationType){\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) this._direction = 1;\n else this._direction = -1;\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) this._direction = -1;\n else this._direction = 1;\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortDistance >= 0) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (this._shortDistance <= 0) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._start = undefined;\n this._currentNonCannonAngle = undefined;\n this._distance = undefined;\n }\n }\n class ScaleTo {\n constructor(entity, scaleX, scaleY, speedX, speedY){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._endX = scaleX;\n this._endY = scaleY;\n this._speedX = speedX;\n this._speedY = speedY;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startX = this._tx.scale.x;\n this._startY = this._tx.scale.y;\n this._distanceX = Math.abs(this._endX - this._startX);\n this._distanceY = Math.abs(this._endY - this._startY);\n }\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\n const directionX = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.x = this._speedX * directionX;\n } else this._motion.scaleFactor.x = 0;\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\n const directionY = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.y = this._speedY * directionY;\n } else this._motion.scaleFactor.y = 0;\n if (this.isComplete()) {\n this._tx.scale = vec(this._endX, this._endY);\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return this._stopped || Math.abs(this._tx.scale.x - this._startX) >= this._distanceX - 0.01 && Math.abs(this._tx.scale.y - this._startY) >= this._distanceY - 0.01;\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class ScaleBy {\n constructor(entity, scaleOffsetX, scaleOffsetY, speed){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\n this._speedX = this._speedY = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startScale = this._tx.scale.clone();\n this._endScale = this._startScale.add(this._offset);\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\n }\n this._motion.scaleFactor.x = this._speedX * this._directionX;\n this._motion.scaleFactor.y = this._speedY * this._directionY;\n if (this.isComplete()) {\n this._tx.scale = this._endScale;\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return this._stopped || Math.abs(this._tx.scale.x - this._startScale.x) >= this._distanceX - 0.01 && Math.abs(this._tx.scale.y - this._startScale.y) >= this._distanceY - 0.01;\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class CallMethod {\n constructor(method){\n this._method = null;\n this._hasBeenCalled = false;\n this._method = method;\n }\n update(_delta) {\n this._method();\n this._hasBeenCalled = true;\n }\n isComplete() {\n return this._hasBeenCalled;\n }\n reset() {\n this._hasBeenCalled = false;\n }\n stop() {\n this._hasBeenCalled = true;\n }\n }\n class EaseTo {\n constructor(entity, x, y, duration, easingFcn){\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._lerpEnd = new Vector(x, y);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) newX = this._lerpStart.x - (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n else newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n if (this._lerpEnd.y < this._lerpStart.y) newY = this._lerpStart.y - (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n else newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n } else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n }\n class EaseBy {\n constructor(entity, offsetX, offsetY, duration, easingFcn){\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._offset = new Vector(offsetX, offsetY);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n this._lerpEnd = this._lerpStart.add(this._offset);\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) newX = this._lerpStart.x - (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n else newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n if (this._lerpEnd.y < this._lerpStart.y) newY = this._lerpStart.y - (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n else newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n } else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n }\n class Blink {\n constructor(entity, timeVisible, timeNotVisible, numBlinks = 1){\n this._timeVisible = 0;\n this._timeNotVisible = 0;\n this._elapsedTime = 0;\n this._totalTime = 0;\n this._stopped = false;\n this._started = false;\n this._graphics = entity.get(GraphicsComponent);\n this._timeVisible = timeVisible;\n this._timeNotVisible = timeNotVisible;\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\n }\n update(delta) {\n if (!this._started) {\n this._started = true;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n if (!this._graphics) return;\n this._elapsedTime += delta;\n this._totalTime += delta;\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\n this._graphics.visible = false;\n this._elapsedTime = 0;\n }\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\n this._graphics.visible = true;\n this._elapsedTime = 0;\n }\n if (this.isComplete()) this._graphics.visible = true;\n }\n isComplete() {\n return this._stopped || this._totalTime >= this._duration;\n }\n stop() {\n if (this._graphics) this._graphics.visible = true;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n }\n class Fade {\n constructor(entity, endOpacity, speed){\n this._multiplier = 1;\n this._started = false;\n this._stopped = false;\n this._graphics = entity.get(GraphicsComponent);\n this._endOpacity = endOpacity;\n this._speed = this._ogspeed = speed;\n }\n update(delta) {\n if (!this._graphics) return;\n if (!this._started) {\n this._started = true;\n this._speed = this._ogspeed;\n // determine direction when we start\n if (this._endOpacity < this._graphics.opacity) this._multiplier = -1;\n else this._multiplier = 1;\n }\n if (this._speed > 0) this._graphics.opacity += this._multiplier * (Math.abs(this._graphics.opacity - this._endOpacity) * delta) / this._speed;\n this._speed -= delta;\n if (this.isComplete()) this._graphics.opacity = this._endOpacity;\n Logger.getInstance().debug(\"[Action fade] Actor opacity:\", this._graphics.opacity);\n }\n isComplete() {\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class Delay {\n constructor(delay){\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n this._delay = delay;\n }\n update(delta) {\n if (!this._started) this._started = true;\n this._elapsedTime += delta;\n }\n isComplete() {\n return this._stopped || this._elapsedTime >= this._delay;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n }\n }\n class Die {\n constructor(entity){\n this._stopped = false;\n this._entity = entity;\n }\n update(_delta) {\n this._entity.get(ActionsComponent).clearActions();\n this._entity.kill();\n this._stopped = true;\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n return;\n }\n reset() {\n return;\n }\n }\n class Follow {\n constructor(entity, entityToFollow, followDistance){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._followTx = entityToFollow.get(TransformComponent);\n this._followMotion = entityToFollow.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\n this._speed = 0;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\n if (actorToFollowSpeed !== 0) this._speed = actorToFollowSpeed;\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n if (this._distanceBetween >= this._maximumDistance) {\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n } else this._motion.vel = vec(0, 0);\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n isComplete() {\n // the actor following should never stop unless specified to do so\n return this._stopped;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class Meet {\n constructor(actor, actorToMeet, speed){\n this._started = false;\n this._stopped = false;\n this._speedWasSpecified = false;\n this._tx = actor.get(TransformComponent);\n this._motion = actor.get(MotionComponent);\n this._meetTx = actorToMeet.get(TransformComponent);\n this._meetMotion = actorToMeet.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\n this._speed = speed || 0;\n if (speed !== undefined) this._speedWasSpecified = true;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) this._speed = actorToMeetSpeed;\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete() {\n return this._stopped || this._distanceBetween <= 1;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._distanceBetween = undefined;\n }\n }\n /**\n * The fluent Action API allows you to perform \"actions\" on\n * [[Actor|Actors]] such as following, moving, rotating, and\n * more. You can implement your own actions by implementing\n * the [[Action]] interface.\n */ class ActionContext {\n constructor(entity){\n this._entity = entity;\n this._queue = new ActionQueue(entity);\n }\n getQueue() {\n return this._queue;\n }\n update(elapsedMs) {\n this._queue.update(elapsedMs);\n }\n /**\n * Clears all queued actions from the Actor\n */ clearActions() {\n this._queue.clearActions();\n }\n runAction(action) {\n action.reset();\n this._queue.add(action);\n return this;\n }\n easeTo(...args) {\n var _a, _b;\n let x = 0;\n let y = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n x = args[0].x;\n y = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n } else {\n x = args[0];\n y = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\n return this;\n }\n easeBy(...args) {\n var _a, _b;\n let offsetX = 0;\n let offsetY = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n offsetX = args[0].x;\n offsetY = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n } else {\n offsetX = args[0];\n offsetY = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\n return this;\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n let x = 0;\n let y = 0;\n let speed = 0;\n if (xOrPos instanceof Vector) {\n x = xOrPos.x;\n y = xOrPos.y;\n speed = yOrSpeed;\n } else {\n x = xOrPos;\n y = yOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveTo(this._entity, x, y, speed));\n return this;\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n let xOffset = 0;\n let yOffset = 0;\n let speed = 0;\n if (xOffsetOrVector instanceof Vector) {\n xOffset = xOffsetOrVector.x;\n yOffset = xOffsetOrVector.y;\n speed = yOffsetOrSpeed;\n } else {\n xOffset = xOffsetOrVector;\n yOffset = yOffsetOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\n return this;\n }\n /**\n * This method will rotate an actor to the specified angle at the speed\n * specified (in radians per second) and return back the actor. This\n * method is part of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadians The angle to rotate to in radians\n * @param speed The angular velocity of the rotation specified in radians per second\n * @param rotationType The [[RotationType]] to use for this rotation\n */ rotateTo(angleRadians, speed, rotationType) {\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\n return this;\n }\n /**\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\n * in radians/sec and return back the actor. This method is part\n * of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\n * @param speed The speed in radians/sec the actor should rotate at\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\n */ rotateBy(angleRadiansOffset, speed, rotationType) {\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\n return this;\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n let sizeX = 1;\n let sizeY = 1;\n let speedX = 0;\n let speedY = 0;\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\n sizeX = sizeXOrVector.x;\n sizeY = sizeXOrVector.y;\n speedX = sizeYOrSpeed.x;\n speedY = sizeYOrSpeed.y;\n }\n if (typeof sizeXOrVector === \"number\" && typeof sizeYOrSpeed === \"number\") {\n sizeX = sizeXOrVector;\n sizeY = sizeYOrSpeed;\n speedX = speedXOrUndefined;\n speedY = speedYOrUndefined;\n }\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\n return this;\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n let sizeOffsetX = 1;\n let sizeOffsetY = 1;\n if (sizeOffsetXOrVector instanceof Vector) {\n sizeOffsetX = sizeOffsetXOrVector.x;\n sizeOffsetY = sizeOffsetXOrVector.y;\n speed = sizeOffsetYOrSpeed;\n }\n if (typeof sizeOffsetXOrVector === \"number\" && typeof sizeOffsetYOrSpeed === \"number\") {\n sizeOffsetX = sizeOffsetXOrVector;\n sizeOffsetY = sizeOffsetYOrSpeed;\n }\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\n return this;\n }\n /**\n * This method will cause an actor to blink (become visible and not\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\n * the actor should be visible per blink, and the amount of time not visible.\n * This method is part of the actor 'Action' fluent API allowing action chaining.\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\n * @param numBlinks The number of times to blink\n */ blink(timeVisible, timeNotVisible, numBlinks = 1) {\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\n return this;\n }\n /**\n * This method will cause an actor's opacity to change from its current value\n * to the provided value by a specified time (in milliseconds). This method is\n * part of the actor 'Action' fluent API allowing action chaining.\n * @param opacity The ending opacity\n * @param time The time it should take to fade the actor (in milliseconds)\n */ fade(opacity, time) {\n this._queue.add(new Fade(this._entity, opacity, time));\n return this;\n }\n /**\n * This method will delay the next action from executing for a certain\n * amount of time (in milliseconds). This method is part of the actor\n * 'Action' fluent API allowing action chaining.\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\n */ delay(time) {\n this._queue.add(new Delay(time));\n return this;\n }\n /**\n * This method will add an action to the queue that will remove the actor from the\n * scene once it has completed its previous Any actions on the\n * action queue after this action will not be executed.\n */ die() {\n this._queue.add(new Die(this._entity));\n return this;\n }\n /**\n * This method allows you to call an arbitrary method as the next action in the\n * action queue. This is useful if you want to execute code in after a specific\n * action, i.e An actor arrives at a destination after traversing a path\n */ callMethod(method) {\n this._queue.add(new CallMethod(method));\n return this;\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\n * will repeat forever\n */ repeat(repeatBuilder, times) {\n if (!times) {\n this.repeatForever(repeatBuilder);\n return this;\n }\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\n return this;\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n */ repeatForever(repeatBuilder) {\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\n return this;\n }\n /**\n * This method will cause the entity to follow another at a specified distance\n * @param entity The entity to follow\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\n */ follow(entity, followDistance) {\n if (followDistance === undefined) this._queue.add(new Follow(this._entity, entity));\n else this._queue.add(new Follow(this._entity, entity, followDistance));\n return this;\n }\n /**\n * This method will cause the entity to move towards another until they\n * collide \"meet\" at a specified speed.\n * @param entity The entity to meet\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\n */ meet(entity, speed) {\n if (speed === undefined) this._queue.add(new Meet(this._entity, entity));\n else this._queue.add(new Meet(this._entity, entity, speed));\n return this;\n }\n /**\n * Returns a promise that resolves when the current action queue up to now\n * is finished.\n */ toPromise() {\n const temp = new Promise((resolve)=>{\n this._queue.add(new CallMethod(()=>{\n resolve();\n }));\n });\n return temp;\n }\n }\n class ActionsComponent extends Component {\n constructor(){\n super(...arguments);\n this.dependencies = [\n TransformComponent,\n MotionComponent\n ];\n this._ctx = null;\n }\n onAdd(entity) {\n this._ctx = new ActionContext(entity);\n }\n onRemove() {\n this._ctx = null;\n }\n _getCtx() {\n if (!this._ctx) throw new Error(\"Actions component not attached to an entity, no context available\");\n return this._ctx;\n }\n /**\n * Returns the internal action queue\n * @returns action queue\n */ getQueue() {\n if (!this._ctx) throw new Error(\"Actions component not attached to an entity, no queue available\");\n return this._ctx.getQueue();\n }\n runAction(action) {\n if (!this._ctx) throw new Error(\"Actions component not attached to an entity, cannot run action\");\n return this._ctx.runAction(action);\n }\n /**\n * Updates the internal action context, performing action and moving through the internal queue\n * @param elapsedMs\n */ update(elapsedMs) {\n var _a;\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.update(elapsedMs);\n }\n /**\n * Clears all queued actions from the Actor\n */ clearActions() {\n var _a;\n (_a = this._ctx) === null || _a === void 0 || _a.clearActions();\n }\n easeTo(...args) {\n return this._getCtx().easeTo.apply(this._ctx, args);\n }\n easeBy(...args) {\n return this._getCtx().easeBy.apply(this._ctx, args);\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n return this._getCtx().moveTo.apply(this._ctx, [\n xOrPos,\n yOrSpeed,\n speedOrUndefined\n ]);\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n return this._getCtx().moveBy.apply(this._ctx, [\n xOffsetOrVector,\n yOffsetOrSpeed,\n speedOrUndefined\n ]);\n }\n /**\n * This method will rotate an actor to the specified angle at the speed\n * specified (in radians per second) and return back the actor. This\n * method is part of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadians The angle to rotate to in radians\n * @param speed The angular velocity of the rotation specified in radians per second\n * @param rotationType The [[RotationType]] to use for this rotation\n */ rotateTo(angleRadians, speed, rotationType) {\n return this._getCtx().rotateTo(angleRadians, speed, rotationType);\n }\n /**\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\n * in radians/sec and return back the actor. This method is part\n * of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\n * @param speed The speed in radians/sec the actor should rotate at\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\n */ rotateBy(angleRadiansOffset, speed, rotationType) {\n return this._getCtx().rotateBy(angleRadiansOffset, speed, rotationType);\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n return this._getCtx().scaleTo.apply(this._ctx, [\n sizeXOrVector,\n sizeYOrSpeed,\n speedXOrUndefined,\n speedYOrUndefined\n ]);\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n return this._getCtx().scaleBy.apply(this._ctx, [\n sizeOffsetXOrVector,\n sizeOffsetYOrSpeed,\n speed\n ]);\n }\n /**\n * This method will cause an actor to blink (become visible and not\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\n * the actor should be visible per blink, and the amount of time not visible.\n * This method is part of the actor 'Action' fluent API allowing action chaining.\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\n * @param numBlinks The number of times to blink\n */ blink(timeVisible, timeNotVisible, numBlinks) {\n return this._getCtx().blink(timeVisible, timeNotVisible, numBlinks);\n }\n /**\n * This method will cause an actor's opacity to change from its current value\n * to the provided value by a specified time (in milliseconds). This method is\n * part of the actor 'Action' fluent API allowing action chaining.\n * @param opacity The ending opacity\n * @param time The time it should take to fade the actor (in milliseconds)\n */ fade(opacity, time) {\n return this._getCtx().fade(opacity, time);\n }\n /**\n * This method will delay the next action from executing for a certain\n * amount of time (in milliseconds). This method is part of the actor\n * 'Action' fluent API allowing action chaining.\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\n */ delay(time) {\n return this._getCtx().delay(time);\n }\n /**\n * This method will add an action to the queue that will remove the actor from the\n * scene once it has completed its previous Any actions on the\n * action queue after this action will not be executed.\n */ die() {\n return this._getCtx().die();\n }\n /**\n * This method allows you to call an arbitrary method as the next action in the\n * action queue. This is useful if you want to execute code in after a specific\n * action, i.e An actor arrives at a destination after traversing a path\n */ callMethod(method) {\n return this._getCtx().callMethod(method);\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\n * will repeat forever\n */ repeat(repeatBuilder, times) {\n return this._getCtx().repeat(repeatBuilder, times);\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n */ repeatForever(repeatBuilder) {\n return this._getCtx().repeatForever(repeatBuilder);\n }\n /**\n * This method will cause the entity to follow another at a specified distance\n * @param entity The entity to follow\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\n */ follow(entity, followDistance) {\n return this._getCtx().follow(entity, followDistance);\n }\n /**\n * This method will cause the entity to move towards another until they\n * collide \"meet\" at a specified speed.\n * @param entity The entity to meet\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\n */ meet(entity, speed) {\n return this._getCtx().meet(entity, speed);\n }\n /**\n * Returns a promise that resolves when the current action queue up to now\n * is finished.\n */ toPromise() {\n return this._getCtx().toPromise();\n }\n }\n /**\n * Enum representing the different font size units\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\n */ var FontUnit;\n (function(FontUnit) {\n /**\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\n */ FontUnit[\"Em\"] = \"em\";\n /**\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\n */ FontUnit[\"Rem\"] = \"rem\";\n /**\n * Pixel is a unit of length in screen pixels\n */ FontUnit[\"Px\"] = \"px\";\n /**\n * Point is a physical unit length (1/72 of an inch)\n */ FontUnit[\"Pt\"] = \"pt\";\n /**\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\n */ FontUnit[\"Percent\"] = \"%\";\n })(FontUnit || (FontUnit = {}));\n /**\n * Enum representing the different horizontal text alignments\n */ var TextAlign;\n (function(TextAlign) {\n /**\n * The text is left-aligned.\n */ TextAlign[\"Left\"] = \"left\";\n /**\n * The text is right-aligned.\n */ TextAlign[\"Right\"] = \"right\";\n /**\n * The text is centered.\n */ TextAlign[\"Center\"] = \"center\";\n /**\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\n * right-aligned for right-to-left locales).\n */ TextAlign[\"Start\"] = \"start\";\n /**\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\n * left-aligned for right-to-left locales).\n */ TextAlign[\"End\"] = \"end\";\n })(TextAlign || (TextAlign = {}));\n /**\n * Enum representing the different baseline text alignments\n */ var BaseAlign;\n (function(BaseAlign) {\n /**\n * The text baseline is the top of the em square.\n */ BaseAlign[\"Top\"] = \"top\";\n /**\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\n * alphabetic.\n */ BaseAlign[\"Hanging\"] = \"hanging\";\n /**\n * The text baseline is the middle of the em square.\n */ BaseAlign[\"Middle\"] = \"middle\";\n /**\n * The text baseline is the normal alphabetic baseline.\n */ BaseAlign[\"Alphabetic\"] = \"alphabetic\";\n /**\n * The text baseline is the ideographic baseline; this is the bottom of\n * the body of the characters, if the main body of characters protrudes\n * beneath the alphabetic baseline. Currently unsupported; this will\n * act like alphabetic.\n */ BaseAlign[\"Ideographic\"] = \"ideographic\";\n /**\n * The text baseline is the bottom of the bounding box. This differs\n * from the ideographic baseline in that the ideographic baseline\n * doesn't consider descenders.\n */ BaseAlign[\"Bottom\"] = \"bottom\";\n })(BaseAlign || (BaseAlign = {}));\n /**\n * Enum representing the different possible font styles\n */ var FontStyle;\n (function(FontStyle) {\n FontStyle[\"Normal\"] = \"normal\";\n FontStyle[\"Italic\"] = \"italic\";\n FontStyle[\"Oblique\"] = \"oblique\";\n })(FontStyle || (FontStyle = {}));\n /**\n * Enum representing the text direction, useful for other languages, or writing text in reverse\n */ var Direction;\n (function(Direction) {\n Direction[\"LeftToRight\"] = \"ltr\";\n Direction[\"RightToLeft\"] = \"rtl\";\n })(Direction || (Direction = {}));\n class FontTextInstance {\n constructor(font, text, color, maxWidth){\n this.font = font;\n this.text = text;\n this.color = color;\n this.maxWidth = maxWidth;\n this._textFragments = [];\n this.disposed = false;\n this._dirty = true;\n this.canvas = document.createElement(\"canvas\");\n this.ctx = this.canvas.getContext(\"2d\");\n this.dimensions = this.measureText(text);\n this._setDimension(this.dimensions, this.ctx);\n this._lastHashCode = this.getHashCode();\n }\n measureText(text, maxWidth) {\n if (this.disposed) throw Error(\"Accessing disposed text instance! \" + this.text);\n let lines = null;\n if (maxWidth != null) lines = this._getLinesFromText(text, maxWidth);\n else lines = text.split(\"\\n\");\n const maxWidthLine = lines.reduce((a, b)=>{\n return a.length > b.length ? a : b;\n });\n this._applyFont(this.ctx); // font must be applied to the context to measure it\n const metrics = this.ctx.measureText(maxWidthLine);\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\n // TODO lineheight makes the text bounds wonky\n const lineAdjustedHeight = textHeight * lines.length;\n textHeight = lineAdjustedHeight;\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\n const x = 0;\n const y = 0;\n const measurement = new BoundingBox({\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\n bottom: y + bottomBounds + this.font.padding,\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\n });\n return measurement;\n }\n _setDimension(textBounds, bitmap) {\n let lineHeightRatio = 1;\n if (this.font.lineHeight) lineHeightRatio = this.font.lineHeight / this.font.size;\n // Changing the width and height clears the context properties\n // We double the bitmap width to account for all possible alignment\n // We scale by \"quality\" so we render text without jaggies\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality * lineHeightRatio;\n }\n static getHashCode(font, text, color) {\n var _a;\n const hash = text + \"__hashcode__\" + font.fontString + font.showDebug + font.textAlign + font.baseAlign + font.direction + font.lineHeight + JSON.stringify(font.shadow) + (font.padding.toString() + font.smoothing.toString() + font.lineWidth.toString() + font.lineDash.toString() + ((_a = font.strokeColor) === null || _a === void 0 ? void 0 : _a.toString()) + (color ? color.toString() : font.color.toString()));\n return hash;\n }\n getHashCode(includeColor = true) {\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\n }\n _applyRasterProperties(ctx) {\n var _a, _b;\n ctx.translate(this.font.padding, this.font.padding);\n ctx.imageSmoothingEnabled = this.font.smoothing;\n ctx.lineWidth = this.font.lineWidth;\n ctx.setLineDash((_a = this.font.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.strokeStyle = (_b = this.font.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = this.color.toString();\n }\n _applyFont(ctx) {\n ctx.resetTransform();\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\n ctx.scale(this.font.quality, this.font.quality);\n ctx.textAlign = this.font.textAlign;\n ctx.textBaseline = this.font.baseAlign;\n ctx.font = this.font.fontString;\n ctx.direction = this.font.direction;\n if (this.font.shadow) {\n ctx.shadowColor = this.font.shadow.color.toString();\n ctx.shadowBlur = this.font.shadow.blur;\n ctx.shadowOffsetX = this.font.shadow.offset.x;\n ctx.shadowOffsetY = this.font.shadow.offset.y;\n }\n }\n _drawText(ctx, lines, lineHeight) {\n this._applyRasterProperties(ctx);\n this._applyFont(ctx);\n for(let i = 0; i < lines.length; i++){\n const line = lines[i];\n if (this.color) ctx.fillText(line, 0, i * lineHeight);\n if (this.font.strokeColor) ctx.strokeText(line, 0, i * lineHeight);\n }\n if (this.font.showDebug) {\n // Horizontal line\n /* istanbul ignore next */ line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\n // Vertical line\n /* istanbul ignore next */ line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\n }\n }\n _splitTextBitmap(bitmap) {\n const textImages = [];\n let currentX = 0;\n let currentY = 0;\n // 4k is the max for mobile devices\n const width = Math.min(4096, bitmap.canvas.width);\n const height = Math.min(4096, bitmap.canvas.height);\n // Splits the original bitmap into 4k max chunks\n while(currentX < bitmap.canvas.width){\n while(currentY < bitmap.canvas.height){\n // create new bitmap\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n // draw current slice to new bitmap in < 4k chunks\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\n textImages.push({\n x: currentX,\n y: currentY,\n canvas: canvas\n });\n currentY += height;\n }\n currentX += width;\n currentY = 0;\n }\n return textImages;\n }\n flagDirty() {\n this._dirty = true;\n }\n render(ex, x, y, maxWidth) {\n var _a;\n if (this.disposed) throw Error(\"Accessing disposed text instance! \" + this.text);\n this._ex = ex;\n const hashCode = this.getHashCode();\n if (this._lastHashCode !== hashCode) this._dirty = true;\n // Calculate image chunks\n if (this._dirty) {\n this.dimensions = this.measureText(this.text, maxWidth);\n this._setDimension(this.dimensions, this.ctx);\n const lines = this._getLinesFromText(this.text, maxWidth);\n const lineHeight = (_a = this.font.lineHeight) !== null && _a !== void 0 ? _a : this.dimensions.height / lines.length;\n // draws the text to the main bitmap\n this._drawText(this.ctx, lines, lineHeight);\n // clear any out old fragments\n if (ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)ex.textureLoader.delete(frag.canvas);\n // splits to < 4k fragments for large text\n this._textFragments = this._splitTextBitmap(this.ctx);\n if (ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)ex.textureLoader.load(frag.canvas, this.font.filtering, true);\n this._lastHashCode = hashCode;\n this._dirty = false;\n }\n // draws the bitmap fragments to excalibur graphics context\n for (const frag of this._textFragments)ex.drawImage(frag.canvas, 0, 0, frag.canvas.width, frag.canvas.height, frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2, frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2, frag.canvas.width / this.font.quality, frag.canvas.height / this.font.quality);\n }\n dispose() {\n this.disposed = true;\n this.dimensions = undefined;\n this.canvas = undefined;\n this.ctx = undefined;\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)this._ex.textureLoader.delete(frag.canvas);\n this._textFragments.length = 0;\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) return this._cachedLines;\n const lines = text.split(\"\\n\");\n if (maxWidth == null) return lines;\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for(let i = 0; i < lines.length; i++){\n let line = lines[i];\n let newLine = \"\";\n if (this.measureText(line).width > maxWidth) {\n while(this.measureText(line).width > maxWidth){\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n }\n class FontCache {\n static measureText(text, font, maxWidth) {\n const hash = FontTextInstance.getHashCode(font, text);\n if (FontCache._MEASURE_CACHE.has(hash)) return FontCache._MEASURE_CACHE.get(hash);\n FontCache._LOGGER.debug(\"Font text measurement cache miss\");\n const measurement = font.measureTextWithoutCache(text, maxWidth);\n FontCache._MEASURE_CACHE.set(hash, measurement);\n return measurement;\n }\n static getTextInstance(text, font, color) {\n const hash = FontTextInstance.getHashCode(font, text, color);\n let textInstance = FontCache._TEXT_CACHE.get(hash);\n if (!textInstance) {\n textInstance = new FontTextInstance(font, text, color);\n FontCache._TEXT_CACHE.set(hash, textInstance);\n FontCache._LOGGER.debug(\"Font text instance cache miss\");\n }\n // Cache the bitmap for certain amount of time\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\n return textInstance;\n }\n static checkAndClearCache() {\n const deferred = [];\n const currentHashCodes = new Set();\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries())// if bitmap hasn't been used in 100 ms clear it\n if (time + FontCache.FONT_TIMEOUT < performance.now()) {\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\n deferred.push(textInstance);\n textInstance.dispose();\n } else {\n const hash = textInstance.getHashCode(false);\n currentHashCodes.add(hash);\n }\n // Deferred removal of text instances\n deferred.forEach((t)=>{\n FontCache._TEXT_USAGE.delete(t);\n });\n // Regenerate text instance cache\n this._TEXT_CACHE.clear();\n for (const [textInstance] of this._TEXT_USAGE.entries())this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\n // Regenerated measurement cache\n const newTextMeasurementCache = new Map();\n for (const current of currentHashCodes)if (FontCache._MEASURE_CACHE.has(current)) newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\n this._MEASURE_CACHE.clear();\n this._MEASURE_CACHE = newTextMeasurementCache;\n }\n static get cacheSize() {\n return FontCache._TEXT_USAGE.size;\n }\n /**\n * Force clear all cached text bitmaps\n */ static clearCache() {\n for (const [textInstance] of FontCache._TEXT_USAGE.entries())textInstance.dispose();\n FontCache._TEXT_USAGE.clear();\n FontCache._TEXT_CACHE.clear();\n FontCache._MEASURE_CACHE.clear();\n }\n }\n FontCache.FONT_TIMEOUT = 500;\n FontCache._LOGGER = Logger.getInstance();\n FontCache._TEXT_USAGE = new Map();\n FontCache._TEXT_CACHE = new Map();\n FontCache._MEASURE_CACHE = new Map();\n /**\n * Represents a system or web font in Excalibur\n *\n * If no options specified, the system sans-serif 10 pixel is used\n *\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\n */ class Font extends Graphic {\n constructor(options = {}){\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;\n super(options); // <- Graphics properties\n /**\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\n *\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\n */ this.filtering = ImageFiltering.Blended;\n /**\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\n *\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\n *\n * (Default 2)\n */ this.quality = 2;\n // Raster properties for fonts\n this.padding = 2;\n this.smoothing = false;\n this.lineWidth = 1;\n this.lineDash = [];\n this.color = Color.Black;\n this.family = \"sans-serif\";\n this.style = FontStyle.Normal;\n this.bold = false;\n this.unit = FontUnit.Px;\n this.textAlign = TextAlign.Left;\n this.baseAlign = BaseAlign.Top;\n this.direction = Direction.LeftToRight;\n /**\n * Font line height in pixels, default line height if unset\n */ this.lineHeight = undefined;\n this.size = 10;\n this.shadow = null;\n this._textBounds = new BoundingBox();\n this._textMeasurement = new FontTextInstance(this, \"\", Color.Black);\n // Raster properties\n this.smoothing = (_a = options === null || options === void 0 ? void 0 : options.smoothing) !== null && _a !== void 0 ? _a : this.smoothing;\n this.padding = (_b = options === null || options === void 0 ? void 0 : options.padding) !== null && _b !== void 0 ? _b : this.padding;\n this.color = (_c = options === null || options === void 0 ? void 0 : options.color) !== null && _c !== void 0 ? _c : this.color;\n this.strokeColor = (_d = options === null || options === void 0 ? void 0 : options.strokeColor) !== null && _d !== void 0 ? _d : this.strokeColor;\n this.lineDash = (_e = options === null || options === void 0 ? void 0 : options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineWidth = (_f = options === null || options === void 0 ? void 0 : options.lineWidth) !== null && _f !== void 0 ? _f : this.lineWidth;\n this.filtering = (_g = options === null || options === void 0 ? void 0 : options.filtering) !== null && _g !== void 0 ? _g : this.filtering;\n // Font specific properties\n this.family = (_h = options === null || options === void 0 ? void 0 : options.family) !== null && _h !== void 0 ? _h : this.family;\n this.style = (_j = options === null || options === void 0 ? void 0 : options.style) !== null && _j !== void 0 ? _j : this.style;\n this.bold = (_k = options === null || options === void 0 ? void 0 : options.bold) !== null && _k !== void 0 ? _k : this.bold;\n this.size = (_l = options === null || options === void 0 ? void 0 : options.size) !== null && _l !== void 0 ? _l : this.size;\n this.unit = (_m = options === null || options === void 0 ? void 0 : options.unit) !== null && _m !== void 0 ? _m : this.unit;\n this.textAlign = (_o = options === null || options === void 0 ? void 0 : options.textAlign) !== null && _o !== void 0 ? _o : this.textAlign;\n this.baseAlign = (_p = options === null || options === void 0 ? void 0 : options.baseAlign) !== null && _p !== void 0 ? _p : this.baseAlign;\n this.direction = (_q = options === null || options === void 0 ? void 0 : options.direction) !== null && _q !== void 0 ? _q : this.direction;\n this.lineHeight = (_r = options === null || options === void 0 ? void 0 : options.lineHeight) !== null && _r !== void 0 ? _r : this.lineHeight;\n this.quality = (_s = options === null || options === void 0 ? void 0 : options.quality) !== null && _s !== void 0 ? _s : this.quality;\n if (options === null || options === void 0 ? void 0 : options.shadow) {\n this.shadow = {};\n this.shadow.blur = (_t = options.shadow.blur) !== null && _t !== void 0 ? _t : this.shadow.blur;\n this.shadow.offset = (_u = options.shadow.offset) !== null && _u !== void 0 ? _u : this.shadow.offset;\n this.shadow.color = (_v = options.shadow.color) !== null && _v !== void 0 ? _v : this.shadow.color;\n }\n }\n clone() {\n return new Font({\n ...this.cloneGraphicOptions(),\n size: this.size,\n unit: this.unit,\n family: this.family,\n style: this.style,\n bold: this.bold,\n textAlign: this.textAlign,\n baseAlign: this.baseAlign,\n direction: this.direction,\n shadow: this.shadow ? {\n blur: this.shadow.blur,\n offset: this.shadow.offset,\n color: this.shadow.color\n } : null\n });\n }\n get fontString() {\n return `${this.style} ${this.bold ? \"bold\" : \"\"} ${this.size}${this.unit} ${this.family}`;\n }\n get localBounds() {\n return this._textBounds;\n }\n _drawImage(_ex, _x, _y) {\n // TODO weird vestigial drawimage\n }\n _rotate(ex) {\n var _a;\n // TODO this needs to change depending on the bounding box...\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : this._textBounds.center;\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this._textBounds.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\n ex.scale(1, -1);\n }\n }\n measureTextWithoutCache(text, maxWidth) {\n return this._textMeasurement.measureText(text, maxWidth);\n }\n /**\n * Returns a BoundingBox that is the total size of the text including multiple lines\n *\n * Does not include any padding or adjustment\n * @param text\n * @returns BoundingBox\n */ measureText(text, maxWidth) {\n return FontCache.measureText(text, this, maxWidth);\n }\n _postDraw(ex) {\n ex.restore();\n }\n render(ex, text, colorOverride, x, y, maxWidth) {\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\n // Apply affine transformations\n this._textBounds = textInstance.dimensions;\n this._preDraw(ex, x, y);\n textInstance.render(ex, x, y, maxWidth);\n this._postDraw(ex);\n }\n }\n /**\n * Represent Text graphics in excalibur\n *\n * Useful for in game labels, ui, or overlays\n */ class Text extends Graphic {\n constructor(options){\n var _a, _b;\n super(options);\n this._text = \"\";\n this._textWidth = 0;\n this._textHeight = 0;\n // This order is important font, color, then text\n this.font = (_a = options.font) !== null && _a !== void 0 ? _a : new Font();\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : this.color;\n this.text = options.text;\n this.maxWidth = options.maxWidth;\n }\n clone() {\n var _a, _b;\n return new Text({\n text: this.text.slice(),\n color: (_b = (_a = this.color) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : Color.Black,\n font: this.font.clone(),\n maxWidth: this.maxWidth\n });\n }\n get text() {\n return this._text;\n }\n set text(value) {\n this._text = value;\n this._calculateDimension();\n }\n get font() {\n return this._font;\n }\n set font(font) {\n this._font = font;\n }\n get width() {\n if (this._textWidth === 0) this._calculateDimension();\n return this._textWidth * this.scale.x;\n }\n get height() {\n if (this._textHeight === 0) this._calculateDimension();\n return this._textHeight * this.scale.y;\n }\n _calculateDimension() {\n const { width: width, height: height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n }\n get localBounds() {\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\n }\n _rotate(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _flip(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _preDraw(ex, x, y) {\n if (this.isStale() || this.font.isStale()) {\n this.font.flipHorizontal = this.flipHorizontal;\n this.font.flipVertical = this.flipVertical;\n this.font.rotation = this.rotation;\n this.font.origin = this.origin;\n this.font.opacity = this.opacity;\n }\n this.font.tint = this.tint;\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n var _a;\n let color = Color.Black;\n if (this.font instanceof Font) color = (_a = this.color) !== null && _a !== void 0 ? _a : this.font.color;\n const { width: width, height: height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\n if (this.font.showDebug) {\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\n if (this.maxWidth != null) ex.debug.drawRect(x, y, this.maxWidth, this.height, {\n color: Color.Yellow\n });\n }\n }\n }\n /**\n * Type guard for checking if something is an Actor\n * @param x\n */ function isActor(x) {\n return x instanceof Actor;\n }\n const ActorEvents = {\n CollisionStart: \"collisionstart\",\n CollisionEnd: \"collisionend\",\n PreCollision: \"precollision\",\n PostCollision: \"postcollision\",\n Kill: \"kill\",\n PreKill: \"prekill\",\n PostKill: \"postkill\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\",\n PreTransformDraw: \"pretransformdraw\",\n PostTransformDraw: \"posttransformdraw\",\n PreDebugDraw: \"predebugdraw\",\n PostDebugDraw: \"postdebugdraw\",\n PointerUp: \"pointerup\",\n PointerDown: \"pointerdown\",\n PointerEnter: \"pointerenter\",\n PointerLeave: \"pointerleave\",\n PointerMove: \"pointermove\",\n PointerCancel: \"pointercancel\",\n Wheel: \"pointerwheel\",\n PointerDrag: \"pointerdragstart\",\n PointerDragEnd: \"pointerdragend\",\n PointerDragEnter: \"pointerdragenter\",\n PointerDragLeave: \"pointerdragleave\",\n PointerDragMove: \"pointerdragmove\",\n EnterViewPort: \"enterviewport\",\n ExitViewPort: \"exitviewport\",\n ActionStart: \"actionstart\",\n ActionComplete: \"actioncomplete\"\n };\n /**\n * The most important primitive in Excalibur is an `Actor`. Anything that\n * can move on the screen, collide with another `Actor`, respond to events,\n * or interact with the current scene, must be an actor. An `Actor` **must**\n * be part of a [[Scene]] for it to be drawn to the screen.\n */ class Actor extends Entity {\n /**\n * Gets the position vector of the actor in pixels\n */ get pos() {\n return this.transform.pos;\n }\n /**\n * Sets the position vector of the actor in pixels\n */ set pos(thePos) {\n this.transform.pos = thePos.clone();\n }\n /**\n * Gets the position vector of the actor from the last frame\n */ get oldPos() {\n return this.body.oldPos;\n }\n /**\n * Sets the position vector of the actor in the last frame\n */ set oldPos(thePos) {\n this.body.oldPos.setTo(thePos.x, thePos.y);\n }\n /**\n * Gets the velocity vector of the actor in pixels/sec\n */ get vel() {\n return this.motion.vel;\n }\n /**\n * Sets the velocity vector of the actor in pixels/sec\n */ set vel(theVel) {\n this.motion.vel = theVel.clone();\n }\n /**\n * Gets the velocity vector of the actor from the last frame\n */ get oldVel() {\n return this.body.oldVel;\n }\n /**\n * Sets the velocity vector of the actor from the last frame\n */ set oldVel(theVel) {\n this.body.oldVel.setTo(theVel.x, theVel.y);\n }\n /**\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\n * useful to simulate a gravitational effect.\n */ get acc() {\n return this.motion.acc;\n }\n /**\n * Sets the acceleration vector of teh actor in pixels/second/second\n */ set acc(theAcc) {\n this.motion.acc = theAcc.clone();\n }\n /**\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */ set oldAcc(theAcc) {\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\n }\n /**\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */ get oldAcc() {\n return this.body.oldAcc;\n }\n /**\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\n */ get rotation() {\n return this.transform.rotation;\n }\n /**\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\n */ set rotation(theAngle) {\n this.transform.rotation = theAngle;\n }\n /**\n * Gets the rotational velocity of the actor in radians/second\n */ get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\n * Sets the rotational velocity of the actor in radians/sec\n */ set angularVelocity(angularVelocity) {\n this.motion.angularVelocity = angularVelocity;\n }\n get scale() {\n return this.get(TransformComponent).scale;\n }\n set scale(scale) {\n this.get(TransformComponent).scale = scale;\n }\n /**\n * The anchor to apply all actor related transformations like rotation,\n * translation, and scaling. By default the anchor is in the center of\n * the actor. By default it is set to the center of the actor (.5, .5)\n *\n * An anchor of (.5, .5) will ensure that drawings are centered.\n *\n * Use `anchor.setTo` to set the anchor to a different point using\n * values between 0 and 1. For example, anchoring to the top-left would be\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\n */ get anchor() {\n return this._anchor;\n }\n set anchor(vec) {\n this._anchor = watch(vec, (v)=>this._handleAnchorChange(v));\n this._handleAnchorChange(vec);\n }\n _handleAnchorChange(v) {\n if (this.graphics) this.graphics.anchor = v;\n }\n /**\n * The offset in pixels to apply to all actor graphics\n *\n * Default offset of (0, 0)\n */ get offset() {\n return this._offset;\n }\n set offset(vec) {\n this._offset = watch(vec, (v)=>this._handleOffsetChange(v));\n this._handleOffsetChange(vec);\n }\n _handleOffsetChange(v) {\n if (this.graphics) this.graphics.offset = v;\n }\n /**\n * Indicates whether the actor is physically in the viewport\n */ get isOffScreen() {\n return this.hasTag(\"ex.offscreen\");\n }\n get draggable() {\n return this._draggable;\n }\n set draggable(isDraggable) {\n if (isDraggable) {\n if (isDraggable && !this._draggable) {\n this.events.on(\"pointerdragstart\", this._pointerDragStartHandler);\n this.events.on(\"pointerdragend\", this._pointerDragEndHandler);\n this.events.on(\"pointerdragmove\", this._pointerDragMoveHandler);\n this.events.on(\"pointerdragleave\", this._pointerDragLeaveHandler);\n } else if (!isDraggable && this._draggable) {\n this.events.off(\"pointerdragstart\", this._pointerDragStartHandler);\n this.events.off(\"pointerdragend\", this._pointerDragEndHandler);\n this.events.off(\"pointerdragmove\", this._pointerDragMoveHandler);\n this.events.off(\"pointerdragleave\", this._pointerDragLeaveHandler);\n }\n this._draggable = isDraggable;\n }\n }\n /**\n * Sets the color of the actor's current graphic\n */ get color() {\n return this._color;\n }\n set color(v) {\n this._color = v.clone();\n const currentGraphic = this.graphics.current;\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) currentGraphic.color = this._color;\n }\n // #endregion\n /**\n *\n * @param config\n */ constructor(config){\n super();\n this.events = new EventEmitter();\n this._anchor = watch(Vector.Half, (v)=>this._handleAnchorChange(v));\n this._offset = watch(Vector.Zero, (v)=>this._handleOffsetChange(v));\n /**\n * Convenience reference to the global logger\n */ this.logger = Logger.getInstance();\n /**\n * Draggable helper\n */ this._draggable = false;\n this._dragging = false;\n this._pointerDragStartHandler = ()=>{\n this._dragging = true;\n };\n this._pointerDragEndHandler = ()=>{\n this._dragging = false;\n };\n this._pointerDragMoveHandler = (pe)=>{\n if (this._dragging) this.pos = pe.worldPos;\n };\n this._pointerDragLeaveHandler = (pe)=>{\n if (this._dragging) this.pos = pe.worldPos;\n };\n const { name: name, x: x, y: y, pos: pos, coordPlane: coordPlane, scale: scale, width: width, height: height, radius: radius, collider: collider, vel: vel, acc: acc, rotation: rotation, angularVelocity: angularVelocity, z: z, color: color, visible: visible, opacity: opacity, anchor: anchor, offset: offset, collisionType: collisionType, collisionGroup: collisionGroup } = {\n ...config\n };\n this.name = name !== null && name !== void 0 ? name : this.name;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : Actor.defaults.anchor.clone();\n this.offset = offset !== null && offset !== void 0 ? offset : Vector.Zero;\n this.transform = new TransformComponent();\n this.addComponent(this.transform);\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.rotation = rotation !== null && rotation !== void 0 ? rotation : 0;\n this.scale = scale !== null && scale !== void 0 ? scale : vec(1, 1);\n this.z = z !== null && z !== void 0 ? z : 0;\n this.transform.coordPlane = coordPlane !== null && coordPlane !== void 0 ? coordPlane : CoordPlane.World;\n this.pointer = new PointerComponent;\n this.addComponent(this.pointer);\n this.graphics = new GraphicsComponent({\n anchor: this.anchor,\n offset: this.offset,\n opacity: opacity\n });\n this.addComponent(this.graphics);\n this.motion = new MotionComponent;\n this.addComponent(this.motion);\n this.vel = vel !== null && vel !== void 0 ? vel : Vector.Zero;\n this.acc = acc !== null && acc !== void 0 ? acc : Vector.Zero;\n this.angularVelocity = angularVelocity !== null && angularVelocity !== void 0 ? angularVelocity : 0;\n this.actions = new ActionsComponent;\n this.addComponent(this.actions);\n this.body = new BodyComponent;\n this.addComponent(this.body);\n this.body.collisionType = collisionType !== null && collisionType !== void 0 ? collisionType : CollisionType.Passive;\n if (collisionGroup) this.body.group = collisionGroup;\n if (collider) {\n this.collider = new ColliderComponent(collider);\n this.addComponent(this.collider);\n } else if (radius) {\n this.collider = new ColliderComponent(Shape.Circle(radius));\n this.addComponent(this.collider);\n } else if (width > 0 && height > 0) {\n this.collider = new ColliderComponent(Shape.Box(width, height, this.anchor));\n this.addComponent(this.collider);\n } else {\n this.collider = new ColliderComponent();\n this.addComponent(this.collider); // no collider\n }\n this.graphics.visible = visible !== null && visible !== void 0 ? visible : true;\n if (color) {\n this.color = color;\n if (width && height) this.graphics.add(new Rectangle({\n color: color,\n width: width,\n height: height\n }));\n else if (radius) this.graphics.add(new Circle({\n color: color,\n radius: radius\n }));\n }\n }\n clone() {\n const clone = new Actor({\n color: this.color.clone(),\n anchor: this.anchor.clone(),\n offset: this.offset.clone()\n });\n clone.clearComponents();\n clone.processComponentRemoval();\n // Clone builtins, order is important, same as ctor\n clone.addComponent(clone.transform = this.transform.clone(), true);\n clone.addComponent(clone.pointer = this.pointer.clone(), true);\n clone.addComponent(clone.graphics = this.graphics.clone(), true);\n clone.addComponent(clone.motion = this.motion.clone(), true);\n clone.addComponent(clone.actions = this.actions.clone(), true);\n clone.addComponent(clone.body = this.body.clone(), true);\n clone.addComponent(clone.collider = this.collider.clone(), true);\n const builtInComponents = [\n this.transform,\n this.pointer,\n this.graphics,\n this.motion,\n this.actions,\n this.body,\n this.collider\n ];\n // Clone non-builtin the current actors components\n const components = this.getComponents();\n for (const c of components)if (!builtInComponents.includes(c)) clone.addComponent(c.clone(), true);\n return clone;\n }\n /**\n * `onInitialize` is called before the first update of the actor. This method is meant to be\n * overridden. This is where initialization of child actors should take place.\n *\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\n */ onInitialize(engine) {\n // Override me\n }\n /**\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\n *\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n * @internal\n */ _initialize(engine) {\n super._initialize(engine);\n for (const child of this.children)child._initialize(engine);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n // #endregion\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _prekill handler for [[onPreKill]] lifecycle event\n * @internal\n */ _prekill(scene) {\n this.events.emit(\"prekill\", new PreKillEvent(this));\n this.onPreKill(scene);\n }\n /**\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\n *\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\n */ onPreKill(scene) {\n // Override me\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _prekill handler for [[onPostKill]] lifecycle event\n * @internal\n */ _postkill(scene) {\n this.events.emit(\"postkill\", new PostKillEvent(this));\n this.onPostKill(scene);\n }\n /**\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\n *\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\n */ onPostKill(scene) {\n // Override me\n }\n /**\n * If the current actor is a member of the scene, this will remove\n * it from the scene graph. It will no longer be drawn or updated.\n */ kill() {\n if (this.scene) {\n this._prekill(this.scene);\n this.events.emit(\"kill\", new KillEvent(this));\n super.kill();\n this._postkill(this.scene);\n } else this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\n }\n /**\n * If the current actor is killed, it will now not be killed.\n */ unkill() {\n this.active = true;\n }\n /**\n * Indicates wether the actor has been killed.\n */ isKilled() {\n return !this.active;\n }\n /**\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\n */ get z() {\n return this.get(TransformComponent).z;\n }\n /**\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\n * The z-index determines the relative order an actor is drawn in.\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\n * @param newZ new z-index to assign\n */ set z(newZ) {\n this.get(TransformComponent).z = newZ;\n }\n /**\n * Get the center point of an actor (global position)\n */ get center() {\n const globalPos = this.getGlobalPos();\n return new Vector(globalPos.x + this.width / 2 - this.anchor.x * this.width, globalPos.y + this.height / 2 - this.anchor.y * this.height);\n }\n /**\n * Get the local center point of an actor\n */ get localCenter() {\n return new Vector(this.pos.x + this.width / 2 - this.anchor.x * this.width, this.pos.y + this.height / 2 - this.anchor.y * this.height);\n }\n get width() {\n return this.collider.localBounds.width * this.getGlobalScale().x;\n }\n get height() {\n return this.collider.localBounds.height * this.getGlobalScale().y;\n }\n /**\n * Gets this actor's rotation taking into account any parent relationships\n * @returns Rotation angle in radians\n */ getGlobalRotation() {\n return this.get(TransformComponent).globalRotation;\n }\n /**\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\n * @returns Position in world coordinates\n */ getGlobalPos() {\n return this.get(TransformComponent).globalPos;\n }\n /**\n * Gets the global scale of the Actor\n */ getGlobalScale() {\n return this.get(TransformComponent).globalScale;\n }\n // #region Collision\n /**\n * Tests whether the x/y specified are contained in the actor\n * @param x X coordinate to test (in world coordinates)\n * @param y Y coordinate to test (in world coordinates)\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\n */ contains(x, y, recurse = false) {\n const point = vec(x, y);\n const collider = this.get(ColliderComponent);\n collider.update();\n const geom = collider.get();\n if (!geom) return false;\n const containment = geom.contains(point);\n if (recurse) return containment || this.children.some((child)=>{\n return child.contains(x, y, true);\n });\n return containment;\n }\n /**\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\n * @param actor Actor to test\n * @param distance Distance in pixels to test\n */ within(actor, distance) {\n const collider = this.get(ColliderComponent);\n const otherCollider = actor.get(ColliderComponent);\n const me = collider.get();\n const other = otherCollider.get();\n if (me && other) return me.getClosestLineBetween(other).getLength() <= distance;\n return false;\n }\n // #endregion\n // #region Update\n /**\n * Called by the Engine, updates the state of the actor\n * @internal\n * @param engine The reference to the current game engine\n * @param delta The time elapsed since the last update in milliseconds\n */ update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this._postupdate(engine, delta);\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before an actor is updated.\n */ onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after an actor is updated.\n */ onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n * Fires before every collision resolution for a confirmed contact\n * @param self\n * @param other\n * @param side\n * @param contact\n */ onPreCollisionResolve(self1, other, side, contact) {\n // Override me\n }\n /**\n * Fires after every resolution for a confirmed contact.\n * @param self\n * @param other\n * @param side\n * @param contact\n */ onPostCollisionResolve(self1, other, side, contact) {\n // Override me\n }\n /**\n * Fires once when 2 entities with a ColliderComponent first start colliding or touching, if the Colliders stay in contact this\n * does not continue firing until they separate and re-collide.\n * @param self\n * @param other\n * @param side\n * @param contact\n */ onCollisionStart(self1, other, side, contact) {\n // Override me\n }\n /**\n * Fires once when 2 entities with a ColliderComponent separate after having been in contact.\n * @param self\n * @param other\n * @param side\n * @param lastContact\n */ onCollisionEnd(self1, other, side, lastContact) {\n // Override me\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n }\n // #region Properties\n /**\n * Set defaults for all Actors\n */ Actor.defaults = {\n anchor: Vector.Half\n };\n /**\n * Type guard to detect a screen element\n */ function isScreenElement(actor) {\n return actor instanceof ScreenElement;\n }\n /**\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\n * not participate in collisions. Drawn on top of all other actors.\n */ class ScreenElement extends Actor {\n constructor(config){\n var _a, _b;\n super({\n ...config\n });\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\n this.anchor = (_a = config === null || config === void 0 ? void 0 : config.anchor) !== null && _a !== void 0 ? _a : vec(0, 0);\n this.body.collisionType = (_b = config === null || config === void 0 ? void 0 : config.collisionType) !== null && _b !== void 0 ? _b : CollisionType.PreventCollision;\n this.pointer.useGraphicsBounds = true;\n this.pointer.useColliderShape = false;\n if (!(config === null || config === void 0 ? void 0 : config.collider) && (config === null || config === void 0 ? void 0 : config.width) > 0 && (config === null || config === void 0 ? void 0 : config.height) > 0) this.collider.useBoxCollider(this.width, this.height, this.anchor);\n }\n _initialize(engine) {\n this._engine = engine;\n super._initialize(engine);\n }\n contains(x, y, useWorld = true) {\n if (useWorld) return super.contains(x, y);\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\n return super.contains(coords.x, coords.y);\n }\n }\n /**\n * The Excalibur timer hooks into the internal timer and fires callbacks,\n * after a certain interval, optionally repeating.\n */ class Timer {\n get complete() {\n return this._complete;\n }\n constructor(fcn, interval, repeats, numberOfRepeats, randomRange, random){\n this._logger = Logger.getInstance();\n this.id = 0;\n this._elapsedTime = 0;\n this._totalTimeAlive = 0;\n this._running = false;\n this._numberOfTicks = 0;\n this.interval = 10;\n this.repeats = false;\n this.maxNumberOfRepeats = -1;\n this.randomRange = [\n 0,\n 0\n ];\n this._baseInterval = 10;\n this._generateRandomInterval = ()=>{\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\n };\n this._complete = false;\n this.scene = null;\n if (typeof fcn !== \"function\") {\n const options = fcn;\n fcn = options.fcn;\n interval = options.interval;\n repeats = options.repeats;\n numberOfRepeats = options.numberOfRepeats;\n randomRange = options.randomRange;\n random = options.random;\n }\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\n this.maxNumberOfRepeats = numberOfRepeats;\n if (!repeats) throw new Error(\"repeats must be set to true if numberOfRepeats is set\");\n }\n this.id = Timer._MAX_ID++;\n this._callbacks = [];\n this._baseInterval = this.interval = interval;\n if (!!randomRange) {\n if (randomRange[0] > randomRange[1]) throw new Error(\"min value must be lower than max value for range\");\n //We use the instance of ex.Random to generate the range\n this.random = random !== null && random !== void 0 ? random : new Random();\n this.randomRange = randomRange;\n this.interval = this._generateRandomInterval();\n this.on(()=>{\n this.interval = this._generateRandomInterval();\n });\n }\n this.repeats = repeats || this.repeats;\n if (fcn) this.on(fcn);\n }\n /**\n * Adds a new callback to be fired after the interval is complete\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\n */ on(fcn) {\n this._callbacks.push(fcn);\n }\n /**\n * Removes a callback from the callback list to be fired after the interval is complete.\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\n */ off(fcn) {\n const index = this._callbacks.indexOf(fcn);\n this._callbacks.splice(index, 1);\n }\n /**\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\n * @param delta Number of elapsed milliseconds since the last update.\n */ update(delta) {\n if (this._running) {\n this._totalTimeAlive += delta;\n this._elapsedTime += delta;\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n if (!this.complete && this._elapsedTime >= this.interval) {\n this._callbacks.forEach((c)=>{\n c.call(this);\n });\n this._numberOfTicks++;\n if (this.repeats) this._elapsedTime = 0;\n else {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n }\n }\n }\n /**\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\n *\n * Warning** you may need to call `timer.start()` again if the timer had completed\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\n */ reset(newInterval, newNumberOfRepeats) {\n if (!!newInterval && newInterval >= 0) this._baseInterval = this.interval = newInterval;\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\n this.maxNumberOfRepeats = newNumberOfRepeats;\n if (!this.repeats) throw new Error(\"repeats must be set to true if numberOfRepeats is set\");\n }\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n get timesRepeated() {\n return this._numberOfTicks;\n }\n getTimeRunning() {\n return this._totalTimeAlive;\n }\n /**\n * @returns milliseconds until the next action callback, if complete will return 0\n */ get timeToNextAction() {\n if (this.complete) return 0;\n return this.interval - this._elapsedTime;\n }\n /**\n * @returns milliseconds elapsed toward the next action\n */ get timeElapsedTowardNextAction() {\n return this._elapsedTime;\n }\n get isRunning() {\n return this._running;\n }\n /**\n * Pauses the timer, time will no longer increment towards the next call\n */ pause() {\n this._running = false;\n return this;\n }\n /**\n * Resumes the timer, time will now increment towards the next call.\n */ resume() {\n this._running = true;\n return this;\n }\n /**\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\n */ start() {\n if (!this.scene) this._logger.warn(\"Cannot start a timer not part of a scene, timer wont start until added\");\n this._running = true;\n if (this.complete) {\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n return this;\n }\n /**\n * Stops the timer and resets the elapsed time counter towards the next action invocation\n */ stop() {\n this._running = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n return this;\n }\n /**\n * Cancels the timer, preventing any further executions.\n */ cancel() {\n this.pause();\n if (this.scene) this.scene.cancelTimer(this);\n }\n }\n Timer._MAX_ID = 0;\n class ParallaxComponent extends Component {\n constructor(parallaxFactor){\n super();\n this.parallaxFactor = vec(1.0, 1.0);\n this.parallaxFactor = parallaxFactor !== null && parallaxFactor !== void 0 ? parallaxFactor : this.parallaxFactor;\n }\n }\n /**\n * Provide arbitrary drawing for the purposes of debugging your game\n *\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\n *\n */ class DebugGraphicsComponent extends Component {\n constructor(draw, useTransform = true){\n super();\n this.draw = draw;\n this.useTransform = useTransform;\n }\n }\n const TileMapEvents = {\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\"\n };\n /**\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\n *\n * TileMaps are useful for top down or side scrolling grid oriented games.\n */ class TileMap extends Entity {\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n flagTilesDirty() {\n for(let i = 0; i < this.tiles.length; i++)if (this.tiles[i]) this.tiles[i].flagDirty();\n }\n get x() {\n var _a;\n return (_a = this.transform.pos.x) !== null && _a !== void 0 ? _a : 0;\n }\n set x(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos) this.get(TransformComponent).pos = vec(val, this.y);\n }\n get y() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos.y) !== null && _b !== void 0 ? _b : 0;\n }\n set y(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos) this.transform.pos = vec(this.x, val);\n }\n get z() {\n var _a;\n return (_a = this.transform.z) !== null && _a !== void 0 ? _a : 0;\n }\n set z(val) {\n if (this.transform) this.transform.z = val;\n }\n get rotation() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.rotation) !== null && _b !== void 0 ? _b : 0;\n }\n set rotation(val) {\n if (this.transform) this.transform.rotation = val;\n }\n get scale() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : Vector.One;\n }\n set scale(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.scale) this.transform.scale = val;\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n get vel() {\n return this._motion.vel;\n }\n set vel(val) {\n this._motion.vel = val;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * @param options\n */ constructor(options){\n var _a, _b, _c;\n super([], options.name);\n this.events = new EventEmitter();\n this._token = 0;\n this.logger = Logger.getInstance();\n this.tiles = [];\n this._rows = [];\n this._cols = [];\n this.renderFromTopOfGraphic = false;\n this.meshingLookBehind = 10;\n this._collidersDirty = true;\n this._originalOffsets = new WeakMap();\n this.meshingLookBehind = (_a = options.meshingLookBehind) !== null && _a !== void 0 ? _a : this.meshingLookBehind;\n this.addComponent(new TransformComponent());\n this.addComponent(new MotionComponent());\n this.addComponent(new BodyComponent({\n type: CollisionType.Fixed\n }));\n this.addComponent(new GraphicsComponent({\n onPostDraw: (ctx, delta)=>this.draw(ctx, delta)\n }));\n this.addComponent(new DebugGraphicsComponent((ctx, debugFlags)=>this.debug(ctx, debugFlags), false));\n this.addComponent(new ColliderComponent());\n this._graphics = this.get(GraphicsComponent);\n this.transform = this.get(TransformComponent);\n this._motion = this.get(MotionComponent);\n this.collider = this.get(ColliderComponent);\n this._composite = this.collider.useCompositeCollider([]);\n this.transform.pos = (_b = options.pos) !== null && _b !== void 0 ? _b : Vector.Zero;\n this._oldPos = this.transform.pos.clone();\n this._oldScale = this.transform.scale.clone();\n this.renderFromTopOfGraphic = (_c = options.renderFromTopOfGraphic) !== null && _c !== void 0 ? _c : this.renderFromTopOfGraphic;\n this.tileWidth = options.tileWidth;\n this.tileHeight = options.tileHeight;\n this.rows = options.rows;\n this.columns = options.columns;\n this.tiles = new Array(this.rows * this.columns);\n this._rows = new Array(this.rows);\n this._cols = new Array(this.columns);\n let currentCol = [];\n for(let i = 0; i < this.columns; i++){\n for(let j = 0; j < this.rows; j++){\n const tile = new Tile({\n x: i,\n y: j,\n map: this\n });\n tile.map = this;\n this.tiles[i + j * this.columns] = tile;\n currentCol.push(tile);\n if (!this._rows[j]) this._rows[j] = [];\n this._rows[j].push(tile);\n }\n this._cols[i] = currentCol;\n currentCol = [];\n }\n this._graphics.localBounds = new BoundingBox({\n left: 0,\n top: 0,\n right: this.columns * this.tileWidth * this.scale.x,\n bottom: this.rows * this.tileHeight * this.scale.y\n });\n }\n _initialize(engine) {\n super._initialize(engine);\n this._engine = engine;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n } else return this._originalOffsets.get(collider);\n }\n /**\n * Tiles colliders based on the solid tiles in the tilemap.\n */ _updateColliders() {\n this.collider.$colliderRemoved.notifyAll(this._composite);\n this._composite.clearColliders();\n const colliders = [];\n this._composite = this.collider.useCompositeCollider([]);\n let current;\n /**\n * Returns wether or not the 2 boxes share an edge and are the same height\n * @param prev\n * @param next\n * @returns true if they share and edge, false if not\n */ const shareEdges = (prev, next)=>{\n if (prev && next) // same top/bottom\n return prev.top === next.top && prev.bottom === next.bottom && // Shared right/left edge\n prev.right === next.left;\n return false;\n };\n /**\n * Potentially merges the current collider into a list of previous ones, mutating the list\n * If checkAndCombine returns true, the collider was successfully merged and should be thrown away\n * @param current current collider to test\n * @param colliders List of colliders to consider merging with\n * @param maxLookBack The amount of colliders to look back for combination\n * @returns false when no combination found, true when successfully combined\n */ const checkAndCombine = (current, colliders, maxLookBack = this.meshingLookBehind)=>{\n if (!current) return false;\n // walk backwards through the list of colliders and combine with the first that shares an edge\n for(let i = colliders.length - 1; i >= 0; i--){\n if (maxLookBack-- < 0) // blunt the O(n^2) algorithm a bit\n return false;\n const prev = colliders[i];\n if (shareEdges(prev, current)) {\n colliders[i] = prev.combine(current);\n return true;\n }\n }\n return false;\n };\n // ? configurable bias perhaps, horizontal strips vs. vertical ones\n // Bad tile collider packing algorithm\n for(let i = 0; i < this.columns; i++){\n // Scan column for colliders\n for(let j = 0; j < this.rows; j++){\n const tile = this.tiles[i + j * this.columns];\n // Current tile in column is solid build up current collider\n if (tile.solid) {\n // Use custom collider otherwise bounding box\n if (tile.getColliders().length > 0) {\n // tile with custom collider interrupting the current run\n for (const collider of tile.getColliders()){\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n //we push any current collider before nulling the current run\n if (current && !checkAndCombine(current, colliders)) colliders.push(current);\n current = null;\n // Use the bounding box\n } else if (!current) // no current run, start one\n current = tile.defaultGeometry;\n else // combine with current run\n current = current.combine(tile.defaultGeometry);\n } else {\n // Not solid skip and cut off the current collider\n // End of run check and combine\n if (current && !checkAndCombine(current, colliders)) colliders.push(current);\n current = null;\n }\n }\n // After a column is complete check to see if it can be merged into the last one\n // Eno of run check and combine\n if (current && !checkAndCombine(current, colliders)) // else new collider if no combination\n colliders.push(current);\n current = null;\n }\n for (const c of colliders){\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n this.collider.update();\n // Notify that colliders have been updated\n this.collider.$colliderAdded.notifyAll(this._composite);\n }\n /**\n * Returns the [[Tile]] by index (row major order)\n */ getTileByIndex(index) {\n return this.tiles[index];\n }\n /**\n * Returns the [[Tile]] by its x and y integer coordinates\n *\n * For example, if I want the tile in fifth column (x), and second row (y):\n * `getTile(4, 1)` 0 based, so 0 is the first in row/column\n */ getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) return null;\n return this.tiles[x + y * this.columns];\n }\n /**\n * Returns the [[Tile]] by testing a point in world coordinates,\n * returns `null` if no Tile was found.\n */ getTileByPoint(point) {\n const { x: x, y: y } = this._getTileCoordinates(point);\n const tile = this.getTile(x, y);\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) return tile;\n return null;\n }\n _getTileCoordinates(point) {\n // Convert to Tile Space point\n point = this.transform.applyInverse(point);\n const x = Math.floor(point.x / this.tileWidth);\n const y = Math.floor(point.y / this.tileHeight);\n return {\n x: x,\n y: y\n };\n }\n getRows() {\n return this._rows;\n }\n getColumns() {\n return this._cols;\n }\n /**\n * Returns the on screen tiles for a tilemap, this will overshoot by a small amount because of the internal quad tree data structure.\n *\n * Useful if you need to perform specific logic on onscreen tiles\n */ getOnScreenTiles() {\n let worldBounds = this._engine.screen.getWorldBounds();\n const maybeParallax = this.get(ParallaxComponent);\n if (maybeParallax && this.isInitialized) {\n let pos = this.pos;\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\n pos = pos.sub(parallaxOffset);\n // adjust world bounds by parallax factor\n worldBounds = worldBounds.translate(pos);\n }\n const bounds = this.transform.coordPlane === CoordPlane.Screen ? this._engine.screen.getScreenBounds() : worldBounds;\n const topLeft = this._getTileCoordinates(bounds.topLeft);\n const topRight = this._getTileCoordinates(bounds.topRight);\n const bottomRight = this._getTileCoordinates(bounds.bottomRight);\n const bottomLeft = this._getTileCoordinates(bounds.bottomLeft);\n const tileStartX = Math.min(clamp(topLeft.x, 0, this.columns - 1), clamp(topRight.x, 0, this.columns - 1));\n const tileStartY = Math.min(clamp(topLeft.y, 0, this.rows - 1), clamp(topRight.y, 0, this.rows - 1));\n const tileEndX = Math.max(clamp(bottomRight.x, 0, this.columns - 1), clamp(bottomLeft.x, 0, this.columns - 1));\n const tileEndY = Math.max(clamp(bottomRight.y, 0, this.rows - 1), clamp(bottomLeft.y, 0, this.rows - 1));\n const tiles = [];\n for(let x = tileStartX; x <= tileEndX; x++)for(let y = tileStartY; y <= tileEndY; y++)tiles.push(this.getTile(x, y));\n return tiles;\n }\n update(engine, delta) {\n this._initialize(engine);\n this.onPreUpdate(engine, delta);\n this.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n if (!this._oldPos.equals(this.pos) || this._oldRotation !== this.rotation || !this._oldScale.equals(this.scale)) {\n this.flagCollidersDirty();\n this.flagTilesDirty();\n }\n if (this._collidersDirty) {\n this._collidersDirty = false;\n this._updateColliders();\n }\n this._token++;\n this.pos.clone(this._oldPos);\n this._oldRotation = this.rotation;\n this.scale.clone(this._oldScale);\n this.transform.pos = this.pos;\n this.onPostUpdate(engine, delta);\n this.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n }\n /**\n * Draws the tile map to the screen. Called by the [[Scene]].\n * @param ctx ExcaliburGraphicsContext\n * @param delta The number of milliseconds since the last draw\n */ draw(ctx, delta) {\n if (!this.isInitialized) return;\n this.emit(\"predraw\", new PreDrawEvent(ctx, delta, this)); // TODO fix event\n let graphics, graphicsIndex, graphicsLen;\n const tiles = this.getOnScreenTiles();\n for(let i = 0; i < tiles.length; i++){\n const tile = tiles[i];\n // get non-negative tile sprites\n const offsets = tile.getGraphicsOffsets();\n graphics = tile.getGraphics();\n for(graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++){\n // draw sprite, warning if sprite doesn't exist\n const graphic = graphics[graphicsIndex];\n const offset = offsets[graphicsIndex];\n if (graphic) {\n if (hasGraphicsTick(graphic)) graphic === null || graphic === void 0 || graphic.tick(delta, this._token);\n const offsetY = this.renderFromTopOfGraphic ? 0 : graphic.height - this.tileHeight;\n graphic.draw(ctx, tile.x * this.tileWidth + offset.x, tile.y * this.tileHeight - offsetY + offset.y);\n }\n }\n }\n this.emit(\"postdraw\", new PostDrawEvent(ctx, delta, this));\n }\n debug(gfx, debugFlags) {\n const { showAll: showAll, showGrid: showGrid, gridColor: gridColor, gridWidth: gridWidth, showSolidBounds: showColliderBounds, solidBoundsColor: colliderBoundsColor, showColliderGeometry: showColliderGeometry } = debugFlags.tilemap;\n const { geometryColor: geometryColor, geometryLineWidth: geometryLineWidth, geometryPointSize: geometryPointSize } = debugFlags.collider;\n const width = this.tileWidth * this.columns * this.scale.x;\n const height = this.tileHeight * this.rows * this.scale.y;\n const pos = this.pos;\n if (showGrid || showAll) {\n for(let r = 0; r < this.rows + 1; r++){\n const yOffset = vec(0, r * this.tileHeight * this.scale.y);\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), gridColor, gridWidth);\n }\n for(let c = 0; c < this.columns + 1; c++){\n const xOffset = vec(c * this.tileWidth * this.scale.x, 0);\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), gridColor, gridWidth);\n }\n }\n if (showAll || showColliderBounds || showColliderGeometry) {\n const colliders = this._composite.getColliders();\n gfx.save();\n gfx.translate(this.pos.x, this.pos.y);\n gfx.scale(this.scale.x, this.scale.y);\n for (const collider of colliders){\n const bounds = collider.localBounds;\n const pos = collider.worldPos.sub(this.pos);\n if (showColliderBounds) gfx.drawRectangle(pos, bounds.width, bounds.height, colliderBoundsColor);\n }\n gfx.restore();\n if (showColliderGeometry) for (const collider of colliders)collider.debug(gfx, geometryColor, {\n lineWidth: geometryLineWidth,\n pointSize: geometryPointSize\n });\n }\n if (showAll || showColliderBounds) {\n gfx.save();\n gfx.z = 999;\n if (showColliderBounds) for(let i = 0; i < this.tiles.length; i++)this.tiles[i].bounds.draw(gfx);\n gfx.restore();\n }\n }\n }\n /**\n * TileMap Tile\n *\n * A light-weight object that occupies a space in a collision map. Generally\n * created by a [[TileMap]].\n *\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\n * of the sprites in the array so the last one will be drawn on top. You can\n * use transparency to create layers this way.\n */ class Tile extends Entity {\n /**\n * Return the world position of the top left corner of the tile\n */ get pos() {\n if (this._posDirty) {\n this._recalculate();\n this._posDirty = false;\n }\n return this._pos;\n }\n /**\n * Width of the tile in pixels\n */ get width() {\n return this._width;\n }\n /**\n * Height of the tile in pixels\n */ get height() {\n return this._height;\n }\n /**\n * Wether this tile should be treated as solid by the tilemap\n */ get solid() {\n return this._solid;\n }\n /**\n * Wether this tile should be treated as solid by the tilemap\n */ set solid(val) {\n var _a;\n (_a = this.map) === null || _a === void 0 || _a.flagCollidersDirty();\n this._solid = val;\n }\n /**\n * Current list of graphics for this tile\n */ getGraphics() {\n return this._graphics;\n }\n /**\n * Current list of offsets for this tile's graphics\n */ getGraphicsOffsets() {\n return this._offsets;\n }\n /**\n * Add another [[Graphic]] to this TileMap tile\n * @param graphic\n */ addGraphic(graphic, options) {\n this._graphics.push(graphic);\n if (options === null || options === void 0 ? void 0 : options.offset) this._offsets.push(options.offset);\n else this._offsets.push(Vector.Zero);\n }\n /**\n * Remove an instance of a [[Graphic]] from this tile\n */ removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) {\n this._graphics.splice(index, 1);\n this._offsets.splice(index, 1);\n }\n }\n /**\n * Clear all graphics from this tile\n */ clearGraphics() {\n this._graphics.length = 0;\n this._offsets.length = 0;\n }\n /**\n * Returns the list of colliders\n */ getColliders() {\n return this._colliders;\n }\n /**\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\n *\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\n *\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\n * @param collider\n */ addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\n * Removes a collider from the [[Tile]]\n * @param collider\n */ removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) this._colliders.splice(index, 1);\n this.map.flagCollidersDirty();\n }\n /**\n * Clears all colliders from the [[Tile]]\n */ clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n constructor(options){\n var _a, _b;\n super();\n this._posDirty = false;\n this._solid = false;\n this._graphics = [];\n this._offsets = [];\n /**\n * Current list of colliders for this tile\n */ this._colliders = [];\n /**\n * Arbitrary data storage per tile, useful for any game specific data\n */ this.data = new Map();\n this.x = options.x;\n this.y = options.y;\n this.map = options.map;\n this._width = options.map.tileWidth * this.map.scale.x;\n this._height = options.map.tileHeight * this.map.scale.y;\n this.solid = (_a = options.solid) !== null && _a !== void 0 ? _a : this.solid;\n this._graphics = (_b = options.graphics) !== null && _b !== void 0 ? _b : [];\n this._recalculate();\n }\n flagDirty() {\n return this._posDirty = true;\n }\n _recalculate() {\n const geometryPos = this.map.pos.add(vec(this.x * this.map.tileWidth, this.y * this.map.tileHeight));\n this._geometry = new BoundingBox(geometryPos.x, geometryPos.y, geometryPos.x + this.map.tileWidth, geometryPos.y + this.map.tileHeight);\n this._width = this.map.tileWidth * this.map.scale.x;\n this._height = this.map.tileHeight * this.map.scale.y;\n this._pos = this.map.pos.add(vec(this.x * this._width, this.y * this._height));\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\n if (this.map.rotation) this._bounds = this._bounds.rotate(this.map.rotation, this.map.pos);\n this._posDirty = false;\n }\n /**\n * Tile bounds in world space\n */ get bounds() {\n if (this._posDirty) this._recalculate();\n return this._bounds;\n }\n get defaultGeometry() {\n return this._geometry;\n }\n /**\n * Tile position in world space\n */ get center() {\n if (this._posDirty) this._recalculate();\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\n }\n }\n /**\n * Container to house convenience strategy methods\n * @internal\n */ class StrategyContainer {\n constructor(camera){\n this.camera = camera;\n }\n /**\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\n * @param actor The actor to lock the camera to\n */ lockToActor(actor) {\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\n }\n /**\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\n * @param actor The actor to lock the camera to\n * @param axis The axis to follow the actor on\n */ lockToActorAxis(actor, axis) {\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\n }\n /**\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\n * correct and bounce around the target\n * @param actor Target actor to elastically follow\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\n */ elasticToActor(actor, cameraElasticity, cameraFriction) {\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\n }\n /**\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\n * @param actor Target actor to follow when it is \"radius\" pixels away\n * @param radius Number of pixels away before the camera will follow\n */ radiusAroundActor(actor, radius) {\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\n }\n /**\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\n * @param box The bounding box to limit the camera to.\n */ limitCameraBounds(box) {\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\n }\n }\n /**\n * Camera axis enum\n */ var Axis;\n (function(Axis) {\n Axis[Axis[\"X\"] = 0] = \"X\";\n Axis[Axis[\"Y\"] = 1] = \"Y\";\n })(Axis || (Axis = {}));\n /**\n * Lock a camera to the exact x/y position of an actor.\n */ class LockCameraToActorStrategy {\n constructor(target){\n this.target = target;\n this.action = (target, camera, engine, delta)=>{\n const center = target.center;\n return center;\n };\n }\n }\n /**\n * Lock a camera to a specific axis around an actor.\n */ class LockCameraToActorAxisStrategy {\n constructor(target, axis){\n this.target = target;\n this.axis = axis;\n this.action = (target, cam, _eng, _delta)=>{\n const center = target.center;\n const currentFocus = cam.getFocus();\n if (this.axis === Axis.X) return new Vector(center.x, currentFocus.y);\n else return new Vector(currentFocus.x, center.y);\n };\n }\n }\n /**\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\n */ class ElasticToActorStrategy {\n /**\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\n * correct and bounce around the target\n * @param target Target actor to elastically follow\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\n */ constructor(target, cameraElasticity, cameraFriction){\n this.target = target;\n this.cameraElasticity = cameraElasticity;\n this.cameraFriction = cameraFriction;\n this.action = (target, cam, _eng, _delta)=>{\n const position = target.center;\n let focus = cam.getFocus();\n let cameraVel = cam.vel.clone();\n // Calculate the stretch vector, using the spring equation\n // F = kX\n // https://en.wikipedia.org/wiki/Hooke's_law\n // Apply to the current camera velocity\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\n cameraVel = cameraVel.add(stretch);\n // Calculate the friction (-1 to apply a force in the opposition of motion)\n // Apply to the current camera velocity\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\n cameraVel = cameraVel.add(friction);\n // Update position by velocity deltas\n focus = focus.add(cameraVel);\n return focus;\n };\n }\n }\n class RadiusAroundActorStrategy {\n /**\n *\n * @param target Target actor to follow when it is \"radius\" pixels away\n * @param radius Number of pixels away before the camera will follow\n */ constructor(target, radius){\n this.target = target;\n this.radius = radius;\n this.action = (target, cam, _eng, _delta)=>{\n const position = target.center;\n const focus = cam.getFocus();\n const direction = position.sub(focus);\n const distance = direction.size;\n if (distance >= this.radius) {\n const offset = distance - this.radius;\n return focus.add(direction.normalize().scale(offset));\n }\n return focus;\n };\n }\n }\n /**\n * Prevent a camera from going beyond the given camera dimensions.\n */ class LimitCameraBoundsStrategy {\n constructor(target){\n this.target = target;\n /**\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\n *\n * Note that this strategy does not perform any movement by itself.\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\n *\n * Make sure that the camera bounds are at least as large as the viewport size.\n * @param target The bounding box to limit the camera to\n */ this.boundSizeChecked = false; // Check and warn only once\n this.action = (target, cam, _eng, _delta)=>{\n const focus = cam.getFocus();\n if (!this.boundSizeChecked) {\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) Logger.getInstance().warn(\"Camera bounds should not be smaller than the engine viewport\");\n this.boundSizeChecked = true;\n }\n let focusX = focus.x;\n let focusY = focus.y;\n if (focus.x < target.left + _eng.halfDrawWidth) focusX = target.left + _eng.halfDrawWidth;\n else if (focus.x > target.right - _eng.halfDrawWidth) focusX = target.right - _eng.halfDrawWidth;\n if (focus.y < target.top + _eng.halfDrawHeight) focusY = target.top + _eng.halfDrawHeight;\n else if (focus.y > target.bottom - _eng.halfDrawHeight) focusY = target.bottom - _eng.halfDrawHeight;\n return vec(focusX, focusY);\n };\n }\n }\n const CameraEvents = {\n Initialize: \"initialize\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\"\n };\n /**\n * Cameras\n *\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\n * to move around your game and set focus. They are used to determine\n * what is \"off screen\" and can be used to scale the game.\n *\n */ class Camera {\n constructor(){\n this.events = new EventEmitter();\n this.transform = AffineMatrix.identity();\n this.inverse = AffineMatrix.identity();\n this._cameraStrategies = [];\n this.strategy = new StrategyContainer(this);\n /**\n * Get or set current zoom of the camera, defaults to 1\n */ this._z = 1;\n /**\n * Get or set rate of change in zoom, defaults to 0\n */ this.dz = 0;\n /**\n * Get or set zoom acceleration\n */ this.az = 0;\n /**\n * Current rotation of the camera\n */ this.rotation = 0;\n this._angularVelocity = 0;\n /**\n * Get or set the camera's position\n */ this._posChanged = false;\n this._pos = watchAny(Vector.Zero, ()=>this._posChanged = true);\n /**\n * Interpolated camera position if more draws are running than updates\n *\n * Enabled when `Engine.fixedUpdateFps` is enabled, in all other cases this will be the same as pos\n */ this.drawPos = this.pos.clone();\n this._oldPos = this.pos.clone();\n /**\n * Get or set the camera's velocity\n */ this.vel = Vector.Zero;\n /**\n * Get or set the camera's acceleration\n */ this.acc = Vector.Zero;\n this._cameraMoving = false;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = null;\n this._lerpEnd = null;\n //camera effects\n this._isShaking = false;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._elapsedShakeTime = 0;\n this._xShake = 0;\n this._yShake = 0;\n this._isZooming = false;\n this._zoomStart = 1;\n this._zoomEnd = 1;\n this._currentZoomTime = 0;\n this._zoomDuration = 0;\n this._zoomEasing = EasingFunctions.EaseInOutCubic;\n this._easing = EasingFunctions.EaseInOutCubic;\n this._halfWidth = 0;\n this._halfHeight = 0;\n this._viewport = null;\n this._isInitialized = false;\n this._snapPos = vec(0, 0);\n }\n get zoom() {\n return this._z;\n }\n set zoom(val) {\n this._z = val;\n if (this._engine) {\n this._halfWidth = this._engine.halfDrawWidth;\n this._halfHeight = this._engine.halfDrawHeight;\n }\n }\n /**\n * Get or set the camera's angular velocity\n */ get angularVelocity() {\n return this._angularVelocity;\n }\n set angularVelocity(value) {\n this._angularVelocity = value;\n }\n get pos() {\n return this._pos;\n }\n set pos(vec) {\n this._pos = watchAny(vec, ()=>this._posChanged = true);\n this._posChanged = true;\n }\n /**\n * Get the camera's x position\n */ get x() {\n return this.pos.x;\n }\n /**\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\n */ set x(value) {\n if (!this._follow && !this._cameraMoving) this.pos = vec(value, this.pos.y);\n }\n /**\n * Get the camera's y position\n */ get y() {\n return this.pos.y;\n }\n /**\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\n */ set y(value) {\n if (!this._follow && !this._cameraMoving) this.pos = vec(this.pos.x, value);\n }\n /**\n * Get or set the camera's x velocity\n */ get dx() {\n return this.vel.x;\n }\n set dx(value) {\n this.vel = vec(value, this.vel.y);\n }\n /**\n * Get or set the camera's y velocity\n */ get dy() {\n return this.vel.y;\n }\n set dy(value) {\n this.vel = vec(this.vel.x, value);\n }\n /**\n * Get or set the camera's x acceleration\n */ get ax() {\n return this.acc.x;\n }\n set ax(value) {\n this.acc = vec(value, this.acc.y);\n }\n /**\n * Get or set the camera's y acceleration\n */ get ay() {\n return this.acc.y;\n }\n set ay(value) {\n this.acc = vec(this.acc.x, value);\n }\n /**\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\n */ getFocus() {\n return this.pos;\n }\n /**\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\n * @param pos The target position to move to\n * @param duration The duration in milliseconds the move should last\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\n */ move(pos, duration, easingFn = EasingFunctions.EaseInOutCubic) {\n if (typeof easingFn !== \"function\") throw \"Please specify an EasingFunction\";\n // cannot move when following an actor\n if (this._follow) return Promise.reject(pos);\n // resolve existing promise, if any\n if (this._lerpPromise && this._lerpResolve) this._lerpResolve(pos);\n this._lerpPromise = new Promise((resolve)=>{\n this._lerpResolve = resolve;\n });\n this._lerpStart = this.getFocus().clone();\n this._lerpDuration = duration;\n this._lerpEnd = pos;\n this._currentLerpTime = 0;\n this._cameraMoving = true;\n this._easing = easingFn;\n return this._lerpPromise;\n }\n /**\n * Sets the camera to shake at the specified magnitudes for the specified duration\n * @param magnitudeX The x magnitude of the shake\n * @param magnitudeY The y magnitude of the shake\n * @param duration The duration of the shake in milliseconds\n */ shake(magnitudeX, magnitudeY, duration) {\n this._isShaking = true;\n this._shakeMagnitudeX = magnitudeX;\n this._shakeMagnitudeY = magnitudeY;\n this._shakeDuration = duration;\n }\n /**\n * Zooms the camera in or out by the specified scale over the specified duration.\n * If no duration is specified, it take effect immediately.\n * @param scale The scale of the zoom\n * @param duration The duration of the zoom in milliseconds\n */ zoomOverTime(scale, duration = 0, easingFn = EasingFunctions.EaseInOutCubic) {\n this._zoomPromise = new Promise((resolve)=>{\n this._zoomResolve = resolve;\n });\n if (duration) {\n this._isZooming = true;\n this._zoomEasing = easingFn;\n this._currentZoomTime = 0;\n this._zoomDuration = duration;\n this._zoomStart = this.zoom;\n this._zoomEnd = scale;\n } else {\n this._isZooming = false;\n this.zoom = scale;\n return Promise.resolve(true);\n }\n return this._zoomPromise;\n }\n /**\n * Gets the bounding box of the viewport of this camera in world coordinates\n */ get viewport() {\n if (this._viewport) return this._viewport;\n return new BoundingBox(0, 0, 0, 0);\n }\n /**\n * Adds a new camera strategy to this camera\n * @param cameraStrategy Instance of an [[CameraStrategy]]\n */ addStrategy(cameraStrategy) {\n this._cameraStrategies.push(cameraStrategy);\n }\n /**\n * Removes a camera strategy by reference\n * @param cameraStrategy Instance of an [[CameraStrategy]]\n */ removeStrategy(cameraStrategy) {\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\n }\n /**\n * Clears all camera strategies from the camera\n */ clearAllStrategies() {\n this._cameraStrategies.length = 0;\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before a scene is updated.\n */ onPreUpdate(engine, delta) {\n // Overridable\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */ onPostUpdate(engine, delta) {\n // Overridable\n }\n get isInitialized() {\n return this._isInitialized;\n }\n _initialize(engine) {\n if (!this.isInitialized) {\n this._engine = engine;\n this._screen = engine.screen;\n const currentRes = this._screen.contentArea;\n let center = vec(currentRes.width / 2, currentRes.height / 2);\n if (!this._engine.loadingComplete) {\n // If there was a loading screen, we peek the configured resolution\n const res = this._screen.peekResolution();\n if (res) center = vec(res.width / 2, res.height / 2);\n }\n this._halfWidth = center.x;\n this._halfHeight = center.y;\n // If the user has not set the camera pos, apply default center screen position\n if (!this._posChanged) this.pos = center;\n this.pos.clone(this.drawPos);\n // First frame bootstrap\n // Ensure camera tx is correct\n // Run update twice to ensure properties are init'd\n this.updateTransform(this.pos);\n // Run strategies for first frame\n this.runStrategies(engine, engine.clock.elapsed());\n // Setup the first frame viewport\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform(this.pos);\n this.pos.clone(this._oldPos);\n this.onInitialize(engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */ onInitialize(engine) {\n // Overridable\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n runStrategies(engine, delta) {\n for (const s of this._cameraStrategies)this.pos = s.action.call(s, s.target, this, engine, delta);\n }\n updateViewport() {\n // recalculate viewport\n this._viewport = new BoundingBox(this.x - this._halfWidth, this.y - this._halfHeight, this.x + this._halfWidth, this.y + this._halfHeight);\n }\n update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this.pos.clone(this._oldPos);\n // Update placements based on linear algebra\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\n this.zoom += this.dz * delta / 1000;\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\n this.dz += this.az * delta / 1000;\n this.rotation += this.angularVelocity * delta / 1000;\n if (this._isZooming) {\n if (this._currentZoomTime < this._zoomDuration) {\n const zoomEasing = this._zoomEasing;\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\n this.zoom = newZoom;\n this._currentZoomTime += delta;\n } else {\n this._isZooming = false;\n this.zoom = this._zoomEnd;\n this._currentZoomTime = 0;\n this._zoomResolve(true);\n }\n }\n if (this._cameraMoving) {\n if (this._currentLerpTime < this._lerpDuration) {\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\n this.pos = lerpPoint;\n this._currentLerpTime += delta;\n } else {\n this.pos = this._lerpEnd;\n const end = this._lerpEnd.clone();\n this._lerpStart = null;\n this._lerpEnd = null;\n this._currentLerpTime = 0;\n this._cameraMoving = false;\n // Order matters here, resolve should be last so any chain promises have a clean slate\n this._lerpResolve(end);\n }\n }\n if (this._isDoneShaking()) {\n this._isShaking = false;\n this._elapsedShakeTime = 0;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._xShake = 0;\n this._yShake = 0;\n } else {\n this._elapsedShakeTime += delta;\n this._xShake = (Math.random() * this._shakeMagnitudeX | 0) + 1;\n this._yShake = (Math.random() * this._shakeMagnitudeY | 0) + 1;\n }\n this.runStrategies(engine, delta);\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform(this.pos);\n this._postupdate(engine, delta);\n }\n /**\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\n * @param ctx Canvas context to apply transformations\n */ draw(ctx) {\n // default to the current position\n this.pos.clone(this.drawPos);\n // interpolation if fixed update is on\n // must happen on the draw, because more draws are potentially happening than updates\n if (this._engine.fixedUpdateFps) {\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n const interpolatedPos = this.pos.scale(blend).add(this._oldPos.scale(1.0 - blend));\n interpolatedPos.clone(this.drawPos);\n this.updateTransform(interpolatedPos);\n }\n // Snap camera to pixel\n if (ctx.snapToPixel) {\n const snapPos = this.drawPos.clone(this._snapPos);\n snapPos.x = ~~(snapPos.x + pixelSnapEpsilon * sign(snapPos.x));\n snapPos.y = ~~(snapPos.y + pixelSnapEpsilon * sign(snapPos.y));\n snapPos.clone(this.drawPos);\n this.updateTransform(snapPos);\n }\n ctx.multiply(this.transform);\n }\n updateTransform(pos) {\n // center the camera\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\n const cameraPos = vec(-pos.x + newCanvasWidth / 2 + this._xShake, -pos.y + newCanvasHeight / 2 + this._yShake);\n // Calculate camera transform\n this.transform.reset();\n this.transform.scale(this.zoom, this.zoom);\n // rotate about the focus\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\n this.transform.rotate(this.rotation);\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\n this.transform.translate(cameraPos.x, cameraPos.y);\n this.transform.inverse(this.inverse);\n }\n _isDoneShaking() {\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\n }\n }\n const TriggerEvents = {\n ExitTrigger: \"exit\",\n EnterTrigger: \"enter\"\n };\n const triggerDefaults = {\n pos: Vector.Zero,\n width: 10,\n height: 10,\n visible: false,\n action: ()=>{\n return;\n },\n filter: ()=>true,\n repeat: -1\n };\n /**\n * Triggers are a method of firing arbitrary code on collision. These are useful\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\n */ class Trigger extends Actor {\n /**\n *\n * @param opts Trigger options\n */ constructor(opts){\n super({\n x: opts.pos.x,\n y: opts.pos.y,\n width: opts.width,\n height: opts.height\n });\n this.events = new EventEmitter();\n /**\n * Action to fire when triggered by collision\n */ this.action = ()=>{\n return;\n };\n /**\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\n * filter return true for the collided actor.\n */ this.filter = ()=>true;\n /**\n * Number of times to repeat before killing the trigger,\n */ this.repeat = -1;\n opts = {\n ...triggerDefaults,\n ...opts\n };\n this.filter = opts.filter || this.filter;\n this.repeat = opts.repeat || this.repeat;\n this.action = opts.action || this.action;\n if (opts.target) this.target = opts.target;\n this.graphics.visible = opts.visible;\n this.body.collisionType = CollisionType.Passive;\n this.events.on(\"collisionstart\", (evt)=>{\n if (this.filter(evt.other)) {\n this.events.emit(\"enter\", new EnterTriggerEvent(this, evt.other));\n this._dispatchAction();\n // remove trigger if its done, -1 repeat forever\n if (this.repeat === 0) this.kill();\n }\n });\n this.events.on(\"collisionend\", (evt)=>{\n if (this.filter(evt.other)) this.events.emit(\"exit\", new ExitTriggerEvent(this, evt.other));\n });\n }\n set target(target) {\n this._target = target;\n this.filter = (actor)=>actor === target;\n }\n get target() {\n return this._target;\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n _dispatchAction() {\n if (this.repeat !== 0) {\n this.action.call(this);\n this.repeat--;\n }\n }\n }\n /**\n * Higher priorities run earlier than others in the system update\n */ const SystemPriority = {\n Highest: -Infinity,\n Higher: -5,\n Average: 0,\n Lower: 5,\n Lowest: Infinity\n };\n /**\n * Enum that determines whether to run the system in the update or draw phase\n */ var SystemType;\n (function(SystemType) {\n SystemType[\"Update\"] = \"update\";\n SystemType[\"Draw\"] = \"draw\";\n })(SystemType || (SystemType = {}));\n /**\n * An Excalibur [[System]] that updates entities of certain types.\n * Systems are scene specific\n *\n *\n *\n * Excalibur Systems currently require at least 1 Component type to operated\n *\n * Multiple types are declared as a type union\n * For example:\n *\n * ```typescript\n * class MySystem extends System {\n * public readonly types = ['a', 'b'] as const;\n * public readonly systemType = SystemType.Update;\n * public update(entities: Entity) {\n * ...\n * }\n * }\n * ```\n */ class System {\n constructor(){\n /**\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\n * For a system to execute after all other a higher priority value (10 for example) must be set.\n */ this.priority = SystemPriority.Average;\n }\n }\n // Add/Remove entities and components\n class EntityManager {\n constructor(_world){\n this._world = _world;\n this.entities = [];\n this._entityIndex = {};\n this._entitiesToRemove = [];\n }\n /**\n * Runs the entity lifecycle\n * @param scene\n * @param elapsed\n */ updateEntities(scene, elapsed) {\n for (const entity of this.entities){\n entity.update(scene.engine, elapsed);\n if (!entity.active) this.removeEntity(entity);\n }\n }\n findEntitiesForRemoval() {\n for (const entity of this.entities)if (!entity.active) this.removeEntity(entity);\n }\n /**\n * Adds an entity to be tracked by the EntityManager\n * @param entity\n */ addEntity(entity) {\n entity.active = true;\n entity.scene = this._world.scene;\n if (entity && !this._entityIndex[entity.id]) {\n this._entityIndex[entity.id] = entity;\n this.entities.push(entity);\n this._world.queryManager.addEntity(entity);\n // if entity has children\n entity.children.forEach((c)=>{\n c.scene = entity.scene;\n this.addEntity(c);\n });\n entity.childrenAdded$.register({\n notify: (e)=>{\n this.addEntity(e);\n }\n });\n entity.childrenRemoved$.register({\n notify: (e)=>{\n this.removeEntity(e, false);\n }\n });\n }\n }\n removeEntity(idOrEntity, deferred = true) {\n var _a, _b;\n let id = 0;\n if (idOrEntity instanceof Entity) id = idOrEntity.id;\n else id = idOrEntity;\n const entity = this._entityIndex[id];\n if (entity && entity.active) entity.active = false;\n if (entity && deferred) {\n this._entitiesToRemove.push(entity);\n return;\n }\n delete this._entityIndex[id];\n if (entity) {\n entity.scene = null;\n removeItemFromArray(entity, this.entities);\n this._world.queryManager.removeEntity(entity);\n // if entity has children\n entity.children.forEach((c)=>{\n c.scene = null;\n this.removeEntity(c, deferred);\n });\n entity.childrenAdded$.clear();\n entity.childrenRemoved$.clear();\n // stats\n if ((_b = (_a = this._world) === null || _a === void 0 ? void 0 : _a.scene) === null || _b === void 0 ? void 0 : _b.engine) this._world.scene.engine.stats.currFrame.actors.killed++;\n }\n }\n processEntityRemovals() {\n for (const entity of this._entitiesToRemove){\n if (entity.active) continue;\n this.removeEntity(entity, false);\n }\n this._entitiesToRemove.length = 0;\n }\n processComponentRemovals() {\n for (const entity of this.entities)entity.processComponentRemoval();\n }\n getById(id) {\n return this._entityIndex[id];\n }\n getByName(name) {\n return this.entities.filter((e)=>e.name === name);\n }\n clear() {\n for(let i = this.entities.length - 1; i >= 0; i--)this.removeEntity(this.entities[i]);\n }\n }\n /**\n * Represents query for entities that match a list of types that is cached and observable\n *\n * Queries can be strongly typed by supplying a type union in the optional type parameter\n * ```typescript\n * const queryAB = new ex.Query(['A', 'B']);\n * ```\n */ class Query {\n constructor(requiredComponents){\n this.requiredComponents = requiredComponents;\n this.components = new Set();\n this.entities = [];\n /**\n * This fires right after the component is added\n */ this.entityAdded$ = new Observable();\n /**\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\n */ this.entityRemoved$ = new Observable();\n if (requiredComponents.length === 0) throw new Error(\"Cannot create query without components\");\n for (const type of requiredComponents)this.components.add(type);\n this.id = Query.createId(requiredComponents);\n }\n static createId(requiredComponents) {\n // TODO what happens if a user defines the same type name as a built in type\n // ! TODO this could be dangerous depending on the bundler's settings for names\n // Maybe some kind of hash function is better here?\n return requiredComponents.slice().map((c)=>c.name).sort().join(\"-\");\n }\n /**\n * Potentially adds an entity to a query index, returns true if added, false if not\n * @param entity\n */ checkAndAdd(entity) {\n if (!this.entities.includes(entity) && entity.hasAll(Array.from(this.components))) {\n this.entities.push(entity);\n this.entityAdded$.notifyAll(entity);\n return true;\n }\n return false;\n }\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index > -1) {\n this.entities.splice(index, 1);\n this.entityRemoved$.notifyAll(entity);\n }\n }\n /**\n * Returns a list of entities that match the query\n * @param sort Optional sorting function to sort entities returned from the query\n */ getEntities(sort) {\n if (sort) this.entities.sort(sort);\n return this.entities;\n }\n }\n class TagQuery {\n constructor(requiredTags){\n this.requiredTags = requiredTags;\n this.tags = new Set();\n this.entities = [];\n /**\n * This fires right after the component is added\n */ this.entityAdded$ = new Observable();\n /**\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\n */ this.entityRemoved$ = new Observable();\n if (requiredTags.length === 0) throw new Error(\"Cannot create tag query without tags\");\n for (const tag of requiredTags)this.tags.add(tag);\n this.id = TagQuery.createId(requiredTags);\n }\n static createId(requiredComponents) {\n return requiredComponents.slice().sort().join(\"-\");\n }\n checkAndAdd(entity) {\n if (!this.entities.includes(entity) && entity.hasAllTags(Array.from(this.tags))) {\n this.entities.push(entity);\n this.entityAdded$.notifyAll(entity);\n return true;\n }\n return false;\n }\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index > -1) {\n this.entities.splice(index, 1);\n this.entityRemoved$.notifyAll(entity);\n }\n }\n /**\n * Returns a list of entities that match the query\n * @param sort Optional sorting function to sort entities returned from the query\n */ getEntities(sort) {\n if (sort) this.entities.sort(sort);\n return this.entities;\n }\n }\n /**\n * The query manager is responsible for updating all queries when entities/components change\n */ class QueryManager {\n constructor(_world){\n this._world = _world;\n this._queries = new Map();\n this._addComponentHandlers = new Map();\n this._removeComponentHandlers = new Map();\n this._componentToQueriesIndex = new Map();\n this._tagQueries = new Map();\n this._addTagHandlers = new Map();\n this._removeTagHandlers = new Map();\n this._tagToQueriesIndex = new Map();\n this._createAddComponentHandler = (entity)=>(c)=>{\n this.addComponent(entity, c);\n };\n this._createRemoveComponentHandler = (entity)=>(c)=>{\n this.removeComponent(entity, c);\n };\n this._createAddTagHandler = (entity)=>(tag)=>{\n this.addTag(entity, tag);\n };\n this._createRemoveTagHandler = (entity)=>(tag)=>{\n this.removeTag(entity, tag);\n };\n }\n createQuery(requiredComponents) {\n const id = Query.createId(requiredComponents);\n if (this._queries.has(id)) // short circuit if query is already created\n return this._queries.get(id);\n const query = new Query(requiredComponents);\n this._queries.set(query.id, query);\n // index maintenance\n for (const component of requiredComponents){\n const queries = this._componentToQueriesIndex.get(component);\n if (!queries) this._componentToQueriesIndex.set(component, [\n query\n ]);\n else queries.push(query);\n }\n for (const entity of this._world.entities)this.addEntity(entity);\n return query;\n }\n createTagQuery(requiredTags) {\n const id = TagQuery.createId(requiredTags);\n if (this._tagQueries.has(id)) // short circuit if query is already created\n return this._tagQueries.get(id);\n const query = new TagQuery(requiredTags);\n this._tagQueries.set(query.id, query);\n // index maintenance\n for (const tag of requiredTags){\n const queries = this._tagToQueriesIndex.get(tag);\n if (!queries) this._tagToQueriesIndex.set(tag, [\n query\n ]);\n else queries.push(query);\n }\n for (const entity of this._world.entities)this.addEntity(entity);\n return query;\n }\n /**\n * Scans queries and locates any that need this entity added\n * @param entity\n */ addEntity(entity) {\n const maybeAddComponent = this._addComponentHandlers.get(entity);\n const maybeRemoveComponent = this._removeComponentHandlers.get(entity);\n const addComponent = maybeAddComponent !== null && maybeAddComponent !== void 0 ? maybeAddComponent : this._createAddComponentHandler(entity);\n const removeComponent = maybeRemoveComponent !== null && maybeRemoveComponent !== void 0 ? maybeRemoveComponent : this._createRemoveComponentHandler(entity);\n this._addComponentHandlers.set(entity, addComponent);\n this._removeComponentHandlers.set(entity, removeComponent);\n const maybeAddTag = this._addTagHandlers.get(entity);\n const maybeRemoveTag = this._removeTagHandlers.get(entity);\n const addTag = maybeAddTag !== null && maybeAddTag !== void 0 ? maybeAddTag : this._createAddTagHandler(entity);\n const removeTag = maybeRemoveTag !== null && maybeRemoveTag !== void 0 ? maybeRemoveTag : this._createRemoveTagHandler(entity);\n this._addTagHandlers.set(entity, addTag);\n this._removeTagHandlers.set(entity, removeTag);\n for (const query of this._queries.values())query.checkAndAdd(entity);\n for (const tagQuery of this._tagQueries.values())tagQuery.checkAndAdd(entity);\n entity.componentAdded$.subscribe(addComponent);\n entity.componentRemoved$.subscribe(removeComponent);\n entity.tagAdded$.subscribe(addTag);\n entity.tagRemoved$.subscribe(removeTag);\n }\n /**\n * Scans queries and locates any that need this entity removed\n * @param entity\n */ removeEntity(entity) {\n // Handle components\n const addComponent = this._addComponentHandlers.get(entity);\n const removeComponent = this._removeComponentHandlers.get(entity);\n for (const query of this._queries.values())query.removeEntity(entity);\n if (addComponent) entity.componentAdded$.unsubscribe(addComponent);\n if (removeComponent) entity.componentRemoved$.unsubscribe(removeComponent);\n // Handle tags\n const addTag = this._addTagHandlers.get(entity);\n const removeTag = this._removeTagHandlers.get(entity);\n for (const tagQuery of this._tagQueries.values())tagQuery.removeEntity(entity);\n if (addTag) entity.tagAdded$.unsubscribe(addTag);\n if (removeTag) entity.tagRemoved$.unsubscribe(removeTag);\n }\n /**\n * Updates any queries when a component is added to an entity\n * @param entity\n * @param component\n */ addComponent(entity, component) {\n var _a;\n const queries = (_a = this._componentToQueriesIndex.get(component.constructor)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries)query.checkAndAdd(entity);\n }\n /**\n * Updates any queries when a component is removed from an entity\n * @param entity\n * @param component\n */ removeComponent(entity, component) {\n var _a;\n const queries = (_a = this._componentToQueriesIndex.get(component.constructor)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries)query.removeEntity(entity);\n }\n /**\n * Updates any queries when a tag is added to an entity\n * @param entity\n * @param tag\n */ addTag(entity, tag) {\n var _a;\n const queries = (_a = this._tagToQueriesIndex.get(tag)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries)query.checkAndAdd(entity);\n }\n /**\n * Updates any queries when a component is removed from an entity\n * @param entity\n * @param tag\n */ removeTag(entity, tag) {\n var _a;\n const queries = (_a = this._tagToQueriesIndex.get(tag)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries)query.removeEntity(entity);\n }\n }\n /**\n *\n */ function isSystemConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n }\n /**\n * The SystemManager is responsible for keeping track of all systems in a scene.\n * Systems are scene specific\n */ class SystemManager {\n constructor(_world){\n this._world = _world;\n /**\n * List of systems, to add a new system call [[SystemManager.addSystem]]\n */ this.systems = [];\n this.initialized = false;\n }\n /**\n * Get a system registered in the manager by type\n * @param systemType\n */ get(systemType) {\n return this.systems.find((s)=>s instanceof systemType);\n }\n /**\n * Adds a system to the manager, it will now be updated every frame\n * @param systemOrCtor\n */ addSystem(systemOrCtor) {\n let system;\n if (systemOrCtor instanceof System) system = systemOrCtor;\n else system = new systemOrCtor(this._world);\n this.systems.push(system);\n this.systems.sort((a, b)=>a.priority - b.priority);\n // If systems are added and the manager has already been init'd\n // then immediately init the system\n if (this.initialized && system.initialize) system.initialize(this._world, this._world.scene);\n }\n /**\n * Removes a system from the manager, it will no longer be updated\n * @param system\n */ removeSystem(system) {\n removeItemFromArray(system, this.systems);\n }\n /**\n * Initialize all systems in the manager\n *\n * Systems added after initialize() will be initialized on add\n */ initialize() {\n if (!this.initialized) {\n this.initialized = true;\n for (const s of this.systems)if (s.initialize) s.initialize(this._world, this._world.scene);\n }\n }\n /**\n * Updates all systems\n * @param type whether this is an update or draw system\n * @param scene context reference\n * @param delta time in milliseconds\n */ updateSystems(type, scene, delta) {\n const systems = this.systems.filter((s)=>s.systemType === type);\n for (const s of systems)if (s.preupdate) s.preupdate(scene, delta);\n for (const s of systems)s.update(delta);\n for (const s of systems)if (s.postupdate) s.postupdate(scene, delta);\n }\n clear() {\n for(let i = this.systems.length - 1; i >= 0; i--)this.removeSystem(this.systems[i]);\n }\n }\n /**\n * The World is a self-contained entity component system for a particular context.\n */ class World {\n /**\n * The context type is passed to the system updates\n * @param scene\n */ constructor(scene){\n this.scene = scene;\n this.queryManager = new QueryManager(this);\n this.entityManager = new EntityManager(this);\n this.systemManager = new SystemManager(this);\n }\n /**\n * Query the ECS world for entities that match your components\n * @param requiredTypes\n */ query(requiredTypes) {\n return this.queryManager.createQuery(requiredTypes);\n }\n queryTags(requiredTags) {\n return this.queryManager.createTagQuery(requiredTags);\n }\n /**\n * Update systems by type and time elapsed in milliseconds\n */ update(type, delta) {\n if (type === SystemType.Update) this.entityManager.updateEntities(this.scene, delta);\n this.systemManager.updateSystems(type, this.scene, delta);\n this.entityManager.findEntitiesForRemoval();\n this.entityManager.processComponentRemovals();\n this.entityManager.processEntityRemovals();\n }\n add(entityOrSystem) {\n if (entityOrSystem instanceof Entity) this.entityManager.addEntity(entityOrSystem);\n if (entityOrSystem instanceof System || isSystemConstructor(entityOrSystem)) this.systemManager.addSystem(entityOrSystem);\n }\n /**\n * Get a system out of the ECS world\n */ get(system) {\n return this.systemManager.get(system);\n }\n remove(entityOrSystem, deferred = true) {\n if (entityOrSystem instanceof Entity) this.entityManager.removeEntity(entityOrSystem, deferred);\n if (entityOrSystem instanceof System) this.systemManager.removeSystem(entityOrSystem);\n }\n get entities() {\n return this.entityManager.entities;\n }\n clearEntities() {\n this.entityManager.clear();\n }\n clearSystems() {\n this.systemManager.clear();\n }\n }\n class EulerIntegrator {\n static integrate(transform, motion, totalAcc, elapsedMs) {\n const seconds = elapsedMs / 1000;\n // This code looks a little wild, but it's to avoid creating any new Vector instances\n // integration is done in a tight loop so this is key to avoid GC'ing\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\n transform.pos.add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS).addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\n const rotation = transform.rotation + motion.angularVelocity * seconds;\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\n const tx = transform.get();\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\n }\n }\n // Scratch vectors to avoid allocation\n EulerIntegrator._POS = new Vector(0, 0);\n EulerIntegrator._SCALE = new Vector(1, 1);\n EulerIntegrator._ACC = new Vector(0, 0);\n EulerIntegrator._VEL = new Vector(0, 0);\n EulerIntegrator._VEL_ACC = new Vector(0, 0);\n EulerIntegrator._SCALE_FACTOR = new Vector(0, 0);\n class MotionSystem extends System {\n constructor(world, physics){\n super();\n this.world = world;\n this.physics = physics;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._physicsConfigDirty = false;\n physics.$configUpdate.subscribe(()=>this._physicsConfigDirty = true);\n this.query = this.world.query([\n TransformComponent,\n MotionComponent\n ]);\n }\n update(elapsedMs) {\n let transform;\n let motion;\n const entities = this.query.entities;\n for(let i = 0; i < entities.length; i++){\n transform = entities[i].get(TransformComponent);\n motion = entities[i].get(MotionComponent);\n const optionalBody = entities[i].get(BodyComponent);\n if (this._physicsConfigDirty && optionalBody) optionalBody.updatePhysicsConfig(this.physics.config.bodies);\n if (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.sleeping) continue;\n const totalAcc = motion.acc.clone();\n if ((optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.collisionType) === CollisionType.Active && (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.useGravity)) totalAcc.addEqual(this.physics.config.gravity);\n optionalBody === null || optionalBody === void 0 || optionalBody.captureOldTransform();\n // Update transform and motion based on Euler linear algebra\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\n }\n }\n }\n /**\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\n * and negates velocity along the collision normal.\n *\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\n *\n */ class ArcadeSolver {\n constructor(config){\n this.config = config;\n this.directionMap = new Map();\n this.distanceMap = new Map();\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter((c)=>!c.isCanceled());\n // Locate collision bias order\n let bias;\n switch(this.config.contactSolveBias){\n case ContactSolveBias.HorizontalFirst:\n bias = HorizontalFirst;\n break;\n case ContactSolveBias.VerticalFirst:\n bias = VerticalFirst;\n break;\n default:\n bias = None;\n }\n // Sort by bias (None, VerticalFirst, HorizontalFirst) to avoid artifacts with seams\n // Sort contacts by distance to avoid artifacts with seams\n // It's important to solve in a specific order\n contacts.sort((a, b)=>{\n const aDir = this.directionMap.get(a.id);\n const bDir = this.directionMap.get(b.id);\n const aDist = this.distanceMap.get(a.id);\n const bDist = this.distanceMap.get(b.id);\n return bias[aDir] - bias[bDir] || aDist - bDist;\n });\n for (const contact of contacts){\n // Solve position first in arcade\n this.solvePosition(contact);\n // Solve velocity second in arcade\n this.solveVelocity(contact);\n }\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n const epsilon = .0001;\n for (const contact of contacts){\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\n this.distanceMap.set(contact.id, distance);\n this.directionMap.set(contact.id, side === Side.Left || side === Side.Right ? \"horizontal\" : \"vertical\");\n // Publish collision events on both participants\n contact.colliderA.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\n contact.colliderB.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact));\n }\n }\n postSolve(contacts) {\n var _a, _b;\n for (const contact of contacts){\n if (contact.isCanceled()) continue;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n // Publish collision events on both participants\n contact.colliderA.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\n contact.colliderB.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact));\n }\n }\n solvePosition(contact) {\n var _a, _b;\n const epsilon = .0001;\n // if bounds no longer intersect skip to the next\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\n // Cancel the contact to prevent and solving\n contact.cancel();\n return;\n }\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n return;\n }\n let mtv = contact.mtv;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) return;\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) // split overlaps if both are Active\n mtv = mtv.scale(0.5);\n // Resolve overlaps\n if (bodyA.collisionType === CollisionType.Active) {\n bodyA.globalPos.x -= mtv.x;\n bodyA.globalPos.y -= mtv.y;\n colliderA.update(bodyA.transform.get());\n }\n if (bodyB.collisionType === CollisionType.Active) {\n bodyB.globalPos.x += mtv.x;\n bodyB.globalPos.y += mtv.y;\n colliderB.update(bodyB.transform.get());\n }\n }\n }\n solveVelocity(contact) {\n var _a, _b;\n if (contact.isCanceled()) return;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) return;\n const normal = contact.normal;\n const opposite = normal.negate();\n if (bodyA.collisionType === CollisionType.Active) // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform when sliding off\n {\n if (bodyA.vel.normalize().dot(opposite) < 0) {\n // Cancel out velocity opposite direction of collision normal\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\n bodyA.vel = bodyA.vel.add(velAdj);\n }\n }\n if (bodyB.collisionType === CollisionType.Active) // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform\n {\n if (bodyB.vel.normalize().dot(normal) < 0) {\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\n bodyB.vel = bodyB.vel.add(velAdj);\n }\n }\n }\n }\n }\n /**\n * Holds information about contact points, meant to be reused over multiple frames of contact\n */ class ContactConstraintPoint {\n constructor(point, local, contact){\n this.point = point;\n this.local = local;\n this.contact = contact;\n /**\n * Impulse accumulated over time in normal direction\n */ this.normalImpulse = 0;\n /**\n * Impulse accumulated over time in the tangent direction\n */ this.tangentImpulse = 0;\n /**\n * Effective mass seen in the normal direction\n */ this.normalMass = 0;\n /**\n * Effective mass seen in the tangent direction\n */ this.tangentMass = 0;\n /**\n * Direction from center of mass of bodyA to contact point\n */ this.aToContact = new Vector(0, 0);\n /**\n * Direction from center of mass of bodyB to contact point\n */ this.bToContact = new Vector(0, 0);\n /**\n * Original contact velocity combined with bounciness\n */ this.originalVelocityAndRestitution = 0;\n this.update();\n }\n /**\n * Updates the contact information\n */ update() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const normal = this.contact.normal;\n const tangent = this.contact.tangent;\n this.aToContact = this.point.sub(bodyA.globalPos);\n this.bToContact = this.point.sub(bodyB.globalPos);\n const aToContactNormal = this.aToContact.cross(normal);\n const bToContactNormal = this.bToContact.cross(normal);\n this.normalMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactNormal * aToContactNormal + bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = this.aToContact.cross(tangent);\n const bToContactTangent = this.bToContact.cross(tangent);\n this.tangentMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactTangent * aToContactTangent + bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n }\n return this;\n }\n /**\n * Returns the relative velocity between bodyA and bodyB\n */ getRelativeVelocity() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Relative velocity in linear terms\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\n return velB.sub(velA);\n }\n return Vector.Zero;\n }\n }\n class RealisticSolver {\n constructor(config){\n this.config = config;\n this.lastFrameContacts = new Map();\n // map contact id to contact points\n this.idToContactConstraint = new Map();\n }\n getContactConstraints(id) {\n var _a;\n return (_a = this.idToContactConstraint.get(id)) !== null && _a !== void 0 ? _a : [];\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter((c)=>!c.isCanceled());\n // Solve velocity first\n this.solveVelocity(contacts);\n // Solve position last because non-overlap is the most important\n this.solvePosition(contacts);\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n var _a, _b, _c;\n const epsilon = .0001;\n for (const contact of contacts){\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderA.events.emit(\"beforecollisionresolve\", new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n contact.colliderB.events.emit(\"beforecollisionresolve\", new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n // Match awake state for sleeping\n contact.matchAwake();\n }\n // Keep track of contacts that done\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\n for (const contact of contacts){\n // Remove all current contacts that are not done\n const index = finishedContactIds.indexOf(contact.id);\n if (index > -1) finishedContactIds.splice(index, 1);\n const contactPoints = (_a = this.idToContactConstraint.get(contact.id)) !== null && _a !== void 0 ? _a : [];\n let pointIndex = 0;\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) for (const point of contact.points){\n const normal = contact.normal;\n const tangent = contact.tangent;\n const aToContact = point.sub(bodyA.globalPos);\n const bToContact = point.sub(bodyB.globalPos);\n const aToContactNormal = aToContact.cross(normal);\n const bToContactNormal = bToContact.cross(normal);\n const normalMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactNormal * aToContactNormal + bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = aToContact.cross(tangent);\n const bToContactTangent = bToContact.cross(tangent);\n const tangentMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactTangent * aToContactTangent + bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n // Preserve normal/tangent impulse by re-using the contact point if it's close\n if (contactPoints[pointIndex] && ((_c = (_b = contactPoints[pointIndex]) === null || _b === void 0 ? void 0 : _b.point) === null || _c === void 0 ? void 0 : _c.squareDistance(point)) < 4) {\n contactPoints[pointIndex].point = point;\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\n } else // new contact if it's not close or doesn't exist\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\n // Update contact point calculations\n contactPoints[pointIndex].aToContact = aToContact;\n contactPoints[pointIndex].bToContact = bToContact;\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\n // Calculate relative velocity before solving to accurately do restitution\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\n if (relativeVelocity < -0.1) contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\n pointIndex++;\n }\n this.idToContactConstraint.set(contact.id, contactPoints);\n }\n // Clean up any contacts that did not occur last frame\n for (const id of finishedContactIds)this.idToContactConstraint.delete(id);\n // Warm contacts with accumulated impulse\n // Useful for tall stacks\n if (this.config.warmStart) this.warmStart(contacts);\n else for (const contact of contacts){\n const contactPoints = this.getContactConstraints(contact.id);\n for (const point of contactPoints){\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n postSolve(contacts) {\n for (const contact of contacts){\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip post solve for active+passive collisions\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n // Update motion values for sleeping\n bodyA.updateMotion();\n bodyB.updateMotion();\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderA.events.emit(\"aftercollisionresolve\", new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n contact.colliderB.events.emit(\"aftercollisionresolve\", new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n }\n // Store contacts\n this.lastFrameContacts.clear();\n for (const c of contacts)this.lastFrameContacts.set(c.id, c);\n }\n /**\n * Warm up body's based on previous frame contact points\n * @param contacts\n */ warmStart(contacts) {\n var _a, _b, _c;\n for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const contactPoints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of contactPoints)if (this.config.warmStart) {\n const normalImpulse = contact.normal.scale(point.normalImpulse);\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\n const impulse = normalImpulse.add(tangentImpulse);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n } else {\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n }\n /**\n * Iteratively solve the position overlap constraint\n * @param contacts\n */ solvePosition(contacts) {\n var _a, _b, _c;\n for(let i = 0; i < this.config.positionIterations; i++)for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of constraints){\n const normal = contact.normal;\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\n const steeringConstant = this.config.steeringFactor; //0.2;\n const maxCorrection = -5;\n const slop = this.config.slop; //1;\n // Clamp to avoid over-correction\n // Remember that we are shooting for 0 overlap in the end\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\n const impulse = normal.scale(-steeringForce * point.normalMass);\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\n // We adjust position and rotation instead of doing the velocity\n if (bodyA.collisionType === CollisionType.Active) {\n // TODO make applyPseudoImpulse function?\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) impulseForce.x = 0;\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) impulseForce.y = 0;\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\n }\n if (bodyB.collisionType === CollisionType.Active) {\n const impulseForce = impulse.scale(bodyB.inverseMass);\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) impulseForce.x = 0;\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) impulseForce.y = 0;\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\n }\n }\n }\n }\n }\n solveVelocity(contacts) {\n var _a, _b, _c;\n for(let i = 0; i < this.config.velocityIterations; i++)for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n const friction = Math.min(bodyA.friction, bodyB.friction);\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n // Friction constraint\n for (const point of constraints){\n const relativeVelocity = point.getRelativeVelocity();\n // Negate velocity in tangent direction to simulate friction\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\n let impulseDelta = tangentVelocity * point.tangentMass;\n // Clamping based in Erin Catto's GDC 2006 talk\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\n // But deltas can vary\n const maxFriction = friction * point.normalImpulse;\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\n impulseDelta = newImpulse - point.tangentImpulse;\n point.tangentImpulse = newImpulse;\n const impulse = contact.tangent.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n // Bounce constraint\n for (const point of constraints){\n // Need to recalc relative velocity because the previous step could have changed vel\n const relativeVelocity = point.getRelativeVelocity();\n // Compute impulse in normal direction\n const normalVelocity = relativeVelocity.dot(contact.normal);\n // Per Erin it is a mistake to apply the restitution inside the iteration\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\n // Clamping based in Erin Catto's GDC 2014 talk\n // Accumulated impulse stored in the contact is always positive (dV > 0)\n // But deltas can be negative\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\n impulseDelta = newImpulse - point.normalImpulse;\n point.normalImpulse = newImpulse;\n const impulse = contact.normal.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n }\n }\n }\n }\n class CollisionSystem extends System {\n get _processor() {\n return this._physics.collisionProcessor;\n }\n constructor(world, _physics){\n super();\n this._physics = _physics;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._configDirty = false;\n this._lastFrameContacts = new Map();\n this._currentFrameContacts = new Map();\n this._arcadeSolver = new ArcadeSolver(_physics.config.arcade);\n this._realisticSolver = new RealisticSolver(_physics.config.realistic);\n this._physics.$configUpdate.subscribe(()=>this._configDirty = true);\n this._trackCollider = (c)=>this._processor.track(c);\n this._untrackCollider = (c)=>this._processor.untrack(c);\n this.query = world.query([\n TransformComponent,\n MotionComponent,\n ColliderComponent\n ]);\n this.query.entityAdded$.subscribe((e)=>{\n const colliderComponent = e.get(ColliderComponent);\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\n const collider = colliderComponent.get();\n if (collider) this._processor.track(collider);\n });\n this.query.entityRemoved$.subscribe((e)=>{\n const colliderComponent = e.get(ColliderComponent);\n const collider = colliderComponent.get();\n if (colliderComponent && collider) this._processor.untrack(collider);\n });\n }\n initialize(world, scene) {\n this._engine = scene.engine;\n }\n update(elapsedMs) {\n var _a, _b, _c, _d;\n if (!this._physics.config.enabled) return;\n // Collect up all the colliders and update them\n let colliders = [];\n for (const entity of this.query.entities){\n const colliderComp = entity.get(ColliderComponent);\n const collider = colliderComp === null || colliderComp === void 0 ? void 0 : colliderComp.get();\n if (colliderComp && ((_a = colliderComp.owner) === null || _a === void 0 ? void 0 : _a.active) && collider) {\n colliderComp.update();\n if (collider instanceof CompositeCollider) {\n const compositeColliders = collider.getColliders();\n if (!collider.compositeStrategy) collider.compositeStrategy = this._physics.config.colliders.compositeStrategy;\n colliders = colliders.concat(compositeColliders);\n } else colliders.push(collider);\n }\n }\n // Update the spatial partitioning data structures\n // TODO if collider invalid it will break the processor\n // TODO rename \"update\" to something more specific\n this._processor.update(colliders);\n // Run broadphase on all colliders and locates potential collisions\n const pairs = this._processor.broadphase(colliders, elapsedMs);\n this._currentFrameContacts.clear();\n // Given possible pairs find actual contacts\n let contacts = this._processor.narrowphase(pairs, (_d = (_c = (_b = this._engine) === null || _b === void 0 ? void 0 : _b.debug) === null || _c === void 0 ? void 0 : _c.stats) === null || _d === void 0 ? void 0 : _d.currFrame);\n const solver = this.getSolver();\n // Solve, this resolves the position/velocity so entities aren't overlapping\n contacts = solver.solve(contacts);\n // Record contacts for start/end\n for (const contact of contacts){\n if (contact.isCanceled()) continue;\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\n const index = contact.id.indexOf(\"|\");\n if (index > 0) {\n const compositeId = contact.id.substring(index + 1);\n this._currentFrameContacts.set(compositeId, contact);\n } else this._currentFrameContacts.set(contact.id, contact);\n }\n // Emit contact start/end events\n this.runContactStartEnd();\n // reset the last frame cache\n this._lastFrameContacts.clear();\n // Keep track of collisions contacts that have started or ended\n this._lastFrameContacts = new Map(this._currentFrameContacts);\n // Process deferred collider removals\n for (const entity of this.query.entities){\n const collider = entity.get(ColliderComponent);\n if (collider) collider.processColliderRemoval();\n }\n }\n getSolver() {\n if (this._configDirty) {\n this._configDirty = false;\n this._arcadeSolver = new ArcadeSolver(this._physics.config.arcade);\n this._realisticSolver = new RealisticSolver(this._physics.config.realistic);\n }\n return this._physics.config.solver === SolverStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\n }\n debug(ex) {\n this._processor.debug(ex);\n }\n runContactStartEnd() {\n // If composite colliders are 'together' collisions may have a duplicate id because we want to treat those as a singular start/end\n for (const [id, c] of this._currentFrameContacts)// find all new contacts\n if (!this._lastFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n const side = Side.fromDirection(c.mtv);\n const opposite = Side.getOpposite(side);\n colliderA.events.emit(\"collisionstart\", new CollisionStartEvent(colliderA, colliderB, side, c));\n colliderA.events.emit(\"contactstart\", new ContactStartEvent(colliderA, colliderB, side, c));\n colliderB.events.emit(\"collisionstart\", new CollisionStartEvent(colliderB, colliderA, opposite, c));\n colliderB.events.emit(\"contactstart\", new ContactStartEvent(colliderB, colliderA, opposite, c));\n }\n // find all contacts that have ceased\n for (const [id, c] of this._lastFrameContacts)if (!this._currentFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n const side = Side.fromDirection(c.mtv);\n const opposite = Side.getOpposite(side);\n colliderA.events.emit(\"collisionend\", new CollisionEndEvent(colliderA, colliderB, side, c));\n colliderA.events.emit(\"contactend\", new ContactEndEvent(colliderA, colliderB, side, c));\n colliderB.events.emit(\"collisionend\", new CollisionEndEvent(colliderB, colliderA, opposite, c));\n colliderB.events.emit(\"contactend\", new ContactEndEvent(colliderB, colliderA, opposite, c));\n }\n }\n }\n var AnimationDirection;\n (function(AnimationDirection) {\n /**\n * Animation is playing forwards\n */ AnimationDirection[\"Forward\"] = \"forward\";\n /**\n * Animation is playing backwards\n */ AnimationDirection[\"Backward\"] = \"backward\";\n })(AnimationDirection || (AnimationDirection = {}));\n var AnimationStrategy;\n (function(AnimationStrategy) {\n /**\n * Animation ends without displaying anything\n */ AnimationStrategy[\"End\"] = \"end\";\n /**\n * Animation loops to the first frame after the last frame\n */ AnimationStrategy[\"Loop\"] = \"loop\";\n /**\n * Animation plays to the last frame, then backwards to the first frame, then repeats\n */ AnimationStrategy[\"PingPong\"] = \"pingpong\";\n /**\n * Animation ends stopping on the last frame\n */ AnimationStrategy[\"Freeze\"] = \"freeze\";\n })(AnimationStrategy || (AnimationStrategy = {}));\n const AnimationEvents = {\n Frame: \"frame\",\n Loop: \"loop\",\n End: \"end\"\n };\n /**\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\n *\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\n */ class Animation extends Graphic {\n constructor(options){\n var _a, _b, _c;\n super(options);\n this.events = new EventEmitter();\n this.frames = [];\n this.strategy = AnimationStrategy.Loop;\n this.frameDuration = 100;\n this._idempotencyToken = -1;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = 0;\n this._pingPongDirection = 1;\n this._done = false;\n this._playing = true;\n this._speed = 1;\n this._reversed = false;\n this.frames = options.frames;\n this.speed = (_a = options.speed) !== null && _a !== void 0 ? _a : this.speed;\n this.strategy = (_b = options.strategy) !== null && _b !== void 0 ? _b : this.strategy;\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : (_c = options.frameDuration) !== null && _c !== void 0 ? _c : this.frameDuration;\n if (options.reverse) this.reverse();\n this.goToFrame(0);\n }\n clone() {\n return new Animation({\n frames: this.frames.map((f)=>({\n ...f\n })),\n frameDuration: this.frameDuration,\n speed: this.speed,\n reverse: this._reversed,\n strategy: this.strategy,\n ...this.cloneGraphicOptions()\n });\n }\n get width() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) return Math.abs(maybeFrame.graphic.width * this.scale.x);\n return 0;\n }\n get height() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) return Math.abs(maybeFrame.graphic.height * this.scale.y);\n return 0;\n }\n /**\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\n * and optional [[AnimationStrategy]]\n *\n * Example:\n * ```typescript\n * const spriteSheet = SpriteSheet.fromImageSource({...});\n *\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\n * ```\n * @param spriteSheet\n * @param frameIndices\n * @param durationPerFrameMs\n * @param strategy\n */ static fromSpriteSheet(spriteSheet, frameIndices, durationPerFrameMs, strategy = AnimationStrategy.Loop) {\n const maxIndex = spriteSheet.sprites.length - 1;\n const invalidIndices = frameIndices.filter((index)=>index < 0 || index > maxIndex);\n if (invalidIndices.length) Animation._LOGGER.warn(`Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(\",\")} no frame will be shown`);\n return new Animation({\n frames: spriteSheet.sprites.filter((_, index)=>frameIndices.indexOf(index) > -1).map((f)=>({\n graphic: f,\n duration: durationPerFrameMs\n })),\n strategy: strategy\n });\n }\n /**\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\n *\n * Example:\n * ```typescript\n * const spriteSheet = SpriteSheet.fromImageSource({...});\n *\n * const anim = Animation.fromSpriteSheetCoordinates({\n * spriteSheet,\n * frameCoordinates: [\n * {x: 0, y: 5, duration: 100, options { flipHorizontal: true }},\n * {x: 1, y: 5, duration: 200},\n * {x: 2, y: 5, duration: 100},\n * {x: 3, y: 5, duration: 500}\n * ],\n * strategy: AnimationStrategy.PingPong\n * });\n * ```\n * @param options\n * @returns Animation\n */ static fromSpriteSheetCoordinates(options) {\n const { spriteSheet: spriteSheet, frameCoordinates: frameCoordinates, durationPerFrameMs: durationPerFrameMs, speed: speed, strategy: strategy, reverse: reverse } = options;\n const defaultDuration = durationPerFrameMs !== null && durationPerFrameMs !== void 0 ? durationPerFrameMs : 100;\n const frames = [];\n for (const coord of frameCoordinates){\n const { x: x, y: y, duration: duration, options: options } = coord;\n const sprite = spriteSheet.getSprite(x, y, options);\n if (sprite) frames.push({\n graphic: sprite,\n duration: duration !== null && duration !== void 0 ? duration : defaultDuration\n });\n else Animation._LOGGER.warn(`Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`);\n }\n return new Animation({\n frames: frames,\n strategy: strategy,\n speed: speed,\n reverse: reverse\n });\n }\n /**\n * Current animation speed\n *\n * 1 meaning normal 1x speed.\n * 2 meaning 2x speed and so on.\n */ get speed() {\n return this._speed;\n }\n /**\n * Current animation speed\n *\n * 1 meaning normal 1x speed.\n * 2 meaning 2x speed and so on.\n */ set speed(val) {\n this._speed = clamp(Math.abs(val), 0, Infinity);\n }\n /**\n * Returns the current Frame of the animation\n *\n * Use [[Animation.currentFrameIndex]] to get the frame number and\n * [[Animation.goToFrame]] to set the current frame index\n */ get currentFrame() {\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) return this.frames[this._currentFrame];\n return null;\n }\n /**\n * Returns the current frame index of the animation\n *\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\n */ get currentFrameIndex() {\n return this._currentFrame;\n }\n /**\n * Returns the amount of time in milliseconds left in the current frame\n */ get currentFrameTimeLeft() {\n return this._timeLeftInFrame;\n }\n /**\n * Returns `true` if the animation is playing\n */ get isPlaying() {\n return this._playing;\n }\n /**\n * Reverses the play direction of the Animation, this preserves the current frame\n */ reverse() {\n // Don't mutate with the original frame list, create a copy\n this.frames = this.frames.slice().reverse();\n this._reversed = !this._reversed;\n }\n /**\n * Returns the current play direction of the animation\n */ get direction() {\n // Keep logically consistent with ping-pong direction\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\n const reversed = this._reversed && this._pingPongDirection === 1 ? true : false;\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\n }\n /**\n * Plays or resumes the animation from the current frame\n */ play() {\n this._playing = true;\n }\n /**\n * Pauses the animation on the current frame\n */ pause() {\n this._playing = false;\n this._firstTick = true; // firstTick must be set to emit the proper frame event\n }\n /**\n * Reset the animation back to the beginning, including if the animation were done\n */ reset() {\n this._done = false;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame) this._timeLeftInFrame = (maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration;\n }\n /**\n * Returns `true` if the animation can end\n */ get canFinish() {\n switch(this.strategy){\n case AnimationStrategy.End:\n case AnimationStrategy.Freeze:\n return true;\n default:\n return false;\n }\n }\n /**\n * Returns `true` if the animation is done, for looping type animations\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\n *\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\n */ get done() {\n return this._done;\n }\n /**\n * Jump the animation immediately to a specific frame if it exists\n *\n * Optionally specify an override for the duration of the frame, useful for\n * keeping multiple animations in sync with one another.\n * @param frameNumber\n * @param duration\n */ goToFrame(frameNumber, duration) {\n this._currentFrame = frameNumber;\n this._timeLeftInFrame = duration !== null && duration !== void 0 ? duration : this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame && !this._done) {\n this._timeLeftInFrame = duration !== null && duration !== void 0 ? duration : (maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration;\n this.events.emit(\"frame\", {\n ...maybeFrame,\n frameIndex: this.currentFrameIndex\n });\n }\n }\n _nextFrame() {\n const currentFrame = this._currentFrame;\n if (this._done) return currentFrame;\n let next = -1;\n switch(this.strategy){\n case AnimationStrategy.Loop:\n next = (currentFrame + 1) % this.frames.length;\n if (next === 0) this.events.emit(\"loop\", this);\n break;\n case AnimationStrategy.End:\n next = currentFrame + 1;\n if (next >= this.frames.length) {\n this._done = true;\n this._currentFrame = this.frames.length;\n this.events.emit(\"end\", this);\n }\n break;\n case AnimationStrategy.Freeze:\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\n if (next >= this.frames.length - 1) {\n this._done = true;\n this.events.emit(\"end\", this);\n }\n break;\n case AnimationStrategy.PingPong:\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\n this._pingPongDirection = -1;\n this.events.emit(\"loop\", this);\n }\n if (currentFrame + this._pingPongDirection < 0) {\n this._pingPongDirection = 1;\n this.events.emit(\"loop\", this);\n }\n next = currentFrame + this._pingPongDirection % this.frames.length;\n break;\n }\n return next;\n }\n /**\n * Called internally by Excalibur to update the state of the animation potential update the current frame\n * @param elapsedMilliseconds Milliseconds elapsed\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\n */ tick(elapsedMilliseconds, idempotencyToken = 0) {\n if (this._idempotencyToken === idempotencyToken) return;\n this._idempotencyToken = idempotencyToken;\n if (!this._playing) return;\n // if it's the first frame emit frame event\n if (this._firstTick) {\n this._firstTick = false;\n this.events.emit(\"frame\", {\n ...this.currentFrame,\n frameIndex: this.currentFrameIndex\n });\n }\n this._timeLeftInFrame -= elapsedMilliseconds * this._speed;\n if (this._timeLeftInFrame <= 0) this.goToFrame(this._nextFrame());\n }\n _drawImage(ctx, x, y) {\n if (this.currentFrame) this.currentFrame.graphic.draw(ctx, x, y);\n }\n }\n Animation._LOGGER = Logger.getInstance();\n class GraphicsGroup extends Graphic {\n constructor(options){\n super(options);\n this._logger = Logger.getInstance();\n this.members = [];\n this.members = options.members;\n this._updateDimensions();\n }\n clone() {\n return new GraphicsGroup({\n members: [\n ...this.members\n ],\n ...this.cloneGraphicOptions()\n });\n }\n _updateDimensions() {\n const bb = this.localBounds;\n this.width = bb.width;\n this.height = bb.height;\n return bb;\n }\n get localBounds() {\n let bb = new BoundingBox();\n for (const member of this.members)if (member instanceof Graphic) bb = member.localBounds.combine(bb);\n else {\n const { graphic: graphic, offset: pos, useBounds: useBounds } = member;\n const shouldUseBounds = useBounds === undefined ? true : useBounds;\n if (graphic) {\n if (shouldUseBounds) bb = graphic.localBounds.translate(pos).combine(bb);\n } else this._logger.warnOnce(`Graphics group member has an null or undefined graphic, member definition: ${JSON.stringify(member)}.`);\n }\n return bb;\n }\n _isAnimationOrGroup(graphic) {\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\n }\n tick(elapsedMilliseconds, idempotencyToken) {\n for (const member of this.members){\n let graphic;\n if (member instanceof Graphic) graphic = member;\n else graphic = member.graphic;\n if (this._isAnimationOrGroup(graphic)) graphic.tick(elapsedMilliseconds, idempotencyToken);\n }\n }\n reset() {\n for (const member of this.members){\n let graphic;\n if (member instanceof Graphic) graphic = member;\n else graphic = member.graphic;\n if (this._isAnimationOrGroup(graphic)) graphic.reset();\n }\n }\n _preDraw(ex, x, y) {\n this._updateDimensions();\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n const pos = Vector.Zero;\n for (const member of this.members){\n let graphic;\n if (member instanceof Graphic) graphic = member;\n else {\n graphic = member.graphic;\n member.offset.clone(pos);\n }\n if (!graphic) continue;\n ex.save();\n ex.translate(x, y);\n graphic.draw(ex, pos.x, pos.y);\n if (this.showDebug) /* istanbul ignore next */ ex.debug.drawRect(0, 0, this.width, this.height);\n ex.restore();\n }\n }\n }\n /**\n * Configurable helper extends base type and makes all properties available as option bag arguments\n * @internal\n * @param base\n */ function Configurable(base) {\n return class extends base {\n assign(props) {\n //set the value of every property that was passed in,\n //if the constructor previously set this value, it will be overridden here\n for(const k in props)// eslint-disable-next-line\n if (typeof this[k] !== \"function\") // eslint-disable-next-line\n this[k] = props[k];\n }\n constructor(...args){\n super(...args);\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\n //of whatever ctor is the implementation, so args.length doesn't work here.\n const size = args.filter(function(value) {\n return value !== undefined;\n }).length;\n if (size === 1 && args[0] && typeof args[0] === \"object\" && !(args[0] instanceof Array)) this.assign(args[0]);\n }\n };\n }\n /**\n * An enum that represents the types of emitter nozzles\n */ var EmitterType;\n (function(EmitterType) {\n /**\n * Constant for the circular emitter type\n */ EmitterType[EmitterType[\"Circle\"] = 0] = \"Circle\";\n /**\n * Constant for the rectangular emitter type\n */ EmitterType[EmitterType[\"Rectangle\"] = 1] = \"Rectangle\";\n })(EmitterType || (EmitterType = {}));\n /**\n * @hidden\n */ class ParticleImpl extends Entity {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite){\n super();\n this.position = new Vector(0, 0);\n this.velocity = new Vector(0, 0);\n this.acceleration = new Vector(0, 0);\n this.particleRotationalVelocity = 0;\n this.currentRotation = 0;\n this.focus = null;\n this.focusAccel = 0;\n this.opacity = 1;\n this.beginColor = Color.White;\n this.endColor = Color.White;\n // Life is counted in ms\n this.life = 300;\n this.fadeFlag = false;\n // Color transitions\n this._rRate = 1;\n this._gRate = 1;\n this._bRate = 1;\n this._aRate = 0;\n this._currentColor = Color.White;\n this.emitter = null;\n this.particleSize = 5;\n this.particleSprite = null;\n this.sizeRate = 0;\n this.elapsedMultiplier = 0;\n this.visible = true;\n this.isOffscreen = false;\n let emitter = emitterOrConfig;\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\n const config = emitterOrConfig;\n emitter = config.emitter;\n life = config.life;\n opacity = config.opacity;\n endColor = config.endColor;\n beginColor = config.beginColor;\n position = config.position;\n velocity = config.velocity;\n acceleration = config.acceleration;\n startSize = config.startSize;\n endSize = config.endSize;\n particleSprite = config.particleSprite;\n }\n this.emitter = emitter;\n this.life = life || this.life;\n this.opacity = opacity || this.opacity;\n this.endColor = endColor || this.endColor.clone();\n this.beginColor = beginColor || this.beginColor.clone();\n this._currentColor = this.beginColor.clone();\n this.particleSprite = particleSprite;\n if (this.emitter.particleTransform === ParticleTransform.Global) {\n const globalPos = this.emitter.transform.globalPos;\n this.position = (position || this.position).add(globalPos);\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\n } else {\n this.velocity = velocity || this.velocity;\n this.position = position || this.position;\n }\n this.acceleration = acceleration || this.acceleration;\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\n this._aRate = this.opacity / this.life;\n this.startSize = startSize || 0;\n this.endSize = endSize || 0;\n if (this.endSize > 0 && this.startSize > 0) {\n this.sizeRate = (this.endSize - this.startSize) / this.life;\n this.particleSize = this.startSize;\n }\n this.addComponent(this.transform = new TransformComponent());\n this.addComponent(this.graphics = new GraphicsComponent());\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // TODO wut\n if (this.particleSprite) {\n this.graphics.opacity = this.opacity;\n this.graphics.use(this.particleSprite);\n } else {\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\n this.graphics.onPostDraw = (ctx)=>{\n ctx.save();\n this.graphics.opacity = this.opacity;\n const tmpColor = this._currentColor.clone();\n tmpColor.a = 1;\n ctx.debug.drawPoint(vec(0, 0), {\n color: tmpColor,\n size: this.particleSize\n });\n ctx.restore();\n };\n }\n }\n kill() {\n this.emitter.removeParticle(this);\n }\n update(engine, delta) {\n this.life = this.life - delta;\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\n if (this.life < 0) this.kill();\n if (this.fadeFlag) this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\n if (this.startSize > 0 && this.endSize > 0) this.particleSize = clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize));\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\n if (this.focus) {\n const accel = this.focus.sub(this.position).normalize().scale(this.focusAccel).scale(delta / 1000);\n this.velocity = this.velocity.add(accel);\n } else this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\n this.position = this.position.add(this.velocity.scale(delta / 1000));\n if (this.particleRotationalVelocity) this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI);\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // todo wut\n this.graphics.opacity = this.opacity;\n }\n }\n /**\n * Particle is used in a [[ParticleEmitter]]\n */ class Particle extends Configurable(ParticleImpl) {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite){\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite);\n }\n }\n var ParticleTransform;\n (function(ParticleTransform) {\n /**\n * [[ParticleTransform.Global]] is the default and emits particles as if\n * they were world space objects, useful for most effects.\n */ ParticleTransform[\"Global\"] = \"global\";\n /**\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\n * as they would in a parent/child actor relationship.\n */ ParticleTransform[\"Local\"] = \"local\";\n })(ParticleTransform || (ParticleTransform = {}));\n /**\n * Using a particle emitter is a great way to create interesting effects\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\n * extend [[Actor]] allowing you to use all of the features that come with.\n */ class ParticleEmitter extends Actor {\n /**\n * Gets the opacity of each particle from 0 to 1.0\n */ get opacity() {\n return this.graphics.opacity;\n }\n /**\n * Gets the opacity of each particle from 0 to 1.0\n */ set opacity(opacity) {\n this.graphics.opacity = opacity;\n }\n /**\n * Gets or sets the sprite that a particle should use\n */ get particleSprite() {\n return this._sprite;\n }\n set particleSprite(val) {\n if (val) this._sprite = val;\n }\n /**\n * @param config particle emitter options bag\n */ constructor(config){\n var _a, _b;\n super({\n width: (_a = config.width) !== null && _a !== void 0 ? _a : 0,\n height: (_b = config.height) !== null && _b !== void 0 ? _b : 0\n });\n this._particlesToEmit = 0;\n this.numParticles = 0;\n /**\n * Gets or sets the isEmitting flag\n */ this.isEmitting = true;\n /**\n * Gets or sets the backing particle collection\n */ this.particles = [];\n /**\n * Gets or sets the backing deadParticle collection\n */ this.deadParticles = [];\n /**\n * Gets or sets the minimum particle velocity\n */ this.minVel = 0;\n /**\n * Gets or sets the maximum particle velocity\n */ this.maxVel = 0;\n /**\n * Gets or sets the acceleration vector for all particles\n */ this.acceleration = new Vector(0, 0);\n /**\n * Gets or sets the minimum angle in radians\n */ this.minAngle = 0;\n /**\n * Gets or sets the maximum angle in radians\n */ this.maxAngle = 0;\n /**\n * Gets or sets the emission rate for particles (particles/sec)\n */ this.emitRate = 1; //particles/sec\n /**\n * Gets or sets the life of each particle in milliseconds\n */ this.particleLife = 2000;\n /**\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\n */ this.fadeFlag = false;\n /**\n * Gets or sets the optional focus where all particles should accelerate towards\n */ this.focus = null;\n /**\n * Gets or sets the acceleration for focusing particles if a focus has been specified\n */ this.focusAccel = null;\n /**\n * Gets or sets the optional starting size for the particles\n */ this.startSize = null;\n /**\n * Gets or sets the optional ending size for the particles\n */ this.endSize = null;\n /**\n * Gets or sets the minimum size of all particles\n */ this.minSize = 5;\n /**\n * Gets or sets the maximum size of all particles\n */ this.maxSize = 5;\n /**\n * Gets or sets the beginning color of all particles\n */ this.beginColor = Color.White;\n /**\n * Gets or sets the ending color of all particles\n */ this.endColor = Color.White;\n this._sprite = null;\n /**\n * Gets or sets the emitter type for the particle emitter\n */ this.emitterType = EmitterType.Rectangle;\n /**\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\n */ this.radius = 0;\n /**\n * Gets or sets the particle rotational speed velocity\n */ this.particleRotationalVelocity = 0;\n /**\n * Indicates whether particles should start with a random rotation\n */ this.randomRotation = false;\n /**\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\n * they were world space objects, useful for most effects.\n *\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\n * as they would in a parent/child actor relationship.\n */ this.particleTransform = ParticleTransform.Global;\n const { x: x, y: y, pos: pos, isEmitting: isEmitting, minVel: minVel, maxVel: maxVel, acceleration: acceleration, minAngle: minAngle, maxAngle: maxAngle, emitRate: emitRate, particleLife: particleLife, opacity: opacity, fadeFlag: fadeFlag, focus: focus, focusAccel: focusAccel, startSize: startSize, endSize: endSize, minSize: minSize, maxSize: maxSize, beginColor: beginColor, endColor: endColor, particleSprite: particleSprite, emitterType: emitterType, radius: radius, particleRotationalVelocity: particleRotationalVelocity, particleTransform: particleTransform, randomRotation: randomRotation, random: random } = {\n ...config\n };\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.isEmitting = isEmitting !== null && isEmitting !== void 0 ? isEmitting : this.isEmitting;\n this.minVel = minVel !== null && minVel !== void 0 ? minVel : this.minVel;\n this.maxVel = maxVel !== null && maxVel !== void 0 ? maxVel : this.maxVel;\n this.acceleration = acceleration !== null && acceleration !== void 0 ? acceleration : this.acceleration;\n this.minAngle = minAngle !== null && minAngle !== void 0 ? minAngle : this.minAngle;\n this.maxAngle = maxAngle !== null && maxAngle !== void 0 ? maxAngle : this.maxAngle;\n this.emitRate = emitRate !== null && emitRate !== void 0 ? emitRate : this.emitRate;\n this.particleLife = particleLife !== null && particleLife !== void 0 ? particleLife : this.particleLife;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.fadeFlag = fadeFlag !== null && fadeFlag !== void 0 ? fadeFlag : this.fadeFlag;\n this.focus = focus !== null && focus !== void 0 ? focus : this.focus;\n this.focusAccel = focusAccel !== null && focusAccel !== void 0 ? focusAccel : this.focusAccel;\n this.startSize = startSize !== null && startSize !== void 0 ? startSize : this.startSize;\n this.endSize = endSize !== null && endSize !== void 0 ? endSize : this.endSize;\n this.minSize = minSize !== null && minSize !== void 0 ? minSize : this.minSize;\n this.maxSize = maxSize !== null && maxSize !== void 0 ? maxSize : this.maxSize;\n this.beginColor = beginColor !== null && beginColor !== void 0 ? beginColor : this.beginColor;\n this.endColor = endColor !== null && endColor !== void 0 ? endColor : this.endColor;\n this.particleSprite = particleSprite !== null && particleSprite !== void 0 ? particleSprite : this.particleSprite;\n this.emitterType = emitterType !== null && emitterType !== void 0 ? emitterType : this.emitterType;\n this.radius = radius !== null && radius !== void 0 ? radius : this.radius;\n this.particleRotationalVelocity = particleRotationalVelocity !== null && particleRotationalVelocity !== void 0 ? particleRotationalVelocity : this.particleRotationalVelocity;\n this.randomRotation = randomRotation !== null && randomRotation !== void 0 ? randomRotation : this.randomRotation;\n this.particleTransform = particleTransform !== null && particleTransform !== void 0 ? particleTransform : this.particleTransform;\n this.body.collisionType = CollisionType.PreventCollision;\n this.random = random !== null && random !== void 0 ? random : new Random();\n }\n removeParticle(particle) {\n this.deadParticles.push(particle);\n }\n /**\n * Causes the emitter to emit particles\n * @param particleCount Number of particles to emit right now\n */ emitParticles(particleCount) {\n var _a;\n for(let i = 0; i < particleCount; i++){\n const p = this._createParticle();\n this.particles.push(p);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\n if (this.particleTransform === ParticleTransform.Global) this.scene.world.add(p);\n else this.addChild(p);\n }\n }\n }\n clearParticles() {\n this.particles.length = 0;\n }\n // Creates a new particle given the constraints of the emitter\n _createParticle() {\n // todo implement emitter constraints;\n let ranX = 0;\n let ranY = 0;\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\n const dx = vel * Math.cos(angle);\n const dy = vel * Math.sin(angle);\n if (this.emitterType === EmitterType.Rectangle) {\n ranX = randomInRange(0, this.width, this.random);\n ranY = randomInRange(0, this.height, this.random);\n } else if (this.emitterType === EmitterType.Circle) {\n const radius = randomInRange(0, this.radius, this.random);\n ranX = radius * Math.cos(angle);\n ranY = radius * Math.sin(angle);\n }\n const p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new Vector(ranX, ranY), new Vector(dx, dy), this.acceleration, this.startSize, this.endSize, this.particleSprite);\n p.fadeFlag = this.fadeFlag;\n p.particleSize = size;\n p.particleRotationalVelocity = this.particleRotationalVelocity;\n if (this.randomRotation) p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\n if (this.focus) {\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\n p.focusAccel = this.focusAccel;\n }\n return p;\n }\n update(engine, delta) {\n var _a;\n super.update(engine, delta);\n if (this.isEmitting) {\n this._particlesToEmit += this.emitRate * (delta / 1000);\n if (this._particlesToEmit > 1.0) {\n this.emitParticles(Math.floor(this._particlesToEmit));\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\n }\n }\n // deferred removal\n for(let i = 0; i < this.deadParticles.length; i++){\n removeItemFromArray(this.deadParticles[i], this.particles);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) this.scene.world.remove(this.deadParticles[i], false);\n }\n this.deadParticles.length = 0;\n }\n }\n /**\n * Blend 2 transforms for interpolation, will interpolate from the context of newTx's parent if it exists\n */ function blendTransform(oldTx, newTx, blend, target) {\n if (oldTx.parent !== newTx.parent) {\n // Caller expects a local transform\n // Adjust old tx to be local to the new parent whatever that is\n const oldTxWithNewParent = oldTx.clone();\n const oldGlobalPos = oldTx.globalPos.clone();\n const oldGlobalScale = oldTx.globalScale.clone();\n const oldGlobalRotation = oldTx.globalRotation;\n oldTxWithNewParent.parent = newTx.parent;\n oldTxWithNewParent.globalPos = oldGlobalPos;\n oldTxWithNewParent.globalScale = oldGlobalScale;\n oldTxWithNewParent.globalRotation = oldGlobalRotation;\n oldTx = oldTxWithNewParent;\n }\n let interpolatedPos = newTx.pos;\n let interpolatedScale = newTx.scale;\n let interpolatedRotation = newTx.rotation;\n interpolatedPos = newTx.pos.scale(blend).add(oldTx.pos.scale(1.0 - blend));\n interpolatedScale = newTx.scale.scale(blend).add(oldTx.scale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(oldTx.rotation) + blend * Math.cos(newTx.rotation);\n const sine = (1.0 - blend) * Math.sin(oldTx.rotation) + blend * Math.sin(newTx.rotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n const tx = target !== null && target !== void 0 ? target : new transform_Transform();\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\n return tx;\n }\n /**\n *\n */ function blendGlobalTransform(oldTx, newTx, blend, target) {\n let interpolatedPos = newTx.globalPos;\n let interpolatedScale = newTx.globalScale;\n let interpolatedRotation = newTx.globalRotation;\n interpolatedPos = newTx.globalPos.scale(blend).add(oldTx.globalPos.scale(1.0 - blend));\n interpolatedScale = newTx.globalScale.scale(blend).add(oldTx.globalScale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(oldTx.globalRotation) + blend * Math.cos(newTx.globalRotation);\n const sine = (1.0 - blend) * Math.sin(oldTx.globalRotation) + blend * Math.sin(newTx.globalRotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n const tx = target !== null && target !== void 0 ? target : new Transform();\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\n return tx;\n }\n // this import seems to bomb wallaby\n class GraphicsSystem extends System {\n get sortedTransforms() {\n return this._sortedTransforms;\n }\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Average;\n this._token = 0;\n this._sortedTransforms = [];\n this._zHasChanged = false;\n this._zIndexUpdate = ()=>{\n this._zHasChanged = true;\n };\n this._targetInterpolationTransform = new transform_Transform();\n this.query = this.world.query([\n TransformComponent,\n GraphicsComponent\n ]);\n this.query.entityAdded$.subscribe((e)=>{\n const tx = e.get(TransformComponent);\n this._sortedTransforms.push(tx);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n });\n this.query.entityRemoved$.subscribe((e)=>{\n const tx = e.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) this._sortedTransforms.splice(index, 1);\n });\n }\n initialize(world, scene) {\n this._camera = scene.camera;\n this._engine = scene.engine;\n }\n preupdate() {\n // Graphics context could be switched to fallback in a new frame\n this._graphicsContext = this._engine.graphicsContext;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b)=>{\n return a.z - b.z;\n });\n this._zHasChanged = false;\n }\n }\n update(delta) {\n this._token++;\n let graphics;\n FontCache.checkAndClearCache();\n // This is a performance enhancement, most things are in world space\n // so if we can only do this once saves a ton of transform updates\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n for (const transform of this._sortedTransforms){\n const entity = transform.owner;\n // If the entity is offscreen skip\n if (entity.hasTag(\"ex.offscreen\")) continue;\n graphics = entity.get(GraphicsComponent);\n // Exit if graphics set to not visible\n if (!graphics.visible) continue;\n // Optionally run the onPreTransformDraw graphics lifecycle draw\n if (graphics.onPreTransformDraw) graphics.onPreTransformDraw(this._graphicsContext, delta);\n entity.events.emit(\"pretransformdraw\", new PreTransformDrawEvent(this._graphicsContext, delta, entity));\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n if (transform.coordPlane === CoordPlane.Screen) this._graphicsContext.restore();\n this._graphicsContext.save();\n if (transform.coordPlane === CoordPlane.Screen) this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n // Tick any graphics state (but only once) for animations and graphics groups\n graphics.update(delta, this._token);\n // Apply parallax\n const parallax = entity.get(ParallaxComponent);\n if (parallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\n const parallaxOffset = this._camera.drawPos.scale(oneMinusFactor);\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\n }\n // Position the entity + estimate lag\n this._applyTransform(entity);\n // If there is a material enable it on the context\n if (graphics.material) this._graphicsContext.material = graphics.material;\n // Optionally run the onPreDraw graphics lifecycle draw\n if (graphics.onPreDraw) graphics.onPreDraw(this._graphicsContext, delta);\n entity.events.emit(\"predraw\", new PreDrawEvent(this._graphicsContext, delta, entity));\n // TODO remove this hack on the particle redo\n // Remove this line after removing the wallaby import\n const particleOpacity = entity instanceof Particle ? entity.opacity : 1;\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\n // Draw the graphics component\n this._drawGraphicsComponent(graphics, transform);\n // Optionally run the onPostDraw graphics lifecycle draw\n if (graphics.onPostDraw) graphics.onPostDraw(this._graphicsContext, delta);\n entity.events.emit(\"postdraw\", new PostDrawEvent(this._graphicsContext, delta, entity));\n this._graphicsContext.restore();\n // Reset the transform back to the original world space\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n }\n // Optionally run the onPreTransformDraw graphics lifecycle draw\n if (graphics.onPostTransformDraw) graphics.onPostTransformDraw(this._graphicsContext, delta);\n entity.events.emit(\"posttransformdraw\", new PostTransformDrawEvent(this._graphicsContext, delta, entity));\n }\n this._graphicsContext.restore();\n }\n _drawGraphicsComponent(graphicsComponent, transformComponent) {\n var _a, _b;\n if (graphicsComponent.visible) {\n const flipHorizontal = graphicsComponent.flipHorizontal;\n const flipVertical = graphicsComponent.flipVertical;\n const graphic = graphicsComponent.current;\n const options = (_a = graphicsComponent.currentOptions) !== null && _a !== void 0 ? _a : {};\n if (graphic) {\n let anchor = graphicsComponent.anchor;\n let offset = graphicsComponent.offset;\n let scaleX = 1;\n let scaleY = 1;\n // handle specific overrides\n if (options === null || options === void 0 ? void 0 : options.anchor) anchor = options.anchor;\n if (options === null || options === void 0 ? void 0 : options.offset) offset = options.offset;\n const globalScale = transformComponent.globalScale;\n scaleX *= graphic.scale.x * globalScale.x;\n scaleY *= graphic.scale.y * globalScale.y;\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\n const offsetX = -graphic.width * anchor.x + offset.x * scaleX;\n const offsetY = -graphic.height * anchor.y + offset.y * scaleY;\n const oldFlipHorizontal = graphic.flipHorizontal;\n const oldFlipVertical = graphic.flipVertical;\n if (flipHorizontal || flipVertical) {\n // flip any currently flipped graphics\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\n }\n graphic === null || graphic === void 0 || graphic.draw(this._graphicsContext, offsetX, offsetY);\n if (flipHorizontal || flipVertical) {\n graphic.flipHorizontal = oldFlipHorizontal;\n graphic.flipVertical = oldFlipVertical;\n }\n // TODO move debug code out?\n if (((_b = this._engine) === null || _b === void 0 ? void 0 : _b.isDebug) && this._engine.debug.graphics.showBounds) {\n const offset = vec(offsetX, offsetY);\n if (graphic instanceof GraphicsGroup) for (const member of graphic.members){\n let g;\n let pos = Vector.Zero;\n if (member instanceof Graphic) g = member;\n else {\n g = member.graphic;\n pos = member.offset;\n }\n g === null || g === void 0 || g.localBounds.translate(offset.add(pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n else /* istanbul ignore next */ graphic === null || graphic === void 0 || graphic.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n }\n }\n }\n /**\n * This applies the current entity transform to the graphics context\n * @param entity\n */ _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors){\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n const optionalBody = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(BodyComponent);\n let tx = transform.get();\n if (optionalBody) {\n if (this._engine.fixedUpdateFps && optionalBody.__oldTransformCaptured && optionalBody.enableFixedUpdateInterpolate) {\n // Interpolate graphics if needed\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n tx = blendTransform(optionalBody.oldTransform, transform.get(), blend, this._targetInterpolationTransform);\n }\n }\n if (transform) {\n this._graphicsContext.z = transform.z;\n this._graphicsContext.translate(tx.pos.x, tx.pos.y);\n this._graphicsContext.scale(tx.scale.x, tx.scale.y);\n this._graphicsContext.rotate(tx.rotation);\n }\n }\n }\n }\n class DebugSystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Lowest;\n this.query = this.world.query([\n TransformComponent\n ]);\n }\n initialize(world, scene) {\n this._graphicsContext = scene.engine.graphicsContext;\n this._camera = scene.camera;\n this._engine = scene.engine;\n this._collisionSystem = world.systemManager.get(CollisionSystem);\n }\n update() {\n var _a;\n if (!this._engine.isDebug) return;\n const filterSettings = this._engine.debug.filter;\n let id;\n let name;\n const entitySettings = this._engine.debug.entity;\n let tx;\n const txSettings = this._engine.debug.transform;\n let motion;\n const motionSettings = this._engine.debug.motion;\n let colliderComp;\n const colliderSettings = this._engine.debug.collider;\n const physicsSettings = this._engine.debug.physics;\n let graphics;\n const graphicsSettings = this._engine.debug.graphics;\n let debugDraw;\n let body;\n const bodySettings = this._engine.debug.body;\n const cameraSettings = this._engine.debug.camera;\n for (const entity of this.query.entities){\n if (entity.hasTag(\"offscreen\")) continue;\n if (entity instanceof Particle) continue;\n if (filterSettings.useFilter) {\n const allIds = filterSettings.ids.length === 0;\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\n if (!idMatch) continue;\n const allNames = filterSettings.nameQuery === \"\";\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\n if (!nameMatch) continue;\n }\n let cursor = Vector.Zero;\n const lineHeight = vec(0, 16);\n id = entity.id;\n name = entity.name;\n tx = entity.get(TransformComponent);\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n this._pushCameraTransform(tx);\n this._graphicsContext.save();\n if (tx.coordPlane === CoordPlane.Screen) this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n this._graphicsContext.z = txSettings.debugZIndex;\n this._applyTransform(entity);\n if (tx) {\n if (txSettings.showAll || txSettings.showPosition) this._graphicsContext.debug.drawPoint(Vector.Zero, {\n size: 4,\n color: txSettings.positionColor\n });\n if (txSettings.showAll || txSettings.showPositionLabel) {\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showZIndex) {\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showId) {\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? \"child of id(\" + ((_a = entity.parent) === null || _a === void 0 ? void 0 : _a.id) + \")\" : \"\"}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showName) {\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showRotation) {\n this._graphicsContext.drawLine(Vector.Zero, Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero), txSettings.rotationColor, 2);\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showScale) this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\n }\n graphics = entity.get(GraphicsComponent);\n if (graphics) {\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\n const bounds = graphics.localBounds;\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\n }\n }\n debugDraw = entity.get(DebugGraphicsComponent);\n if (debugDraw) {\n if (!debugDraw.useTransform) this._graphicsContext.restore();\n debugDraw.draw(this._graphicsContext, this._engine.debug);\n if (!debugDraw.useTransform) {\n this._graphicsContext.save();\n this._applyTransform(entity);\n }\n }\n body = entity.get(BodyComponent);\n if (body) {\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showCollisionType) {\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMass) {\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMotion) {\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showSleeping) {\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping : \"cant sleep\"})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n }\n this._graphicsContext.restore();\n // World space\n this._graphicsContext.save();\n if (tx.coordPlane === CoordPlane.Screen) this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n this._graphicsContext.z = txSettings.debugZIndex;\n motion = entity.get(MotionComponent);\n if (motion) {\n if (motionSettings.showAll || motionSettings.showVelocity) {\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\n cursor = cursor.add(lineHeight);\n }\n if (motionSettings.showAll || motionSettings.showAcceleration) this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\n }\n // Colliders live in world space already so after the restore()\n colliderComp = entity.get(ColliderComponent);\n if (colliderComp) {\n const collider = colliderComp.get();\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) collider.debug(this._graphicsContext, colliderSettings.geometryColor, {\n lineWidth: colliderSettings.geometryLineWidth,\n pointSize: colliderSettings.geometryPointSize\n });\n if (colliderSettings.showAll || colliderSettings.showBounds) {\n if (collider instanceof CompositeCollider) {\n const colliders = collider.getColliders();\n for (const collider of colliders){\n const bounds = collider.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, {\n color: colliderSettings.boundsColor\n });\n if (colliderSettings.showAll || colliderSettings.showOwner) this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\n }\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\n } else if (collider) {\n const bounds = colliderComp.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, {\n color: colliderSettings.boundsColor\n });\n if (colliderSettings.showAll || colliderSettings.showOwner) this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\n }\n }\n }\n this._graphicsContext.restore();\n this._popCameraTransform(tx);\n }\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) this._collisionSystem.debug(this._graphicsContext);\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts){\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) for (const point of contact.points)this._graphicsContext.debug.drawPoint(point, {\n size: physicsSettings.contactSize,\n color: physicsSettings.collisionContactColor\n });\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) for (const point of contact.points)this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\n color: physicsSettings.collisionNormalColor\n });\n }\n this._graphicsContext.restore();\n if (cameraSettings) {\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (cameraSettings.showAll || cameraSettings.showFocus) this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\n if (cameraSettings.showAll || cameraSettings.showZoom) this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\n this._graphicsContext.restore();\n }\n this._graphicsContext.flush();\n }\n postupdate(engine, elapsedMs) {\n if (this._engine.isDebug) {\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n Debug.flush(this._graphicsContext);\n this._graphicsContext.restore();\n }\n }\n /**\n * This applies the current entity transform to the graphics context\n * @param entity\n */ _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors){\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n if (transform) {\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\n this._graphicsContext.rotate(transform.rotation);\n }\n }\n }\n /**\n * Applies the current camera transform if in world coordinates\n * @param transform\n */ _pushCameraTransform(transform) {\n // Establish camera offset per entity\n if (transform.coordPlane === CoordPlane.World) {\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n }\n }\n /**\n * Resets the current camera transform if in world coordinates\n * @param transform\n */ _popCameraTransform(transform) {\n if (transform.coordPlane === CoordPlane.World) // Apply camera world offset\n this._graphicsContext.restore();\n }\n }\n /**\n * The PointerSystem is responsible for dispatching pointer events to entities\n * that need them.\n *\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\n * the [[Collider]]'s shape for pointer events.\n */ class PointerSystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n /**\n * Optionally override component configuration for all entities\n */ this.overrideUseColliderShape = false;\n /**\n * Optionally override component configuration for all entities\n */ this.overrideUseGraphicsBounds = false;\n this.lastFrameEntityToPointers = new Map();\n this.currentFrameEntityToPointers = new Map();\n this._sortedTransforms = [];\n this._sortedEntities = [];\n this._zHasChanged = false;\n this._zIndexUpdate = ()=>{\n this._zHasChanged = true;\n };\n this.query = this.world.query([\n TransformComponent,\n PointerComponent\n ]);\n this.query.entityAdded$.subscribe((e)=>{\n const tx = e.get(TransformComponent);\n this._sortedTransforms.push(tx);\n this._sortedEntities.push(tx.owner);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n });\n this.query.entityRemoved$.subscribe((e)=>{\n const tx = e.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) {\n this._sortedTransforms.splice(index, 1);\n this._sortedEntities.splice(index, 1);\n }\n });\n }\n initialize(world, scene) {\n this._engine = scene.engine;\n this._scene = scene;\n }\n preupdate() {\n // event receiver might change per frame\n this._receivers = [\n this._engine.input.pointers,\n this._scene.input.pointers\n ];\n this._engineReceiver = this._engine.input.pointers;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b)=>{\n return b.z - a.z;\n });\n this._sortedEntities = this._sortedTransforms.map((t)=>t.owner);\n this._zHasChanged = false;\n }\n }\n entityCurrentlyUnderPointer(entity, pointerId) {\n return this.currentFrameEntityToPointers.has(entity.id) && this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entityWasUnderPointer(entity, pointerId) {\n return this.lastFrameEntityToPointers.has(entity.id) && this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entered(entity, pointerId) {\n return this.entityCurrentlyUnderPointer(entity, pointerId) && !this.lastFrameEntityToPointers.has(entity.id);\n }\n left(entity, pointerId) {\n return !this.currentFrameEntityToPointers.has(entity.id) && this.entityWasUnderPointer(entity, pointerId);\n }\n addPointerToEntity(entity, pointerId) {\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\n this.currentFrameEntityToPointers.set(entity.id, [\n pointerId\n ]);\n return;\n }\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\n }\n update() {\n // Locate all the pointer/entity mappings\n this._processPointerToEntity(this._sortedEntities);\n // Dispatch pointer events on entities\n this._dispatchEvents(this._sortedEntities);\n // Clear last frame's events\n this._receivers.forEach((r)=>r.update());\n this.lastFrameEntityToPointers.clear();\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\n this.currentFrameEntityToPointers.clear();\n this._receivers.forEach((r)=>r.clear());\n }\n _processPointerToEntity(entities) {\n var _a;\n let transform;\n let collider;\n let graphics;\n let pointer;\n const receiver = this._engineReceiver;\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\n // doesn't seem to cause issues tho for perf\n // Pre-process find entities under pointers\n for (const entity of entities){\n transform = entity.get(TransformComponent);\n pointer = (_a = entity.get(PointerComponent)) !== null && _a !== void 0 ? _a : new PointerComponent;\n // Check collider contains pointer\n collider = entity.get(ColliderComponent);\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\n collider.update();\n const geom = collider.get();\n if (geom) {\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries())if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) this.addPointerToEntity(entity, pointerId);\n }\n }\n // Check graphics contains pointer\n graphics = entity.get(GraphicsComponent);\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries())if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) this.addPointerToEntity(entity, pointerId);\n }\n }\n }\n _processDownAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastDownPerPointer = new Map(); // TODO will this get confused between receivers?\n // Loop through down and dispatch to entities\n for (const event of receiver.currentFrameDown){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit(\"pointerdown\", event);\n if (receiver.isDragStart(event.pointerId)) entity.events.emit(\"pointerdragstart\", event);\n }\n lastDownPerPointer.set(event.pointerId, event);\n }\n return lastDownPerPointer;\n }\n _processUpAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastUpPerPointer = new Map();\n // Loop through up and dispatch to entities\n for (const event of receiver.currentFrameUp){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit(\"pointerup\", event);\n if (receiver.isDragEnd(event.pointerId)) entity.events.emit(\"pointerdragend\", event);\n }\n lastUpPerPointer.set(event.pointerId, event);\n }\n return lastUpPerPointer;\n }\n _processMoveAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastMovePerPointer = new Map();\n // Loop through move and dispatch to entities\n for (const event of receiver.currentFrameMove){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n // move\n entity.events.emit(\"pointermove\", event);\n if (receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragmove\", event);\n }\n lastMovePerPointer.set(event.pointerId, event);\n }\n return lastMovePerPointer;\n }\n _processEnterLeaveAndEmit(entity, lastUpDownMoveEvents) {\n const receiver = this._engineReceiver;\n // up, down, and move are considered for enter and leave\n for (const event of lastUpDownMoveEvents){\n // enter\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\n entity.events.emit(\"pointerenter\", event);\n if (receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragenter\", event);\n break;\n }\n if (event.active && entity.active && // leave can happen on move\n (this.left(entity, event.pointerId) || // or leave can happen on pointer up\n this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === \"up\")) {\n entity.events.emit(\"pointerleave\", event);\n if (receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragleave\", event);\n break;\n }\n }\n }\n _processCancelAndEmit(entity) {\n const receiver = this._engineReceiver;\n // cancel\n for (const event of receiver.currentFrameCancel)if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) entity.events.emit(\"pointercancel\", event);\n }\n _processWheelAndEmit(entity) {\n const receiver = this._engineReceiver;\n // wheel\n for (const event of receiver.currentFrameWheel)// Currently the wheel only fires under the primary pointer '0'\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) entity.events.emit(\"pointerwheel\", event);\n }\n _dispatchEvents(entities) {\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\n // Filter preserves z order\n const entitiesWithEvents = entities.filter((e)=>lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\n let lastMovePerPointer;\n let lastUpPerPointer;\n let lastDownPerPointer;\n // Dispatch events in entity z order\n for (const entity of entitiesWithEvents){\n lastDownPerPointer = this._processDownAndEmit(entity);\n lastUpPerPointer = this._processUpAndEmit(entity);\n lastMovePerPointer = this._processMoveAndEmit(entity);\n const lastUpDownMoveEvents = [\n ...lastMovePerPointer.values(),\n ...lastDownPerPointer.values(),\n ...lastUpPerPointer.values()\n ];\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\n this._processCancelAndEmit(entity);\n this._processWheelAndEmit(entity);\n }\n }\n }\n class ActionsSystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._actions = [];\n this.query = this.world.query([\n ActionsComponent\n ]);\n this.query.entityAdded$.subscribe((e)=>this._actions.push(e.get(ActionsComponent)));\n this.query.entityRemoved$.subscribe((e)=>{\n const action = e.get(ActionsComponent);\n const index = this._actions.indexOf(action);\n if (index > -1) this._actions.splice(index, 1);\n });\n }\n update(delta) {\n for (const actions of this._actions)actions.update(delta);\n }\n }\n class IsometricEntityComponent extends Component {\n /**\n * Specify the isometric map to use to position this entity's z-index\n * @param mapOrOptions\n */ constructor(mapOrOptions){\n super();\n /**\n * Vertical \"height\" in the isometric world\n */ this.elevation = 0;\n this.columns = mapOrOptions.columns;\n this.rows = mapOrOptions.rows;\n this.tileWidth = mapOrOptions.tileWidth;\n this.tileHeight = mapOrOptions.tileHeight;\n }\n }\n class IsometricEntitySystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Lower;\n this.query = this.world.query([\n TransformComponent,\n IsometricEntityComponent\n ]);\n }\n update() {\n let transform;\n let iso;\n for (const entity of this.query.entities){\n transform = entity.get(TransformComponent);\n iso = entity.get(IsometricEntityComponent);\n const maxZindexPerElevation = Math.max(iso.columns * iso.tileWidth, iso.rows * iso.tileHeight);\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\n transform.z = newZ;\n }\n }\n }\n class OffscreenSystem extends System {\n constructor(world){\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Higher;\n this.query = this.world.query([\n TransformComponent,\n GraphicsComponent\n ]);\n }\n initialize(world, scene) {\n this._camera = scene.camera;\n this._screen = scene.engine.screen;\n }\n update() {\n this._worldBounds = this._screen.getWorldBounds();\n let transform;\n let graphics;\n let maybeParallax;\n for (const entity of this.query.entities){\n graphics = entity.get(GraphicsComponent);\n transform = entity.get(TransformComponent);\n maybeParallax = entity.get(ParallaxComponent);\n let parallaxOffset;\n if (maybeParallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\n }\n // Figure out if entities are offscreen\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\n if (entityOffscreen && !entity.hasTag(\"ex.offscreen\")) {\n entity.events.emit(\"exitviewport\", new ExitViewPortEvent(entity));\n entity.addTag(\"ex.offscreen\");\n }\n if (!entityOffscreen && entity.hasTag(\"ex.offscreen\")) {\n entity.events.emit(\"enterviewport\", new EnterViewPortEvent(entity));\n entity.removeTag(\"ex.offscreen\");\n }\n }\n }\n _isOffscreen(transform, graphics, parallaxOffset) {\n if (transform.coordPlane === CoordPlane.World) {\n let bounds = graphics.localBounds;\n if (parallaxOffset) bounds = bounds.translate(parallaxOffset);\n const transformedBounds = bounds.transform(transform.get().matrix);\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\n return graphicsOffscreen;\n } else // TODO screen coordinates\n return false;\n }\n }\n class PhysicsWorld {\n get config() {\n return watchDeep(this._config, (change)=>{\n this.$configUpdate.notifyAll(change);\n });\n }\n set config(newConfig) {\n this._config = newConfig;\n this.$configUpdate.notifyAll(newConfig);\n }\n /**\n * Spatial data structure for locating potential collision pairs and ray casts\n */ get collisionProcessor() {\n if (this._configDirty) {\n this._configDirty = false;\n // preserve tracked colliders if config updates\n const colliders = this._collisionProcessor.getColliders();\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this._config);\n for (const collider of colliders)this._collisionProcessor.track(collider);\n }\n return this._collisionProcessor;\n }\n constructor(config){\n this.$configUpdate = new Observable;\n this._configDirty = false;\n this.config = config;\n this.$configUpdate.subscribe((config)=>{\n this._configDirty = true;\n BodyComponent.updateDefaultPhysicsConfig(config.bodies);\n });\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this.config);\n }\n /**\n * Raycast into the scene's physics world\n * @param ray\n * @param options\n */ rayCast(ray, options) {\n return this.collisionProcessor.rayCast(ray, options);\n }\n }\n const GamepadEvents = {\n GamepadConnect: \"connect\",\n GamepadDisconnect: \"disconnect\",\n GamepadButton: \"button\",\n GamepadAxis: \"axis\"\n };\n /**\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\n * to provide controller support for your games.\n */ class Gamepads {\n constructor(){\n this.events = new EventEmitter();\n /**\n * Whether or not to poll for Gamepad input (default: `false`)\n */ this.enabled = false;\n /**\n * Whether or not Gamepad API is supported\n */ this.supported = !!navigator.getGamepads;\n this._gamePadTimeStamps = [\n 0,\n 0,\n 0,\n 0\n ];\n this._oldPads = [];\n this._pads = [];\n this._initSuccess = false;\n this._navigator = navigator;\n this._minimumConfiguration = null;\n this._enabled = true;\n }\n init() {\n if (!this.supported) return;\n if (this._initSuccess) return;\n // In Chrome, this will return 4 undefined items until a button is pressed\n // In FF, this will not return any items until a button is pressed\n this._oldPads = this._clonePads(this._navigator.getGamepads());\n if (this._oldPads.length && this._oldPads[0]) this._initSuccess = true;\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n /**\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\n * all other controllers with more axis or buttons are valid as well. If no minimum\n * configuration is set all pads are valid.\n */ setMinimumGamepadConfiguration(config) {\n this._enableAndUpdate(); // if config is used, implicitly enable\n this._minimumConfiguration = config;\n }\n /**\n * When implicitly enabled, set the enabled flag and run an update so information is updated\n */ _enableAndUpdate() {\n if (!this.enabled) {\n this.enabled = true;\n this.update();\n }\n }\n /**\n * Checks a navigator gamepad against the minimum configuration if present.\n */ _isGamepadValid(pad) {\n if (!this._minimumConfiguration) return true;\n if (!pad) return false;\n const axesLength = pad.axes.filter((value)=>{\n return true;\n }).length;\n const buttonLength = pad.buttons.filter((value)=>{\n return true;\n }).length;\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n this.events.off(eventName, handler);\n }\n /**\n * Updates Gamepad state and publishes Gamepad events\n */ update() {\n if (!this.enabled || !this.supported) return;\n if (!this._enabled) return;\n this.init();\n const gamepads = this._navigator.getGamepads();\n for(let i = 0; i < gamepads.length; i++){\n if (!gamepads[i]) {\n const gamepad = this.at(i);\n // If was connected, but now isn't emit the disconnect event\n if (gamepad.connected) this.events.emit(\"disconnect\", new GamepadDisconnectEvent(i, gamepad));\n // Reset connection status\n gamepad.connected = false;\n continue;\n } else {\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) this.events.emit(\"connect\", new GamepadConnectEvent(i, this.at(i)));\n // Set connection status\n this.at(i).connected = true;\n }\n this.at(i).update();\n // Only supported in Chrome\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) continue;\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\n // Add reference to navigator gamepad\n this.at(i).navigatorGamepad = gamepads[i];\n // Buttons\n let b, bi, a, ai, value;\n for(b in Buttons){\n bi = Buttons[b];\n if (typeof bi === \"number\") {\n if (gamepads[i].buttons[bi]) {\n value = gamepads[i].buttons[bi].value;\n if (value !== this._oldPads[i].getButton(bi)) {\n if (gamepads[i].buttons[bi].pressed) {\n this.at(i).updateButton(bi, value);\n this.at(i).events.emit(\"button\", new GamepadButtonEvent(bi, value, this.at(i)));\n } else this.at(i).updateButton(bi, 0);\n }\n }\n }\n }\n // Axes\n for(a in Axes){\n ai = Axes[a];\n if (typeof ai === \"number\") {\n value = gamepads[i].axes[ai];\n if (value !== this._oldPads[i].getAxes(ai)) {\n this.at(i).updateAxes(ai, value);\n this.at(i).events.emit(\"axis\", new GamepadAxisEvent(ai, value, this.at(i)));\n }\n }\n }\n this._oldPads[i] = this._clonePad(gamepads[i]);\n }\n }\n /**\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\n */ at(index) {\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\n if (index >= this._pads.length) // Ensure there is a pad to retrieve\n for(let i = this._pads.length - 1, max = index; i < max; i++){\n this._pads.push(new Gamepad());\n this._oldPads.push(new Gamepad());\n }\n return this._pads[index];\n }\n /**\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\n */ getValidGamepads() {\n this._enableAndUpdate();\n const result = [];\n for(let i = 0; i < this._pads.length; i++)if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) result.push(this.at(i));\n return result;\n }\n /**\n * Gets the number of connected gamepads\n */ count() {\n return this._pads.filter((p)=>p.connected).length;\n }\n _clonePads(pads) {\n const arr = [];\n for(let i = 0, len = pads.length; i < len; i++)arr.push(this._clonePad(pads[i]));\n return arr;\n }\n /**\n * Fastest way to clone a known object is to do it yourself\n */ _clonePad(pad) {\n let i, len;\n const clonedPad = new Gamepad();\n if (!pad) return clonedPad;\n for(i = 0, len = pad.buttons.length; i < len; i++)if (pad.buttons[i]) clonedPad.updateButton(i, pad.buttons[i].value);\n for(i = 0, len = pad.axes.length; i < len; i++)clonedPad.updateAxes(i, pad.axes[i]);\n return clonedPad;\n }\n }\n /**\n * The minimum value an axis has to move before considering it a change\n */ Gamepads.MinAxisMoveThreshold = 0.05;\n /**\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\n * for more information on handling controller input.\n */ class Gamepad {\n constructor(){\n this.events = new EventEmitter();\n this.connected = false;\n this._axes = new Array(4);\n this._buttons = new Array(16);\n this._buttonsUp = new Array(16);\n this._buttonsDown = new Array(16);\n for(let i = 0; i < this._buttons.length; i++)this._buttons[i] = 0;\n for(let i = 0; i < this._axes.length; i++)this._axes[i] = 0;\n }\n update() {\n // Reset buttonsDown and buttonsUp after update is complete\n this._buttonsDown = new Array(16);\n this._buttonsUp = new Array(16);\n }\n /**\n * Whether or not the given button is pressed\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\n * @param button The button to query\n * @param threshold The threshold over which the button is considered to be pressed\n */ isButtonPressed(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\n * Tests if a certain button is held down. This is persisted between frames.\n * @param button The button to query\n * @param threshold The threshold over which the button is considered to be pressed\n */ isButtonHeld(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\n * @param button Test whether a button was just pressed\n * @param threshold The threshold over which the button is considered to be pressed\n */ wasButtonPressed(button, threshold = 1) {\n return this._buttonsDown[button] >= threshold;\n }\n /**\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\n * @param button Test whether a button was just released\n */ wasButtonReleased(button) {\n return Boolean(this._buttonsUp[button]);\n }\n /**\n * Gets the given button value between 0 and 1\n */ getButton(button) {\n return this._buttons[button];\n }\n /**\n * Gets the given axis value between -1 and 1. Values below\n * [[MinAxisMoveThreshold]] are considered 0.\n */ getAxes(axes) {\n const value = this._axes[axes];\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) return 0;\n else return value;\n }\n updateButton(buttonIndex, value) {\n // button was just released\n if (value === 0 && this._buttons[buttonIndex]) this._buttonsUp[buttonIndex] = 1;\n else this._buttonsDown[buttonIndex] = value;\n this._buttons[buttonIndex] = value;\n }\n updateAxes(axesIndex, value) {\n this._axes[axesIndex] = value;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n /**\n * Gamepad Buttons enumeration\n */ var Buttons;\n (function(Buttons) {\n /**\n * Face 1 button (e.g. A)\n */ Buttons[Buttons[\"Face1\"] = 0] = \"Face1\";\n /**\n * Face 2 button (e.g. B)\n */ Buttons[Buttons[\"Face2\"] = 1] = \"Face2\";\n /**\n * Face 3 button (e.g. X)\n */ Buttons[Buttons[\"Face3\"] = 2] = \"Face3\";\n /**\n * Face 4 button (e.g. Y)\n */ Buttons[Buttons[\"Face4\"] = 3] = \"Face4\";\n /**\n * Left bumper button\n */ Buttons[Buttons[\"LeftBumper\"] = 4] = \"LeftBumper\";\n /**\n * Right bumper button\n */ Buttons[Buttons[\"RightBumper\"] = 5] = \"RightBumper\";\n /**\n * Left trigger button\n */ Buttons[Buttons[\"LeftTrigger\"] = 6] = \"LeftTrigger\";\n /**\n * Right trigger button\n */ Buttons[Buttons[\"RightTrigger\"] = 7] = \"RightTrigger\";\n /**\n * Select button\n */ Buttons[Buttons[\"Select\"] = 8] = \"Select\";\n /**\n * Start button\n */ Buttons[Buttons[\"Start\"] = 9] = \"Start\";\n /**\n * Left analog stick press (e.g. L3)\n */ Buttons[Buttons[\"LeftStick\"] = 10] = \"LeftStick\";\n /**\n * Right analog stick press (e.g. R3)\n */ Buttons[Buttons[\"RightStick\"] = 11] = \"RightStick\";\n /**\n * D-pad up\n */ Buttons[Buttons[\"DpadUp\"] = 12] = \"DpadUp\";\n /**\n * D-pad down\n */ Buttons[Buttons[\"DpadDown\"] = 13] = \"DpadDown\";\n /**\n * D-pad left\n */ Buttons[Buttons[\"DpadLeft\"] = 14] = \"DpadLeft\";\n /**\n * D-pad right\n */ Buttons[Buttons[\"DpadRight\"] = 15] = \"DpadRight\";\n })(Buttons || (Buttons = {}));\n /**\n * Gamepad Axes enumeration\n */ var Axes;\n (function(Axes) {\n /**\n * Left analogue stick X direction\n */ Axes[Axes[\"LeftStickX\"] = 0] = \"LeftStickX\";\n /**\n * Left analogue stick Y direction\n */ Axes[Axes[\"LeftStickY\"] = 1] = \"LeftStickY\";\n /**\n * Right analogue stick X direction\n */ Axes[Axes[\"RightStickX\"] = 2] = \"RightStickX\";\n /**\n * Right analogue stick Y direction\n */ Axes[Axes[\"RightStickY\"] = 3] = \"RightStickY\";\n })(Axes || (Axes = {}));\n /**\n * This allows you to map multiple inputs to specific commands! This is especially useful when\n * you need to allow multiple input sources to control a specific action.\n */ class InputMapper {\n constructor(inputs){\n this.inputs = inputs;\n this._handlers = new Map();\n }\n /**\n * Executes the input map, called internally by Excalibur\n */ execute() {\n for (const [input, command] of this._handlers.entries()){\n const results = input(this.inputs);\n if (results) command(results);\n }\n }\n /**\n * This allows you to map multiple inputs to specific commands! This is useful\n *\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\n *\n * Example:\n * ```typescript\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\n *\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\n * ```\n * @param inputHandler\n * @param commandHandler\n */ on(inputHandler, commandHandler) {\n this._handlers.set(inputHandler, commandHandler);\n }\n }\n /**\n * Checks if excalibur is in a x-origin iframe\n */ function isCrossOriginIframe() {\n try {\n // Try and listen to events on top window frame if within an iframe.\n //\n // See https://github.com/excaliburjs/Excalibur/issues/1294\n //\n // Attempt to add an event listener, which triggers a DOMException on\n // cross-origin iframes\n const noop = ()=>{\n return;\n };\n window.top.addEventListener(\"blur\", noop);\n window.top.removeEventListener(\"blur\", noop);\n } catch (_a) {\n return true;\n }\n return false;\n }\n /**\n * Enum representing physical input key codes\n */ var Keys;\n (function(Keys) {\n // NUMPAD\n Keys[\"Num0\"] = \"Numpad0\";\n Keys[\"Num1\"] = \"Numpad1\";\n Keys[\"Num2\"] = \"Numpad2\";\n Keys[\"Num3\"] = \"Numpad3\";\n Keys[\"Num4\"] = \"Numpad4\";\n Keys[\"Num5\"] = \"Numpad5\";\n Keys[\"Num6\"] = \"Numpad6\";\n Keys[\"Num7\"] = \"Numpad7\";\n Keys[\"Num8\"] = \"Numpad8\";\n Keys[\"Num9\"] = \"Numpad9\";\n Keys[\"NumAdd\"] = \"NumpadAdd\";\n Keys[\"NumSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumDivide\"] = \"NumpadDivide\";\n // NumComma = 'NumpadComma', // not x-browser\n Keys[\"NumDecimal\"] = \"NumpadDecimal\";\n Keys[\"Numpad0\"] = \"Numpad0\";\n Keys[\"Numpad1\"] = \"Numpad1\";\n Keys[\"Numpad2\"] = \"Numpad2\";\n Keys[\"Numpad3\"] = \"Numpad3\";\n Keys[\"Numpad4\"] = \"Numpad4\";\n Keys[\"Numpad5\"] = \"Numpad5\";\n Keys[\"Numpad6\"] = \"Numpad6\";\n Keys[\"Numpad7\"] = \"Numpad7\";\n Keys[\"Numpad8\"] = \"Numpad8\";\n Keys[\"Numpad9\"] = \"Numpad9\";\n Keys[\"NumpadAdd\"] = \"NumpadAdd\";\n Keys[\"NumpadSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumpadMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumpadDivide\"] = \"NumpadDivide\";\n // NumpadComma = 'NumpadComma', // not x-browser\n Keys[\"NumpadDecimal\"] = \"NumpadDecimal\";\n // MODIFIERS\n Keys[\"NumLock\"] = \"NumLock\";\n Keys[\"ShiftLeft\"] = \"ShiftLeft\";\n Keys[\"ShiftRight\"] = \"ShiftRight\";\n Keys[\"AltLeft\"] = \"AltLeft\";\n Keys[\"AltRight\"] = \"AltRight\";\n Keys[\"ControlLeft\"] = \"ControlLeft\";\n Keys[\"ControlRight\"] = \"ControlRight\";\n Keys[\"MetaLeft\"] = \"MetaLeft\";\n Keys[\"MetaRight\"] = \"MetaRight\";\n // NUMBERS\n Keys[\"Key0\"] = \"Digit0\";\n Keys[\"Key1\"] = \"Digit1\";\n Keys[\"Key2\"] = \"Digit2\";\n Keys[\"Key3\"] = \"Digit3\";\n Keys[\"Key4\"] = \"Digit4\";\n Keys[\"Key5\"] = \"Digit5\";\n Keys[\"Key6\"] = \"Digit6\";\n Keys[\"Key7\"] = \"Digit7\";\n Keys[\"Key8\"] = \"Digit8\";\n Keys[\"Key9\"] = \"Digit9\";\n Keys[\"Digit0\"] = \"Digit0\";\n Keys[\"Digit1\"] = \"Digit1\";\n Keys[\"Digit2\"] = \"Digit2\";\n Keys[\"Digit3\"] = \"Digit3\";\n Keys[\"Digit4\"] = \"Digit4\";\n Keys[\"Digit5\"] = \"Digit5\";\n Keys[\"Digit6\"] = \"Digit6\";\n Keys[\"Digit7\"] = \"Digit7\";\n Keys[\"Digit8\"] = \"Digit8\";\n Keys[\"Digit9\"] = \"Digit9\";\n // FUNCTION KEYS\n Keys[\"F1\"] = \"F1\";\n Keys[\"F2\"] = \"F2\";\n Keys[\"F3\"] = \"F3\";\n Keys[\"F4\"] = \"F4\";\n Keys[\"F5\"] = \"F5\";\n Keys[\"F6\"] = \"F6\";\n Keys[\"F7\"] = \"F7\";\n Keys[\"F8\"] = \"F8\";\n Keys[\"F9\"] = \"F9\";\n Keys[\"F10\"] = \"F10\";\n Keys[\"F11\"] = \"F11\";\n Keys[\"F12\"] = \"F12\";\n // LETTERS\n Keys[\"A\"] = \"KeyA\";\n Keys[\"B\"] = \"KeyB\";\n Keys[\"C\"] = \"KeyC\";\n Keys[\"D\"] = \"KeyD\";\n Keys[\"E\"] = \"KeyE\";\n Keys[\"F\"] = \"KeyF\";\n Keys[\"G\"] = \"KeyG\";\n Keys[\"H\"] = \"KeyH\";\n Keys[\"I\"] = \"KeyI\";\n Keys[\"J\"] = \"KeyJ\";\n Keys[\"K\"] = \"KeyK\";\n Keys[\"L\"] = \"KeyL\";\n Keys[\"M\"] = \"KeyM\";\n Keys[\"N\"] = \"KeyN\";\n Keys[\"O\"] = \"KeyO\";\n Keys[\"P\"] = \"KeyP\";\n Keys[\"Q\"] = \"KeyQ\";\n Keys[\"R\"] = \"KeyR\";\n Keys[\"S\"] = \"KeyS\";\n Keys[\"T\"] = \"KeyT\";\n Keys[\"U\"] = \"KeyU\";\n Keys[\"V\"] = \"KeyV\";\n Keys[\"W\"] = \"KeyW\";\n Keys[\"X\"] = \"KeyX\";\n Keys[\"Y\"] = \"KeyY\";\n Keys[\"Z\"] = \"KeyZ\";\n Keys[\"KeyA\"] = \"KeyA\";\n Keys[\"KeyB\"] = \"KeyB\";\n Keys[\"KeyC\"] = \"KeyC\";\n Keys[\"KeyD\"] = \"KeyD\";\n Keys[\"KeyE\"] = \"KeyE\";\n Keys[\"KeyF\"] = \"KeyF\";\n Keys[\"KeyG\"] = \"KeyG\";\n Keys[\"KeyH\"] = \"KeyH\";\n Keys[\"KeyI\"] = \"KeyI\";\n Keys[\"KeyJ\"] = \"KeyJ\";\n Keys[\"KeyK\"] = \"KeyK\";\n Keys[\"KeyL\"] = \"KeyL\";\n Keys[\"KeyM\"] = \"KeyM\";\n Keys[\"KeyN\"] = \"KeyN\";\n Keys[\"KeyO\"] = \"KeyO\";\n Keys[\"KeyP\"] = \"KeyP\";\n Keys[\"KeyQ\"] = \"KeyQ\";\n Keys[\"KeyR\"] = \"KeyR\";\n Keys[\"KeyS\"] = \"KeyS\";\n Keys[\"KeyT\"] = \"KeyT\";\n Keys[\"KeyU\"] = \"KeyU\";\n Keys[\"KeyV\"] = \"KeyV\";\n Keys[\"KeyW\"] = \"KeyW\";\n Keys[\"KeyX\"] = \"KeyX\";\n Keys[\"KeyY\"] = \"KeyY\";\n Keys[\"KeyZ\"] = \"KeyZ\";\n // SYMBOLS\n Keys[\"Semicolon\"] = \"Semicolon\";\n Keys[\"Quote\"] = \"Quote\";\n Keys[\"Comma\"] = \"Comma\";\n Keys[\"Minus\"] = \"Minus\";\n Keys[\"Period\"] = \"Period\";\n Keys[\"Slash\"] = \"Slash\";\n Keys[\"Equal\"] = \"Equal\";\n Keys[\"BracketLeft\"] = \"BracketLeft\";\n Keys[\"Backslash\"] = \"Backslash\";\n Keys[\"BracketRight\"] = \"BracketRight\";\n Keys[\"Backquote\"] = \"Backquote\";\n // DIRECTIONS\n Keys[\"Up\"] = \"ArrowUp\";\n Keys[\"Down\"] = \"ArrowDown\";\n Keys[\"Left\"] = \"ArrowLeft\";\n Keys[\"Right\"] = \"ArrowRight\";\n Keys[\"ArrowUp\"] = \"ArrowUp\";\n Keys[\"ArrowDown\"] = \"ArrowDown\";\n Keys[\"ArrowLeft\"] = \"ArrowLeft\";\n Keys[\"ArrowRight\"] = \"ArrowRight\";\n // OTHER\n Keys[\"Space\"] = \"Space\";\n Keys[\"Backspace\"] = \"Backspace\";\n Keys[\"Delete\"] = \"Delete\";\n Keys[\"Esc\"] = \"Escape\";\n Keys[\"Escape\"] = \"Escape\";\n Keys[\"Enter\"] = \"Enter\";\n Keys[\"NumpadEnter\"] = \"NumpadEnter\";\n Keys[\"ContextMenu\"] = \"ContextMenu\";\n })(Keys || (Keys = {}));\n /**\n * Event thrown on a game object for a key event\n */ class KeyEvent extends GameEvent {\n /**\n * @param key The key responsible for throwing the event\n * @param value The key's typed value the browser detected\n * @param originalEvent The original keyboard event that Excalibur handled\n */ constructor(key, value, originalEvent){\n super();\n this.key = key;\n this.value = value;\n this.originalEvent = originalEvent;\n }\n }\n const KeyEvents = {\n Press: \"press\",\n Hold: \"hold\",\n Release: \"release\"\n };\n /**\n * Provides keyboard support for Excalibur.\n */ class Keyboard {\n constructor(){\n this.events = new EventEmitter();\n this._enabled = true;\n /**\n * Keys that are currently held down\n */ this._keys = [];\n /**\n * Keys up in the current frame\n */ this._keysUp = [];\n /**\n * Keys down in the current frame\n */ this._keysDown = [];\n this._releaseAllKeys = (ev)=>{\n for (const code of this._keys){\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit(\"up\", keyEvent);\n this.events.emit(\"release\", keyEvent);\n }\n this._keysUp = Array.from(new Set(this._keys.concat(this._keysUp)));\n this._keys.length = 0;\n };\n this._handleKeyDown = (ev)=>{\n if (!this._enabled) return;\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) this._releaseAllKeys(ev);\n const code = ev.code;\n if (this._keys.indexOf(code) === -1) {\n this._keys.push(code);\n this._keysDown.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit(\"down\", keyEvent);\n this.events.emit(\"press\", keyEvent);\n }\n };\n this._handleKeyUp = (ev)=>{\n if (!this._enabled) return;\n const code = ev.code;\n const key = this._keys.indexOf(code);\n this._keys.splice(key, 1);\n this._keysUp.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n // alias the old api, we may want to deprecate this in the future\n this.events.emit(\"up\", keyEvent);\n this.events.emit(\"release\", keyEvent);\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (ev.key === \"Meta\") this._releaseAllKeys(ev);\n };\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Initialize Keyboard event listeners\n */ init(keyboardOptions) {\n let { global: global } = keyboardOptions;\n const { grabWindowFocus: grabWindowFocus } = keyboardOptions;\n if (!global) {\n if (isCrossOriginIframe()) {\n global = window;\n // Workaround for iframes like for itch.io or codesandbox\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\n if (grabWindowFocus) window.focus();\n Logger.getInstance().warn(\"Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus\");\n } else global = window.top;\n }\n global.addEventListener(\"blur\", ()=>{\n this._keys.length = 0; // empties array efficiently\n });\n // key up is on window because canvas cannot have focus\n global.addEventListener(\"keyup\", this._handleKeyUp);\n // key down is on window because canvas cannot have focus\n global.addEventListener(\"keydown\", this._handleKeyDown);\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n update() {\n // Reset keysDown and keysUp after update is complete\n this._keysDown.length = 0;\n this._keysUp.length = 0;\n // Emit synthetic \"hold\" event\n for(let i = 0; i < this._keys.length; i++)this.events.emit(\"hold\", new KeyEvent(this._keys[i]));\n }\n /**\n * Gets list of keys being pressed down\n */ getKeys() {\n return this._keys;\n }\n /**\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\n * @param key Test whether a key was just pressed\n */ wasPressed(key) {\n return this._keysDown.indexOf(key) > -1;\n }\n /**\n * Tests if a certain key is held down. This is persisted between frames.\n * @param key Test whether a key is held down\n */ isHeld(key) {\n return this._keys.indexOf(key) > -1;\n }\n /**\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\n * @param key Test whether a key was just released\n */ wasReleased(key) {\n return this._keysUp.indexOf(key) > -1;\n }\n /**\n * Trigger a manual key event\n * @param type\n * @param key\n * @param character\n */ triggerEvent(type, key, character) {\n if (type === \"down\") this._handleKeyDown(new KeyboardEvent(\"keydown\", {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n if (type === \"up\") this._handleKeyUp(new KeyboardEvent(\"keyup\", {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n }\n }\n class GlobalCoordinates {\n static fromPagePosition(xOrPos, yOrEngine, engineOrUndefined) {\n let pageX;\n let pageY;\n let pagePos;\n let engine;\n if (arguments.length === 3) {\n pageX = xOrPos;\n pageY = yOrEngine;\n pagePos = new Vector(pageX, pageY);\n engine = engineOrUndefined;\n } else {\n pagePos = xOrPos;\n pageX = pagePos.x;\n pageY = pagePos.y;\n engine = yOrEngine;\n }\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\n }\n constructor(worldPos, pagePos, screenPos){\n this.worldPos = worldPos;\n this.pagePos = pagePos;\n this.screenPos = screenPos;\n }\n }\n class PointerEvent {\n cancel() {\n this.active = false;\n }\n get pagePos() {\n return this.coordinates.pagePos;\n }\n get screenPos() {\n return this.coordinates.screenPos;\n }\n get worldPos() {\n return this.coordinates.worldPos;\n }\n constructor(type, pointerId, button, pointerType, coordinates, nativeEvent){\n this.type = type;\n this.pointerId = pointerId;\n this.button = button;\n this.pointerType = pointerType;\n this.coordinates = coordinates;\n this.nativeEvent = nativeEvent;\n this.active = true;\n }\n }\n class WheelEvent {\n cancel() {\n this.active = false;\n }\n constructor(x, y, pageX, pageY, screenX, screenY, index, deltaX, deltaY, deltaZ, deltaMode, ev){\n this.x = x;\n this.y = y;\n this.pageX = pageX;\n this.pageY = pageY;\n this.screenX = screenX;\n this.screenY = screenY;\n this.index = index;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.deltaZ = deltaZ;\n this.deltaMode = deltaMode;\n this.ev = ev;\n this.active = true;\n }\n }\n class PointerAbstraction {\n constructor(){\n this.events = new EventEmitter();\n /**\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\n */ this.lastPagePos = Vector.Zero;\n /**\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\n */ this.lastScreenPos = Vector.Zero;\n /**\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\n */ this.lastWorldPos = Vector.Zero;\n this._onPointerMove = (ev)=>{\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this._onPointerDown = (ev)=>{\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this.on(\"move\", this._onPointerMove);\n this.on(\"down\", this._onPointerDown);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n var WheelDeltaMode;\n (function(WheelDeltaMode) {\n WheelDeltaMode[\"Pixel\"] = \"Pixel\";\n WheelDeltaMode[\"Line\"] = \"Line\";\n WheelDeltaMode[\"Page\"] = \"Page\";\n })(WheelDeltaMode || (WheelDeltaMode = {}));\n /**\n * Native browser button enumeration\n */ var NativePointerButton;\n (function(NativePointerButton) {\n NativePointerButton[NativePointerButton[\"NoButton\"] = -1] = \"NoButton\";\n NativePointerButton[NativePointerButton[\"Left\"] = 0] = \"Left\";\n NativePointerButton[NativePointerButton[\"Middle\"] = 1] = \"Middle\";\n NativePointerButton[NativePointerButton[\"Right\"] = 2] = \"Right\";\n NativePointerButton[NativePointerButton[\"Unknown\"] = 3] = \"Unknown\";\n })(NativePointerButton || (NativePointerButton = {}));\n /**\n * The mouse button being pressed.\n */ var PointerButton;\n (function(PointerButton) {\n PointerButton[\"Left\"] = \"Left\";\n PointerButton[\"Middle\"] = \"Middle\";\n PointerButton[\"Right\"] = \"Right\";\n PointerButton[\"Unknown\"] = \"Unknown\";\n PointerButton[\"NoButton\"] = \"NoButton\";\n })(PointerButton || (PointerButton = {}));\n /**\n * The type of pointer for a [[PointerEvent]].\n */ var PointerType;\n (function(PointerType) {\n PointerType[\"Touch\"] = \"Touch\";\n PointerType[\"Mouse\"] = \"Mouse\";\n PointerType[\"Pen\"] = \"Pen\";\n PointerType[\"Unknown\"] = \"Unknown\";\n })(PointerType || (PointerType = {}));\n const PointerEvents = {\n Move: \"move\",\n Down: \"down\",\n Up: \"up\",\n Wheel: \"wheel\"\n };\n /**\n * Is this event a native touch event?\n */ function isTouchEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\n }\n /**\n * Is this event a native pointer event\n */ function isPointerEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\n }\n /**\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\n */ class PointerEventReceiver {\n constructor(target, engine){\n this.target = target;\n this.engine = engine;\n this.events = new EventEmitter();\n this.primary = new PointerAbstraction();\n this._activeNativePointerIdsToNormalized = new Map();\n this.lastFramePointerCoords = new Map();\n this.currentFramePointerCoords = new Map();\n this.currentFramePointerDown = new Map();\n this.lastFramePointerDown = new Map();\n this.currentFrameDown = [];\n this.currentFrameUp = [];\n this.currentFrameMove = [];\n this.currentFrameCancel = [];\n this.currentFrameWheel = [];\n this._enabled = true;\n this._pointers = [\n this.primary\n ];\n this._boundHandle = this._handle.bind(this);\n this._boundWheel = this._handleWheel.bind(this);\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n /**\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\n * handlers.\n * @param target\n * @param engine\n */ recreate(target, engine) {\n const eventReceiver = new PointerEventReceiver(target, engine);\n eventReceiver.primary = this.primary;\n eventReceiver._pointers = this._pointers;\n return eventReceiver;\n }\n /**\n * Locates a specific pointer by id, creates it if it doesn't exist\n * @param index\n */ at(index) {\n if (index >= this._pointers.length) // Ensure there is a pointer to retrieve\n for(let i = this._pointers.length - 1, max = index; i < max; i++)this._pointers.push(new PointerAbstraction());\n return this._pointers[index];\n }\n /**\n * The number of pointers currently being tracked by excalibur\n */ count() {\n return this._pointers.length;\n }\n /**\n * Is the specified pointer id down this frame\n * @param pointerId\n */ isDown(pointerId) {\n var _a;\n return (_a = this.currentFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\n * Was the specified pointer id down last frame\n * @param pointerId\n */ wasDown(pointerId) {\n var _a;\n return (_a = this.lastFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\n * Whether the Pointer is currently dragging.\n */ isDragging(pointerId) {\n return this.isDown(pointerId);\n }\n /**\n * Whether the Pointer just started dragging.\n */ isDragStart(pointerId) {\n return this.isDown(pointerId) && !this.wasDown(pointerId);\n }\n /**\n * Whether the Pointer just ended dragging.\n */ isDragEnd(pointerId) {\n return !this.isDown(pointerId) && this.wasDown(pointerId);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Called internally by excalibur\n *\n * Updates the current frame pointer info and emits raw pointer events\n *\n * This does not emit events to entities, see PointerSystem\n */ update() {\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\n for (const event of this.currentFrameDown){\n this.emit(\"down\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"down\", event);\n this.primary.emit(\"pointerdown\", event);\n }\n for (const event of this.currentFrameUp){\n this.emit(\"up\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"up\", event);\n }\n for (const event of this.currentFrameMove){\n this.emit(\"move\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"move\", event);\n }\n for (const event of this.currentFrameCancel){\n this.emit(\"cancel\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"cancel\", event);\n }\n for (const event of this.currentFrameWheel){\n this.emit(\"wheel\", event);\n this.primary.emit(\"pointerwheel\", event);\n this.primary.emit(\"wheel\", event);\n }\n }\n /**\n * Clears the current frame event and pointer data\n */ clear() {\n for (const event of this.currentFrameUp){\n this.currentFramePointerCoords.delete(event.pointerId);\n const ids = this._activeNativePointerIdsToNormalized.entries();\n for (const [native, normalized] of ids)if (normalized === event.pointerId) this._activeNativePointerIdsToNormalized.delete(native);\n }\n this.currentFrameDown.length = 0;\n this.currentFrameUp.length = 0;\n this.currentFrameMove.length = 0;\n this.currentFrameCancel.length = 0;\n this.currentFrameWheel.length = 0;\n }\n /**\n * Initializes the pointer event receiver so that it can start listening to native\n * browser events.\n */ init(options) {\n var _a;\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\n // It is important on mobile to have touch action 'none'\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\n if (this.target === this.engine.canvas) this.engine.canvas.style.touchAction = \"none\";\n else document.body.style.touchAction = \"none\";\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.addEventListener(\"pointerdown\", this._boundHandle);\n this.target.addEventListener(\"pointerup\", this._boundHandle);\n this.target.addEventListener(\"pointermove\", this._boundHandle);\n this.target.addEventListener(\"pointercancel\", this._boundHandle);\n } else {\n // Touch Events\n this.target.addEventListener(\"touchstart\", this._boundHandle);\n this.target.addEventListener(\"touchend\", this._boundHandle);\n this.target.addEventListener(\"touchmove\", this._boundHandle);\n this.target.addEventListener(\"touchcancel\", this._boundHandle);\n // Mouse Events\n this.target.addEventListener(\"mousedown\", this._boundHandle);\n this.target.addEventListener(\"mouseup\", this._boundHandle);\n this.target.addEventListener(\"mousemove\", this._boundHandle);\n }\n // MDN MouseWheelEvent\n const wheelOptions = {\n passive: !(this.engine.pageScrollPreventionMode === ScrollPreventionMode.All || this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas)\n };\n if (\"onwheel\" in document.createElement(\"div\")) // Modern Browsers\n this.target.addEventListener(\"wheel\", this._boundWheel, wheelOptions);\n else if (document.onmousewheel !== undefined) // Webkit and IE\n this.target.addEventListener(\"mousewheel\", this._boundWheel, wheelOptions);\n else // Remaining browser and older Firefox\n this.target.addEventListener(\"MozMousePixelScroll\", this._boundWheel, wheelOptions);\n const grabWindowFocus = (_a = options === null || options === void 0 ? void 0 : options.grabWindowFocus) !== null && _a !== void 0 ? _a : true;\n // Handle cross origin iframe\n if (grabWindowFocus && isCrossOriginIframe()) {\n const grabFocus = ()=>{\n window.focus();\n };\n // Preferred pointer events\n if (window.PointerEvent) this.target.addEventListener(\"pointerdown\", grabFocus);\n else {\n // Touch Events\n this.target.addEventListener(\"touchstart\", grabFocus);\n // Mouse Events\n this.target.addEventListener(\"mousedown\", grabFocus);\n }\n }\n }\n detach() {\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.removeEventListener(\"pointerdown\", this._boundHandle);\n this.target.removeEventListener(\"pointerup\", this._boundHandle);\n this.target.removeEventListener(\"pointermove\", this._boundHandle);\n this.target.removeEventListener(\"pointercancel\", this._boundHandle);\n } else {\n // Touch Events\n this.target.removeEventListener(\"touchstart\", this._boundHandle);\n this.target.removeEventListener(\"touchend\", this._boundHandle);\n this.target.removeEventListener(\"touchmove\", this._boundHandle);\n this.target.removeEventListener(\"touchcancel\", this._boundHandle);\n // Mouse Events\n this.target.removeEventListener(\"mousedown\", this._boundHandle);\n this.target.removeEventListener(\"mouseup\", this._boundHandle);\n this.target.removeEventListener(\"mousemove\", this._boundHandle);\n }\n if (\"onwheel\" in document.createElement(\"div\")) // Modern Browsers\n this.target.removeEventListener(\"wheel\", this._boundWheel);\n else if (document.onmousewheel !== undefined) // Webkit and IE\n this.target.addEventListener(\"mousewheel\", this._boundWheel);\n else // Remaining browser and older Firefox\n this.target.addEventListener(\"MozMousePixelScroll\", this._boundWheel);\n }\n /**\n * Take native pointer id and map it to index in active pointers\n * @param nativePointerId\n */ _normalizePointerId(nativePointerId) {\n // Add to the the native pointer set id\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\n // Native pointer ids in ascending order\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b)=>a - b);\n // The index into sorted ids will be the new id, will always have an id\n const id = currentPointerIds.findIndex((p)=>p === nativePointerId);\n // Save the mapping so we can reverse it later\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\n // ignore pointer because game isn't watching\n return id;\n }\n /**\n * Responsible for handling and parsing pointer events\n */ _handle(ev) {\n if (!this._enabled) return;\n ev.preventDefault();\n const eventCoords = new Map();\n let button;\n let pointerType;\n if (isTouchEvent(ev)) {\n button = PointerButton.Unknown;\n pointerType = PointerType.Touch;\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\n for(let i = 0; i < ev.changedTouches.length; i++){\n const touch = ev.changedTouches[i];\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\n const nativePointerId = i + 1;\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n } else {\n button = this._nativeButtonToPointerButton(ev.button);\n pointerType = PointerType.Mouse;\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\n let nativePointerId = 1;\n if (isPointerEvent(ev)) {\n nativePointerId = ev.pointerId;\n pointerType = this._stringToPointerType(ev.pointerType);\n }\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n for (const [pointerId, coord] of eventCoords.entries())switch(ev.type){\n case \"mousedown\":\n case \"pointerdown\":\n case \"touchstart\":\n this.currentFrameDown.push(new PointerEvent(\"down\", pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, true);\n break;\n case \"mouseup\":\n case \"pointerup\":\n case \"touchend\":\n this.currentFrameUp.push(new PointerEvent(\"up\", pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, false);\n break;\n case \"mousemove\":\n case \"pointermove\":\n case \"touchmove\":\n this.currentFrameMove.push(new PointerEvent(\"move\", pointerId, button, pointerType, coord, ev));\n break;\n case \"touchcancel\":\n case \"pointercancel\":\n this.currentFrameCancel.push(new PointerEvent(\"cancel\", pointerId, button, pointerType, coord, ev));\n break;\n }\n }\n _handleWheel(ev) {\n if (!this._enabled) return;\n // Should we prevent page scroll because of this event\n if (this.engine.pageScrollPreventionMode === ScrollPreventionMode.All || this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas) ev.preventDefault();\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\n const world = this.engine.screen.screenToWorldCoordinates(screen);\n /**\n * A constant used to normalize wheel events across different browsers\n *\n * This normalization factor is pulled from\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\n */ const ScrollWheelNormalizationFactor = -1 / 40;\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\n const deltaY = ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\n const deltaZ = ev.deltaZ || 0;\n let deltaMode = WheelDeltaMode.Pixel;\n if (ev.deltaMode) {\n if (ev.deltaMode === 1) deltaMode = WheelDeltaMode.Line;\n else if (ev.deltaMode === 2) deltaMode = WheelDeltaMode.Page;\n }\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\n this.currentFrameWheel.push(we);\n }\n /**\n * Triggers an excalibur pointer event in a world space pos\n *\n * Useful for testing pointers in excalibur\n * @param type\n * @param pos\n */ triggerEvent(type, pos) {\n const page = this.engine.screen.worldToPageCoordinates(pos);\n // Send an event to the event receiver\n if (window.PointerEvent) this._handle(new window.PointerEvent(\"pointer\" + type, {\n pointerId: 0,\n clientX: page.x,\n clientY: page.y\n }));\n else // Safari hack\n this._handle(new window.MouseEvent(\"mouse\" + type, {\n clientX: page.x,\n clientY: page.y\n }));\n // Force update pointer system\n const pointerSystem = this.engine.currentScene.world.get(PointerSystem);\n pointerSystem.preupdate(this.engine.currentScene, 1);\n pointerSystem.update(1);\n }\n _nativeButtonToPointerButton(s) {\n switch(s){\n case NativePointerButton.NoButton:\n return PointerButton.NoButton;\n case NativePointerButton.Left:\n return PointerButton.Left;\n case NativePointerButton.Middle:\n return PointerButton.Middle;\n case NativePointerButton.Right:\n return PointerButton.Right;\n case NativePointerButton.Unknown:\n return PointerButton.Unknown;\n default:\n return fail(s);\n }\n }\n _stringToPointerType(s) {\n switch(s){\n case \"touch\":\n return PointerType.Touch;\n case \"mouse\":\n return PointerType.Mouse;\n case \"pen\":\n return PointerType.Pen;\n default:\n return PointerType.Unknown;\n }\n }\n }\n class InputHost {\n constructor(options){\n this._enabled = true;\n const { pointerTarget: pointerTarget, grabWindowFocus: grabWindowFocus, engine: engine } = options;\n this.keyboard = new Keyboard();\n this.pointers = new PointerEventReceiver(pointerTarget, engine);\n this.gamepads = new Gamepads();\n this.keyboard.init({\n grabWindowFocus: grabWindowFocus\n });\n this.pointers.init({\n grabWindowFocus: grabWindowFocus\n });\n this.gamepads.init();\n this.inputMapper = new InputMapper({\n keyboard: this.keyboard,\n pointers: this.pointers,\n gamepads: this.gamepads\n });\n }\n get enabled() {\n return this._enabled;\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n this.keyboard.toggleEnabled(this._enabled);\n this.pointers.toggleEnabled(this._enabled);\n this.gamepads.toggleEnabled(this._enabled);\n }\n update() {\n if (this._enabled) {\n this.inputMapper.execute();\n this.keyboard.update();\n this.gamepads.update();\n }\n }\n }\n class PreLoadEvent {\n }\n const SceneEvents = {\n Initialize: \"initialize\",\n Activate: \"activate\",\n Deactivate: \"deactivate\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\",\n PreDebugDraw: \"predebugdraw\",\n PostDebugDraw: \"postdebugdraw\",\n PreLoad: \"preload\"\n };\n /**\n *\n */ function isSceneConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n }\n /**\n * [[Actor|Actors]] are composed together into groupings called Scenes in\n * Excalibur. The metaphor models the same idea behind real world\n * actors in a scene. Only actors in scenes will be updated and drawn.\n *\n * Typical usages of a scene include: levels, menus, loading screens, etc.\n */ class Scene {\n /**\n * The actors in the current scene\n */ get actors() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof Actor;\n });\n }\n /**\n * The entities in the current scene\n */ get entities() {\n return this.world.entityManager.entities;\n }\n /**\n * The triggers in the current scene\n */ get triggers() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof Trigger;\n });\n }\n /**\n * The [[TileMap]]s in the scene, if any\n */ get tileMaps() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof TileMap;\n });\n }\n get timers() {\n return this._timers;\n }\n constructor(){\n // Initialize systems\n this._logger = Logger.getInstance();\n this.events = new EventEmitter();\n /**\n * Gets or sets the current camera for the scene\n */ this.camera = new Camera();\n /**\n * The ECS world for the scene\n */ this.world = new World(this);\n /**\n * The Excalibur physics world for the scene. Used to interact\n * with colliders included in the scene.\n *\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\n */ this.physics = new PhysicsWorld(DefaultPhysicsConfig);\n this._isInitialized = false;\n this._timers = [];\n this._cancelQueue = [];\n // Update\n this.world.add(ActionsSystem);\n this.world.add(new MotionSystem(this.world, this.physics));\n this.world.add(new CollisionSystem(this.world, this.physics));\n this.world.add(PointerSystem);\n this.world.add(IsometricEntitySystem);\n // Draw\n this.world.add(OffscreenSystem);\n this.world.add(GraphicsSystem);\n this.world.add(DebugSystem);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Event hook to provide Scenes a way of loading scene specific resources.\n *\n * This is called before the Scene.onInitialize during scene transition. It will only ever fire once for a scene.\n * @param loader\n */ onPreLoad(loader) {\n // will be overridden\n }\n /**\n * Event hook fired directly before transition, either \"in\" or \"out\" of the scene\n *\n * This overrides the Engine scene definition. However transitions specified in goToScene take highest precedence\n *\n * ```typescript\n * // Overrides all\n * Engine.goToScene('scene', { destinationIn: ..., sourceOut: ... });\n * ```\n *\n * This can be used to configure custom transitions for a scene dynamically\n */ onTransition(direction) {\n // will be overridden\n return undefined;\n }\n /**\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\n * overridden. This is where initialization of child actors should take place.\n */ onInitialize(engine) {\n // will be overridden\n }\n /**\n * This is called when the scene is made active and started. It is meant to be overridden,\n * this is where you should setup any DOM UI or event handlers needed for the scene.\n */ onActivate(context) {\n // will be overridden\n }\n /**\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\n */ onDeactivate(context) {\n // will be overridden\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before a scene is updated.\n */ onPreUpdate(engine, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */ onPostUpdate(engine, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreDraw` is called directly before a scene is drawn.\n *\n */ onPreDraw(ctx, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostDraw` is called directly after a scene is drawn.\n *\n */ onPostDraw(ctx, delta) {\n // will be overridden\n }\n /**\n * Initializes actors in the scene\n */ _initializeChildren() {\n for (const child of this.entities)child._initialize(this.engine);\n }\n /**\n * Gets whether or not the [[Scene]] has been initialized\n */ get isInitialized() {\n return this._isInitialized;\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Initializes the scene before the first update, meant to be called by engine not by users of\n * Excalibur\n * @internal\n */ async _initialize(engine) {\n var _a;\n if (!this.isInitialized) {\n try {\n this.engine = engine;\n // PhysicsWorld config is watched so things will automagically update\n this.physics.config = this.engine.physics;\n this.input = new InputHost({\n pointerTarget: engine.pointerScope === PointerScope.Canvas ? engine.canvas : document,\n grabWindowFocus: engine.grabWindowFocus,\n engine: engine\n });\n // Initialize camera first\n this.camera._initialize(engine);\n this.world.systemManager.initialize();\n // This order is important! we want to be sure any custom init that add actors\n // fire before the actor init\n await this.onInitialize(engine);\n this._initializeChildren();\n this._logger.debug(\"Scene.onInitialize\", this, engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n } catch (e) {\n this._logger.error(`Error during scene initialization for scene ${(_a = engine.director) === null || _a === void 0 ? void 0 : _a.getSceneName(this)}!`);\n throw e;\n }\n this._isInitialized = true;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\n * @internal\n */ async _activate(context) {\n var _a, _b;\n try {\n this._logger.debug(\"Scene.onActivate\", this);\n this.input.toggleEnabled(true);\n await this.onActivate(context);\n } catch (e) {\n this._logger.error(`Error during scene activation for scene ${(_b = (_a = this.engine) === null || _a === void 0 ? void 0 : _a.director) === null || _b === void 0 ? void 0 : _b.getSceneName(this)}!`);\n throw e;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\n * @internal\n */ async _deactivate(context) {\n this._logger.debug(\"Scene.onDeactivate\", this);\n this.input.toggleEnabled(false);\n await this.onDeactivate(context);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */ _preupdate(engine, delta) {\n this.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */ _postupdate(engine, delta) {\n this.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\n * @internal\n */ _predraw(ctx, delta) {\n this.emit(\"predraw\", new PreDrawEvent(ctx, delta, this));\n this.onPreDraw(ctx, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\n * @internal\n */ _postdraw(ctx, delta) {\n this.emit(\"postdraw\", new PostDrawEvent(ctx, delta, this));\n this.onPostDraw(ctx, delta);\n }\n /**\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\n * @param engine Reference to the current Engine\n * @param delta The number of milliseconds since the last update\n */ update(engine, delta) {\n var _a;\n if (!this.isInitialized) {\n this._logger.warnOnce(`Scene update called before initialize for scene ${(_a = engine.director) === null || _a === void 0 ? void 0 : _a.getSceneName(this)}!`);\n return;\n }\n this._preupdate(engine, delta);\n // TODO differed entity removal for timers\n let i, len;\n // Remove timers in the cancel queue before updating them\n for(i = 0, len = this._cancelQueue.length; i < len; i++)this.removeTimer(this._cancelQueue[i]);\n this._cancelQueue.length = 0;\n // Cycle through timers updating timers\n for (const timer of this._timers)timer.update(delta);\n this.world.update(SystemType.Update, delta);\n // Camera last keeps renders smooth that are based on entity/actor\n if (this.camera) this.camera.update(engine, delta);\n this._collectActorStats(engine);\n this._postupdate(engine, delta);\n this.input.update();\n }\n /**\n * Draws all the actors in the Scene. Called by the [[Engine]].\n * @param ctx The current rendering context\n * @param delta The number of milliseconds since the last draw\n */ draw(ctx, delta) {\n var _a;\n if (!this.isInitialized) {\n this._logger.warnOnce(`Scene draw called before initialize!`);\n return;\n }\n this._predraw(ctx, delta);\n this.world.update(SystemType.Draw, delta);\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.isDebug) this.debugDraw(ctx);\n this._postdraw(ctx, delta);\n }\n /**\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\n * @param ctx The current rendering context\n */ /* istanbul ignore next */ debugDraw(ctx) {\n this.emit(\"predebugdraw\", new PreDebugDrawEvent(ctx, this));\n // pass\n this.emit(\"postdebugdraw\", new PostDebugDrawEvent(ctx, this));\n }\n /**\n * Checks whether an actor is contained in this scene or not\n */ contains(actor) {\n return this.actors.indexOf(actor) > -1;\n }\n add(entity) {\n this.emit(\"entityadded\", {\n target: entity\n });\n this.world.add(entity);\n entity.scene = this;\n if (entity instanceof Timer) {\n if (!contains(this._timers, entity)) this.addTimer(entity);\n return;\n }\n }\n /**\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\n * and adds it to this scene.\n *\n * Useful if you want to have an object be present in only 1 scene at a time.\n * @param entity\n */ transfer(entity) {\n let scene;\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\n scene = entity.scene;\n entity.scene.world.remove(entity, false);\n }\n if (entity instanceof Timer && entity.scene) {\n scene = entity.scene;\n entity.scene.removeTimer(entity);\n }\n scene === null || scene === void 0 || scene.emit(\"entityremoved\", {\n target: entity\n });\n this.add(entity);\n }\n remove(entity) {\n if (entity instanceof Entity) {\n this.emit(\"entityremoved\", {\n target: entity\n });\n if (entity.active) entity.kill();\n this.world.remove(entity);\n }\n if (entity instanceof Timer) this.removeTimer(entity);\n }\n /**\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\n *\n * By default entities use deferred removal\n * @param deferred\n */ clear(deferred = true) {\n for(let i = this.entities.length - 1; i >= 0; i--)this.world.remove(this.entities[i], deferred);\n for(let i = this.timers.length - 1; i >= 0; i--)this.removeTimer(this.timers[i]);\n }\n /**\n * Adds a [[Timer]] to the scene\n * @param timer The timer to add\n */ addTimer(timer) {\n this._timers.push(timer);\n timer.scene = this;\n return timer;\n }\n /**\n * Removes a [[Timer]] from the scene.\n * @warning Can be dangerous, use [[cancelTimer]] instead\n * @param timer The timer to remove\n */ removeTimer(timer) {\n const i = this._timers.indexOf(timer);\n if (i !== -1) this._timers.splice(i, 1);\n return timer;\n }\n /**\n * Cancels a [[Timer]], removing it from the scene nicely\n * @param timer The timer to cancel\n */ cancelTimer(timer) {\n this._cancelQueue.push(timer);\n return timer;\n }\n /**\n * Tests whether a [[Timer]] is active in the scene\n */ isTimerActive(timer) {\n return this._timers.indexOf(timer) > -1 && !timer.complete;\n }\n isCurrentScene() {\n if (this.engine) return this.engine.currentScene === this;\n return false;\n }\n _collectActorStats(engine) {\n const screenElements = this.actors.filter((a)=>a instanceof ScreenElement);\n for (const _ui of screenElements)engine.stats.currFrame.actors.ui++;\n for (const actor of this.actors){\n engine.stats.currFrame.actors.alive++;\n for (const child of actor.children)if (isScreenElement(child)) // TODO not true\n engine.stats.currFrame.actors.ui++;\n else engine.stats.currFrame.actors.alive++;\n }\n }\n }\n var ColorBlindnessMode;\n (function(ColorBlindnessMode) {\n ColorBlindnessMode[\"Protanope\"] = \"Protanope\";\n ColorBlindnessMode[\"Deuteranope\"] = \"Deuteranope\";\n ColorBlindnessMode[\"Tritanope\"] = \"Tritanope\";\n })(ColorBlindnessMode || (ColorBlindnessMode = {}));\n /* harmony default export */ const color_blind_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\";\n /**\n * Helper that defines a whole screen renderer, just provide a fragment source!\n *\n * Currently supports 1 varying\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\n */ class ScreenShader {\n constructor(gl, fragmentSource){\n this._shader = new Shader({\n gl: gl,\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\n fragmentSource: fragmentSource\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n type: \"static\",\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1,\n -1,\n 0,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n -1,\n 1,\n 0,\n 1,\n -1,\n 1,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n 1,\n 1,\n 1\n ])\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_texcoord\",\n 2\n ]\n ]\n });\n this._buffer.upload();\n }\n getShader() {\n return this._shader;\n }\n getLayout() {\n return this._layout;\n }\n }\n class ColorBlindnessPostProcessor {\n constructor(_colorBlindnessMode, simulate = false){\n this._colorBlindnessMode = _colorBlindnessMode;\n this._simulate = false;\n this._simulate = simulate;\n }\n initialize(gl) {\n this._shader = new ScreenShader(gl, color_blind_fragment);\n this.simulate = this._simulate;\n this.colorBlindnessMode = this._colorBlindnessMode;\n }\n getShader() {\n return this._shader.getShader();\n }\n getLayout() {\n return this._shader.getLayout();\n }\n set colorBlindnessMode(colorBlindMode) {\n this._colorBlindnessMode = colorBlindMode;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) shader.setUniformInt(\"u_type\", 0);\n else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) shader.setUniformInt(\"u_type\", 1);\n else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) shader.setUniformInt(\"u_type\", 2);\n }\n }\n get colorBlindnessMode() {\n return this._colorBlindnessMode;\n }\n set simulate(value) {\n this._simulate = value;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n shader.setUniformBoolean(\"u_simulate\", value);\n }\n }\n get simulate() {\n return this._simulate;\n }\n }\n class ColorBlindFlags {\n constructor(engine){\n this._engine = engine;\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\n }\n /**\n * Correct colors for a specified color blindness\n * @param colorBlindness\n */ correct(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = false;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Simulate colors for a specified color blindness\n * @param colorBlindness\n */ simulate(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = true;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Remove color blindness post processor\n */ clear() {\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Debug statistics and flags for Excalibur. If polling these values, it would be\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\n * updated during a frame.\n */ class DebugConfig {\n constructor(engine){\n /**\n * Performance statistics\n */ this.stats = {\n /**\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\n * Best accessed on [[postframe]] event. See [[FrameStats]]\n */ currFrame: new FrameStats(),\n /**\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\n */ prevFrame: new FrameStats()\n };\n /**\n * Filter debug context to named entities or entity ids\n */ this.filter = {\n /**\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\n */ useFilter: false,\n /**\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\n */ nameQuery: \"\",\n /**\n * Query for Entity ids, if the id matches it will be included\n */ ids: []\n };\n /**\n * Entity debug settings\n */ this.entity = {\n showAll: false,\n showId: false,\n showName: false\n };\n /**\n * Transform component debug settings\n */ this.transform = {\n showAll: false,\n debugZIndex: 10000000,\n showPosition: false,\n showPositionLabel: false,\n positionColor: Color.Yellow,\n showZIndex: false,\n showScale: false,\n scaleColor: Color.Green,\n showRotation: false,\n rotationColor: Color.Blue\n };\n /**\n * Graphics component debug settings\n */ this.graphics = {\n showAll: false,\n showBounds: false,\n boundsColor: Color.Yellow\n };\n /**\n * Collider component debug settings\n */ this.collider = {\n showAll: false,\n showBounds: false,\n boundsColor: Color.Blue,\n showOwner: false,\n showGeometry: true,\n geometryColor: Color.Green,\n geometryLineWidth: 1,\n geometryPointSize: .5\n };\n /**\n * Physics simulation debug settings\n */ this.physics = {\n showAll: false,\n showBroadphaseSpacePartitionDebug: false,\n showCollisionNormals: false,\n collisionNormalColor: Color.Cyan,\n showCollisionContacts: true,\n contactSize: 2,\n collisionContactColor: Color.Red\n };\n /**\n * Motion component debug settings\n */ this.motion = {\n showAll: false,\n showVelocity: false,\n velocityColor: Color.Yellow,\n showAcceleration: false,\n accelerationColor: Color.Red\n };\n /**\n * Body component debug settings\n */ this.body = {\n showAll: false,\n showCollisionGroup: false,\n showCollisionType: false,\n showSleeping: false,\n showMotion: false,\n showMass: false\n };\n /**\n * Camera debug settings\n */ this.camera = {\n showAll: false,\n showFocus: false,\n focusColor: Color.Red,\n showZoom: false\n };\n this.tilemap = {\n showAll: false,\n showGrid: false,\n gridColor: Color.Red,\n gridWidth: .5,\n showSolidBounds: false,\n solidBoundsColor: Color.fromHex(\"#8080807F\"),\n showColliderGeometry: true\n };\n this.isometric = {\n showAll: false,\n showPosition: false,\n positionColor: Color.Yellow,\n positionSize: 1,\n showGrid: false,\n gridColor: Color.Red,\n gridWidth: 1,\n showColliderGeometry: true\n };\n this._engine = engine;\n this.colorBlindMode = new ColorBlindFlags(this._engine);\n }\n /**\n * Switch the current excalibur clock with the [[TestClock]] and return\n * it in the same running state.\n *\n * This is useful when you need to debug frame by frame.\n */ useTestClock() {\n const clock = this._engine.clock;\n const wasRunning = clock.isRunning();\n clock.stop();\n const testClock = clock.toTestClock();\n if (wasRunning) testClock.start();\n this._engine.clock = testClock;\n return testClock;\n }\n /**\n * Switch the current excalibur clock with the [[StandardClock]] and\n * return it in the same running state.\n *\n * This is useful when you need to switch back to normal mode after\n * debugging.\n */ useStandardClock() {\n const currentClock = this._engine.clock;\n const wasRunning = currentClock.isRunning();\n currentClock.stop();\n const standardClock = currentClock.toStandardClock();\n if (wasRunning) standardClock.start();\n this._engine.clock = standardClock;\n return standardClock;\n }\n }\n /**\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\n * creating instances of this every frame.\n */ class FrameStats {\n constructor(){\n this._id = 0;\n this._delta = 0;\n this._fps = 0;\n this._actorStats = {\n alive: 0,\n killed: 0,\n ui: 0,\n get remaining () {\n return this.alive - this.killed;\n },\n get total () {\n return this.remaining + this.ui;\n }\n };\n this._durationStats = {\n update: 0,\n draw: 0,\n get total () {\n return this.update + this.draw;\n }\n };\n this._physicsStats = new PhysicsStats();\n this._graphicsStats = {\n drawCalls: 0,\n drawnImages: 0\n };\n }\n /**\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\n * @param [otherStats] Optional stats to clone\n */ reset(otherStats) {\n if (otherStats) {\n this.id = otherStats.id;\n this.delta = otherStats.delta;\n this.fps = otherStats.fps;\n this.actors.alive = otherStats.actors.alive;\n this.actors.killed = otherStats.actors.killed;\n this.actors.ui = otherStats.actors.ui;\n this.duration.update = otherStats.duration.update;\n this.duration.draw = otherStats.duration.draw;\n this._physicsStats.reset(otherStats.physics);\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\n } else {\n this.id = this.delta = this.fps = 0;\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\n this.duration.update = this.duration.draw = 0;\n this._physicsStats.reset();\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\n }\n }\n /**\n * Provides a clone of this instance.\n */ clone() {\n const fs = new FrameStats();\n fs.reset(this);\n return fs;\n }\n /**\n * Gets the frame's id\n */ get id() {\n return this._id;\n }\n /**\n * Sets the frame's id\n */ set id(value) {\n this._id = value;\n }\n /**\n * Gets the frame's delta (time since last frame)\n */ get delta() {\n return this._delta;\n }\n /**\n * Sets the frame's delta (time since last frame). Internal use only.\n * @internal\n */ set delta(value) {\n this._delta = value;\n }\n /**\n * Gets the frame's frames-per-second (FPS)\n */ get fps() {\n return this._fps;\n }\n /**\n * Sets the frame's frames-per-second (FPS). Internal use only.\n * @internal\n */ set fps(value) {\n this._fps = value;\n }\n /**\n * Gets the frame's actor statistics\n */ get actors() {\n return this._actorStats;\n }\n /**\n * Gets the frame's duration statistics\n */ get duration() {\n return this._durationStats;\n }\n /**\n * Gets the frame's physics statistics\n */ get physics() {\n return this._physicsStats;\n }\n /**\n * Gets the frame's graphics statistics\n */ get graphics() {\n return this._graphicsStats;\n }\n }\n class PhysicsStats {\n constructor(){\n this._pairs = 0;\n this._collisions = 0;\n this._contacts = new Map();\n this._fastBodies = 0;\n this._fastBodyCollisions = 0;\n this._broadphase = 0;\n this._narrowphase = 0;\n }\n /**\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\n * @param [otherStats] Optional stats to clone\n */ reset(otherStats) {\n if (otherStats) {\n this.pairs = otherStats.pairs;\n this.collisions = otherStats.collisions;\n this.contacts = otherStats.contacts;\n this.fastBodies = otherStats.fastBodies;\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\n this.broadphase = otherStats.broadphase;\n this.narrowphase = otherStats.narrowphase;\n } else {\n this.pairs = this.collisions = this.fastBodies = 0;\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\n this.contacts.clear();\n }\n }\n /**\n * Provides a clone of this instance.\n */ clone() {\n const ps = new PhysicsStats();\n ps.reset(this);\n return ps;\n }\n get pairs() {\n return this._pairs;\n }\n set pairs(value) {\n this._pairs = value;\n }\n get collisions() {\n return this._collisions;\n }\n set collisions(value) {\n this._collisions = value;\n }\n get contacts() {\n return this._contacts;\n }\n set contacts(contacts) {\n this._contacts = contacts;\n }\n get fastBodies() {\n return this._fastBodies;\n }\n set fastBodies(value) {\n this._fastBodies = value;\n }\n get fastBodyCollisions() {\n return this._fastBodyCollisions;\n }\n set fastBodyCollisions(value) {\n this._fastBodyCollisions = value;\n }\n get broadphase() {\n return this._broadphase;\n }\n set broadphase(value) {\n this._broadphase = value;\n }\n get narrowphase() {\n return this._narrowphase;\n }\n set narrowphase(value) {\n this._narrowphase = value;\n }\n }\n class BrowserComponent {\n on(eventName, handler) {\n if (this._nativeHandlers[eventName]) this.off(eventName, this._nativeHandlers[eventName]);\n this._nativeHandlers[eventName] = this._decorate(handler);\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\n }\n off(eventName, handler) {\n if (!handler) handler = this._nativeHandlers[eventName];\n this.nativeComponent.removeEventListener(eventName, handler);\n this._nativeHandlers[eventName] = null;\n }\n _decorate(handler) {\n return (evt)=>{\n if (!this._paused) handler(evt);\n };\n }\n pause() {\n this._paused = true;\n }\n resume() {\n this._paused = false;\n }\n clear() {\n for(const event in this._nativeHandlers)this.off(event);\n }\n constructor(nativeComponent){\n this.nativeComponent = nativeComponent;\n this._paused = false;\n this._nativeHandlers = {};\n }\n }\n class BrowserEvents {\n constructor(_windowGlobal, _documentGlobal){\n this._windowGlobal = _windowGlobal;\n this._documentGlobal = _documentGlobal;\n this._windowComponent = new BrowserComponent(this._windowGlobal);\n this._documentComponent = new BrowserComponent(this._documentGlobal);\n }\n get window() {\n return this._windowComponent;\n }\n get document() {\n return this._documentComponent;\n }\n pause() {\n this.window.pause();\n this.document.pause();\n }\n resume() {\n this.window.resume();\n this.document.resume();\n }\n clear() {\n this.window.clear();\n this.document.clear();\n }\n }\n const DefaultAntialiasOptions = {\n pixelArtSampler: false,\n nativeContextAntialiasing: false,\n multiSampleAntialiasing: true,\n filtering: ImageFiltering.Blended,\n canvasImageRendering: \"auto\"\n };\n const DefaultPixelArtOptions = {\n pixelArtSampler: true,\n nativeContextAntialiasing: false,\n multiSampleAntialiasing: true,\n filtering: ImageFiltering.Blended,\n canvasImageRendering: \"auto\"\n };\n class FpsSampler {\n constructor(options){\n var _a;\n this._samplePeriod = 100;\n this._currentFrameTime = 0;\n this._frames = 0;\n this._previousSampleTime = 0;\n this._beginFrameTime = 0;\n this._fps = options.initialFps;\n this._samplePeriod = (_a = options.samplePeriod) !== null && _a !== void 0 ? _a : this._samplePeriod;\n this._currentFrameTime = 1000 / options.initialFps;\n this._nowFn = options.nowFn;\n this._previousSampleTime = this._nowFn();\n }\n /**\n * Start of code block to sample FPS for\n */ start() {\n this._beginFrameTime = this._nowFn();\n }\n /**\n * End of code block to sample FPS for\n */ end() {\n this._frames++;\n const time = this._nowFn();\n this._currentFrameTime = time - this._beginFrameTime;\n if (time >= this._previousSampleTime + this._samplePeriod) {\n this._fps = this._frames * 1000 / (time - this._previousSampleTime);\n this._previousSampleTime = time;\n this._frames = 0;\n }\n }\n /**\n * Return the currently sampled fps over the last sample period, by default every 100ms\n */ get fps() {\n return this._fps;\n }\n /**\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\n */ get instant() {\n return 1000 / this._currentFrameTime;\n }\n }\n /**\n * Abstract Clock is the base type of all Clocks\n *\n * It has a few opinions\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\n * 2. The default timing api is implemented in now()\n *\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\n * method is unique to your clock implementation.\n */ class Clock {\n constructor(options){\n var _a, _b, _c;\n this._onFatalException = ()=>{};\n this._maxFps = Infinity;\n this._lastTime = 0;\n this._elapsed = 1;\n this._scheduledCbs = [];\n this._totalElapsed = 0;\n this._options = options;\n this.tick = options.tick;\n this._lastTime = (_a = this.now()) !== null && _a !== void 0 ? _a : 0;\n this._maxFps = (_b = options.maxFps) !== null && _b !== void 0 ? _b : this._maxFps;\n this._onFatalException = (_c = options.onFatalException) !== null && _c !== void 0 ? _c : this._onFatalException;\n this.fpsSampler = new FpsSampler({\n initialFps: 60,\n nowFn: ()=>this.now()\n });\n }\n /**\n * Get the elapsed time for the last completed frame\n */ elapsed() {\n return this._elapsed;\n }\n /**\n * Get the current time in milliseconds\n */ now() {\n return performance.now();\n }\n toTestClock() {\n const testClock = new TestClock({\n ...this._options,\n defaultUpdateMs: 16.6\n });\n return testClock;\n }\n toStandardClock() {\n const clock = new StandardClock({\n ...this._options\n });\n return clock;\n }\n setFatalExceptionHandler(handler) {\n this._onFatalException = handler;\n }\n /**\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\n *\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\n * stopped or paused.\n * @param cb callback to fire\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\n */ schedule(cb, timeoutMs = 0) {\n // Scheduled based on internal elapsed time\n const scheduledTime = this._totalElapsed + timeoutMs;\n this._scheduledCbs.push([\n cb,\n scheduledTime\n ]);\n }\n _runScheduledCbs() {\n // walk backwards to delete items as we loop\n for(let i = this._scheduledCbs.length - 1; i > -1; i--)if (this._scheduledCbs[i][1] <= this._totalElapsed) {\n this._scheduledCbs[i][0](this._elapsed);\n this._scheduledCbs.splice(i, 1);\n }\n }\n update(overrideUpdateMs) {\n try {\n this.fpsSampler.start();\n // Get the time to calculate time-elapsed\n const now = this.now();\n let elapsed = now - this._lastTime || 1; // first frame\n // Constrain fps\n const fpsInterval = 1000 / this._maxFps;\n // only run frame if enough time has elapsed\n if (elapsed >= fpsInterval) {\n let leftover = 0;\n if (fpsInterval !== 0) {\n leftover = elapsed % fpsInterval;\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\n }\n // Resolves issue #138 if the game has been paused, or blurred for\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\n // and provides more expected behavior when the engine comes back\n // into focus\n if (elapsed > 200) elapsed = 1;\n // tick the mainloop and run scheduled callbacks\n this._elapsed = overrideUpdateMs || elapsed;\n this._totalElapsed += this._elapsed;\n this._runScheduledCbs();\n this.tick(overrideUpdateMs || elapsed);\n if (fpsInterval !== 0) this._lastTime = now - leftover;\n else this._lastTime = now;\n this.fpsSampler.end();\n }\n } catch (e) {\n this._onFatalException(e);\n this.stop();\n }\n }\n }\n /**\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\n */ class StandardClock extends Clock {\n constructor(options){\n super(options);\n this._running = false;\n }\n isRunning() {\n return this._running;\n }\n start() {\n if (this._running) return;\n this._running = true;\n const mainloop = ()=>{\n // stop the loop\n if (!this._running) return;\n try {\n // request next loop\n this._requestId = window.requestAnimationFrame(mainloop);\n this.update();\n } catch (e) {\n window.cancelAnimationFrame(this._requestId);\n throw e;\n }\n };\n // begin the first frame\n mainloop();\n }\n stop() {\n window.cancelAnimationFrame(this._requestId);\n this._running = false;\n }\n }\n /**\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\n */ class TestClock extends Clock {\n constructor(options){\n super({\n ...options\n });\n this._logger = Logger.getInstance();\n this._running = false;\n this._currentTime = 0;\n this._updateMs = options.defaultUpdateMs;\n }\n /**\n * Get the current time in milliseconds\n */ now() {\n var _a;\n return (_a = this._currentTime) !== null && _a !== void 0 ? _a : 0;\n }\n isRunning() {\n return this._running;\n }\n start() {\n this._running = true;\n }\n stop() {\n this._running = false;\n }\n /**\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\n * @param overrideUpdateMs\n */ step(overrideUpdateMs) {\n const time = overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs;\n if (this._running) {\n // to be comparable to RAF this needs to be a full blown Task\n // For example, images cannot decode synchronously in a single step\n this.update(time);\n this._currentTime += time;\n } else this._logger.warn(\"The clock is not running, no step will be performed\");\n }\n /**\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\n * @param numberOfSteps\n * @param overrideUpdateMs\n */ run(numberOfSteps, overrideUpdateMs) {\n for(let i = 0; i < numberOfSteps; i++)this.step(overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs);\n }\n }\n // EXTERNAL MODULE: ./Util/Toaster.css\n var Util_Toaster = $2c23f148d58cd887$var$__webpack_require__(7379);\n /**\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\n */ class Toaster {\n constructor(){\n this._toasterCss = Util_Toaster /* default */ .Z.toString();\n this._isInitialized = false;\n }\n _initialize() {\n if (!this._isInitialized) {\n this._container = document.createElement(\"div\");\n this._container.id = \"ex-toast-container\";\n document.body.appendChild(this._container);\n this._isInitialized = true;\n this._styleBlock = document.createElement(\"style\");\n this._styleBlock.textContent = this._toasterCss;\n document.head.appendChild(this._styleBlock);\n }\n }\n dispose() {\n this._container.parentElement.removeChild(this._container);\n this._styleBlock.parentElement.removeChild(this._styleBlock);\n this._isInitialized = false;\n }\n _createFragment(message) {\n const toastMessage = document.createElement(\"span\");\n toastMessage.innerText = message;\n return toastMessage;\n }\n /**\n * Display a toast message to a player\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\n * @param linkTarget Optionally specify a link location\n * @param linkName Optionally specify a name for that link location\n */ toast(message, linkTarget, linkName) {\n this._initialize();\n const toast = document.createElement(\"div\");\n toast.className = \"ex-toast-message\";\n const messageFragments = message.split(\"[LINK]\").map((message)=>this._createFragment(message));\n if (linkTarget) {\n const link = document.createElement(\"a\");\n link.href = linkTarget;\n if (linkName) link.innerText = linkName;\n else link.innerText = linkTarget;\n messageFragments.splice(1, 0, link);\n }\n // Assembly message\n const finalMessage = document.createElement(\"div\");\n messageFragments.forEach((message)=>{\n finalMessage.appendChild(message);\n });\n toast.appendChild(finalMessage);\n // Dismiss button\n const dismissBtn = document.createElement(\"button\");\n dismissBtn.innerText = \"x\";\n dismissBtn.addEventListener(\"click\", ()=>{\n this._container.removeChild(toast);\n });\n toast.appendChild(dismissBtn);\n // Escape to dismiss\n const keydownHandler = (evt)=>{\n if (evt.key === \"Escape\") try {\n this._container.removeChild(toast);\n } catch (_a) {\n // pass\n }\n document.removeEventListener(\"keydown\", keydownHandler);\n };\n document.addEventListener(\"keydown\", keydownHandler);\n // Insert into container\n const first = this._container.firstChild;\n this._container.insertBefore(toast, first);\n }\n }\n const DirectorEvents = {\n NavigationStart: \"navigationstart\",\n Navigation: \"navigation\",\n NavigationEnd: \"navigationend\"\n };\n /**\n * The Director is responsible for managing scenes and changing scenes in Excalibur.\n *\n * It deals with transitions, scene loaders, switching scenes\n *\n * This is used internally by Excalibur, generally not mean to\n * be instantiated end users directly.\n */ class Director {\n /**\n * Gets whether the director currently transitioning between scenes\n *\n * Useful if you need to block behavior during transition\n */ get isTransitioning() {\n return this._isTransitioning;\n }\n constructor(_engine, scenes){\n this._engine = _engine;\n this.events = new EventEmitter();\n this._logger = Logger.getInstance();\n this._initialized = false;\n /**\n * All registered scenes in Excalibur\n */ this.scenes = {};\n /**\n * Holds all instantiated scenes\n */ this._sceneToInstance = new Map();\n this._sceneToLoader = new Map();\n this._sceneToTransition = new Map();\n /**\n * Used to keep track of scenes that have already been loaded so we don't load multiple times\n */ this._loadedScenes = new Set();\n this._isTransitioning = false;\n this.rootScene = this.currentScene = new Scene();\n this.add(\"root\", this.rootScene);\n this.currentScene = this.rootScene;\n this.currentSceneName = \"root\";\n for(const sceneKey in scenes){\n const sceneOrOptions = scenes[sceneKey];\n this.add(sceneKey, sceneOrOptions);\n if (sceneKey === \"root\") {\n this.rootScene = this.getSceneInstance(\"root\");\n this.currentScene = this.rootScene;\n }\n }\n }\n /**\n * Initialize the director's internal state\n */ async onInitialize() {\n if (!this._initialized) {\n this._initialized = true;\n if (this._deferredGoto) {\n const deferredScene = this._deferredGoto;\n this._deferredGoto = null;\n await this.swapScene(deferredScene);\n } else await this.swapScene(\"root\");\n }\n }\n get isInitialized() {\n return this._initialized;\n }\n /**\n * Configures the start scene, and optionally the transition & loader for the director\n *\n * Typically this is called at the beginning of the game to the start scene and transition and never again.\n * @param startScene\n * @param options\n */ configureStart(startScene, options) {\n const maybeLoaderOrCtor = options === null || options === void 0 ? void 0 : options.loader;\n if (maybeLoaderOrCtor instanceof DefaultLoader) this.mainLoader = maybeLoaderOrCtor;\n else if (isLoaderConstructor(maybeLoaderOrCtor)) this.mainLoader = new maybeLoaderOrCtor();\n else this.mainLoader = new Loader();\n let maybeStartTransition;\n if (options) {\n const { inTransition: inTransition } = options;\n maybeStartTransition = inTransition;\n }\n this.startScene = startScene;\n // Fire and forget promise for the initial scene\n if (maybeStartTransition) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.swapScene(this.startScene);\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.playTransition(maybeStartTransition);\n } else // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.swapScene(this.startScene);\n this.currentSceneName = this.startScene;\n }\n _getLoader(sceneName) {\n return this._sceneToLoader.get(sceneName);\n }\n _getInTransition(sceneName) {\n var _a;\n const sceneOrRoute = this.scenes[sceneName];\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) return null;\n return (_a = sceneOrRoute === null || sceneOrRoute === void 0 ? void 0 : sceneOrRoute.transitions) === null || _a === void 0 ? void 0 : _a.in;\n }\n _getOutTransition(sceneName) {\n var _a;\n const sceneOrRoute = this.scenes[sceneName];\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) return null;\n return (_a = sceneOrRoute === null || sceneOrRoute === void 0 ? void 0 : sceneOrRoute.transitions) === null || _a === void 0 ? void 0 : _a.out;\n }\n getDeferredScene() {\n const maybeDeferred = this.getSceneDefinition(this._deferredGoto);\n if (this._deferredGoto && maybeDeferred) return maybeDeferred;\n return null;\n }\n /**\n * Returns a scene by name if it exists, might be the constructor and not the instance of a scene\n * @param name\n */ getSceneDefinition(name) {\n const maybeScene = this.scenes[name];\n if (maybeScene instanceof Scene || isSceneConstructor(maybeScene)) return maybeScene;\n else if (maybeScene) return maybeScene.scene;\n return undefined;\n }\n getSceneName(scene) {\n for (const [name, sceneInstance] of this._sceneToInstance){\n if (scene === sceneInstance) return name;\n }\n return \"unknown scene name\";\n }\n /**\n * Returns the same Director, but asserts a scene DOES exist to the type system\n * @param name\n */ assertAdded(name) {\n return this;\n }\n /**\n * Returns the same Director, but asserts a scene DOES NOT exist to the type system\n * @param name\n */ assertRemoved(name) {\n return this;\n }\n /**\n * Adds additional Scenes to the game!\n * @param name\n * @param sceneOrRoute\n */ add(name, sceneOrRoute) {\n if (!(sceneOrRoute instanceof Scene) && !isSceneConstructor(sceneOrRoute)) {\n const { loader: loader, transitions: transitions } = sceneOrRoute;\n const { in: inTransition, out: outTransition } = transitions !== null && transitions !== void 0 ? transitions : {};\n this._sceneToTransition.set(name, {\n in: inTransition,\n out: outTransition\n });\n if (isLoaderConstructor(loader)) this._sceneToLoader.set(name, new loader());\n else this._sceneToLoader.set(name, loader);\n }\n if (this.scenes[name]) this._logger.warn(\"Scene\", name, \"already exists overwriting\");\n this.scenes[name] = sceneOrRoute;\n return this.assertAdded(name);\n }\n remove(nameOrScene) {\n if (nameOrScene instanceof Scene || isSceneConstructor(nameOrScene)) {\n const sceneOrCtor = nameOrScene;\n // remove scene\n for(const key in this.scenes)if (this.scenes.hasOwnProperty(key)) {\n const potentialSceneOrOptions = this.scenes[key];\n let scene;\n if (potentialSceneOrOptions instanceof Scene || isSceneConstructor(potentialSceneOrOptions)) scene = potentialSceneOrOptions;\n else scene = potentialSceneOrOptions.scene;\n if (scene === sceneOrCtor) {\n if (key === this.currentSceneName) throw new Error(`Cannot remove a currently active scene: ${key}`);\n this._sceneToTransition.delete(key);\n this._sceneToLoader.delete(key);\n delete this.scenes[key];\n }\n }\n }\n if (typeof nameOrScene === \"string\") {\n if (nameOrScene === this.currentSceneName) throw new Error(`Cannot remove a currently active scene: ${nameOrScene}`);\n // remove scene\n this._sceneToTransition.delete(nameOrScene);\n this._sceneToLoader.delete(nameOrScene);\n delete this.scenes[nameOrScene];\n }\n }\n /**\n * Go to a specific scene, and optionally override loaders and transitions\n * @param destinationScene\n * @param options\n */ async goto(destinationScene, options) {\n var _a, _b, _c, _d, _e, _f;\n const maybeDest = this.getSceneInstance(destinationScene);\n if (!maybeDest) {\n this._logger.warn(`Scene ${destinationScene} does not exist! Check the name, are you sure you added it?`);\n return;\n }\n const sourceScene = this.currentSceneName;\n const engineInputEnabled = (_b = (_a = this._engine.input) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;\n this._isTransitioning = true;\n const maybeSourceOut = (_c = this.getSceneInstance(sourceScene)) === null || _c === void 0 ? void 0 : _c.onTransition(\"out\");\n const maybeDestinationIn = maybeDest === null || maybeDest === void 0 ? void 0 : maybeDest.onTransition(\"in\");\n options = {\n sourceOut: (_d = this._getOutTransition(this.currentSceneName)) !== null && _d !== void 0 ? _d : maybeSourceOut,\n destinationIn: (_e = this._getInTransition(destinationScene)) !== null && _e !== void 0 ? _e : maybeDestinationIn,\n // Goto options\n ...options\n };\n const { sourceOut: sourceOut, destinationIn: destinationIn, sceneActivationData: sceneActivationData } = options;\n const outTransition = sourceOut !== null && sourceOut !== void 0 ? sourceOut : this._getOutTransition(this.currentSceneName);\n const inTransition = destinationIn !== null && destinationIn !== void 0 ? destinationIn : this._getInTransition(destinationScene);\n const hideLoader = (outTransition === null || outTransition === void 0 ? void 0 : outTransition.hideLoader) || (inTransition === null || inTransition === void 0 ? void 0 : inTransition.hideLoader);\n if (hideLoader) // Start hidden loader early and take advantage of the transition\n // Don't await and block on a hidden loader\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.maybeLoadScene(destinationScene, hideLoader);\n this._emitEvent(\"navigationstart\", sourceScene, destinationScene);\n // Run the out transition on the current scene if present\n await this.playTransition(outTransition);\n // Run the loader if present\n await this.maybeLoadScene(destinationScene, hideLoader);\n // Give incoming transition a chance to grab info from previous\n await (inTransition === null || inTransition === void 0 ? void 0 : inTransition.onPreviousSceneDeactivate(this.currentScene));\n // Swap to the new scene\n await this.swapScene(destinationScene, sceneActivationData);\n this._emitEvent(\"navigation\", sourceScene, destinationScene);\n // Run the in transition on the new scene if present\n await this.playTransition(inTransition);\n this._emitEvent(\"navigationend\", sourceScene, destinationScene);\n (_f = this._engine.input) === null || _f === void 0 || _f.toggleEnabled(engineInputEnabled);\n this._isTransitioning = false;\n }\n /**\n * Retrieves a scene instance by key if it's registered.\n *\n * This will call any constructors that were given as a definition\n * @param scene\n */ getSceneInstance(scene) {\n const sceneDefinition = this.getSceneDefinition(scene);\n if (!sceneDefinition) return undefined;\n if (this._sceneToInstance.has(scene)) return this._sceneToInstance.get(scene);\n if (sceneDefinition instanceof Scene) {\n this._sceneToInstance.set(scene, sceneDefinition);\n return sceneDefinition;\n }\n const newScene = new sceneDefinition();\n this._sceneToInstance.set(scene, newScene);\n return newScene;\n }\n /**\n * Triggers scene loading if has not already been loaded\n * @param scene\n * @param hideLoader\n */ async maybeLoadScene(scene, hideLoader = false) {\n var _a;\n const loader = (_a = this._getLoader(scene)) !== null && _a !== void 0 ? _a : new DefaultLoader();\n const sceneToLoad = this.getSceneDefinition(scene);\n const sceneToLoadInstance = this.getSceneInstance(scene);\n if (sceneToLoad && sceneToLoadInstance && !this._loadedScenes.has(sceneToLoadInstance)) {\n sceneToLoadInstance.onPreLoad(loader);\n sceneToLoadInstance.events.emit(\"preload\", {\n loader: loader\n });\n if (hideLoader) // Don't await a hidden loader\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this._engine.load(loader, hideLoader);\n else await this._engine.load(loader);\n this._loadedScenes.add(sceneToLoadInstance);\n }\n }\n /**\n * Plays a transition in the current scene\n * @param transition\n */ async playTransition(transition) {\n var _a, _b, _c, _d, _e, _f, _g;\n if (transition) {\n this.currentTransition = transition;\n const currentScene = this._engine.currentScene;\n const sceneInputEnabled = (_b = (_a = currentScene.input) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;\n (_c = currentScene.input) === null || _c === void 0 || _c.toggleEnabled(!transition.blockInput);\n (_d = this._engine.input) === null || _d === void 0 || _d.toggleEnabled(!transition.blockInput);\n await this.currentTransition.play(this._engine);\n (_e = currentScene.input) === null || _e === void 0 || _e.toggleEnabled(sceneInputEnabled);\n }\n (_f = this.currentTransition) === null || _f === void 0 || _f.kill();\n (_g = this.currentTransition) === null || _g === void 0 || _g.reset();\n this.currentTransition = null;\n }\n /**\n * Swaps the current and destination scene after performing required lifecycle events\n * @param destinationScene\n * @param data\n */ async swapScene(destinationScene, data) {\n const engine = this._engine;\n // if not yet initialized defer goToScene\n if (!this.isInitialized) {\n this._deferredGoto = destinationScene;\n return;\n }\n const maybeDest = this.getSceneInstance(destinationScene);\n if (maybeDest) {\n const previousScene = this.currentScene;\n const nextScene = maybeDest;\n this._logger.debug(\"Going to scene:\", destinationScene);\n // only deactivate when initialized\n if (this.currentScene.isInitialized) {\n const context = {\n engine: engine,\n previousScene: previousScene,\n nextScene: nextScene\n };\n await this.currentScene._deactivate(context);\n this.currentScene.events.emit(\"deactivate\", new DeactivateEvent(context, this.currentScene));\n }\n // wait for the scene to be loaded if needed\n const destLoader = this._sceneToLoader.get(destinationScene);\n await (destLoader === null || destLoader === void 0 ? void 0 : destLoader.areResourcesLoaded());\n // set current scene to new one\n this.currentScene = nextScene;\n this.currentSceneName = destinationScene;\n engine.screen.setCurrentCamera(nextScene.camera);\n // initialize the current scene if has not been already\n await this.currentScene._initialize(engine);\n const context = {\n engine: engine,\n previousScene: previousScene,\n nextScene: nextScene,\n data: data\n };\n await this.currentScene._activate(context);\n this.currentScene.events.emit(\"activate\", new ActivateEvent(context, this.currentScene));\n } else this._logger.error(\"Scene\", destinationScene, \"does not exist!\");\n }\n _emitEvent(eventName, sourceScene, destinationScene) {\n const source = this.getSceneDefinition(sourceScene);\n const dest = this.getSceneDefinition(destinationScene);\n this.events.emit(eventName, {\n sourceScene: source,\n sourceName: sourceScene,\n destinationScene: dest,\n destinationName: destinationScene\n });\n }\n }\n polyfill();\n const EngineEvents = {\n FallbackGraphicsContext: \"fallbackgraphicscontext\",\n Initialize: \"initialize\",\n Visible: \"visible\",\n Hidden: \"hidden\",\n Start: \"start\",\n Stop: \"stop\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreFrame: \"preframe\",\n PostFrame: \"postframe\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\"\n };\n /**\n * Enum representing the different mousewheel event bubble prevention\n */ var ScrollPreventionMode;\n (function(ScrollPreventionMode) {\n /**\n * Do not prevent any page scrolling\n */ ScrollPreventionMode[ScrollPreventionMode[\"None\"] = 0] = \"None\";\n /**\n * Prevent page scroll if mouse is over the game canvas\n */ ScrollPreventionMode[ScrollPreventionMode[\"Canvas\"] = 1] = \"Canvas\";\n /**\n * Prevent all page scrolling via mouse wheel\n */ ScrollPreventionMode[ScrollPreventionMode[\"All\"] = 2] = \"All\";\n })(ScrollPreventionMode || (ScrollPreventionMode = {}));\n /**\n * The Excalibur Engine\n *\n * The [[Engine]] is the main driver for a game. It is responsible for\n * starting/stopping the game, maintaining state, transmitting events,\n * loading resources, and managing the scene.\n */ class Engine {\n /**\n * The width of the game canvas in pixels (physical width component of the\n * resolution of the canvas element)\n */ get canvasWidth() {\n return this.screen.canvasWidth;\n }\n /**\n * Returns half width of the game canvas in pixels (half physical width component)\n */ get halfCanvasWidth() {\n return this.screen.halfCanvasWidth;\n }\n /**\n * The height of the game canvas in pixels, (physical height component of\n * the resolution of the canvas element)\n */ get canvasHeight() {\n return this.screen.canvasHeight;\n }\n /**\n * Returns half height of the game canvas in pixels (half physical height component)\n */ get halfCanvasHeight() {\n return this.screen.halfCanvasHeight;\n }\n /**\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get drawWidth() {\n return this.screen.drawWidth;\n }\n /**\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get halfDrawWidth() {\n return this.screen.halfDrawWidth;\n }\n /**\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get drawHeight() {\n return this.screen.drawHeight;\n }\n /**\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */ get halfDrawHeight() {\n return this.screen.halfDrawHeight;\n }\n /**\n * Returns whether excalibur detects the current screen to be HiDPI\n */ get isHiDpi() {\n return this.screen.isHiDpi;\n }\n /**\n * Access [[stats]] that holds frame statistics.\n */ get stats() {\n return this.debug.stats;\n }\n /**\n * The current [[Scene]] being drawn and updated on screen\n */ get currentScene() {\n return this.director.currentScene;\n }\n /**\n * The current [[Scene]] being drawn and updated on screen\n */ get currentSceneName() {\n return this.director.currentSceneName;\n }\n /**\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\n */ get rootScene() {\n return this.director.rootScene;\n }\n /**\n * Contains all the scenes currently registered with Excalibur\n */ get scenes() {\n return this.director.scenes;\n }\n /**\n * Indicates whether the engine is set to fullscreen or not\n */ get isFullscreen() {\n return this.screen.isFullScreen;\n }\n /**\n * Indicates the current [[DisplayMode]] of the engine.\n */ get displayMode() {\n return this.screen.displayMode;\n }\n /**\n * Returns the calculated pixel ration for use in rendering\n */ get pixelRatio() {\n return this.screen.pixelRatio;\n }\n get isDebug() {\n return this._isDebug;\n }\n /**\n * Hints the graphics context to truncate fractional world space coordinates\n */ get snapToPixel() {\n return this.graphicsContext.snapToPixel;\n }\n set snapToPixel(shouldSnapToPixel) {\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\n * the game will be rendered full screen (taking up all available browser window space).\n * You can customize the game rendering through [[EngineOptions]].\n *\n * Example:\n *\n * ```js\n * var game = new ex.Engine({\n * width: 0, // the width of the canvas\n * height: 0, // the height of the canvas\n * enableCanvasTransparency: true, // the transparencySection of the canvas\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\n * });\n *\n * // call game.start, which is a Promise\n * game.start().then(function () {\n * // ready, set, go!\n * });\n * ```\n */ constructor(options){\n var _a, _b, _c, _d, _e, _f, _g;\n /**\n * Current Excalibur version string\n *\n * Useful for plugins or other tools that need to know what features are available\n */ this.version = EX_VERSION;\n /**\n * Listen to and emit events on the Engine\n */ this.events = new EventEmitter();\n /**\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\n *\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\n * one that bounces between 30fps and 60fps\n */ this.maxFps = Number.POSITIVE_INFINITY;\n this._inputEnabled = true;\n this._suppressPlayButton = false;\n /**\n * Indicates whether audio should be paused when the game is no longer visible.\n */ this.pauseAudioWhenHidden = true;\n /**\n * Indicates whether the engine should draw with debug information\n */ this._isDebug = false;\n /**\n * Sets the Transparency for the engine.\n */ this.enableCanvasTransparency = true;\n /**\n * The action to take when a fatal exception is thrown\n */ this.onFatalException = (e)=>{\n Logger.getInstance().fatal(e, e.stack);\n };\n this._toaster = new Toaster();\n this._timescale = 1.0;\n this._isInitialized = false;\n this._originalOptions = {};\n this._performanceThresholdTriggered = false;\n this._fpsSamples = [];\n this._disposed = false;\n this._isLoading = false;\n this._hideLoader = false;\n this._isReadyFuture = new Future();\n /**\n * Returns the current frames elapsed milliseconds\n */ this.currentFrameElapsedMs = 0;\n /**\n * Returns the current frame lag when in fixed update mode\n */ this.currentFrameLagMs = 0;\n this._lagMs = 0;\n this._screenShotRequests = [];\n options = {\n ...Engine._DEFAULT_ENGINE_OPTIONS,\n ...options\n };\n this._originalOptions = options;\n Flags.freeze();\n // Initialize browser events facade\n this.browser = new BrowserEvents(window, document);\n // Check compatibility\n const detector = new Detector();\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\n const message = document.createElement(\"div\");\n message.innerText = \"Sorry, your browser does not support all the features needed for Excalibur\";\n document.body.appendChild(message);\n detector.failedTests.forEach(function(test) {\n const testMessage = document.createElement(\"div\");\n testMessage.innerText = \"Browser feature missing \" + test;\n document.body.appendChild(testMessage);\n });\n if (options.canvasElementId) {\n const canvas = document.getElementById(options.canvasElementId);\n if (canvas) canvas.parentElement.removeChild(canvas);\n }\n return;\n } else this._compatible = true;\n // Use native console API for color fun\n // eslint-disable-next-line no-console\n if (console.log && !options.suppressConsoleBootMessage) {\n // eslint-disable-next-line no-console\n console.log(`%cPowered by Excalibur.js (v${EX_VERSION})`, \"background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;\");\n // eslint-disable-next-line no-console\n console.log(\"\\n /| ________________\\nO|===|* >________________>\\n \\\\|\");\n // eslint-disable-next-line no-console\n console.log(\"Visit\", \"http://excaliburjs.com\", \"for more information\");\n }\n // Suppress play button\n if (options.suppressPlayButton) this._suppressPlayButton = true;\n this._logger = Logger.getInstance();\n // If debug is enabled, let's log browser features to the console.\n if (this._logger.defaultLevel === LogLevel.Debug) detector.logBrowserFeatures();\n this._logger.debug(\"Building engine...\");\n this.canvasElementId = options.canvasElementId;\n if (options.canvasElementId) {\n this._logger.debug(\"Using Canvas element specified: \" + options.canvasElementId);\n //test for existence of element\n if (document.getElementById(options.canvasElementId) === null) throw new Error(\"Cannot find existing element in the DOM, please ensure element is created prior to engine creation.\");\n this.canvas = document.getElementById(options.canvasElementId);\n } else if (options.canvasElement) {\n this._logger.debug(\"Using Canvas element specified:\", options.canvasElement);\n this.canvas = options.canvasElement;\n } else {\n this._logger.debug(\"Using generated canvas element\");\n this.canvas = document.createElement(\"canvas\");\n }\n let displayMode = (_a = options.displayMode) !== null && _a !== void 0 ? _a : DisplayMode.Fixed;\n if (options.width && options.height || options.viewport) {\n if (options.displayMode === undefined) displayMode = DisplayMode.Fixed;\n this._logger.debug(\"Engine viewport is size \" + options.width + \" x \" + options.height);\n } else if (!options.displayMode) {\n this._logger.debug(\"Engine viewport is fit\");\n displayMode = DisplayMode.FitScreen;\n }\n this._originalDisplayMode = displayMode;\n let pixelArtSampler;\n let uvPadding;\n let nativeContextAntialiasing;\n let canvasImageRendering;\n let filtering;\n let multiSampleAntialiasing;\n if (typeof options.antialiasing === \"object\") ({ pixelArtSampler: pixelArtSampler, nativeContextAntialiasing: nativeContextAntialiasing, multiSampleAntialiasing: multiSampleAntialiasing, filtering: filtering, canvasImageRendering: canvasImageRendering } = {\n ...options.pixelArt ? DefaultPixelArtOptions : DefaultAntialiasOptions,\n ...options.antialiasing\n });\n else {\n pixelArtSampler = !!options.pixelArt;\n nativeContextAntialiasing = false;\n multiSampleAntialiasing = options.antialiasing;\n canvasImageRendering = options.antialiasing ? \"auto\" : \"pixelated\";\n filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\n }\n if (nativeContextAntialiasing && multiSampleAntialiasing) this._logger.warnOnce(`Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing` + ` at the same time, they are incompatible settings. If you aren\\'t sure use multiSampleAntialiasing`);\n if (options.pixelArt) uvPadding = .25;\n if (!options.antialiasing || filtering === ImageFiltering.Pixel) uvPadding = 0;\n // Override with any user option, if non default to .25 for pixel art, 0.01 for everything else\n uvPadding = (_c = (_b = options.uvPadding) !== null && _b !== void 0 ? _b : uvPadding) !== null && _c !== void 0 ? _c : 0.01;\n // Canvas 2D fallback can be flagged on\n let useCanvasGraphicsContext = Flags.isEnabled(\"use-canvas-context\");\n if (!useCanvasGraphicsContext) // Attempt webgl first\n try {\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n pixelArtSampler: pixelArtSampler,\n antialiasing: nativeContextAntialiasing,\n multiSampleAntialiasing: multiSampleAntialiasing,\n uvPadding: uvPadding,\n powerPreference: options.powerPreference,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n } catch (e) {\n this._logger.warn(`Excalibur could not load webgl for some reason (${e.message}) and loaded a Canvas 2D fallback. ` + `Some features of Excalibur will not work in this mode. \\n\\n` + \"Read more about this issue at https://excaliburjs.com/docs/webgl\");\n // fallback to canvas in case of failure\n useCanvasGraphicsContext = true;\n }\n if (useCanvasGraphicsContext) this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n antialiasing: nativeContextAntialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: nativeContextAntialiasing,\n canvasImageRendering: canvasImageRendering,\n browser: this.browser,\n viewport: (_d = options.viewport) !== null && _d !== void 0 ? _d : options.width && options.height ? {\n width: options.width,\n height: options.height\n } : Resolution.SVGA,\n resolution: options.resolution,\n displayMode: displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : (_e = options.pixelRatio) !== null && _e !== void 0 ? _e : null\n });\n // TODO REMOVE STATIC!!!\n // Set default filtering based on antialiasing\n TextureLoader.filtering = filtering;\n if (options.backgroundColor) this.backgroundColor = options.backgroundColor.clone();\n this.grabWindowFocus = options.grabWindowFocus;\n this.pointerScope = options.pointerScope;\n this.maxFps = (_f = options.maxFps) !== null && _f !== void 0 ? _f : this.maxFps;\n this.fixedUpdateFps = (_g = options.fixedUpdateFps) !== null && _g !== void 0 ? _g : this.fixedUpdateFps;\n this.clock = new StandardClock({\n maxFps: this.maxFps,\n tick: this._mainloop.bind(this),\n onFatalException: (e)=>this.onFatalException(e)\n });\n this.enableCanvasTransparency = options.enableCanvasTransparency;\n if (typeof options.physics === \"boolean\") this.physics = {\n ...DefaultPhysicsConfig,\n ...DeprecatedStaticToConfig(),\n enabled: options.physics\n };\n else this.physics = {\n ...DefaultPhysicsConfig,\n ...DeprecatedStaticToConfig(),\n ...options.physics\n };\n this.debug = new DebugConfig(this);\n this.director = new Director(this, options.scenes);\n this._initialize(options);\n window.___EXCALIBUR_DEVTOOL = this;\n }\n _monitorPerformanceThresholdAndTriggerFallback() {\n const { allow: allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\n let { threshold: threshold, showPlayerMessage: showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\n if (threshold === undefined) threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\n if (showPlayerMessage === undefined) showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\n if (!Flags.isEnabled(\"use-canvas-context\") && allow && this.ready && !this._performanceThresholdTriggered) {\n // Calculate Average fps for last X number of frames after start\n if (this._fpsSamples.length === threshold.numberOfFrames) this._fpsSamples.splice(0, 1);\n this._fpsSamples.push(this.clock.fpsSampler.fps);\n let total = 0;\n for(let i = 0; i < this._fpsSamples.length; i++)total += this._fpsSamples[i];\n const average = total / this._fpsSamples.length;\n if (this._fpsSamples.length === threshold.numberOfFrames) {\n if (average <= threshold.fps) {\n this._performanceThresholdTriggered = true;\n this._logger.warn(`Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` + \"this might mean your browser doesn't have webgl enabled or hardware acceleration is unavailable.\\n\\n\" + \"If in Chrome:\\n\" + ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n' + ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' + \"If in Firefox, visit about:config\\n\" + \" * Ensure webgl.disabled = false\\n\" + \" * Ensure webgl.force-enabled = true\\n\" + \" * Ensure layers.acceleration.force-enabled = true\\n\\n\" + \"Read more about this issue at https://excaliburjs.com/docs/performance\");\n if (showPlayerMessage) this._toaster.toast(\"Excalibur is encountering performance issues. It's possible that your browser doesn't have hardware acceleration enabled. Visit [LINK] for more information and potential solutions.\", \"https://excaliburjs.com/docs/performance\");\n this.useCanvas2DFallback();\n this.emit(\"fallbackgraphicscontext\", this.graphicsContext);\n }\n }\n }\n }\n /**\n * Switches the engine's graphics context to the 2D Canvas.\n * @warning Some features of Excalibur will not work in this mode.\n */ useCanvas2DFallback() {\n var _a, _b, _c;\n // Swap out the canvas\n const newCanvas = this.canvas.cloneNode(false);\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\n this.canvas = newCanvas;\n const options = {\n ...this._originalOptions,\n antialiasing: this.getAntialiasing()\n };\n const displayMode = this._originalDisplayMode;\n // New graphics context\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n antialiasing: options.antialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n // Reset screen\n if (this.screen) this.screen.dispose();\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: (_a = options.antialiasing) !== null && _a !== void 0 ? _a : true,\n browser: this.browser,\n viewport: (_b = options.viewport) !== null && _b !== void 0 ? _b : options.width && options.height ? {\n width: options.width,\n height: options.height\n } : Resolution.SVGA,\n resolution: options.resolution,\n displayMode: displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : (_c = options.pixelRatio) !== null && _c !== void 0 ? _c : null\n });\n this.screen.setCurrentCamera(this.currentScene.camera);\n // Reset pointers\n this.input.pointers.detach();\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\n this.input.pointers.init();\n }\n /**\n * Attempts to completely clean up excalibur resources, including removing the canvas from the dom.\n *\n * To start again you will need to new up an Engine.\n */ dispose() {\n if (!this._disposed) {\n this._disposed = true;\n this.stop();\n this.input.toggleEnabled(false);\n this.canvas.parentNode.removeChild(this.canvas);\n this.canvas = null;\n this.screen.dispose();\n this.graphicsContext.dispose();\n this.graphicsContext = null;\n }\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen\n * and the bottom right corner of the screen.\n */ getWorldBounds() {\n return this.screen.getWorldBounds();\n }\n /**\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\n */ get timescale() {\n return this._timescale;\n }\n /**\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\n * when using time-based movement.\n */ set timescale(value) {\n if (value <= 0) {\n Logger.getInstance().error(\"Cannot set engine.timescale to a value of 0 or less than 0.\");\n return;\n }\n this._timescale = value;\n }\n /**\n * Adds a [[Timer]] to the [[currentScene]].\n * @param timer The timer to add to the [[currentScene]].\n */ addTimer(timer) {\n return this.currentScene.addTimer(timer);\n }\n /**\n * Removes a [[Timer]] from the [[currentScene]].\n * @param timer The timer to remove to the [[currentScene]].\n */ removeTimer(timer) {\n return this.currentScene.removeTimer(timer);\n }\n /**\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\n * would levels or menus.\n * @param key The name of the scene, must be unique\n * @param scene The scene to add to the engine\n */ addScene(key, scene) {\n this.director.add(key, scene);\n return this;\n }\n /**\n * @internal\n */ removeScene(entity) {\n this.director.remove(entity);\n }\n add(entity) {\n if (arguments.length === 2) {\n this.director.add(arguments[0], arguments[1]);\n return;\n }\n const maybeDeferred = this.director.getDeferredScene();\n if (maybeDeferred instanceof Scene) maybeDeferred.add(entity);\n else this.currentScene.add(entity);\n }\n remove(entity) {\n if (entity instanceof Entity) this.currentScene.remove(entity);\n if (entity instanceof Scene || isSceneConstructor(entity)) this.removeScene(entity);\n if (typeof entity === \"string\") this.removeScene(entity);\n }\n /**\n * Changes the current scene with optionally supplied:\n * * Activation data\n * * Transitions\n * * Loaders\n *\n * Example:\n * ```typescript\n * game.goToScene('myScene', {\n * sceneActivationData: {any: 'thing at all'},\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\n * loader: MyLoader\n * });\n * ```\n *\n * Scenes are defined in the Engine constructor\n * ```typescript\n * const engine = new ex.Engine({\n scenes: {...}\n });\n * ```\n * Or by adding dynamically\n *\n * ```typescript\n * engine.addScene('myScene', new ex.Scene());\n * ```\n * @param destinationScene\n * @param options\n * @deprecated use goToScene, it now behaves the same as goto\n */ async goto(destinationScene, options) {\n await this.director.goto(destinationScene, options);\n }\n /**\n * Changes the current scene with optionally supplied:\n * * Activation data\n * * Transitions\n * * Loaders\n *\n * Example:\n * ```typescript\n * game.goToScene('myScene', {\n * sceneActivationData: {any: 'thing at all'},\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\n * loader: MyLoader\n * });\n * ```\n *\n * Scenes are defined in the Engine constructor\n * ```typescript\n * const engine = new ex.Engine({\n scenes: {...}\n });\n * ```\n * Or by adding dynamically\n *\n * ```typescript\n * engine.addScene('myScene', new ex.Scene());\n * ```\n * @param destinationScene\n * @param options\n */ async goToScene(destinationScene, options) {\n await this.director.goto(destinationScene, options);\n }\n /**\n * Transforms the current x, y from screen coordinates to world coordinates\n * @param point Screen coordinate to convert\n */ screenToWorldCoordinates(point) {\n return this.screen.screenToWorldCoordinates(point);\n }\n /**\n * Transforms a world coordinate, to a screen coordinate\n * @param point World coordinate to convert\n */ worldToScreenCoordinates(point) {\n return this.screen.worldToScreenCoordinates(point);\n }\n /**\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\n */ _initialize(options) {\n var _a, _b;\n this.pageScrollPreventionMode = options.scrollPreventionMode;\n // initialize inputs\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n const grabWindowFocus = (_b = (_a = this._originalOptions) === null || _a === void 0 ? void 0 : _a.grabWindowFocus) !== null && _b !== void 0 ? _b : true;\n this.input = new InputHost({\n pointerTarget: pointerTarget,\n grabWindowFocus: grabWindowFocus,\n engine: this\n });\n this.inputMapper = this.input.inputMapper;\n // Issue #385 make use of the visibility api\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\n this.browser.document.on(\"visibilitychange\", ()=>{\n if (document.visibilityState === \"hidden\") {\n this.events.emit(\"hidden\", new HiddenEvent(this));\n this._logger.debug(\"Window hidden\");\n } else if (document.visibilityState === \"visible\") {\n this.events.emit(\"visible\", new VisibleEvent(this));\n this._logger.debug(\"Window visible\");\n }\n });\n if (!this.canvasElementId && !options.canvasElement) document.body.appendChild(this.canvas);\n }\n toggleInputEnabled(enabled) {\n this._inputEnabled = enabled;\n this.input.toggleEnabled(this._inputEnabled);\n }\n onInitialize(engine) {\n // Override me\n }\n /**\n * If supported by the browser, this will set the antialiasing flag on the\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\n * image resources.\n * @param isSmooth Set smoothing to true or false\n * @deprecated Set in engine constructor, will be removed in v0.30\n */ setAntialiasing(isSmooth) {\n this.screen.antialiasing = isSmooth;\n }\n /**\n * Return the current smoothing status of the canvas\n * @deprecated Set in engine constructor, will be removed in v0.30\n */ getAntialiasing() {\n return this.screen.antialiasing;\n }\n /**\n * Gets whether the actor is Initialized\n */ get isInitialized() {\n return this._isInitialized;\n }\n async _overrideInitialize(engine) {\n if (!this.isInitialized) {\n await this.director.onInitialize();\n await this.onInitialize(engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * Updates the entire state of the game\n * @param delta Number of milliseconds elapsed since the last update.\n */ _update(delta) {\n var _a;\n if (this._isLoading) {\n // suspend updates until loading is finished\n (_a = this._loader) === null || _a === void 0 || _a.onUpdate(this, delta);\n // Update input listeners\n this.input.update();\n return;\n }\n // Publish preupdate events\n this._preupdate(delta);\n // process engine level events\n this.currentScene.update(this, delta);\n // Update graphics postprocessors\n this.graphicsContext.updatePostProcessors(delta);\n // Publish update event\n this._postupdate(delta);\n // Update input listeners\n this.input.update();\n }\n /**\n * @internal\n */ _preupdate(delta) {\n this.emit(\"preupdate\", new PreUpdateEvent(this, delta, this));\n this.onPreUpdate(this, delta);\n }\n onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * @internal\n */ _postupdate(delta) {\n this.emit(\"postupdate\", new PostUpdateEvent(this, delta, this));\n this.onPostUpdate(this, delta);\n }\n onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n * Draws the entire game\n * @param delta Number of milliseconds elapsed since the last draw.\n */ _draw(delta) {\n var _a, _b;\n this.graphicsContext.beginDrawLifecycle();\n this.graphicsContext.clear();\n this._predraw(this.graphicsContext, delta);\n // Drawing nothing else while loading\n if (this._isLoading) {\n if (!this._hideLoader) {\n (_a = this._loader) === null || _a === void 0 || _a.canvas.draw(this.graphicsContext, 0, 0);\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n }\n return;\n }\n // Use scene background color if present, fallback to engine\n this.graphicsContext.backgroundColor = (_b = this.currentScene.backgroundColor) !== null && _b !== void 0 ? _b : this.backgroundColor;\n this.currentScene.draw(this.graphicsContext, delta);\n this._postdraw(this.graphicsContext, delta);\n // Flush any pending drawings\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n this._checkForScreenShots();\n }\n /**\n * @internal\n */ _predraw(ctx, delta) {\n this.emit(\"predraw\", new PreDrawEvent(ctx, delta, this));\n this.onPreDraw(ctx, delta);\n }\n onPreDraw(ctx, delta) {\n // Override me\n }\n /**\n * @internal\n */ _postdraw(ctx, delta) {\n this.emit(\"postdraw\", new PostDrawEvent(ctx, delta, this));\n this.onPostDraw(ctx, delta);\n }\n onPostDraw(ctx, delta) {\n // Override me\n }\n /**\n * Enable or disable Excalibur debugging functionality.\n * @param toggle a value that debug drawing will be changed to\n */ showDebug(toggle) {\n this._isDebug = toggle;\n }\n /**\n * Toggle Excalibur debugging functionality.\n */ toggleDebug() {\n this._isDebug = !this._isDebug;\n return this._isDebug;\n }\n /**\n * Returns true when loading is totally complete and the player has clicked start\n */ get loadingComplete() {\n return !this._isLoading;\n }\n get ready() {\n return this._isReadyFuture.isCompleted;\n }\n isReady() {\n return this._isReadyFuture.promise;\n }\n async start(sceneNameOrLoader, options) {\n if (!this._compatible) throw new Error(\"Excalibur is incompatible with your browser\");\n this._isLoading = true;\n let loader;\n if (sceneNameOrLoader instanceof DefaultLoader) loader = sceneNameOrLoader;\n else if (typeof sceneNameOrLoader === \"string\") {\n this.director.configureStart(sceneNameOrLoader, options);\n loader = this.director.mainLoader;\n }\n // Start the excalibur clock which drives the mainloop\n this._logger.debug(\"Starting game clock...\");\n this.browser.resume();\n this.clock.start();\n this._logger.debug(\"Game clock started\");\n await this.load(loader !== null && loader !== void 0 ? loader : new Loader());\n // Initialize before ready\n await this._overrideInitialize(this);\n this._isReadyFuture.resolve();\n this.emit(\"start\", new GameStartEvent(this));\n return this._isReadyFuture.promise;\n }\n _mainloop(elapsed) {\n this.emit(\"preframe\", new PreFrameEvent(this, this.stats.prevFrame));\n const delta = elapsed * this.timescale;\n this.currentFrameElapsedMs = delta;\n // reset frame stats (reuse existing instances)\n const frameId = this.stats.prevFrame.id + 1;\n this.stats.currFrame.reset();\n this.stats.currFrame.id = frameId;\n this.stats.currFrame.delta = delta;\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\n GraphicsDiagnostics.clear();\n const beforeUpdate = this.clock.now();\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\n if (this.fixedUpdateFps) {\n this._lagMs += delta;\n while(this._lagMs >= fixedTimestepMs){\n this._update(fixedTimestepMs);\n this._lagMs -= fixedTimestepMs;\n }\n } else this._update(delta);\n const afterUpdate = this.clock.now();\n this.currentFrameLagMs = this._lagMs;\n this._draw(delta);\n const afterDraw = this.clock.now();\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\n this.emit(\"postframe\", new PostFrameEvent(this, this.stats.currFrame));\n this.stats.prevFrame.reset(this.stats.currFrame);\n this._monitorPerformanceThresholdAndTriggerFallback();\n }\n /**\n * Stops Excalibur's main loop, useful for pausing the game.\n */ stop() {\n if (this.clock.isRunning()) {\n this.emit(\"stop\", new GameStopEvent(this));\n this.browser.pause();\n this.clock.stop();\n this._logger.debug(\"Game stopped\");\n }\n }\n /**\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\n */ isRunning() {\n return this.clock.isRunning();\n }\n /**\n * Takes a screen shot of the current viewport and returns it as an\n * HTML Image Element.\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\n */ screenshot(preserveHiDPIResolution = false) {\n const screenShotPromise = new Promise((resolve)=>{\n this._screenShotRequests.push({\n preserveHiDPIResolution: preserveHiDPIResolution,\n resolve: resolve\n });\n });\n return screenShotPromise;\n }\n _checkForScreenShots() {\n // We must grab the draw buffer before we yield to the browser\n // the draw buffer is cleared after compositing\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\n // forces the browser to copy buffers which can have a mass perf impact on mobile\n for (const request of this._screenShotRequests){\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\n const screenshot = document.createElement(\"canvas\");\n screenshot.width = finalWidth;\n screenshot.height = finalHeight;\n const ctx = screenshot.getContext(\"2d\");\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\n const result = new Image();\n const raw = screenshot.toDataURL(\"image/png\");\n result.src = raw;\n request.resolve(result);\n }\n // Reset state\n this._screenShotRequests.length = 0;\n }\n /**\n * Another option available to you to load resources into the game.\n * Immediately after calling this the game will pause and the loading screen\n * will appear.\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\n */ async load(loader, hideLoader = false) {\n try {\n // early exit if loaded\n if (loader.isLoaded()) return;\n this._loader = loader;\n this._isLoading = true;\n this._hideLoader = hideLoader;\n if (loader instanceof Loader) loader.suppressPlayButton = this._suppressPlayButton;\n this._loader.onInitialize(this);\n await loader.load();\n } catch (e) {\n this._logger.error(\"Error loading resources, things may not behave properly\", e);\n await Promise.resolve();\n } finally{\n this._isLoading = false;\n this._hideLoader = false;\n this._loader = null;\n }\n }\n }\n /**\n * Default [[EngineOptions]]\n */ Engine._DEFAULT_ENGINE_OPTIONS = {\n width: 0,\n height: 0,\n enableCanvasTransparency: true,\n useDrawSorting: true,\n configurePerformanceCanvas2DFallback: {\n allow: false,\n showPlayerMessage: false,\n threshold: {\n fps: 20,\n numberOfFrames: 100\n }\n },\n canvasElementId: \"\",\n canvasElement: undefined,\n snapToPixel: false,\n antialiasing: true,\n pixelArt: false,\n powerPreference: \"high-performance\",\n pointerScope: PointerScope.Canvas,\n suppressConsoleBootMessage: null,\n suppressMinimumBrowserFeatureDetection: null,\n suppressHiDPIScaling: null,\n suppressPlayButton: null,\n grabWindowFocus: true,\n scrollPreventionMode: ScrollPreventionMode.Canvas,\n backgroundColor: Color.fromHex(\"#2185d0\") // Excalibur blue\n };\n /**\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\n */ class EventDispatcher {\n constructor(){\n this._handlers = {};\n this._wiredEventDispatchers = [];\n this._deferedHandlerRemovals = [];\n }\n /**\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\n */ clear() {\n this._handlers = {};\n this._wiredEventDispatchers = [];\n }\n _processDeferredHandlerRemovals() {\n for (const eventHandler of this._deferedHandlerRemovals)this._removeHandler(eventHandler.name, eventHandler.handler);\n this._deferedHandlerRemovals.length = 0;\n }\n /**\n * Emits an event for target\n * @param eventName The name of the event to publish\n * @param event Optionally pass an event data object to the handler\n */ emit(eventName, event) {\n this._processDeferredHandlerRemovals();\n if (!eventName) // key not mapped\n return;\n eventName = eventName.toLowerCase();\n if (typeof event === \"undefined\" || event === null) event = new GameEvent();\n let i, len;\n if (this._handlers[eventName]) {\n i = 0;\n len = this._handlers[eventName].length;\n for(i; i < len; i++)this._handlers[eventName][i](event);\n }\n i = 0;\n len = this._wiredEventDispatchers.length;\n for(i; i < len; i++)this._wiredEventDispatchers[i].emit(eventName, event);\n }\n /**\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\n * @param eventName The name of the event to subscribe to\n * @param handler The handler callback to fire on this event\n */ on(eventName, handler) {\n this._processDeferredHandlerRemovals();\n eventName = eventName.toLowerCase();\n if (!this._handlers[eventName]) this._handlers[eventName] = [];\n this._handlers[eventName].push(handler);\n }\n /**\n * Unsubscribe an event handler(s) from an event. If a specific handler\n * is specified for an event, only that handler will be unsubscribed.\n * Otherwise all handlers will be unsubscribed for that event.\n * @param eventName The name of the event to unsubscribe\n * @param handler Optionally the specific handler to unsubscribe\n */ off(eventName, handler) {\n this._deferedHandlerRemovals.push({\n name: eventName,\n handler: handler\n });\n }\n _removeHandler(eventName, handler) {\n eventName = eventName.toLowerCase();\n const eventHandlers = this._handlers[eventName];\n if (eventHandlers) {\n // if no explicit handler is give with the event name clear all handlers\n if (!handler) this._handlers[eventName].length = 0;\n else {\n const index = eventHandlers.indexOf(handler);\n if (index > -1) this._handlers[eventName].splice(index, 1);\n }\n }\n }\n /**\n * Once listens to an event one time, then unsubscribes from that event\n * @param eventName The name of the event to subscribe to once\n * @param handler The handler of the event that will be auto unsubscribed\n */ once(eventName, handler) {\n this._processDeferredHandlerRemovals();\n const metaHandler = (event)=>{\n const ev = event || new GameEvent();\n this.off(eventName, metaHandler);\n handler(ev);\n };\n this.on(eventName, metaHandler);\n }\n /**\n * Wires this event dispatcher to also receive events from another\n */ wire(eventDispatcher) {\n eventDispatcher._wiredEventDispatchers.push(this);\n }\n /**\n * Unwires this event dispatcher from another\n */ unwire(eventDispatcher) {\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\n if (index > -1) eventDispatcher._wiredEventDispatchers.splice(index, 1);\n }\n }\n /**\n * Labels are the way to draw small amounts of text to the screen. They are\n * actors and inherit all of the benefits and capabilities.\n */ class Label extends Actor {\n get font() {\n return this._font;\n }\n set font(newFont) {\n this._font = newFont;\n this._text.font = newFont;\n }\n /**\n * The text to draw.\n */ get text() {\n return this._text.text;\n }\n set text(text) {\n this._text.text = text;\n }\n get color() {\n return this._text.color;\n }\n set color(color) {\n if (this._text) this._text.color = color;\n }\n get opacity() {\n return this._text.opacity;\n }\n set opacity(opacity) {\n this._text.opacity = opacity;\n }\n /**\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\n */ get spriteFont() {\n return this._spriteFont;\n }\n set spriteFont(sf) {\n if (sf) {\n this._spriteFont = sf;\n this._text.font = this._spriteFont;\n }\n }\n /**\n * Build a new label\n * @param options\n */ constructor(options){\n super(options);\n this._font = new Font();\n this._text = new Text({\n text: \"\",\n font: this._font\n });\n const { text: text, pos: pos, x: x, y: y, spriteFont: spriteFont, font: font, color: color } = {\n text: \"\",\n ...options\n };\n this.pos = pos !== null && pos !== void 0 ? pos : x && y ? vec(x, y) : this.pos;\n this.text = text !== null && text !== void 0 ? text : this.text;\n this.font = font !== null && font !== void 0 ? font : this.font;\n this.spriteFont = spriteFont !== null && spriteFont !== void 0 ? spriteFont : this.spriteFont;\n this._text.color = color !== null && color !== void 0 ? color : this.color;\n const gfx = this.get(GraphicsComponent);\n gfx.anchor = Vector.Zero;\n gfx.use(this._text);\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n /**\n * Returns the width of the text in the label (in pixels);\n */ getTextWidth() {\n return this._text.width;\n }\n }\n class IsometricTile extends Entity {\n getGraphics() {\n return this._graphics;\n }\n /**\n * Tile graphics\n */ addGraphic(graphic, options) {\n this._graphics.push(graphic);\n this._gfx.visible = this.map.visible;\n this._gfx.opacity = this.map.opacity;\n if (options === null || options === void 0 ? void 0 : options.offset) this._gfx.offset = options.offset;\n // TODO detect when this changes on the map and apply to all tiles\n this._gfx.localBounds = this._recalculateBounds();\n }\n _recalculateBounds() {\n let bounds = this._tileBounds.clone();\n for (const graphic of this._graphics){\n const offset = vec(this.map.graphicsOffset.x - this.map.tileWidth / 2, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : graphic.height - this.map.tileHeight));\n bounds = bounds.combine(graphic.localBounds.translate(offset));\n }\n return bounds;\n }\n removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) this._graphics.splice(index, 1);\n this._gfx.localBounds = this._recalculateBounds();\n }\n clearGraphics() {\n this._graphics.length = 0;\n this._gfx.visible = false;\n this._gfx.localBounds = this._recalculateBounds();\n }\n getColliders() {\n return this._colliders;\n }\n /**\n * Adds a collider to the IsometricTile\n *\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\n * @param collider\n */ addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\n * Removes a collider from the IsometricTile\n * @param collider\n */ removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) this._colliders.splice(index, 1);\n this.map.flagCollidersDirty();\n }\n /**\n * Clears all colliders from the IsometricTile\n */ clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n /**\n * Returns the top left corner of the [[IsometricTile]] in world space\n */ get pos() {\n return this.map.tileToWorld(vec(this.x, this.y));\n }\n /**\n * Returns the center of the [[IsometricTile]]\n */ get center() {\n return this.pos.add(vec(0, this.map.tileHeight / 2));\n }\n /**\n * Construct a new IsometricTile\n * @param x tile coordinate in x (not world position)\n * @param y tile coordinate in y (not world position)\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\n * @param map reference to owning IsometricMap\n */ constructor(x, y, graphicsOffset, map){\n super([\n new TransformComponent(),\n new GraphicsComponent({\n offset: graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : Vector.Zero,\n onPostDraw: (gfx, elapsed)=>this.draw(gfx, elapsed)\n }),\n new IsometricEntityComponent(map)\n ]);\n /**\n * Indicates whether this tile is solid\n */ this.solid = false;\n this._tileBounds = new BoundingBox();\n this._graphics = [];\n /**\n * Tile colliders\n */ this._colliders = [];\n /**\n * Arbitrary data storage per tile, useful for any game specific data\n */ this.data = new Map();\n this.x = x;\n this.y = y;\n this.map = map;\n this._transform = this.get(TransformComponent);\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\n const halfTileWidth = this.map.tileWidth / 2;\n const halfTileHeight = this.map.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n // The x position shifts left with every y step\n const xPos = (this.x - this.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (this.x + this.y) * halfTileHeight;\n this._transform.pos = vec(xPos, yPos);\n this._isometricEntityComponent.elevation = map.elevation;\n this._gfx = this.get(GraphicsComponent);\n this._gfx.visible = false; // start not visible\n const totalWidth = this.map.tileWidth;\n const totalHeight = this.map.tileHeight;\n // initial guess at gfx bounds based on the tile\n const offset = vec(0, this.map.renderFromTopOfGraphic ? totalHeight : 0);\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\n left: -totalWidth / 2,\n top: -totalHeight,\n right: totalWidth / 2,\n bottom: totalHeight\n }).translate(offset);\n }\n draw(gfx, _elapsed) {\n const halfTileWidth = this.map.tileWidth / 2;\n gfx.save();\n // shift left origin to corner of map, not the left corner of the first sprite\n gfx.translate(-halfTileWidth, 0);\n for (const graphic of this._graphics)graphic.draw(gfx, this.map.graphicsOffset.x, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : graphic.height - this.map.tileHeight));\n gfx.restore();\n }\n }\n /**\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\n *\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\n *\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\n * your art assets.\n */ class IsometricMap extends Entity {\n constructor(options){\n super([\n new TransformComponent(),\n new BodyComponent({\n type: CollisionType.Fixed\n }),\n new ColliderComponent(),\n new DebugGraphicsComponent((ctx, debugFlags)=>this.debug(ctx, debugFlags), false)\n ], options.name);\n this.elevation = 0;\n /**\n * Whether tiles should be visible\n */ this.visible = true;\n /**\n * Opacity of tiles\n */ this.opacity = 1.0;\n /**\n * Render the tile graphic from the top instead of the bottom\n *\n * default is `false` meaning rendering from the bottom\n */ this.renderFromTopOfGraphic = false;\n this.graphicsOffset = vec(0, 0);\n this._collidersDirty = false;\n this._originalOffsets = new WeakMap();\n const { pos: pos, tileWidth: tileWidth, tileHeight: tileHeight, columns: width, rows: height, renderFromTopOfGraphic: renderFromTopOfGraphic, graphicsOffset: graphicsOffset, elevation: elevation } = options;\n this.transform = this.get(TransformComponent);\n if (pos) this.transform.pos = pos;\n this.collider = this.get(ColliderComponent);\n if (this.collider) this.collider.set(this._composite = new CompositeCollider([]));\n this.renderFromTopOfGraphic = renderFromTopOfGraphic !== null && renderFromTopOfGraphic !== void 0 ? renderFromTopOfGraphic : this.renderFromTopOfGraphic;\n this.graphicsOffset = graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : this.graphicsOffset;\n this.elevation = elevation !== null && elevation !== void 0 ? elevation : this.elevation;\n this.tileWidth = tileWidth;\n this.tileHeight = tileHeight;\n this.columns = width;\n this.rows = height;\n this.tiles = new Array(width * height);\n // build up tile representation\n for(let y = 0; y < height; y++)for(let x = 0; x < width; x++){\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\n this.tiles[x + y * width] = tile;\n this.addChild(tile);\n }\n }\n update() {\n if (this._collidersDirty) {\n this.updateColliders();\n this._collidersDirty = false;\n }\n }\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n } else return this._originalOffsets.get(collider);\n }\n updateColliders() {\n this._composite.clearColliders();\n const pos = this.get(TransformComponent).pos;\n for (const tile of this.tiles){\n if (tile.solid) for (const collider of tile.getColliders()){\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = this.tileToWorld(vec(tile.x, tile.y)).sub(pos).add(originalOffset).sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n }\n this.collider.update();\n }\n /**\n * Convert world space coordinates to the tile x, y coordinate\n * @param worldCoordinate\n */ worldToTile(worldCoordinate) {\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n return vec(~~((worldCoordinate.x / halfTileWidth + worldCoordinate.y / halfTileHeight) / 2), ~~((worldCoordinate.y / halfTileHeight - worldCoordinate.x / halfTileWidth) / 2));\n }\n /**\n * Given a tile coordinate, return the top left corner in world space\n * @param tileCoordinate\n */ tileToWorld(tileCoordinate) {\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // The x position shifts left with every y step\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\n return vec(xPos, yPos).add(this.transform.pos);\n }\n /**\n * Returns the [[IsometricTile]] by its x and y coordinates\n */ getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) return null;\n return this.tiles[x + y * this.columns];\n }\n /**\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\n * returns `null` if no Tile was found.\n */ getTileByPoint(point) {\n const tileCoord = this.worldToTile(point);\n const tile = this.getTile(tileCoord.x, tileCoord.y);\n return tile;\n }\n _getMaxZIndex() {\n let maxZ = Number.NEGATIVE_INFINITY;\n for (const tile of this.tiles){\n const currentZ = tile.get(TransformComponent).z;\n if (currentZ > maxZ) maxZ = currentZ;\n }\n return maxZ;\n }\n /**\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\n * @param gfx\n */ debug(gfx, debugFlags) {\n const { showAll: showAll, showPosition: showPosition, positionColor: positionColor, positionSize: positionSize, showGrid: showGrid, gridColor: gridColor, gridWidth: gridWidth, showColliderGeometry: showColliderGeometry } = debugFlags.isometric;\n const { geometryColor: geometryColor, geometryLineWidth: geometryLineWidth, geometryPointSize: geometryPointSize } = debugFlags.collider;\n gfx.save();\n gfx.z = this._getMaxZIndex() + 0.5;\n if (showAll || showGrid) {\n for(let y = 0; y < this.rows + 1; y++){\n const left = this.tileToWorld(vec(0, y));\n const right = this.tileToWorld(vec(this.columns, y));\n gfx.drawLine(left, right, gridColor, gridWidth);\n }\n for(let x = 0; x < this.columns + 1; x++){\n const top = this.tileToWorld(vec(x, 0));\n const bottom = this.tileToWorld(vec(x, this.rows));\n gfx.drawLine(top, bottom, gridColor, gridWidth);\n }\n }\n if (showAll || showPosition) for (const tile of this.tiles)gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), positionSize, positionColor);\n if (showAll || showColliderGeometry) for (const tile of this.tiles){\n if (tile.solid) for (const collider of tile.getColliders())collider.debug(gfx, geometryColor, {\n lineWidth: geometryLineWidth,\n pointSize: geometryPointSize\n });\n }\n gfx.restore();\n }\n }\n /**\n * Action that can represent a sequence of actions, this can be useful in conjunction with\n * [[ParallelActions]] to run multiple sequences in parallel.\n */ class ActionSequence {\n constructor(entity, actionBuilder){\n this._stopped = false;\n this._sequenceBuilder = actionBuilder;\n this._sequenceContext = new ActionContext(entity);\n this._actionQueue = this._sequenceContext.getQueue();\n this._sequenceBuilder(this._sequenceContext);\n }\n update(delta) {\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || this._actionQueue.isComplete();\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._stopped = false;\n this._actionQueue.reset();\n }\n clone(entity) {\n return new ActionSequence(entity, this._sequenceBuilder);\n }\n }\n /**\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\n */ class ParallelActions {\n constructor(parallelActions){\n this._actions = parallelActions;\n }\n update(delta) {\n for(let i = 0; i < this._actions.length; i++)this._actions[i].update(delta);\n }\n isComplete(entity) {\n return this._actions.every((a)=>a.isComplete(entity));\n }\n reset() {\n this._actions.forEach((a)=>a.reset());\n }\n stop() {\n this._actions.forEach((a)=>a.stop());\n }\n }\n /**\n * QuadTree spatial data structure. Useful for quickly retrieving all objects that might\n * be in a specific location.\n */ class QuadTree {\n constructor(bounds, options){\n this.bounds = bounds;\n this.options = options;\n this._defaultOptions = {\n maxDepth: 10,\n capacity: 10,\n level: 0\n };\n this.items = [];\n this._isDivided = false;\n this.topLeft = null;\n this.topRight = null;\n this.bottomLeft = null;\n this.bottomRight = null;\n this.options = {\n ...this._defaultOptions,\n ...options\n };\n this.halfWidth = bounds.width / 2;\n this.halfHeight = bounds.height / 2;\n }\n /**\n * Splits the quad tree one level deeper\n */ _split() {\n this._isDivided = true;\n const newLevelOptions = {\n maxDepth: this.options.maxDepth,\n capacity: this.options.capacity,\n level: this.options.level + 1\n };\n this.topLeft = new QuadTree(new BoundingBox({\n left: this.bounds.left,\n top: this.bounds.top,\n right: this.bounds.left + this.halfWidth,\n bottom: this.bounds.top + this.halfHeight\n }), newLevelOptions);\n this.topRight = new QuadTree(new BoundingBox({\n left: this.bounds.left + this.halfWidth,\n top: this.bounds.top,\n right: this.bounds.right,\n bottom: this.bounds.top + this.halfHeight\n }), newLevelOptions);\n this.bottomLeft = new QuadTree(new BoundingBox({\n left: this.bounds.left,\n top: this.bounds.top + this.halfHeight,\n right: this.bounds.left + this.halfWidth,\n bottom: this.bounds.bottom\n }), newLevelOptions);\n this.bottomRight = new QuadTree(new BoundingBox({\n left: this.bounds.left + this.halfWidth,\n top: this.bounds.top + this.halfHeight,\n right: this.bounds.right,\n bottom: this.bounds.bottom\n }), newLevelOptions);\n }\n _insertIntoSubNodes(item) {\n var _a, _b, _c, _d;\n if ((_a = this.topLeft) === null || _a === void 0 ? void 0 : _a.bounds.overlaps(item.bounds)) this.topLeft.insert(item);\n if ((_b = this.topRight) === null || _b === void 0 ? void 0 : _b.bounds.overlaps(item.bounds)) this.topRight.insert(item);\n if ((_c = this.bottomLeft) === null || _c === void 0 ? void 0 : _c.bounds.overlaps(item.bounds)) this.bottomLeft.insert(item);\n if ((_d = this.bottomRight) === null || _d === void 0 ? void 0 : _d.bounds.overlaps(item.bounds)) this.bottomRight.insert(item);\n }\n /**\n * Insert an item to be tracked in the QuadTree\n * @param item\n */ insert(item) {\n // add to subnodes if it matches\n if (this._isDivided) {\n this._insertIntoSubNodes(item);\n return;\n }\n // leaf case\n this.items.push(item);\n // capacity\n if (this.items.length > this.options.capacity && this.options.level < this.options.maxDepth) {\n if (!this._isDivided) this._split();\n // divide this level's items into it's subnodes\n for (const item of this.items)this._insertIntoSubNodes(item);\n // clear this level\n this.items.length = 0;\n }\n }\n /**\n * Remove a tracked item in the QuadTree\n * @param item\n */ remove(item) {\n var _a, _b, _c, _d;\n if (!this.bounds.overlaps(item.bounds)) return;\n if (!this._isDivided) {\n const index = this.items.indexOf(item);\n if (index > -1) this.items.splice(index, 1);\n return;\n }\n if ((_a = this.topLeft) === null || _a === void 0 ? void 0 : _a.bounds.overlaps(item.bounds)) this.topLeft.remove(item);\n if ((_b = this.topRight) === null || _b === void 0 ? void 0 : _b.bounds.overlaps(item.bounds)) this.topRight.remove(item);\n if ((_c = this.bottomLeft) === null || _c === void 0 ? void 0 : _c.bounds.overlaps(item.bounds)) this.bottomLeft.remove(item);\n if ((_d = this.bottomRight) === null || _d === void 0 ? void 0 : _d.bounds.overlaps(item.bounds)) this.bottomRight.remove(item);\n }\n /**\n * Query the structure for all objects that intersect the bounding box\n * @param boundingBox\n * @returns items\n */ query(boundingBox) {\n let results = this.items;\n if (this._isDivided) {\n if (this.topLeft.bounds.overlaps(boundingBox)) results = results.concat(this.topLeft.query(boundingBox));\n if (this.topRight.bounds.overlaps(boundingBox)) results = results.concat(this.topRight.query(boundingBox));\n if (this.bottomLeft.bounds.overlaps(boundingBox)) results = results.concat(this.bottomLeft.query(boundingBox));\n if (this.bottomRight.bounds.overlaps(boundingBox)) results = results.concat(this.bottomRight.query(boundingBox));\n }\n results = results.filter((item, index)=>{\n return results.indexOf(item) >= index;\n });\n return results;\n }\n clear() {\n this.items = [];\n this._isDivided = false;\n this.topLeft = null;\n this.topRight = null;\n this.bottomLeft = null;\n this.bottomRight = null;\n }\n getAllItems() {\n let results = this.items;\n if (this._isDivided) {\n results = results.concat(this.topLeft.getAllItems());\n results = results.concat(this.topRight.getAllItems());\n results = results.concat(this.bottomLeft.getAllItems());\n results = results.concat(this.bottomRight.getAllItems());\n }\n results = results.filter((item, index)=>{\n return results.indexOf(item) >= index;\n });\n return results;\n }\n getTreeDepth() {\n if (!this._isDivided) return 0;\n return 1 + Math.max(this.topLeft.getTreeDepth(), this.topRight.getTreeDepth(), this.bottomLeft.getTreeDepth(), this.bottomRight.getTreeDepth());\n }\n debug(ctx) {\n this.bounds.draw(ctx, Color.Yellow);\n if (this._isDivided) {\n this.topLeft.bounds.draw(ctx, Color.Yellow);\n this.topRight.bounds.draw(ctx, Color.Yellow);\n this.bottomLeft.bounds.draw(ctx, Color.Yellow);\n this.bottomRight.bounds.draw(ctx, Color.Yellow);\n }\n }\n }\n /**\n * Type guard checking for internal initialize method\n * @internal\n * @param a\n */ function has_initialize(a) {\n return !!a._initialize;\n }\n /**\n *\n */ function hasOnInitialize(a) {\n return !!a.onInitialize;\n }\n /**\n *\n */ function has_preupdate(a) {\n return !!a._preupdate;\n }\n /**\n *\n */ function hasOnPreUpdate(a) {\n return !!a.onPreUpdate;\n }\n /**\n *\n */ function has_postupdate(a) {\n return !!a.onPostUpdate;\n }\n /**\n *\n */ function hasOnPostUpdate(a) {\n return !!a.onPostUpdate;\n }\n /**\n *\n */ function hasPreDraw(a) {\n return !!a.onPreDraw;\n }\n /**\n *\n */ function hasPostDraw(a) {\n return !!a.onPostDraw;\n }\n /**\n * The [[Texture]] object allows games built in Excalibur to load image resources.\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\n * to pre-load before starting a level or game.\n */ class Gif {\n /**\n * @param path Path to the image resource\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\n * @param bustCache Optionally load texture with cache busting\n */ constructor(path, color = Color.Magenta, bustCache = false){\n this.path = path;\n this.color = color;\n this._stream = null;\n this._gif = null;\n this._textures = [];\n this._animation = null;\n this._transparentColor = null;\n this._resource = new Resource(path, \"arraybuffer\", bustCache);\n this._transparentColor = color;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * Begins loading the texture and returns a promise to be resolved on completion\n */ async load() {\n const arraybuffer = await this._resource.load();\n this._stream = new Stream(arraybuffer);\n this._gif = new ParseGif(this._stream, this._transparentColor);\n const images = this._gif.images.map((i)=>new ImageSource(i.src, false));\n // Load all textures\n await Promise.all(images.map((t)=>t.load()));\n return this.data = this._textures = images;\n }\n isLoaded() {\n return !!this.data;\n }\n /**\n * Return a frame of the gif as a sprite by id\n * @param id\n */ toSprite(id = 0) {\n const sprite = this._textures[id].toSprite();\n return sprite;\n }\n /**\n * Return the gif as a spritesheet\n */ toSpriteSheet() {\n const sprites = this._textures.map((image)=>{\n return image.toSprite();\n });\n return new SpriteSheet({\n sprites: sprites\n });\n }\n /**\n * Transform the GIF into an animation with duration per frame\n */ toAnimation(durationPerFrameMs) {\n const spriteSheet = this.toSpriteSheet();\n const length = spriteSheet.sprites.length;\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\n return this._animation;\n }\n get readCheckBytes() {\n return this._gif.checkBytes;\n }\n }\n const bitsToNum = (ba)=>{\n return ba.reduce(function(s, n) {\n return s * 2 + n;\n }, 0);\n };\n const byteToBitArr = (bite)=>{\n const a = [];\n for(let i = 7; i >= 0; i--)a.push(!!(bite & 1 << i));\n return a;\n };\n class Stream {\n constructor(dataArray){\n this.data = null;\n this.len = 0;\n this.position = 0;\n this.readByte = ()=>{\n if (this.position >= this.data.byteLength) throw new Error(\"Attempted to read past end of stream.\");\n return this.data[this.position++];\n };\n this.readBytes = (n)=>{\n const bytes = [];\n for(let i = 0; i < n; i++)bytes.push(this.readByte());\n return bytes;\n };\n this.read = (n)=>{\n let s = \"\";\n for(let i = 0; i < n; i++)s += String.fromCharCode(this.readByte());\n return s;\n };\n this.readUnsigned = ()=>{\n // Little-endian.\n const a = this.readBytes(2);\n return (a[1] << 8) + a[0];\n };\n this.data = new Uint8Array(dataArray);\n this.len = this.data.byteLength;\n if (this.len === 0) throw new Error(\"No data loaded from file\");\n }\n }\n const lzwDecode = function(minCodeSize, data) {\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\n const readCode = function(size) {\n let code = 0;\n for(let i = 0; i < size; i++){\n if (data.charCodeAt(pos >> 3) & 1 << (pos & 7)) code |= 1 << i;\n pos++;\n }\n return code;\n };\n const output = [];\n const clearCode = 1 << minCodeSize;\n const eoiCode = clearCode + 1;\n let codeSize = minCodeSize + 1;\n let dict = [];\n const clear = function() {\n dict = [];\n codeSize = minCodeSize + 1;\n for(let i = 0; i < clearCode; i++)dict[i] = [\n i\n ];\n dict[clearCode] = [];\n dict[eoiCode] = null;\n };\n let code;\n let last;\n while(true){\n last = code;\n code = readCode(codeSize);\n if (code === clearCode) {\n clear();\n continue;\n }\n if (code === eoiCode) break;\n if (code < dict.length) {\n if (last !== clearCode) dict.push(dict[last].concat(dict[code][0]));\n } else {\n if (code !== dict.length) throw new Error(\"Invalid LZW code.\");\n dict.push(dict[last].concat(dict[last][0]));\n }\n output.push.apply(output, dict[code]);\n if (dict.length === 1 << codeSize && codeSize < 12) // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\n codeSize++;\n }\n // I don't know if this is technically an error, but some GIFs do it.\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\n return output;\n };\n // The actual parsing; returns an object with properties.\n class ParseGif {\n constructor(stream, color = Color.Magenta){\n this._st = null;\n this._handler = {};\n this._transparentColor = null;\n this.frames = [];\n this.images = [];\n this.globalColorTable = [];\n this.checkBytes = [];\n // LZW (GIF-specific)\n this.parseColorTable = (entries)=>{\n // Each entry is 3 bytes, for RGB.\n const ct = [];\n for(let i = 0; i < entries; i++){\n const rgb = this._st.readBytes(3);\n const rgba = \"#\" + rgb.map((x)=>{\n const hex = x.toString(16);\n return hex.length === 1 ? \"0\" + hex : hex;\n }).join(\"\");\n ct.push(rgba);\n }\n return ct;\n };\n this.readSubBlocks = ()=>{\n let size, data;\n data = \"\";\n do {\n size = this._st.readByte();\n data += this._st.read(size);\n }while (size !== 0);\n return data;\n };\n this.parseHeader = ()=>{\n const hdr = {\n sig: null,\n ver: null,\n width: null,\n height: null,\n colorRes: null,\n globalColorTableSize: null,\n gctFlag: null,\n sorted: null,\n globalColorTable: [],\n bgColor: null,\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n };\n hdr.sig = this._st.read(3);\n hdr.ver = this._st.read(3);\n if (hdr.sig !== \"GIF\") throw new Error(\"Not a GIF file.\"); // XXX: This should probably be handled more nicely.\n hdr.width = this._st.readUnsigned();\n hdr.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n hdr.gctFlag = bits.shift();\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\n hdr.sorted = bits.shift();\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\n hdr.bgColor = this._st.readByte();\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n if (hdr.gctFlag) {\n hdr.globalColorTable = this.parseColorTable(1 << hdr.globalColorTableSize + 1);\n this.globalColorTable = hdr.globalColorTable;\n }\n if (this._handler.hdr && this._handler.hdr(hdr)) this.checkBytes.push(this._handler.hdr);\n };\n this.parseExt = (block)=>{\n const parseGCExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 4\n const bits = byteToBitArr(this._st.readByte());\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\n block.userInput = bits.shift();\n block.transparencyGiven = bits.shift();\n block.delayTime = this._st.readUnsigned();\n block.transparencyIndex = this._st.readByte();\n block.terminator = this._st.readByte();\n if (this._handler.gce && this._handler.gce(block)) this.checkBytes.push(this._handler.gce);\n };\n const parseComExt = (block)=>{\n block.comment = this.readSubBlocks();\n if (this._handler.com && this._handler.com(block)) this.checkBytes.push(this._handler.com);\n };\n const parsePTExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 12\n block.ptHeader = this._st.readBytes(12);\n block.ptData = this.readSubBlocks();\n if (this._handler.pte && this._handler.pte(block)) this.checkBytes.push(this._handler.pte);\n };\n const parseAppExt = (block)=>{\n const parseNetscapeExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 3\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\n block.iterations = this._st.readUnsigned();\n block.terminator = this._st.readByte();\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) this.checkBytes.push(this._handler.app);\n };\n const parseUnknownAppExt = (block)=>{\n block.appData = this.readSubBlocks();\n // FIXME: This won't work if a handler wants to match on any identifier.\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) this.checkBytes.push(this._handler.app[block.identifier]);\n };\n this.checkBytes.push(this._st.readByte()); // Always 11\n block.identifier = this._st.read(8);\n block.authCode = this._st.read(3);\n switch(block.identifier){\n case \"NETSCAPE\":\n parseNetscapeExt(block);\n break;\n default:\n parseUnknownAppExt(block);\n break;\n }\n };\n const parseUnknownExt = (block)=>{\n block.data = this.readSubBlocks();\n if (this._handler.unknown && this._handler.unknown(block)) this.checkBytes.push(this._handler.unknown);\n };\n block.label = this._st.readByte();\n switch(block.label){\n case 0xf9:\n block.extType = \"gce\";\n parseGCExt(block);\n break;\n case 0xfe:\n block.extType = \"com\";\n parseComExt(block);\n break;\n case 0x01:\n block.extType = \"pte\";\n parsePTExt(block);\n break;\n case 0xff:\n block.extType = \"app\";\n parseAppExt(block);\n break;\n default:\n block.extType = \"unknown\";\n parseUnknownExt(block);\n break;\n }\n };\n this.parseImg = (img)=>{\n const deinterlace = (pixels, width)=>{\n // Of course this defeats the purpose of interlacing. And it's *probably*\n // the least efficient way it's ever been implemented. But nevertheless...\n const newPixels = new Array(pixels.length);\n const rows = pixels.length / width;\n const cpRow = (toRow, fromRow)=>{\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\n newPixels.splice.apply(newPixels, [\n toRow * width,\n width\n ].concat(fromPixels));\n };\n const offsets = [\n 0,\n 4,\n 2,\n 1\n ];\n const steps = [\n 8,\n 8,\n 4,\n 2\n ];\n let fromRow = 0;\n for(let pass = 0; pass < 4; pass++)for(let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]){\n cpRow(toRow, fromRow);\n fromRow++;\n }\n return newPixels;\n };\n img.leftPos = this._st.readUnsigned();\n img.topPos = this._st.readUnsigned();\n img.width = this._st.readUnsigned();\n img.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n img.lctFlag = bits.shift();\n img.interlaced = bits.shift();\n img.sorted = bits.shift();\n img.reserved = bits.splice(0, 2);\n img.lctSize = bitsToNum(bits.splice(0, 3));\n if (img.lctFlag) img.lct = this.parseColorTable(1 << img.lctSize + 1);\n img.lzwMinCodeSize = this._st.readByte();\n const lzwData = this.readSubBlocks();\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\n if (img.interlaced) // Move\n img.pixels = deinterlace(img.pixels, img.width);\n this.frames.push(img);\n this.arrayToImage(img);\n if (this._handler.img && this._handler.img(img)) this.checkBytes.push(this._handler);\n };\n this.parseBlock = ()=>{\n const block = {\n sentinel: this._st.readByte(),\n type: \"\"\n };\n const blockChar = String.fromCharCode(block.sentinel);\n switch(blockChar){\n case \"!\":\n block.type = \"ext\";\n this.parseExt(block);\n break;\n case \",\":\n block.type = \"img\";\n this.parseImg(block);\n break;\n case \";\":\n block.type = \"eof\";\n if (this._handler.eof && this._handler.eof(block)) this.checkBytes.push(this._handler.eof);\n break;\n default:\n throw new Error(\"Unknown block: 0x\" + block.sentinel.toString(16));\n }\n if (block.type !== \"eof\") this.parseBlock();\n };\n this.arrayToImage = (frame)=>{\n let count = 0;\n const c = document.createElement(\"canvas\");\n c.id = count.toString();\n c.width = frame.width;\n c.height = frame.height;\n count++;\n const context = c.getContext(\"2d\");\n const pixSize = 1;\n let y = 0;\n let x = 0;\n for(let i = 0; i < frame.pixels.length; i++){\n if (x % frame.width === 0) {\n y++;\n x = 0;\n }\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) context.fillStyle = `rgba(0, 0, 0, 0)`;\n else context.fillStyle = this.globalColorTable[frame.pixels[i]];\n context.fillRect(x, y, pixSize, pixSize);\n x++;\n }\n const img = new Image();\n img.src = c.toDataURL();\n this.images.push(img);\n };\n this._st = stream;\n this._handler = {};\n this._transparentColor = color;\n this.parseHeader();\n this.parseBlock();\n }\n }\n class FontSource {\n constructor(/**\n * Path to the font resource relative from the HTML document hosting the game, or absolute\n */ path, /**\n * The font family name\n */ family, { bustCache: bustCache, ...options } = {}){\n this.path = path;\n this.family = family;\n this._isLoaded = false;\n this._resource = new Resource(path, \"blob\", bustCache);\n this._options = options;\n }\n async load() {\n if (this.isLoaded()) return this.data;\n try {\n const blob = await this._resource.load();\n const url = URL.createObjectURL(blob);\n if (!this.data) {\n this.data = new FontFace(this.family, `url(${url})`);\n document.fonts.add(this.data);\n }\n await this.data.load();\n this._isLoaded = true;\n } catch (error) {\n throw `Error loading FontSource from path '${this.path}' with error [${error.message}]`;\n }\n return this.data;\n }\n isLoaded() {\n return this._isLoaded;\n }\n /**\n * Build a font from this FontSource.\n * @param options {FontOptions} Override the font options\n */ toFont(options) {\n return new Font({\n family: this.family,\n ...this._options,\n ...options\n });\n }\n }\n /**\n * Excalibur coroutine helper, returns a promise when complete. Coroutines run before frame update.\n *\n * Each coroutine yield is 1 excalibur frame. Coroutines get passed the elapsed time our of yield. Coroutines\n * run internally on the excalibur clock.\n *\n * If you yield a promise it will be awaited before resumed\n * If you yield a number it will wait that many ms before resumed\n * @param engine\n * @param coroutineGenerator\n */ function coroutine(engine, coroutineGenerator) {\n return new Promise((resolve, reject)=>{\n const generator = coroutineGenerator();\n const loop = (elapsedMs)=>{\n try {\n const { done: done, value: value } = generator.next(elapsedMs);\n if (done) resolve();\n if (value instanceof Promise) value.then(()=>{\n // schedule next loop\n engine.clock.schedule(loop);\n });\n else if (value === undefined || value === void 0) // schedule next frame\n engine.clock.schedule(loop);\n else // schedule value milliseconds from now\n engine.clock.schedule(loop, value || 0);\n } catch (e) {\n reject(e);\n }\n };\n loop(engine.clock.elapsed()); // run first frame immediately\n });\n }\n /**\n * Base Transition that can be extended to provide custom scene transitions in Excalibur.\n */ class Transition extends Entity {\n /**\n * Returns a number between [0, 1] indicating what state the transition is in.\n *\n * * For 'out' direction transitions start at 0 and end at 1\n * * For 'in' direction transitions start at 1 and end at 0\n */ get progress() {\n return this._currentProgress;\n }\n get complete() {\n if (this.direction === \"out\") return this.progress >= 1;\n else return this.progress <= 0;\n }\n constructor(options){\n var _a, _b, _c, _d;\n super();\n this._logger = Logger.getInstance();\n this.transform = new TransformComponent();\n this.graphics = new GraphicsComponent();\n this._completeFuture = new Future();\n // State needs to be reset between uses\n this.started = false;\n this._currentDistance = 0;\n this._currentProgress = 0;\n this.done = this._completeFuture.promise;\n this.name = `Transition#${this.id}`;\n this.duration = options.duration;\n this.easing = (_a = options.easing) !== null && _a !== void 0 ? _a : EasingFunctions.Linear;\n this.direction = (_b = options.direction) !== null && _b !== void 0 ? _b : \"out\";\n this.hideLoader = (_c = options.hideLoader) !== null && _c !== void 0 ? _c : false;\n this.blockInput = (_d = options.blockInput) !== null && _d !== void 0 ? _d : false;\n this.transform.coordPlane = CoordPlane.Screen;\n this.transform.pos = Vector.Zero;\n this.transform.z = Infinity; // Transitions sit on top of everything\n this.graphics.anchor = Vector.Zero;\n this.addComponent(this.transform);\n this.addComponent(this.graphics);\n if (this.direction === \"out\") this._currentProgress = 0;\n else this._currentProgress = 1;\n }\n /**\n * Overridable lifecycle method, called before each update.\n *\n * **WARNING BE SURE** to call `super.updateTransition()` if overriding in your own custom implementation\n * @param engine\n * @param delta\n */ updateTransition(engine, delta) {\n if (this.complete) return;\n this._currentDistance += clamp(delta / this.duration, 0, 1);\n if (this._currentDistance >= 1) this._currentDistance = 1;\n if (this.direction === \"out\") this._currentProgress = clamp(this.easing(this._currentDistance, 0, 1, 1), 0, 1);\n else this._currentProgress = clamp(this.easing(this._currentDistance, 1, 0, 1), 0, 1);\n }\n /**\n * Overridable lifecycle method, called right before the previous scene has deactivated.\n *\n * This gives incoming transition a chance to grab info from previous scene if desired\n * @param scene\n */ async onPreviousSceneDeactivate(scene) {\n // override me\n }\n /**\n * Overridable lifecycle method, called once at the beginning of the transition\n *\n * `progress` is given between 0 and 1\n * @param progress\n */ onStart(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called every frame of the transition\n *\n * `progress` is given between 0 and 1\n * @param progress\n */ onUpdate(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called at the end of the transition,\n *\n * `progress` is given between 0 and 1\n * @param progress\n */ onEnd(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called when the transition is reset\n *\n * Use this to override and provide your own reset logic for internal state in custom transition implementations\n */ onReset() {\n // override me\n }\n /**\n * reset() is called by the engine to reset transitions\n */ reset() {\n this.started = false;\n this._completeFuture = new Future();\n this.done = this._completeFuture.promise;\n this._currentDistance = 0;\n if (this.direction === \"out\") this._currentProgress = 0;\n else this._currentProgress = 1;\n this.onReset();\n }\n play(engine) {\n if (this.started) {\n this._logger.warn(`Attempted to play a transition ${this.name} that is already playing`);\n return Promise.resolve();\n }\n engine.add(this);\n const self1 = this;\n return coroutine(engine, function*() {\n while(!self1.complete){\n const elapsed = yield; // per frame\n self1.updateTransition(engine, elapsed);\n self1.execute();\n }\n });\n }\n /**\n * execute() is called by the engine every frame to update the Transition lifecycle onStart/onUpdate/onEnd\n */ execute() {\n if (!this.isInitialized) return;\n if (!this.started) {\n this.started = true;\n this.onStart(this.progress);\n }\n this.onUpdate(this.progress);\n if (this.complete && !this._completeFuture.isCompleted) {\n this.onEnd(this.progress);\n this._completeFuture.resolve();\n }\n }\n }\n class FadeInOut extends Transition {\n constructor(options){\n var _a, _b;\n super({\n ...options,\n duration: (_a = options.duration) !== null && _a !== void 0 ? _a : 2000\n });\n this.name = `FadeInOut#${this.id}`;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n }\n onInitialize(engine) {\n const bounds = engine.screen.getWorldBounds();\n this.transform.pos = vec(bounds.left, bounds.top);\n this.screenCover = new Rectangle({\n width: bounds.width,\n height: bounds.height,\n color: this.color\n });\n this.graphics.add(this.screenCover);\n this.graphics.opacity = this.progress;\n }\n onReset() {\n this.graphics.opacity = this.progress;\n }\n onStart(progress) {\n this.graphics.opacity = progress;\n }\n onEnd(progress) {\n this.graphics.opacity = progress;\n }\n onUpdate(progress) {\n this.graphics.opacity = progress;\n }\n }\n /**\n * CrossFades between the previous scene and the destination scene\n *\n * Note: CrossFade only works as an \"in\" transition\n */ class CrossFade extends Transition {\n constructor(options){\n super({\n direction: \"in\",\n ...options\n }); // default the correct direction\n this.name = `CrossFade#${this.id}`;\n }\n async onPreviousSceneDeactivate(scene) {\n this.image = await scene.engine.screenshot(true);\n // Firefox is particularly slow\n // needed in case the image isn't ready yet\n await this.image.decode();\n }\n onInitialize(engine) {\n this.engine = engine;\n const bounds = engine.screen.getWorldBounds();\n this.transform.pos = vec(bounds.left, bounds.top);\n this.screenCover = ImageSource.fromHtmlImageElement(this.image).toSprite();\n this.graphics.add(this.screenCover);\n this.transform.scale = vec(1 / engine.screen.pixelRatio, 1 / engine.screen.pixelRatio);\n this.graphics.opacity = this.progress;\n }\n onStart(_progress) {\n this.graphics.opacity = this.progress;\n }\n onReset() {\n this.graphics.opacity = this.progress;\n }\n onEnd(progress) {\n this.graphics.opacity = progress;\n }\n onUpdate(progress) {\n this.graphics.opacity = progress;\n }\n }\n class Line extends Graphic {\n constructor(options){\n super();\n this.color = Color.Black;\n this.thickness = 1;\n const { start: start, end: end, color: color, thickness: thickness } = options;\n this.start = start;\n this.end = end;\n this.color = color !== null && color !== void 0 ? color : this.color;\n this.thickness = thickness !== null && thickness !== void 0 ? thickness : this.thickness;\n this._localBounds = this._calculateBounds();\n const { width: width, height: height } = this._localBounds;\n this.width = width;\n this.height = height;\n }\n get localBounds() {\n return this._localBounds;\n }\n _calculateBounds() {\n const lineNormal = this.end.sub(this.start).normal();\n const halfThickness = this.thickness / 2;\n const points = [\n this.start.add(lineNormal.scale(halfThickness)),\n this.end.add(lineNormal.scale(halfThickness)),\n this.end.add(lineNormal.scale(-halfThickness)),\n this.start.add(lineNormal.scale(-halfThickness))\n ];\n return BoundingBox.fromPoints(points);\n }\n _drawImage(ctx, _x, _y) {\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\n }\n clone() {\n return new Line({\n start: this.start,\n end: this.end,\n color: this.color,\n thickness: this.thickness\n });\n }\n }\n /**\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\n *\n * Polygons default to [[ImageFiltering.Blended]]\n */ class Polygon extends Raster {\n get points() {\n return this._points;\n }\n set points(points) {\n this._points = points;\n const min = this.minPoint;\n this.width = this._points.reduce((max, p)=>Math.max(p.x, max), 0) - min.x;\n this.height = this._points.reduce((max, p)=>Math.max(p.y, max), 0) - min.y;\n this.flagDirty();\n }\n get minPoint() {\n const minX = this._points.reduce((min, p)=>Math.min(p.x, min), Infinity);\n const minY = this._points.reduce((min, p)=>Math.min(p.y, min), Infinity);\n return vec(minX, minY);\n }\n constructor(options){\n super(options);\n this.points = options.points;\n this.filtering = ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Polygon({\n points: this.points.map((p)=>p.clone()),\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.points && this.points.length) {\n ctx.beginPath();\n // Iterate through the supplied points and construct a 'polygon'\n const min = this.minPoint.negate();\n const firstPoint = this.points[0].add(min);\n ctx.moveTo(firstPoint.x, firstPoint.y);\n this.points.forEach((point)=>{\n ctx.lineTo(point.x + min.x, point.y + min.y);\n });\n ctx.lineTo(firstPoint.x, firstPoint.y);\n ctx.closePath();\n if (this.color) ctx.fill();\n if (this.strokeColor) ctx.stroke();\n }\n }\n }\n const maxMessages = 5;\n const obsoleteMessage = {};\n const resetObsoleteCounter = ()=>{\n for(const message in obsoleteMessage)obsoleteMessage[message] = 0;\n };\n const logMessage = (message, options)=>{\n const suppressObsoleteMessages = Flags.isEnabled(\"suppress-obsolete-message\");\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\n Logger.getInstance().warn(message);\n // tslint:disable-next-line: no-console\n if (console.trace && options.showStackTrace) // tslint:disable-next-line: no-console\n console.trace();\n }\n obsoleteMessage[message]++;\n };\n /**\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\n */ function obsolete(options) {\n options = {\n message: \"This feature will be removed in future versions of Excalibur.\",\n alternateMethod: null,\n showStackTrace: false,\n ...options\n };\n return function(target, property, descriptor) {\n if (descriptor && !(typeof descriptor.value === \"function\" || typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\")) throw new SyntaxError(\"Only classes/functions/getters/setters can be marked as obsolete\");\n const methodSignature = `${target.name || \"\"}${target.name && property ? \".\" : \"\"}${property ? property : \"\"}`;\n const message = `${methodSignature} is marked obsolete: ${options.message}` + (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : \"\");\n if (!obsoleteMessage[message]) obsoleteMessage[message] = 0;\n // If descriptor is null it is a class\n const method = descriptor ? {\n ...descriptor\n } : target;\n if (!descriptor) {\n // with es2015 classes we need to change our decoration tactic\n class DecoratedClass extends method {\n constructor(...args){\n logMessage(message, options);\n super(...args);\n }\n }\n return DecoratedClass;\n }\n if (descriptor && descriptor.value) {\n method.value = function() {\n logMessage(message, options);\n return descriptor.value.apply(this, arguments);\n };\n return method;\n }\n if (descriptor && descriptor.get) method.get = function() {\n logMessage(message, options);\n return descriptor.get.apply(this, arguments);\n };\n if (descriptor && descriptor.set) method.set = function() {\n logMessage(message, options);\n return descriptor.set.apply(this, arguments);\n };\n return method;\n };\n }\n class AsyncWaitQueue {\n constructor(){\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\n this._queue = [];\n }\n get length() {\n return this._queue.length;\n }\n enqueue() {\n const future = new Future();\n this._queue.push(future);\n return future.promise;\n }\n dequeue(value) {\n const future = this._queue.shift();\n future.resolve(value);\n }\n }\n /**\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\n *\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\n * around browser limitations like max Image.decode() calls in chromium being 256.\n */ class Semaphore {\n constructor(_count){\n this._count = _count;\n this._waitQueue = new AsyncWaitQueue();\n }\n get count() {\n return this._count;\n }\n get waiting() {\n return this._waitQueue.length;\n }\n // eslint-disable-next-line require-await\n async enter() {\n if (this._count !== 0) {\n this._count--;\n return Promise.resolve();\n }\n return this._waitQueue.enqueue();\n }\n exit(count = 1) {\n if (count === 0) return;\n while(count !== 0 && this._waitQueue.length !== 0){\n this._waitQueue.dequeue(null);\n count--;\n }\n this._count += count;\n }\n }\n /**\n * The current Excalibur version string\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\n */ const EX_VERSION = \"0.29.0\";\n polyfill();\n// This file is used as the bundle entry point and exports everything\n// that will be exposed as the `ex` global variable.\n// ex.Events namespace\n// ex.Input namespace\n// TODO deprecated import site remove in v0.29.0\n// ex.Util namespaces\n// ex.Deprecated\n// import * as deprecated from './Deprecated';\n// export { deprecated as Deprecated };\n// export * from './Deprecated';\n})();\nvar $2c23f148d58cd887$export$f05c91211c084e80 = $2c23f148d58cd887$var$__webpack_exports__.y1j;\nvar $2c23f148d58cd887$export$e04e17a44f37debc = $2c23f148d58cd887$var$__webpack_exports__.fWn;\nvar $2c23f148d58cd887$export$dfcd1bb88f6d711b = $2c23f148d58cd887$var$__webpack_exports__.Ia8;\nvar $2c23f148d58cd887$export$89f31cec7c284d42 = $2c23f148d58cd887$var$__webpack_exports__.rqv;\nvar $2c23f148d58cd887$export$a3f070f3e473c3b = $2c23f148d58cd887$var$__webpack_exports__.zH6;\nvar $2c23f148d58cd887$export$856e7d6d9d698871 = $2c23f148d58cd887$var$__webpack_exports__.hLI;\nvar $2c23f148d58cd887$export$caffe607ed29fca1 = $2c23f148d58cd887$var$__webpack_exports__.yyv;\nvar $2c23f148d58cd887$export$adc62e83dbcda319 = $2c23f148d58cd887$var$__webpack_exports__.tX5;\nvar $2c23f148d58cd887$export$f73d3eb6fd876d80 = $2c23f148d58cd887$var$__webpack_exports__.vtX;\nvar $2c23f148d58cd887$export$da248c61eea53296 = $2c23f148d58cd887$var$__webpack_exports__.r7K;\nvar $2c23f148d58cd887$export$f0455ab08e3fbd0e = $2c23f148d58cd887$var$__webpack_exports__.cE4;\nvar $2c23f148d58cd887$export$c35d437ae5945fcd = $2c23f148d58cd887$var$__webpack_exports__.fwF;\nvar $2c23f148d58cd887$export$67ee29bab3792d4c = $2c23f148d58cd887$var$__webpack_exports__.sce;\nvar $2c23f148d58cd887$export$d230853e97069d46 = $2c23f148d58cd887$var$__webpack_exports__.AQ6;\nvar $2c23f148d58cd887$export$6cfd78ddb48c90c6 = $2c23f148d58cd887$var$__webpack_exports__._c7;\nvar $2c23f148d58cd887$export$3769e64eb87b5ecc = $2c23f148d58cd887$var$__webpack_exports__.KUs;\nvar $2c23f148d58cd887$export$54dc36bc2fac5425 = $2c23f148d58cd887$var$__webpack_exports__.Ajp;\nvar $2c23f148d58cd887$export$387a78ab20784494 = $2c23f148d58cd887$var$__webpack_exports__.dkO;\nvar $2c23f148d58cd887$export$d06866a9fb0606da = $2c23f148d58cd887$var$__webpack_exports__.RDh;\nvar $2c23f148d58cd887$export$83c931ba0d3bbaf5 = $2c23f148d58cd887$var$__webpack_exports__._H9;\nvar $2c23f148d58cd887$export$1a553341cd0b8415 = $2c23f148d58cd887$var$__webpack_exports__.mxs;\nvar $2c23f148d58cd887$export$43416332cf06b1f = $2c23f148d58cd887$var$__webpack_exports__.OmD;\nvar $2c23f148d58cd887$export$63080c4de6cfc362 = $2c23f148d58cd887$var$__webpack_exports__.kBf;\nvar $2c23f148d58cd887$export$fa45ecb18b97ae89 = $2c23f148d58cd887$var$__webpack_exports__.C4F;\nvar $2c23f148d58cd887$export$c24f8f35353a1e26 = $2c23f148d58cd887$var$__webpack_exports__.NQt;\nvar $2c23f148d58cd887$export$8688def55452cbca = $2c23f148d58cd887$var$__webpack_exports__.JjN;\nvar $2c23f148d58cd887$export$665d5a662b7213f3 = $2c23f148d58cd887$var$__webpack_exports__.EK_;\nvar $2c23f148d58cd887$export$79f141de891a5fed = $2c23f148d58cd887$var$__webpack_exports__.V1s;\nvar $2c23f148d58cd887$export$41606648ac8a293c = $2c23f148d58cd887$var$__webpack_exports__.xHm;\nvar $2c23f148d58cd887$export$8d01c972ee8b14a9 = $2c23f148d58cd887$var$__webpack_exports__.Xz7;\nvar $2c23f148d58cd887$export$c89a927ffc67e6fa = $2c23f148d58cd887$var$__webpack_exports__.Cdc;\nvar $2c23f148d58cd887$export$e2395b697f5a931f = $2c23f148d58cd887$var$__webpack_exports__.FKn;\nvar $2c23f148d58cd887$export$9735c82c4bae3302 = $2c23f148d58cd887$var$__webpack_exports__.SUY;\nvar $2c23f148d58cd887$export$44e6803d1d57f89a = $2c23f148d58cd887$var$__webpack_exports__.ab2;\nvar $2c23f148d58cd887$export$1ed419d47673a225 = $2c23f148d58cd887$var$__webpack_exports__.GfZ;\nvar $2c23f148d58cd887$export$b7c6eef0ebb06133 = $2c23f148d58cd887$var$__webpack_exports__.YMS;\nvar $2c23f148d58cd887$export$3c9e91dc1b611d2e = $2c23f148d58cd887$var$__webpack_exports__.oyv;\nvar $2c23f148d58cd887$export$ce0ca64520c7bfd2 = $2c23f148d58cd887$var$__webpack_exports__.aUb;\nvar $2c23f148d58cd887$export$83caf30c40e9d4b8 = $2c23f148d58cd887$var$__webpack_exports__.SdD;\nvar $2c23f148d58cd887$export$4df0464d8c812c98 = $2c23f148d58cd887$var$__webpack_exports__.JUv;\nvar $2c23f148d58cd887$export$55e924fc640a8405 = $2c23f148d58cd887$var$__webpack_exports__.jEj;\nvar $2c23f148d58cd887$export$fbd6eb86d6a3f08 = $2c23f148d58cd887$var$__webpack_exports__.TFq;\nvar $2c23f148d58cd887$export$7cd2649c3408da6c = $2c23f148d58cd887$var$__webpack_exports__.HDU;\nvar $2c23f148d58cd887$export$897cd666d936ac4c = $2c23f148d58cd887$var$__webpack_exports__.R_y;\nvar $2c23f148d58cd887$export$cf976780b3106589 = $2c23f148d58cd887$var$__webpack_exports__.t50;\nvar $2c23f148d58cd887$export$5dcfde0f6b96512b = $2c23f148d58cd887$var$__webpack_exports__.s$$;\nvar $2c23f148d58cd887$export$ddb2ed749236e720 = $2c23f148d58cd887$var$__webpack_exports__.v2G;\nvar $2c23f148d58cd887$export$892596cec99bc70e = $2c23f148d58cd887$var$__webpack_exports__.Ilk;\nvar $2c23f148d58cd887$export$8ed4b5bb5352fe14 = $2c23f148d58cd887$var$__webpack_exports__.s9i;\nvar $2c23f148d58cd887$export$c46090c9df657074 = $2c23f148d58cd887$var$__webpack_exports__.dxL;\nvar $2c23f148d58cd887$export$b3bf2ffaa538264b = $2c23f148d58cd887$var$__webpack_exports__.LLX;\nvar $2c23f148d58cd887$export$16fa2f45be04daa8 = $2c23f148d58cd887$var$__webpack_exports__.wA2;\nvar $2c23f148d58cd887$export$d16a7c95008e315d = $2c23f148d58cd887$var$__webpack_exports__.R_p;\nvar $2c23f148d58cd887$export$abda45806f5adbae = $2c23f148d58cd887$var$__webpack_exports__.IQ$;\nvar $2c23f148d58cd887$export$e5a30aa3d28b26e2 = $2c23f148d58cd887$var$__webpack_exports__.I5F;\nvar $2c23f148d58cd887$export$de7807bd8bd828df = $2c23f148d58cd887$var$__webpack_exports__.X8$;\nvar $2c23f148d58cd887$export$1bdfb0c7c42d632d = $2c23f148d58cd887$var$__webpack_exports__.FR6;\nvar $2c23f148d58cd887$export$bf92f329076cd7a3 = $2c23f148d58cd887$var$__webpack_exports__.pTZ;\nvar $2c23f148d58cd887$export$71de6146fb6d69d2 = $2c23f148d58cd887$var$__webpack_exports__.U8o;\nvar $2c23f148d58cd887$export$71efaa2be447940c = $2c23f148d58cd887$var$__webpack_exports__.kbG;\nvar $2c23f148d58cd887$export$d78c8c6074541cf2 = $2c23f148d58cd887$var$__webpack_exports__.FEv;\nvar $2c23f148d58cd887$export$7d34ad93c25aa8e7 = $2c23f148d58cd887$var$__webpack_exports__.iS_;\nvar $2c23f148d58cd887$export$153e5dc2c098b35c = $2c23f148d58cd887$var$__webpack_exports__.cGG;\nvar $2c23f148d58cd887$export$f7c1896972d6c454 = $2c23f148d58cd887$var$__webpack_exports__.ETM;\nvar $2c23f148d58cd887$export$c3e6e677dda8521a = $2c23f148d58cd887$var$__webpack_exports__.RPN;\nvar $2c23f148d58cd887$export$e52858e61b0ea117 = $2c23f148d58cd887$var$__webpack_exports__.skb;\nvar $2c23f148d58cd887$export$3d1f12550a40f54d = $2c23f148d58cd887$var$__webpack_exports__.SLU;\nvar $2c23f148d58cd887$export$4544b2d7eff33859 = $2c23f148d58cd887$var$__webpack_exports__.Q3w;\nvar $2c23f148d58cd887$export$dd6b48f99ee8a36 = $2c23f148d58cd887$var$__webpack_exports__.xK2;\nvar $2c23f148d58cd887$export$aafe01318a900193 = $2c23f148d58cd887$var$__webpack_exports__.vrO;\nvar $2c23f148d58cd887$export$fd69b6a3b7f47e29 = $2c23f148d58cd887$var$__webpack_exports__.EA2;\nvar $2c23f148d58cd887$export$e1545123b54f6785 = $2c23f148d58cd887$var$__webpack_exports__.RdJ;\nvar $2c23f148d58cd887$export$7419ff430885d61c = $2c23f148d58cd887$var$__webpack_exports__.cNu;\nvar $2c23f148d58cd887$export$a340d4e5571cbd07 = $2c23f148d58cd887$var$__webpack_exports__.wtG;\nvar $2c23f148d58cd887$export$e695250628cde35 = $2c23f148d58cd887$var$__webpack_exports__.gU7;\nvar $2c23f148d58cd887$export$c5e124f7bab3d492 = $2c23f148d58cd887$var$__webpack_exports__.LSk;\nvar $2c23f148d58cd887$export$cacd6541cfeeb6c1 = $2c23f148d58cd887$var$__webpack_exports__.Nmp;\nvar $2c23f148d58cd887$export$a74d557191881f82 = $2c23f148d58cd887$var$__webpack_exports__.twX;\nvar $2c23f148d58cd887$export$99bf88c530739783 = $2c23f148d58cd887$var$__webpack_exports__.UND;\nvar $2c23f148d58cd887$export$4b7264771109adb6 = $2c23f148d58cd887$var$__webpack_exports__.d1Y;\nvar $2c23f148d58cd887$export$62053d374d83dfb1 = $2c23f148d58cd887$var$__webpack_exports__.xrL;\nvar $2c23f148d58cd887$export$d7078bb1ea3ba3f2 = $2c23f148d58cd887$var$__webpack_exports__.sRW;\nvar $2c23f148d58cd887$export$86ae8da356d53161 = $2c23f148d58cd887$var$__webpack_exports__.cmV;\nvar $2c23f148d58cd887$export$62230588c4867d28 = $2c23f148d58cd887$var$__webpack_exports__.qWz;\nvar $2c23f148d58cd887$export$df007b1d5b86e25a = $2c23f148d58cd887$var$__webpack_exports__.N0Q;\nvar $2c23f148d58cd887$export$6ff391a2049fdf40 = $2c23f148d58cd887$var$__webpack_exports__.q8b;\nvar $2c23f148d58cd887$export$89e5ccdc4c19a8f6 = $2c23f148d58cd887$var$__webpack_exports__.ynB;\nvar $2c23f148d58cd887$export$2cbc8fe61dd10773 = $2c23f148d58cd887$var$__webpack_exports__.jT9;\nvar $2c23f148d58cd887$export$d45269226a4bbdc1 = $2c23f148d58cd887$var$__webpack_exports__.wAz;\nvar $2c23f148d58cd887$export$2c3b404bf3a77a1f = $2c23f148d58cd887$var$__webpack_exports__.D4V;\nvar $2c23f148d58cd887$export$20434e7e042d306a = $2c23f148d58cd887$var$__webpack_exports__.NLr;\nvar $2c23f148d58cd887$export$462adefbb095232e = $2c23f148d58cd887$var$__webpack_exports__.N6H;\nvar $2c23f148d58cd887$export$83f8212621739c1f = $2c23f148d58cd887$var$__webpack_exports__.W1A;\nvar $2c23f148d58cd887$export$bc644a473284d944 = $2c23f148d58cd887$var$__webpack_exports__.JHW;\nvar $2c23f148d58cd887$export$66b8a9cb33a156c = $2c23f148d58cd887$var$__webpack_exports__.ZZ$;\nvar $2c23f148d58cd887$export$c7b7134fd828a5 = $2c23f148d58cd887$var$__webpack_exports__.v2K;\nvar $2c23f148d58cd887$export$ec8b666c5fe2c75a = $2c23f148d58cd887$var$__webpack_exports__.pBf;\nvar $2c23f148d58cd887$export$4fae95256245c8c0 = $2c23f148d58cd887$var$__webpack_exports__.vpe;\nvar $2c23f148d58cd887$export$86d9a347f2bf71d6 = $2c23f148d58cd887$var$__webpack_exports__.GMl;\nvar $2c23f148d58cd887$export$ada873a34909da65 = $2c23f148d58cd887$var$__webpack_exports__.zW2;\nvar $2c23f148d58cd887$export$afee3afd6be961ec = $2c23f148d58cd887$var$__webpack_exports__.B0K;\nvar $2c23f148d58cd887$export$c03216fb3a7a2f87 = $2c23f148d58cd887$var$__webpack_exports__.Nv7;\nvar $2c23f148d58cd887$export$81940238f313e11f = $2c23f148d58cd887$var$__webpack_exports__.C_p;\nvar $2c23f148d58cd887$export$40f8f9a8f94db930 = $2c23f148d58cd887$var$__webpack_exports__.MUA;\nvar $2c23f148d58cd887$export$c579e21b95165414 = $2c23f148d58cd887$var$__webpack_exports__.xqU;\nvar $2c23f148d58cd887$export$c983850c6c9d8b0e = $2c23f148d58cd887$var$__webpack_exports__.pTp;\nvar $2c23f148d58cd887$export$be5b6c6ac24b4683 = $2c23f148d58cd887$var$__webpack_exports__.trb;\nvar $2c23f148d58cd887$export$434ba092ed0eee4e = $2c23f148d58cd887$var$__webpack_exports__.vUK;\nvar $2c23f148d58cd887$export$455f05776f1ba8ba = $2c23f148d58cd887$var$__webpack_exports__.j9l;\nvar $2c23f148d58cd887$export$89abf52a030e56ee = $2c23f148d58cd887$var$__webpack_exports__.Zxw;\nvar $2c23f148d58cd887$export$549c899505235621 = $2c23f148d58cd887$var$__webpack_exports__.v51;\nvar $2c23f148d58cd887$export$1f6d1255105a925c = $2c23f148d58cd887$var$__webpack_exports__.gYv;\nvar $2c23f148d58cd887$export$23b468d4ca3f8c96 = $2c23f148d58cd887$var$__webpack_exports__.Hdx;\nvar $2c23f148d58cd887$export$6976e674e6d5804c = $2c23f148d58cd887$var$__webpack_exports__.Z$d;\nvar $2c23f148d58cd887$export$420acfc1740638d3 = $2c23f148d58cd887$var$__webpack_exports__.iqV;\nvar $2c23f148d58cd887$export$e84927905accfe51 = $2c23f148d58cd887$var$__webpack_exports__.o$7;\nvar $2c23f148d58cd887$export$c9d7bf589772a8ce = $2c23f148d58cd887$var$__webpack_exports__.olM;\nvar $2c23f148d58cd887$export$d5011a4647754c9b = $2c23f148d58cd887$var$__webpack_exports__.Zm$;\nvar $2c23f148d58cd887$export$b8c6aa234afa01bc = $2c23f148d58cd887$var$__webpack_exports__.$QH;\nvar $2c23f148d58cd887$export$6c3776220abeb931 = $2c23f148d58cd887$var$__webpack_exports__.i78;\nvar $2c23f148d58cd887$export$27a9cd7ebdd38262 = $2c23f148d58cd887$var$__webpack_exports__.nJg;\nvar $2c23f148d58cd887$export$fb1b94e06ba8ebc8 = $2c23f148d58cd887$var$__webpack_exports__.h6u;\nvar $2c23f148d58cd887$export$3d953a2d86354b5f = $2c23f148d58cd887$var$__webpack_exports__.hts;\nvar $2c23f148d58cd887$export$88528019d270f582 = $2c23f148d58cd887$var$__webpack_exports__.j88;\nvar $2c23f148d58cd887$export$402da60b1c009e43 = $2c23f148d58cd887$var$__webpack_exports__.VME;\nvar $2c23f148d58cd887$export$757ccd1717b77f48 = $2c23f148d58cd887$var$__webpack_exports__.fy2;\nvar $2c23f148d58cd887$export$48ebf29bc7cb1dd7 = $2c23f148d58cd887$var$__webpack_exports__.nt;\nvar $2c23f148d58cd887$export$3c8c04bde7eed7cb = $2c23f148d58cd887$var$__webpack_exports__.Ukr;\nvar $2c23f148d58cd887$export$adfa9d260876eca5 = $2c23f148d58cd887$var$__webpack_exports__.zsu;\nvar $2c23f148d58cd887$export$6c043ed3a716859a = $2c23f148d58cd887$var$__webpack_exports__.oA6;\nvar $2c23f148d58cd887$export$9f9afb456a8bef30 = $2c23f148d58cd887$var$__webpack_exports__.TVh;\nvar $2c23f148d58cd887$export$1033a6fa0779f4f5 = $2c23f148d58cd887$var$__webpack_exports__.xxj;\nvar $2c23f148d58cd887$export$38f8109d2b8f43ef = $2c23f148d58cd887$var$__webpack_exports__.XdK;\nvar $2c23f148d58cd887$export$b5aa7fe3676b74a9 = $2c23f148d58cd887$var$__webpack_exports__.fBD;\nvar $2c23f148d58cd887$export$5213deb2877a09f2 = $2c23f148d58cd887$var$__webpack_exports__.Jmb;\nvar $2c23f148d58cd887$export$280e9a68c3ffd919 = $2c23f148d58cd887$var$__webpack_exports__.cXo;\nvar $2c23f148d58cd887$export$49a1ecce8d203 = $2c23f148d58cd887$var$__webpack_exports__.Dm5;\nvar $2c23f148d58cd887$export$f5b8910cec6cf069 = $2c23f148d58cd887$var$__webpack_exports__.IIB;\nvar $2c23f148d58cd887$export$99f13cbf742a0580 = $2c23f148d58cd887$var$__webpack_exports__.IX$;\nvar $2c23f148d58cd887$export$2ae6ec0f10d96242 = $2c23f148d58cd887$var$__webpack_exports__.ebW;\nvar $2c23f148d58cd887$export$d379657aa3df1705 = $2c23f148d58cd887$var$__webpack_exports__.zI0;\nvar $2c23f148d58cd887$export$ffed6a4cd9a88787 = $2c23f148d58cd887$var$__webpack_exports__.LYD;\nvar $2c23f148d58cd887$export$7705889256a9371a = $2c23f148d58cd887$var$__webpack_exports__.cEG;\nvar $2c23f148d58cd887$export$539f65e788a82c62 = $2c23f148d58cd887$var$__webpack_exports__.SEl;\nvar $2c23f148d58cd887$export$851e6d93385b6ad2 = $2c23f148d58cd887$var$__webpack_exports__.t9V;\nvar $2c23f148d58cd887$export$4b0c1c390bf9a356 = $2c23f148d58cd887$var$__webpack_exports__.ez5;\nvar $2c23f148d58cd887$export$16e4d70cc375e707 = $2c23f148d58cd887$var$__webpack_exports__.N1d;\nvar $2c23f148d58cd887$export$4b0075e5ea5e1f26 = $2c23f148d58cd887$var$__webpack_exports__.R8U;\nvar $2c23f148d58cd887$export$f3a6c1ca682fd40f = $2c23f148d58cd887$var$__webpack_exports__.SKZ;\nvar $2c23f148d58cd887$export$b04be29aa201d4f5 = $2c23f148d58cd887$var$__webpack_exports__.__J;\nvar $2c23f148d58cd887$export$b3509fba7d85d294 = $2c23f148d58cd887$var$__webpack_exports__.RI$;\nvar $2c23f148d58cd887$export$17d680238e50603e = $2c23f148d58cd887$var$__webpack_exports__.x12;\nvar $2c23f148d58cd887$export$8b98feb4a2766c75 = $2c23f148d58cd887$var$__webpack_exports__.ccz;\nvar $2c23f148d58cd887$export$3b0d6d7590275603 = $2c23f148d58cd887$var$__webpack_exports__.aNw;\nvar $2c23f148d58cd887$export$38d47553764a3d88 = $2c23f148d58cd887$var$__webpack_exports__.XrL;\nvar $2c23f148d58cd887$export$1c4c6d3f8d56581 = $2c23f148d58cd887$var$__webpack_exports__.xwn;\nvar $2c23f148d58cd887$export$fc869739b2177284 = $2c23f148d58cd887$var$__webpack_exports__.dNK;\nvar $2c23f148d58cd887$export$243e62d78d3b544d = $2c23f148d58cd887$var$__webpack_exports__.ini;\nvar $2c23f148d58cd887$export$efa9a398d6368992 = $2c23f148d58cd887$var$__webpack_exports__.YdH;\nvar $2c23f148d58cd887$export$a2d8b23205c25948 = $2c23f148d58cd887$var$__webpack_exports__.F5T;\nvar $2c23f148d58cd887$export$5b12bf1653c0dd85 = $2c23f148d58cd887$var$__webpack_exports__.y3G;\nvar $2c23f148d58cd887$export$9f9b2346169b00c0 = $2c23f148d58cd887$var$__webpack_exports__.l57;\nvar $2c23f148d58cd887$export$8c37b217b84d3f89 = $2c23f148d58cd887$var$__webpack_exports__.xn0;\nvar $2c23f148d58cd887$export$35624b13e79b24a9 = $2c23f148d58cd887$var$__webpack_exports__.t2V;\nvar $2c23f148d58cd887$export$f75e7304717c9cbc = $2c23f148d58cd887$var$__webpack_exports__.uxB;\nvar $2c23f148d58cd887$export$ec1251c88c8bd5c9 = $2c23f148d58cd887$var$__webpack_exports__.cpd;\nvar $2c23f148d58cd887$export$d17844835b0fe8a8 = $2c23f148d58cd887$var$__webpack_exports__.fiy;\nvar $2c23f148d58cd887$export$d1d8cb3d5c2a5671 = $2c23f148d58cd887$var$__webpack_exports__.$XZ;\nvar $2c23f148d58cd887$export$4d607ef791645d6 = $2c23f148d58cd887$var$__webpack_exports__.UG6;\nvar $2c23f148d58cd887$export$f0b55daf9f154b55 = $2c23f148d58cd887$var$__webpack_exports__.uqK;\nvar $2c23f148d58cd887$export$fa9699e41ba6faff = $2c23f148d58cd887$var$__webpack_exports__.STE;\nvar $2c23f148d58cd887$export$57ca7e07b341709d = $2c23f148d58cd887$var$__webpack_exports__.Hq9;\nvar $2c23f148d58cd887$export$77cea355fa80b5f4 = $2c23f148d58cd887$var$__webpack_exports__.y$z;\nvar $2c23f148d58cd887$export$8844adde4348f85c = $2c23f148d58cd887$var$__webpack_exports__.mAD;\nvar $2c23f148d58cd887$export$d63d7cff08fe4dc9 = $2c23f148d58cd887$var$__webpack_exports__.sOq;\nvar $2c23f148d58cd887$export$a960801e47624f4f = $2c23f148d58cd887$var$__webpack_exports__.hUw;\nvar $2c23f148d58cd887$export$ed6a63ee685a4d78 = $2c23f148d58cd887$var$__webpack_exports__._0G;\nvar $2c23f148d58cd887$export$4fe52ae24ae61d51 = $2c23f148d58cd887$var$__webpack_exports__.Sqs;\nvar $2c23f148d58cd887$export$c36c68baa13912a5 = $2c23f148d58cd887$var$__webpack_exports__.hpZ;\nvar $2c23f148d58cd887$export$616c632b282478dd = $2c23f148d58cd887$var$__webpack_exports__.Vol;\nvar $2c23f148d58cd887$export$459b1801e3134a24 = $2c23f148d58cd887$var$__webpack_exports__.vYX;\nvar $2c23f148d58cd887$export$2f09efa5b67124a7 = $2c23f148d58cd887$var$__webpack_exports__.wIZ;\nvar $2c23f148d58cd887$export$618424ba3f30cd41 = $2c23f148d58cd887$var$__webpack_exports__.cBi;\nvar $2c23f148d58cd887$export$4a963ea7a16edf21 = $2c23f148d58cd887$var$__webpack_exports__.c30;\nvar $2c23f148d58cd887$export$a4017560efebe97d = $2c23f148d58cd887$var$__webpack_exports__.PGK;\nvar $2c23f148d58cd887$export$982e5de016bedff1 = $2c23f148d58cd887$var$__webpack_exports__.MPV;\nvar $2c23f148d58cd887$export$6860c0696b73f79b = $2c23f148d58cd887$var$__webpack_exports__.RFv;\nvar $2c23f148d58cd887$export$94806efd9890932f = $2c23f148d58cd887$var$__webpack_exports__.Ux6;\nvar $2c23f148d58cd887$export$3bee0b2628b43478 = $2c23f148d58cd887$var$__webpack_exports__.rxy;\nvar $2c23f148d58cd887$export$caed39dbb767d548 = $2c23f148d58cd887$var$__webpack_exports__.I$c;\nvar $2c23f148d58cd887$export$7e5ab4f7f9fd407 = $2c23f148d58cd887$var$__webpack_exports__.kfC;\nvar $2c23f148d58cd887$export$330520496d871ecf = $2c23f148d58cd887$var$__webpack_exports__.VjY;\nvar $2c23f148d58cd887$export$7d31b617c820d435 = $2c23f148d58cd887$var$__webpack_exports__.mgq;\nvar $2c23f148d58cd887$export$f23a2a272a8df60 = $2c23f148d58cd887$var$__webpack_exports__.YVA;\nvar $2c23f148d58cd887$export$14963ee5c8637e11 = $2c23f148d58cd887$var$__webpack_exports__.Kgp;\nvar $2c23f148d58cd887$export$1d2c184034fc4cc2 = $2c23f148d58cd887$var$__webpack_exports__.HH$;\nvar $2c23f148d58cd887$export$fea21a521a6360c1 = $2c23f148d58cd887$var$__webpack_exports__.M_d;\nvar $2c23f148d58cd887$export$8c15bdf7e3727f73 = $2c23f148d58cd887$var$__webpack_exports__.rgh;\nvar $2c23f148d58cd887$export$6eb043bf81d89752 = $2c23f148d58cd887$var$__webpack_exports__.Ra6;\nvar $2c23f148d58cd887$export$e390b859365a3d5b = $2c23f148d58cd887$var$__webpack_exports__.KhR;\nvar $2c23f148d58cd887$export$82a33120f6a0d987 = $2c23f148d58cd887$var$__webpack_exports__.gvQ;\nvar $2c23f148d58cd887$export$1ec85152758537e0 = $2c23f148d58cd887$var$__webpack_exports__.BS5;\nvar $2c23f148d58cd887$export$a8584993858a18df = $2c23f148d58cd887$var$__webpack_exports__.xhz;\nvar $2c23f148d58cd887$export$906049a3747337a6 = $2c23f148d58cd887$var$__webpack_exports__.xOq;\nvar $2c23f148d58cd887$export$dbd8a6303ac26a42 = $2c23f148d58cd887$var$__webpack_exports__.a9j;\nvar $2c23f148d58cd887$export$9f68b6f37a444556 = $2c23f148d58cd887$var$__webpack_exports__.bHk;\nvar $2c23f148d58cd887$export$fe2b6ac465da985d = $2c23f148d58cd887$var$__webpack_exports__.CgK;\nvar $2c23f148d58cd887$export$4c3c82f4dcd79fcc = $2c23f148d58cd887$var$__webpack_exports__.A0M;\nvar $2c23f148d58cd887$export$e4ce43ec0499fb8f = $2c23f148d58cd887$var$__webpack_exports__.cEd;\nvar $2c23f148d58cd887$export$e44279b5c44add28 = $2c23f148d58cd887$var$__webpack_exports__.cuY;\nvar $2c23f148d58cd887$export$dfa3a012bb2ef2e1 = $2c23f148d58cd887$var$__webpack_exports__.kvE;\nvar $2c23f148d58cd887$export$8201b979875baf73 = $2c23f148d58cd887$var$__webpack_exports__.SBu;\nvar $2c23f148d58cd887$export$b82688eb02220411 = $2c23f148d58cd887$var$__webpack_exports__.PsT;\nvar $2c23f148d58cd887$export$62297b13309008b2 = $2c23f148d58cd887$var$__webpack_exports__.AE_;\nvar $2c23f148d58cd887$export$b986383a50b53ea4 = $2c23f148d58cd887$var$__webpack_exports__.ctO;\nvar $2c23f148d58cd887$export$ad5b3d166367714c = $2c23f148d58cd887$var$__webpack_exports__.OLH;\nvar $2c23f148d58cd887$export$a92776769f460054 = $2c23f148d58cd887$var$__webpack_exports__.kky;\nvar $2c23f148d58cd887$export$eeb71495ca594706 = $2c23f148d58cd887$var$__webpack_exports__.nSF;\nvar $2c23f148d58cd887$export$a186db52eed6d40e = $2c23f148d58cd887$var$__webpack_exports__.zHn;\nvar $2c23f148d58cd887$export$c07ce6d13c46df49 = $2c23f148d58cd887$var$__webpack_exports__.zwx;\nvar $2c23f148d58cd887$export$4617fb02663045ef = $2c23f148d58cd887$var$__webpack_exports__.AeJ;\nvar $2c23f148d58cd887$export$32437fc39ad02208 = $2c23f148d58cd887$var$__webpack_exports__.hLz;\nvar $2c23f148d58cd887$export$f9d61a2a6155ab51 = $2c23f148d58cd887$var$__webpack_exports__.wA;\nvar $2c23f148d58cd887$export$9bd81f7d9b69ccb3 = $2c23f148d58cd887$var$__webpack_exports__.jhr;\nvar $2c23f148d58cd887$export$3e4ff2216a90b8a4 = $2c23f148d58cd887$var$__webpack_exports__.GVs;\nvar $2c23f148d58cd887$export$39a853cfb5a94a63 = $2c23f148d58cd887$var$__webpack_exports__._zO;\nvar $2c23f148d58cd887$export$62833702c6700187 = $2c23f148d58cd887$var$__webpack_exports__.LXZ;\nvar $2c23f148d58cd887$export$a43177620e7a9310 = $2c23f148d58cd887$var$__webpack_exports__.w6$;\nvar $2c23f148d58cd887$export$a16b6ef1fd362a19 = $2c23f148d58cd887$var$__webpack_exports__.mhV;\nvar $2c23f148d58cd887$export$91397be43fc980cc = $2c23f148d58cd887$var$__webpack_exports__.MOD;\nvar $2c23f148d58cd887$export$23b9d128e61caefd = $2c23f148d58cd887$var$__webpack_exports__.kwd;\nvar $2c23f148d58cd887$export$ab681471d41eeddc = $2c23f148d58cd887$var$__webpack_exports__.Lmr;\nvar $2c23f148d58cd887$export$38af1803e3442a7f = $2c23f148d58cd887$var$__webpack_exports__.xsS;\nvar $2c23f148d58cd887$export$c1825d965cf69ea3 = $2c23f148d58cd887$var$__webpack_exports__.K5l;\nvar $2c23f148d58cd887$export$a98515d67472a41f = $2c23f148d58cd887$var$__webpack_exports__.lLr;\nvar $2c23f148d58cd887$export$57486627f01aaaf3 = $2c23f148d58cd887$var$__webpack_exports__.Z$r;\nvar $2c23f148d58cd887$export$77630fcd7c3f2eb6 = $2c23f148d58cd887$var$__webpack_exports__.IXb;\nvar $2c23f148d58cd887$export$3bf088dd0bb7575 = $2c23f148d58cd887$var$__webpack_exports__.Xsu;\nvar $2c23f148d58cd887$export$2f3ac66e390c188b = $2c23f148d58cd887$var$__webpack_exports__.SGH;\nvar $2c23f148d58cd887$export$d160a188872e1e4e = $2c23f148d58cd887$var$__webpack_exports__.SMj;\nvar $2c23f148d58cd887$export$5c7bd08c630c970c = $2c23f148d58cd887$var$__webpack_exports__.L34;\nvar $2c23f148d58cd887$export$462bb059fed9d9e5 = $2c23f148d58cd887$var$__webpack_exports__.exe;\nvar $2c23f148d58cd887$export$6428a7f2611ef1fa = $2c23f148d58cd887$var$__webpack_exports__.bnF;\nvar $2c23f148d58cd887$export$80a00690bda7f17e = $2c23f148d58cd887$var$__webpack_exports__.MFA;\nvar $2c23f148d58cd887$export$50994fad4c4676f4 = $2c23f148d58cd887$var$__webpack_exports__.kPj;\nvar $2c23f148d58cd887$export$85990f0f98a390bb = $2c23f148d58cd887$var$__webpack_exports__.$uU;\nvar $2c23f148d58cd887$export$5bff0d6cc6200d64 = $2c23f148d58cd887$var$__webpack_exports__.Sap;\nvar $2c23f148d58cd887$export$3075603db8e6204c = $2c23f148d58cd887$var$__webpack_exports__.jyi;\nvar $2c23f148d58cd887$export$e1896ac0c4970221 = $2c23f148d58cd887$var$__webpack_exports__.E03;\nvar $2c23f148d58cd887$export$bd73ddfe5f8475d8 = $2c23f148d58cd887$var$__webpack_exports__.V6q;\nvar $2c23f148d58cd887$export$f62bb2892382b3dd = $2c23f148d58cd887$var$__webpack_exports__.rg2;\nvar $2c23f148d58cd887$export$cbf2d83d1eab018a = $2c23f148d58cd887$var$__webpack_exports__.DVW;\nvar $2c23f148d58cd887$export$9ad53eded130cce4 = $2c23f148d58cd887$var$__webpack_exports__.nVo;\nvar $2c23f148d58cd887$export$6a4eb2e7fc9e8903 = $2c23f148d58cd887$var$__webpack_exports__.F6N;\nvar $2c23f148d58cd887$export$e1dae5660003ffa7 = $2c23f148d58cd887$var$__webpack_exports__.xP7;\nvar $2c23f148d58cd887$export$a12e67a4b4590901 = $2c23f148d58cd887$var$__webpack_exports__.Odq;\nvar $2c23f148d58cd887$export$7c88eb83095afadd = $2c23f148d58cd887$var$__webpack_exports__.uY9;\nvar $2c23f148d58cd887$export$c586aa7b67d94d19 = $2c23f148d58cd887$var$__webpack_exports__.Zif;\nvar $2c23f148d58cd887$export$47b45ce774071a36 = $2c23f148d58cd887$var$__webpack_exports__.c_d;\nvar $2c23f148d58cd887$export$9440a22058545f9a = $2c23f148d58cd887$var$__webpack_exports__.MJk;\nvar $2c23f148d58cd887$export$5f1af8db9871e1d6 = $2c23f148d58cd887$var$__webpack_exports__.xvT;\nvar $2c23f148d58cd887$export$3720eb13f948f394 = $2c23f148d58cd887$var$__webpack_exports__.PHM;\nvar $2c23f148d58cd887$export$fd1bfc71f64c538c = $2c23f148d58cd887$var$__webpack_exports__.dpR;\nvar $2c23f148d58cd887$export$235cb65c20ad2b7 = $2c23f148d58cd887$var$__webpack_exports__.n9L;\nvar $2c23f148d58cd887$export$16ec26812de3ce7a = $2c23f148d58cd887$var$__webpack_exports__.KwO;\nvar $2c23f148d58cd887$export$dac3abbdc575ce73 = $2c23f148d58cd887$var$__webpack_exports__.SxM;\nvar $2c23f148d58cd887$export$c57e9b2d8b9e4de = $2c23f148d58cd887$var$__webpack_exports__.B7y;\nvar $2c23f148d58cd887$export$fb98e3a2a4cd92d7 = $2c23f148d58cd887$var$__webpack_exports__.x7r;\nvar $2c23f148d58cd887$export$563a914cafbdc389 = $2c23f148d58cd887$var$__webpack_exports__.wx7;\nvar $2c23f148d58cd887$export$1def2aa75b7c7fe0 = $2c23f148d58cd887$var$__webpack_exports__.Uvn;\nvar $2c23f148d58cd887$export$be58926105124dd4 = $2c23f148d58cd887$var$__webpack_exports__.uTP;\nvar $2c23f148d58cd887$export$2eba8ec3a333fdbb = $2c23f148d58cd887$var$__webpack_exports__.OFT;\nvar $2c23f148d58cd887$export$41fb9f06171c75f4 = $2c23f148d58cd887$var$__webpack_exports__.xzN;\nvar $2c23f148d58cd887$export$14963f945d6d59f0 = $2c23f148d58cd887$var$__webpack_exports__.CcZ;\nvar $2c23f148d58cd887$export$ba8651401a8a2b84 = $2c23f148d58cd887$var$__webpack_exports__.M5Z;\nvar $2c23f148d58cd887$export$f8f26dd395d7e1bd = $2c23f148d58cd887$var$__webpack_exports__.ZrN;\nvar $2c23f148d58cd887$export$9b781de7bf37bf48 = $2c23f148d58cd887$var$__webpack_exports__.OWs;\nvar $2c23f148d58cd887$export$ab650c8e5b9b9f2c = $2c23f148d58cd887$var$__webpack_exports__.dF9;\nvar $2c23f148d58cd887$export$41825a1ed6473903 = $2c23f148d58cd887$var$__webpack_exports__.oZy;\nvar $2c23f148d58cd887$export$f5ae2f144b95ebf4 = $2c23f148d58cd887$var$__webpack_exports__.rD2;\nvar $2c23f148d58cd887$export$31ac8f65680039dd = $2c23f148d58cd887$var$__webpack_exports__.KmN;\nvar $2c23f148d58cd887$export$d5c6f73f7a77b9d = $2c23f148d58cd887$var$__webpack_exports__.VHo;\nvar $2c23f148d58cd887$export$8bfbf00b5dba81f6 = $2c23f148d58cd887$var$__webpack_exports__.ohE;\nvar $2c23f148d58cd887$export$2af5ef044257da25 = $2c23f148d58cd887$var$__webpack_exports__.R$E;\nvar $2c23f148d58cd887$export$8c3375c231593a9d = $2c23f148d58cd887$var$__webpack_exports__.xQN;\nvar $2c23f148d58cd887$export$9a4eae43f302c46e = $2c23f148d58cd887$var$__webpack_exports__.AdJ;\nvar $2c23f148d58cd887$export$812cd9544993280d = $2c23f148d58cd887$var$__webpack_exports__.q3I;\nvar $2c23f148d58cd887$export$a4913eafbb02ceb4 = $2c23f148d58cd887$var$__webpack_exports__.Pab;\nvar $2c23f148d58cd887$export$7d15b64cf5a3a4c4 = $2c23f148d58cd887$var$__webpack_exports__.uZ5;\nvar $2c23f148d58cd887$export$c372a5d5a3996cbf = $2c23f148d58cd887$var$__webpack_exports__.TAE;\nvar $2c23f148d58cd887$export$7149c6ffc9994c32 = $2c23f148d58cd887$var$__webpack_exports__.McK;\nvar $2c23f148d58cd887$export$d436988b04cb99a5 = $2c23f148d58cd887$var$__webpack_exports__.F9c;\nvar $2c23f148d58cd887$export$3ba9f2e94585ecc6 = $2c23f148d58cd887$var$__webpack_exports__.k0b;\nvar $2c23f148d58cd887$export$25dac40984956196 = $2c23f148d58cd887$var$__webpack_exports__.hnT;\nvar $2c23f148d58cd887$export$57932b71da6538b7 = $2c23f148d58cd887$var$__webpack_exports__.RSJ;\nvar $2c23f148d58cd887$export$a17402ef5f32064d = $2c23f148d58cd887$var$__webpack_exports__.Mku;\nvar $2c23f148d58cd887$export$d5dea09620a858fd = $2c23f148d58cd887$var$__webpack_exports__.h90;\nvar $2c23f148d58cd887$export$1377812d73ae3cab = $2c23f148d58cd887$var$__webpack_exports__.rms;\nvar $2c23f148d58cd887$export$331f4c7ef74a9752 = $2c23f148d58cd887$var$__webpack_exports__.ErP;\nvar $2c23f148d58cd887$export$5f4e18965661d41f = $2c23f148d58cd887$var$__webpack_exports__.aVg;\nvar $2c23f148d58cd887$export$817667946f51142b = $2c23f148d58cd887$var$__webpack_exports__.lPc;\nvar $2c23f148d58cd887$export$adc479603c39b28 = $2c23f148d58cd887$var$__webpack_exports__.Z8E;\nvar $2c23f148d58cd887$export$ba30ba18962891e7 = $2c23f148d58cd887$var$__webpack_exports__.k15;\nvar $2c23f148d58cd887$export$bcf8f1355133000b = $2c23f148d58cd887$var$__webpack_exports__.YsU;\nvar $2c23f148d58cd887$export$256576ea924e6c90 = $2c23f148d58cd887$var$__webpack_exports__.lNv;\nvar $2c23f148d58cd887$export$786d9ab531bddbaa = $2c23f148d58cd887$var$__webpack_exports__.Xyg;\nvar $2c23f148d58cd887$export$e87630d8ef35465d = $2c23f148d58cd887$var$__webpack_exports__.cu9;\nvar $2c23f148d58cd887$export$c3cedacda2d7ce48 = $2c23f148d58cd887$var$__webpack_exports__.p88;\nvar $2c23f148d58cd887$export$5a62d8eea226ddc = $2c23f148d58cd887$var$__webpack_exports__.MZQ;\nvar $2c23f148d58cd887$export$640d107500a3202a = $2c23f148d58cd887$var$__webpack_exports__.FUM;\nvar $2c23f148d58cd887$export$506bf22710a79182 = $2c23f148d58cd887$var$__webpack_exports__.BxR;\nvar $2c23f148d58cd887$export$8b958c8ecd94a804 = $2c23f148d58cd887$var$__webpack_exports__.vdf;\nvar $2c23f148d58cd887$export$816343276f749e02 = $2c23f148d58cd887$var$__webpack_exports__.iaL;\nvar $2c23f148d58cd887$export$d02631cccf789723 = $2c23f148d58cd887$var$__webpack_exports__.w6H;\nvar $2c23f148d58cd887$export$5dc5812d8b390c43 = $2c23f148d58cd887$var$__webpack_exports__.Q4c;\nvar $2c23f148d58cd887$export$c5552dfdbc7cec71 = $2c23f148d58cd887$var$__webpack_exports__.Xxe;\nvar $2c23f148d58cd887$export$56cb859c01fa134d = $2c23f148d58cd887$var$__webpack_exports__.Uxb;\nvar $2c23f148d58cd887$export$cba01ba138429a1d = $2c23f148d58cd887$var$__webpack_exports__.Yr5;\nvar $2c23f148d58cd887$export$202e0172ed3c7be0 = $2c23f148d58cd887$var$__webpack_exports__.Bhw;\nvar $2c23f148d58cd887$export$d55298c9efc5ed14 = $2c23f148d58cd887$var$__webpack_exports__.yOA;\n\n});\n\n\nvar $3MXpL = parcelRequire(\"3MXpL\");\n\nvar $3MXpL = parcelRequire(\"3MXpL\");\n\nvar $3MXpL = parcelRequire(\"3MXpL\");\nvar $f82d5511d53990a3$exports = {};\n\n!function(e, t) {\n $f82d5511d53990a3$exports = t((parcelRequire(\"3MXpL\")));\n}(self, (e)=>(()=>{\n \"use strict\";\n var t = {\n 445: (e, t, s)=>{\n s.r(t), s.d(t, {\n compare: ()=>u,\n compareVersions: ()=>l,\n satisfies: ()=>f,\n validate: ()=>m,\n validateStrict: ()=>y\n });\n const r = /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i, i = (e)=>{\n if (\"string\" != typeof e) throw new TypeError(\"Invalid argument expected string\");\n const t = e.match(r);\n if (!t) throw new Error(`Invalid argument not valid semver ('${e}' received)`);\n return t.shift(), t;\n }, a = (e)=>\"*\" === e || \"x\" === e || \"X\" === e, n = (e)=>{\n const t = parseInt(e, 10);\n return isNaN(t) ? e : t;\n }, o = (e, t)=>{\n if (a(e) || a(t)) return 0;\n const [s, r] = ((e, t)=>typeof e != typeof t ? [\n String(e),\n String(t)\n ] : [\n e,\n t\n ])(n(e), n(t));\n return s > r ? 1 : s < r ? -1 : 0;\n }, d = (e, t)=>{\n for(let s = 0; s < Math.max(e.length, t.length); s++){\n const r = o(e[s] || \"0\", t[s] || \"0\");\n if (0 !== r) return r;\n }\n return 0;\n }, l = (e, t)=>{\n const s = i(e), r = i(t), a = s.pop(), n = r.pop(), o = d(s, r);\n return 0 !== o ? o : a && n ? d(a.split(\".\"), n.split(\".\")) : a || n ? a ? -1 : 1 : 0;\n }, u = (e, t, s)=>{\n h(s);\n const r = l(e, t);\n return c[s].includes(r);\n }, c = {\n \">\": [\n 1\n ],\n \">=\": [\n 0,\n 1\n ],\n \"=\": [\n 0\n ],\n \"<=\": [\n -1,\n 0\n ],\n \"<\": [\n -1\n ],\n \"!=\": [\n -1,\n 1\n ]\n }, p = Object.keys(c), h = (e)=>{\n if (\"string\" != typeof e) throw new TypeError(\"Invalid operator type, expected string but got \" + typeof e);\n if (-1 === p.indexOf(e)) throw new Error(`Invalid operator, expected one of ${p.join(\"|\")}`);\n }, f = (e, t)=>{\n if ((t = t.replace(/([><=]+)\\s+/g, \"$1\")).includes(\"||\")) return t.split(\"||\").some((t)=>f(e, t));\n if (t.includes(\" - \")) {\n const [s, r] = t.split(\" - \", 2);\n return f(e, `>=${s} <=${r}`);\n }\n if (t.includes(\" \")) return t.trim().replace(/\\s{2,}/g, \" \").split(\" \").every((t)=>f(e, t));\n const s = t.match(/^([<>=~^]+)/), r = s ? s[1] : \"=\";\n if (\"^\" !== r && \"~\" !== r) return u(e, t, r);\n const [a, n, o, , l] = i(e), [c, p, h, , m] = i(t), y = [\n a,\n n,\n o\n ], _ = [\n c,\n null != p ? p : \"x\",\n null != h ? h : \"x\"\n ];\n if (m) {\n if (!l) return !1;\n if (0 !== d(y, _)) return !1;\n if (-1 === d(l.split(\".\"), m.split(\".\"))) return !1;\n }\n const v = _.findIndex((e)=>\"0\" !== e) + 1, g = \"~\" === r ? 2 : v > 1 ? v : 1;\n return 0 === d(y.slice(0, g), _.slice(0, g)) && -1 !== d(y.slice(g), _.slice(g));\n }, m = (e)=>\"string\" == typeof e && /^[v\\d]/.test(e) && r.test(e), y = (e)=>\"string\" == typeof e && /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/.test(e);\n },\n 961: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.EntityLayer = void 0;\n const r = s(205);\n t.EntityLayer = class {\n constructor(e, t, s, i){\n var a, n;\n if (this.ldtkLayer = t, this.resource = s, this.order = i, this.entities = [], this.ldtkToEntity = new Map, this.entityToLdtk = new Map, this.worldPos = (0, r.vec)(e.ldtkLevel.worldX, e.ldtkLevel.worldY), this.offset = (0, r.vec)(t.__pxTotalOffsetX, t.__pxTotalOffsetY), t.entityInstances) for (let e of t.entityInstances){\n const t = s.projectMetadata.defs.entities.find((t)=>t.identifier === e.__identifier);\n if (s.factories.has(e.__identifier)) {\n const i = s.factories.get(e.__identifier);\n if (i) {\n const s = i({\n type: e.__identifier,\n worldPos: (0, r.vec)(e.px[0], e.px[1]).add(this.worldPos.add(this.offset)),\n entity: e,\n definition: t,\n layer: this\n });\n s && (this.entities.push(s), this.ldtkToEntity.set(e, s), this.entityToLdtk.set(s, e));\n }\n } else {\n const o = new r.Actor({\n name: e.__identifier,\n pos: (0, r.vec)(e.px[0], e.px[1]).add(this.worldPos.add(this.offset)),\n width: e.width,\n height: e.height,\n anchor: (0, r.vec)(null !== (a = null == t ? void 0 : t.pivotX) && void 0 !== a ? a : 0, null !== (n = null == t ? void 0 : t.pivotY) && void 0 !== n ? n : 0),\n z: i\n });\n if (e.__tile) {\n const t = s.tilesets.get(e.__tile.tilesetUid);\n if (t) {\n const s = Math.floor(e.__tile.x / e.__tile.w), r = Math.floor(e.__tile.y / e.__tile.h), i = t.spritesheet.getSprite(s, r);\n i && o.graphics.use(i);\n }\n }\n this.entities.push(o), this.ldtkToEntity.set(e, o), this.entityToLdtk.set(o, e);\n }\n }\n }\n runFactory(e) {\n if (this.resource.factories.has(e) && this.ldtkLayer.entityInstances) for (let e of this.ldtkLayer.entityInstances){\n const t = this.resource.projectMetadata.defs.entities.find((t)=>t.identifier === e.__identifier), s = this.resource.factories.get(e.__identifier);\n if (s) {\n const i = s({\n type: e.__identifier,\n worldPos: (0, r.vec)(e.px[0], e.px[1]).add(this.worldPos.add(this.offset)),\n entity: e,\n definition: t,\n layer: this\n });\n if (i) {\n const t = this.ldtkToEntity.get(e);\n if (t) {\n const s = this.entities.indexOf(t);\n s > -1 && (this.entities.splice(s, 1), this.ldtkToEntity.delete(e), this.entityToLdtk.delete(t));\n }\n return this.entities.push(i), this.ldtkToEntity.set(e, i), this.entityToLdtk.set(i, e), i;\n }\n }\n }\n }\n getEntitiesByIdentifier(e) {\n const t = this.getLdtkEntitiesByIdentifier(e);\n let s = [];\n for (const e of t){\n const t = this.ldtkToEntity.get(e);\n t && s.push(t);\n }\n return s;\n }\n getEntitiesByField(e, t) {\n const s = this.getLdtkEntitiesByField(e, t);\n let r = [];\n for (const e of s){\n const t = this.ldtkToEntity.get(e);\n t && r.push(t);\n }\n return r;\n }\n getLdtkEntitiesByIdentifier(e) {\n return this.ldtkLayer.entityInstances.filter((t)=>t.__identifier.toLocaleLowerCase() === e.toLowerCase());\n }\n getLdtkEntitiesByField(e, t) {\n return this.ldtkLayer.entityInstances.filter((s)=>{\n if (void 0 !== t) {\n let r = t;\n \"string\" == typeof t && (r = t.toLocaleLowerCase());\n const i = s.fieldInstances.find((t)=>t.__identifier.toLocaleLowerCase() === e.toLocaleLowerCase());\n return !!i && i.__value === r;\n }\n return !!s.fieldInstances.find((t)=>t.__identifier.toLocaleLowerCase() === e.toLocaleLowerCase());\n });\n }\n };\n },\n 710: (e, t)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.FetchLoader = void 0, t.FetchLoader = async (e, t)=>{\n const s = await fetch(e);\n switch(t.toLowerCase()){\n case \"xml\":\n default:\n return await s.text();\n case \"json\":\n return await s.json();\n }\n };\n },\n 607: function(e, t, s) {\n var r = this && this.__createBinding || (Object.create ? function(e, t, s, r) {\n void 0 === r && (r = s);\n var i = Object.getOwnPropertyDescriptor(t, s);\n i && !(\"get\" in i ? !t.__esModule : i.writable || i.configurable) || (i = {\n enumerable: !0,\n get: function() {\n return t[s];\n }\n }), Object.defineProperty(e, r, i);\n } : function(e, t, s, r) {\n void 0 === r && (r = s), e[r] = t[s];\n }), i = this && this.__exportStar || function(e, t) {\n for(var s in e)\"default\" === s || Object.prototype.hasOwnProperty.call(t, s) || r(t, e, s);\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), i(s(398), t), i(s(961), t), i(s(710), t), i(s(920), t), i(s(515), t), i(s(512), t), i(s(289), t), i(s(32), t), i(s(692), t), i(s(245), t), i(s(699), t);\n },\n 920: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.IntGridLayer = void 0;\n const r = s(205);\n t.IntGridLayer = class {\n constructor(e, t, s, i){\n if (this.order = i, this.worldPos = (0, r.vec)(e.ldtkLevel.worldX, e.ldtkLevel.worldY), this.offset = (0, r.vec)(t.__pxTotalOffsetX, t.__pxTotalOffsetY), this.ldtkLayer = t, t.intGridCsv.length) {\n const e = t.__cHei, i = t.__cWid;\n this.tilemap = new r.TileMap({\n name: t.__identifier,\n pos: this.worldPos.add(this.offset),\n tileWidth: t.__gridSize,\n tileHeight: t.__gridSize,\n rows: e,\n columns: i\n });\n const a = s.projectMetadata.defs.layers.find((e)=>t.__identifier === e.identifier);\n if (a) {\n const e = a.intGridValues.find((e)=>{\n var t;\n return \"solid\" === (null === (t = null == e ? void 0 : e.identifier) || void 0 === t ? void 0 : t.toLocaleLowerCase());\n });\n for(let s = 0; s < t.intGridCsv.length; s++){\n const r = s % i, a = Math.floor(s / i), n = this.tilemap.getTile(r, a);\n e && t.intGridCsv[s] === e.value && (n.solid = !0), e || 1 !== t.intGridCsv[s] || (n.solid = !0);\n }\n }\n }\n }\n };\n },\n 398: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.LdtkResource = void 0;\n const r = s(692), i = s(32), a = s(710), n = s(699), o = s(445), d = s(289), l = s(205), u = s(515), c = s(245), p = s(512), h = s(961), f = s(920);\n class m {\n constructor(e, t){\n this.path = e, this.tilesets = new Map, this.levels = new Map, this.levelsByName = new Map, this.factories = new Map, this.fileLoader = a.FetchLoader, this._imageLoader = new d.LoaderCache(l.ImageSource), this._levelLoader = new d.LoaderCache(u.LevelResource), this.startZIndex = 0, this.textQuality = 4, this.useExcaliburWiring = !0, this.useMapBackgroundColor = !1, this.useTilemapCameraStrategy = !1, this.headless = !1, this.strict = !0;\n const { useExcaliburWiring: s, useTilemapCameraStrategy: r, entityIdentifierFactories: i, pathMap: n, useMapBackgroundColor: o, fileLoader: c, strict: p, headless: h, startZIndex: f } = {\n ...t\n };\n this.strict = null != p ? p : this.strict, this.headless = null != h ? h : this.headless, this.useExcaliburWiring = null != s ? s : this.useExcaliburWiring, this.useTilemapCameraStrategy = null != r ? r : this.useTilemapCameraStrategy, this.useMapBackgroundColor = null != o ? o : this.useMapBackgroundColor, this.startZIndex = null != f ? f : this.startZIndex, this.fileLoader = null != c ? c : this.fileLoader, this.pathMap = n;\n for(const e in i)this.registerEntityIdentifierFactory(e, i[e]);\n }\n async load() {\n var e;\n const t = await this.fileLoader(this.path, \"json\");\n if (this.strict) try {\n this.projectMetadata = n.LdtkProjectMetadata.parse(t);\n } catch (e) {\n throw console.error(`Could not parse LDtk map from location ${this.path}.\\nExcalibur only supports the latest version of LDtk formats as of the plugin's release.`), console.error(\"Is your map file corrupted or being interpreted as the wrong type?\"), e;\n }\n else this.projectMetadata = t;\n (0, o.compare)(m.supportedLdtkVersion, null !== (e = this.projectMetadata.jsonVersion) && void 0 !== e ? e : \"0.0.0\", \">\") && console.warn(`The excalibur ldtk plugin officially supports ${m.supportedLdtkVersion}+, the current map has LDtk version ${this.projectMetadata.jsonVersion}`);\n for (let e of this.projectMetadata.defs.tilesets)if (e.relPath) {\n const t = (0, i.pathRelativeToBase)(this.path, e.relPath, this.pathMap), s = this._imageLoader.getOrAdd(t), r = new c.Tileset({\n image: s,\n ldtkTileset: e\n });\n this.tilesets.set(e.uid, r);\n } else \"Internal_Icons\" !== e.identifier && console.warn(`No tileset image provided for ${e.identifier}`);\n for (let e of this.projectMetadata.levels)if (e.externalRelPath) {\n const t = (0, i.pathRelativeToBase)(this.path, e.externalRelPath, this.pathMap);\n this._levelLoader.getOrAdd(t, this, {\n headless: this.headless,\n strict: this.strict,\n fileLoader: this.fileLoader,\n imageLoader: this._imageLoader,\n pathMap: this.pathMap\n });\n } else {\n const t = new p.Level(e, this);\n this.levels.set(e.uid, t), this.levelsByName.set(e.identifier, t);\n }\n return await Promise.all([\n this._imageLoader.load(),\n this._levelLoader.load()\n ]), this._levelLoader.values().forEach((e)=>{\n this.levels.set(e.data.ldtkLevel.uid, e.data), this.levelsByName.set(e.data.ldtkLevel.identifier, e.data);\n }), this.data = this.projectMetadata;\n }\n isLoaded() {\n return !!this.data;\n }\n registerEntityIdentifierFactory(e, t) {\n if (this.factories.set(e, t), this.isLoaded()) for (let t of this.getEntityLayers())t.runFactory(e);\n }\n getLevel(e) {\n return this.levelsByName.get(e);\n }\n getEntityLayers(e) {\n let t = [];\n if (e) {\n const s = this.getLevel(e);\n if (s) for (let e of s.layers)e instanceof h.EntityLayer && t.push(e);\n } else for (const e of this.levels.values())for (let s of e.layers)s instanceof h.EntityLayer && t.push(s);\n return t;\n }\n getTileLayers(e) {\n let t = [];\n if (e) {\n const s = this.getLevel(e);\n if (s) for (let e of s.layers)e instanceof r.TileLayer && t.push(e);\n } else for (const e of this.levels.values())for (let s of e.layers)s instanceof r.TileLayer && t.push(s);\n return t;\n }\n getIntGridLayers(e) {\n let t = [];\n if (e) {\n const s = this.getLevel(e);\n if (s) for (let e of s.layers)e instanceof f.IntGridLayer && t.push(e);\n } else for (const e of this.levels.values())for (let s of e.layers)s instanceof f.IntGridLayer && t.push(s);\n return t;\n }\n getLdtkEntitiesByIdentifier(e) {\n let t = [];\n const s = this.getEntityLayers();\n for (let r of s)t = t.concat(r.getLdtkEntitiesByIdentifier(e));\n return t;\n }\n getLdtkEntitiesByField(e, t) {\n let s = [];\n const r = this.getEntityLayers();\n for (let i of r)s = s.concat(i.getLdtkEntitiesByField(e, t));\n return s;\n }\n addToScene(e, t) {\n var s, i;\n const { pos: a, useLevelOffsets: n } = {\n pos: (0, l.vec)(0, 0),\n useLevelOffsets: !0,\n ...t\n };\n for (let [i, o] of this.levels.entries())if (!(null === (s = null == t ? void 0 : t.levelFilter) || void 0 === s ? void 0 : s.length) || t.levelFilter.includes(o.ldtkLevel.identifier)) for (let t of o.layers)if (t instanceof r.TileLayer || t instanceof f.IntGridLayer) t.tilemap.pos = t.tilemap.pos.add(a), n || (t.tilemap.pos = t.tilemap.pos.sub(t.worldPos)), e.add(t.tilemap);\n else for (let s of t.entities){\n const r = s.get(l.TransformComponent);\n r && (r.pos = r.pos.add(a), n || (r.pos = r.pos.sub(t.worldPos))), e.add(s);\n }\n if (this.useExcaliburWiring) {\n const t = this.getLdtkEntitiesByField(\"camera\", !0)[0];\n if (t) {\n e.camera.pos = (0, l.vec)(t.px[0], t.px[0]);\n const s = t.fieldInstances.find((e)=>\"zoom\" === e.__identifier.toLocaleLowerCase());\n s && (e.camera.zoom = +s.__value);\n }\n }\n if (this.useTilemapCameraStrategy) {\n let t = new l.BoundingBox;\n for (const e of this.levels.values()){\n const s = this.getTileLayers(e.ldtkLevel.identifier)[0];\n s && (t = t.combine(l.BoundingBox.fromDimension(s.tilemap.tileWidth * s.tilemap.columns, s.tilemap.tileHeight * s.tilemap.rows, l.Vector.Zero, s.tilemap.pos)));\n }\n e.camera.strategy.limitCameraBounds(t);\n }\n if (this.useMapBackgroundColor) {\n for (let [s, r] of this.levels.entries())if (!(null === (i = null == t ? void 0 : t.levelFilter) || void 0 === i ? void 0 : i.length) || t.levelFilter.includes(r.ldtkLevel.identifier)) {\n e.backgroundColor = r.backgroundColor;\n break;\n }\n }\n }\n }\n t.LdtkResource = m, m.supportedLdtkVersion = \"1.5.3\";\n },\n 515: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.LevelResource = void 0;\n const r = s(205), i = s(289), a = s(710), n = s(512), o = s(699);\n t.LevelResource = class {\n constructor(e, t, s){\n this.path = e, this.resource = t, this.fileLoader = a.FetchLoader, this.strict = !0, this.headless = !1;\n const { headless: n, strict: o, fileLoader: d, imageLoader: l, pathMap: u } = {\n ...s\n };\n this.fileLoader = null != d ? d : this.fileLoader, this.strict = null != o ? o : this.strict, this.headless = null != n ? n : this.headless, this.imageLoader = null != l ? l : new i.LoaderCache(r.ImageSource), this.pathMap = null != u ? u : this.pathMap;\n }\n async load() {\n const e = await this.fileLoader(this.path, \"json\");\n let t;\n if (this.strict) try {\n t = o.LdtkLevel.parse(e);\n } catch (e) {\n throw console.error(`Could not parse LDtk level data at ${this.path} are you sure a level is there and not corrupt?`), e;\n }\n else t = e;\n return this.data = new n.Level(t, this.resource);\n }\n isLoaded() {\n return !!this.data;\n }\n };\n },\n 512: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.Level = void 0;\n const r = s(205), i = s(961), a = s(920), n = s(692);\n t.Level = class {\n constructor(e, t){\n var s, o, d;\n if (this.ldtkLevel = e, this.resource = t, this.layers = [], e.__bgColor && (this.backgroundColor = r.Color.fromHex(e.__bgColor)), e.layerInstances) {\n let r = t.startZIndex, l = e.layerInstances.slice().reverse();\n for (let e of l)0 !== (null === (s = e.entityInstances) || void 0 === s ? void 0 : s.length) && this.layers.push(new i.EntityLayer(this, e, t, r)), 0 !== (null === (o = e.gridTiles) || void 0 === o ? void 0 : o.length) && this.layers.push(new n.TileLayer(this, e, t, r)), 0 !== (null === (d = e.intGridCsv) || void 0 === d ? void 0 : d.length) && this.layers.push(new a.IntGridLayer(this, e, t, r)), r++;\n }\n }\n };\n },\n 289: (e, t)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.LoaderCache = void 0, t.LoaderCache = class {\n constructor(e){\n this.type = e, this._loaded = !1, this.cache = new Map;\n }\n getOrAdd(...e) {\n let t = this.cache.get(e.join(\"+\"));\n return t || (t = new this.type(...e), this.cache.set(e.join(\"+\"), t), t);\n }\n values() {\n if (this._loaded) return Array.from(this.cache.values());\n throw new Error(\"Read through cache not yet loaded! No values to return!\");\n }\n async load() {\n const e = Array.from(this.cache.entries()), t = await Promise.allSettled(e.map((e)=>e[1].load()));\n let s = 0;\n for(let r = 0; r < t.length; r++){\n const i = t[r];\n \"rejected\" === i.status && (console.error(`Error loading resource at ${e[r][0]}, is your pathMap correct? or your LDtk map corrupted?`, i.reason), s++);\n }\n if (s) throw new Error(`Error loading ${s} resources`);\n this._loaded = !0;\n }\n };\n },\n 32: (e, t)=>{\n function s(e, t) {\n for (const { path: s, output: r } of t)if (\"string\" == typeof s) {\n if (e.includes(s)) return r;\n } else {\n const t = e.match(s);\n if (t) return r.replace(\"[match]\", t[0]);\n }\n return e;\n }\n function r(e, t) {\n if (!t) return !1;\n for (const { path: s, output: r } of t)if (\"string\" == typeof s) {\n if (e.includes(s)) return !0;\n } else if (e.match(s)) return !0;\n return !1;\n }\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.pathRelativeToBase = t.pathInMap = t.mapPath = t.filenameFromPath = void 0, t.filenameFromPath = function(e) {\n const t = e.match(/[^/\\\\&\\?]+\\.\\w{2,4}(?=([\\#\\?&].*$|$))/gi);\n if (t) return t[0];\n throw new Error(`Could not locate filename from path: ${e}`);\n }, t.mapPath = s, t.pathInMap = r, t.pathRelativeToBase = function(e, t, i) {\n if (r(t, i) && i) return s(t, i);\n if (0 === t.indexOf(\"/\")) return t;\n const a = e.split(\"/\"), n = t.split(\"/\");\n return a[a.length - 1].includes(\".\") && a.pop(), a.concat(n).join(\"/\");\n };\n },\n 692: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.TileLayer = void 0;\n const r = s(205);\n t.TileLayer = class {\n constructor(e, t, s, i){\n this.order = i, this.worldPos = (0, r.vec)(e.ldtkLevel.worldX, e.ldtkLevel.worldY), this.offset = (0, r.vec)(t.__pxTotalOffsetX, t.__pxTotalOffsetY), this.ldtkLayer = t, this.tilemap = new r.TileMap({\n name: t.__identifier,\n pos: this.worldPos.add(this.offset),\n tileWidth: t.__gridSize,\n tileHeight: t.__gridSize,\n rows: t.__cHei,\n columns: t.__cWid\n }), this.tilemap.z = i;\n for (let e of t.gridTiles){\n const r = Math.floor(e.px[0] / t.__gridSize), i = Math.floor(e.px[1] / t.__gridSize), a = this.tilemap.getTile(r, i);\n if (t.__tilesetDefUid) {\n const r = s.tilesets.get(t.__tilesetDefUid);\n if (r) {\n const t = Math.floor(e.src[0] / r.ldtkTileset.tileGridSize), s = Math.floor(e.src[1] / r.ldtkTileset.tileGridSize), i = r.spritesheet.getSprite(t, s);\n i ? a.addGraphic(i) : console.error(\"Could not find sprite in LDtk spritesheet at\", t, s);\n }\n } else console.error(\"Could not tileset in LDtk\", t.__tilesetDefUid, t.__tilesetRelPath);\n }\n }\n };\n },\n 245: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.Tileset = void 0;\n const r = s(205);\n t.Tileset = class {\n constructor(e){\n const { image: t, ldtkTileset: s } = e;\n this.image = t, this.ldtkTileset = s, this.spritesheet = r.SpriteSheet.fromImageSource({\n image: t,\n grid: {\n rows: s.pxHei / s.tileGridSize,\n columns: s.pxWid / s.tileGridSize,\n spriteHeight: s.tileGridSize,\n spriteWidth: s.tileGridSize\n }\n });\n }\n };\n },\n 699: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.LdtkProjectMetadata = t.LdtkEntityDefinition = t.LdtkLayerDefinition = t.LdtkLevel = t.LdtkLayerInstance = t.LdtkEntityInstance = void 0;\n const r = s(754), i = r.z.object({\n h: r.z.number(),\n tilesetUid: r.z.number(),\n w: r.z.number(),\n x: r.z.number(),\n y: r.z.number()\n }), a = r.z.tuple([\n r.z.number(),\n r.z.number()\n ]), n = r.z.object({\n __identifier: r.z.string(),\n __tile: i.nullable(),\n __type: r.z.string(),\n __value: r.z.any(),\n defUid: r.z.number()\n }), o = r.z.object({\n a: r.z.number(),\n f: r.z.number(),\n px: a,\n src: a,\n t: r.z.number()\n });\n t.LdtkEntityInstance = r.z.object({\n __grid: a,\n __identifier: r.z.string(),\n __pivot: a,\n __smartColor: r.z.string(),\n __tags: r.z.array(r.z.string()),\n __tile: i.nullable(),\n __worldX: r.z.number().nullable(),\n __worldY: r.z.number().nullable(),\n defUid: r.z.number(),\n fieldInstances: r.z.array(n),\n height: r.z.number(),\n iid: r.z.string(),\n px: a,\n width: r.z.number()\n }), t.LdtkLayerInstance = r.z.object({\n __cHei: r.z.number(),\n __cWid: r.z.number(),\n __gridSize: r.z.number(),\n __identifier: r.z.string(),\n __opacity: r.z.number(),\n __pxTotalOffsetX: r.z.number(),\n __pxTotalOffsetY: r.z.number(),\n __tilesetDefUid: r.z.number().nullable(),\n __tilesetRelPath: r.z.string().nullable(),\n __type: r.z.union([\n r.z.literal(\"IntGrid\"),\n r.z.literal(\"Entities\"),\n r.z.literal(\"Tiles\"),\n r.z.literal(\"AutoLayer\")\n ]),\n autoLayerTiles: r.z.array(o),\n entityInstances: r.z.array(t.LdtkEntityInstance),\n gridTiles: r.z.array(o),\n iid: r.z.string(),\n intGridCsv: r.z.array(r.z.number()),\n layerDefUid: r.z.number(),\n levelId: r.z.number(),\n overrideTilesetUid: r.z.number().nullable(),\n pxOffsetX: r.z.number(),\n pxOffsetY: r.z.number(),\n visible: r.z.boolean()\n }), t.LdtkLevel = r.z.object({\n __bgColor: r.z.string().nullable(),\n bgColor: r.z.string().nullable(),\n __bgPos: r.z.object({\n cropRect: r.z.array(r.z.tuple([\n r.z.number(),\n r.z.number(),\n r.z.number(),\n r.z.number()\n ])),\n scale: r.z.tuple([\n r.z.number(),\n r.z.number()\n ]),\n topLeftPx: a\n }).nullable(),\n __neighbours: r.z.array(r.z.object({\n dir: r.z.union([\n r.z.literal(\"n\"),\n r.z.literal(\"s\"),\n r.z.literal(\"w\"),\n r.z.literal(\"e\"),\n r.z.literal(\"ne\"),\n r.z.literal(\"nw\"),\n r.z.literal(\"se\"),\n r.z.literal(\"sw\"),\n r.z.literal(\"o\"),\n r.z.literal(\"<\"),\n r.z.literal(\">\")\n ]),\n levelIid: r.z.string()\n })),\n bgRelPath: r.z.string().nullable(),\n externalRelPath: r.z.string().nullable(),\n fieldInstances: r.z.array(n),\n identifier: r.z.string(),\n iid: r.z.string(),\n layerInstances: r.z.array(t.LdtkLayerInstance).nullable(),\n pxHei: r.z.number(),\n pxWid: r.z.number(),\n uid: r.z.number(),\n worldDepth: r.z.number(),\n worldX: r.z.number(),\n worldY: r.z.number()\n });\n const d = r.z.object({\n identifier: r.z.string(),\n iid: r.z.string(),\n levels: r.z.array(t.LdtkLevel),\n worldGridHeight: r.z.number(),\n worldGridWidth: r.z.number(),\n worldLayout: r.z.union([\n r.z.literal(\"Free\"),\n r.z.literal(\"GridVania\"),\n r.z.literal(\"LinearHorizontal\"),\n r.z.literal(\"LinearVertical\")\n ])\n }), l = r.z.object({\n color: r.z.number(),\n id: r.z.string(),\n tileRect: i.nullable()\n }), u = r.z.object({\n externalRelPath: r.z.string().nullable(),\n iconTilesetUid: r.z.number().nullable(),\n identifier: r.z.string(),\n tags: r.z.array(r.z.string()),\n uid: r.z.number(),\n values: r.z.array(l)\n }), c = r.z.object({\n __cHei: r.z.number(),\n __cWid: r.z.number(),\n customData: r.z.array(r.z.object({\n data: r.z.string(),\n tileId: r.z.number()\n })),\n embedAtlas: r.z.string().nullable(),\n enumsTags: r.z.optional(r.z.array(r.z.object({\n enumValueId: r.z.string(),\n tileIds: r.z.array(r.z.number())\n }))),\n identifier: r.z.string(),\n padding: r.z.number(),\n pxHei: r.z.number(),\n pxWid: r.z.number(),\n relPath: r.z.string().nullable(),\n spacing: r.z.number(),\n tags: r.z.array(r.z.string()),\n tagsSourceEnumUid: r.z.number().nullable(),\n tileGridSize: r.z.number(),\n uid: r.z.number()\n });\n t.LdtkLayerDefinition = r.z.object({\n __type: r.z.union([\n r.z.literal(\"IntGrid\"),\n r.z.literal(\"Entities\"),\n r.z.literal(\"Tiles\"),\n r.z.literal(\"AutoLayer\")\n ]),\n autoSourceLayerDefUid: r.z.number().nullable(),\n displayOpacity: r.z.number(),\n gridSize: r.z.number(),\n identifier: r.z.string(),\n intGridValues: r.z.array(r.z.object({\n color: r.z.string(),\n groupUid: r.z.number(),\n identifier: r.z.string().nullable(),\n tile: i.nullable(),\n value: r.z.number()\n })),\n intGridValuesGroups: r.z.array(r.z.object({\n color: r.z.string().nullable(),\n identifier: r.z.string().nullable(),\n uid: r.z.number()\n })),\n parallaxFactorX: r.z.number(),\n parallaxFactorY: r.z.number(),\n parallaxScaling: r.z.boolean(),\n pxOffsetX: r.z.number(),\n pxOffsetY: r.z.number(),\n tilesetDefUid: r.z.number().nullable(),\n uid: r.z.number()\n }), t.LdtkEntityDefinition = r.z.object({\n color: r.z.string(),\n height: r.z.number(),\n identifier: r.z.string(),\n nineSliceBorders: r.z.array(r.z.number()),\n pivotX: r.z.number(),\n pivotY: r.z.number(),\n tileRect: i.nullable(),\n tileRenderMode: r.z.union([\n r.z.literal(\"Cover\"),\n r.z.literal(\"FitInside\"),\n r.z.literal(\"Repeat\"),\n r.z.literal(\"Stretch\"),\n r.z.literal(\"FullSizeCropped\"),\n r.z.literal(\"FullSizeUncropped\"),\n r.z.literal(\"NineSlice\")\n ]),\n tilesetId: r.z.number().nullable(),\n uiTileRect: i.nullable(),\n uid: r.z.number(),\n width: r.z.number()\n });\n const p = r.z.object({\n tilesets: r.z.array(c),\n enums: r.z.array(u),\n layers: r.z.array(t.LdtkLayerDefinition),\n entities: r.z.array(t.LdtkEntityDefinition)\n });\n t.LdtkProjectMetadata = r.z.object({\n iid: r.z.string(),\n bgColor: r.z.string().nullable(),\n defs: p,\n externalLevels: r.z.boolean(),\n jsonVersion: r.z.string(),\n levels: r.z.array(t.LdtkLevel),\n toc: r.z.array(r.z.object({\n identifier: r.z.string(),\n instancesData: r.z.array(r.z.object({\n fields: r.z.any(),\n heiPx: r.z.number(),\n iids: r.z.string(),\n widPix: r.z.number(),\n worldX: r.z.number(),\n worldY: r.z.number()\n }))\n })),\n worldGridHeight: r.z.number().nullable(),\n worldGridWidth: r.z.number().nullable(),\n worldLayout: r.z.union([\n r.z.literal(\"Free\"),\n r.z.literal(\"GridVania\"),\n r.z.literal(\"LinearHorizontal\"),\n r.z.literal(\"LinearVertical\")\n ]).nullable(),\n worlds: r.z.array(d)\n });\n },\n 280: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.ZodError = t.quotelessJson = t.ZodIssueCode = void 0;\n const r = s(110);\n t.ZodIssueCode = r.util.arrayToEnum([\n \"invalid_type\",\n \"invalid_literal\",\n \"custom\",\n \"invalid_union\",\n \"invalid_union_discriminator\",\n \"invalid_enum_value\",\n \"unrecognized_keys\",\n \"invalid_arguments\",\n \"invalid_return_type\",\n \"invalid_date\",\n \"invalid_string\",\n \"too_small\",\n \"too_big\",\n \"invalid_intersection_types\",\n \"not_multiple_of\",\n \"not_finite\"\n ]), t.quotelessJson = (e)=>JSON.stringify(e, null, 2).replace(/\"([^\"]+)\":/g, \"$1:\");\n class i extends Error {\n constructor(e){\n super(), this.issues = [], this.addIssue = (e)=>{\n this.issues = [\n ...this.issues,\n e\n ];\n }, this.addIssues = (e = [])=>{\n this.issues = [\n ...this.issues,\n ...e\n ];\n };\n const t = new.target.prototype;\n Object.setPrototypeOf ? Object.setPrototypeOf(this, t) : this.__proto__ = t, this.name = \"ZodError\", this.issues = e;\n }\n get errors() {\n return this.issues;\n }\n format(e) {\n const t = e || function(e) {\n return e.message;\n }, s = {\n _errors: []\n }, r = (e)=>{\n for (const i of e.issues)if (\"invalid_union\" === i.code) i.unionErrors.map(r);\n else if (\"invalid_return_type\" === i.code) r(i.returnTypeError);\n else if (\"invalid_arguments\" === i.code) r(i.argumentsError);\n else if (0 === i.path.length) s._errors.push(t(i));\n else {\n let e = s, r = 0;\n for(; r < i.path.length;){\n const s = i.path[r];\n r === i.path.length - 1 ? (e[s] = e[s] || {\n _errors: []\n }, e[s]._errors.push(t(i))) : e[s] = e[s] || {\n _errors: []\n }, e = e[s], r++;\n }\n }\n };\n return r(this), s;\n }\n toString() {\n return this.message;\n }\n get message() {\n return JSON.stringify(this.issues, r.util.jsonStringifyReplacer, 2);\n }\n get isEmpty() {\n return 0 === this.issues.length;\n }\n flatten(e = (e)=>e.message) {\n const t = {}, s = [];\n for (const r of this.issues)r.path.length > 0 ? (t[r.path[0]] = t[r.path[0]] || [], t[r.path[0]].push(e(r))) : s.push(e(r));\n return {\n formErrors: s,\n fieldErrors: t\n };\n }\n get formErrors() {\n return this.flatten();\n }\n }\n t.ZodError = i, i.create = (e)=>new i(e);\n },\n 996: function(e, t, s) {\n var r = this && this.__importDefault || function(e) {\n return e && e.__esModule ? e : {\n default: e\n };\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.getErrorMap = t.setErrorMap = t.defaultErrorMap = void 0;\n const i = r(s(325));\n t.defaultErrorMap = i.default;\n let a = i.default;\n t.setErrorMap = function(e) {\n a = e;\n }, t.getErrorMap = function() {\n return a;\n };\n },\n 349: function(e, t, s) {\n var r = this && this.__createBinding || (Object.create ? function(e, t, s, r) {\n void 0 === r && (r = s), Object.defineProperty(e, r, {\n enumerable: !0,\n get: function() {\n return t[s];\n }\n });\n } : function(e, t, s, r) {\n void 0 === r && (r = s), e[r] = t[s];\n }), i = this && this.__exportStar || function(e, t) {\n for(var s in e)\"default\" === s || Object.prototype.hasOwnProperty.call(t, s) || r(t, e, s);\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), i(s(996), t), i(s(187), t), i(s(116), t), i(s(110), t), i(s(433), t), i(s(280), t);\n },\n 762: (e, t)=>{\n var s;\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.errorUtil = void 0, (s = t.errorUtil || (t.errorUtil = {})).errToObj = (e)=>\"string\" == typeof e ? {\n message: e\n } : e || {}, s.toString = (e)=>\"string\" == typeof e ? e : null == e ? void 0 : e.message;\n },\n 187: function(e, t, s) {\n var r = this && this.__importDefault || function(e) {\n return e && e.__esModule ? e : {\n default: e\n };\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.isAsync = t.isValid = t.isDirty = t.isAborted = t.OK = t.DIRTY = t.INVALID = t.ParseStatus = t.addIssueToContext = t.EMPTY_PATH = t.makeIssue = void 0;\n const i = s(996), a = r(s(325));\n t.makeIssue = (e)=>{\n const { data: t, path: s, errorMaps: r, issueData: i } = e, a = [\n ...s,\n ...i.path || []\n ], n = {\n ...i,\n path: a\n };\n let o = \"\";\n const d = r.filter((e)=>!!e).slice().reverse();\n for (const e of d)o = e(n, {\n data: t,\n defaultError: o\n }).message;\n return {\n ...i,\n path: a,\n message: i.message || o\n };\n }, t.EMPTY_PATH = [], t.addIssueToContext = function(e, s) {\n const r = (0, t.makeIssue)({\n issueData: s,\n data: e.data,\n path: e.path,\n errorMaps: [\n e.common.contextualErrorMap,\n e.schemaErrorMap,\n (0, i.getErrorMap)(),\n a.default\n ].filter((e)=>!!e)\n });\n e.common.issues.push(r);\n };\n class n {\n constructor(){\n this.value = \"valid\";\n }\n dirty() {\n \"valid\" === this.value && (this.value = \"dirty\");\n }\n abort() {\n \"aborted\" !== this.value && (this.value = \"aborted\");\n }\n static mergeArray(e, s) {\n const r = [];\n for (const i of s){\n if (\"aborted\" === i.status) return t.INVALID;\n \"dirty\" === i.status && e.dirty(), r.push(i.value);\n }\n return {\n status: e.value,\n value: r\n };\n }\n static async mergeObjectAsync(e, t) {\n const s = [];\n for (const e of t)s.push({\n key: await e.key,\n value: await e.value\n });\n return n.mergeObjectSync(e, s);\n }\n static mergeObjectSync(e, s) {\n const r = {};\n for (const i of s){\n const { key: s, value: a } = i;\n if (\"aborted\" === s.status) return t.INVALID;\n if (\"aborted\" === a.status) return t.INVALID;\n \"dirty\" === s.status && e.dirty(), \"dirty\" === a.status && e.dirty(), \"__proto__\" === s.value || void 0 === a.value && !i.alwaysSet || (r[s.value] = a.value);\n }\n return {\n status: e.value,\n value: r\n };\n }\n }\n t.ParseStatus = n, t.INVALID = Object.freeze({\n status: \"aborted\"\n }), t.DIRTY = (e)=>({\n status: \"dirty\",\n value: e\n }), t.OK = (e)=>({\n status: \"valid\",\n value: e\n }), t.isAborted = (e)=>\"aborted\" === e.status, t.isDirty = (e)=>\"dirty\" === e.status, t.isValid = (e)=>\"valid\" === e.status, t.isAsync = (e)=>\"undefined\" != typeof Promise && e instanceof Promise;\n },\n 116: (e, t)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n });\n },\n 110: (e, t)=>{\n var s;\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.getParsedType = t.ZodParsedType = t.objectUtil = t.util = void 0, function(e) {\n e.assertEqual = (e)=>e, e.assertIs = function(e) {}, e.assertNever = function(e) {\n throw new Error;\n }, e.arrayToEnum = (e)=>{\n const t = {};\n for (const s of e)t[s] = s;\n return t;\n }, e.getValidEnumValues = (t)=>{\n const s = e.objectKeys(t).filter((e)=>\"number\" != typeof t[t[e]]), r = {};\n for (const e of s)r[e] = t[e];\n return e.objectValues(r);\n }, e.objectValues = (t)=>e.objectKeys(t).map(function(e) {\n return t[e];\n }), e.objectKeys = \"function\" == typeof Object.keys ? (e)=>Object.keys(e) : (e)=>{\n const t = [];\n for(const s in e)Object.prototype.hasOwnProperty.call(e, s) && t.push(s);\n return t;\n }, e.find = (e, t)=>{\n for (const s of e)if (t(s)) return s;\n }, e.isInteger = \"function\" == typeof Number.isInteger ? (e)=>Number.isInteger(e) : (e)=>\"number\" == typeof e && isFinite(e) && Math.floor(e) === e, e.joinValues = function(e, t = \" | \") {\n return e.map((e)=>\"string\" == typeof e ? `'${e}'` : e).join(t);\n }, e.jsonStringifyReplacer = (e, t)=>\"bigint\" == typeof t ? t.toString() : t;\n }(s = t.util || (t.util = {})), (t.objectUtil || (t.objectUtil = {})).mergeShapes = (e, t)=>({\n ...e,\n ...t\n }), t.ZodParsedType = s.arrayToEnum([\n \"string\",\n \"nan\",\n \"number\",\n \"integer\",\n \"float\",\n \"boolean\",\n \"date\",\n \"bigint\",\n \"symbol\",\n \"function\",\n \"undefined\",\n \"null\",\n \"array\",\n \"object\",\n \"unknown\",\n \"promise\",\n \"void\",\n \"never\",\n \"map\",\n \"set\"\n ]), t.getParsedType = (e)=>{\n switch(typeof e){\n case \"undefined\":\n return t.ZodParsedType.undefined;\n case \"string\":\n return t.ZodParsedType.string;\n case \"number\":\n return isNaN(e) ? t.ZodParsedType.nan : t.ZodParsedType.number;\n case \"boolean\":\n return t.ZodParsedType.boolean;\n case \"function\":\n return t.ZodParsedType.function;\n case \"bigint\":\n return t.ZodParsedType.bigint;\n case \"symbol\":\n return t.ZodParsedType.symbol;\n case \"object\":\n return Array.isArray(e) ? t.ZodParsedType.array : null === e ? t.ZodParsedType.null : e.then && \"function\" == typeof e.then && e.catch && \"function\" == typeof e.catch ? t.ZodParsedType.promise : \"undefined\" != typeof Map && e instanceof Map ? t.ZodParsedType.map : \"undefined\" != typeof Set && e instanceof Set ? t.ZodParsedType.set : \"undefined\" != typeof Date && e instanceof Date ? t.ZodParsedType.date : t.ZodParsedType.object;\n default:\n return t.ZodParsedType.unknown;\n }\n };\n },\n 754: function(e, t, s) {\n var r = this && this.__createBinding || (Object.create ? function(e, t, s, r) {\n void 0 === r && (r = s), Object.defineProperty(e, r, {\n enumerable: !0,\n get: function() {\n return t[s];\n }\n });\n } : function(e, t, s, r) {\n void 0 === r && (r = s), e[r] = t[s];\n }), i = this && this.__setModuleDefault || (Object.create ? function(e, t) {\n Object.defineProperty(e, \"default\", {\n enumerable: !0,\n value: t\n });\n } : function(e, t) {\n e.default = t;\n }), a = this && this.__importStar || function(e) {\n if (e && e.__esModule) return e;\n var t = {};\n if (null != e) for(var s in e)\"default\" !== s && Object.prototype.hasOwnProperty.call(e, s) && r(t, e, s);\n return i(t, e), t;\n }, n = this && this.__exportStar || function(e, t) {\n for(var s in e)\"default\" === s || Object.prototype.hasOwnProperty.call(t, s) || r(t, e, s);\n };\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.z = void 0;\n const o = a(s(349));\n t.z = o, n(s(349), t), t.default = o;\n },\n 325: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n });\n const r = s(110), i = s(280);\n t.default = (e, t)=>{\n let s;\n switch(e.code){\n case i.ZodIssueCode.invalid_type:\n s = e.received === r.ZodParsedType.undefined ? \"Required\" : `Expected ${e.expected}, received ${e.received}`;\n break;\n case i.ZodIssueCode.invalid_literal:\n s = `Invalid literal value, expected ${JSON.stringify(e.expected, r.util.jsonStringifyReplacer)}`;\n break;\n case i.ZodIssueCode.unrecognized_keys:\n s = `Unrecognized key(s) in object: ${r.util.joinValues(e.keys, \", \")}`;\n break;\n case i.ZodIssueCode.invalid_union:\n s = \"Invalid input\";\n break;\n case i.ZodIssueCode.invalid_union_discriminator:\n s = `Invalid discriminator value. Expected ${r.util.joinValues(e.options)}`;\n break;\n case i.ZodIssueCode.invalid_enum_value:\n s = `Invalid enum value. Expected ${r.util.joinValues(e.options)}, received '${e.received}'`;\n break;\n case i.ZodIssueCode.invalid_arguments:\n s = \"Invalid function arguments\";\n break;\n case i.ZodIssueCode.invalid_return_type:\n s = \"Invalid function return type\";\n break;\n case i.ZodIssueCode.invalid_date:\n s = \"Invalid date\";\n break;\n case i.ZodIssueCode.invalid_string:\n \"object\" == typeof e.validation ? \"includes\" in e.validation ? (s = `Invalid input: must include \"${e.validation.includes}\"`, \"number\" == typeof e.validation.position && (s = `${s} at one or more positions greater than or equal to ${e.validation.position}`)) : \"startsWith\" in e.validation ? s = `Invalid input: must start with \"${e.validation.startsWith}\"` : \"endsWith\" in e.validation ? s = `Invalid input: must end with \"${e.validation.endsWith}\"` : r.util.assertNever(e.validation) : s = \"regex\" !== e.validation ? `Invalid ${e.validation}` : \"Invalid\";\n break;\n case i.ZodIssueCode.too_small:\n s = \"array\" === e.type ? `Array must contain ${e.exact ? \"exactly\" : e.inclusive ? \"at least\" : \"more than\"} ${e.minimum} element(s)` : \"string\" === e.type ? `String must contain ${e.exact ? \"exactly\" : e.inclusive ? \"at least\" : \"over\"} ${e.minimum} character(s)` : \"number\" === e.type ? `Number must be ${e.exact ? \"exactly equal to \" : e.inclusive ? \"greater than or equal to \" : \"greater than \"}${e.minimum}` : \"date\" === e.type ? `Date must be ${e.exact ? \"exactly equal to \" : e.inclusive ? \"greater than or equal to \" : \"greater than \"}${new Date(Number(e.minimum))}` : \"Invalid input\";\n break;\n case i.ZodIssueCode.too_big:\n s = \"array\" === e.type ? `Array must contain ${e.exact ? \"exactly\" : e.inclusive ? \"at most\" : \"less than\"} ${e.maximum} element(s)` : \"string\" === e.type ? `String must contain ${e.exact ? \"exactly\" : e.inclusive ? \"at most\" : \"under\"} ${e.maximum} character(s)` : \"number\" === e.type ? `Number must be ${e.exact ? \"exactly\" : e.inclusive ? \"less than or equal to\" : \"less than\"} ${e.maximum}` : \"bigint\" === e.type ? `BigInt must be ${e.exact ? \"exactly\" : e.inclusive ? \"less than or equal to\" : \"less than\"} ${e.maximum}` : \"date\" === e.type ? `Date must be ${e.exact ? \"exactly\" : e.inclusive ? \"smaller than or equal to\" : \"smaller than\"} ${new Date(Number(e.maximum))}` : \"Invalid input\";\n break;\n case i.ZodIssueCode.custom:\n s = \"Invalid input\";\n break;\n case i.ZodIssueCode.invalid_intersection_types:\n s = \"Intersection results could not be merged\";\n break;\n case i.ZodIssueCode.not_multiple_of:\n s = `Number must be a multiple of ${e.multipleOf}`;\n break;\n case i.ZodIssueCode.not_finite:\n s = \"Number must be finite\";\n break;\n default:\n s = t.defaultError, r.util.assertNever(e);\n }\n return {\n message: s\n };\n };\n },\n 433: (e, t, s)=>{\n Object.defineProperty(t, \"__esModule\", {\n value: !0\n }), t.date = t.boolean = t.bigint = t.array = t.any = t.coerce = t.ZodFirstPartyTypeKind = t.late = t.ZodSchema = t.Schema = t.custom = t.ZodReadonly = t.ZodPipeline = t.ZodBranded = t.BRAND = t.ZodNaN = t.ZodCatch = t.ZodDefault = t.ZodNullable = t.ZodOptional = t.ZodTransformer = t.ZodEffects = t.ZodPromise = t.ZodNativeEnum = t.ZodEnum = t.ZodLiteral = t.ZodLazy = t.ZodFunction = t.ZodSet = t.ZodMap = t.ZodRecord = t.ZodTuple = t.ZodIntersection = t.ZodDiscriminatedUnion = t.ZodUnion = t.ZodObject = t.ZodArray = t.ZodVoid = t.ZodNever = t.ZodUnknown = t.ZodAny = t.ZodNull = t.ZodUndefined = t.ZodSymbol = t.ZodDate = t.ZodBoolean = t.ZodBigInt = t.ZodNumber = t.ZodString = t.ZodType = void 0, t.NEVER = t.void = t.unknown = t.union = t.undefined = t.tuple = t.transformer = t.symbol = t.string = t.strictObject = t.set = t.record = t.promise = t.preprocess = t.pipeline = t.ostring = t.optional = t.onumber = t.oboolean = t.object = t.number = t.nullable = t.null = t.never = t.nativeEnum = t.nan = t.map = t.literal = t.lazy = t.intersection = t.instanceof = t.function = t.enum = t.effect = t.discriminatedUnion = void 0;\n const r = s(996), i = s(762), a = s(187), n = s(110), o = s(280);\n class d {\n constructor(e, t, s, r){\n this._cachedPath = [], this.parent = e, this.data = t, this._path = s, this._key = r;\n }\n get path() {\n return this._cachedPath.length || (this._key instanceof Array ? this._cachedPath.push(...this._path, ...this._key) : this._cachedPath.push(...this._path, this._key)), this._cachedPath;\n }\n }\n const l = (e, t)=>{\n if ((0, a.isValid)(t)) return {\n success: !0,\n data: t.value\n };\n if (!e.common.issues.length) throw new Error(\"Validation failed but no issues detected.\");\n return {\n success: !1,\n get error () {\n if (this._error) return this._error;\n const t = new o.ZodError(e.common.issues);\n return this._error = t, this._error;\n }\n };\n };\n function u(e) {\n if (!e) return {};\n const { errorMap: t, invalid_type_error: s, required_error: r, description: i } = e;\n if (t && (s || r)) throw new Error('Can\\'t use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.');\n return t ? {\n errorMap: t,\n description: i\n } : {\n errorMap: (e, t)=>\"invalid_type\" !== e.code ? {\n message: t.defaultError\n } : void 0 === t.data ? {\n message: null != r ? r : t.defaultError\n } : {\n message: null != s ? s : t.defaultError\n },\n description: i\n };\n }\n class c {\n constructor(e){\n this.spa = this.safeParseAsync, this._def = e, this.parse = this.parse.bind(this), this.safeParse = this.safeParse.bind(this), this.parseAsync = this.parseAsync.bind(this), this.safeParseAsync = this.safeParseAsync.bind(this), this.spa = this.spa.bind(this), this.refine = this.refine.bind(this), this.refinement = this.refinement.bind(this), this.superRefine = this.superRefine.bind(this), this.optional = this.optional.bind(this), this.nullable = this.nullable.bind(this), this.nullish = this.nullish.bind(this), this.array = this.array.bind(this), this.promise = this.promise.bind(this), this.or = this.or.bind(this), this.and = this.and.bind(this), this.transform = this.transform.bind(this), this.brand = this.brand.bind(this), this.default = this.default.bind(this), this.catch = this.catch.bind(this), this.describe = this.describe.bind(this), this.pipe = this.pipe.bind(this), this.readonly = this.readonly.bind(this), this.isNullable = this.isNullable.bind(this), this.isOptional = this.isOptional.bind(this);\n }\n get description() {\n return this._def.description;\n }\n _getType(e) {\n return (0, n.getParsedType)(e.data);\n }\n _getOrReturnCtx(e, t) {\n return t || {\n common: e.parent.common,\n data: e.data,\n parsedType: (0, n.getParsedType)(e.data),\n schemaErrorMap: this._def.errorMap,\n path: e.path,\n parent: e.parent\n };\n }\n _processInputParams(e) {\n return {\n status: new a.ParseStatus,\n ctx: {\n common: e.parent.common,\n data: e.data,\n parsedType: (0, n.getParsedType)(e.data),\n schemaErrorMap: this._def.errorMap,\n path: e.path,\n parent: e.parent\n }\n };\n }\n _parseSync(e) {\n const t = this._parse(e);\n if ((0, a.isAsync)(t)) throw new Error(\"Synchronous parse encountered promise.\");\n return t;\n }\n _parseAsync(e) {\n const t = this._parse(e);\n return Promise.resolve(t);\n }\n parse(e, t) {\n const s = this.safeParse(e, t);\n if (s.success) return s.data;\n throw s.error;\n }\n safeParse(e, t) {\n var s;\n const r = {\n common: {\n issues: [],\n async: null !== (s = null == t ? void 0 : t.async) && void 0 !== s && s,\n contextualErrorMap: null == t ? void 0 : t.errorMap\n },\n path: (null == t ? void 0 : t.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data: e,\n parsedType: (0, n.getParsedType)(e)\n }, i = this._parseSync({\n data: e,\n path: r.path,\n parent: r\n });\n return l(r, i);\n }\n async parseAsync(e, t) {\n const s = await this.safeParseAsync(e, t);\n if (s.success) return s.data;\n throw s.error;\n }\n async safeParseAsync(e, t) {\n const s = {\n common: {\n issues: [],\n contextualErrorMap: null == t ? void 0 : t.errorMap,\n async: !0\n },\n path: (null == t ? void 0 : t.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data: e,\n parsedType: (0, n.getParsedType)(e)\n }, r = this._parse({\n data: e,\n path: s.path,\n parent: s\n }), i = await ((0, a.isAsync)(r) ? r : Promise.resolve(r));\n return l(s, i);\n }\n refine(e, t) {\n const s = (e)=>\"string\" == typeof t || void 0 === t ? {\n message: t\n } : \"function\" == typeof t ? t(e) : t;\n return this._refinement((t, r)=>{\n const i = e(t), a = ()=>r.addIssue({\n code: o.ZodIssueCode.custom,\n ...s(t)\n });\n return \"undefined\" != typeof Promise && i instanceof Promise ? i.then((e)=>!!e || (a(), !1)) : !!i || (a(), !1);\n });\n }\n refinement(e, t) {\n return this._refinement((s, r)=>!!e(s) || (r.addIssue(\"function\" == typeof t ? t(s, r) : t), !1));\n }\n _refinement(e) {\n return new J({\n schema: this,\n typeName: oe.ZodEffects,\n effect: {\n type: \"refinement\",\n refinement: e\n }\n });\n }\n superRefine(e) {\n return this._refinement(e);\n }\n optional() {\n return Q.create(this, this._def);\n }\n nullable() {\n return ee.create(this, this._def);\n }\n nullish() {\n return this.nullable().optional();\n }\n array() {\n return E.create(this, this._def);\n }\n promise() {\n return X.create(this, this._def);\n }\n or(e) {\n return M.create([\n this,\n e\n ], this._def);\n }\n and(e) {\n return R.create(this, e, this._def);\n }\n transform(e) {\n return new J({\n ...u(this._def),\n schema: this,\n typeName: oe.ZodEffects,\n effect: {\n type: \"transform\",\n transform: e\n }\n });\n }\n default(e) {\n const t = \"function\" == typeof e ? e : ()=>e;\n return new te({\n ...u(this._def),\n innerType: this,\n defaultValue: t,\n typeName: oe.ZodDefault\n });\n }\n brand() {\n return new ie({\n typeName: oe.ZodBranded,\n type: this,\n ...u(this._def)\n });\n }\n catch(e) {\n const t = \"function\" == typeof e ? e : ()=>e;\n return new se({\n ...u(this._def),\n innerType: this,\n catchValue: t,\n typeName: oe.ZodCatch\n });\n }\n describe(e) {\n return new this.constructor({\n ...this._def,\n description: e\n });\n }\n pipe(e) {\n return ae.create(this, e);\n }\n readonly() {\n return ne.create(this);\n }\n isOptional() {\n return this.safeParse(void 0).success;\n }\n isNullable() {\n return this.safeParse(null).success;\n }\n }\n t.ZodType = c, t.Schema = c, t.ZodSchema = c;\n const p = /^c[^\\s-]{8,}$/i, h = /^[a-z][a-z0-9]*$/, f = /^[0-9A-HJKMNP-TV-Z]{26}$/, m = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i, y = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_+-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\n let _;\n const v = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/, g = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;\n class b extends c {\n _parse(e) {\n if (this._def.coerce && (e.data = String(e.data)), this._getType(e) !== n.ZodParsedType.string) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.string,\n received: t.parsedType\n }), a.INVALID;\n }\n const t = new a.ParseStatus;\n let s;\n for (const l of this._def.checks)if (\"min\" === l.kind) e.data.length < l.value && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n minimum: l.value,\n type: \"string\",\n inclusive: !0,\n exact: !1,\n message: l.message\n }), t.dirty());\n else if (\"max\" === l.kind) e.data.length > l.value && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n maximum: l.value,\n type: \"string\",\n inclusive: !0,\n exact: !1,\n message: l.message\n }), t.dirty());\n else if (\"length\" === l.kind) {\n const r = e.data.length > l.value, i = e.data.length < l.value;\n (r || i) && (s = this._getOrReturnCtx(e, s), r ? (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n maximum: l.value,\n type: \"string\",\n inclusive: !0,\n exact: !0,\n message: l.message\n }) : i && (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n minimum: l.value,\n type: \"string\",\n inclusive: !0,\n exact: !0,\n message: l.message\n }), t.dirty());\n } else if (\"email\" === l.kind) y.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"email\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"emoji\" === l.kind) _ || (_ = new RegExp(\"^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$\", \"u\")), _.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"emoji\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"uuid\" === l.kind) m.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"uuid\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"cuid\" === l.kind) p.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"cuid\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"cuid2\" === l.kind) h.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"cuid2\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"ulid\" === l.kind) f.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"ulid\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty());\n else if (\"url\" === l.kind) try {\n new URL(e.data);\n } catch (r) {\n s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"url\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty();\n }\n else \"regex\" === l.kind ? (l.regex.lastIndex = 0, l.regex.test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"regex\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty())) : \"trim\" === l.kind ? e.data = e.data.trim() : \"includes\" === l.kind ? e.data.includes(l.value, l.position) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_string,\n validation: {\n includes: l.value,\n position: l.position\n },\n message: l.message\n }), t.dirty()) : \"toLowerCase\" === l.kind ? e.data = e.data.toLowerCase() : \"toUpperCase\" === l.kind ? e.data = e.data.toUpperCase() : \"startsWith\" === l.kind ? e.data.startsWith(l.value) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_string,\n validation: {\n startsWith: l.value\n },\n message: l.message\n }), t.dirty()) : \"endsWith\" === l.kind ? e.data.endsWith(l.value) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_string,\n validation: {\n endsWith: l.value\n },\n message: l.message\n }), t.dirty()) : \"datetime\" === l.kind ? ((d = l).precision ? d.offset ? new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{${d.precision}}(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$`) : new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{${d.precision}}Z$`) : 0 === d.precision ? d.offset ? new RegExp(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$\") : new RegExp(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}Z$\") : d.offset ? new RegExp(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$\") : new RegExp(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?Z$\")).test(e.data) || (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_string,\n validation: \"datetime\",\n message: l.message\n }), t.dirty()) : \"ip\" === l.kind ? (r = e.data, (\"v4\" !== (i = l.version) && i || !v.test(r)) && (\"v6\" !== i && i || !g.test(r)) && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n validation: \"ip\",\n code: o.ZodIssueCode.invalid_string,\n message: l.message\n }), t.dirty())) : n.util.assertNever(l);\n var r, i, d;\n return {\n status: t.value,\n value: e.data\n };\n }\n _regex(e, t, s) {\n return this.refinement((t)=>e.test(t), {\n validation: t,\n code: o.ZodIssueCode.invalid_string,\n ...i.errorUtil.errToObj(s)\n });\n }\n _addCheck(e) {\n return new b({\n ...this._def,\n checks: [\n ...this._def.checks,\n e\n ]\n });\n }\n email(e) {\n return this._addCheck({\n kind: \"email\",\n ...i.errorUtil.errToObj(e)\n });\n }\n url(e) {\n return this._addCheck({\n kind: \"url\",\n ...i.errorUtil.errToObj(e)\n });\n }\n emoji(e) {\n return this._addCheck({\n kind: \"emoji\",\n ...i.errorUtil.errToObj(e)\n });\n }\n uuid(e) {\n return this._addCheck({\n kind: \"uuid\",\n ...i.errorUtil.errToObj(e)\n });\n }\n cuid(e) {\n return this._addCheck({\n kind: \"cuid\",\n ...i.errorUtil.errToObj(e)\n });\n }\n cuid2(e) {\n return this._addCheck({\n kind: \"cuid2\",\n ...i.errorUtil.errToObj(e)\n });\n }\n ulid(e) {\n return this._addCheck({\n kind: \"ulid\",\n ...i.errorUtil.errToObj(e)\n });\n }\n ip(e) {\n return this._addCheck({\n kind: \"ip\",\n ...i.errorUtil.errToObj(e)\n });\n }\n datetime(e) {\n var t;\n return \"string\" == typeof e ? this._addCheck({\n kind: \"datetime\",\n precision: null,\n offset: !1,\n message: e\n }) : this._addCheck({\n kind: \"datetime\",\n precision: void 0 === (null == e ? void 0 : e.precision) ? null : null == e ? void 0 : e.precision,\n offset: null !== (t = null == e ? void 0 : e.offset) && void 0 !== t && t,\n ...i.errorUtil.errToObj(null == e ? void 0 : e.message)\n });\n }\n regex(e, t) {\n return this._addCheck({\n kind: \"regex\",\n regex: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n includes(e, t) {\n return this._addCheck({\n kind: \"includes\",\n value: e,\n position: null == t ? void 0 : t.position,\n ...i.errorUtil.errToObj(null == t ? void 0 : t.message)\n });\n }\n startsWith(e, t) {\n return this._addCheck({\n kind: \"startsWith\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n endsWith(e, t) {\n return this._addCheck({\n kind: \"endsWith\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n min(e, t) {\n return this._addCheck({\n kind: \"min\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n max(e, t) {\n return this._addCheck({\n kind: \"max\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n length(e, t) {\n return this._addCheck({\n kind: \"length\",\n value: e,\n ...i.errorUtil.errToObj(t)\n });\n }\n nonempty(e) {\n return this.min(1, i.errorUtil.errToObj(e));\n }\n trim() {\n return new b({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: \"trim\"\n }\n ]\n });\n }\n toLowerCase() {\n return new b({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: \"toLowerCase\"\n }\n ]\n });\n }\n toUpperCase() {\n return new b({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: \"toUpperCase\"\n }\n ]\n });\n }\n get isDatetime() {\n return !!this._def.checks.find((e)=>\"datetime\" === e.kind);\n }\n get isEmail() {\n return !!this._def.checks.find((e)=>\"email\" === e.kind);\n }\n get isURL() {\n return !!this._def.checks.find((e)=>\"url\" === e.kind);\n }\n get isEmoji() {\n return !!this._def.checks.find((e)=>\"emoji\" === e.kind);\n }\n get isUUID() {\n return !!this._def.checks.find((e)=>\"uuid\" === e.kind);\n }\n get isCUID() {\n return !!this._def.checks.find((e)=>\"cuid\" === e.kind);\n }\n get isCUID2() {\n return !!this._def.checks.find((e)=>\"cuid2\" === e.kind);\n }\n get isULID() {\n return !!this._def.checks.find((e)=>\"ulid\" === e.kind);\n }\n get isIP() {\n return !!this._def.checks.find((e)=>\"ip\" === e.kind);\n }\n get minLength() {\n let e = null;\n for (const t of this._def.checks)\"min\" === t.kind && (null === e || t.value > e) && (e = t.value);\n return e;\n }\n get maxLength() {\n let e = null;\n for (const t of this._def.checks)\"max\" === t.kind && (null === e || t.value < e) && (e = t.value);\n return e;\n }\n }\n function x(e, t) {\n const s = (e.toString().split(\".\")[1] || \"\").length, r = (t.toString().split(\".\")[1] || \"\").length, i = s > r ? s : r;\n return parseInt(e.toFixed(i).replace(\".\", \"\")) % parseInt(t.toFixed(i).replace(\".\", \"\")) / Math.pow(10, i);\n }\n t.ZodString = b, b.create = (e)=>{\n var t;\n return new b({\n checks: [],\n typeName: oe.ZodString,\n coerce: null !== (t = null == e ? void 0 : e.coerce) && void 0 !== t && t,\n ...u(e)\n });\n };\n class I extends c {\n constructor(){\n super(...arguments), this.min = this.gte, this.max = this.lte, this.step = this.multipleOf;\n }\n _parse(e) {\n if (this._def.coerce && (e.data = Number(e.data)), this._getType(e) !== n.ZodParsedType.number) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.number,\n received: t.parsedType\n }), a.INVALID;\n }\n let t;\n const s = new a.ParseStatus;\n for (const r of this._def.checks)\"int\" === r.kind ? n.util.isInteger(e.data) || (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: \"integer\",\n received: \"float\",\n message: r.message\n }), s.dirty()) : \"min\" === r.kind ? (r.inclusive ? e.data < r.value : e.data <= r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_small,\n minimum: r.value,\n type: \"number\",\n inclusive: r.inclusive,\n exact: !1,\n message: r.message\n }), s.dirty()) : \"max\" === r.kind ? (r.inclusive ? e.data > r.value : e.data >= r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_big,\n maximum: r.value,\n type: \"number\",\n inclusive: r.inclusive,\n exact: !1,\n message: r.message\n }), s.dirty()) : \"multipleOf\" === r.kind ? 0 !== x(e.data, r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.not_multiple_of,\n multipleOf: r.value,\n message: r.message\n }), s.dirty()) : \"finite\" === r.kind ? Number.isFinite(e.data) || (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.not_finite,\n message: r.message\n }), s.dirty()) : n.util.assertNever(r);\n return {\n status: s.value,\n value: e.data\n };\n }\n gte(e, t) {\n return this.setLimit(\"min\", e, !0, i.errorUtil.toString(t));\n }\n gt(e, t) {\n return this.setLimit(\"min\", e, !1, i.errorUtil.toString(t));\n }\n lte(e, t) {\n return this.setLimit(\"max\", e, !0, i.errorUtil.toString(t));\n }\n lt(e, t) {\n return this.setLimit(\"max\", e, !1, i.errorUtil.toString(t));\n }\n setLimit(e, t, s, r) {\n return new I({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: e,\n value: t,\n inclusive: s,\n message: i.errorUtil.toString(r)\n }\n ]\n });\n }\n _addCheck(e) {\n return new I({\n ...this._def,\n checks: [\n ...this._def.checks,\n e\n ]\n });\n }\n int(e) {\n return this._addCheck({\n kind: \"int\",\n message: i.errorUtil.toString(e)\n });\n }\n positive(e) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: !1,\n message: i.errorUtil.toString(e)\n });\n }\n negative(e) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: !1,\n message: i.errorUtil.toString(e)\n });\n }\n nonpositive(e) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: !0,\n message: i.errorUtil.toString(e)\n });\n }\n nonnegative(e) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: !0,\n message: i.errorUtil.toString(e)\n });\n }\n multipleOf(e, t) {\n return this._addCheck({\n kind: \"multipleOf\",\n value: e,\n message: i.errorUtil.toString(t)\n });\n }\n finite(e) {\n return this._addCheck({\n kind: \"finite\",\n message: i.errorUtil.toString(e)\n });\n }\n safe(e) {\n return this._addCheck({\n kind: \"min\",\n inclusive: !0,\n value: Number.MIN_SAFE_INTEGER,\n message: i.errorUtil.toString(e)\n })._addCheck({\n kind: \"max\",\n inclusive: !0,\n value: Number.MAX_SAFE_INTEGER,\n message: i.errorUtil.toString(e)\n });\n }\n get minValue() {\n let e = null;\n for (const t of this._def.checks)\"min\" === t.kind && (null === e || t.value > e) && (e = t.value);\n return e;\n }\n get maxValue() {\n let e = null;\n for (const t of this._def.checks)\"max\" === t.kind && (null === e || t.value < e) && (e = t.value);\n return e;\n }\n get isInt() {\n return !!this._def.checks.find((e)=>\"int\" === e.kind || \"multipleOf\" === e.kind && n.util.isInteger(e.value));\n }\n get isFinite() {\n let e = null, t = null;\n for (const s of this._def.checks){\n if (\"finite\" === s.kind || \"int\" === s.kind || \"multipleOf\" === s.kind) return !0;\n \"min\" === s.kind ? (null === t || s.value > t) && (t = s.value) : \"max\" === s.kind && (null === e || s.value < e) && (e = s.value);\n }\n return Number.isFinite(t) && Number.isFinite(e);\n }\n }\n t.ZodNumber = I, I.create = (e)=>new I({\n checks: [],\n typeName: oe.ZodNumber,\n coerce: (null == e ? void 0 : e.coerce) || !1,\n ...u(e)\n });\n class Z extends c {\n constructor(){\n super(...arguments), this.min = this.gte, this.max = this.lte;\n }\n _parse(e) {\n if (this._def.coerce && (e.data = BigInt(e.data)), this._getType(e) !== n.ZodParsedType.bigint) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.bigint,\n received: t.parsedType\n }), a.INVALID;\n }\n let t;\n const s = new a.ParseStatus;\n for (const r of this._def.checks)\"min\" === r.kind ? (r.inclusive ? e.data < r.value : e.data <= r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_small,\n type: \"bigint\",\n minimum: r.value,\n inclusive: r.inclusive,\n message: r.message\n }), s.dirty()) : \"max\" === r.kind ? (r.inclusive ? e.data > r.value : e.data >= r.value) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_big,\n type: \"bigint\",\n maximum: r.value,\n inclusive: r.inclusive,\n message: r.message\n }), s.dirty()) : \"multipleOf\" === r.kind ? e.data % r.value !== BigInt(0) && (t = this._getOrReturnCtx(e, t), (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.not_multiple_of,\n multipleOf: r.value,\n message: r.message\n }), s.dirty()) : n.util.assertNever(r);\n return {\n status: s.value,\n value: e.data\n };\n }\n gte(e, t) {\n return this.setLimit(\"min\", e, !0, i.errorUtil.toString(t));\n }\n gt(e, t) {\n return this.setLimit(\"min\", e, !1, i.errorUtil.toString(t));\n }\n lte(e, t) {\n return this.setLimit(\"max\", e, !0, i.errorUtil.toString(t));\n }\n lt(e, t) {\n return this.setLimit(\"max\", e, !1, i.errorUtil.toString(t));\n }\n setLimit(e, t, s, r) {\n return new Z({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind: e,\n value: t,\n inclusive: s,\n message: i.errorUtil.toString(r)\n }\n ]\n });\n }\n _addCheck(e) {\n return new Z({\n ...this._def,\n checks: [\n ...this._def.checks,\n e\n ]\n });\n }\n positive(e) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: !1,\n message: i.errorUtil.toString(e)\n });\n }\n negative(e) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: !1,\n message: i.errorUtil.toString(e)\n });\n }\n nonpositive(e) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: !0,\n message: i.errorUtil.toString(e)\n });\n }\n nonnegative(e) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: !0,\n message: i.errorUtil.toString(e)\n });\n }\n multipleOf(e, t) {\n return this._addCheck({\n kind: \"multipleOf\",\n value: e,\n message: i.errorUtil.toString(t)\n });\n }\n get minValue() {\n let e = null;\n for (const t of this._def.checks)\"min\" === t.kind && (null === e || t.value > e) && (e = t.value);\n return e;\n }\n get maxValue() {\n let e = null;\n for (const t of this._def.checks)\"max\" === t.kind && (null === e || t.value < e) && (e = t.value);\n return e;\n }\n }\n t.ZodBigInt = Z, Z.create = (e)=>{\n var t;\n return new Z({\n checks: [],\n typeName: oe.ZodBigInt,\n coerce: null !== (t = null == e ? void 0 : e.coerce) && void 0 !== t && t,\n ...u(e)\n });\n };\n class T extends c {\n _parse(e) {\n if (this._def.coerce && (e.data = Boolean(e.data)), this._getType(e) !== n.ZodParsedType.boolean) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.boolean,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodBoolean = T, T.create = (e)=>new T({\n typeName: oe.ZodBoolean,\n coerce: (null == e ? void 0 : e.coerce) || !1,\n ...u(e)\n });\n class k extends c {\n _parse(e) {\n if (this._def.coerce && (e.data = new Date(e.data)), this._getType(e) !== n.ZodParsedType.date) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.date,\n received: t.parsedType\n }), a.INVALID;\n }\n if (isNaN(e.data.getTime())) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_date\n }), a.INVALID;\n }\n const t = new a.ParseStatus;\n let s;\n for (const r of this._def.checks)\"min\" === r.kind ? e.data.getTime() < r.value && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n message: r.message,\n inclusive: !0,\n exact: !1,\n minimum: r.value,\n type: \"date\"\n }), t.dirty()) : \"max\" === r.kind ? e.data.getTime() > r.value && (s = this._getOrReturnCtx(e, s), (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n message: r.message,\n inclusive: !0,\n exact: !1,\n maximum: r.value,\n type: \"date\"\n }), t.dirty()) : n.util.assertNever(r);\n return {\n status: t.value,\n value: new Date(e.data.getTime())\n };\n }\n _addCheck(e) {\n return new k({\n ...this._def,\n checks: [\n ...this._def.checks,\n e\n ]\n });\n }\n min(e, t) {\n return this._addCheck({\n kind: \"min\",\n value: e.getTime(),\n message: i.errorUtil.toString(t)\n });\n }\n max(e, t) {\n return this._addCheck({\n kind: \"max\",\n value: e.getTime(),\n message: i.errorUtil.toString(t)\n });\n }\n get minDate() {\n let e = null;\n for (const t of this._def.checks)\"min\" === t.kind && (null === e || t.value > e) && (e = t.value);\n return null != e ? new Date(e) : null;\n }\n get maxDate() {\n let e = null;\n for (const t of this._def.checks)\"max\" === t.kind && (null === e || t.value < e) && (e = t.value);\n return null != e ? new Date(e) : null;\n }\n }\n t.ZodDate = k, k.create = (e)=>new k({\n checks: [],\n coerce: (null == e ? void 0 : e.coerce) || !1,\n typeName: oe.ZodDate,\n ...u(e)\n });\n class w extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.symbol) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.symbol,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodSymbol = w, w.create = (e)=>new w({\n typeName: oe.ZodSymbol,\n ...u(e)\n });\n class C extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.undefined) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.undefined,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodUndefined = C, C.create = (e)=>new C({\n typeName: oe.ZodUndefined,\n ...u(e)\n });\n class z extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.null) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.null,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodNull = z, z.create = (e)=>new z({\n typeName: oe.ZodNull,\n ...u(e)\n });\n class L extends c {\n constructor(){\n super(...arguments), this._any = !0;\n }\n _parse(e) {\n return (0, a.OK)(e.data);\n }\n }\n t.ZodAny = L, L.create = (e)=>new L({\n typeName: oe.ZodAny,\n ...u(e)\n });\n class P extends c {\n constructor(){\n super(...arguments), this._unknown = !0;\n }\n _parse(e) {\n return (0, a.OK)(e.data);\n }\n }\n t.ZodUnknown = P, P.create = (e)=>new P({\n typeName: oe.ZodUnknown,\n ...u(e)\n });\n class O extends c {\n _parse(e) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.never,\n received: t.parsedType\n }), a.INVALID;\n }\n }\n t.ZodNever = O, O.create = (e)=>new O({\n typeName: oe.ZodNever,\n ...u(e)\n });\n class j extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.undefined) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.void,\n received: t.parsedType\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n }\n t.ZodVoid = j, j.create = (e)=>new j({\n typeName: oe.ZodVoid,\n ...u(e)\n });\n class E extends c {\n _parse(e) {\n const { ctx: t, status: s } = this._processInputParams(e), r = this._def;\n if (t.parsedType !== n.ZodParsedType.array) return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.array,\n received: t.parsedType\n }), a.INVALID;\n if (null !== r.exactLength) {\n const e = t.data.length > r.exactLength.value, i = t.data.length < r.exactLength.value;\n (e || i) && ((0, a.addIssueToContext)(t, {\n code: e ? o.ZodIssueCode.too_big : o.ZodIssueCode.too_small,\n minimum: i ? r.exactLength.value : void 0,\n maximum: e ? r.exactLength.value : void 0,\n type: \"array\",\n inclusive: !0,\n exact: !0,\n message: r.exactLength.message\n }), s.dirty());\n }\n if (null !== r.minLength && t.data.length < r.minLength.value && ((0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_small,\n minimum: r.minLength.value,\n type: \"array\",\n inclusive: !0,\n exact: !1,\n message: r.minLength.message\n }), s.dirty()), null !== r.maxLength && t.data.length > r.maxLength.value && ((0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.too_big,\n maximum: r.maxLength.value,\n type: \"array\",\n inclusive: !0,\n exact: !1,\n message: r.maxLength.message\n }), s.dirty()), t.common.async) return Promise.all([\n ...t.data\n ].map((e, s)=>r.type._parseAsync(new d(t, e, t.path, s)))).then((e)=>a.ParseStatus.mergeArray(s, e));\n const i = [\n ...t.data\n ].map((e, s)=>r.type._parseSync(new d(t, e, t.path, s)));\n return a.ParseStatus.mergeArray(s, i);\n }\n get element() {\n return this._def.type;\n }\n min(e, t) {\n return new E({\n ...this._def,\n minLength: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n max(e, t) {\n return new E({\n ...this._def,\n maxLength: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n length(e, t) {\n return new E({\n ...this._def,\n exactLength: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n nonempty(e) {\n return this.min(1, e);\n }\n }\n function S(e) {\n if (e instanceof N) {\n const t = {};\n for(const s in e.shape){\n const r = e.shape[s];\n t[s] = Q.create(S(r));\n }\n return new N({\n ...e._def,\n shape: ()=>t\n });\n }\n return e instanceof E ? new E({\n ...e._def,\n type: S(e.element)\n }) : e instanceof Q ? Q.create(S(e.unwrap())) : e instanceof ee ? ee.create(S(e.unwrap())) : e instanceof V ? V.create(e.items.map((e)=>S(e))) : e;\n }\n t.ZodArray = E, E.create = (e, t)=>new E({\n type: e,\n minLength: null,\n maxLength: null,\n exactLength: null,\n typeName: oe.ZodArray,\n ...u(t)\n });\n class N extends c {\n constructor(){\n super(...arguments), this._cached = null, this.nonstrict = this.passthrough, this.augment = this.extend;\n }\n _getCached() {\n if (null !== this._cached) return this._cached;\n const e = this._def.shape(), t = n.util.objectKeys(e);\n return this._cached = {\n shape: e,\n keys: t\n };\n }\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.object) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.object,\n received: t.parsedType\n }), a.INVALID;\n }\n const { status: t, ctx: s } = this._processInputParams(e), { shape: r, keys: i } = this._getCached(), l = [];\n if (!(this._def.catchall instanceof O && \"strip\" === this._def.unknownKeys)) for(const e in s.data)i.includes(e) || l.push(e);\n const u = [];\n for (const e of i){\n const t = r[e], i = s.data[e];\n u.push({\n key: {\n status: \"valid\",\n value: e\n },\n value: t._parse(new d(s, i, s.path, e)),\n alwaysSet: e in s.data\n });\n }\n if (this._def.catchall instanceof O) {\n const e = this._def.unknownKeys;\n if (\"passthrough\" === e) for (const e of l)u.push({\n key: {\n status: \"valid\",\n value: e\n },\n value: {\n status: \"valid\",\n value: s.data[e]\n }\n });\n else if (\"strict\" === e) l.length > 0 && ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.unrecognized_keys,\n keys: l\n }), t.dirty());\n else if (\"strip\" !== e) throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\");\n } else {\n const e = this._def.catchall;\n for (const t of l){\n const r = s.data[t];\n u.push({\n key: {\n status: \"valid\",\n value: t\n },\n value: e._parse(new d(s, r, s.path, t)),\n alwaysSet: t in s.data\n });\n }\n }\n return s.common.async ? Promise.resolve().then(async ()=>{\n const e = [];\n for (const t of u){\n const s = await t.key;\n e.push({\n key: s,\n value: await t.value,\n alwaysSet: t.alwaysSet\n });\n }\n return e;\n }).then((e)=>a.ParseStatus.mergeObjectSync(t, e)) : a.ParseStatus.mergeObjectSync(t, u);\n }\n get shape() {\n return this._def.shape();\n }\n strict(e) {\n return i.errorUtil.errToObj, new N({\n ...this._def,\n unknownKeys: \"strict\",\n ...void 0 !== e ? {\n errorMap: (t, s)=>{\n var r, a, n, o;\n const d = null !== (n = null === (a = (r = this._def).errorMap) || void 0 === a ? void 0 : a.call(r, t, s).message) && void 0 !== n ? n : s.defaultError;\n return \"unrecognized_keys\" === t.code ? {\n message: null !== (o = i.errorUtil.errToObj(e).message) && void 0 !== o ? o : d\n } : {\n message: d\n };\n }\n } : {}\n });\n }\n strip() {\n return new N({\n ...this._def,\n unknownKeys: \"strip\"\n });\n }\n passthrough() {\n return new N({\n ...this._def,\n unknownKeys: \"passthrough\"\n });\n }\n extend(e) {\n return new N({\n ...this._def,\n shape: ()=>({\n ...this._def.shape(),\n ...e\n })\n });\n }\n merge(e) {\n return new N({\n unknownKeys: e._def.unknownKeys,\n catchall: e._def.catchall,\n shape: ()=>({\n ...this._def.shape(),\n ...e._def.shape()\n }),\n typeName: oe.ZodObject\n });\n }\n setKey(e, t) {\n return this.augment({\n [e]: t\n });\n }\n catchall(e) {\n return new N({\n ...this._def,\n catchall: e\n });\n }\n pick(e) {\n const t = {};\n return n.util.objectKeys(e).forEach((s)=>{\n e[s] && this.shape[s] && (t[s] = this.shape[s]);\n }), new N({\n ...this._def,\n shape: ()=>t\n });\n }\n omit(e) {\n const t = {};\n return n.util.objectKeys(this.shape).forEach((s)=>{\n e[s] || (t[s] = this.shape[s]);\n }), new N({\n ...this._def,\n shape: ()=>t\n });\n }\n deepPartial() {\n return S(this);\n }\n partial(e) {\n const t = {};\n return n.util.objectKeys(this.shape).forEach((s)=>{\n const r = this.shape[s];\n e && !e[s] ? t[s] = r : t[s] = r.optional();\n }), new N({\n ...this._def,\n shape: ()=>t\n });\n }\n required(e) {\n const t = {};\n return n.util.objectKeys(this.shape).forEach((s)=>{\n if (e && !e[s]) t[s] = this.shape[s];\n else {\n let e = this.shape[s];\n for(; e instanceof Q;)e = e._def.innerType;\n t[s] = e;\n }\n }), new N({\n ...this._def,\n shape: ()=>t\n });\n }\n keyof() {\n return Y(n.util.objectKeys(this.shape));\n }\n }\n t.ZodObject = N, N.create = (e, t)=>new N({\n shape: ()=>e,\n unknownKeys: \"strip\",\n catchall: O.create(),\n typeName: oe.ZodObject,\n ...u(t)\n }), N.strictCreate = (e, t)=>new N({\n shape: ()=>e,\n unknownKeys: \"strict\",\n catchall: O.create(),\n typeName: oe.ZodObject,\n ...u(t)\n }), N.lazycreate = (e, t)=>new N({\n shape: e,\n unknownKeys: \"strip\",\n catchall: O.create(),\n typeName: oe.ZodObject,\n ...u(t)\n });\n class M extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e), s = this._def.options;\n if (t.common.async) return Promise.all(s.map(async (e)=>{\n const s = {\n ...t,\n common: {\n ...t.common,\n issues: []\n },\n parent: null\n };\n return {\n result: await e._parseAsync({\n data: t.data,\n path: t.path,\n parent: s\n }),\n ctx: s\n };\n })).then(function(e) {\n for (const t of e)if (\"valid\" === t.result.status) return t.result;\n for (const s of e)if (\"dirty\" === s.result.status) return t.common.issues.push(...s.ctx.common.issues), s.result;\n const s = e.map((e)=>new o.ZodError(e.ctx.common.issues));\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_union,\n unionErrors: s\n }), a.INVALID;\n });\n {\n let e;\n const r = [];\n for (const i of s){\n const s = {\n ...t,\n common: {\n ...t.common,\n issues: []\n },\n parent: null\n }, a = i._parseSync({\n data: t.data,\n path: t.path,\n parent: s\n });\n if (\"valid\" === a.status) return a;\n \"dirty\" !== a.status || e || (e = {\n result: a,\n ctx: s\n }), s.common.issues.length && r.push(s.common.issues);\n }\n if (e) return t.common.issues.push(...e.ctx.common.issues), e.result;\n const i = r.map((e)=>new o.ZodError(e));\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_union,\n unionErrors: i\n }), a.INVALID;\n }\n }\n get options() {\n return this._def.options;\n }\n }\n t.ZodUnion = M, M.create = (e, t)=>new M({\n options: e,\n typeName: oe.ZodUnion,\n ...u(t)\n });\n const A = (e)=>e instanceof G ? A(e.schema) : e instanceof J ? A(e.innerType()) : e instanceof W ? [\n e.value\n ] : e instanceof H ? e.options : e instanceof q ? Object.keys(e.enum) : e instanceof te ? A(e._def.innerType) : e instanceof C ? [\n void 0\n ] : e instanceof z ? [\n null\n ] : null;\n class D extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n if (t.parsedType !== n.ZodParsedType.object) return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.object,\n received: t.parsedType\n }), a.INVALID;\n const s = this.discriminator, r = t.data[s], i = this.optionsMap.get(r);\n return i ? t.common.async ? i._parseAsync({\n data: t.data,\n path: t.path,\n parent: t\n }) : i._parseSync({\n data: t.data,\n path: t.path,\n parent: t\n }) : ((0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_union_discriminator,\n options: Array.from(this.optionsMap.keys()),\n path: [\n s\n ]\n }), a.INVALID);\n }\n get discriminator() {\n return this._def.discriminator;\n }\n get options() {\n return this._def.options;\n }\n get optionsMap() {\n return this._def.optionsMap;\n }\n static create(e, t, s) {\n const r = new Map;\n for (const s of t){\n const t = A(s.shape[e]);\n if (!t) throw new Error(`A discriminator value for key \\`${e}\\` could not be extracted from all schema options`);\n for (const i of t){\n if (r.has(i)) throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(i)}`);\n r.set(i, s);\n }\n }\n return new D({\n typeName: oe.ZodDiscriminatedUnion,\n discriminator: e,\n options: t,\n optionsMap: r,\n ...u(s)\n });\n }\n }\n function U(e, t) {\n const s = (0, n.getParsedType)(e), r = (0, n.getParsedType)(t);\n if (e === t) return {\n valid: !0,\n data: e\n };\n if (s === n.ZodParsedType.object && r === n.ZodParsedType.object) {\n const s = n.util.objectKeys(t), r = n.util.objectKeys(e).filter((e)=>-1 !== s.indexOf(e)), i = {\n ...e,\n ...t\n };\n for (const s of r){\n const r = U(e[s], t[s]);\n if (!r.valid) return {\n valid: !1\n };\n i[s] = r.data;\n }\n return {\n valid: !0,\n data: i\n };\n }\n if (s === n.ZodParsedType.array && r === n.ZodParsedType.array) {\n if (e.length !== t.length) return {\n valid: !1\n };\n const s = [];\n for(let r = 0; r < e.length; r++){\n const i = U(e[r], t[r]);\n if (!i.valid) return {\n valid: !1\n };\n s.push(i.data);\n }\n return {\n valid: !0,\n data: s\n };\n }\n return s === n.ZodParsedType.date && r === n.ZodParsedType.date && +e == +t ? {\n valid: !0,\n data: e\n } : {\n valid: !1\n };\n }\n t.ZodDiscriminatedUnion = D;\n class R extends c {\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e), r = (e, r)=>{\n if ((0, a.isAborted)(e) || (0, a.isAborted)(r)) return a.INVALID;\n const i = U(e.value, r.value);\n return i.valid ? (((0, a.isDirty)(e) || (0, a.isDirty)(r)) && t.dirty(), {\n status: t.value,\n value: i.data\n }) : ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_intersection_types\n }), a.INVALID);\n };\n return s.common.async ? Promise.all([\n this._def.left._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n }),\n this._def.right._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n })\n ]).then(([e, t])=>r(e, t)) : r(this._def.left._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n }), this._def.right._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n }));\n }\n }\n t.ZodIntersection = R, R.create = (e, t, s)=>new R({\n left: e,\n right: t,\n typeName: oe.ZodIntersection,\n ...u(s)\n });\n class V extends c {\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.parsedType !== n.ZodParsedType.array) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.array,\n received: s.parsedType\n }), a.INVALID;\n if (s.data.length < this._def.items.length) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n minimum: this._def.items.length,\n inclusive: !0,\n exact: !1,\n type: \"array\"\n }), a.INVALID;\n !this._def.rest && s.data.length > this._def.items.length && ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n maximum: this._def.items.length,\n inclusive: !0,\n exact: !1,\n type: \"array\"\n }), t.dirty());\n const r = [\n ...s.data\n ].map((e, t)=>{\n const r = this._def.items[t] || this._def.rest;\n return r ? r._parse(new d(s, e, s.path, t)) : null;\n }).filter((e)=>!!e);\n return s.common.async ? Promise.all(r).then((e)=>a.ParseStatus.mergeArray(t, e)) : a.ParseStatus.mergeArray(t, r);\n }\n get items() {\n return this._def.items;\n }\n rest(e) {\n return new V({\n ...this._def,\n rest: e\n });\n }\n }\n t.ZodTuple = V, V.create = (e, t)=>{\n if (!Array.isArray(e)) throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");\n return new V({\n items: e,\n typeName: oe.ZodTuple,\n rest: null,\n ...u(t)\n });\n };\n class $ extends c {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.parsedType !== n.ZodParsedType.object) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.object,\n received: s.parsedType\n }), a.INVALID;\n const r = [], i = this._def.keyType, l = this._def.valueType;\n for(const e in s.data)r.push({\n key: i._parse(new d(s, e, s.path, e)),\n value: l._parse(new d(s, s.data[e], s.path, e))\n });\n return s.common.async ? a.ParseStatus.mergeObjectAsync(t, r) : a.ParseStatus.mergeObjectSync(t, r);\n }\n get element() {\n return this._def.valueType;\n }\n static create(e, t, s) {\n return new $(t instanceof c ? {\n keyType: e,\n valueType: t,\n typeName: oe.ZodRecord,\n ...u(s)\n } : {\n keyType: b.create(),\n valueType: e,\n typeName: oe.ZodRecord,\n ...u(t)\n });\n }\n }\n t.ZodRecord = $;\n class B extends c {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.parsedType !== n.ZodParsedType.map) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.map,\n received: s.parsedType\n }), a.INVALID;\n const r = this._def.keyType, i = this._def.valueType, l = [\n ...s.data.entries()\n ].map(([e, t], a)=>({\n key: r._parse(new d(s, e, s.path, [\n a,\n \"key\"\n ])),\n value: i._parse(new d(s, t, s.path, [\n a,\n \"value\"\n ]))\n }));\n if (s.common.async) {\n const e = new Map;\n return Promise.resolve().then(async ()=>{\n for (const s of l){\n const r = await s.key, i = await s.value;\n if (\"aborted\" === r.status || \"aborted\" === i.status) return a.INVALID;\n \"dirty\" !== r.status && \"dirty\" !== i.status || t.dirty(), e.set(r.value, i.value);\n }\n return {\n status: t.value,\n value: e\n };\n });\n }\n {\n const e = new Map;\n for (const s of l){\n const r = s.key, i = s.value;\n if (\"aborted\" === r.status || \"aborted\" === i.status) return a.INVALID;\n \"dirty\" !== r.status && \"dirty\" !== i.status || t.dirty(), e.set(r.value, i.value);\n }\n return {\n status: t.value,\n value: e\n };\n }\n }\n }\n t.ZodMap = B, B.create = (e, t, s)=>new B({\n valueType: t,\n keyType: e,\n typeName: oe.ZodMap,\n ...u(s)\n });\n class F extends c {\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.parsedType !== n.ZodParsedType.set) return (0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.set,\n received: s.parsedType\n }), a.INVALID;\n const r = this._def;\n null !== r.minSize && s.data.size < r.minSize.value && ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_small,\n minimum: r.minSize.value,\n type: \"set\",\n inclusive: !0,\n exact: !1,\n message: r.minSize.message\n }), t.dirty()), null !== r.maxSize && s.data.size > r.maxSize.value && ((0, a.addIssueToContext)(s, {\n code: o.ZodIssueCode.too_big,\n maximum: r.maxSize.value,\n type: \"set\",\n inclusive: !0,\n exact: !1,\n message: r.maxSize.message\n }), t.dirty());\n const i = this._def.valueType;\n function l(e) {\n const s = new Set;\n for (const r of e){\n if (\"aborted\" === r.status) return a.INVALID;\n \"dirty\" === r.status && t.dirty(), s.add(r.value);\n }\n return {\n status: t.value,\n value: s\n };\n }\n const u = [\n ...s.data.values()\n ].map((e, t)=>i._parse(new d(s, e, s.path, t)));\n return s.common.async ? Promise.all(u).then((e)=>l(e)) : l(u);\n }\n min(e, t) {\n return new F({\n ...this._def,\n minSize: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n max(e, t) {\n return new F({\n ...this._def,\n maxSize: {\n value: e,\n message: i.errorUtil.toString(t)\n }\n });\n }\n size(e, t) {\n return this.min(e, t).max(e, t);\n }\n nonempty(e) {\n return this.min(1, e);\n }\n }\n t.ZodSet = F, F.create = (e, t)=>new F({\n valueType: e,\n minSize: null,\n maxSize: null,\n typeName: oe.ZodSet,\n ...u(t)\n });\n class K extends c {\n constructor(){\n super(...arguments), this.validate = this.implement;\n }\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n if (t.parsedType !== n.ZodParsedType.function) return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.function,\n received: t.parsedType\n }), a.INVALID;\n function s(e, s) {\n return (0, a.makeIssue)({\n data: e,\n path: t.path,\n errorMaps: [\n t.common.contextualErrorMap,\n t.schemaErrorMap,\n (0, r.getErrorMap)(),\n r.defaultErrorMap\n ].filter((e)=>!!e),\n issueData: {\n code: o.ZodIssueCode.invalid_arguments,\n argumentsError: s\n }\n });\n }\n function i(e, s) {\n return (0, a.makeIssue)({\n data: e,\n path: t.path,\n errorMaps: [\n t.common.contextualErrorMap,\n t.schemaErrorMap,\n (0, r.getErrorMap)(),\n r.defaultErrorMap\n ].filter((e)=>!!e),\n issueData: {\n code: o.ZodIssueCode.invalid_return_type,\n returnTypeError: s\n }\n });\n }\n const d = {\n errorMap: t.common.contextualErrorMap\n }, l = t.data;\n if (this._def.returns instanceof X) {\n const e = this;\n return (0, a.OK)(async function(...t) {\n const r = new o.ZodError([]), a = await e._def.args.parseAsync(t, d).catch((e)=>{\n throw r.addIssue(s(t, e)), r;\n }), n = await Reflect.apply(l, this, a);\n return await e._def.returns._def.type.parseAsync(n, d).catch((e)=>{\n throw r.addIssue(i(n, e)), r;\n });\n });\n }\n {\n const e = this;\n return (0, a.OK)(function(...t) {\n const r = e._def.args.safeParse(t, d);\n if (!r.success) throw new o.ZodError([\n s(t, r.error)\n ]);\n const a = Reflect.apply(l, this, r.data), n = e._def.returns.safeParse(a, d);\n if (!n.success) throw new o.ZodError([\n i(a, n.error)\n ]);\n return n.data;\n });\n }\n }\n parameters() {\n return this._def.args;\n }\n returnType() {\n return this._def.returns;\n }\n args(...e) {\n return new K({\n ...this._def,\n args: V.create(e).rest(P.create())\n });\n }\n returns(e) {\n return new K({\n ...this._def,\n returns: e\n });\n }\n implement(e) {\n return this.parse(e);\n }\n strictImplement(e) {\n return this.parse(e);\n }\n static create(e, t, s) {\n return new K({\n args: e || V.create([]).rest(P.create()),\n returns: t || P.create(),\n typeName: oe.ZodFunction,\n ...u(s)\n });\n }\n }\n t.ZodFunction = K;\n class G extends c {\n get schema() {\n return this._def.getter();\n }\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n return this._def.getter()._parse({\n data: t.data,\n path: t.path,\n parent: t\n });\n }\n }\n t.ZodLazy = G, G.create = (e, t)=>new G({\n getter: e,\n typeName: oe.ZodLazy,\n ...u(t)\n });\n class W extends c {\n _parse(e) {\n if (e.data !== this._def.value) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n received: t.data,\n code: o.ZodIssueCode.invalid_literal,\n expected: this._def.value\n }), a.INVALID;\n }\n return {\n status: \"valid\",\n value: e.data\n };\n }\n get value() {\n return this._def.value;\n }\n }\n function Y(e, t) {\n return new H({\n values: e,\n typeName: oe.ZodEnum,\n ...u(t)\n });\n }\n t.ZodLiteral = W, W.create = (e, t)=>new W({\n value: e,\n typeName: oe.ZodLiteral,\n ...u(t)\n });\n class H extends c {\n _parse(e) {\n if (\"string\" != typeof e.data) {\n const t = this._getOrReturnCtx(e), s = this._def.values;\n return (0, a.addIssueToContext)(t, {\n expected: n.util.joinValues(s),\n received: t.parsedType,\n code: o.ZodIssueCode.invalid_type\n }), a.INVALID;\n }\n if (-1 === this._def.values.indexOf(e.data)) {\n const t = this._getOrReturnCtx(e), s = this._def.values;\n return (0, a.addIssueToContext)(t, {\n received: t.data,\n code: o.ZodIssueCode.invalid_enum_value,\n options: s\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n get options() {\n return this._def.values;\n }\n get enum() {\n const e = {};\n for (const t of this._def.values)e[t] = t;\n return e;\n }\n get Values() {\n const e = {};\n for (const t of this._def.values)e[t] = t;\n return e;\n }\n get Enum() {\n const e = {};\n for (const t of this._def.values)e[t] = t;\n return e;\n }\n extract(e) {\n return H.create(e);\n }\n exclude(e) {\n return H.create(this.options.filter((t)=>!e.includes(t)));\n }\n }\n t.ZodEnum = H, H.create = Y;\n class q extends c {\n _parse(e) {\n const t = n.util.getValidEnumValues(this._def.values), s = this._getOrReturnCtx(e);\n if (s.parsedType !== n.ZodParsedType.string && s.parsedType !== n.ZodParsedType.number) {\n const e = n.util.objectValues(t);\n return (0, a.addIssueToContext)(s, {\n expected: n.util.joinValues(e),\n received: s.parsedType,\n code: o.ZodIssueCode.invalid_type\n }), a.INVALID;\n }\n if (-1 === t.indexOf(e.data)) {\n const e = n.util.objectValues(t);\n return (0, a.addIssueToContext)(s, {\n received: s.data,\n code: o.ZodIssueCode.invalid_enum_value,\n options: e\n }), a.INVALID;\n }\n return (0, a.OK)(e.data);\n }\n get enum() {\n return this._def.values;\n }\n }\n t.ZodNativeEnum = q, q.create = (e, t)=>new q({\n values: e,\n typeName: oe.ZodNativeEnum,\n ...u(t)\n });\n class X extends c {\n unwrap() {\n return this._def.type;\n }\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n if (t.parsedType !== n.ZodParsedType.promise && !1 === t.common.async) return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.promise,\n received: t.parsedType\n }), a.INVALID;\n const s = t.parsedType === n.ZodParsedType.promise ? t.data : Promise.resolve(t.data);\n return (0, a.OK)(s.then((e)=>this._def.type.parseAsync(e, {\n path: t.path,\n errorMap: t.common.contextualErrorMap\n })));\n }\n }\n t.ZodPromise = X, X.create = (e, t)=>new X({\n type: e,\n typeName: oe.ZodPromise,\n ...u(t)\n });\n class J extends c {\n innerType() {\n return this._def.schema;\n }\n sourceType() {\n return this._def.schema._def.typeName === oe.ZodEffects ? this._def.schema.sourceType() : this._def.schema;\n }\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e), r = this._def.effect || null, i = {\n addIssue: (e)=>{\n (0, a.addIssueToContext)(s, e), e.fatal ? t.abort() : t.dirty();\n },\n get path () {\n return s.path;\n }\n };\n if (i.addIssue = i.addIssue.bind(i), \"preprocess\" === r.type) {\n const e = r.transform(s.data, i);\n return s.common.issues.length ? {\n status: \"dirty\",\n value: s.data\n } : s.common.async ? Promise.resolve(e).then((e)=>this._def.schema._parseAsync({\n data: e,\n path: s.path,\n parent: s\n })) : this._def.schema._parseSync({\n data: e,\n path: s.path,\n parent: s\n });\n }\n if (\"refinement\" === r.type) {\n const e = (e)=>{\n const t = r.refinement(e, i);\n if (s.common.async) return Promise.resolve(t);\n if (t instanceof Promise) throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");\n return e;\n };\n if (!1 === s.common.async) {\n const r = this._def.schema._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n });\n return \"aborted\" === r.status ? a.INVALID : (\"dirty\" === r.status && t.dirty(), e(r.value), {\n status: t.value,\n value: r.value\n });\n }\n return this._def.schema._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n }).then((s)=>\"aborted\" === s.status ? a.INVALID : (\"dirty\" === s.status && t.dirty(), e(s.value).then(()=>({\n status: t.value,\n value: s.value\n }))));\n }\n if (\"transform\" === r.type) {\n if (!1 === s.common.async) {\n const e = this._def.schema._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n });\n if (!(0, a.isValid)(e)) return e;\n const n = r.transform(e.value, i);\n if (n instanceof Promise) throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");\n return {\n status: t.value,\n value: n\n };\n }\n return this._def.schema._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n }).then((e)=>(0, a.isValid)(e) ? Promise.resolve(r.transform(e.value, i)).then((e)=>({\n status: t.value,\n value: e\n })) : e);\n }\n n.util.assertNever(r);\n }\n }\n t.ZodEffects = J, t.ZodTransformer = J, J.create = (e, t, s)=>new J({\n schema: e,\n typeName: oe.ZodEffects,\n effect: t,\n ...u(s)\n }), J.createWithPreprocess = (e, t, s)=>new J({\n schema: t,\n effect: {\n type: \"preprocess\",\n transform: e\n },\n typeName: oe.ZodEffects,\n ...u(s)\n });\n class Q extends c {\n _parse(e) {\n return this._getType(e) === n.ZodParsedType.undefined ? (0, a.OK)(void 0) : this._def.innerType._parse(e);\n }\n unwrap() {\n return this._def.innerType;\n }\n }\n t.ZodOptional = Q, Q.create = (e, t)=>new Q({\n innerType: e,\n typeName: oe.ZodOptional,\n ...u(t)\n });\n class ee extends c {\n _parse(e) {\n return this._getType(e) === n.ZodParsedType.null ? (0, a.OK)(null) : this._def.innerType._parse(e);\n }\n unwrap() {\n return this._def.innerType;\n }\n }\n t.ZodNullable = ee, ee.create = (e, t)=>new ee({\n innerType: e,\n typeName: oe.ZodNullable,\n ...u(t)\n });\n class te extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e);\n let s = t.data;\n return t.parsedType === n.ZodParsedType.undefined && (s = this._def.defaultValue()), this._def.innerType._parse({\n data: s,\n path: t.path,\n parent: t\n });\n }\n removeDefault() {\n return this._def.innerType;\n }\n }\n t.ZodDefault = te, te.create = (e, t)=>new te({\n innerType: e,\n typeName: oe.ZodDefault,\n defaultValue: \"function\" == typeof t.default ? t.default : ()=>t.default,\n ...u(t)\n });\n class se extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e), s = {\n ...t,\n common: {\n ...t.common,\n issues: []\n }\n }, r = this._def.innerType._parse({\n data: s.data,\n path: s.path,\n parent: {\n ...s\n }\n });\n return (0, a.isAsync)(r) ? r.then((e)=>({\n status: \"valid\",\n value: \"valid\" === e.status ? e.value : this._def.catchValue({\n get error () {\n return new o.ZodError(s.common.issues);\n },\n input: s.data\n })\n })) : {\n status: \"valid\",\n value: \"valid\" === r.status ? r.value : this._def.catchValue({\n get error () {\n return new o.ZodError(s.common.issues);\n },\n input: s.data\n })\n };\n }\n removeCatch() {\n return this._def.innerType;\n }\n }\n t.ZodCatch = se, se.create = (e, t)=>new se({\n innerType: e,\n typeName: oe.ZodCatch,\n catchValue: \"function\" == typeof t.catch ? t.catch : ()=>t.catch,\n ...u(t)\n });\n class re extends c {\n _parse(e) {\n if (this._getType(e) !== n.ZodParsedType.nan) {\n const t = this._getOrReturnCtx(e);\n return (0, a.addIssueToContext)(t, {\n code: o.ZodIssueCode.invalid_type,\n expected: n.ZodParsedType.nan,\n received: t.parsedType\n }), a.INVALID;\n }\n return {\n status: \"valid\",\n value: e.data\n };\n }\n }\n t.ZodNaN = re, re.create = (e)=>new re({\n typeName: oe.ZodNaN,\n ...u(e)\n }), t.BRAND = Symbol(\"zod_brand\");\n class ie extends c {\n _parse(e) {\n const { ctx: t } = this._processInputParams(e), s = t.data;\n return this._def.type._parse({\n data: s,\n path: t.path,\n parent: t\n });\n }\n unwrap() {\n return this._def.type;\n }\n }\n t.ZodBranded = ie;\n class ae extends c {\n _parse(e) {\n const { status: t, ctx: s } = this._processInputParams(e);\n if (s.common.async) return (async ()=>{\n const e = await this._def.in._parseAsync({\n data: s.data,\n path: s.path,\n parent: s\n });\n return \"aborted\" === e.status ? a.INVALID : \"dirty\" === e.status ? (t.dirty(), (0, a.DIRTY)(e.value)) : this._def.out._parseAsync({\n data: e.value,\n path: s.path,\n parent: s\n });\n })();\n {\n const e = this._def.in._parseSync({\n data: s.data,\n path: s.path,\n parent: s\n });\n return \"aborted\" === e.status ? a.INVALID : \"dirty\" === e.status ? (t.dirty(), {\n status: \"dirty\",\n value: e.value\n }) : this._def.out._parseSync({\n data: e.value,\n path: s.path,\n parent: s\n });\n }\n }\n static create(e, t) {\n return new ae({\n in: e,\n out: t,\n typeName: oe.ZodPipeline\n });\n }\n }\n t.ZodPipeline = ae;\n class ne extends c {\n _parse(e) {\n const t = this._def.innerType._parse(e);\n return (0, a.isValid)(t) && (t.value = Object.freeze(t.value)), t;\n }\n }\n var oe;\n t.ZodReadonly = ne, ne.create = (e, t)=>new ne({\n innerType: e,\n typeName: oe.ZodReadonly,\n ...u(t)\n }), t.custom = (e, t = {}, s)=>e ? L.create().superRefine((r, i)=>{\n var a, n;\n if (!e(r)) {\n const e = \"function\" == typeof t ? t(r) : \"string\" == typeof t ? {\n message: t\n } : t, o = null === (n = null !== (a = e.fatal) && void 0 !== a ? a : s) || void 0 === n || n, d = \"string\" == typeof e ? {\n message: e\n } : e;\n i.addIssue({\n code: \"custom\",\n ...d,\n fatal: o\n });\n }\n }) : L.create(), t.late = {\n object: N.lazycreate\n }, function(e) {\n e.ZodString = \"ZodString\", e.ZodNumber = \"ZodNumber\", e.ZodNaN = \"ZodNaN\", e.ZodBigInt = \"ZodBigInt\", e.ZodBoolean = \"ZodBoolean\", e.ZodDate = \"ZodDate\", e.ZodSymbol = \"ZodSymbol\", e.ZodUndefined = \"ZodUndefined\", e.ZodNull = \"ZodNull\", e.ZodAny = \"ZodAny\", e.ZodUnknown = \"ZodUnknown\", e.ZodNever = \"ZodNever\", e.ZodVoid = \"ZodVoid\", e.ZodArray = \"ZodArray\", e.ZodObject = \"ZodObject\", e.ZodUnion = \"ZodUnion\", e.ZodDiscriminatedUnion = \"ZodDiscriminatedUnion\", e.ZodIntersection = \"ZodIntersection\", e.ZodTuple = \"ZodTuple\", e.ZodRecord = \"ZodRecord\", e.ZodMap = \"ZodMap\", e.ZodSet = \"ZodSet\", e.ZodFunction = \"ZodFunction\", e.ZodLazy = \"ZodLazy\", e.ZodLiteral = \"ZodLiteral\", e.ZodEnum = \"ZodEnum\", e.ZodEffects = \"ZodEffects\", e.ZodNativeEnum = \"ZodNativeEnum\", e.ZodOptional = \"ZodOptional\", e.ZodNullable = \"ZodNullable\", e.ZodDefault = \"ZodDefault\", e.ZodCatch = \"ZodCatch\", e.ZodPromise = \"ZodPromise\", e.ZodBranded = \"ZodBranded\", e.ZodPipeline = \"ZodPipeline\", e.ZodReadonly = \"ZodReadonly\";\n }(oe = t.ZodFirstPartyTypeKind || (t.ZodFirstPartyTypeKind = {})), t.instanceof = (e, s = {\n message: `Input not instance of ${e.name}`\n })=>(0, t.custom)((t)=>t instanceof e, s);\n const de = b.create;\n t.string = de;\n const le = I.create;\n t.number = le;\n const ue = re.create;\n t.nan = ue;\n const ce = Z.create;\n t.bigint = ce;\n const pe = T.create;\n t.boolean = pe;\n const he = k.create;\n t.date = he;\n const fe = w.create;\n t.symbol = fe;\n const me = C.create;\n t.undefined = me;\n const ye = z.create;\n t.null = ye;\n const _e = L.create;\n t.any = _e;\n const ve = P.create;\n t.unknown = ve;\n const ge = O.create;\n t.never = ge;\n const be = j.create;\n t.void = be;\n const xe = E.create;\n t.array = xe;\n const Ie = N.create;\n t.object = Ie;\n const Ze = N.strictCreate;\n t.strictObject = Ze;\n const Te = M.create;\n t.union = Te;\n const ke = D.create;\n t.discriminatedUnion = ke;\n const we = R.create;\n t.intersection = we;\n const Ce = V.create;\n t.tuple = Ce;\n const ze = $.create;\n t.record = ze;\n const Le = B.create;\n t.map = Le;\n const Pe = F.create;\n t.set = Pe;\n const Oe = K.create;\n t.function = Oe;\n const je = G.create;\n t.lazy = je;\n const Ee = W.create;\n t.literal = Ee;\n const Se = H.create;\n t.enum = Se;\n const Ne = q.create;\n t.nativeEnum = Ne;\n const Me = X.create;\n t.promise = Me;\n const Ae = J.create;\n t.effect = Ae, t.transformer = Ae;\n const De = Q.create;\n t.optional = De;\n const Ue = ee.create;\n t.nullable = Ue;\n const Re = J.createWithPreprocess;\n t.preprocess = Re;\n const Ve = ae.create;\n t.pipeline = Ve, t.ostring = ()=>de().optional(), t.onumber = ()=>le().optional(), t.oboolean = ()=>pe().optional(), t.coerce = {\n string: (e)=>b.create({\n ...e,\n coerce: !0\n }),\n number: (e)=>I.create({\n ...e,\n coerce: !0\n }),\n boolean: (e)=>T.create({\n ...e,\n coerce: !0\n }),\n bigint: (e)=>Z.create({\n ...e,\n coerce: !0\n }),\n date: (e)=>k.create({\n ...e,\n coerce: !0\n })\n }, t.NEVER = a.INVALID;\n },\n 205: (t)=>{\n t.exports = e;\n }\n }, s = {};\n function r(e) {\n var i = s[e];\n if (void 0 !== i) return i.exports;\n var a = s[e] = {\n exports: {}\n };\n return t[e].call(a.exports, a, a.exports, r), a.exports;\n }\n return r.d = (e, t)=>{\n for(var s in t)r.o(t, s) && !r.o(e, s) && Object.defineProperty(e, s, {\n enumerable: !0,\n get: t[s]\n });\n }, r.o = (e, t)=>Object.prototype.hasOwnProperty.call(e, t), r.r = (e)=>{\n \"undefined\" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {\n value: \"Module\"\n }), Object.defineProperty(e, \"__esModule\", {\n value: !0\n });\n }, r(607);\n })());\n\n\nvar $53be842a0003f2fd$exports = {};\n$53be842a0003f2fd$exports = new URL(\"Hero 01.0a89e3b5.png\", import.meta.url).toString();\n\n\nvar $ee38e295ce16494f$exports = {};\n$ee38e295ce16494f$exports = new URL(\"Solaria Demo Update 01.c847244e.png\", import.meta.url).toString();\n\n\nvar $6e5a0b5cd91b5e01$exports = {};\n$6e5a0b5cd91b5e01$exports = new URL(\"Level_0.076f9bf4.ldtkl\", import.meta.url).toString();\n\n\nvar $bbaeefda90929bac$exports = {};\n$bbaeefda90929bac$exports = new URL(\"Level_1.fb97a422.ldtkl\", import.meta.url).toString();\n\n\nvar $2b4fa2e46d897f1a$exports = {};\n$2b4fa2e46d897f1a$exports = new URL(\"top-down.8a075006.ldtk\", import.meta.url).toString();\n\n\nconst $7c4c300842bd4cf2$export$e9a269813a6315a4 = {\n HeroSpriteSheetPng: new (0, $3MXpL.ImageSource)((0, (/*@__PURE__*/$parcel$interopDefault($53be842a0003f2fd$exports))), false, (0, $3MXpL.ImageFiltering).Pixel),\n LdtkResource: new (0, $f82d5511d53990a3$exports.LdtkResource)((0, (/*@__PURE__*/$parcel$interopDefault($2b4fa2e46d897f1a$exports))), {\n useTilemapCameraStrategy: true,\n useMapBackgroundColor: true,\n // Path map intercepts and redirects to work around parcel's static bundling\n pathMap: [\n {\n path: \"Hero 01.png\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($53be842a0003f2fd$exports)))\n },\n {\n path: \"Level_0.ldtkl\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($6e5a0b5cd91b5e01$exports)))\n },\n {\n path: \"Level_1.ldtkl\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($bbaeefda90929bac$exports)))\n },\n {\n path: \"Solaria Demo Update 01.png\",\n output: (0, (/*@__PURE__*/$parcel$interopDefault($ee38e295ce16494f$exports)))\n }\n ]\n })\n};\nconst $7c4c300842bd4cf2$export$f4c5de44377d2946 = new (0, $3MXpL.Loader)();\nfor (let resource of Object.values($7c4c300842bd4cf2$export$e9a269813a6315a4))$7c4c300842bd4cf2$export$f4c5de44377d2946.addResource(resource);\n\n\nconst $9d936a2aecb96285$export$29cd7b75162a9425 = {\n PlayerSpeed: 32,\n PlayerFrameSpeed: 200\n};\n\n\nclass $51d548b0596e1d08$export$2616165974278734 extends $3MXpL.Actor {\n constructor(args){\n super({\n ...args,\n collisionType: $3MXpL.CollisionType.Active\n });\n }\n onInitialize(engine) {\n const playerSpriteSheet = $3MXpL.SpriteSheet.fromImageSource({\n image: (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).HeroSpriteSheetPng,\n grid: {\n spriteWidth: 16,\n spriteHeight: 16,\n rows: 8,\n columns: 8\n }\n });\n const leftIdle = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 1),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 1),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 1),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 1),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"left-idle\", leftIdle);\n const rightIdle = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 2),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 2),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 2),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 2),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"right-idle\", rightIdle);\n const upIdle = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 3),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 3),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 3),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 3),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"up-idle\", upIdle);\n const downIdle = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 0),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 0),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 0),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 0),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"down-idle\", downIdle);\n const leftWalk = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 5),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 5),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 5),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 5),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"left-walk\", leftWalk);\n const rightWalk = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 6),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 6),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 6),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 6),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"right-walk\", rightWalk);\n const upWalk = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 7),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 7),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 7),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 7),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"up-walk\", upWalk);\n const downWalk = new $3MXpL.Animation({\n frames: [\n {\n graphic: playerSpriteSheet.getSprite(0, 4),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(1, 4),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(2, 4),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n },\n {\n graphic: playerSpriteSheet.getSprite(3, 4),\n duration: (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerFrameSpeed\n }\n ]\n });\n this.graphics.add(\"down-walk\", downWalk);\n }\n onPreUpdate(engine, elapsedMs) {\n this.vel = $3MXpL.Vector.Zero;\n this.graphics.use(\"down-idle\");\n if (engine.input.keyboard.isHeld($3MXpL.Input.Keys.ArrowRight)) {\n this.vel = $3MXpL.vec((0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerSpeed, 0);\n this.graphics.use(\"right-walk\");\n }\n if (engine.input.keyboard.isHeld($3MXpL.Input.Keys.ArrowLeft)) {\n this.vel = $3MXpL.vec(-(0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerSpeed, 0);\n this.graphics.use(\"left-walk\");\n }\n if (engine.input.keyboard.isHeld($3MXpL.Input.Keys.ArrowUp)) {\n this.vel = $3MXpL.vec(0, -(0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerSpeed);\n this.graphics.use(\"up-walk\");\n }\n if (engine.input.keyboard.isHeld($3MXpL.Input.Keys.ArrowDown)) {\n this.vel = $3MXpL.vec(0, (0, $9d936a2aecb96285$export$29cd7b75162a9425).PlayerSpeed);\n this.graphics.use(\"down-walk\");\n }\n }\n}\n\n\n\nconst $ad2bcec7a0192558$var$game = new $3MXpL.Engine({\n resolution: {\n width: 256,\n height: 256\n },\n viewport: {\n width: 1024,\n height: 1024\n },\n suppressPlayButton: true,\n pixelArt: true,\n pixelRatio: 4\n});\n$ad2bcec7a0192558$var$game.start((0, $7c4c300842bd4cf2$export$f4c5de44377d2946)).then(()=>{\n console.log(\"Game start!\");\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.registerEntityIdentifierFactory(\"PlayerStart\", (props)=>{\n const player = new (0, $51d548b0596e1d08$export$2616165974278734)({\n name: \"player\",\n anchor: $3MXpL.vec(props.entity.__pivot[0], props.entity.__pivot[1]),\n width: props.entity.width,\n height: props.entity.height,\n pos: props.worldPos,\n z: props.layer.order\n });\n $ad2bcec7a0192558$var$game.currentScene.camera.strategy.lockToActor(player);\n return player;\n });\n // Resources.LdtkResource.getLevel('Level_0')?.layers\n // Provide a type to the plugin to use for a specific entity identifier\n // Player.ts\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LdtkResource.addToScene($ad2bcec7a0192558$var$game.currentScene, {\n pos: $3MXpL.vec(0, 0)\n });\n});\n\n\n//# sourceMappingURL=index.c2a0b4ac.js.map\n","/*!\n * excalibur - 0.29.0 - 2024-2-20\n * https://github.com/excaliburjs/Excalibur\n * Copyright (c) 2024 Excalibur.js \n * Licensed BSD-2-Clause\n * @preserve\n */\n/******/ var __webpack_modules__ = ({\n\n/***/ 7835:\n/***/ ((module, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./Director/Loader.css\"],\"names\":[],\"mappings\":\"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\"sourcesContent\":[\"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n/***/ }),\n\n/***/ 7379:\n/***/ ((module, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./Util/Toaster.css\"],\"names\":[],\"mappings\":\";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\"sourcesContent\":[\"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n/***/ }),\n\n/***/ 2609:\n/***/ ((module) => {\n\n\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};\n\n/***/ }),\n\n/***/ 272:\n/***/ ((module) => {\n\n\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};\n\n/***/ }),\n\n/***/ 1324:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n__webpack_require__(7206);\nvar entryUnbind = __webpack_require__(8193);\n\nmodule.exports = entryUnbind('Array', 'sort');\n\n\n/***/ }),\n\n/***/ 3571:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n__webpack_require__(9867);\nvar path = __webpack_require__(8588);\n\nmodule.exports = path.Object.keys;\n\n\n/***/ }),\n\n/***/ 1052:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(688);\nvar tryToString = __webpack_require__(3397);\n\nvar $TypeError = TypeError;\n\n// `Assert: IsCallable(argument) is true`\nmodule.exports = function (argument) {\n if (isCallable(argument)) return argument;\n throw new $TypeError(tryToString(argument) + ' is not a function');\n};\n\n\n/***/ }),\n\n/***/ 9175:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isObject = __webpack_require__(5309);\n\nvar $String = String;\nvar $TypeError = TypeError;\n\n// `Assert: Type(argument) is Object`\nmodule.exports = function (argument) {\n if (isObject(argument)) return argument;\n throw new $TypeError($String(argument) + ' is not an object');\n};\n\n\n/***/ }),\n\n/***/ 1138:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIndexedObject = __webpack_require__(6854);\nvar toAbsoluteIndex = __webpack_require__(7352);\nvar lengthOfArrayLike = __webpack_require__(8344);\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\nvar createMethod = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el !== el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value !== value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) {\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n};\n\n\n/***/ }),\n\n/***/ 567:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4694);\n\nmodule.exports = function (METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function () { return 1; }, 1);\n });\n};\n\n\n/***/ }),\n\n/***/ 7686:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\n\nmodule.exports = uncurryThis([].slice);\n\n\n/***/ }),\n\n/***/ 3097:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar arraySlice = __webpack_require__(7686);\n\nvar floor = Math.floor;\n\nvar sort = function (array, comparefn) {\n var length = array.length;\n\n if (length < 8) {\n // insertion sort\n var i = 1;\n var element, j;\n\n while (i < length) {\n j = i;\n element = array[i];\n while (j && comparefn(array[j - 1], element) > 0) {\n array[j] = array[--j];\n }\n if (j !== i++) array[j] = element;\n }\n } else {\n // merge sort\n var middle = floor(length / 2);\n var left = sort(arraySlice(array, 0, middle), comparefn);\n var right = sort(arraySlice(array, middle), comparefn);\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n\n while (lindex < llength || rindex < rlength) {\n array[lindex + rindex] = (lindex < llength && rindex < rlength)\n ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]\n : lindex < llength ? left[lindex++] : right[rindex++];\n }\n }\n\n return array;\n};\n\nmodule.exports = sort;\n\n\n/***/ }),\n\n/***/ 2177:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\n\nvar toString = uncurryThis({}.toString);\nvar stringSlice = uncurryThis(''.slice);\n\nmodule.exports = function (it) {\n return stringSlice(toString(it), 8, -1);\n};\n\n\n/***/ }),\n\n/***/ 1566:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar TO_STRING_TAG_SUPPORT = __webpack_require__(2522);\nvar isCallable = __webpack_require__(688);\nvar classofRaw = __webpack_require__(2177);\nvar wellKnownSymbol = __webpack_require__(2032);\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar $Object = Object;\n\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result;\n};\n\n\n/***/ }),\n\n/***/ 3891:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar hasOwn = __webpack_require__(4678);\nvar ownKeys = __webpack_require__(990);\nvar getOwnPropertyDescriptorModule = __webpack_require__(7537);\nvar definePropertyModule = __webpack_require__(2131);\n\nmodule.exports = function (target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {\n defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n }\n};\n\n\n/***/ }),\n\n/***/ 2385:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar definePropertyModule = __webpack_require__(2131);\nvar createPropertyDescriptor = __webpack_require__(7781);\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n\n\n/***/ }),\n\n/***/ 7781:\n/***/ ((module) => {\n\n\nmodule.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n\n\n/***/ }),\n\n/***/ 2470:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(688);\nvar definePropertyModule = __webpack_require__(2131);\nvar makeBuiltIn = __webpack_require__(1135);\nvar defineGlobalProperty = __webpack_require__(1604);\n\nmodule.exports = function (O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) { /* empty */ }\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n } return O;\n};\n\n\n/***/ }),\n\n/***/ 1604:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\n\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\n\nmodule.exports = function (key, value) {\n try {\n defineProperty(global, key, { value: value, configurable: true, writable: true });\n } catch (error) {\n global[key] = value;\n } return value;\n};\n\n\n/***/ }),\n\n/***/ 955:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar tryToString = __webpack_require__(3397);\n\nvar $TypeError = TypeError;\n\nmodule.exports = function (O, P) {\n if (!delete O[P]) throw new $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));\n};\n\n\n/***/ }),\n\n/***/ 9924:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4694);\n\n// Detect IE8's incomplete defineProperty implementation\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7;\n});\n\n\n/***/ }),\n\n/***/ 1442:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar isObject = __webpack_require__(5309);\n\nvar document = global.document;\n// typeof document.createElement is 'object' in old IE\nvar EXISTS = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return EXISTS ? document.createElement(it) : {};\n};\n\n\n/***/ }),\n\n/***/ 9016:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar userAgent = __webpack_require__(1370);\n\nvar firefox = userAgent.match(/firefox\\/(\\d+)/i);\n\nmodule.exports = !!firefox && +firefox[1];\n\n\n/***/ }),\n\n/***/ 821:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar UA = __webpack_require__(1370);\n\nmodule.exports = /MSIE|Trident/.test(UA);\n\n\n/***/ }),\n\n/***/ 1370:\n/***/ ((module) => {\n\n\nmodule.exports = typeof navigator != 'undefined' && String(navigator.userAgent) || '';\n\n\n/***/ }),\n\n/***/ 7067:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar userAgent = __webpack_require__(1370);\n\nvar process = global.process;\nvar Deno = global.Deno;\nvar versions = process && process.versions || Deno && Deno.version;\nvar v8 = versions && versions.v8;\nvar match, version;\n\nif (v8) {\n match = v8.split('.');\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n}\n\n// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n// so check `userAgent` even if `.v8` exists, but 0\nif (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n}\n\nmodule.exports = version;\n\n\n/***/ }),\n\n/***/ 4389:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar userAgent = __webpack_require__(1370);\n\nvar webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n\nmodule.exports = !!webkit && +webkit[1];\n\n\n/***/ }),\n\n/***/ 8193:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar uncurryThis = __webpack_require__(9668);\n\nmodule.exports = function (CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n};\n\n\n/***/ }),\n\n/***/ 2367:\n/***/ ((module) => {\n\n\n// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n\n\n/***/ }),\n\n/***/ 5532:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar getOwnPropertyDescriptor = (__webpack_require__(7537).f);\nvar createNonEnumerableProperty = __webpack_require__(2385);\nvar defineBuiltIn = __webpack_require__(2470);\nvar defineGlobalProperty = __webpack_require__(1604);\nvar copyConstructorProperties = __webpack_require__(3891);\nvar isForced = __webpack_require__(1633);\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = global;\n } else if (STATIC) {\n target = global[TARGET] || defineGlobalProperty(TARGET, {});\n } else {\n target = global[TARGET] && global[TARGET].prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n createNonEnumerableProperty(sourceProperty, 'sham', true);\n }\n defineBuiltIn(target, key, sourceProperty, options);\n }\n};\n\n\n/***/ }),\n\n/***/ 4694:\n/***/ ((module) => {\n\n\nmodule.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n\n\n/***/ }),\n\n/***/ 6398:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4694);\n\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function () { /* empty */ }).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != 'function' || test.hasOwnProperty('prototype');\n});\n\n\n/***/ }),\n\n/***/ 8724:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_BIND = __webpack_require__(6398);\n\nvar call = Function.prototype.call;\n\nmodule.exports = NATIVE_BIND ? call.bind(call) : function () {\n return call.apply(call, arguments);\n};\n\n\n/***/ }),\n\n/***/ 453:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar hasOwn = __webpack_require__(4678);\n\nvar FunctionPrototype = Function.prototype;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n\nvar EXISTS = hasOwn(FunctionPrototype, 'name');\n// additional protection from minified / mangled / dropped function names\nvar PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';\nvar CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable));\n\nmodule.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n};\n\n\n/***/ }),\n\n/***/ 9668:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_BIND = __webpack_require__(6398);\n\nvar FunctionPrototype = Function.prototype;\nvar call = FunctionPrototype.call;\nvar uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n\nmodule.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {\n return function () {\n return call.apply(fn, arguments);\n };\n};\n\n\n/***/ }),\n\n/***/ 2160:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar isCallable = __webpack_require__(688);\n\nvar aFunction = function (argument) {\n return isCallable(argument) ? argument : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n};\n\n\n/***/ }),\n\n/***/ 5383:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar aCallable = __webpack_require__(1052);\nvar isNullOrUndefined = __webpack_require__(5268);\n\n// `GetMethod` abstract operation\n// https://tc39.es/ecma262/#sec-getmethod\nmodule.exports = function (V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n};\n\n\n/***/ }),\n\n/***/ 2150:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\n\nvar check = function (it) {\n return it && it.Math === Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == 'object' && globalThis) ||\n check(typeof window == 'object' && window) ||\n // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == 'object' && self) ||\n check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) ||\n check(typeof this == 'object' && this) ||\n // eslint-disable-next-line no-new-func -- fallback\n (function () { return this; })() || Function('return this')();\n\n\n/***/ }),\n\n/***/ 4678:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar toObject = __webpack_require__(298);\n\nvar hasOwnProperty = uncurryThis({}.hasOwnProperty);\n\n// `HasOwnProperty` abstract operation\n// https://tc39.es/ecma262/#sec-hasownproperty\n// eslint-disable-next-line es/no-object-hasown -- safe\nmodule.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n};\n\n\n/***/ }),\n\n/***/ 7390:\n/***/ ((module) => {\n\n\nmodule.exports = {};\n\n\n/***/ }),\n\n/***/ 7913:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar fails = __webpack_require__(4694);\nvar createElement = __webpack_require__(1442);\n\n// Thanks to IE8 for its funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a !== 7;\n});\n\n\n/***/ }),\n\n/***/ 4347:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar fails = __webpack_require__(4694);\nvar classof = __webpack_require__(2177);\n\nvar $Object = Object;\nvar split = uncurryThis(''.split);\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) === 'String' ? split(it, '') : $Object(it);\n} : $Object;\n\n\n/***/ }),\n\n/***/ 1881:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar isCallable = __webpack_require__(688);\nvar store = __webpack_require__(6762);\n\nvar functionToString = uncurryThis(Function.toString);\n\n// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\nif (!isCallable(store.inspectSource)) {\n store.inspectSource = function (it) {\n return functionToString(it);\n };\n}\n\nmodule.exports = store.inspectSource;\n\n\n/***/ }),\n\n/***/ 7804:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_WEAK_MAP = __webpack_require__(4724);\nvar global = __webpack_require__(2150);\nvar isObject = __webpack_require__(5309);\nvar createNonEnumerableProperty = __webpack_require__(2385);\nvar hasOwn = __webpack_require__(4678);\nvar shared = __webpack_require__(6762);\nvar sharedKey = __webpack_require__(1962);\nvar hiddenKeys = __webpack_require__(7390);\n\nvar OBJECT_ALREADY_INITIALIZED = 'Object already initialized';\nvar TypeError = global.TypeError;\nvar WeakMap = global.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw new TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap());\n /* eslint-disable no-self-assign -- prototype methods protection */\n store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */\n set = function (it, metadata) {\n if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function (it) {\n return store.get(it) || {};\n };\n has = function (it) {\n return store.has(it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return hasOwn(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n\n\n/***/ }),\n\n/***/ 688:\n/***/ ((module) => {\n\n\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\nvar documentAll = typeof document == 'object' && document.all;\n\n// `IsCallable` abstract operation\n// https://tc39.es/ecma262/#sec-iscallable\n// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\nmodule.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) {\n return typeof argument == 'function' || argument === documentAll;\n} : function (argument) {\n return typeof argument == 'function';\n};\n\n\n/***/ }),\n\n/***/ 1633:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4694);\nvar isCallable = __webpack_require__(688);\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value === POLYFILL ? true\n : value === NATIVE ? false\n : isCallable(detection) ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n\n\n/***/ }),\n\n/***/ 5268:\n/***/ ((module) => {\n\n\n// we can't use just `it == null` since of `document.all` special case\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\nmodule.exports = function (it) {\n return it === null || it === undefined;\n};\n\n\n/***/ }),\n\n/***/ 5309:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(688);\n\nmodule.exports = function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it);\n};\n\n\n/***/ }),\n\n/***/ 6555:\n/***/ ((module) => {\n\n\nmodule.exports = false;\n\n\n/***/ }),\n\n/***/ 7935:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar getBuiltIn = __webpack_require__(2160);\nvar isCallable = __webpack_require__(688);\nvar isPrototypeOf = __webpack_require__(6148);\nvar USE_SYMBOL_AS_UID = __webpack_require__(4866);\n\nvar $Object = Object;\n\nmodule.exports = USE_SYMBOL_AS_UID ? function (it) {\n return typeof it == 'symbol';\n} : function (it) {\n var $Symbol = getBuiltIn('Symbol');\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n};\n\n\n/***/ }),\n\n/***/ 8344:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toLength = __webpack_require__(7331);\n\n// `LengthOfArrayLike` abstract operation\n// https://tc39.es/ecma262/#sec-lengthofarraylike\nmodule.exports = function (obj) {\n return toLength(obj.length);\n};\n\n\n/***/ }),\n\n/***/ 1135:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar fails = __webpack_require__(4694);\nvar isCallable = __webpack_require__(688);\nvar hasOwn = __webpack_require__(4678);\nvar DESCRIPTORS = __webpack_require__(9924);\nvar CONFIGURABLE_FUNCTION_NAME = (__webpack_require__(453).CONFIGURABLE);\nvar inspectSource = __webpack_require__(1881);\nvar InternalStateModule = __webpack_require__(7804);\n\nvar enforceInternalState = InternalStateModule.enforce;\nvar getInternalState = InternalStateModule.get;\nvar $String = String;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\nvar stringSlice = uncurryThis(''.slice);\nvar replace = uncurryThis(''.replace);\nvar join = uncurryThis([].join);\n\nvar CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () {\n return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;\n});\n\nvar TEMPLATE = String(String).split('String');\n\nvar makeBuiltIn = module.exports = function (value, name, options) {\n if (stringSlice($String(name), 0, 7) === 'Symbol(') {\n name = '[' + replace($String(name), /^Symbol\\(([^)]*)\\).*$/, '$1') + ']';\n }\n if (options && options.getter) name = 'get ' + name;\n if (options && options.setter) name = 'set ' + name;\n if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {\n if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) {\n defineProperty(value, 'length', { value: options.arity });\n }\n try {\n if (options && hasOwn(options, 'constructor') && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false });\n // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) { /* empty */ }\n var state = enforceInternalState(value);\n if (!hasOwn(state, 'source')) {\n state.source = join(TEMPLATE, typeof name == 'string' ? name : '');\n } return value;\n};\n\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n// eslint-disable-next-line no-extend-native -- required\nFunction.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n}, 'toString');\n\n\n/***/ }),\n\n/***/ 1787:\n/***/ ((module) => {\n\n\nvar ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `Math.trunc` method\n// https://tc39.es/ecma262/#sec-math.trunc\n// eslint-disable-next-line es/no-math-trunc -- safe\nmodule.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n};\n\n\n/***/ }),\n\n/***/ 2131:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar IE8_DOM_DEFINE = __webpack_require__(7913);\nvar V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(2666);\nvar anObject = __webpack_require__(9175);\nvar toPropertyKey = __webpack_require__(2358);\n\nvar $TypeError = TypeError;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar $defineProperty = Object.defineProperty;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar ENUMERABLE = 'enumerable';\nvar CONFIGURABLE = 'configurable';\nvar WRITABLE = 'writable';\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\nexports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n } return $defineProperty(O, P, Attributes);\n} : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n\n\n/***/ }),\n\n/***/ 7537:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar call = __webpack_require__(8724);\nvar propertyIsEnumerableModule = __webpack_require__(8208);\nvar createPropertyDescriptor = __webpack_require__(7781);\nvar toIndexedObject = __webpack_require__(6854);\nvar toPropertyKey = __webpack_require__(2358);\nvar hasOwn = __webpack_require__(4678);\nvar IE8_DOM_DEFINE = __webpack_require__(7913);\n\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\nexports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n};\n\n\n/***/ }),\n\n/***/ 6217:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar internalObjectKeys = __webpack_require__(1528);\nvar enumBugKeys = __webpack_require__(2367);\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.es/ecma262/#sec-object.getownpropertynames\n// eslint-disable-next-line es/no-object-getownpropertynames -- safe\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n\n\n/***/ }),\n\n/***/ 5168:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\nexports.f = Object.getOwnPropertySymbols;\n\n\n/***/ }),\n\n/***/ 6148:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\n\nmodule.exports = uncurryThis({}.isPrototypeOf);\n\n\n/***/ }),\n\n/***/ 1528:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\nvar hasOwn = __webpack_require__(4678);\nvar toIndexedObject = __webpack_require__(6854);\nvar indexOf = (__webpack_require__(1138).indexOf);\nvar hiddenKeys = __webpack_require__(7390);\n\nvar push = uncurryThis([].push);\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (hasOwn(O, key = names[i++])) {\n ~indexOf(result, key) || push(result, key);\n }\n return result;\n};\n\n\n/***/ }),\n\n/***/ 1728:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar internalObjectKeys = __webpack_require__(1528);\nvar enumBugKeys = __webpack_require__(2367);\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n// eslint-disable-next-line es/no-object-keys -- safe\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n\n\n/***/ }),\n\n/***/ 8208:\n/***/ ((__unused_webpack_module, exports) => {\n\n\nvar $propertyIsEnumerable = {}.propertyIsEnumerable;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);\n\n// `Object.prototype.propertyIsEnumerable` method implementation\n// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : $propertyIsEnumerable;\n\n\n/***/ }),\n\n/***/ 110:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar call = __webpack_require__(8724);\nvar isCallable = __webpack_require__(688);\nvar isObject = __webpack_require__(5309);\n\nvar $TypeError = TypeError;\n\n// `OrdinaryToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-ordinarytoprimitive\nmodule.exports = function (input, pref) {\n var fn, val;\n if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw new $TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/***/ }),\n\n/***/ 990:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar getBuiltIn = __webpack_require__(2160);\nvar uncurryThis = __webpack_require__(9668);\nvar getOwnPropertyNamesModule = __webpack_require__(6217);\nvar getOwnPropertySymbolsModule = __webpack_require__(5168);\nvar anObject = __webpack_require__(9175);\n\nvar concat = uncurryThis([].concat);\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n};\n\n\n/***/ }),\n\n/***/ 8588:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\n\nmodule.exports = global;\n\n\n/***/ }),\n\n/***/ 1166:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isNullOrUndefined = __webpack_require__(5268);\n\nvar $TypeError = TypeError;\n\n// `RequireObjectCoercible` abstract operation\n// https://tc39.es/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (isNullOrUndefined(it)) throw new $TypeError(\"Can't call method on \" + it);\n return it;\n};\n\n\n/***/ }),\n\n/***/ 1962:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar shared = __webpack_require__(2645);\nvar uid = __webpack_require__(5736);\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n\n\n/***/ }),\n\n/***/ 6762:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar defineGlobalProperty = __webpack_require__(1604);\n\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || defineGlobalProperty(SHARED, {});\n\nmodule.exports = store;\n\n\n/***/ }),\n\n/***/ 2645:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar IS_PURE = __webpack_require__(6555);\nvar store = __webpack_require__(6762);\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: '3.35.1',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)',\n license: 'https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE',\n source: 'https://github.com/zloirock/core-js'\n});\n\n\n/***/ }),\n\n/***/ 4112:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n/* eslint-disable es/no-symbol -- required for testing */\nvar V8_VERSION = __webpack_require__(7067);\nvar fails = __webpack_require__(4694);\nvar global = __webpack_require__(2150);\n\nvar $String = global.String;\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n var symbol = Symbol('symbol detection');\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) ||\n // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n});\n\n\n/***/ }),\n\n/***/ 7352:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIntegerOrInfinity = __webpack_require__(1680);\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\nmodule.exports = function (index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n\n\n/***/ }),\n\n/***/ 6854:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = __webpack_require__(4347);\nvar requireObjectCoercible = __webpack_require__(1166);\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n\n\n/***/ }),\n\n/***/ 1680:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar trunc = __webpack_require__(1787);\n\n// `ToIntegerOrInfinity` abstract operation\n// https://tc39.es/ecma262/#sec-tointegerorinfinity\nmodule.exports = function (argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n};\n\n\n/***/ }),\n\n/***/ 7331:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIntegerOrInfinity = __webpack_require__(1680);\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.es/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n var len = toIntegerOrInfinity(argument);\n return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n\n\n/***/ }),\n\n/***/ 298:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar requireObjectCoercible = __webpack_require__(1166);\n\nvar $Object = Object;\n\n// `ToObject` abstract operation\n// https://tc39.es/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return $Object(requireObjectCoercible(argument));\n};\n\n\n/***/ }),\n\n/***/ 1272:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar call = __webpack_require__(8724);\nvar isObject = __webpack_require__(5309);\nvar isSymbol = __webpack_require__(7935);\nvar getMethod = __webpack_require__(5383);\nvar ordinaryToPrimitive = __webpack_require__(110);\nvar wellKnownSymbol = __webpack_require__(2032);\n\nvar $TypeError = TypeError;\nvar TO_PRIMITIVE = wellKnownSymbol('toPrimitive');\n\n// `ToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-toprimitive\nmodule.exports = function (input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = 'default';\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw new $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = 'number';\n return ordinaryToPrimitive(input, pref);\n};\n\n\n/***/ }),\n\n/***/ 2358:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toPrimitive = __webpack_require__(1272);\nvar isSymbol = __webpack_require__(7935);\n\n// `ToPropertyKey` abstract operation\n// https://tc39.es/ecma262/#sec-topropertykey\nmodule.exports = function (argument) {\n var key = toPrimitive(argument, 'string');\n return isSymbol(key) ? key : key + '';\n};\n\n\n/***/ }),\n\n/***/ 2522:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar wellKnownSymbol = __webpack_require__(2032);\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n\ntest[TO_STRING_TAG] = 'z';\n\nmodule.exports = String(test) === '[object z]';\n\n\n/***/ }),\n\n/***/ 599:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar classof = __webpack_require__(1566);\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n return $String(argument);\n};\n\n\n/***/ }),\n\n/***/ 3397:\n/***/ ((module) => {\n\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n try {\n return $String(argument);\n } catch (error) {\n return 'Object';\n }\n};\n\n\n/***/ }),\n\n/***/ 5736:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(9668);\n\nvar id = 0;\nvar postfix = Math.random();\nvar toString = uncurryThis(1.0.toString);\n\nmodule.exports = function (key) {\n return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);\n};\n\n\n/***/ }),\n\n/***/ 4866:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n/* eslint-disable es/no-symbol -- required for testing */\nvar NATIVE_SYMBOL = __webpack_require__(4112);\n\nmodule.exports = NATIVE_SYMBOL\n && !Symbol.sham\n && typeof Symbol.iterator == 'symbol';\n\n\n/***/ }),\n\n/***/ 2666:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(9924);\nvar fails = __webpack_require__(4694);\n\n// V8 ~ Chrome 36-\n// https://bugs.chromium.org/p/v8/issues/detail?id=3334\nmodule.exports = DESCRIPTORS && fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function () { /* empty */ }, 'prototype', {\n value: 42,\n writable: false\n }).prototype !== 42;\n});\n\n\n/***/ }),\n\n/***/ 4724:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar isCallable = __webpack_require__(688);\n\nvar WeakMap = global.WeakMap;\n\nmodule.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));\n\n\n/***/ }),\n\n/***/ 2032:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(2150);\nvar shared = __webpack_require__(2645);\nvar hasOwn = __webpack_require__(4678);\nvar uid = __webpack_require__(5736);\nvar NATIVE_SYMBOL = __webpack_require__(4112);\nvar USE_SYMBOL_AS_UID = __webpack_require__(4866);\n\nvar Symbol = global.Symbol;\nvar WellKnownSymbolsStore = shared('wks');\nvar createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;\n\nmodule.exports = function (name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) {\n WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name)\n ? Symbol[name]\n : createWellKnownSymbol('Symbol.' + name);\n } return WellKnownSymbolsStore[name];\n};\n\n\n/***/ }),\n\n/***/ 7206:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar $ = __webpack_require__(5532);\nvar uncurryThis = __webpack_require__(9668);\nvar aCallable = __webpack_require__(1052);\nvar toObject = __webpack_require__(298);\nvar lengthOfArrayLike = __webpack_require__(8344);\nvar deletePropertyOrThrow = __webpack_require__(955);\nvar toString = __webpack_require__(599);\nvar fails = __webpack_require__(4694);\nvar internalSort = __webpack_require__(3097);\nvar arrayMethodIsStrict = __webpack_require__(567);\nvar FF = __webpack_require__(9016);\nvar IE_OR_EDGE = __webpack_require__(821);\nvar V8 = __webpack_require__(7067);\nvar WEBKIT = __webpack_require__(4389);\n\nvar test = [];\nvar nativeSort = uncurryThis(test.sort);\nvar push = uncurryThis(test.push);\n\n// IE8-\nvar FAILS_ON_UNDEFINED = fails(function () {\n test.sort(undefined);\n});\n// V8 bug\nvar FAILS_ON_NULL = fails(function () {\n test.sort(null);\n});\n// Old WebKit\nvar STRICT_METHOD = arrayMethodIsStrict('sort');\n\nvar STABLE_SORT = !fails(function () {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n\n var result = '';\n var code, chr, value, index;\n\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for (code = 65; code < 76; code++) {\n chr = String.fromCharCode(code);\n\n switch (code) {\n case 66: case 69: case 70: case 72: value = 3; break;\n case 68: case 71: value = 4; break;\n default: value = 2;\n }\n\n for (index = 0; index < 47; index++) {\n test.push({ k: chr + index, v: value });\n }\n }\n\n test.sort(function (a, b) { return b.v - a.v; });\n\n for (index = 0; index < test.length; index++) {\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n\n return result !== 'DGBEFHACIJK';\n});\n\nvar FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n\nvar getSortCompare = function (comparefn) {\n return function (x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n};\n\n// `Array.prototype.sort` method\n// https://tc39.es/ecma262/#sec-array.prototype.sort\n$({ target: 'Array', proto: true, forced: FORCED }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n\n var array = toObject(this);\n\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n\n for (index = 0; index < arrayLength; index++) {\n if (index in array) push(items, array[index]);\n }\n\n internalSort(items, getSortCompare(comparefn));\n\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n\n while (index < itemsLength) array[index] = items[index++];\n while (index < arrayLength) deletePropertyOrThrow(array, index++);\n\n return array;\n }\n});\n\n\n/***/ }),\n\n/***/ 9867:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar $ = __webpack_require__(5532);\nvar toObject = __webpack_require__(298);\nvar nativeKeys = __webpack_require__(1728);\nvar fails = __webpack_require__(4694);\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeKeys(1); });\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n});\n\n\n/***/ })\n\n/******/ });\n/************************************************************************/\n/******/ // The module cache\n/******/ var __webpack_module_cache__ = {};\n/******/ \n/******/ // The require function\n/******/ function __webpack_require__(moduleId) {\n/******/ \t// Check if module is in cache\n/******/ \tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \tif (cachedModule !== undefined) {\n/******/ \t\treturn cachedModule.exports;\n/******/ \t}\n/******/ \t// Create a new module (and put it into the cache)\n/******/ \tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\tid: moduleId,\n/******/ \t\t// no module.loaded needed\n/******/ \t\texports: {}\n/******/ \t};\n/******/ \n/******/ \t// Execute the module function\n/******/ \t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/ \n/******/ \t// Return the exports of the module\n/******/ \treturn module.exports;\n/******/ }\n/******/ \n/************************************************************************/\n/******/ /* webpack/runtime/compat get default export */\n/******/ (() => {\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = (module) => {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t() => (module['default']) :\n/******/ \t\t\t() => (module);\n/******/ \t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\treturn getter;\n/******/ \t};\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/define property getters */\n/******/ (() => {\n/******/ \t// define getter functions for harmony exports\n/******/ \t__webpack_require__.d = (exports, definition) => {\n/******/ \t\tfor(var key in definition) {\n/******/ \t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t};\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/global */\n/******/ (() => {\n/******/ \t__webpack_require__.g = (function() {\n/******/ \t\tif (typeof globalThis === 'object') return globalThis;\n/******/ \t\ttry {\n/******/ \t\t\treturn this || new Function('return this')();\n/******/ \t\t} catch (e) {\n/******/ \t\t\tif (typeof window === 'object') return window;\n/******/ \t\t}\n/******/ \t})();\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/hasOwnProperty shorthand */\n/******/ (() => {\n/******/ \t__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/make namespace object */\n/******/ (() => {\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = (exports) => {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/ })();\n/******/ \n/************************************************************************/\nvar __webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(() => {\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n y1j: () => (/* reexport */ ActionCompleteEvent),\n fWn: () => (/* reexport */ ActionContext),\n Ia8: () => (/* reexport */ ActionQueue),\n rqv: () => (/* reexport */ ActionSequence),\n zH6: () => (/* reexport */ ActionStartEvent),\n hLI: () => (/* reexport */ ActionsComponent),\n yyv: () => (/* reexport */ ActionsSystem),\n tX5: () => (/* reexport */ ActivateEvent),\n vtX: () => (/* reexport */ Actor),\n r7K: () => (/* reexport */ AddedComponent),\n cE4: () => (/* reexport */ AffineMatrix),\n fwF: () => (/* reexport */ Animation),\n sce: () => (/* reexport */ AnimationDirection),\n AQ6: () => (/* reexport */ AnimationEvents),\n _c7: () => (/* reexport */ AnimationStrategy),\n KUs: () => (/* reexport */ ArcadeSolver),\n Ajp: () => (/* reexport */ AudioContextFactory),\n dkO: () => (/* reexport */ Axes),\n RDh: () => (/* reexport */ Axis),\n _H9: () => (/* reexport */ BaseAlign),\n mxs: () => (/* reexport */ Blink),\n OmD: () => (/* reexport */ BodyComponent),\n kBf: () => (/* reexport */ BoundingBox),\n C4F: () => (/* reexport */ BroadphaseStrategy),\n NQt: () => (/* reexport */ BrowserComponent),\n JjN: () => (/* reexport */ BrowserEvents),\n EK_: () => (/* reexport */ Buttons),\n V1s: () => (/* reexport */ Camera),\n xHm: () => (/* reexport */ CameraEvents),\n Xz7: () => (/* reexport */ Canvas),\n Cdc: () => (/* reexport */ Circle),\n FKn: () => (/* reexport */ CircleCollider),\n SUY: () => (/* reexport */ Clock),\n ab2: () => (/* reexport */ ClosestLine),\n GfZ: () => (/* reexport */ ClosestLineJumpTable),\n YMS: () => (/* reexport */ Collider),\n oyv: () => (/* reexport */ ColliderComponent),\n aUb: () => (/* reexport */ CollisionContact),\n SdD: () => (/* reexport */ CollisionEndEvent),\n JUv: () => (/* reexport */ CollisionGroup),\n jEj: () => (/* reexport */ CollisionGroupManager),\n TFq: () => (/* reexport */ CollisionJumpTable),\n HDU: () => (/* reexport */ CollisionPostSolveEvent),\n R_y: () => (/* reexport */ CollisionPreSolveEvent),\n t50: () => (/* reexport */ CollisionStartEvent),\n s$$: () => (/* reexport */ CollisionSystem),\n v2G: () => (/* reexport */ CollisionType),\n Ilk: () => (/* reexport */ Color),\n s9i: () => (/* reexport */ ColorBlindFlags),\n dxL: () => (/* reexport */ ColorBlindnessMode),\n LLX: () => (/* reexport */ ColorBlindnessPostProcessor),\n wA2: () => (/* reexport */ Component),\n R_p: () => (/* reexport */ CompositeCollider),\n IQ$: () => (/* reexport */ Configurable),\n I5F: () => (/* reexport */ ConsoleAppender),\n X8$: () => (/* reexport */ ContactConstraintPoint),\n FR6: () => (/* reexport */ ContactEndEvent),\n pTZ: () => (/* reexport */ ContactSolveBias),\n U8o: () => (/* reexport */ ContactStartEvent),\n kbG: () => (/* reexport */ CoordPlane),\n FEv: () => (/* reexport */ CrossFade),\n iS_: () => (/* reexport */ DeactivateEvent),\n cGG: () => (/* reexport */ Debug),\n ETM: () => (/* reexport */ DebugConfig),\n RPN: () => (/* reexport */ DebugGraphicsComponent),\n skb: () => (/* reexport */ DebugSystem),\n SLU: () => (/* reexport */ DebugText),\n Q3w: () => (/* reexport */ DefaultAntialiasOptions),\n xK2: () => (/* reexport */ DefaultLoader),\n vrO: () => (/* reexport */ DefaultPhysicsConfig),\n EA2: () => (/* reexport */ DefaultPixelArtOptions),\n RdJ: () => (/* reexport */ DegreeOfFreedom),\n cNu: () => (/* reexport */ Delay),\n wtG: () => (/* reexport */ DeprecatedStaticToConfig),\n gU7: () => (/* reexport */ Detector),\n LSk: () => (/* reexport */ Die),\n Nmp: () => (/* reexport */ Direction),\n twX: () => (/* reexport */ Director),\n UND: () => (/* reexport */ DirectorEvents),\n d1Y: () => (/* reexport */ DisplayMode),\n xrL: () => (/* reexport */ DynamicTree),\n sRW: () => (/* reexport */ DynamicTreeCollisionProcessor),\n cmV: () => (/* binding */ EX_VERSION),\n qWz: () => (/* reexport */ EaseBy),\n N0Q: () => (/* reexport */ EaseTo),\n q8b: () => (/* reexport */ EasingFunctions),\n ynB: () => (/* reexport */ EdgeCollider),\n jT9: () => (/* reexport */ ElasticToActorStrategy),\n wAz: () => (/* reexport */ EmitterType),\n D4V: () => (/* reexport */ Engine),\n NLr: () => (/* reexport */ EngineEvents),\n N6H: () => (/* reexport */ EnterTriggerEvent),\n W1A: () => (/* reexport */ EnterViewPortEvent),\n JHW: () => (/* reexport */ Entity),\n ZZ$: () => (/* reexport */ EntityEvents),\n v2K: () => (/* reexport */ EntityManager),\n pBf: () => (/* reexport */ EventDispatcher),\n vpe: () => (/* reexport */ EventEmitter),\n GMl: () => (/* reexport */ EventTypes),\n zW2: () => (/* reexport */ Events_namespaceObject),\n B0K: () => (/* reexport */ ExResponse),\n Nv7: () => (/* reexport */ ExcaliburGraphicsContext2DCanvas),\n C_p: () => (/* reexport */ ExcaliburGraphicsContextWebGL),\n MUA: () => (/* reexport */ ExitTriggerEvent),\n xqU: () => (/* reexport */ ExitViewPortEvent),\n pTp: () => (/* reexport */ Fade),\n trb: () => (/* reexport */ FadeInOut),\n vUK: () => (/* reexport */ Flags),\n j9l: () => (/* reexport */ Follow),\n Zxw: () => (/* reexport */ Font),\n v51: () => (/* reexport */ FontCache),\n gYv: () => (/* reexport */ FontSource),\n Hdx: () => (/* reexport */ FontStyle),\n Z$d: () => (/* reexport */ FontUnit),\n iqV: () => (/* reexport */ FpsSampler),\n o$7: () => (/* reexport */ FrameStats),\n olM: () => (/* reexport */ Future),\n Zm$: () => (/* reexport */ GameEvent),\n $QH: () => (/* reexport */ GameStartEvent),\n i78: () => (/* reexport */ GameStopEvent),\n nJg: () => (/* reexport */ Gamepad),\n h6u: () => (/* reexport */ GamepadAxisEvent),\n hts: () => (/* reexport */ GamepadButtonEvent),\n j88: () => (/* reexport */ GamepadConnectEvent),\n VME: () => (/* reexport */ GamepadDisconnectEvent),\n fy2: () => (/* reexport */ Gamepads),\n nt: () => (/* reexport */ Gif),\n Ukr: () => (/* reexport */ GlobalCoordinates),\n zsu: () => (/* reexport */ Graphic),\n oA6: () => (/* reexport */ GraphicsComponent),\n TVh: () => (/* reexport */ GraphicsGroup),\n xxj: () => (/* reexport */ GraphicsSystem),\n XdK: () => (/* reexport */ HiddenEvent),\n fBD: () => (/* reexport */ HorizontalFirst),\n Jmb: () => (/* reexport */ ImageFiltering),\n cXo: () => (/* reexport */ ImageSource),\n Dm5: () => (/* reexport */ InitializeEvent),\n IIB: () => (/* reexport */ Input_Index_namespaceObject),\n IX$: () => (/* reexport */ InputHost),\n ebW: () => (/* reexport */ InputMapper),\n zI0: () => (/* reexport */ Integrator),\n LYD: () => (/* reexport */ IsometricEntityComponent),\n cEG: () => (/* reexport */ IsometricEntitySystem),\n SEl: () => (/* reexport */ IsometricMap),\n t9V: () => (/* reexport */ IsometricTile),\n ez5: () => (/* reexport */ KeyEvent),\n N1d: () => (/* reexport */ Keyboard),\n R8U: () => (/* reexport */ Keys),\n SKZ: () => (/* reexport */ KillEvent),\n __J: () => (/* reexport */ Label),\n RI$: () => (/* reexport */ LimitCameraBoundsStrategy),\n x12: () => (/* reexport */ Line),\n ccz: () => (/* reexport */ LineSegment),\n aNw: () => (/* reexport */ Loader),\n XrL: () => (/* reexport */ LoaderEvents),\n xwn: () => (/* reexport */ LockCameraToActorAxisStrategy),\n dNK: () => (/* reexport */ LockCameraToActorStrategy),\n ini: () => (/* reexport */ LogLevel),\n YdH: () => (/* reexport */ Logger),\n F5T: () => (/* reexport */ Material),\n y3G: () => (/* reexport */ Matrix),\n l57: () => (/* reexport */ MatrixLocations),\n xn0: () => (/* reexport */ MediaEvent),\n t2V: () => (/* reexport */ Meet),\n uxB: () => (/* reexport */ MotionComponent),\n cpd: () => (/* reexport */ MotionSystem),\n fiy: () => (/* reexport */ MoveBy),\n $XZ: () => (/* reexport */ MoveTo),\n UG6: () => (/* reexport */ NativePointerButton),\n uqK: () => (/* reexport */ NativeSoundEvent),\n STE: () => (/* reexport */ NativeSoundProcessedEvent),\n Hq9: () => (/* reexport */ None),\n y$z: () => (/* reexport */ Observable),\n mAD: () => (/* reexport */ OffscreenSystem),\n sOq: () => (/* reexport */ Pair),\n hUw: () => (/* reexport */ ParallaxComponent),\n _0G: () => (/* reexport */ ParallelActions),\n Sqs: () => (/* reexport */ ParseGif),\n hpZ: () => (/* reexport */ Particle),\n Vol: () => (/* reexport */ ParticleEmitter),\n vYX: () => (/* reexport */ ParticleTransform),\n wIZ: () => (/* reexport */ Physics),\n cBi: () => (/* reexport */ PhysicsStats),\n c30: () => (/* reexport */ PhysicsWorld),\n PGK: () => (/* reexport */ PointerAbstraction),\n MPV: () => (/* reexport */ PointerButton),\n RFv: () => (/* reexport */ PointerComponent),\n Ux6: () => (/* reexport */ PointerEvent),\n rxy: () => (/* reexport */ PointerEventReceiver),\n I$c: () => (/* reexport */ PointerScope),\n kfC: () => (/* reexport */ PointerSystem),\n VjY: () => (/* reexport */ PointerType),\n mgq: () => (/* reexport */ Polygon),\n YVA: () => (/* reexport */ PolygonCollider),\n Kgp: () => (/* reexport */ Pool),\n HH$: () => (/* reexport */ PostCollisionEvent),\n M_d: () => (/* reexport */ PostDebugDrawEvent),\n rgh: () => (/* reexport */ PostDrawEvent),\n Ra6: () => (/* reexport */ PostFrameEvent),\n KhR: () => (/* reexport */ PostKillEvent),\n gvQ: () => (/* reexport */ PostTransformDrawEvent),\n BS5: () => (/* reexport */ PostUpdateEvent),\n xhz: () => (/* reexport */ PreCollisionEvent),\n xOq: () => (/* reexport */ PreDebugDrawEvent),\n a9j: () => (/* reexport */ PreDrawEvent),\n bHk: () => (/* reexport */ PreFrameEvent),\n CgK: () => (/* reexport */ PreKillEvent),\n A0M: () => (/* reexport */ PreLoadEvent),\n cEd: () => (/* reexport */ PreTransformDrawEvent),\n cuY: () => (/* reexport */ PreUpdateEvent),\n kvE: () => (/* reexport */ Projection),\n SBu: () => (/* reexport */ QuadIndexBuffer),\n PsT: () => (/* reexport */ QuadTree),\n AE_: () => (/* reexport */ Query),\n ctO: () => (/* reexport */ QueryManager),\n OLH: () => (/* reexport */ RadiusAroundActorStrategy),\n kky: () => (/* reexport */ Random),\n nSF: () => (/* reexport */ Raster),\n zHn: () => (/* reexport */ Ray),\n zwx: () => (/* reexport */ RealisticSolver),\n AeJ: () => (/* reexport */ Rectangle),\n hLz: () => (/* reexport */ RemovedComponent),\n wA: () => (/* reexport */ Repeat),\n jhr: () => (/* reexport */ RepeatForever),\n GVs: () => (/* reexport */ Resolution),\n _zO: () => (/* reexport */ Resource),\n LXZ: () => (/* reexport */ ResourceEvents),\n w6$: () => (/* reexport */ RotateBy),\n mhV: () => (/* reexport */ RotateTo),\n MOD: () => (/* reexport */ RotationType),\n kwd: () => (/* reexport */ ScaleBy),\n Lmr: () => (/* reexport */ ScaleTo),\n xsS: () => (/* reexport */ Scene),\n K5l: () => (/* reexport */ SceneEvents),\n lLr: () => (/* reexport */ Screen),\n Z$r: () => (/* reexport */ ScreenAppender),\n IXb: () => (/* reexport */ ScreenElement),\n Xsu: () => (/* reexport */ ScreenEvents),\n SGH: () => (/* reexport */ ScreenShader),\n SMj: () => (/* reexport */ ScrollPreventionMode),\n L34: () => (/* reexport */ Semaphore),\n exe: () => (/* reexport */ Shader),\n bnF: () => (/* reexport */ Shape),\n MFA: () => (/* reexport */ Side),\n kPj: () => (/* reexport */ SolverStrategy),\n $uU: () => (/* reexport */ Sound),\n Sap: () => (/* reexport */ SoundEvents),\n jyi: () => (/* reexport */ Sprite),\n E03: () => (/* reexport */ SpriteFont),\n V6q: () => (/* reexport */ SpriteSheet),\n rg2: () => (/* reexport */ StandardClock),\n DVW: () => (/* reexport */ StateMachine),\n nVo: () => (/* reexport */ StrategyContainer),\n F6N: () => (/* reexport */ Stream),\n xP7: () => (/* reexport */ System),\n Odq: () => (/* reexport */ SystemManager),\n uY9: () => (/* reexport */ SystemPriority),\n Zif: () => (/* reexport */ SystemType),\n c_d: () => (/* reexport */ TagQuery),\n MJk: () => (/* reexport */ TestClock),\n xvT: () => (/* reexport */ Text),\n PHM: () => (/* reexport */ TextAlign),\n dpR: () => (/* reexport */ TextureLoader),\n n9L: () => (/* reexport */ Tile),\n KwO: () => (/* reexport */ TileMap),\n SxM: () => (/* reexport */ TileMapEvents),\n B7y: () => (/* reexport */ Timer),\n x7r: () => (/* reexport */ Toaster),\n wx7: () => (/* reexport */ transform_Transform),\n Uvn: () => (/* reexport */ TransformComponent),\n uTP: () => (/* reexport */ Transition),\n OFT: () => (/* reexport */ TreeNode),\n xzN: () => (/* reexport */ Trigger),\n CcZ: () => (/* reexport */ TriggerEvents),\n M5Z: () => (/* reexport */ TwoPI),\n ZrN: () => (/* reexport */ Util_Index_namespaceObject),\n OWs: () => (/* reexport */ Vector),\n dF9: () => (/* reexport */ VectorView),\n oZy: () => (/* reexport */ VertexBuffer),\n rD2: () => (/* reexport */ VertexLayout),\n KmN: () => (/* reexport */ VerticalFirst),\n VHo: () => (/* reexport */ VisibleEvent),\n ohE: () => (/* reexport */ WebAudio),\n R$E: () => (/* reexport */ WebAudioInstance),\n xQN: () => (/* reexport */ WheelDeltaMode),\n AdJ: () => (/* reexport */ WheelEvent),\n q3I: () => (/* reexport */ World),\n Pab: () => (/* reexport */ canonicalizeAngle),\n uZ5: () => (/* reexport */ clamp),\n TAE: () => (/* reexport */ coroutine),\n McK: () => (/* reexport */ createId),\n F9c: () => (/* reexport */ frac),\n k0b: () => (/* reexport */ hasGraphicsTick),\n hnT: () => (/* reexport */ hasOnInitialize),\n RSJ: () => (/* reexport */ hasOnPostUpdate),\n Mku: () => (/* reexport */ hasOnPreUpdate),\n h90: () => (/* reexport */ hasPostDraw),\n rms: () => (/* reexport */ hasPreDraw),\n ErP: () => (/* reexport */ has_initialize),\n aVg: () => (/* reexport */ has_postupdate),\n lPc: () => (/* reexport */ has_preupdate),\n Z8E: () => (/* reexport */ isAddedComponent),\n k15: () => (/* reexport */ isComponentCtor),\n YsU: () => (/* reexport */ isLoaderConstructor),\n lNv: () => (/* reexport */ isRemovedComponent),\n Xyg: () => (/* reexport */ isSceneConstructor),\n cu9: () => (/* reexport */ isScreenElement),\n p88: () => (/* reexport */ isSystemConstructor),\n MZQ: () => (/* reexport */ maxMessages),\n FUM: () => (/* reexport */ obsolete),\n BxR: () => (/* reexport */ pixelSnapEpsilon),\n vdf: () => (/* reexport */ randomInRange),\n iaL: () => (/* reexport */ randomIntInRange),\n w6H: () => (/* reexport */ range),\n Q4c: () => (/* reexport */ resetObsoleteCounter),\n Xxe: () => (/* reexport */ sign),\n Uxb: () => (/* reexport */ toDegrees),\n Yr5: () => (/* reexport */ toRadians),\n Bhw: () => (/* reexport */ vec),\n yOA: () => (/* reexport */ webgl_util_namespaceObject)\n});\n\n// NAMESPACE OBJECT: ./Graphics/Context/webgl-util.ts\nvar webgl_util_namespaceObject = {};\n__webpack_require__.r(webgl_util_namespaceObject);\n__webpack_require__.d(webgl_util_namespaceObject, {\n getAttributeComponentSize: () => (getAttributeComponentSize),\n getAttributePointerType: () => (getAttributePointerType),\n getGlTypeSizeBytes: () => (getGlTypeSizeBytes)\n});\n\n// NAMESPACE OBJECT: ./Events.ts\nvar Events_namespaceObject = {};\n__webpack_require__.r(Events_namespaceObject);\n__webpack_require__.d(Events_namespaceObject, {\n ActionCompleteEvent: () => (ActionCompleteEvent),\n ActionStartEvent: () => (ActionStartEvent),\n ActivateEvent: () => (ActivateEvent),\n CollisionEndEvent: () => (CollisionEndEvent),\n CollisionPostSolveEvent: () => (CollisionPostSolveEvent),\n CollisionPreSolveEvent: () => (CollisionPreSolveEvent),\n CollisionStartEvent: () => (CollisionStartEvent),\n ContactEndEvent: () => (ContactEndEvent),\n ContactStartEvent: () => (ContactStartEvent),\n DeactivateEvent: () => (DeactivateEvent),\n EnterTriggerEvent: () => (EnterTriggerEvent),\n EnterViewPortEvent: () => (EnterViewPortEvent),\n EventTypes: () => (EventTypes),\n ExitTriggerEvent: () => (ExitTriggerEvent),\n ExitViewPortEvent: () => (ExitViewPortEvent),\n GameEvent: () => (GameEvent),\n GameStartEvent: () => (GameStartEvent),\n GameStopEvent: () => (GameStopEvent),\n GamepadAxisEvent: () => (GamepadAxisEvent),\n GamepadButtonEvent: () => (GamepadButtonEvent),\n GamepadConnectEvent: () => (GamepadConnectEvent),\n GamepadDisconnectEvent: () => (GamepadDisconnectEvent),\n HiddenEvent: () => (HiddenEvent),\n InitializeEvent: () => (InitializeEvent),\n KillEvent: () => (KillEvent),\n PostCollisionEvent: () => (PostCollisionEvent),\n PostDebugDrawEvent: () => (PostDebugDrawEvent),\n PostDrawEvent: () => (PostDrawEvent),\n PostFrameEvent: () => (PostFrameEvent),\n PostKillEvent: () => (PostKillEvent),\n PostTransformDrawEvent: () => (PostTransformDrawEvent),\n PostUpdateEvent: () => (PostUpdateEvent),\n PreCollisionEvent: () => (PreCollisionEvent),\n PreDebugDrawEvent: () => (PreDebugDrawEvent),\n PreDrawEvent: () => (PreDrawEvent),\n PreFrameEvent: () => (PreFrameEvent),\n PreKillEvent: () => (PreKillEvent),\n PreTransformDrawEvent: () => (PreTransformDrawEvent),\n PreUpdateEvent: () => (PreUpdateEvent),\n VisibleEvent: () => (VisibleEvent)\n});\n\n// NAMESPACE OBJECT: ./Util/DrawUtil.ts\nvar DrawUtil_namespaceObject = {};\n__webpack_require__.r(DrawUtil_namespaceObject);\n__webpack_require__.d(DrawUtil_namespaceObject, {\n circle: () => (circle),\n line: () => (line),\n point: () => (point),\n roundRect: () => (roundRect),\n vector: () => (vector)\n});\n\n// NAMESPACE OBJECT: ./Input/Index.ts\nvar Input_Index_namespaceObject = {};\n__webpack_require__.r(Input_Index_namespaceObject);\n__webpack_require__.d(Input_Index_namespaceObject, {\n Axes: () => (Axes),\n Buttons: () => (Buttons),\n Gamepad: () => (Gamepad),\n Gamepads: () => (Gamepads),\n KeyEvent: () => (KeyEvent),\n Keyboard: () => (Keyboard),\n Keys: () => (Keys),\n NativePointerButton: () => (NativePointerButton),\n PointerButton: () => (PointerButton),\n PointerComponent: () => (PointerComponent),\n PointerEvent: () => (PointerEvent),\n PointerEventReceiver: () => (PointerEventReceiver),\n PointerScope: () => (PointerScope),\n PointerSystem: () => (PointerSystem),\n PointerType: () => (PointerType),\n WheelDeltaMode: () => (WheelDeltaMode),\n WheelEvent: () => (WheelEvent)\n});\n\n// NAMESPACE OBJECT: ./Util/Index.ts\nvar Util_Index_namespaceObject = {};\n__webpack_require__.r(Util_Index_namespaceObject);\n__webpack_require__.d(Util_Index_namespaceObject, {\n ConsoleAppender: () => (ConsoleAppender),\n DrawUtil: () => (DrawUtil_namespaceObject),\n EasingFunctions: () => (EasingFunctions),\n LogLevel: () => (LogLevel),\n Logger: () => (Logger),\n Observable: () => (Observable),\n ScreenAppender: () => (ScreenAppender),\n addItemToArray: () => (addItemToArray),\n contains: () => (contains),\n delay: () => (delay),\n fail: () => (fail),\n getPosition: () => (getPosition),\n omit: () => (omit),\n removeItemFromArray: () => (removeItemFromArray)\n});\n\n// EXTERNAL MODULE: ../../node_modules/core-js/es/array/sort.js\nvar sort = __webpack_require__(1324);\n// EXTERNAL MODULE: ../../node_modules/core-js/es/object/keys.js\nvar keys = __webpack_require__(3571);\n;// CONCATENATED MODULE: ./Polyfill.ts\n\n\n/**\n * Polyfill adding function\n */\nfunction polyfill() {\n /* istanbul ignore next */\n if (typeof window === 'undefined') {\n window = {\n audioContext: function () {\n return;\n }\n };\n }\n /* istanbul ignore next */\n if (typeof window !== 'undefined' && !window.requestAnimationFrame) {\n window.requestAnimationFrame =\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n function (callback) {\n window.setInterval(callback, 1000 / 60);\n };\n }\n /* istanbul ignore next */\n if (typeof window !== 'undefined' && !window.cancelAnimationFrame) {\n window.cancelAnimationFrame =\n window.webkitCancelAnimationFrame ||\n window.mozCancelAnimationFrame ||\n function () {\n return;\n };\n }\n /* istanbul ignore next */\n if (typeof window !== 'undefined' && !window.AudioContext) {\n if (window.webkitAudioContext) {\n const ctx = window.webkitAudioContext;\n const replaceMe = ctx.prototype.decodeAudioData;\n window.webkitAudioContext.prototype.decodeAudioData = function (arrayBuffer) {\n return new Promise((resolve, reject) => {\n replaceMe.call(this, arrayBuffer, resolve, reject);\n });\n };\n }\n window.AudioContext =\n window.AudioContext ||\n window.webkitAudioContext ||\n window.mozAudioContext ||\n window.msAudioContext ||\n window.oAudioContext;\n }\n /* istanbul ignore next */\n if (typeof window !== 'undefined' && !window.devicePixelRatio) {\n window.devicePixelRatio = window.devicePixelRatio || 1;\n }\n}\n\n;// CONCATENATED MODULE: ./Flags.ts\n/**\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\n * after which they are frozen and are read-only.\n *\n * Flags are used to enable experimental or preview features in Excalibur.\n */\nclass Flags {\n /**\n * Force excalibur to load the Canvas 2D graphics context fallback\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\n */\n static useCanvasGraphicsContext() {\n Flags.enable('use-canvas-context');\n }\n /**\n * Freeze all flag modifications making them readonly\n */\n static freeze() {\n Flags._FROZEN = true;\n }\n /**\n * Resets internal flag state, not meant to be called by users. Only used for testing.\n *\n * Calling this in your game is UNSUPPORTED\n * @internal\n */\n static _reset() {\n Flags._FROZEN = false;\n Flags._FLAGS = {};\n }\n /**\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\n * @param flagName\n */\n static enable(flagName) {\n if (this._FROZEN) {\n throw Error('Feature flags can only be enabled before Engine constructor time');\n }\n Flags._FLAGS[flagName] = true;\n }\n /**\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\n * @param flagName\n */\n static disable(flagName) {\n if (this._FROZEN) {\n throw Error('Feature flags can only be disabled before Engine constructor time');\n }\n Flags._FLAGS[flagName] = false;\n }\n /**\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\n * @param flagName\n */\n static isEnabled(flagName) {\n return !!Flags._FLAGS[flagName];\n }\n /**\n * Show a list of currently known flags\n */\n static show() {\n return Object.keys(Flags._FLAGS);\n }\n}\nFlags._FROZEN = false;\nFlags._FLAGS = {};\n\n;// CONCATENATED MODULE: ./Id.ts\n/**\n * Create a branded ID type from a number\n */\nfunction createId(type, value) {\n return { type, value };\n}\n;\n\n;// CONCATENATED MODULE: ./Util/Future.ts\n/**\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\n */\nclass Future {\n constructor() {\n this._isCompleted = false;\n this.promise = new Promise((resolve, reject) => {\n this._resolver = resolve;\n this._rejecter = reject;\n });\n }\n get isCompleted() {\n return this._isCompleted;\n }\n resolve(value) {\n if (this._isCompleted) {\n return;\n }\n this._isCompleted = true;\n this._resolver(value);\n }\n reject(error) {\n if (this._isCompleted) {\n return;\n }\n this._isCompleted = true;\n this._rejecter(error);\n }\n}\n\n;// CONCATENATED MODULE: ./EventEmitter.ts\n/**\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\n */\nclass EventEmitter {\n constructor() {\n this._paused = false;\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes = [];\n }\n clear() {\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes.length = 0;\n }\n on(eventName, handler) {\n var _a;\n this._listeners[eventName] = (_a = this._listeners[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listeners[eventName].push(handler);\n return {\n close: () => this.off(eventName, handler)\n };\n }\n once(eventName, handler) {\n var _a;\n this._listenersOnce[eventName] = (_a = this._listenersOnce[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listenersOnce[eventName].push(handler);\n return {\n close: () => this.off(eventName, handler)\n };\n }\n off(eventName, handler) {\n var _a, _b;\n if (handler) {\n const newListeners = (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.filter(h => h !== handler);\n this._listeners[eventName] = newListeners;\n const newOnceListeners = (_b = this._listenersOnce[eventName]) === null || _b === void 0 ? void 0 : _b.filter(h => h !== handler);\n this._listenersOnce[eventName] = newOnceListeners;\n }\n else {\n delete this._listeners[eventName];\n }\n }\n emit(eventName, event) {\n var _a;\n if (this._paused) {\n return;\n }\n (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.forEach((fn) => fn(event));\n const onces = this._listenersOnce[eventName];\n this._listenersOnce[eventName] = [];\n if (onces) {\n onces.forEach((fn) => fn(event));\n }\n this._pipes.forEach((pipe) => {\n pipe.emit(eventName, event);\n });\n }\n pipe(emitter) {\n if (this === emitter) {\n throw Error('Cannot pipe to self');\n }\n this._pipes.push(emitter);\n return {\n close: () => {\n const i = this._pipes.indexOf(emitter);\n if (i > -1) {\n this._pipes.splice(i, 1);\n }\n }\n };\n }\n unpipe(emitter) {\n const i = this._pipes.indexOf(emitter);\n if (i > -1) {\n this._pipes.splice(i, 1);\n }\n }\n pause() {\n this._paused = true;\n }\n unpause() {\n this._paused = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerScope.ts\n/**\n * Determines the scope of handling mouse/touch events.\n */\nvar PointerScope;\n(function (PointerScope) {\n /**\n * Handle events on the `canvas` element only. Events originating outside the\n * `canvas` will not be handled.\n */\n PointerScope[\"Canvas\"] = \"Canvas\";\n /**\n * Handles events on the entire document. All events will be handled by Excalibur.\n */\n PointerScope[\"Document\"] = \"Document\";\n})(PointerScope || (PointerScope = {}));\n\n;// CONCATENATED MODULE: ./Math/Random.ts\n/**\n * @module\n * Pseudo-Random Utility\n *\n * A pseudo-random utility to add seeded random support for help in\n * generating things like terrain or reproducible randomness. Uses the\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\n */\n/**\n * 32-bit mask\n */\nconst BITMASK32 = 0xffffffff;\n/**\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\n * of numbers each time it is called.\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\n *\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\n */\nclass Random {\n /**\n * If no seed is specified, the Date.now() is used\n */\n constructor(seed) {\n this.seed = seed;\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\n this._lowerMask = 0x7fffffff; // 31 bits same as _r\n this._upperMask = 0x80000000; // 34 high bits\n // Word size, 64 bits\n this._w = 32;\n // Degree of recurrence\n this._n = 624;\n // Middle word, an offset used in the recurrence defining the series x, 1<=m>> 0;\n for (let i = 1; i < this._n; i++) {\n const s = this._mt[i - 1] ^ (this._mt[i - 1] >>> (this._w - 2));\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\n this._mt[i] = (((this._f * ((s & 0xffff0000) >>> 16)) << 16) + this._f * (s & 0xffff) + i) >>> 0;\n }\n this._index = this._n;\n }\n /**\n * Apply the twist\n */\n _twist() {\n const mag01 = [0x0, this._a];\n let y = 0, i = 0;\n for (; i < this._n - this._m; i++) {\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\n this._mt[i] = this._mt[i + this._m] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\n }\n for (; i < this._n - 1; i++) {\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\n }\n y = (this._mt[this._n - 1] & this._upperMask) | (this._mt[0] & this._lowerMask);\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\n this._index = 0;\n }\n /**\n * Return next 32 bit integer number in sequence\n */\n nextInt() {\n if (this._index >= this._n) {\n this._twist();\n }\n let y = this._mt[this._index++];\n y ^= y >>> this._u;\n y ^= (y << this._s) & this._b;\n y ^= (y << this._t) & this._c;\n y ^= y >>> this._l;\n return y >>> 0;\n }\n /**\n * Return a random floating point number between [0, 1)\n */\n next() {\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\n }\n /**\n * Return a random floating point in range [min, max) min is included, max is not included\n */\n floating(min, max) {\n return (max - min) * this.next() + min;\n }\n /**\n * Return a random integer in range [min, max] min is included, max is included.\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\n */\n integer(min, max) {\n return Math.floor((max - min + 1) * this.next() + min);\n }\n /**\n * Returns true or false randomly with 50/50 odds by default.\n * By default the likelihood of returning a true is .5 (50%).\n * @param likelihood takes values between [0, 1]\n */\n bool(likelihood = 0.5) {\n return this.next() <= likelihood;\n }\n /**\n * Returns one element from an array at random\n */\n pickOne(array) {\n return array[this.integer(0, array.length - 1)];\n }\n /**\n * Returns a new array random picking elements from the original\n * @param array Original array to pick from\n * @param numPicks can be any positive number\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\n * just that it is possible)\n */\n pickSet(array, numPicks, allowDuplicates = false) {\n if (allowDuplicates) {\n return this._pickSetWithDuplicates(array, numPicks);\n }\n else {\n return this._pickSetWithoutDuplicates(array, numPicks);\n }\n }\n /**\n * Returns a new array randomly picking elements in the original (not reused)\n * @param array Array to pick elements out of\n * @param numPicks must be less than or equal to the number of elements in the array.\n */\n _pickSetWithoutDuplicates(array, numPicks) {\n if (numPicks > array.length || numPicks < 0) {\n throw new Error('Invalid number of elements to pick, must pick a value 0 < n <= length');\n }\n if (numPicks === array.length) {\n return array;\n }\n const result = new Array(numPicks);\n let currentPick = 0;\n const tempArray = array.slice(0);\n while (currentPick < numPicks) {\n const index = this.integer(0, tempArray.length - 1);\n result[currentPick++] = tempArray[index];\n tempArray.splice(index, 1);\n }\n return result;\n }\n /**\n * Returns a new array random picking elements from the original allowing duplicates\n * @param array Array to pick elements out of\n * @param numPicks can be any positive number\n */\n _pickSetWithDuplicates(array, numPicks) {\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\n if (numPicks < 0) {\n throw new Error('Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT');\n }\n const result = new Array(numPicks);\n for (let i = 0; i < numPicks; i++) {\n result[i] = this.pickOne(array);\n }\n return result;\n }\n /**\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\n */\n shuffle(array) {\n const tempArray = array.slice(0);\n let swap = null;\n for (let i = 0; i < tempArray.length - 2; i++) {\n const randomIndex = this.integer(i, tempArray.length - 1);\n swap = tempArray[i];\n tempArray[i] = tempArray[randomIndex];\n tempArray[randomIndex] = swap;\n }\n return tempArray;\n }\n /**\n * Generate a list of random integer numbers\n * @param length the length of the final array\n * @param min the minimum integer number to generate inclusive\n * @param max the maximum integer number to generate inclusive\n */\n range(length, min, max) {\n const result = new Array(length);\n for (let i = 0; i < length; i++) {\n result[i] = this.integer(min, max);\n }\n return result;\n }\n /**\n * Returns the result of a d4 dice roll\n */\n d4() {\n return this.integer(1, 4);\n }\n /**\n * Returns the result of a d6 dice roll\n */\n d6() {\n return this.integer(1, 6);\n }\n /**\n * Returns the result of a d8 dice roll\n */\n d8() {\n return this.integer(1, 8);\n }\n /**\n * Returns the result of a d10 dice roll\n */\n d10() {\n return this.integer(1, 10);\n }\n /**\n * Returns the result of a d12 dice roll\n */\n d12() {\n return this.integer(1, 12);\n }\n /**\n * Returns the result of a d20 dice roll\n */\n d20() {\n return this.integer(1, 20);\n }\n}\n\n;// CONCATENATED MODULE: ./Math/util.ts\n\n/**\n * Two PI constant\n */\nconst TwoPI = Math.PI * 2;\n/**\n * Returns the fractional part of a number\n * @param x\n */\nfunction frac(x) {\n if (x >= 0) {\n return x - Math.floor(x);\n }\n else {\n return x - Math.ceil(x);\n }\n}\n/**\n * Returns the sign of a number, if 0 returns 0\n */\nfunction sign(val) {\n if (val === 0) {\n return 0;\n }\n return val < 0 ? -1 : 1;\n}\n;\n/**\n * Clamps a value between a min and max inclusive\n */\nfunction clamp(val, min, max) {\n return Math.min(Math.max(min, val), max);\n}\n/**\n * Convert an angle to be the equivalent in the range [0, 2PI]\n */\nfunction canonicalizeAngle(angle) {\n let tmpAngle = angle;\n if (angle > TwoPI) {\n while (tmpAngle > TwoPI) {\n tmpAngle -= TwoPI;\n }\n }\n if (angle < 0) {\n while (tmpAngle < 0) {\n tmpAngle += TwoPI;\n }\n }\n return tmpAngle;\n}\n/**\n * Convert radians to degrees\n */\nfunction toDegrees(radians) {\n return (180 / Math.PI) * radians;\n}\n/**\n * Convert degrees to radians\n */\nfunction toRadians(degrees) {\n return (degrees / 180) * Math.PI;\n}\n/**\n * Generate a range of numbers\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\n * @param from inclusive\n * @param to inclusive\n */\nconst range = (from, to) => Array.from(new Array(to - from + 1), (_x, i) => i + from);\n/**\n * Find a random floating point number in range\n */\nfunction randomInRange(min, max, random = new Random()) {\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\n}\n/**\n * Find a random integer in a range\n */\nfunction randomIntInRange(min, max, random = new Random()) {\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\n}\n\n;// CONCATENATED MODULE: ./Math/vector.ts\n\n/**\n * A 2D vector on a plane.\n */\nclass Vector {\n /**\n * A (0, 0) vector\n */\n static get Zero() {\n return new Vector(0, 0);\n }\n /**\n * A (1, 1) vector\n */\n static get One() {\n return new Vector(1, 1);\n }\n /**\n * A (0.5, 0.5) vector\n */\n static get Half() {\n return new Vector(0.5, 0.5);\n }\n /**\n * A unit vector pointing up (0, -1)\n */\n static get Up() {\n return new Vector(0, -1);\n }\n /**\n * A unit vector pointing down (0, 1)\n */\n static get Down() {\n return new Vector(0, 1);\n }\n /**\n * A unit vector pointing left (-1, 0)\n */\n static get Left() {\n return new Vector(-1, 0);\n }\n /**\n * A unit vector pointing right (1, 0)\n */\n static get Right() {\n return new Vector(1, 0);\n }\n /**\n * Returns a vector of unit length in the direction of the specified angle in Radians.\n * @param angle The angle to generate the vector\n */\n static fromAngle(angle) {\n return new Vector(Math.cos(angle), Math.sin(angle));\n }\n /**\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\n */\n static isValid(vec) {\n if (vec === null || vec === undefined) {\n return false;\n }\n if (isNaN(vec.x) || isNaN(vec.y)) {\n return false;\n }\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) {\n return false;\n }\n return true;\n }\n /**\n * Calculates distance between two Vectors\n * @param vec1\n * @param vec2\n */\n static distance(vec1, vec2) {\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\n }\n static min(vec1, vec2) {\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\n }\n static max(vec1, vec2) {\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\n }\n /**\n * @param x X component of the Vector\n * @param y Y component of the Vector\n */\n constructor(x, y) {\n this._x = 0;\n this._y = 0;\n this._x = x;\n this._y = y;\n }\n /**\n * Get the x component of the vector\n */\n get x() {\n return this._x;\n }\n /**\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\n */\n set x(val) {\n this._x = val;\n }\n /**\n * Get the y component of the vector\n */\n get y() {\n return this._y;\n }\n /**\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\n */\n set y(val) {\n this._y = val;\n }\n /**\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\n */\n setTo(x, y) {\n this.x = x;\n this.y = y;\n }\n /**\n * Compares this point against another and tests for equality\n * @param vector The other point to compare to\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\n */\n equals(vector, tolerance = 0.001) {\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\n }\n /**\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\n * @param v The other vector. Leave blank to use origin vector.\n */\n distance(v) {\n if (!v) {\n return Math.sqrt(this.x * this.x + this.y * this.y);\n }\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n }\n squareDistance(v) {\n if (!v) {\n v = Vector.Zero;\n }\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return deltaX * deltaX + deltaY * deltaY;\n }\n /**\n * Clamps the current vector's magnitude mutating it\n * @param magnitude\n */\n clampMagnitude(magnitude) {\n const size = this.size;\n const newSize = clamp(size, 0, magnitude);\n this.size = newSize;\n return this;\n }\n /**\n * The size (magnitude) of the Vector\n */\n get size() {\n return this.distance();\n }\n /**\n * Setting the size mutates the current vector\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\n */\n set size(newLength) {\n const v = this.normalize().scale(newLength);\n this.setTo(v.x, v.y);\n }\n /**\n * Normalizes a vector to have a magnitude of 1.\n */\n normalize() {\n const d = this.distance();\n if (d > 0) {\n return new Vector(this.x / d, this.y / d);\n }\n else {\n return new Vector(0, 1);\n }\n }\n /**\n * Returns the average (midpoint) between the current point and the specified\n */\n average(vec) {\n return this.add(vec).scale(0.5);\n }\n scale(sizeOrScale, dest) {\n const result = dest || new Vector(0, 0);\n if (sizeOrScale instanceof Vector) {\n result.x = this.x * sizeOrScale.x;\n result.y = this.y * sizeOrScale.y;\n }\n else {\n result.x = this.x * sizeOrScale;\n result.y = this.y * sizeOrScale;\n }\n return result;\n }\n /**\n * Adds one vector to another\n * @param v The vector to add\n * @param dest Optionally copy the result into a provided vector\n */\n add(v, dest) {\n if (dest) {\n dest.x = this.x + v.x;\n dest.y = this.y + v.y;\n return dest;\n }\n return new Vector(this.x + v.x, this.y + v.y);\n }\n /**\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\n * @param v The vector to subtract\n */\n sub(v) {\n return new Vector(this.x - v.x, this.y - v.y);\n }\n /**\n * Adds one vector to this one modifying the original\n * @param v The vector to add\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */\n addEqual(v) {\n this.setTo(this.x + v.x, this.y + v.y);\n return this;\n }\n /**\n * Subtracts a vector from this one modifying the original\n * @param v The vector to subtract\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */\n subEqual(v) {\n this.setTo(this.x - v.x, this.y - v.y);\n return this;\n }\n /**\n * Scales this vector by a factor of size and modifies the original\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\n */\n scaleEqual(size) {\n this.setTo(this.x * size, this.y * size);\n return this;\n }\n /**\n * Performs a dot product with another vector\n * @param v The vector to dot\n */\n dot(v) {\n return this.x * v.x + this.y * v.y;\n }\n cross(v) {\n if (v instanceof Vector) {\n return this.x * v.y - this.y * v.x;\n }\n else if (typeof v === 'number') {\n return new Vector(v * this.y, -v * this.x);\n }\n }\n static cross(num, vec) {\n return new Vector(-num * vec.y, num * vec.x);\n }\n /**\n * Returns the perpendicular vector to this one\n */\n perpendicular() {\n return new Vector(this.y, -this.x);\n }\n /**\n * Returns the normal vector to this one, same as the perpendicular of length 1\n */\n normal() {\n return this.perpendicular().normalize();\n }\n /**\n * Negate the current vector\n */\n negate() {\n return this.scale(-1);\n }\n /**\n * Returns the angle of this vector.\n */\n toAngle() {\n return Math.atan2(this.y, this.x);\n }\n /**\n * Rotates the current vector around a point by a certain number of\n * degrees in radians\n */\n rotate(angle, anchor) {\n if (!anchor) {\n anchor = new Vector(0, 0);\n }\n const sinAngle = Math.sin(angle);\n const cosAngle = Math.cos(angle);\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\n return new Vector(x, y);\n }\n /**\n * Creates new vector that has the same values as the previous.\n */\n clone(dest) {\n const v = dest !== null && dest !== void 0 ? dest : new Vector(0, 0);\n v.x = this.x;\n v.y = this.y;\n return v;\n }\n /**\n * Returns a string representation of the vector.\n */\n toString(fixed) {\n if (fixed) {\n return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\n }\n return `(${this.x}, ${this.y})`;\n }\n}\n/**\n * Shorthand for creating new Vectors - returns a new Vector instance with the\n * provided X and Y components.\n * @param x X component of the Vector\n * @param y Y component of the Vector\n */\nfunction vec(x, y) {\n return new Vector(x, y);\n}\n\n;// CONCATENATED MODULE: ./Color.ts\n/**\n * Provides standard colors (e.g. [[Color.Black]])\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\n */\nclass Color {\n /**\n * Creates a new instance of Color from an r, g, b, a\n * @param r The red component of color (0-255)\n * @param g The green component of color (0-255)\n * @param b The blue component of color (0-255)\n * @param a The alpha component of color (0-1.0)\n */\n constructor(r, g, b, a) {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a != null ? a : 1;\n }\n /**\n * Creates a new instance of Color from an r, g, b, a\n * @param r The red component of color (0-255)\n * @param g The green component of color (0-255)\n * @param b The blue component of color (0-255)\n * @param a The alpha component of color (0-1.0)\n */\n static fromRGB(r, g, b, a) {\n return new Color(r, g, b, a);\n }\n /**\n * Creates a new instance of Color from a rgb string\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\n */\n static fromRGBString(string) {\n const rgbaRegEx = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\n let match = null;\n if ((match = string.match(rgbaRegEx))) {\n const r = parseInt(match[1], 10);\n const g = parseInt(match[2], 10);\n const b = parseInt(match[3], 10);\n let a = 1;\n if (match[4]) {\n a = parseFloat(match[4]);\n }\n return new Color(r, g, b, a);\n }\n else {\n throw new Error('Invalid rgb/a string: ' + string);\n }\n }\n /**\n * Creates a new instance of Color from a hex string\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\n */\n static fromHex(hex) {\n const hexRegEx = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\n let match = null;\n if ((match = hex.match(hexRegEx))) {\n const r = parseInt(match[1], 16);\n const g = parseInt(match[2], 16);\n const b = parseInt(match[3], 16);\n let a = 1;\n if (match[4]) {\n a = parseInt(match[4], 16) / 255;\n }\n return new Color(r, g, b, a);\n }\n else {\n throw new Error('Invalid hex string: ' + hex);\n }\n }\n /**\n * Creates a new instance of Color from hsla values\n * @param h Hue is represented [0-1]\n * @param s Saturation is represented [0-1]\n * @param l Luminance is represented [0-1]\n * @param a Alpha is represented [0-1]\n */\n static fromHSL(h, s, l, a = 1.0) {\n const temp = new HSLColor(h, s, l, a);\n return temp.toRGBA();\n }\n /**\n * Lightens the current color by a specified amount\n * @param factor The amount to lighten by [0-1]\n */\n lighten(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l += (1 - temp.l) * factor;\n return temp.toRGBA();\n }\n /**\n * Darkens the current color by a specified amount\n * @param factor The amount to darken by [0-1]\n */\n darken(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l -= temp.l * factor;\n return temp.toRGBA();\n }\n /**\n * Saturates the current color by a specified amount\n * @param factor The amount to saturate by [0-1]\n */\n saturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s += temp.s * factor;\n return temp.toRGBA();\n }\n /**\n * Desaturates the current color by a specified amount\n * @param factor The amount to desaturate by [0-1]\n */\n desaturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s -= temp.s * factor;\n return temp.toRGBA();\n }\n /**\n * Multiplies a color by another, results in a darker color\n * @param color The other color\n */\n multiply(color) {\n const newR = (((color.r / 255) * this.r) / 255) * 255;\n const newG = (((color.g / 255) * this.g) / 255) * 255;\n const newB = (((color.b / 255) * this.b) / 255) * 255;\n const newA = color.a * this.a;\n return new Color(newR, newG, newB, newA);\n }\n /**\n * Screens a color by another, results in a lighter color\n * @param color The other color\n */\n screen(color) {\n const color1 = color.invert();\n const color2 = color.invert();\n return color1.multiply(color2).invert();\n }\n /**\n * Inverts the current color\n */\n invert() {\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\n }\n /**\n * Averages the current color with another\n * @param color The other color\n */\n average(color) {\n const newR = (color.r + this.r) / 2;\n const newG = (color.g + this.g) / 2;\n const newB = (color.b + this.b) / 2;\n const newA = (color.a + this.a) / 2;\n return new Color(newR, newG, newB, newA);\n }\n equal(color) {\n return this.toString() === color.toString();\n }\n /**\n * Returns a CSS string representation of a color.\n * @param format Color representation, accepts: rgb, hsl, or hex\n */\n toString(format = 'rgb') {\n switch (format) {\n case 'rgb':\n return this.toRGBA();\n case 'hsl':\n return this.toHSLA();\n case 'hex':\n return this.toHex();\n default:\n throw new Error('Invalid Color format');\n }\n }\n /**\n * Returns Hex Value of a color component\n * @param c color component\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\n */\n _componentToHex(c) {\n const hex = c.toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n }\n /**\n * Return Hex representation of a color.\n */\n toHex() {\n return '#' + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\n }\n /**\n * Return RGBA representation of a color.\n */\n toRGBA() {\n const result = String(this.r.toFixed(0)) + ', ' + String(this.g.toFixed(0)) + ', ' + String(this.b.toFixed(0));\n if (this.a !== undefined || this.a !== null) {\n return 'rgba(' + result + ', ' + String(this.a) + ')';\n }\n return 'rgb(' + result + ')';\n }\n /**\n * Return HSLA representation of a color.\n */\n toHSLA() {\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\n }\n /**\n * Returns a CSS string representation of a color.\n */\n fillStyle() {\n return this.toString();\n }\n /**\n * Returns a clone of the current color.\n */\n clone() {\n return new Color(this.r, this.g, this.b, this.a);\n }\n /**\n * Black (#000000)\n */\n static get Black() {\n return Color.fromHex('#000000');\n }\n /**\n * White (#FFFFFF)\n */\n static get White() {\n return Color.fromHex('#FFFFFF');\n }\n /**\n * Gray (#808080)\n */\n static get Gray() {\n return Color.fromHex('#808080');\n }\n /**\n * Light gray (#D3D3D3)\n */\n static get LightGray() {\n return Color.fromHex('#D3D3D3');\n }\n /**\n * Dark gray (#A9A9A9)\n */\n static get DarkGray() {\n return Color.fromHex('#A9A9A9');\n }\n /**\n * Yellow (#FFFF00)\n */\n static get Yellow() {\n return Color.fromHex('#FFFF00');\n }\n /**\n * Orange (#FFA500)\n */\n static get Orange() {\n return Color.fromHex('#FFA500');\n }\n /**\n * Red (#FF0000)\n */\n static get Red() {\n return Color.fromHex('#FF0000');\n }\n /**\n * Vermilion (#FF5B31)\n */\n static get Vermilion() {\n return Color.fromHex('#FF5B31');\n }\n /**\n * Rose (#FF007F)\n */\n static get Rose() {\n return Color.fromHex('#FF007F');\n }\n /**\n * Magenta (#FF00FF)\n */\n static get Magenta() {\n return Color.fromHex('#FF00FF');\n }\n /**\n * Violet (#7F00FF)\n */\n static get Violet() {\n return Color.fromHex('#7F00FF');\n }\n /**\n * Blue (#0000FF)\n */\n static get Blue() {\n return Color.fromHex('#0000FF');\n }\n /**\n * Azure (#007FFF)\n */\n static get Azure() {\n return Color.fromHex('#007FFF');\n }\n /**\n * Cyan (#00FFFF)\n */\n static get Cyan() {\n return Color.fromHex('#00FFFF');\n }\n /**\n * Viridian (#59978F)\n */\n static get Viridian() {\n return Color.fromHex('#59978F');\n }\n /**\n * Green (#00FF00)\n */\n static get Green() {\n return Color.fromHex('#00FF00');\n }\n /**\n * Chartreuse (#7FFF00)\n */\n static get Chartreuse() {\n return Color.fromHex('#7FFF00');\n }\n /**\n * Transparent (#FFFFFF00)\n */\n static get Transparent() {\n return Color.fromHex('#FFFFFF00');\n }\n /**\n * ExcaliburBlue (#176BAA)\n */\n static get ExcaliburBlue() {\n return Color.fromHex('#176BAA');\n }\n}\n/**\n * Internal HSL Color representation\n *\n * http://en.wikipedia.org/wiki/HSL_and_HSV\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\n */\nclass HSLColor {\n constructor(h, s, l, a) {\n this.h = h;\n this.s = s;\n this.l = l;\n this.a = a;\n }\n static hue2rgb(p, q, t) {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n }\n static fromRGBA(r, g, b, a) {\n r /= 255;\n g /= 255;\n b /= 255;\n const max = Math.max(r, g, b), min = Math.min(r, g, b);\n let h, s;\n const l = (max + min) / 2;\n if (max === min) {\n h = s = 0; // achromatic\n }\n else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n return new HSLColor(h, s, l, a);\n }\n toRGBA() {\n let r, g, b;\n if (this.s === 0) {\n r = g = b = this.l; // achromatic\n }\n else {\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\n const p = 2 * this.l - q;\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\n g = HSLColor.hue2rgb(p, q, this.h);\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\n }\n return new Color(r * 255, g * 255, b * 255, this.a);\n }\n toString() {\n const h = this.h.toFixed(0), s = this.s.toFixed(0), l = this.l.toFixed(0), a = this.a.toFixed(0);\n return `hsla(${h}, ${s}, ${l}, ${a})`;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Log.ts\n/* eslint-disable no-console */\n\n\n/**\n * Logging level that Excalibur will tag\n */\nvar LogLevel;\n(function (LogLevel) {\n LogLevel[LogLevel[\"Debug\"] = 0] = \"Debug\";\n LogLevel[LogLevel[\"Info\"] = 1] = \"Info\";\n LogLevel[LogLevel[\"Warn\"] = 2] = \"Warn\";\n LogLevel[LogLevel[\"Error\"] = 3] = \"Error\";\n LogLevel[LogLevel[\"Fatal\"] = 4] = \"Fatal\";\n})(LogLevel || (LogLevel = {}));\n/**\n * Static singleton that represents the logging facility for Excalibur.\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\n * Derive from [[Appender]] to create your own logging appenders.\n */\nclass Logger {\n constructor() {\n this._appenders = [];\n /**\n * Gets or sets the default logging level. Excalibur will only log\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\n */\n this.defaultLevel = LogLevel.Info;\n this._logOnceSet = new Set();\n if (Logger._INSTANCE) {\n throw new Error('Logger is a singleton');\n }\n Logger._INSTANCE = this;\n // Default console appender\n Logger._INSTANCE.addAppender(new ConsoleAppender());\n return Logger._INSTANCE;\n }\n /**\n * Gets the current static instance of Logger\n */\n static getInstance() {\n if (Logger._INSTANCE == null) {\n Logger._INSTANCE = new Logger();\n }\n return Logger._INSTANCE;\n }\n /**\n * Adds a new [[Appender]] to the list of appenders to write to\n */\n addAppender(appender) {\n this._appenders.push(appender);\n }\n /**\n * Clears all appenders from the logger\n */\n clearAppenders() {\n this._appenders.length = 0;\n }\n /**\n * Logs a message at a given LogLevel\n * @param level The LogLevel`to log the message at\n * @param args An array of arguments to write to an appender\n */\n _log(level, args) {\n if (level == null) {\n level = this.defaultLevel;\n }\n const len = this._appenders.length;\n for (let i = 0; i < len; i++) {\n if (level >= this.defaultLevel) {\n this._appenders[i].log(level, args);\n }\n }\n }\n _logOnce(level, args) {\n const serialized = level + args.join('+');\n if (this._logOnceSet.has(serialized)) {\n return;\n }\n else {\n this._logOnceSet.add(serialized);\n this._log(level, args);\n }\n }\n /**\n * Writes a log message at the [[LogLevel.Debug]] level\n * @param args Accepts any number of arguments\n */\n debug(...args) {\n this._log(LogLevel.Debug, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it wont log\n * @param args Accepts any number of arguments\n */\n debugOnce(...args) {\n this._logOnce(LogLevel.Debug, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Info]] level\n * @param args Accepts any number of arguments\n */\n info(...args) {\n this._log(LogLevel.Info, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Info]] level, if it sees the same args again it wont log\n * @param args Accepts any number of arguments\n */\n infoOnce(...args) {\n this._logOnce(LogLevel.Info, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Warn]] level\n * @param args Accepts any number of arguments\n */\n warn(...args) {\n this._log(LogLevel.Warn, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Warn]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */\n warnOnce(...args) {\n this._logOnce(LogLevel.Warn, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Error]] level\n * @param args Accepts any number of arguments\n */\n error(...args) {\n this._log(LogLevel.Error, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Error]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */\n errorOnce(...args) {\n this._logOnce(LogLevel.Error, args);\n }\n /**\n * Writes a log message at the [[LogLevel.Fatal]] level\n * @param args Accepts any number of arguments\n */\n fatal(...args) {\n this._log(LogLevel.Fatal, args);\n }\n /**\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it won't log\n * @param args Accepts any number of arguments\n */\n fatalOnce(...args) {\n this._logOnce(LogLevel.Fatal, args);\n }\n}\nLogger._INSTANCE = null;\n/**\n * Console appender for browsers (i.e. `console.log`)\n */\nclass ConsoleAppender {\n /**\n * Logs a message at the given [[LogLevel]]\n * @param level Level to log at\n * @param args Arguments to log\n */\n log(level, args) {\n // Check for console support\n if (!console && !console.log && console.warn && console.error) {\n // todo maybe do something better than nothing\n return;\n }\n // Create a new console args array\n const consoleArgs = [];\n consoleArgs.unshift.apply(consoleArgs, args);\n consoleArgs.unshift('[' + LogLevel[level] + '] : ');\n if (level < LogLevel.Warn) {\n // Call .log for Debug/Info\n if (console.log.apply) {\n // this is required on some older browsers that don't support apply on console.log :(\n console.log.apply(console, consoleArgs);\n }\n else {\n console.log(consoleArgs.join(' '));\n }\n }\n else if (level < LogLevel.Error) {\n // Call .warn for Warn\n if (console.warn.apply) {\n console.warn.apply(console, consoleArgs);\n }\n else {\n console.warn(consoleArgs.join(' '));\n }\n }\n else {\n // Call .error for Error/Fatal\n if (console.error.apply) {\n console.error.apply(console, consoleArgs);\n }\n else {\n console.error(consoleArgs.join(' '));\n }\n }\n }\n}\n/**\n * On-screen (canvas) appender\n */\nclass ScreenAppender {\n constructor(options) {\n var _a, _b;\n this._messages = [];\n this._pos = 10;\n this._color = Color.Black;\n this._options = options;\n this.canvas = document.createElement('canvas');\n this._ctx = this.canvas.getContext('2d');\n this.canvas.style.position = 'absolute';\n this.canvas.style.zIndex = (_b = (_a = options.zIndex) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '99';\n document.body.appendChild(this.canvas);\n this._positionScreenAppenderCanvas();\n options.engine.screen.events.on('resize', () => {\n this._positionScreenAppenderCanvas();\n });\n }\n _positionScreenAppenderCanvas() {\n var _a, _b, _c, _d;\n const options = this._options;\n this.canvas.width = (_a = options.width) !== null && _a !== void 0 ? _a : options.engine.screen.resolution.width;\n this.canvas.height = (_b = options.height) !== null && _b !== void 0 ? _b : options.engine.screen.resolution.height;\n this.canvas.style.position = 'absolute';\n const pagePos = options.engine.screen.screenToPageCoordinates(vec(0, 0));\n this.canvas.style.left = pagePos.x + 'px';\n this.canvas.style.top = pagePos.y + 'px';\n this._pos = (_c = options.xPos) !== null && _c !== void 0 ? _c : this._pos;\n this._color = (_d = options.color) !== null && _d !== void 0 ? _d : this._color;\n }\n /**\n * Logs a message at the given [[LogLevel]]\n * @param level Level to log at\n * @param args Arguments to log\n */\n log(level, args) {\n const message = args.join(',');\n this._ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this._messages.unshift('[' + LogLevel[level] + '] : ' + message);\n let pos = 10;\n this._messages = this._messages.slice(0, 1000);\n for (let i = 0; i < this._messages.length; i++) {\n this._ctx.fillStyle = this._color.toRGBA();\n this._ctx.fillText(this._messages[i], this._pos, pos);\n pos += 10;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Side.ts\n\n/**\n * An enum that describes the sides of an axis aligned box for collision\n */\nvar Side;\n(function (Side) {\n Side[\"None\"] = \"None\";\n Side[\"Top\"] = \"Top\";\n Side[\"Bottom\"] = \"Bottom\";\n Side[\"Left\"] = \"Left\";\n Side[\"Right\"] = \"Right\";\n})(Side || (Side = {}));\n(function (Side) {\n /**\n * Returns the opposite side from the current\n */\n function getOpposite(side) {\n if (side === Side.Top) {\n return Side.Bottom;\n }\n if (side === Side.Bottom) {\n return Side.Top;\n }\n if (side === Side.Left) {\n return Side.Right;\n }\n if (side === Side.Right) {\n return Side.Left;\n }\n return Side.None;\n }\n Side.getOpposite = getOpposite;\n /**\n * Given a vector, return the Side most in that direction (via dot product)\n */\n function fromDirection(direction) {\n const directions = [Vector.Left, Vector.Right, Vector.Up, Vector.Down];\n const directionEnum = [Side.Left, Side.Right, Side.Top, Side.Bottom];\n let max = -Number.MAX_VALUE;\n let maxIndex = -1;\n for (let i = 0; i < directions.length; i++) {\n if (directions[i].dot(direction) > max) {\n max = directions[i].dot(direction);\n maxIndex = i;\n }\n }\n return directionEnum[maxIndex];\n }\n Side.fromDirection = fromDirection;\n})(Side || (Side = {}));\n\n;// CONCATENATED MODULE: ./Collision/BoundingBox.ts\n\n\n\n/**\n * Axis Aligned collision primitive for Excalibur.\n */\nclass BoundingBox {\n /**\n * Constructor allows passing of either an object with all coordinate components,\n * or the coordinate components passed separately.\n * @param leftOrOptions Either x coordinate of the left edge or an options object\n * containing the four coordinate components.\n * @param top y coordinate of the top edge\n * @param right x coordinate of the right edge\n * @param bottom y coordinate of the bottom edge\n */\n constructor(leftOrOptions = 0, top = 0, right = 0, bottom = 0) {\n // Cache bounding box point returns\n this._points = [];\n if (typeof leftOrOptions === 'object') {\n this.left = leftOrOptions.left;\n this.top = leftOrOptions.top;\n this.right = leftOrOptions.right;\n this.bottom = leftOrOptions.bottom;\n }\n else if (typeof leftOrOptions === 'number') {\n this.left = leftOrOptions;\n this.top = top;\n this.right = right;\n this.bottom = bottom;\n }\n }\n /**\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\n */\n clone() {\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\n }\n /**\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\n * @param intersection Intersection vector between 2 bounding boxes\n */\n static getSideFromIntersection(intersection) {\n if (!intersection) {\n return Side.None;\n }\n if (intersection) {\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\n if (intersection.x < 0) {\n return Side.Right;\n }\n return Side.Left;\n }\n else {\n if (intersection.y < 0) {\n return Side.Bottom;\n }\n return Side.Top;\n }\n }\n return Side.None;\n }\n static fromPoints(points) {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < points.length; i++) {\n if (points[i].x < minX) {\n minX = points[i].x;\n }\n if (points[i].x > maxX) {\n maxX = points[i].x;\n }\n if (points[i].y < minY) {\n minY = points[i].y;\n }\n if (points[i].y > maxY) {\n maxY = points[i].y;\n }\n }\n return new BoundingBox(minX, minY, maxX, maxY);\n }\n /**\n * Creates a bounding box from a width and height\n * @param width\n * @param height\n * @param anchor Default Vector.Half\n * @param pos Default Vector.Zero\n */\n static fromDimension(width, height, anchor = Vector.Half, pos = Vector.Zero) {\n return new BoundingBox(-width * anchor.x + pos.x, -height * anchor.y + pos.y, width - width * anchor.x + pos.x, height - height * anchor.y + pos.y);\n }\n /**\n * Returns the calculated width of the bounding box\n */\n get width() {\n return this.right - this.left;\n }\n /**\n * Returns the calculated height of the bounding box\n */\n get height() {\n return this.bottom - this.top;\n }\n /**\n * Return whether the bounding box has zero dimensions in height,width or both\n */\n hasZeroDimensions() {\n return this.width === 0 || this.height === 0;\n }\n /**\n * Returns the center of the bounding box\n */\n get center() {\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\n }\n get topLeft() {\n return new Vector(this.left, this.top);\n }\n get bottomRight() {\n return new Vector(this.right, this.bottom);\n }\n get topRight() {\n return new Vector(this.right, this.top);\n }\n get bottomLeft() {\n return new Vector(this.left, this.bottom);\n }\n translate(pos) {\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\n }\n /**\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\n */\n rotate(angle, point = Vector.Zero) {\n const points = this.getPoints().map((p) => p.rotate(angle, point));\n return BoundingBox.fromPoints(points);\n }\n /**\n * Scale a bounding box by a scale factor, optionally provide a point\n * @param scale\n * @param point\n */\n scale(scale, point = Vector.Zero) {\n const shifted = this.translate(point);\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\n }\n /**\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\n * @param matrix\n */\n transform(matrix) {\n // inlined these calculations to not use vectors would speed it up slightly\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\n // const xa = matFirstColumn.scale(this.left);\n const xa1 = matrix.data[0] * this.left;\n const xa2 = matrix.data[1] * this.left;\n // const xb = matFirstColumn.scale(this.right);\n const xb1 = matrix.data[0] * this.right;\n const xb2 = matrix.data[1] * this.right;\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\n // const ya = matSecondColumn.scale(this.top);\n const ya1 = matrix.data[2] * this.top;\n const ya2 = matrix.data[3] * this.top;\n // const yb = matSecondColumn.scale(this.bottom);\n const yb1 = matrix.data[2] * this.bottom;\n const yb2 = matrix.data[3] * this.bottom;\n const matrixPos = matrix.getPosition();\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\n return new BoundingBox({\n left, //: topLeft.x,\n top, //: topLeft.y,\n right, //: bottomRight.x,\n bottom //: bottomRight.y\n });\n }\n /**\n * Returns the perimeter of the bounding box\n */\n getPerimeter() {\n const wx = this.width;\n const wy = this.height;\n return 2 * (wx + wy);\n }\n /**\n * Returns the world space points that make up the corners of the bounding box as a polygon\n */\n getPoints() {\n if (this._left !== this.left ||\n this._right !== this.right ||\n this._top !== this.top ||\n this._bottom !== this.bottom) {\n this._points.length = 0;\n this._points.push(new Vector(this.left, this.top));\n this._points.push(new Vector(this.right, this.top));\n this._points.push(new Vector(this.right, this.bottom));\n this._points.push(new Vector(this.left, this.bottom));\n this._left = this.left;\n this._right = this.right;\n this._top = this.top;\n this._bottom = this.bottom;\n }\n return this._points;\n }\n /**\n * Determines whether a ray intersects with a bounding box\n */\n rayCast(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = +Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\n }\n rayCastTime(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = +Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) {\n return tmin;\n }\n return -1;\n }\n contains(val) {\n if (val instanceof Vector) {\n return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\n }\n else if (val instanceof BoundingBox) {\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) {\n return true;\n }\n return false;\n }\n return false;\n }\n /**\n * Combines this bounding box and another together returning a new bounding box\n * @param other The bounding box to combine\n */\n combine(other) {\n const compositeBB = new BoundingBox(Math.min(this.left, other.left), Math.min(this.top, other.top), Math.max(this.right, other.right), Math.max(this.bottom, other.bottom));\n return compositeBB;\n }\n get dimensions() {\n return new Vector(this.width, this.height);\n }\n /**\n * Returns true if the bounding boxes overlap.\n * @param other\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\n * This epsilon is useful in stable collision simulations.\n */\n overlaps(other, epsilon) {\n const e = epsilon || 0;\n if (other.hasZeroDimensions()) {\n return this.contains(other);\n }\n if (this.hasZeroDimensions()) {\n return other.contains(this);\n }\n const totalBoundingBox = this.combine(other);\n return totalBoundingBox.width + e < other.width + this.width &&\n totalBoundingBox.height + e < other.height + this.height;\n }\n /**\n * Test wether this bounding box intersects with another returning\n * the intersection vector that can be used to resolve the collision. If there\n * is no intersection null is returned.\n * @param other Other [[BoundingBox]] to test intersection with\n * @returns A Vector in the direction of the current BoundingBox, this <- other\n */\n intersect(other) {\n const totalBoundingBox = this.combine(other);\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\n if (totalBoundingBox.width < other.width + this.width &&\n totalBoundingBox.height < other.height + this.height &&\n !totalBoundingBox.dimensions.equals(other.dimensions) &&\n !totalBoundingBox.dimensions.equals(this.dimensions)) {\n // collision\n let overlapX = 0;\n // right edge is between the other's left and right edge\n /**\n * +-this-+\n * | |\n * | +-other-+\n * +----|-+ |\n * | |\n * +-------+\n * <---\n * ^ overlap\n */\n if (this.right >= other.left && this.right <= other.right) {\n overlapX = other.left - this.right;\n // right edge is past the other's right edge\n /**\n * +-other-+\n * | |\n * | +-this-+\n * +----|--+ |\n * | |\n * +------+\n * --->\n * ^ overlap\n */\n }\n else {\n overlapX = other.right - this.left;\n }\n let overlapY = 0;\n // top edge is between the other's top and bottom edge\n /**\n * +-other-+\n * | |\n * | +-this-+ | <- overlap\n * +----|--+ | |\n * | | \\ /\n * +------+ '\n */\n if (this.top <= other.bottom && this.top >= other.top) {\n overlapY = other.bottom - this.top;\n // top edge is above the other top edge\n /**\n * +-this-+ .\n * | | / \\\n * | +-other-+ | <- overlap\n * +----|-+ | |\n * | |\n * +-------+\n */\n }\n else {\n overlapY = other.top - this.bottom;\n }\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\n return new Vector(overlapX, 0);\n }\n else {\n return new Vector(0, overlapY);\n }\n // Case of total containment of one bounding box by another\n }\n else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\n let overlapX = 0;\n // this is wider than the other\n if (this.width - other.width >= 0) {\n // This right edge is closest to the others right edge\n if (this.right - other.right <= other.left - this.left) {\n overlapX = other.left - this.right;\n // This left edge is closest to the others left edge\n }\n else {\n overlapX = other.right - this.left;\n }\n // other is wider than this\n }\n else {\n // This right edge is closest to the others right edge\n if (other.right - this.right <= this.left - other.left) {\n overlapX = this.left - other.right;\n // This left edge is closest to the others left edge\n }\n else {\n overlapX = this.right - other.left;\n }\n }\n let overlapY = 0;\n // this is taller than other\n if (this.height - other.height >= 0) {\n // The bottom edge is closest to the others bottom edge\n if (this.bottom - other.bottom <= other.top - this.top) {\n overlapY = other.top - this.bottom;\n }\n else {\n overlapY = other.bottom - this.top;\n }\n // other is taller than this\n }\n else {\n // The bottom edge is closest to the others bottom edge\n if (other.bottom - this.bottom <= this.top - other.top) {\n overlapY = this.top - other.bottom;\n }\n else {\n overlapY = this.bottom - other.top;\n }\n }\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\n return new Vector(overlapX, 0);\n }\n else {\n return new Vector(0, overlapY);\n }\n }\n else {\n return null;\n }\n }\n /**\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\n * @param bb The other actor to test\n */\n intersectWithSide(bb) {\n const intersect = this.intersect(bb);\n return BoundingBox.getSideFromIntersection(intersect);\n }\n /**\n * Draw a debug bounding box\n * @param ex\n * @param color\n */\n draw(ex, color = Color.Yellow) {\n ex.debug.drawRect(this.left, this.top, this.width, this.height, { color });\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Util.ts\n\n\n/**\n * Find the screen position of an HTML element\n */\nfunction getPosition(el) {\n // do we need the scroll too? technically the offset method before did that\n const rect = el.getBoundingClientRect();\n return vec(rect.x + window.scrollX, rect.y + window.scrollY);\n}\n/**\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\n * @deprecated Will be removed in v0.26.0\n */\nfunction addItemToArray(item, array) {\n if (array.indexOf(item) === -1) {\n array.push(item);\n return true;\n }\n return false;\n}\n/**\n * Remove an item from an list\n * @deprecated Will be removed in v0.26.0\n */\nfunction removeItemFromArray(item, array) {\n let index = -1;\n if ((index = array.indexOf(item)) > -1) {\n array.splice(index, 1);\n return true;\n }\n return false;\n}\n/**\n * See if an array contains something\n */\nfunction contains(array, obj) {\n for (let i = 0; i < array.length; i++) {\n if (array[i] === obj) {\n return true;\n }\n }\n return false;\n}\n/**\n * Used for exhaustive checks at compile time\n */\nfunction fail(message) {\n throw new Error(message);\n}\n/**\n * Create a promise that resolves after a certain number of milliseconds\n *\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\n * excalibur clock which would be unaffected by stop/pause.\n * @param milliseconds\n * @param clock\n */\nfunction delay(milliseconds, clock) {\n var _a;\n const future = new Future();\n const schedule = (_a = clock === null || clock === void 0 ? void 0 : clock.schedule.bind(clock)) !== null && _a !== void 0 ? _a : setTimeout;\n schedule(() => {\n future.resolve();\n }, milliseconds);\n return future.promise;\n}\n/**\n * Remove keys from object literals\n * @param object\n * @param keys\n */\nfunction omit(object, keys) {\n const newObj = {};\n for (const key in object) {\n if (!keys.includes(key)) {\n newObj[key] = object[key];\n }\n }\n return newObj;\n}\n\n;// CONCATENATED MODULE: ./Math/matrix.ts\n\n\n\nvar MatrixLocations;\n(function (MatrixLocations) {\n MatrixLocations[MatrixLocations[\"X\"] = 12] = \"X\";\n MatrixLocations[MatrixLocations[\"Y\"] = 13] = \"Y\";\n})(MatrixLocations || (MatrixLocations = {}));\n/**\n * Excalibur Matrix helper for 4x4 matrices\n *\n * Useful for webgl 4x4 matrices\n */\nclass Matrix {\n constructor() {\n /**\n * 4x4 matrix in column major order\n *\n * | | | | |\n * | ------- | ------- | -------- | -------- |\n * | data[0] | data[4] | data[8] | data[12] |\n * | data[1] | data[5] | data[9] | data[13] |\n * | data[2] | data[6] | data[10] | data[14] |\n * | data[3] | data[7] | data[11] | data[15] |\n *\n */\n this.data = new Float32Array(16);\n this._scaleX = 1;\n this._scaleSignX = 1;\n this._scaleY = 1;\n this._scaleSignY = 1;\n }\n /**\n * Creates an orthographic (flat non-perspective) projection\n * https://en.wikipedia.org/wiki/Orthographic_projection\n * @param left\n * @param right\n * @param bottom\n * @param top\n * @param near\n * @param far\n */\n static ortho(left, right, bottom, top, near, far) {\n const mat = new Matrix();\n mat.data[0] = 2 / (right - left);\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 2 / (top - bottom);\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = -2 / (far - near);\n mat.data[11] = 0;\n mat.data[12] = -(right + left) / (right - left);\n mat.data[13] = -(top + bottom) / (top - bottom);\n mat.data[14] = -(far + near) / (far - near);\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a new Matrix with the same data as the current 4x4\n */\n clone(dest) {\n const mat = dest || new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n mat.data[6] = this.data[6];\n mat.data[7] = this.data[7];\n mat.data[8] = this.data[8];\n mat.data[9] = this.data[9];\n mat.data[10] = this.data[10];\n mat.data[11] = this.data[11];\n mat.data[12] = this.data[12];\n mat.data[13] = this.data[13];\n mat.data[14] = this.data[14];\n mat.data[15] = this.data[15];\n return mat;\n }\n /**\n * Converts the current matrix into a DOMMatrix\n *\n * This is useful when working with the browser Canvas context\n * @returns {DOMMatrix} DOMMatrix\n */\n toDOMMatrix() {\n return new DOMMatrix([...this.data]);\n }\n static fromFloat32Array(data) {\n const matrix = new Matrix();\n matrix.data = data;\n return matrix;\n }\n /**\n * Creates a new identity matrix (a matrix that when applied does nothing)\n */\n static identity() {\n const mat = new Matrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Resets the current matrix to the identity matrix, mutating it\n * @returns {Matrix} Current matrix as identity\n */\n reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a brand new translation matrix at the specified 3d point\n * @param x\n * @param y\n */\n static translation(x, y) {\n const mat = Matrix.identity();\n mat.data[12] = x;\n mat.data[13] = y;\n return mat;\n }\n /**\n * Creates a brand new scaling matrix with the specified scaling factor\n * @param sx\n * @param sy\n */\n static scale(sx, sy) {\n const mat = Matrix.identity();\n mat.data[0] = sx;\n mat.data[5] = sy;\n mat.data[10] = 1;\n mat.data[15] = 1;\n return mat;\n }\n /**\n * Creates a brand new rotation matrix with the specified angle\n * @param angleRadians\n */\n static rotation(angleRadians) {\n const mat = Matrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[4] = -Math.sin(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[5] = Math.cos(angleRadians);\n return mat;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\n result.x = resultX;\n result.y = resultY;\n return result;\n }\n else {\n const result = dest || new Matrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n const b11 = other.data[0];\n const b21 = other.data[1];\n const b31 = other.data[2];\n const b41 = other.data[3];\n const b12 = other.data[4];\n const b22 = other.data[5];\n const b32 = other.data[6];\n const b42 = other.data[7];\n const b13 = other.data[8];\n const b23 = other.data[9];\n const b33 = other.data[10];\n const b43 = other.data[11];\n const b14 = other.data[12];\n const b24 = other.data[13];\n const b34 = other.data[14];\n const b44 = other.data[15];\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n /**\n * Applies translation to the current matrix mutating it\n * @param x\n * @param y\n */\n translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n // Doesn't change z\n const z = 0;\n const w = 1;\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\n return this;\n }\n setPosition(x, y) {\n this.data[12] = x;\n this.data[13] = y;\n }\n getPosition() {\n return vec(this.data[12], this.data[13]);\n }\n /**\n * Applies rotation to the current matrix mutating it\n * @param angle in Radians\n */\n rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a31 + sine * a32;\n this.data[3] = cosine * a41 + sine * a42;\n this.data[4] = cosine * a12 - sine * a11;\n this.data[5] = cosine * a22 - sine * a21;\n this.data[6] = cosine * a32 - sine * a31;\n this.data[7] = cosine * a42 - sine * a41;\n return this;\n }\n /**\n * Applies scaling to the current matrix mutating it\n * @param x\n * @param y\n */\n scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a31 * x;\n this.data[3] = a41 * x;\n this.data[4] = a12 * y;\n this.data[5] = a22 * y;\n this.data[6] = a32 * y;\n this.data[7] = a42 * y;\n return this;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[4] = -sine * currentScale.x;\n this.data[5] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[4]).size;\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[5]).size;\n return this._scaleSignY * yscale;\n }\n /**\n * Get the scale of the matrix\n */\n getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (this._scaleX === val) {\n return;\n }\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[4] = xscale.y * val;\n this._scaleX = val;\n }\n setScaleY(val) {\n if (this._scaleY === val) {\n return;\n }\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[5] = yscale.y * val;\n this._scaleY = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n /**\n * Determinant of the upper left 2x2 matrix\n */\n getBasisDeterminant() {\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\n }\n /**\n * Return the affine inverse, optionally store it in a target matrix.\n *\n * It's recommended you call .reset() the target unless you know what you're doing\n * @param target\n */\n getAffineInverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.getBasisDeterminant();\n const inverseDet = 1 / det; // todo zero check\n const a = this.data[0];\n const b = this.data[4];\n const c = this.data[1];\n const d = this.data[5];\n const m = target || Matrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[4] = -b * inverseDet;\n m.data[5] = a * inverseDet;\n const tx = this.data[12];\n const ty = this.data[13];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\n return m;\n }\n isIdentity() {\n return (this.data[0] === 1 &&\n this.data[1] === 0 &&\n this.data[2] === 0 &&\n this.data[3] === 0 &&\n this.data[4] === 0 &&\n this.data[5] === 1 &&\n this.data[6] === 0 &&\n this.data[7] === 0 &&\n this.data[8] === 0 &&\n this.data[9] === 0 &&\n this.data[10] === 1 &&\n this.data[11] === 0 &&\n this.data[12] === 0 &&\n this.data[13] === 0 &&\n this.data[14] === 0 &&\n this.data[15] === 1);\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\n }\n}\n\n;// CONCATENATED MODULE: ./Math/affine-matrix.ts\n\n\n\nclass AffineMatrix {\n constructor() {\n /**\n * | | | |\n * | ------- | ------- | -------- |\n * | data[0] | data[2] | data[4] |\n * | data[1] | data[3] | data[5] |\n * | 0 | 0 | 1 |\n */\n this.data = new Float64Array(6);\n this._scale = new Float64Array([1, 1]);\n this._scaleSignX = 1;\n this._scaleSignY = 1;\n }\n /**\n * Converts the current matrix into a DOMMatrix\n *\n * This is useful when working with the browser Canvas context\n * @returns {DOMMatrix} DOMMatrix\n */\n toDOMMatrix() {\n return new DOMMatrix([...this.data]);\n }\n static identity() {\n const mat = new AffineMatrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\n * Creates a brand new translation matrix at the specified 3d point\n * @param x\n * @param y\n */\n static translation(x, y) {\n const mat = AffineMatrix.identity();\n mat.data[4] = x;\n mat.data[5] = y;\n return mat;\n }\n /**\n * Creates a brand new scaling matrix with the specified scaling factor\n * @param sx\n * @param sy\n */\n static scale(sx, sy) {\n const mat = AffineMatrix.identity();\n mat.data[0] = sx;\n mat.data[3] = sy;\n mat._scale[0] = sx;\n mat._scale[1] = sy;\n return mat;\n }\n /**\n * Creates a brand new rotation matrix with the specified angle\n * @param angleRadians\n */\n static rotation(angleRadians) {\n const mat = AffineMatrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[2] = -Math.sin(angleRadians);\n mat.data[3] = Math.cos(angleRadians);\n return mat;\n }\n setPosition(x, y) {\n this.data[4] = x;\n this.data[5] = y;\n }\n getPosition() {\n return vec(this.data[4], this.data[5]);\n }\n /**\n * Applies rotation to the current matrix mutating it\n * @param angle in Radians\n */\n rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a12 - sine * a11;\n this.data[3] = cosine * a22 - sine * a21;\n return this;\n }\n /**\n * Applies translation to the current matrix mutating it\n * @param x\n * @param y\n */\n translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n // Doesn't change z\n this.data[4] = a11 * x + a12 * y + a13;\n this.data[5] = a21 * x + a22 * y + a23;\n return this;\n }\n /**\n * Applies scaling to the current matrix mutating it\n * @param x\n * @param y\n */\n scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a12 * y;\n this.data[3] = a22 * y;\n this._scale[0] = x;\n this._scale[1] = y;\n return this;\n }\n determinant() {\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\n }\n /**\n * Return the affine inverse, optionally store it in a target matrix.\n *\n * It's recommended you call .reset() the target unless you know what you're doing\n * @param target\n */\n inverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.determinant();\n const inverseDet = 1 / det; // TODO zero check\n const a = this.data[0];\n const b = this.data[2];\n const c = this.data[1];\n const d = this.data[3];\n const m = target || AffineMatrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[2] = -b * inverseDet;\n m.data[3] = a * inverseDet;\n const tx = this.data[4];\n const ty = this.data[5];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\n return m;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\n result.x = resultX;\n result.y = resultY;\n return result;\n }\n else {\n const result = dest || new AffineMatrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n const b11 = other.data[0];\n const b21 = other.data[1];\n // const b31 = 0;\n const b12 = other.data[2];\n const b22 = other.data[3];\n // const b32 = 0;\n const b13 = other.data[4];\n const b23 = other.data[5];\n // const b33 = 1;\n result.data[0] = a11 * b11 + a12 * b21; // + a13 * b31; // zero\n result.data[1] = a21 * b11 + a22 * b21; // + a23 * b31; // zero\n result.data[2] = a11 * b12 + a12 * b22; // + a13 * b32; // zero\n result.data[3] = a21 * b12 + a22 * b22; // + a23 * b32; // zero\n result.data[4] = a11 * b13 + a12 * b23 + a13; // * b33; // one\n result.data[5] = a21 * b13 + a22 * b23 + a23; // * b33; // one\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n to4x4() {\n const mat = new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = this.data[2];\n mat.data[5] = this.data[3];\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = this.data[4];\n mat.data[13] = this.data[5];\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[2] = -sine * currentScale.x;\n this.data[3] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[2]).distance();\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[3]).distance();\n return this._scaleSignY * yscale;\n }\n /**\n * Get the scale of the matrix\n */\n getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (val === this._scale[0]) {\n return;\n }\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[2] = xscale.y * val;\n this._scale[0] = val;\n }\n setScaleY(val) {\n if (val === this._scale[1]) {\n return;\n }\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[3] = yscale.y * val;\n this._scale[1] = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n isIdentity() {\n return (this.data[0] === 1 &&\n this.data[1] === 0 &&\n this.data[2] === 0 &&\n this.data[3] === 1 &&\n this.data[4] === 0 &&\n this.data[5] === 0);\n }\n /**\n * Resets the current matrix to the identity matrix, mutating it\n * @returns {AffineMatrix} Current matrix as identity\n */\n reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\n * Creates a new Matrix with the same data as the current 4x4\n */\n clone(dest) {\n const mat = dest || new AffineMatrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n return mat;\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/transform-stack.ts\n\nclass TransformStack {\n constructor() {\n this._transforms = [];\n this._currentTransform = AffineMatrix.identity();\n }\n save() {\n this._transforms.push(this._currentTransform);\n this._currentTransform = this._currentTransform.clone();\n }\n restore() {\n this._currentTransform = this._transforms.pop();\n }\n translate(x, y) {\n return this._currentTransform.translate(x, y);\n }\n rotate(angle) {\n return this._currentTransform.rotate(angle);\n }\n scale(x, y) {\n return this._currentTransform.scale(x, y);\n }\n set current(matrix) {\n this._currentTransform = matrix;\n }\n get current() {\n return this._currentTransform;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/state-stack.ts\n\nclass StateStack {\n constructor() {\n this._states = [];\n this._currentState = this._getDefaultState();\n }\n _getDefaultState() {\n return {\n opacity: 1,\n z: 0,\n tint: Color.White,\n material: null\n };\n }\n _cloneState() {\n return {\n opacity: this._currentState.opacity,\n z: this._currentState.z,\n tint: this._currentState.tint.clone(),\n material: this._currentState.material // TODO is this going to cause problems when cloning\n };\n }\n save() {\n this._states.push(this._currentState);\n this._currentState = this._cloneState();\n }\n restore() {\n this._currentState = this._states.pop();\n }\n get current() {\n return this._currentState;\n }\n set current(val) {\n this._currentState = val;\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Resource.ts\n\n\nconst ResourceEvents = {\n Complete: 'complete',\n Load: 'load',\n LoadStart: 'loadstart',\n Progress: 'progress',\n Error: 'error'\n};\n/**\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\n */\nclass Resource {\n /**\n * @param path Path to the remote resource\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\n * @param bustCache Whether or not to cache-bust requests\n */\n constructor(path, responseType, bustCache = false) {\n this.path = path;\n this.responseType = responseType;\n this.bustCache = bustCache;\n this.data = null;\n this.logger = Logger.getInstance();\n this.events = new EventEmitter();\n }\n /**\n * Returns true if the Resource is completely loaded and is ready\n * to be drawn.\n */\n isLoaded() {\n return this.data !== null;\n }\n _cacheBust(uri) {\n const query = /\\?\\w*=\\w*/;\n if (query.test(uri)) {\n uri += '&__=' + Date.now();\n }\n else {\n uri += '?__=' + Date.now();\n }\n return uri;\n }\n /**\n * Begin loading the resource and returns a promise to be resolved on completion\n */\n load() {\n return new Promise((resolve, reject) => {\n // Exit early if we already have data\n if (this.data !== null) {\n this.logger.debug('Already have data for resource', this.path);\n this.events.emit('complete', this.data);\n resolve(this.data);\n return;\n }\n const request = new XMLHttpRequest();\n request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true);\n request.responseType = this.responseType;\n request.addEventListener('loadstart', (e) => this.events.emit('loadstart', e));\n request.addEventListener('progress', (e) => this.events.emit('progress', e));\n request.addEventListener('error', (e) => this.events.emit('error', e));\n request.addEventListener('load', (e) => this.events.emit('load', e));\n request.addEventListener('load', () => {\n // XHR on file:// success status is 0, such as with PhantomJS\n if (request.status !== 0 && request.status !== 200) {\n this.logger.error('Failed to load resource ', this.path, ' server responded with error code', request.status);\n this.events.emit('error', request.response);\n reject(new Error(request.statusText));\n return;\n }\n this.data = request.response;\n this.events.emit('complete', this.data);\n this.logger.debug('Completed loading resource', this.path);\n resolve(this.data);\n });\n request.send();\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Watch.ts\n/**\n * Watch an object with a proxy, only fires if property value is different\n */\nfunction watch(type, change) {\n if (!type) {\n return type;\n }\n if (type.__isProxy === undefined) {\n // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value) => {\n // The default behavior to store the value\n if (obj[prop] !== value) {\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === 'string') {\n if (prop[0] !== '_') {\n change(obj);\n }\n }\n }\n // Indicate success\n return true;\n },\n get: (obj, prop) => {\n if (prop !== '__isProxy') {\n return obj[prop];\n }\n return true;\n }\n });\n }\n return type;\n}\nconst createHandler = (path = [], change, typeType) => ({\n get: (target, key) => {\n if (key === '__isProxy') {\n return true;\n }\n if (typeof target[key] === 'object' && target[key] != null) {\n return new Proxy(target[key], createHandler([...path, key], change, typeType));\n }\n return target[key];\n },\n set: (target, key, value) => {\n if (typeof key === 'string') {\n if (key[0] !== '_') {\n change(typeType);\n }\n }\n target[key] = value;\n return true;\n }\n});\n/**\n *\n */\nfunction watchDeep(type, change) {\n if (!type) {\n return type;\n }\n if (type.__isProxy === undefined) {\n // expando hack to mark a proxy\n return new Proxy(type, createHandler([], change, type));\n }\n return type;\n}\n/**\n * Watch an object with a proxy, fires change on any property value change\n */\nfunction watchAny(type, change) {\n if (!type) {\n return type;\n }\n if (type.__isProxy === undefined) {\n // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value) => {\n // The default behavior to store the value\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === 'string') {\n if (prop[0] !== '_') {\n change(obj);\n }\n }\n // Indicate success\n return true;\n },\n get: (obj, prop) => {\n if (prop !== '__isProxy') {\n return obj[prop];\n }\n return true;\n }\n });\n }\n return type;\n}\n\n;// CONCATENATED MODULE: ./Graphics/Graphic.ts\n\n\n\n\n/**\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\n * [[Graphic]] abstract class.\n *\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\n */\nclass Graphic {\n isStale() {\n return this._transformStale;\n }\n /**\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\n */\n get flipHorizontal() {\n return this._flipHorizontal;\n }\n set flipHorizontal(value) {\n this._flipHorizontal = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\n */\n get flipVertical() {\n return this._flipVertical;\n }\n set flipVertical(value) {\n this._flipVertical = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the rotation of the graphic\n */\n get rotation() {\n return this._rotation;\n }\n set rotation(value) {\n this._rotation = value;\n this._transformStale = true;\n }\n /**\n * Gets or sets the scale of the graphic, this affects the width and\n */\n get scale() {\n return this._scale;\n }\n set scale(value) {\n this._scale = watch(value, () => {\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n /**\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\n */\n get origin() {\n return this._origin;\n }\n set origin(value) {\n this._origin = watch(value, () => {\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n constructor(options) {\n var _a, _b, _c, _d, _e, _f, _g;\n this.id = Graphic._ID++;\n this.transform = AffineMatrix.identity();\n this.tint = null;\n this._transformStale = true;\n /**\n * Gets or sets wether to show debug information about the graphic\n */\n this.showDebug = false;\n this._flipHorizontal = false;\n this._flipVertical = false;\n this._rotation = 0;\n /**\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\n */\n this.opacity = 1;\n this._scale = Vector.One;\n this._origin = null;\n this._width = 0;\n this._height = 0;\n if (options) {\n this.origin = (_a = options.origin) !== null && _a !== void 0 ? _a : this.origin;\n this.flipHorizontal = (_b = options.flipHorizontal) !== null && _b !== void 0 ? _b : this.flipHorizontal;\n this.flipVertical = (_c = options.flipVertical) !== null && _c !== void 0 ? _c : this.flipVertical;\n this.rotation = (_d = options.rotation) !== null && _d !== void 0 ? _d : this.rotation;\n this.opacity = (_e = options.opacity) !== null && _e !== void 0 ? _e : this.opacity;\n this.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : this.scale;\n this.tint = (_g = options.tint) !== null && _g !== void 0 ? _g : this.tint;\n }\n }\n cloneGraphicOptions() {\n return {\n width: this.width / this.scale.x,\n height: this.height / this.scale.y,\n origin: this.origin ? this.origin.clone() : null,\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n rotation: this.rotation,\n opacity: this.opacity,\n scale: this.scale ? this.scale.clone() : null,\n tint: this.tint ? this.tint.clone() : null\n };\n }\n /**\n * Gets or sets the width of the graphic (always positive)\n */\n get width() {\n return Math.abs(this._width * this.scale.x);\n }\n /**\n * Gets or sets the height of the graphic (always positive)\n */\n get height() {\n return Math.abs(this._height * this.scale.y);\n }\n set width(value) {\n this._width = value;\n this._transformStale = true;\n }\n set height(value) {\n this._height = value;\n this._transformStale = true;\n }\n /**\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\n */\n get localBounds() {\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\n }\n /**\n * Draw the whole graphic to the context including transform\n * @param ex The excalibur graphics context\n * @param x\n * @param y\n */\n draw(ex, x, y) {\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0);\n this._postDraw(ex);\n }\n /**\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\n * @param ex\n * @param x\n * @param y\n */\n _preDraw(ex, x, y) {\n ex.save();\n ex.translate(x, y);\n if (this._transformStale) {\n this.transform.reset();\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\n this._rotate(this.transform);\n this._flip(this.transform);\n this._transformStale = false;\n }\n ex.multiply(this.transform);\n // it is important to multiply alphas so graphics respect the current context\n ex.opacity = ex.opacity * this.opacity;\n if (this.tint) {\n ex.tint = this.tint;\n }\n }\n _rotate(ex) {\n var _a;\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : vec(this.width / 2, this.height / 2);\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\n ex.scale(scaleDirX, scaleDirY);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, this.height / this.scale.y);\n ex.scale(1, -1);\n }\n }\n /**\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\n * @param ex\n */\n _postDraw(ex) {\n if (this.showDebug) {\n ex.debug.drawRect(0, 0, this.width, this.height);\n }\n ex.restore();\n }\n}\nGraphic._ID = 0;\n\n;// CONCATENATED MODULE: ./Graphics/Sprite.ts\n\n\nclass Sprite extends Graphic {\n static from(image) {\n return new Sprite({\n image: image\n });\n }\n constructor(options) {\n var _a, _b;\n super(options);\n this._logger = Logger.getInstance();\n this._dirty = true;\n this.image = options.image;\n const { width, height } = options;\n this.sourceView = (_a = options.sourceView) !== null && _a !== void 0 ? _a : { x: 0, y: 0, width: width !== null && width !== void 0 ? width : 0, height: height !== null && height !== void 0 ? height : 0 };\n this.destSize = (_b = options.destSize) !== null && _b !== void 0 ? _b : { width: width !== null && width !== void 0 ? width : 0, height: height !== null && height !== void 0 ? height : 0 };\n this._updateSpriteDimensions();\n // Fire when loaded\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.image.ready.then(() => {\n this._updateSpriteDimensions();\n });\n }\n get width() {\n return Math.abs(this.destSize.width * this.scale.x);\n }\n get height() {\n return Math.abs(this.destSize.height * this.scale.y);\n }\n set width(newWidth) {\n newWidth /= Math.abs(this.scale.x);\n this.destSize.width = newWidth;\n super.width = Math.ceil(this.destSize.width);\n }\n set height(newHeight) {\n newHeight /= Math.abs(this.scale.y);\n this.destSize.height = newHeight;\n super.height = Math.ceil(this.destSize.height);\n }\n _updateSpriteDimensions() {\n var _a, _b, _c, _d, _e, _f;\n const { width: nativeWidth, height: nativeHeight } = this.image;\n // This code uses || to avoid 0's\n // If the source is not specified, use the native dimension\n this.sourceView.width = ((_a = this.sourceView) === null || _a === void 0 ? void 0 : _a.width) || nativeWidth;\n this.sourceView.height = ((_b = this.sourceView) === null || _b === void 0 ? void 0 : _b.height) || nativeHeight;\n // If the destination is not specified, use the source if specified, then native\n this.destSize.width = ((_c = this.destSize) === null || _c === void 0 ? void 0 : _c.width) || ((_d = this.sourceView) === null || _d === void 0 ? void 0 : _d.width) || nativeWidth;\n this.destSize.height = ((_e = this.destSize) === null || _e === void 0 ? void 0 : _e.height) || ((_f = this.sourceView) === null || _f === void 0 ? void 0 : _f.height) || nativeHeight;\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\n }\n _preDraw(ex, x, y) {\n if (this.image.isLoaded() && this._dirty) {\n this._dirty = false;\n this._updateSpriteDimensions();\n }\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n if (this.image.isLoaded()) {\n ex.drawImage(this.image.image, this.sourceView.x, this.sourceView.y, this.sourceView.width, this.sourceView.height, x, y, this.destSize.width, this.destSize.height);\n }\n else {\n this._logger.warnOnce(`ImageSource ${this.image.path}` +\n ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` +\n `Read https://excaliburjs.com/docs/imagesource for more information.`);\n }\n }\n clone() {\n return new Sprite({\n image: this.image,\n sourceView: { ...this.sourceView },\n destSize: { ...this.destSize },\n ...this.cloneGraphicOptions()\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Filtering.ts\n/**\n * Describes the different image filtering modes\n */\nvar ImageFiltering;\n(function (ImageFiltering) {\n /**\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\n *\n * Useful for Pixel art aesthetics.\n */\n ImageFiltering[\"Pixel\"] = \"Pixel\";\n /**\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\n */\n ImageFiltering[\"Blended\"] = \"Blended\";\n})(ImageFiltering || (ImageFiltering = {}));\n\n;// CONCATENATED MODULE: ./Graphics/Context/texture-loader.ts\n\n\n/**\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\n */\nclass TextureLoader {\n constructor(gl) {\n this._textureMap = new Map();\n this._gl = gl;\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n dispose() {\n for (const [image] of this._textureMap) {\n this.delete(image);\n }\n this._textureMap.clear();\n this._gl = null;\n }\n /**\n * Get the WebGL Texture from a source image\n * @param image\n */\n get(image) {\n return this._textureMap.get(image);\n }\n /**\n * Returns whether a source image has been loaded as a texture\n * @param image\n */\n has(image) {\n return this._textureMap.has(image);\n }\n /**\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\n * @param image Source graphic\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\n */\n load(image, filtering, forceUpdate = false) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) {\n return null;\n }\n let tex = null;\n // If reuse the texture if it's from the same source\n if (this.has(image)) {\n tex = this.get(image);\n }\n // Update existing webgl texture and return early\n if (tex) {\n if (forceUpdate) {\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n }\n return tex;\n }\n // No texture exists create a new one\n tex = gl.createTexture();\n // TODO implement texture gc with weakmap and timer\n TextureLoader.checkImageSizeSupportedAndLog(image);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n // TODO make configurable\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // NEAREST for pixel art, LINEAR for hi-res\n const filterMode = filtering !== null && filtering !== void 0 ? filtering : TextureLoader.filtering;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n this._textureMap.set(image, tex);\n return tex;\n }\n delete(image) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) {\n return null;\n }\n let tex = null;\n if (this.has(image)) {\n tex = this.get(image);\n gl.deleteTexture(tex);\n }\n }\n /**\n * Takes an image and returns if it meets size criteria for hardware\n * @param image\n * @returns if the image will be supported at runtime\n */\n static checkImageSizeSupportedAndLog(image) {\n var _a;\n const originalSrc = (_a = image.dataset.originalSrc) !== null && _a !== void 0 ? _a : 'internal canvas bitmap';\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\n TextureLoader._LOGGER.error(`The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of ` +\n `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image `\n + `for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n` +\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n return false;\n }\n else if (image.width > 4096 || image.height > 4096) {\n // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\n TextureLoader._LOGGER.warn(`The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, ` +\n `it is recommended you resize images to a maximum (4096x4096).\\n\\n` +\n `Images will likely render as black rectangles on some mobile platforms.\\n\\n` +\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n }\n return true;\n }\n}\nTextureLoader._LOGGER = Logger.getInstance();\n/**\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\n */\nTextureLoader.filtering = ImageFiltering.Blended;\nTextureLoader._MAX_TEXTURE_SIZE = 4096;\n\n;// CONCATENATED MODULE: ./Graphics/ImageSource.ts\n\n\n\n\n\n\nclass ImageSource {\n /**\n * The original size of the source image in pixels\n */\n get width() {\n return this.image.naturalWidth;\n }\n /**\n * The original height of the source image in pixels\n */\n get height() {\n return this.image.naturalHeight;\n }\n /**\n * Returns true if the Texture is completely loaded and is ready\n * to be drawn.\n */\n isLoaded() {\n if (!this._src) {\n // this boosts speed of access\n this._src = this.data.src;\n }\n return !!this._src;\n }\n get image() {\n return this.data;\n }\n /**\n * The path to the image, can also be a data url like 'data:image/'\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\n */\n constructor(path, bustCache = false, filtering) {\n this.path = path;\n this._logger = Logger.getInstance();\n /**\n * Access to the underlying html image element\n */\n this.data = new Image();\n this._readyFuture = new Future();\n /**\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\n */\n this.ready = this._readyFuture.promise;\n this._resource = new Resource(path, 'blob', bustCache);\n this.filtering = filtering;\n if (path.endsWith('.svg') || path.endsWith('.gif')) {\n this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\n }\n }\n /**\n * Create an ImageSource from and HTML tag element\n * @param image\n */\n static fromHtmlImageElement(image, options) {\n const imageSource = new ImageSource('');\n imageSource._src = 'image-element';\n imageSource.data = image;\n imageSource.data.setAttribute('data-original-src', 'image-element');\n if (options === null || options === void 0 ? void 0 : options.filtering) {\n imageSource.data.setAttribute('filtering', options === null || options === void 0 ? void 0 : options.filtering);\n }\n else {\n imageSource.data.setAttribute('filtering', ImageFiltering.Blended);\n }\n TextureLoader.checkImageSizeSupportedAndLog(image);\n imageSource._readyFuture.resolve(image);\n return imageSource;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */\n get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * Begins loading the image and returns a promise that resolves when the image is loaded\n */\n async load() {\n if (this.isLoaded()) {\n return this.data;\n }\n try {\n // Load base64 or blob if needed\n let url;\n if (!this.path.includes('data:image/')) {\n const blob = await this._resource.load();\n url = URL.createObjectURL(blob);\n }\n else {\n url = this.path;\n }\n // Decode the image\n const image = new Image();\n // Use Image.onload over Image.decode()\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\n // Otherwise chrome will throw still Image.decode() failures for large textures\n const loadedFuture = new Future();\n image.onload = () => loadedFuture.resolve();\n image.src = url;\n image.setAttribute('data-original-src', this.path);\n await loadedFuture.promise;\n // Set results\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\n // See image-renderer.ts draw()\n this.data = image;\n // emit warning if potentially too big\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\n }\n catch (error) {\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\n }\n // Do a bad thing to pass the filtering as an attribute\n this.data.setAttribute('filtering', this.filtering);\n // todo emit complete\n this._readyFuture.resolve(this.data);\n return this.data;\n }\n /**\n * Build a sprite from this ImageSource\n */\n toSprite() {\n return Sprite.from(this);\n }\n /**\n * Unload images from memory\n */\n unload() {\n this.data = new Image();\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/SpriteFont.ts\n\n\n\n\nclass SpriteFont extends Graphic {\n constructor(options) {\n super(options);\n this._text = '';\n this.alphabet = '';\n this.shadow = null;\n this.caseInsensitive = false;\n this.spacing = 0;\n this.lineHeight = undefined;\n this._logger = Logger.getInstance();\n const { alphabet, spriteSheet, caseInsensitive, spacing, shadow, lineHeight } = options;\n this.alphabet = alphabet;\n this.spriteSheet = spriteSheet;\n this.caseInsensitive = caseInsensitive !== null && caseInsensitive !== void 0 ? caseInsensitive : this.caseInsensitive;\n this.spacing = spacing !== null && spacing !== void 0 ? spacing : this.spacing;\n this.shadow = shadow !== null && shadow !== void 0 ? shadow : this.shadow;\n this.lineHeight = lineHeight !== null && lineHeight !== void 0 ? lineHeight : this.lineHeight;\n }\n _getCharacterSprites(text) {\n const results = [];\n // handle case insensitive\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\n // for each letter in text\n for (let letterIndex = 0; letterIndex < textToRender.length; letterIndex++) {\n // find the sprite index in alphabet , if there is an error pick the first\n const letter = textToRender[letterIndex];\n let spriteIndex = alphabet.indexOf(letter);\n if (spriteIndex === -1) {\n spriteIndex = 0;\n this._logger.warnOnce(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\n this._logger.warnOnce('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\n }\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\n if (letterSprite) {\n results.push(letterSprite);\n }\n else {\n this._logger.warnOnce(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\n this._logger.warnOnce('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\n }\n }\n return results;\n }\n measureText(text, maxWidth) {\n const lines = this._getLinesFromText(text, maxWidth);\n const maxWidthLine = lines.reduce((a, b) => {\n return a.length > b.length ? a : b;\n });\n const sprites = this._getCharacterSprites(maxWidthLine);\n let width = 0;\n let height = 0;\n for (const sprite of sprites) {\n width += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\n }\n _drawImage(ex, x, y, maxWidth) {\n var _a;\n let xCursor = 0;\n let yCursor = 0;\n let height = 0;\n const lines = this._getLinesFromText(this._text, maxWidth);\n for (const line of lines) {\n for (const sprite of this._getCharacterSprites(line)) {\n // draw it in the right spot and increase the cursor by sprite width\n sprite.draw(ex, x + xCursor, y + yCursor);\n xCursor += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n xCursor = 0;\n yCursor += (_a = this.lineHeight) !== null && _a !== void 0 ? _a : height;\n }\n }\n render(ex, text, _color, x, y, maxWidth) {\n // SpriteFont doesn't support _color, yet...\n this._text = text;\n const bounds = this.measureText(text, maxWidth);\n this.width = bounds.width;\n this.height = bounds.height;\n if (this.shadow) {\n ex.save();\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n ex.restore();\n }\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n }\n clone() {\n return new SpriteFont({\n alphabet: this.alphabet,\n spriteSheet: this.spriteSheet,\n spacing: this.spacing\n });\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\n return this._cachedLines;\n }\n const lines = text.split('\\n');\n if (maxWidth == null) {\n return lines;\n }\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i];\n let newLine = '';\n // Note: we subtract the spacing to counter the initial padding on the left side.\n if (this.measureText(line).width > maxWidth) {\n while (this.measureText(line).width > maxWidth) {\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/SpriteSheet.ts\n\n/**\n * Represents a collection of sprites from a source image with some organization in a grid\n */\nclass SpriteSheet {\n /**\n * Build a new sprite sheet from a list of sprites\n *\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\n * @param options\n */\n constructor(options) {\n this.sprites = [];\n const { sprites, rows, columns } = options;\n this.sprites = sprites;\n this.rows = rows !== null && rows !== void 0 ? rows : 1;\n this.columns = columns !== null && columns !== void 0 ? columns : this.sprites.length;\n }\n /**\n * Find a sprite by their x/y integer coordinates in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\n * and `getSprite(1, 0)` is the sprite one to the right.\n * @param x\n * @param y\n */\n getSprite(x, y, options) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j;\n if (x >= this.columns || x < 0) {\n throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\n }\n if (y >= this.rows || y < 0) {\n throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\n }\n const spriteIndex = x + y * this.columns;\n const sprite = this.sprites[spriteIndex];\n if (sprite) {\n if (options) {\n const spriteWithOptions = sprite.clone();\n spriteWithOptions.flipHorizontal = (_a = options.flipHorizontal) !== null && _a !== void 0 ? _a : spriteWithOptions.flipHorizontal;\n spriteWithOptions.flipVertical = (_b = options.flipVertical) !== null && _b !== void 0 ? _b : spriteWithOptions.flipVertical;\n spriteWithOptions.width = (_c = options.width) !== null && _c !== void 0 ? _c : spriteWithOptions.width;\n spriteWithOptions.height = (_d = options.height) !== null && _d !== void 0 ? _d : spriteWithOptions.height;\n spriteWithOptions.rotation = (_e = options.rotation) !== null && _e !== void 0 ? _e : spriteWithOptions.rotation;\n spriteWithOptions.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : spriteWithOptions.scale;\n spriteWithOptions.opacity = (_g = options.opacity) !== null && _g !== void 0 ? _g : spriteWithOptions.opacity;\n spriteWithOptions.tint = (_h = options.tint) !== null && _h !== void 0 ? _h : spriteWithOptions.tint;\n spriteWithOptions.origin = (_j = options.origin) !== null && _j !== void 0 ? _j : spriteWithOptions.origin;\n return spriteWithOptions;\n }\n return sprite;\n }\n throw Error(`Invalid sprite coordinates (${x}, ${y}`);\n }\n /**\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\n * @param options\n */\n static fromImageSourceWithSourceViews(options) {\n const sprites = options.sourceViews.map(sourceView => {\n return new Sprite({\n image: options.image,\n sourceView\n });\n });\n return new SpriteSheet({ sprites });\n }\n /**\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\n *\n * Example:\n * ```\n * const spriteSheet = SpriteSheet.fromImageSource({\n * image: imageSource,\n * grid: {\n * rows: 5,\n * columns: 2,\n * spriteWidth: 32, // pixels\n * spriteHeight: 32 // pixels\n * },\n * // Optionally specify spacing\n * spacing: {\n * // pixels from the top left to start the sprite parsing\n * originOffset: {\n * x: 5,\n * y: 5\n * },\n * // pixels between each sprite while parsing\n * margin: {\n * x: 1,\n * y: 1\n * }\n * }\n * })\n * ```\n * @param options\n */\n static fromImageSource(options) {\n var _a;\n const sprites = [];\n options.spacing = (_a = options.spacing) !== null && _a !== void 0 ? _a : {};\n const { image, grid: { rows, columns: cols, spriteWidth, spriteHeight }, spacing: { originOffset, margin } } = options;\n const offsetDefaults = { x: 0, y: 0, ...originOffset };\n const marginDefaults = { x: 0, y: 0, ...margin };\n for (let x = 0; x < cols; x++) {\n for (let y = 0; y < rows; y++) {\n sprites[x + y * cols] = new Sprite({\n image: image,\n sourceView: {\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\n width: spriteWidth,\n height: spriteHeight\n },\n destSize: { height: spriteHeight, width: spriteWidth }\n });\n }\n }\n return new SpriteSheet({\n sprites: sprites,\n rows: rows,\n columns: cols\n });\n }\n clone() {\n return new SpriteSheet({\n sprites: this.sprites.map(sprite => sprite.clone()),\n rows: this.rows,\n columns: this.columns\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/debug-font.png\n/* harmony default export */ const debug_font = (\"data:image/png;base64,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\");\n;// CONCATENATED MODULE: ./Graphics/Context/debug-text.ts\n\n\n\n\n/**\n * Internal debugtext helper\n */\nclass DebugText {\n constructor() {\n /**\n * base64 font\n */\n this.fontSheet = debug_font;\n this.size = 16;\n // We fire and forget, we don't care if it's loaded or not\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.load();\n }\n load() {\n this._imageSource = new ImageSource(this.fontSheet);\n return this._imageSource.load().then(() => {\n this._spriteSheet = SpriteSheet.fromImageSource({\n image: this._imageSource,\n grid: {\n rows: 4,\n columns: 16,\n spriteWidth: 16,\n spriteHeight: 16\n }\n });\n this._spriteFont = new SpriteFont({\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!\\'&.\"?-()+# ',\n caseInsensitive: true,\n spriteSheet: this._spriteSheet,\n spacing: -6\n });\n });\n }\n /**\n * Writes debug text using the built in sprint font\n * @param ctx\n * @param text\n * @param pos\n */\n write(ctx, text, pos) {\n if (this._imageSource.isLoaded()) {\n this._spriteFont.render(ctx, text, null, pos.x, pos.y);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/render-source.ts\nclass RenderSource {\n constructor(_gl, _texture) {\n this._gl = _gl;\n this._texture = _texture;\n }\n use() {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\n }\n disable() {\n const gl = this._gl;\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/render-target.ts\n\nclass RenderTarget {\n constructor(options) {\n var _a, _b;\n this.antialias = false;\n this.samples = 1;\n this._gl = options.gl;\n this.width = options.width;\n this.height = options.height;\n this.transparency = options.transparency;\n this.antialias = (_a = options.antialias) !== null && _a !== void 0 ? _a : this.antialias;\n this.samples = (_b = options.samples) !== null && _b !== void 0 ? _b : this._gl.getParameter(this._gl.MAX_SAMPLES);\n const gl = this._gl;\n // Determine current context format for blitting later needs to match\n if (gl.drawingBufferFormat) {\n this.bufferFormat = gl.drawingBufferFormat;\n }\n else {\n // Documented in webgl spec\n // https://registry.khronos.org/webgl/specs/latest/1.0/\n if (this.transparency) {\n this.bufferFormat = gl.RGBA8;\n }\n else {\n this.bufferFormat = gl.RGB8;\n }\n }\n this._setupRenderBuffer();\n this._setupFramebuffer();\n }\n setResolution(width, height) {\n const gl = this._gl;\n this.width = width;\n this.height = height;\n // update backing texture size\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // update render buffer size\n if (this._renderBuffer) {\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\n gl.renderbufferStorageMultisample(gl.RENDERBUFFER, Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, this.height);\n }\n }\n get renderBuffer() {\n return this._renderBuffer;\n }\n get renderFrameBuffer() {\n return this._renderFrameBuffer;\n }\n get frameBuffer() {\n return this._frameBuffer;\n }\n get frameTexture() {\n return this._frameTexture;\n }\n _setupRenderBuffer() {\n if (this.antialias) {\n const gl = this._gl;\n // Render buffers can be used as an input to a shader\n this._renderBuffer = gl.createRenderbuffer();\n this._renderFrameBuffer = gl.createFramebuffer();\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\n gl.renderbufferStorageMultisample(gl.RENDERBUFFER, Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)), this.bufferFormat, this.width, this.height);\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\n gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._renderBuffer);\n }\n }\n _setupFramebuffer() {\n // Allocates frame buffer\n const gl = this._gl;\n this._frameTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // set the filtering so we don't need mips\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // attach the texture as the first color attachment\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\n // After this bind all draw calls will draw to this framebuffer texture\n this._frameBuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\n // Reset after initialized\n this.disable();\n }\n toRenderSource() {\n if (this.renderBuffer) {\n this.blitRenderBufferToFrameBuffer();\n }\n const source = new RenderSource(this._gl, this._frameTexture);\n return source;\n }\n blitToScreen() {\n const gl = this._gl;\n // set to size of canvas's drawingBuffer\n if (this._renderBuffer) {\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n else {\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.frameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n }\n blitRenderBufferToFrameBuffer() {\n if (this._renderBuffer) {\n const gl = this._gl;\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.frameBuffer);\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\n gl.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this.width, this.height, gl.COLOR_BUFFER_BIT, gl.LINEAR);\n }\n }\n copyToTexture(texture) {\n const gl = this._gl;\n if (this._renderBuffer) {\n this.blitRenderBufferToFrameBuffer();\n }\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, this.width, this.height, 0);\n }\n /**\n * When called, all drawing gets redirected to this render target\n */\n use() {\n const gl = this._gl;\n if (this.antialias) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\n }\n else {\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n }\n // very important to set the viewport to the size of the framebuffer texture\n gl.viewport(0, 0, this.width, this.height);\n }\n /**\n * When called, all drawing is sent back to the canvas\n */\n disable() {\n const gl = this._gl;\n // passing null switches rendering back to the canvas\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-vertex.glsl\n/* harmony default export */ const line_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-fragment.glsl\n/* harmony default export */ const line_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/webgl-util.ts\n/**\n * Return the size of the GlType in bytes\n * @param gl\n * @param type\n */\nfunction getGlTypeSizeBytes(gl, type) {\n switch (type) {\n case gl.FLOAT:\n return 4;\n case gl.SHORT:\n return 2;\n case gl.UNSIGNED_SHORT:\n return 2;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n default:\n return 1;\n }\n}\n/**\n * Based on the type return the number of attribute components\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\n * @param gl\n * @param type\n */\nfunction getAttributeComponentSize(gl, type) {\n switch (type) {\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n return 1;\n case gl.FLOAT_VEC2:\n return 2;\n case gl.FLOAT_VEC3:\n return 3;\n case gl.FLOAT_VEC4:\n return 4;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n case gl.UNSIGNED_SHORT:\n case gl.SHORT:\n return 1;\n default:\n return 1;\n }\n}\n/**\n * Based on the attribute return the corresponding supported attrib pointer type\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\n * @param gl\n * @param type\n */\nfunction getAttributePointerType(gl, type) {\n switch (type) {\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n case gl.FLOAT_VEC2:\n case gl.FLOAT_VEC3:\n case gl.FLOAT_VEC4:\n return gl.FLOAT;\n case gl.BYTE:\n return gl.BYTE;\n case gl.UNSIGNED_BYTE:\n return gl.UNSIGNED_BYTE;\n case gl.SHORT:\n return gl.SHORT;\n case gl.UNSIGNED_SHORT:\n return gl.UNSIGNED_SHORT;\n default:\n return gl.FLOAT;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/shader.ts\n\n\nclass Shader {\n get compiled() {\n return this._compiled;\n }\n /**\n * Create a shader program in excalibur\n * @param options specify shader vertex and fragment source\n */\n constructor(options) {\n this._logger = Logger.getInstance();\n this.uniforms = {};\n this.attributes = {};\n this._compiled = false;\n const { gl, vertexSource, fragmentSource } = options;\n this._gl = gl;\n this.vertexSource = vertexSource;\n this.fragmentSource = fragmentSource;\n }\n dispose() {\n const gl = this._gl;\n gl.deleteProgram(this.program);\n this._gl = null;\n }\n /**\n * Binds the shader program\n */\n use() {\n const gl = this._gl;\n gl.useProgram(this.program);\n Shader._ACTIVE_SHADER_INSTANCE = this;\n }\n isCurrentlyBound() {\n return Shader._ACTIVE_SHADER_INSTANCE === this;\n }\n /**\n * Compile the current shader against a webgl context\n */\n compile() {\n const gl = this._gl;\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\n const attributes = this.getAttributes();\n for (const attribute of attributes) {\n this.attributes[attribute.name] = attribute;\n }\n const uniforms = this.getUniforms();\n for (const uniform of uniforms) {\n this.uniforms[uniform.name] = uniform;\n }\n this._compiled = true;\n return this.program;\n }\n getUniforms() {\n const gl = this._gl;\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\n const uniforms = [];\n for (let i = 0; i < uniformCount; i++) {\n const uniform = gl.getActiveUniform(this.program, i);\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\n uniforms.push({\n name: uniform.name,\n glType: uniform.type,\n location: uniformLocation\n });\n }\n return uniforms;\n }\n getAttributes() {\n const gl = this._gl;\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\n const attributes = [];\n for (let i = 0; i < attributeCount; i++) {\n const attribute = gl.getActiveAttrib(this.program, i);\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\n attributes.push({\n name: attribute.name,\n glType: getAttributePointerType(gl, attribute.type),\n size: getAttributeComponentSize(gl, attribute.type),\n location: attributeLocation,\n normalized: false\n });\n }\n return attributes;\n }\n /**\n * Set a texture in a gpu texture slot\n * @param slotNumber\n * @param texture\n */\n setTexture(slotNumber, texture) {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n }\n /**\n * Set an integer uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformInt(name, value) {\n this.setUniform('uniform1i', name, ~~value);\n }\n /**\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformInt(name, value) {\n return this.trySetUniform('uniform1i', name, ~~value);\n }\n /**\n * Set an integer array uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformIntArray(name, value) {\n this.setUniform('uniform1iv', name, value);\n }\n /**\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformIntArray(name, value) {\n return this.trySetUniform('uniform1iv', name, value);\n }\n /**\n * Set a boolean uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformBoolean(name, value) {\n this.setUniform('uniform1i', name, value ? 1 : 0);\n }\n /**\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformBoolean(name, value) {\n return this.trySetUniform('uniform1i', name, value ? 1 : 0);\n }\n /**\n * Set a float uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformFloat(name, value) {\n this.setUniform('uniform1f', name, value);\n }\n /**\n * Set a float uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformFloat(name, value) {\n return this.trySetUniform('uniform1f', name, value);\n }\n /**\n * Set a float array uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformFloatArray(name, value) {\n this.setUniform('uniform1fv', name, value);\n }\n /**\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformFloatArray(name, value) {\n return this.trySetUniform('uniform1fv', name, value);\n }\n /**\n * Set a [[Vector]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformFloatVector(name, value) {\n this.setUniform('uniform2f', name, value.x, value.y);\n }\n /**\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformFloatVector(name, value) {\n return this.trySetUniform('uniform2f', name, value.x, value.y);\n }\n /**\n * Set a [[Color]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformFloatColor(name, value) {\n this.setUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformFloatColor(name, value) {\n return this.trySetUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\n * Set an [[Matrix]] uniform for the current shader\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n setUniformMatrix(name, value) {\n this.setUniform('uniformMatrix4fv', name, false, value.data);\n }\n /**\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\n *\n * **Important** Must call ex.Shader.use() before setting a uniform!\n * @param name\n * @param value\n */\n trySetUniformMatrix(name, value) {\n return this.trySetUniform('uniformMatrix4fv', name, false, value.data);\n }\n /**\n * Set any available uniform type in webgl\n *\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\n */\n setUniform(uniformType, name, ...value) {\n if (!this._compiled) {\n throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n }\n if (!this.isCurrentlyBound()) {\n throw Error('Currently accessed shader instance is not the current active shader in WebGL,' +\n ' must call `shader.use()` before setting uniforms');\n }\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [location, ...value];\n this._gl[uniformType].apply(this._gl, args);\n }\n else {\n throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,` +\n ' unused uniforms are optimized away by most browsers');\n }\n }\n /**\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\n * true if it was set.\n *\n * WILL NOT THROW on error\n *\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\n *\n */\n trySetUniform(uniformType, name, ...value) {\n if (!this._compiled) {\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n return false;\n }\n if (!this.isCurrentlyBound()) {\n this._logger.warn('Currently accessed shader instance is not the current active shader in WebGL,' +\n ' must call `shader.use()` before setting uniforms');\n return false;\n }\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [location, ...value];\n this._gl[uniformType].apply(this._gl, args);\n }\n else {\n return false;\n }\n return true;\n }\n _createProgram(gl, vertexShader, fragmentShader) {\n const program = gl.createProgram();\n if (program === null) {\n throw Error('Could not create graphics shader program');\n }\n // attach the shaders.\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n // link the program.\n gl.linkProgram(program);\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n if (!success) {\n throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\n }\n return program;\n }\n _compileShader(gl, source, type) {\n const typeName = gl.VERTEX_SHADER === type ? 'vertex' : 'fragment';\n const shader = gl.createShader(type);\n if (shader === null) {\n throw Error(`Could not build shader: [${source}]`);\n }\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (!success) {\n const errorInfo = gl.getShaderInfoLog(shader);\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\n }\n return shader;\n }\n _processSourceForError(source, errorInfo) {\n if (!source) {\n return errorInfo;\n }\n const lines = source.split('\\n');\n const errorLineStart = errorInfo.search(/\\d:\\d/);\n const errorLineEnd = errorInfo.indexOf(' ', errorLineStart);\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(':').map(v => Number(v));\n for (let i = 0; i < lines.length; i++) {\n lines[i] = `${i + 1}: ${lines[i]}${error2 === (i + 1) ? ' <----- ERROR!' : ''}`;\n }\n return '\\n\\nSource:\\n' + lines.join('\\n');\n }\n}\nShader._ACTIVE_SHADER_INSTANCE = null;\n\n;// CONCATENATED MODULE: ./Graphics/Context/vertex-buffer.ts\n/**\n * Helper around vertex buffer to simplify creating and uploading geometry\n *\n * Under the hood uses Float32Array\n */\nclass VertexBuffer {\n constructor(options) {\n /**\n * If the vertices never change switching 'static' can be more efficient on the gpu\n *\n * Default is 'dynamic'\n */\n this.type = 'dynamic';\n const { gl, size, type, data } = options;\n this._gl = gl;\n this.buffer = this._gl.createBuffer();\n if (!data && !size) {\n throw Error('Must either provide data or a size to the VertexBuffer');\n }\n if (!data) {\n this.bufferData = new Float32Array(size);\n }\n else {\n this.bufferData = data;\n }\n this.type = type !== null && type !== void 0 ? type : this.type;\n // Allocate buffer\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n /**\n * Bind this vertex buffer\n */\n bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n }\n /**\n * Upload vertex buffer geometry to the GPU\n */\n upload(count) {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n if (count) {\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\n }\n else {\n // TODO always use bufferSubData? need to perf test it\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n }\n dispose() {\n const gl = this._gl;\n gl.deleteBuffer(this.buffer);\n this._gl = null;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/vertex-layout.ts\n\n\n/**\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\n * the memory layout for your vertices inside a particular buffer\n *\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\n *\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\n */\nclass VertexLayout {\n get vertexBuffer() {\n return this._vertexBuffer;\n }\n get attributes() {\n return this._attributes;\n }\n constructor(options) {\n this._logger = Logger.getInstance();\n this._layout = [];\n this._attributes = [];\n this._vertexTotalSizeBytes = 0;\n const { gl, shader, vertexBuffer, attributes } = options;\n this._gl = gl;\n this._vertexBuffer = vertexBuffer;\n this._attributes = attributes;\n this._shader = shader;\n if (shader) {\n this.initialize();\n }\n }\n /**\n * Total number of bytes that the vertex will take up\n */\n get totalVertexSizeBytes() {\n return this._vertexTotalSizeBytes;\n }\n set shader(shader) {\n if (shader && this._shader !== shader) {\n this._shader = shader;\n this.initialize();\n }\n }\n get shader() {\n return this._shader;\n }\n /**\n * Layouts need shader locations and must be bound to a shader\n */\n initialize() {\n if (!this._shader) {\n return;\n }\n if (!this._shader.compiled) {\n throw Error('Shader not compiled, shader must be compiled before defining a vertex layout');\n }\n this._vertexTotalSizeBytes = 0;\n this._layout.length = 0;\n const shaderAttributes = this._shader.attributes;\n for (const attribute of this._attributes) {\n const attrib = shaderAttributes[attribute[0]];\n if (!attrib) {\n throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}` +\n ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\n }\n if (attrib.size !== attribute[1]) {\n throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],`\n + ` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\n }\n this._layout.push(attrib);\n }\n // calc size\n let componentsPerVertex = 0;\n for (const vertAttribute of this._layout) {\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\n componentsPerVertex += vertAttribute.size;\n }\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) {\n this._logger.warn(`The vertex component size (${componentsPerVertex}) does NOT divide evenly into the specified vertex buffer`\n + ` (${this._vertexBuffer.bufferData.length})`);\n }\n }\n /**\n * Bind this layout with it's associated vertex buffer\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\n */\n use(uploadBuffer = false, count) {\n if (!this._shader) {\n throw Error('No shader is associated with this vertex layout, a shader must be set');\n }\n const gl = this._gl;\n if (!this._shader.isCurrentlyBound()) {\n throw Error('Shader associated with this vertex layout is not active! Call shader.use() before layout.use()');\n }\n this._vertexBuffer.bind();\n if (uploadBuffer) {\n this._vertexBuffer.upload(count);\n }\n let offset = 0;\n // TODO switch to VAOs if the extension is\n for (const vert of this._layout) {\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\n gl.enableVertexAttribArray(vert.location);\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsDiagnostics.ts\nclass GraphicsDiagnostics {\n static clear() {\n GraphicsDiagnostics.DrawCallCount = 0;\n GraphicsDiagnostics.DrawnImagesCount = 0;\n }\n}\nGraphicsDiagnostics.DrawCallCount = 0;\nGraphicsDiagnostics.DrawnImagesCount = 0;\n\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-renderer.ts\n\n\n\n\nclass LineRenderer {\n constructor() {\n this.type = 'ex.line';\n this.priority = 0;\n this._maxLines = 10922;\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl,\n vertexSource: line_vertex,\n fragmentSource: line_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n this._vertexBuffer = new VertexBuffer({\n gl,\n size: 6 * 2 * this._maxLines,\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n vertexBuffer: this._vertexBuffer,\n shader: this._shader,\n attributes: [\n ['a_position', 2],\n ['a_color', 4]\n ]\n });\n }\n dispose() {\n this._vertexBuffer.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n draw(start, end, color) {\n // Force a render if the batch is full\n if (this._isFull()) {\n this.flush();\n }\n this._lineCount++;\n const transform = this._context.getTransform();\n const finalStart = transform.multiply(start);\n const finalEnd = transform.multiply(end);\n const vertexBuffer = this._vertexBuffer.bufferData;\n // Start\n vertexBuffer[this._vertexIndex++] = finalStart.x;\n vertexBuffer[this._vertexIndex++] = finalStart.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n // End\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n }\n _isFull() {\n if (this._lineCount >= this._maxLines) {\n return true;\n }\n return false;\n }\n hasPendingDraws() {\n return this._lineCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._lineCount === 0) {\n return;\n }\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\n GraphicsDiagnostics.DrawCallCount++;\n // reset\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-vertex.glsl\n/* harmony default export */ const point_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-fragment.glsl\n/* harmony default export */ const point_fragment = (\"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \\\"premultiply\\\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-renderer.ts\n\n\n\n\n\n\n\nclass PointRenderer {\n constructor() {\n this.type = 'ex.point';\n this.priority = 0;\n this._maxPoints = 10922;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl,\n vertexSource: point_vertex,\n fragmentSource: point_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n this._buffer = new VertexBuffer({\n gl,\n size: 7 * this._maxPoints,\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_color', 4],\n ['a_size', 1]\n ]\n });\n }\n dispose() {\n this._buffer.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n draw(point, color, size) {\n // Force a render if the batch is full\n if (this._isFull()) {\n this.flush();\n }\n this._pointCount++;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const finalPoint = transform.multiply(point);\n if (snapToPixel) {\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\n }\n const vertexBuffer = this._buffer.bufferData;\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\n }\n _isFull() {\n if (this._pointCount >= this._maxPoints) {\n return true;\n }\n return false;\n }\n hasPendingDraws() {\n return this._pointCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._pointCount === 0) {\n return;\n }\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\n GraphicsDiagnostics.DrawCallCount++;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-vertex.glsl\n/* harmony default export */ const screen_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-fragment.glsl\n/* harmony default export */ const screen_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-pass-painter.ts\n\n\n\n\n\n/**\n * This is responsible for painting the entire screen during the render passes\n */\nclass ScreenPassPainter {\n constructor(gl) {\n this._gl = gl;\n this._shader = new Shader({\n gl,\n vertexSource: screen_vertex,\n fragmentSource: screen_fragment\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl,\n type: 'static',\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1, -1, 0, 0,\n -1, 1, 0, 1,\n 1, -1, 1, 0,\n 1, -1, 1, 0,\n -1, 1, 0, 1,\n 1, 1, 1, 1\n ])\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_texcoord', 2]\n ]\n });\n this._buffer.upload();\n }\n renderWithPostProcessor(postprocessor) {\n const gl = this._gl;\n postprocessor.getShader().use();\n postprocessor.getLayout().use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n renderToScreen() {\n const gl = this._gl;\n this._shader.use();\n this._layout.use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/quad-index-buffer.ts\n\n/**\n * Helper that defines and index buffer for quad geometry\n *\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\n * it is almost always worth it in terms of performance to use an index buffer.\n */\nclass QuadIndexBuffer {\n /**\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\n * @param numberOfQuads Specify the max number of quads you want to draw\n * @param useUint16 Optionally force a uint16 buffer\n */\n constructor(gl, numberOfQuads, useUint16) {\n this._logger = Logger.getInstance();\n this._gl = gl;\n this.buffer = gl.createBuffer();\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n const totalVertices = numberOfQuads * 6;\n if (!useUint16) {\n this.bufferData = new Uint32Array(totalVertices);\n }\n else {\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\n const maxUint16 = 65535;\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\n this.bufferGlType = gl.UNSIGNED_SHORT;\n this.bufferData = new Uint16Array(totalVertices);\n // TODO Should we error if this happens?? maybe not might crash mid game\n if (numberOfQuads > maxUint16Index) {\n this._logger.warn(`Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\n }\n }\n let currentQuad = 0;\n for (let i = 0; i < totalVertices; i += 6) {\n // first triangle\n this.bufferData[i + 0] = currentQuad + 0;\n this.bufferData[i + 1] = currentQuad + 1;\n this.bufferData[i + 2] = currentQuad + 2;\n // second triangle\n this.bufferData[i + 3] = currentQuad + 2;\n this.bufferData[i + 4] = currentQuad + 1;\n this.bufferData[i + 5] = currentQuad + 3;\n currentQuad += 4;\n }\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n get size() {\n return this.bufferData.length;\n }\n /**\n * Upload data to the GPU\n */\n upload() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n /**\n * Bind this index buffer\n */\n bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n }\n dispose() {\n const gl = this._gl;\n gl.deleteBuffer(this.buffer);\n this._gl = null;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.frag.glsl\n/* harmony default export */ const image_renderer_frag = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\nuniform bool u_pixelart;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nin vec2 v_res;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\n// Inigo Quilez pixel art filter https://jorenjoestar.github.io/post/pixel_art_filtering/\\r\\nvec2 uv_iq(in vec2 uv, in vec2 texture_size) {\\r\\n vec2 pixel = uv * texture_size;\\r\\n \\r\\n vec2 seam=floor(pixel+.5);\\r\\n vec2 dudv=fwidth(pixel);\\r\\n pixel=seam+clamp((pixel-seam)/dudv,-.5,.5);\\r\\n \\r\\n return pixel/texture_size;\\r\\n}\\r\\n\\r\\nvoid main(){\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n \\r\\n vec4 color=vec4(1.,0,0,1.);\\r\\n \\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n \\r\\n color.rgb=color.rgb*v_opacity;\\r\\n color.a=color.a*v_opacity;\\r\\n fragColor=color*v_tint;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.vert.glsl\n/* harmony default export */ const image_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity\\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture res\\r\\nin vec2 a_res;\\r\\nout vec2 v_res;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main(){\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position=u_matrix*vec4(a_position,0.,1.);\\r\\n \\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity=a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord=a_texcoord;\\r\\n\\r\\n v_res = a_res;\\r\\n\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex=a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint=a_tint;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.ts\n\n\n\n\n\n\n\n\n\n\n\nclass ImageRenderer {\n constructor(options) {\n this.type = 'ex.image';\n this.priority = 0;\n this._maxImages = 10922; // max(uint16) / 6 verts\n this._maxTextures = 0;\n // Per flush vars\n this._imageCount = 0;\n this._textures = [];\n this._vertexIndex = 0;\n this.pixelArtSampler = options.pixelArtSampler;\n this.uvPadding = options.uvPadding;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Transform shader source\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\n const transformedFrag = this._transformFragmentSource(image_renderer_frag, this._maxTextures);\n // Compile shader\n this._shader = new Shader({\n gl,\n fragmentSource: transformedFrag,\n vertexSource: image_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', context.ortho);\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\n this._shader.setUniformIntArray('u_textures', [...Array(this._maxTextures)].map((_, i) => i));\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl,\n size: 12 * 4 * this._maxImages, // 12 components * 4 verts\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_opacity', 1],\n ['a_res', 2],\n ['a_texcoord', 2],\n ['a_textureIndex', 1],\n ['a_tint', 4]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._textures.length = 0;\n this._context = null;\n this._gl = null;\n }\n _transformFragmentSource(source, maxTextures) {\n let newSource = source.replace('%%count%%', maxTextures.toString());\n let texturePickerBuilder = '';\n for (let i = 0; i < maxTextures; i++) {\n if (i === 0) {\n texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\n }\n else {\n texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\n }\n texturePickerBuilder += ` vec2 uv = u_pixelart ? uv_iq(v_texcoord, v_res) : v_texcoord;\\n`;\n texturePickerBuilder += ` color = texture(u_textures[${i}], uv);\\n`;\n texturePickerBuilder += ` }\\n`;\n }\n newSource = newSource.replace('%%texture_picker%%', texturePickerBuilder);\n return newSource;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute('filtering');\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended ||\n maybeFiltering === ImageFiltering.Pixel) {\n filtering = maybeFiltering;\n }\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute('forceUpload');\n if (this._textures.indexOf(texture) === -1) {\n this._textures.push(texture);\n }\n }\n _bindTextures(gl) {\n // Bind textures in the correct order\n for (let i = 0; i < this._maxTextures; i++) {\n gl.activeTexture(gl.TEXTURE0 + i);\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\n }\n }\n _getTextureIdForImage(image) {\n if (image) {\n const maybeTexture = this._context.textureLoader.get(image);\n return this._textures.indexOf(maybeTexture);\n }\n return -1;\n }\n _isFull() {\n if (this._imageCount >= this._maxImages) {\n return true;\n }\n if (this._textures.length >= this._maxTextures) {\n return true;\n }\n return false;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n // Force a render if the batch is full\n if (this._isFull()) {\n this.flush();\n }\n this._imageCount++;\n // This creates and uploads the texture if not already done\n this._addImageAsTexture(image);\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [0, 0, (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0, (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0];\n let dest = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1, (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0, (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0];\n dest = [dx, dy];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n let topLeft = vec(dest[0], dest[1]);\n let topRight = vec(dest[0] + width, dest[1]);\n let bottomLeft = vec(dest[0], dest[1] + height);\n let bottomRight = vec(dest[0] + width, dest[1] + height);\n topLeft = transform.multiply(topLeft);\n topRight = transform.multiply(topRight);\n bottomLeft = transform.multiply(bottomLeft);\n bottomRight = transform.multiply(bottomRight);\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + sign(topLeft.x) * pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + sign(topLeft.y) * pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + sign(topRight.x) * pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + sign(topRight.y) * pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + sign(bottomLeft.x) * pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + sign(bottomLeft.y) * pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + sign(bottomRight.x) * pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + sign(bottomRight.y) * pixelSnapEpsilon);\n }\n const tint = this._context.tint;\n const textureId = this._getTextureIdForImage(image);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = (sx + this.uvPadding) / imageWidth;\n const uvy0 = (sy + this.uvPadding) / imageHeight;\n const uvx1 = (sx + sw - this.uvPadding) / imageWidth;\n const uvy1 = (sy + sh - this.uvPadding) / imageHeight;\n const txWidth = image.width;\n const txHeight = image.height;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = txWidth;\n vertexBuffer[this._vertexIndex++] = txHeight;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n }\n hasPendingDraws() {\n return this._imageCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._imageCount === 0) {\n return;\n }\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true, 4 * 12 * this._imageCount); // 4 verts * 12 components\n // Update ortho matrix uniform\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n // Turn on pixel art aa sampler\n this._shader.setUniformBoolean('u_pixelart', this.pixelArtSampler);\n // Bind textures to\n this._bindTextures(gl);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._imageCount = 0;\n this._vertexIndex = 0;\n this._textures.length = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.frag.glsl\n/* harmony default export */ const rectangle_renderer_frag = (\"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.vert.glsl\n/* harmony default export */ const rectangle_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.ts\n\n\n\n\n\n\n\n\n\n\nclass RectangleRenderer {\n constructor() {\n this.type = 'ex.rectangle';\n this.priority = 0;\n this._maxRectangles = 10922; // max(uint16) / 6 verts\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\n this._shader = new Shader({\n gl,\n fragmentSource: rectangle_renderer_frag,\n vertexSource: rectangle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', context.ortho);\n this._buffer = new VertexBuffer({\n gl,\n size: 16 * 4 * this._maxRectangles,\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_uv', 2],\n ['a_size', 2],\n ['a_opacity', 1],\n ['a_color', 4],\n ['a_strokeColor', 4],\n ['a_strokeThickness', 1]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n _isFull() {\n if (this._rectangleCount >= this._maxRectangles) {\n return true;\n }\n return false;\n }\n draw(...args) {\n if (args[0] instanceof Vector && args[1] instanceof Vector) {\n this.drawLine.apply(this, args);\n }\n else {\n this.drawRectangle.apply(this, args);\n }\n }\n drawLine(start, end, color, thickness = 1) {\n if (this._isFull()) {\n this.flush();\n }\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const dir = end.sub(start);\n const length = dir.size;\n const normal = dir.normalize().perpendicular();\n const halfThick = thickness / 2;\n /**\n * +---------------------^----------------------+\n * | | (normal) |\n * (startx, starty)------------------>(endx, endy)\n * | |\n * + -------------------------------------------+\n */\n const startTop = transform.multiply(normal.scale(halfThick).add(start));\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\n if (snapToPixel) {\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n const stroke = Color.Transparent;\n const strokeThickness = 0;\n const width = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = startTop.x;\n vertexBuffer[this._vertexIndex++] = startTop.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = startBottom.x;\n vertexBuffer[this._vertexIndex++] = startBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = endTop.x;\n vertexBuffer[this._vertexIndex++] = endTop.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = endBottom.x;\n vertexBuffer[this._vertexIndex++] = endBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n }\n drawRectangle(pos, width, height, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) {\n this.flush();\n }\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\n const topRight = transform.multiply(pos.add(vec(width, 0)));\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n }\n hasPendingDraws() {\n return this._rectangleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._rectangleCount === 0) {\n return;\n }\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.frag.glsl\n/* harmony default export */ const circle_renderer_frag = (\"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.vert.glsl\n/* harmony default export */ const circle_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.ts\n\n\n\n\n\n\n\n\n\n\nclass CircleRenderer {\n constructor() {\n this.type = 'ex.circle';\n this.priority = 0;\n this._maxCircles = 10922; // max(uint16) / 6 verts\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl,\n fragmentSource: circle_renderer_frag,\n vertexSource: circle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix('u_matrix', context.ortho);\n this._buffer = new VertexBuffer({\n gl,\n size: 14 * 4 * this._maxCircles,\n type: 'dynamic'\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_uv', 2],\n ['a_opacity', 1],\n ['a_color', 4],\n ['a_strokeColor', 4],\n ['a_strokeThickness', 1]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._shader.dispose();\n this._context = null;\n this._gl = null;\n }\n _isFull() {\n if (this._circleCount >= this._maxCircles) {\n return true;\n }\n return false;\n }\n draw(pos, radius, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) {\n this.flush();\n }\n this._circleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO UV could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n }\n hasPendingDraws() {\n return this._circleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._circleCount === 0) {\n return;\n }\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Pool.ts\n\nclass Pool {\n constructor(builder, recycler, maxObjects = 100) {\n this.builder = builder;\n this.recycler = recycler;\n this.maxObjects = maxObjects;\n this.totalAllocations = 0;\n this.index = 0;\n this.objects = [];\n this.disableWarnings = false;\n this._logger = Logger.getInstance();\n }\n dispose() {\n this.objects.length = 0;\n }\n preallocate() {\n for (let i = 0; i < this.maxObjects; i++) {\n this.objects[i] = this.builder();\n }\n }\n /**\n * Use many instances out of the in the context and return all to the pool.\n *\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\n * @param context\n */\n using(context) {\n const result = context(this);\n if (result) {\n return this.done(...result);\n }\n return this.done();\n }\n /**\n * Use a single instance out of th pool and immediately return it to the pool\n * @param context\n */\n borrow(context) {\n const object = this.get();\n context(object);\n this.index--;\n }\n /**\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\n * @param args\n */\n get(...args) {\n if (this.index === this.maxObjects) {\n if (!this.disableWarnings) {\n this._logger.warn('Max pooled objects reached, possible memory leak? Doubling');\n }\n this.maxObjects = this.maxObjects * 2;\n }\n if (this.objects[this.index]) {\n // Pool has an available object already constructed\n return this.recycler(this.objects[this.index++], ...args);\n }\n else {\n // New allocation\n this.totalAllocations++;\n const object = (this.objects[this.index++] = this.builder(...args));\n return object;\n }\n }\n done(...objects) {\n // All objects in pool now considered \"free\"\n this.index = 0;\n for (const object of objects) {\n const poolIndex = this.objects.indexOf(object);\n // Build a new object to take the pool place\n this.objects[poolIndex] = this.builder(); // TODO problematic 0-arg only support\n this.totalAllocations++;\n }\n return objects;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/draw-call.ts\n\n\nclass DrawCall {\n constructor() {\n this.z = 0;\n this.priority = 0;\n this.transform = AffineMatrix.identity();\n this.state = {\n z: 0,\n opacity: 1,\n tint: Color.White,\n material: null\n };\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/material.ts\n\n\n\n\nconst defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nin vec2 a_screenuv;\r\nout vec2 v_screenuv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n v_screenuv = a_screenuv;\r\n}\r\n`;\nclass Material {\n constructor(options) {\n this._logger = Logger.getInstance();\n this._color = Color.Transparent;\n this._initialized = false;\n this._images = new Map();\n this._textures = new Map();\n const { color, name, vertexSource, fragmentSource, graphicsContext, images } = options;\n this._name = name !== null && name !== void 0 ? name : 'anonymous material';\n this._vertexSource = vertexSource !== null && vertexSource !== void 0 ? vertexSource : defaultVertexSource;\n this._fragmentSource = fragmentSource;\n this._color = color !== null && color !== void 0 ? color : this._color;\n if (!graphicsContext) {\n throw Error(`Material ${name} must be provided an excalibur webgl graphics context`);\n }\n if (graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this._graphicsContext = graphicsContext;\n this._initialize(graphicsContext);\n }\n else {\n this._logger.warn(`Material ${name} was created in 2D Canvas mode, currently only WebGL is supported`);\n }\n if (images) {\n for (const key in images) {\n this.addImageSource(key, images[key]);\n }\n }\n }\n _initialize(graphicsContextWebGL) {\n if (this._initialized) {\n return;\n }\n const gl = graphicsContextWebGL.__gl;\n // max texture slots - 2 for the graphic texture and screen texture\n this._maxTextureSlots = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) - 2;\n this._shader = graphicsContextWebGL.createShader({\n vertexSource: this._vertexSource,\n fragmentSource: this._fragmentSource\n });\n this._shader.compile();\n this._initialized = true;\n }\n get name() {\n var _a;\n return (_a = this._name) !== null && _a !== void 0 ? _a : 'anonymous material';\n }\n get isUsingScreenTexture() {\n return this._fragmentSource.includes('u_screen_texture');\n }\n update(callback) {\n if (this._shader) {\n this._shader.use();\n callback(this._shader);\n }\n }\n getShader() {\n return this._shader;\n }\n addImageSource(textureUniformName, image) {\n if (this._images.size < this._maxTextureSlots) {\n this._images.set(textureUniformName, image);\n }\n else {\n this._logger.warn(`Max number texture slots ${this._maxTextureSlots} have been reached for material \"${this.name}\", ` +\n `no more textures will be uploaded due to hardware constraints.`);\n }\n }\n removeImageSource(textureName) {\n const image = this._images.get(textureName);\n this._graphicsContext.textureLoader.delete(image.image);\n this._images.delete(textureName);\n }\n _loadImageSource(image) {\n const imageElement = image.image;\n const maybeFiltering = imageElement.getAttribute('filtering');\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended ||\n maybeFiltering === ImageFiltering.Pixel) {\n filtering = maybeFiltering;\n }\n const force = imageElement.getAttribute('forceUpload') === 'true' ? true : false;\n const texture = this._graphicsContext.textureLoader.load(imageElement, filtering, force);\n // remove force attribute after upload\n imageElement.removeAttribute('forceUpload');\n if (!this._textures.has(image)) {\n this._textures.set(image, texture);\n }\n return texture;\n }\n uploadAndBind(gl, startingTextureSlot = 2) {\n let textureSlot = startingTextureSlot;\n for (const [textureName, image] of this._images.entries()) {\n if (!image.isLoaded()) {\n this._logger.warnOnce(`Image named ${textureName} in material ${this.name} not loaded, nothing will be uploaded to the shader.` +\n ` Did you forget to add this to a loader? https://excaliburjs.com/docs/loaders/`);\n continue;\n } // skip unloaded images, maybe warn\n const texture = this._loadImageSource(image);\n gl.activeTexture(gl.TEXTURE0 + textureSlot);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n this._shader.trySetUniformInt(textureName, textureSlot);\n textureSlot++;\n }\n }\n use() {\n if (this._initialized) {\n // bind the shader\n this._shader.use();\n // Apply standard uniforms\n this._shader.trySetUniformFloatColor('u_color', this._color);\n }\n else {\n throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/material-renderer/material-renderer.ts\n\n\n\n\n\n\nclass MaterialRenderer {\n constructor() {\n this.type = 'ex.material';\n this.priority = 0;\n this._textures = [];\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl,\n size: 6 * 4, // 6 components * 4 verts\n type: 'dynamic'\n });\n // Setup a vertex layout/buffer to the material\n this._layout = new VertexLayout({\n gl,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_uv', 2],\n ['a_screenuv', 2]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, 1, true);\n }\n dispose() {\n this._buffer.dispose();\n this._quads.dispose();\n this._textures.length = 0;\n this._context = null;\n this._gl = null;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n const gl = this._gl;\n // Extract context info\n const material = this._context.material;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n // material shader\n const shader = material.getShader();\n // construct geometry, or hold on to it in the material?\n // geometry primitive for drawing rectangles?\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n let vertexIndex = 0;\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [0, 0, (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0, (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0];\n let dest = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1, (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0, (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0];\n dest = [dx, dy];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n const topLeft = vec(dest[0], dest[1]);\n const topRight = vec(dest[0] + width, dest[1]);\n const bottomLeft = vec(dest[0], dest[1] + height);\n const bottomRight = vec(dest[0] + width, dest[1] + height);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = (sx) / imageWidth;\n const uvy0 = (sy) / imageHeight;\n const uvx1 = (sx + sw - 0.01) / imageWidth;\n const uvy1 = (sy + sh - 0.01) / imageHeight;\n const topLeftScreen = transform.getPosition();\n const bottomRightScreen = topLeftScreen.add(bottomRight);\n const screenUVX0 = topLeftScreen.x / this._context.width;\n const screenUVY0 = topLeftScreen.y / this._context.height;\n const screenUVX1 = bottomRightScreen.x / this._context.width;\n const screenUVY1 = bottomRightScreen.y / this._context.height;\n // (0, 0) - 0\n vertexBuffer[vertexIndex++] = topLeft.x;\n vertexBuffer[vertexIndex++] = topLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy0;\n vertexBuffer[vertexIndex++] = screenUVX0;\n vertexBuffer[vertexIndex++] = screenUVY0;\n // (0, 1) - 1\n vertexBuffer[vertexIndex++] = bottomLeft.x;\n vertexBuffer[vertexIndex++] = bottomLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy1;\n vertexBuffer[vertexIndex++] = screenUVX0;\n vertexBuffer[vertexIndex++] = screenUVY1;\n // (1, 0) - 2\n vertexBuffer[vertexIndex++] = topRight.x;\n vertexBuffer[vertexIndex++] = topRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy0;\n vertexBuffer[vertexIndex++] = screenUVX1;\n vertexBuffer[vertexIndex++] = screenUVY0;\n // (1, 1) - 3\n vertexBuffer[vertexIndex++] = bottomRight.x;\n vertexBuffer[vertexIndex++] = bottomRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy1;\n vertexBuffer[vertexIndex++] = screenUVX1;\n vertexBuffer[vertexIndex++] = screenUVY1;\n // This creates and uploads the texture if not already done\n const texture = this._addImageAsTexture(image);\n // apply material\n material.use();\n this._layout.shader = shader;\n // apply layout and geometry\n this._layout.use(true);\n // apply time in ms since the page (performance.now())\n shader.trySetUniformFloat('u_time_ms', performance.now());\n // apply opacity\n shader.trySetUniformFloat('u_opacity', opacity);\n // apply resolution\n shader.trySetUniformFloatVector('u_resolution', vec(this._context.width, this._context.height));\n // apply graphic resolution\n shader.trySetUniformFloatVector('u_graphic_resolution', vec(imageWidth, imageHeight));\n // apply size\n shader.trySetUniformFloatVector('u_size', vec(sw, sh));\n // apply orthographic projection\n shader.trySetUniformMatrix('u_matrix', this._context.ortho);\n // apply geometry transform\n shader.trySetUniformMatrix('u_transform', transform.to4x4());\n // bind graphic image texture 'uniform sampler2D u_graphic;'\n gl.activeTexture(gl.TEXTURE0 + 0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n shader.trySetUniformInt('u_graphic', 0);\n // bind the screen texture\n gl.activeTexture(gl.TEXTURE0 + 1);\n gl.bindTexture(gl.TEXTURE_2D, this._context.materialScreenTexture);\n shader.trySetUniformInt('u_screen_texture', 1);\n // bind any additional textures in the material\n material.uploadAndBind(gl);\n // bind quad index buffer\n this._quads.bind();\n // Draw a single quad\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount++;\n GraphicsDiagnostics.DrawCallCount++;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute('filtering');\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended ||\n maybeFiltering === ImageFiltering.Pixel) {\n filtering = maybeFiltering;\n }\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute('forceUpload');\n if (this._textures.indexOf(texture) === -1) {\n this._textures.push(texture);\n }\n return texture;\n }\n hasPendingDraws() {\n return false;\n }\n flush() {\n // flush does not do anything, material renderer renders immediately per draw\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/ExcaliburGraphicsContextWebGL.ts\n\n\n\n\n\n\n\n\n\n// renderers\n\n\n\n\n\n\n\n\n\n\n\n\nconst pixelSnapEpsilon = 0.0001;\nclass ExcaliburGraphicsContextWebGLDebug {\n constructor(_webglCtx) {\n this._webglCtx = _webglCtx;\n this._debugText = new DebugText();\n }\n /**\n * Draw a debugging rectangle to the context\n * @param x\n * @param y\n * @param width\n * @param height\n */\n drawRect(x, y, width, height, rectOptions = { color: Color.Black }) {\n this.drawLine(vec(x, y), vec(x + width, y), { ...rectOptions });\n this.drawLine(vec(x + width, y), vec(x + width, y + height), { ...rectOptions });\n this.drawLine(vec(x + width, y + height), vec(x, y + height), { ...rectOptions });\n this.drawLine(vec(x, y + height), vec(x, y), { ...rectOptions });\n }\n /**\n * Draw a debugging line to the context\n * @param start\n * @param end\n * @param lineOptions\n */\n drawLine(start, end, lineOptions = { color: Color.Black }) {\n this._webglCtx.draw('ex.line', start, end, lineOptions.color);\n }\n /**\n * Draw a debugging point to the context\n * @param point\n * @param pointOptions\n */\n drawPoint(point, pointOptions = { color: Color.Black, size: 5 }) {\n this._webglCtx.draw('ex.point', point, pointOptions.color, pointOptions.size);\n }\n drawText(text, pos) {\n this._debugText.write(this._webglCtx, text, pos);\n }\n}\nclass ExcaliburGraphicsContextWebGL {\n get z() {\n return this._state.current.z;\n }\n set z(value) {\n this._state.current.z = value;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get width() {\n return this.__gl.canvas.width;\n }\n get height() {\n return this.__gl.canvas.height;\n }\n get ortho() {\n return this._ortho;\n }\n /**\n * Checks the underlying webgl implementation if the requested internal resolution is supported\n * @param dim\n */\n checkIfResolutionSupported(dim) {\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\n let supported = true;\n if (dim.width > 4096 || dim.height > 4096) {\n supported = false;\n }\n return supported;\n }\n constructor(options) {\n this._logger = Logger.getInstance();\n this._renderers = new Map();\n this._isDrawLifecycle = false;\n this.useDrawSorting = true;\n this._drawCallPool = new Pool(() => new DrawCall(), (instance) => {\n instance.priority = 0;\n instance.z = 0;\n instance.renderer = undefined;\n instance.args = undefined;\n return instance;\n }, 4000);\n this._drawCalls = [];\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\n this._postProcessTargets = [];\n this._postprocessors = [];\n this._transform = new TransformStack();\n this._state = new StateStack();\n /**\n * Snaps the drawing x/y coordinate to the nearest whole pixel\n */\n this.snapToPixel = false;\n /**\n * Native context smoothing\n */\n this.smoothing = false;\n /**\n * Whether the pixel art sampler is enabled for smooth sub pixel anti-aliasing\n */\n this.pixelArtSampler = false;\n /**\n * UV padding in pixels to use in internal image rendering to prevent texture bleed\n *\n */\n this.uvPadding = .01;\n this.backgroundColor = Color.ExcaliburBlue;\n this.multiSampleAntialiasing = true;\n this.transparency = true;\n this._disposed = false;\n this.debug = new ExcaliburGraphicsContextWebGLDebug(this);\n this._totalPostProcessorTime = 0;\n const { canvasElement, context, enableTransparency, antialiasing, uvPadding, multiSampleAntialiasing, pixelArtSampler, powerPreference, snapToPixel, backgroundColor, useDrawSorting } = options;\n this.__gl = context !== null && context !== void 0 ? context : canvasElement.getContext('webgl2', {\n antialias: antialiasing !== null && antialiasing !== void 0 ? antialiasing : this.smoothing,\n premultipliedAlpha: false,\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : this.transparency,\n depth: false,\n powerPreference: powerPreference !== null && powerPreference !== void 0 ? powerPreference : 'high-performance'\n });\n if (!this.__gl) {\n throw Error('Failed to retrieve webgl context from browser');\n }\n this.textureLoader = new TextureLoader(this.__gl);\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = antialiasing !== null && antialiasing !== void 0 ? antialiasing : this.smoothing;\n this.transparency = enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : this.transparency;\n this.pixelArtSampler = pixelArtSampler !== null && pixelArtSampler !== void 0 ? pixelArtSampler : this.pixelArtSampler;\n this.uvPadding = uvPadding !== null && uvPadding !== void 0 ? uvPadding : this.uvPadding;\n this.multiSampleAntialiasing = typeof multiSampleAntialiasing === 'boolean' ? multiSampleAntialiasing : this.multiSampleAntialiasing;\n this.samples = typeof multiSampleAntialiasing === 'object' ? multiSampleAntialiasing.samples : undefined;\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.useDrawSorting = useDrawSorting !== null && useDrawSorting !== void 0 ? useDrawSorting : this.useDrawSorting;\n this._drawCallPool.disableWarnings = true;\n this._drawCallPool.preallocate();\n this._init();\n }\n dispose() {\n if (!this._disposed) {\n this._disposed = true;\n this.textureLoader.dispose();\n for (const renderer of this._renderers.values()) {\n renderer.dispose();\n }\n this._renderers.clear();\n this._drawCallPool.dispose();\n this._drawCalls.length = 0;\n this.__gl = null;\n }\n }\n _init() {\n const gl = this.__gl;\n // Setup viewport and view matrix\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\n // Clear background\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n // Enable alpha blending\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n // Setup builtin renderers\n this.register(new ImageRenderer({\n uvPadding: this.uvPadding,\n pixelArtSampler: this.pixelArtSampler\n }));\n this.register(new MaterialRenderer());\n this.register(new RectangleRenderer());\n this.register(new CircleRenderer());\n this.register(new PointRenderer());\n this.register(new LineRenderer());\n this.materialScreenTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this.materialScreenTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n gl.bindTexture(gl.TEXTURE_2D, null);\n this._screenRenderer = new ScreenPassPainter(gl);\n this._renderTarget = new RenderTarget({\n gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n });\n this._postProcessTargets = [\n new RenderTarget({\n gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n }),\n new RenderTarget({\n gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height\n })\n ];\n this._msaaTarget = new RenderTarget({\n gl,\n transparency: this.transparency,\n width: gl.canvas.width,\n height: gl.canvas.height,\n antialias: this.multiSampleAntialiasing,\n samples: this.samples\n });\n }\n register(renderer) {\n this._renderers.set(renderer.type, renderer);\n renderer.initialize(this.__gl, this);\n }\n get(rendererName) {\n return this._renderers.get(rendererName);\n }\n _isCurrentRenderer(renderer) {\n if (!this._currentRenderer || this._currentRenderer === renderer) {\n return true;\n }\n return false;\n }\n beginDrawLifecycle() {\n this._isDrawLifecycle = true;\n }\n endDrawLifecycle() {\n this._isDrawLifecycle = false;\n }\n draw(rendererName, ...args) {\n if (!this._isDrawLifecycle) {\n this._logger.warnOnce(`Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` +\n `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\n }\n const renderer = this._renderers.get(rendererName);\n if (renderer) {\n if (this.useDrawSorting) {\n const drawCall = this._drawCallPool.get();\n drawCall.z = this._state.current.z;\n drawCall.priority = renderer.priority;\n drawCall.renderer = rendererName;\n this.getTransform().clone(drawCall.transform);\n drawCall.state.z = this._state.current.z;\n drawCall.state.opacity = this._state.current.opacity;\n drawCall.state.tint = this._state.current.tint;\n drawCall.state.material = this._state.current.material;\n drawCall.args = args;\n this._drawCalls.push(drawCall);\n }\n else {\n // Set the current renderer if not defined\n if (!this._currentRenderer) {\n this._currentRenderer = renderer;\n }\n if (!this._isCurrentRenderer(renderer)) {\n // switching graphics means we must flush the previous\n this._currentRenderer.flush();\n }\n // If we are still using the same renderer we can add to the current batch\n renderer.draw(...args);\n this._currentRenderer = renderer;\n }\n }\n else {\n throw Error(`No renderer with name ${rendererName} has been registered`);\n }\n }\n resetTransform() {\n this._transform.current = AffineMatrix.identity();\n }\n updateViewport(resolution) {\n const gl = this.__gl;\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._msaaTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) {\n return; // zero dimension dest exit early\n }\n else if (dwidth === 0 || dheight === 0) {\n return; // zero dimension dest exit early\n }\n else if (image.width === 0 || image.height === 0) {\n return; // zero dimension source exit early\n }\n if (!image) {\n Logger.getInstance().warn('Cannot draw a null or undefined image');\n // tslint:disable-next-line: no-console\n if (console.trace) {\n // tslint:disable-next-line: no-console\n console.trace();\n }\n return;\n }\n if (this._state.current.material) {\n this.draw('ex.material', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n }\n else {\n this.draw('ex.image', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n }\n }\n drawLine(start, end, color, thickness = 1) {\n this.draw('ex.rectangle', start, end, color, thickness);\n }\n drawRectangle(pos, width, height, color, stroke, strokeThickness) {\n this.draw('ex.rectangle', pos, width, height, color, stroke, strokeThickness);\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.draw('ex.circle', pos, radius, color, stroke, thickness);\n }\n save() {\n this._transform.save();\n this._state.save();\n }\n restore() {\n this._transform.restore();\n this._state.restore();\n }\n translate(x, y) {\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\n }\n rotate(angle) {\n this._transform.rotate(angle);\n }\n scale(x, y) {\n this._transform.scale(x, y);\n }\n transform(matrix) {\n this._transform.current = matrix;\n }\n getTransform() {\n return this._transform.current;\n }\n multiply(m) {\n this._transform.current.multiply(m, this._transform.current);\n }\n addPostProcessor(postprocessor) {\n this._postprocessors.push(postprocessor);\n postprocessor.initialize(this.__gl);\n }\n removePostProcessor(postprocessor) {\n const index = this._postprocessors.indexOf(postprocessor);\n if (index !== -1) {\n this._postprocessors.splice(index, 1);\n }\n }\n clearPostProcessors() {\n this._postprocessors.length = 0;\n }\n updatePostProcessors(delta) {\n for (const postprocessor of this._postprocessors) {\n const shader = postprocessor.getShader();\n shader.use();\n const uniforms = shader.getUniforms();\n this._totalPostProcessorTime += delta;\n if (uniforms.find(u => u.name === 'u_time_ms')) {\n shader.setUniformFloat('u_time_ms', this._totalPostProcessorTime);\n }\n if (uniforms.find(u => u.name === 'u_elapsed_ms')) {\n shader.setUniformFloat('u_elapsed_ms', delta);\n }\n if (uniforms.find(u => u.name === 'u_resolution')) {\n shader.setUniformFloatVector('u_resolution', vec(this.width, this.height));\n }\n if (postprocessor.onUpdate) {\n postprocessor.onUpdate(delta);\n }\n }\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n /**\n * Creates and initializes the material which compiles the internal shader\n * @param options\n * @returns Material\n */\n createMaterial(options) {\n const material = new Material({ ...options, graphicsContext: this });\n return material;\n }\n createShader(options) {\n const gl = this.__gl;\n const { vertexSource, fragmentSource } = options;\n const shader = new Shader({\n gl,\n vertexSource,\n fragmentSource\n });\n shader.compile();\n return shader;\n }\n clear() {\n const gl = this.__gl;\n const currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\n currentTarget.use();\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n // Clear the context with the newly set color. This is\n // the function call that actually does the drawing.\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n /**\n * Flushes all batched rendering to the screen\n */\n flush() {\n // render target captures all draws and redirects to the render target\n let currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\n currentTarget.use();\n if (this.useDrawSorting) {\n // sort draw calls\n // Find the original order of the first instance of the draw call\n const originalSort = new Map();\n for (const [name] of this._renderers) {\n const firstIndex = this._drawCalls.findIndex(dc => dc.renderer === name);\n originalSort.set(name, firstIndex);\n }\n this._drawCalls.sort((a, b) => {\n const zIndex = a.z - b.z;\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\n const priority = a.priority - b.priority;\n if (zIndex === 0) { // sort by z first\n if (priority === 0) { // sort by priority\n return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\n }\n return priority;\n }\n return zIndex;\n });\n const oldTransform = this._transform.current;\n const oldState = this._state.current;\n if (this._drawCalls.length) {\n let currentRendererName = this._drawCalls[0].renderer;\n let currentRenderer = this._renderers.get(currentRendererName);\n for (let i = 0; i < this._drawCalls.length; i++) {\n // hydrate the state for renderers\n this._transform.current = this._drawCalls[i].transform;\n this._state.current = this._drawCalls[i].state;\n if (this._drawCalls[i].renderer !== currentRendererName) {\n // switching graphics renderer means we must flush the previous\n currentRenderer.flush();\n currentRendererName = this._drawCalls[i].renderer;\n currentRenderer = this._renderers.get(currentRendererName);\n }\n // ! hack to grab screen texture before materials run because they might want it\n if (currentRenderer instanceof MaterialRenderer && this.material.isUsingScreenTexture) {\n currentTarget.copyToTexture(this.materialScreenTexture);\n currentTarget.use();\n }\n // If we are still using the same renderer we can add to the current batch\n currentRenderer.draw(...this._drawCalls[i].args);\n }\n if (currentRenderer.hasPendingDraws()) {\n currentRenderer.flush();\n }\n }\n // reset state\n this._transform.current = oldTransform;\n this._state.current = oldState;\n // reclaim draw calls\n this._drawCallPool.done();\n this._drawCalls.length = 0;\n }\n else {\n // This is the final flush at the moment to draw any leftover pending draw\n for (const renderer of this._renderers.values()) {\n if (renderer.hasPendingDraws()) {\n renderer.flush();\n }\n }\n }\n currentTarget.disable();\n // post process step\n if (this._postprocessors.length > 0) {\n const source = currentTarget.toRenderSource();\n source.use();\n }\n // flip flop render targets for post processing\n for (let i = 0; i < this._postprocessors.length; i++) {\n currentTarget = this._postProcessTargets[i % 2];\n this._postProcessTargets[i % 2].use();\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\n this._postProcessTargets[i % 2].toRenderSource().use();\n }\n // Final blit to the screen\n currentTarget.blitToScreen();\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts\n\n\n\n\nconst ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon = 0.0001;\nclass ExcaliburGraphicsContext2DCanvasDebug {\n constructor(_ex) {\n this._ex = _ex;\n this._debugText = new DebugText();\n }\n /**\n * Draw a debug rectangle to the context\n * @param x\n * @param y\n * @param width\n * @param height\n */\n drawRect(x, y, width, height) {\n this._ex.__ctx.save();\n this._ex.__ctx.strokeStyle = 'red';\n this._ex.__ctx.strokeRect(this._ex.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this._ex.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y, this._ex.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this._ex.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this._ex.__ctx.restore();\n }\n drawLine(start, end, lineOptions = { color: Color.Black }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\n this._ex.__ctx.moveTo(this._ex.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this._ex.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this._ex.__ctx.lineTo(this._ex.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this._ex.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this._ex.__ctx.lineWidth = 2;\n this._ex.__ctx.stroke();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawPoint(point, pointOptions = { color: Color.Black, size: 5 }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\n this._ex.__ctx.arc(this._ex.snapToPixel ? ~~(point.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.x, this._ex.snapToPixel ? ~~(point.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.y, pointOptions.size, 0, Math.PI * 2);\n this._ex.__ctx.fill();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawText(text, pos) {\n this._debugText.write(this._ex, text, pos);\n }\n}\nclass ExcaliburGraphicsContext2DCanvas {\n get width() {\n return this.__ctx.canvas.width;\n }\n get height() {\n return this.__ctx.canvas.height;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get smoothing() {\n return this.__ctx.imageSmoothingEnabled;\n }\n set smoothing(value) {\n this.__ctx.imageSmoothingEnabled = value;\n }\n constructor(options) {\n /**\n * Unused in Canvas implementation\n */\n this.useDrawSorting = false;\n /**\n * Unused in Canvas implementation\n */\n this.z = 0;\n this.backgroundColor = Color.ExcaliburBlue;\n this._state = new StateStack();\n this.snapToPixel = false;\n this.debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\n const { canvasElement, context, enableTransparency, snapToPixel, antialiasing: smoothing, backgroundColor } = options;\n this.__ctx = context !== null && context !== void 0 ? context : canvasElement.getContext('2d', {\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : true\n });\n if (!this.__ctx) {\n throw new Error('Cannot build new ExcaliburGraphicsContext2D for some reason!');\n }\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing;\n }\n resetTransform() {\n this.__ctx.resetTransform();\n }\n updateViewport(_resolution) {\n // pass\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) {\n return; // zero dimension dest exit early\n }\n else if (dwidth === 0 || dheight === 0) {\n return; // zero dimension dest exit early\n }\n else if (image.width === 0 || image.height === 0) {\n return; // zero dimension source exit early\n }\n this.__ctx.globalAlpha = this.opacity;\n const args = [image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight]\n .filter((a) => a !== undefined)\n .map((a) => (typeof a === 'number' && this.snapToPixel ? ~~a : a));\n this.__ctx.drawImage.apply(this.__ctx, args);\n GraphicsDiagnostics.DrawCallCount++;\n GraphicsDiagnostics.DrawnImagesCount = 1;\n }\n drawLine(start, end, color, thickness = 1) {\n this.__ctx.save();\n this.__ctx.beginPath();\n this.__ctx.strokeStyle = color.toString();\n this.__ctx.moveTo(this.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this.__ctx.lineTo(this.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this.__ctx.lineWidth = thickness;\n this.__ctx.stroke();\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n drawRectangle(pos, width, height, color) {\n this.__ctx.save();\n this.__ctx.fillStyle = color.toString();\n this.__ctx.fillRect(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, this.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this.__ctx.restore();\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.__ctx.save();\n this.__ctx.beginPath();\n if (stroke) {\n this.__ctx.strokeStyle = stroke.toString();\n }\n if (thickness) {\n this.__ctx.lineWidth = thickness;\n }\n this.__ctx.fillStyle = color.toString();\n this.__ctx.arc(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2);\n this.__ctx.fill();\n if (stroke) {\n this.__ctx.stroke();\n }\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n /**\n * Save the current state of the canvas to the stack (transforms and opacity)\n */\n save() {\n this.__ctx.save();\n this._state.save();\n }\n /**\n * Restore the state of the canvas from the stack\n */\n restore() {\n this.__ctx.restore();\n this._state.restore();\n }\n /**\n * Translate the origin of the context by an x and y\n * @param x\n * @param y\n */\n translate(x, y) {\n this.__ctx.translate(this.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y);\n }\n /**\n * Rotate the context about the current origin\n */\n rotate(angle) {\n this.__ctx.rotate(angle);\n }\n /**\n * Scale the context by an x and y factor\n * @param x\n * @param y\n */\n scale(x, y) {\n this.__ctx.scale(x, y);\n }\n getTransform() {\n throw new Error('Not implemented');\n }\n multiply(_m) {\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\n }\n addPostProcessor(_postprocessor) {\n // pass\n }\n removePostProcessor(_postprocessor) {\n // pass\n }\n clearPostProcessors() {\n // pass\n }\n updatePostProcessors(delta) {\n // pass\n }\n beginDrawLifecycle() {\n // pass\n }\n endDrawLifecycle() {\n // pass\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n createMaterial(options) {\n // pass\n return null;\n }\n clear() {\n // Clear frame\n this.__ctx.clearRect(0, 0, this.width, this.height);\n this.__ctx.fillStyle = this.backgroundColor.toString();\n this.__ctx.fillRect(0, 0, this.width, this.height);\n GraphicsDiagnostics.clear();\n }\n /**\n * Flushes the batched draw calls to the screen\n */\n flush() {\n // pass\n }\n dispose() {\n this.__ctx = null;\n }\n}\n\n;// CONCATENATED MODULE: ./Screen.ts\n\n\n\n\n\n\n\n/**\n * Enum representing the different display modes available to Excalibur.\n */\nvar DisplayMode;\n(function (DisplayMode) {\n /**\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\n */\n DisplayMode[\"Fixed\"] = \"Fixed\";\n /**\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\n * is guaranteed to be on screen.\n */\n DisplayMode[\"FitContainerAndFill\"] = \"FitContainerAndFill\";\n /**\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\n * is guaranteed to be on screen.\n */\n DisplayMode[\"FitScreenAndFill\"] = \"FitScreenAndFill\";\n /**\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\n * (letterbox) that would otherwise be present in [[FitContainer]].\n *\n * **warning** This will clip some drawable area from the user because of the zoom,\n * use [[Screen.contentArea]] to know the safe to draw area.\n */\n DisplayMode[\"FitContainerAndZoom\"] = \"FitContainerAndZoom\";\n /**\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\n * (letterbox) that would otherwise be present in [[FitScreen]].\n *\n * **warning** This will clip some drawable area from the user because of the zoom,\n * use [[Screen.contentArea]] to know the safe to draw area.\n */\n DisplayMode[\"FitScreenAndZoom\"] = \"FitScreenAndZoom\";\n /**\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\n *\n * You may want to center your game here is an example\n * ```html\n * \n * \n *
\n * \n *
\n * \n * ```\n *\n * ```css\n * // css\n * main {\n * display: flex;\n * align-items: center;\n * justify-content: center;\n * height: 100%;\n * width: 100%;\n * }\n * ```\n */\n DisplayMode[\"FitScreen\"] = \"FitScreen\";\n /**\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\n */\n DisplayMode[\"FillScreen\"] = \"FillScreen\";\n /**\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\n */\n DisplayMode[\"FitContainer\"] = \"FitContainer\";\n /**\n * Use the parent DOM container's css width/height for the game resolution dynamically\n */\n DisplayMode[\"FillContainer\"] = \"FillContainer\";\n})(DisplayMode || (DisplayMode = {}));\n/**\n * Convenience class for quick resolutions\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\n */\nclass Resolution {\n /* istanbul ignore next */\n static get SVGA() {\n return { width: 800, height: 600 };\n }\n /* istanbul ignore next */\n static get Standard() {\n return { width: 1920, height: 1080 };\n }\n /* istanbul ignore next */\n static get Atari2600() {\n return { width: 160, height: 192 };\n }\n /* istanbul ignore next */\n static get GameBoy() {\n return { width: 160, height: 144 };\n }\n /* istanbul ignore next */\n static get GameBoyAdvance() {\n return { width: 240, height: 160 };\n }\n /* istanbul ignore next */\n static get NintendoDS() {\n return { width: 256, height: 192 };\n }\n /* istanbul ignore next */\n static get NES() {\n return { width: 256, height: 224 };\n }\n /* istanbul ignore next */\n static get SNES() {\n return { width: 256, height: 244 };\n }\n}\nconst ScreenEvents = {\n ScreenResize: 'resize',\n PixelRatioChange: 'pixelratio',\n FullScreenChange: 'fullscreen'\n};\n/**\n * The Screen handles all aspects of interacting with the screen for Excalibur.\n */\nclass Screen {\n constructor(options) {\n var _a, _b, _c, _d;\n /**\n * Listen to screen events [[ScreenEvents]]\n */\n this.events = new EventEmitter();\n this._antialiasing = true;\n this._canvasImageRendering = 'auto';\n this._resolutionStack = [];\n this._viewportStack = [];\n this._pixelRatioOverride = null;\n this._isFullScreen = false;\n this._isDisposed = false;\n this._logger = Logger.getInstance();\n this._fullscreenChangeHandler = () => {\n if (this._isDisposed) {\n return;\n }\n this._isFullScreen = !this._isFullScreen;\n this._logger.debug('Fullscreen Change', this._isFullScreen);\n this.events.emit('fullscreen', {\n fullscreen: this.isFullScreen\n });\n };\n this._pixelRatioChangeHandler = () => {\n if (this._isDisposed) {\n return;\n }\n this._logger.debug('Pixel Ratio Change', window.devicePixelRatio);\n this._listenForPixelRatio();\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this.applyResolutionAndViewport();\n this.events.emit('pixelratio', {\n pixelRatio: this.pixelRatio\n });\n };\n this._resizeHandler = () => {\n if (this._isDisposed) {\n return;\n }\n const parent = this.parent;\n this._logger.debug('View port resized');\n this._setResolutionAndViewportByDisplayMode(parent);\n this.applyResolutionAndViewport();\n // Emit resize event\n this.events.emit('resize', {\n resolution: this.resolution,\n viewport: this.viewport\n });\n };\n // Asking the window.devicePixelRatio is expensive we do it once\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this._contentArea = new BoundingBox();\n this.viewport = options.viewport;\n this.resolution = (_a = options.resolution) !== null && _a !== void 0 ? _a : { ...this.viewport };\n this._contentResolution = this.resolution;\n this._displayMode = (_b = options.displayMode) !== null && _b !== void 0 ? _b : DisplayMode.Fixed;\n this._canvas = options.canvas;\n this.graphicsContext = options.context;\n this._antialiasing = (_c = options.antialiasing) !== null && _c !== void 0 ? _c : this._antialiasing;\n this._canvasImageRendering = (_d = options.canvasImageRendering) !== null && _d !== void 0 ? _d : this._canvasImageRendering;\n this._browser = options.browser;\n this._pixelRatioOverride = options.pixelRatio;\n this._applyDisplayMode();\n this._listenForPixelRatio();\n this._canvas.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\n this.applyResolutionAndViewport();\n }\n _listenForPixelRatio() {\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) {\n // Safari <=13.1 workaround, remove any existing handlers\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n }\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.addEventListener) {\n this._mediaQueryList.addEventListener('change', this._pixelRatioChangeHandler, { once: true });\n }\n else {\n this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\n }\n }\n dispose() {\n if (!this._isDisposed) {\n // Clean up handlers\n this._isDisposed = true;\n this.events.clear();\n this._browser.window.off('resize', this._resizeHandler);\n this._browser.window.clear();\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n }\n this.parent.removeEventListener('resize', this._resizeHandler);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.removeEventListener) {\n this._mediaQueryList.removeEventListener('change', this._pixelRatioChangeHandler);\n }\n else {\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n }\n this._canvas.removeEventListener('fullscreenchange', this._fullscreenChangeHandler);\n this._canvas = null;\n }\n }\n _calculateDevicePixelRatio() {\n if (window.devicePixelRatio < 1) {\n return 1;\n }\n const devicePixelRatio = window.devicePixelRatio || 1;\n return devicePixelRatio;\n }\n /**\n * Returns the computed pixel ratio, first using any override, then the device pixel ratio\n */\n get pixelRatio() {\n if (this._pixelRatioOverride) {\n return this._pixelRatioOverride;\n }\n return this._devicePixelRatio;\n }\n /**\n * Get or set the pixel ratio override\n *\n * You will need to call applyResolutionAndViewport() affect change on the screen\n */\n get pixelRatioOverride() {\n return this._pixelRatioOverride;\n }\n set pixelRatioOverride(value) {\n this._pixelRatioOverride = value;\n }\n get isHiDpi() {\n return this.pixelRatio !== 1;\n }\n get displayMode() {\n return this._displayMode;\n }\n get canvas() {\n return this._canvas;\n }\n get parent() {\n switch (this.displayMode) {\n case DisplayMode.FillContainer:\n case DisplayMode.FitContainer:\n case DisplayMode.FitContainerAndFill:\n case DisplayMode.FitContainerAndZoom:\n return this.canvas.parentElement || document.body;\n default:\n return window;\n }\n }\n get resolution() {\n return this._resolution;\n }\n set resolution(resolution) {\n this._resolution = resolution;\n }\n get viewport() {\n if (this._viewport) {\n return this._viewport;\n }\n return this._resolution;\n }\n set viewport(viewport) {\n this._viewport = viewport;\n }\n get aspectRatio() {\n return this._resolution.width / this._resolution.height;\n }\n get scaledWidth() {\n return this._resolution.width * this.pixelRatio;\n }\n get scaledHeight() {\n return this._resolution.height * this.pixelRatio;\n }\n setCurrentCamera(camera) {\n this._camera = camera;\n }\n pushResolutionAndViewport() {\n this._resolutionStack.push(this.resolution);\n this._viewportStack.push(this.viewport);\n this.resolution = { ...this.resolution };\n this.viewport = { ...this.viewport };\n }\n peekViewport() {\n return this._viewportStack[this._viewportStack.length - 1];\n }\n peekResolution() {\n return this._resolutionStack[this._resolutionStack.length - 1];\n }\n popResolutionAndViewport() {\n if (this._resolutionStack.length && this._viewportStack.length) {\n this.resolution = this._resolutionStack.pop();\n this.viewport = this._viewportStack.pop();\n }\n }\n applyResolutionAndViewport() {\n this._canvas.width = this.scaledWidth;\n this._canvas.height = this.scaledHeight;\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n const supported = this.graphicsContext.checkIfResolutionSupported({\n width: this.scaledWidth,\n height: this.scaledHeight\n });\n if (!supported) {\n this._logger.warnOnce(`The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` +\n ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' +\n ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' +\n ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).');\n }\n }\n if (this._canvasImageRendering === 'auto') {\n this._canvas.style.imageRendering = 'auto';\n }\n else {\n this._canvas.style.imageRendering = 'pixelated';\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\n if (this._canvas.style.imageRendering === '') {\n this._canvas.style.imageRendering = 'crisp-edges';\n }\n }\n this._canvas.style.width = this.viewport.width + 'px';\n this._canvas.style.height = this.viewport.height + 'px';\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\n this.graphicsContext.updateViewport(this.resolution);\n this.graphicsContext.resetTransform();\n this.graphicsContext.smoothing = this._antialiasing;\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) {\n this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\n }\n }\n get antialiasing() {\n return this._antialiasing;\n }\n set antialiasing(isSmooth) {\n this._antialiasing = isSmooth;\n this.graphicsContext.smoothing = this._antialiasing;\n }\n /**\n * Returns true if excalibur is fullscreen using the browser fullscreen api\n */\n get isFullScreen() {\n return this._isFullScreen;\n }\n /**\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\n * For example, wire this to a user click handler.\n *\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\n * @param elementId\n */\n goFullScreen(elementId) {\n if (elementId) {\n const maybeElement = document.getElementById(elementId);\n if (maybeElement) {\n if (!maybeElement.getAttribute('ex-fullscreen-listener')) {\n maybeElement.setAttribute('ex-fullscreen-listener', 'true');\n maybeElement.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\n }\n const fullscreenPromise = maybeElement.requestFullscreen();\n return fullscreenPromise;\n }\n }\n return this._canvas.requestFullscreen();\n }\n /**\n * Requests to exit fullscreen using the browser fullscreen api\n */\n exitFullScreen() {\n return document.exitFullscreen();\n }\n /**\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\n * Excalibur screen space.\n *\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\n * bottom right corner (resolutionX, resolutionY). When using *AndFill suffixed display modes screen space\n * (0, 0) is the top left of the safe content area bounding box not the viewport.\n * @param point\n */\n pageToScreenCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n if (!this._isFullScreen) {\n newX -= getPosition(this._canvas).x;\n newY -= getPosition(this._canvas).y;\n }\n // if fullscreen api on it centers with black bars\n // we need to adjust the screen to world coordinates in this case\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = ((newY - screenMarginY) / screenHeight) * this.viewport.height;\n newX = (newX / window.innerWidth) * this.viewport.width;\n }\n else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = ((newX - screenMarginX) / screenWidth) * this.viewport.width;\n newY = (newY / window.innerHeight) * this.viewport.height;\n }\n }\n newX = (newX / this.viewport.width) * this.resolution.width;\n newY = (newY / this.viewport.height) * this.resolution.height;\n // offset by content area\n newX = newX - this.contentArea.left;\n newY = newY - this.contentArea.top;\n return new Vector(newX, newY);\n }\n /**\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\n * this is where html elements might live if you want to position them relative to Excalibur.\n *\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\n * bottom right corner (resolutionX, resolutionY)\n * @param point\n */\n screenToPageCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n // no need to offset by content area, drawing is already offset by this\n newX = (newX / this.resolution.width) * this.viewport.width;\n newY = (newY / this.resolution.height) * this.viewport.height;\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = (newY / this.viewport.height) * screenHeight + screenMarginY;\n newX = (newX / this.viewport.width) * window.innerWidth;\n }\n else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = (newX / this.viewport.width) * screenWidth + screenMarginX;\n newY = (newY / this.viewport.height) * window.innerHeight;\n }\n }\n if (!this._isFullScreen) {\n newX += getPosition(this._canvas).x;\n newY += getPosition(this._canvas).y;\n }\n return new Vector(newX, newY);\n }\n /**\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\n *\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\n * and extends infinitely out relative from the [[Camera]].\n * @param point Screen coordinate to convert\n */\n screenToWorldCoordinates(point) {\n // offset by content area\n point = point.add(vec(this.contentArea.left, this.contentArea.top));\n // the only difference between screen & world is the camera transform\n if (this._camera) {\n return this._camera.inverse.multiply(point);\n }\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n /**\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\n *\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\n * @param point World coordinate to convert\n */\n worldToScreenCoordinates(point) {\n if (this._camera) {\n return this._camera.transform.multiply(point);\n }\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n pageToWorldCoordinates(point) {\n const screen = this.pageToScreenCoordinates(point);\n return this.screenToWorldCoordinates(screen);\n }\n worldToPageCoordinates(point) {\n const screen = this.worldToScreenCoordinates(point);\n return this.screenToPageCoordinates(screen);\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen\n * and the bottom right corner of the screen.\n *\n * World bounds are in world coordinates, useful for culling objects offscreen that are in world space\n */\n getWorldBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Half)\n .scale(vec(1 / this._camera.zoom, 1 / this._camera.zoom))\n .rotate(this._camera.rotation)\n .translate(this._camera.pos);\n return bounds;\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen and the bottom right corner of the screen.\n *\n * Screen bounds are in screen coordinates, useful for culling objects offscreen that are in screen space\n */\n getScreenBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero, Vector.Zero);\n return bounds;\n }\n /**\n * The width of the game canvas in pixels (physical width component of the\n * resolution of the canvas element)\n */\n get canvasWidth() {\n return this.canvas.width;\n }\n /**\n * Returns half width of the game canvas in pixels (half physical width component)\n */\n get halfCanvasWidth() {\n return this.canvas.width / 2;\n }\n /**\n * The height of the game canvas in pixels, (physical height component of\n * the resolution of the canvas element)\n */\n get canvasHeight() {\n return this.canvas.height;\n }\n /**\n * Returns half height of the game canvas in pixels (half physical height component)\n */\n get halfCanvasHeight() {\n return this.canvas.height / 2;\n }\n /**\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get drawWidth() {\n if (this._camera) {\n return this.resolution.width / this._camera.zoom;\n }\n return this.resolution.width;\n }\n /**\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get halfDrawWidth() {\n return this.drawWidth / 2;\n }\n /**\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get drawHeight() {\n if (this._camera) {\n return this.resolution.height / this._camera.zoom;\n }\n return this.resolution.height;\n }\n /**\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get halfDrawHeight() {\n return this.drawHeight / 2;\n }\n /**\n * Returns screen center coordinates including zoom and device pixel ratio.\n */\n get center() {\n return vec(this.halfDrawWidth, this.halfDrawHeight);\n }\n /**\n * Returns the content area in screen space where it is safe to place content\n */\n get contentArea() {\n return this._contentArea;\n }\n _computeFit() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (window.innerWidth / aspect < window.innerHeight) {\n adjustedWidth = window.innerWidth;\n adjustedHeight = window.innerWidth / aspect;\n }\n else {\n adjustedWidth = window.innerHeight * aspect;\n adjustedHeight = window.innerHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _computeFitScreenAndFill() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitContainerAndFill() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n const parent = this.canvas.parentElement;\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitAndFill(vw, vh) {\n this.viewport = {\n width: vw,\n height: vh\n };\n // if the current screen aspectRatio is less than the original aspectRatio\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\n // compute new resolution to match the original aspect ratio\n this.resolution = {\n width: vw * this._contentResolution.width / vw,\n height: vw * this._contentResolution.width / vw * vh / vw\n };\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\n this._contentArea = new BoundingBox({\n top: clip,\n left: 0,\n right: this._contentResolution.width,\n bottom: this.resolution.height - clip\n });\n }\n else {\n this.resolution = {\n width: vh * this._contentResolution.height / vh * vw / vh,\n height: vh * this._contentResolution.height / vh\n };\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\n this._contentArea = new BoundingBox({\n top: 0,\n left: clip,\n right: this.resolution.width - clip,\n bottom: this._contentResolution.height\n });\n }\n }\n _computeFitScreenAndZoom() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n this.canvas.style.position = 'absolute';\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitContainerAndZoom() {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n this.canvas.style.position = 'absolute';\n const parent = this.canvas.parentElement;\n parent.style.position = 'relative';\n parent.style.overflow = 'hidden';\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitAndZoom(vw, vh) {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (vw / aspect < vh) {\n adjustedWidth = vw;\n adjustedHeight = vw / aspect;\n }\n else {\n adjustedWidth = vh * aspect;\n adjustedHeight = vh;\n }\n const scaleX = vw / adjustedWidth;\n const scaleY = vh / adjustedHeight;\n const maxScaleFactor = Math.max(scaleX, scaleY);\n const zoomedWidth = adjustedWidth * maxScaleFactor;\n const zoomedHeight = adjustedHeight * maxScaleFactor;\n // Center zoomed dimension if bigger than the screen\n if (zoomedWidth > vw) {\n this.canvas.style.left = -(zoomedWidth - vw) / 2 + 'px';\n }\n else {\n this.canvas.style.left = '';\n }\n if (zoomedHeight > vh) {\n this.canvas.style.top = -(zoomedHeight - vh) / 2 + 'px';\n }\n else {\n this.canvas.style.top = '';\n }\n this.viewport = {\n width: zoomedWidth,\n height: zoomedHeight\n };\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\n // return safe area\n if (this.viewport.width > vw) {\n const clip = (this.viewport.width - vw) / this.viewport.width * this.resolution.width;\n bounds.top = 0;\n bounds.left = clip / 2;\n bounds.right = this.resolution.width - clip / 2;\n bounds.bottom = this.resolution.height;\n }\n if (this.viewport.height > vh) {\n const clip = (this.viewport.height - vh) / this.viewport.height * this.resolution.height;\n bounds.top = clip / 2;\n bounds.left = 0;\n bounds.bottom = this.resolution.height - clip / 2;\n bounds.right = this.resolution.width;\n }\n this._contentArea = bounds;\n }\n _computeFitContainer() {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n const parent = this.canvas.parentElement;\n if (parent.clientWidth / aspect < parent.clientHeight) {\n adjustedWidth = parent.clientWidth;\n adjustedHeight = parent.clientWidth / aspect;\n }\n else {\n adjustedWidth = parent.clientHeight * aspect;\n adjustedHeight = parent.clientHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _applyDisplayMode() {\n this._setResolutionAndViewportByDisplayMode(this.parent);\n // watch resizing\n if (this.parent instanceof Window) {\n this._browser.window.on('resize', this._resizeHandler);\n }\n else {\n this._resizeObserver = new ResizeObserver(() => {\n this._resizeHandler();\n });\n this._resizeObserver.observe(this.parent);\n }\n this.parent.addEventListener('resize', this._resizeHandler);\n }\n /**\n * Sets the resolution and viewport based on the selected display mode.\n */\n _setResolutionAndViewportByDisplayMode(parent) {\n if (this.displayMode === DisplayMode.FillContainer) {\n this.resolution = {\n width: parent.clientWidth,\n height: parent.clientHeight\n };\n this.viewport = this.resolution;\n }\n if (this.displayMode === DisplayMode.FillScreen) {\n document.body.style.margin = '0px';\n document.body.style.overflow = 'hidden';\n this.resolution = {\n width: parent.innerWidth,\n height: parent.innerHeight\n };\n this.viewport = this.resolution;\n }\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n if (this.displayMode === DisplayMode.FitScreen) {\n this._computeFit();\n }\n if (this.displayMode === DisplayMode.FitContainer) {\n this._computeFitContainer();\n }\n if (this.displayMode === DisplayMode.FitScreenAndFill) {\n this._computeFitScreenAndFill();\n }\n if (this.displayMode === DisplayMode.FitContainerAndFill) {\n this._computeFitContainerAndFill();\n }\n if (this.displayMode === DisplayMode.FitScreenAndZoom) {\n this._computeFitScreenAndZoom();\n }\n if (this.displayMode === DisplayMode.FitContainerAndZoom) {\n this._computeFitContainerAndZoom();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Sound/AudioContext.ts\n/**\n * Internal class used to build instances of AudioContext\n */\n/* istanbul ignore next */\nclass AudioContextFactory {\n static create() {\n if (!this._INSTANCE) {\n if (window.AudioContext || window.webkitAudioContext) {\n this._INSTANCE = new AudioContext();\n }\n }\n return this._INSTANCE;\n }\n}\nAudioContextFactory._INSTANCE = null;\n\n;// CONCATENATED MODULE: ./Util/WebAudio.ts\n\n\n/**\n * Patch for detecting legacy web audio in browsers\n * @internal\n * @param source\n */\nfunction isLegacyWebAudioSource(source) {\n return !!source.playbackState;\n}\nclass WebAudio {\n /**\n * Play an empty sound to unlock Safari WebAudio context. Call this function\n * right after a user interaction event.\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\n */\n static unlock() {\n const promise = new Promise((resolve, reject) => {\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) {\n return resolve(true);\n }\n const unlockTimeoutTimer = setTimeout(() => {\n Logger.getInstance().warn('Excalibur was unable to unlock the audio context, audio probably will not play in this browser.');\n resolve(false);\n }, 200);\n const audioContext = AudioContextFactory.create();\n audioContext.resume().then(() => {\n // create empty buffer and play it\n const buffer = audioContext.createBuffer(1, 1, 22050);\n const source = audioContext.createBufferSource();\n let ended = false;\n source.buffer = buffer;\n source.connect(audioContext.destination);\n source.onended = () => (ended = true);\n source.start(0);\n // by checking the play state after some time, we know if we're really unlocked\n setTimeout(() => {\n if (isLegacyWebAudioSource(source)) {\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) {\n WebAudio._UNLOCKED = true;\n }\n }\n else {\n if (audioContext.currentTime > 0 || ended) {\n WebAudio._UNLOCKED = true;\n }\n }\n }, 0);\n clearTimeout(unlockTimeoutTimer);\n resolve(true);\n }, () => {\n reject();\n });\n });\n return promise;\n }\n static isUnlocked() {\n return this._UNLOCKED;\n }\n}\nWebAudio._UNLOCKED = false;\n\n;// CONCATENATED MODULE: ./Graphics/Raster.ts\n\n\n\n\n\n\n/**\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\n *\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\n */\nclass Raster extends Graphic {\n constructor(options) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;\n super(omit(options, ['width', 'height'])); // rasters do some special sauce with width/height\n this.filtering = null;\n this.lineCap = 'butt';\n this.quality = 1;\n this._dirty = true;\n this._smoothing = false;\n this._color = watch(Color.Black, () => this.flagDirty());\n this._lineWidth = 1;\n this._lineDash = [];\n this._padding = 0;\n if (options) {\n this.quality = (_a = options.quality) !== null && _a !== void 0 ? _a : this.quality;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n this.strokeColor = options === null || options === void 0 ? void 0 : options.strokeColor;\n this.smoothing = (_c = options.smoothing) !== null && _c !== void 0 ? _c : this.smoothing;\n this.lineWidth = (_d = options.lineWidth) !== null && _d !== void 0 ? _d : this.lineWidth;\n this.lineDash = (_e = options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineCap = (_f = options.lineCap) !== null && _f !== void 0 ? _f : this.lineCap;\n this.padding = (_g = options.padding) !== null && _g !== void 0 ? _g : this.padding;\n this.filtering = (_h = options.filtering) !== null && _h !== void 0 ? _h : this.filtering;\n }\n this._bitmap = document.createElement('canvas');\n // get the default canvas width/height as a fallback\n const bitmapWidth = (_j = options === null || options === void 0 ? void 0 : options.width) !== null && _j !== void 0 ? _j : this._bitmap.width;\n const bitmapHeight = (_k = options === null || options === void 0 ? void 0 : options.height) !== null && _k !== void 0 ? _k : this._bitmap.height;\n this.width = bitmapWidth;\n this.height = bitmapHeight;\n const maybeCtx = this._bitmap.getContext('2d');\n if (!maybeCtx) {\n /* istanbul ignore next */\n throw new Error('Browser does not support 2d canvas drawing, cannot create Raster graphic');\n }\n else {\n this._ctx = maybeCtx;\n }\n }\n cloneRasterOptions() {\n return {\n color: this.color ? this.color.clone() : null,\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\n smoothing: this.smoothing,\n lineWidth: this.lineWidth,\n lineDash: this.lineDash,\n lineCap: this.lineCap,\n quality: this.quality,\n padding: this.padding\n };\n }\n /**\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\n */\n get dirty() {\n return this._dirty;\n }\n /**\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\n * This should be called any time the graphics state changes such that it affects the outputted drawing\n */\n flagDirty() {\n this._dirty = true;\n }\n /**\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n *\n * Any `padding`s or `quality` set will be factored into the width\n */\n get width() {\n return Math.abs(this._getTotalWidth() * this.scale.x);\n }\n set width(value) {\n value /= Math.abs(this.scale.x);\n this._bitmap.width = value;\n this._originalWidth = value;\n this.flagDirty();\n }\n /**\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n *\n * Any `padding` or `quality` set will be factored into the height\n */\n get height() {\n return Math.abs(this._getTotalHeight() * this.scale.y);\n }\n set height(value) {\n value /= Math.abs(this.scale.y);\n this._bitmap.height = value;\n this._originalHeight = value;\n this.flagDirty();\n }\n _getTotalWidth() {\n var _a;\n return (((_a = this._originalWidth) !== null && _a !== void 0 ? _a : this._bitmap.width) + this.padding * 2) * 1;\n }\n _getTotalHeight() {\n var _a;\n return (((_a = this._originalHeight) !== null && _a !== void 0 ? _a : this._bitmap.height) + this.padding * 2) * 1;\n }\n /**\n * Returns the local bounds of the Raster including the padding\n */\n get localBounds() {\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\n }\n /**\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\n * to be flagged dirty causing a re-raster on the next draw.\n */\n get smoothing() {\n return this._smoothing;\n }\n set smoothing(value) {\n this._smoothing = value;\n this.flagDirty();\n }\n /**\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */\n get color() {\n return this._color;\n }\n set color(value) {\n this.flagDirty();\n this._color = watch(value, () => this.flagDirty());\n }\n /**\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */\n get strokeColor() {\n return this._strokeColor;\n }\n set strokeColor(value) {\n this.flagDirty();\n this._strokeColor = watch(value, () => this.flagDirty());\n }\n /**\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\n * flagged dirty causing a re-raster on the next draw.\n */\n get lineWidth() {\n return this._lineWidth;\n }\n set lineWidth(value) {\n this._lineWidth = value;\n this.flagDirty();\n }\n get lineDash() {\n return this._lineDash;\n }\n set lineDash(value) {\n this._lineDash = value;\n this.flagDirty();\n }\n get padding() {\n return this._padding;\n }\n set padding(value) {\n this._padding = value;\n this.flagDirty();\n }\n /**\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\n */\n rasterize() {\n this._dirty = false;\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\n this._ctx.save();\n this._applyRasterProperties(this._ctx);\n this.execute(this._ctx);\n this._ctx.restore();\n }\n _applyRasterProperties(ctx) {\n var _a, _b, _c;\n this._bitmap.width = this._getTotalWidth() * this.quality;\n this._bitmap.height = this._getTotalHeight() * this.quality;\n // Do a bad thing to pass the filtering as an attribute\n this._bitmap.setAttribute('filtering', this.filtering);\n this._bitmap.setAttribute('forceUpload', 'true');\n ctx.scale(this.quality, this.quality);\n ctx.translate(this.padding, this.padding);\n ctx.imageSmoothingEnabled = this.smoothing;\n ctx.lineWidth = this.lineWidth;\n ctx.setLineDash((_a = this.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.lineCap = this.lineCap;\n ctx.strokeStyle = (_b = this.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = (_c = this.color) === null || _c === void 0 ? void 0 : _c.toString();\n }\n _drawImage(ex, x, y) {\n if (this._dirty) {\n this.rasterize();\n }\n ex.scale(1 / this.quality, 1 / this.quality);\n ex.drawImage(this._bitmap, x, y);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Canvas.ts\n\n/**\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\n *\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\n *\n * **Low performance API**\n */\nclass Canvas extends Raster {\n /**\n * Return the 2D graphics context of this canvas\n */\n get ctx() {\n return this._ctx;\n }\n constructor(_options) {\n super(_options);\n this._options = _options;\n }\n clone() {\n return new Canvas({\n ...this._options,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n var _a, _b;\n if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.draw) {\n (_b = this._options) === null || _b === void 0 ? void 0 : _b.draw(ctx);\n }\n if (!this._options.cache) {\n this.flagDirty();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Interfaces/AudioImplementation.ts\nclass ExResponse {\n}\nExResponse.type = {\n any: '',\n blob: 'blob',\n json: 'json',\n text: 'text',\n document: 'document',\n arraybuffer: 'arraybuffer'\n};\n\n;// CONCATENATED MODULE: ./Util/StateMachine.ts\nclass StateMachine {\n constructor() {\n this.states = new Map();\n }\n get currentState() {\n return this._currentState;\n }\n set currentState(state) {\n this._currentState = state;\n }\n static create(machineDescription, data) {\n const machine = new StateMachine();\n machine.data = data;\n for (const stateName in machineDescription.states) {\n machine.states.set(stateName, {\n name: stateName,\n ...machineDescription.states[stateName]\n });\n }\n // validate transitions are states\n for (const state of machine.states.values()) {\n for (const transitionState of state.transitions) {\n if (transitionState === '*') {\n continue;\n }\n if (!machine.states.has(transitionState)) {\n throw Error(`Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`);\n }\n }\n }\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\n return machine;\n }\n in(state) {\n return this.currentState.name === state;\n }\n go(stateName, eventData) {\n var _a, _b;\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes('*')) {\n const potentialNewState = this.states.get(stateName);\n if (this.currentState.onExit) {\n const canExit = (_a = this.currentState) === null || _a === void 0 ? void 0 : _a.onExit({ to: potentialNewState.name, data: this.data });\n if (canExit === false) {\n return false;\n }\n }\n if (potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter) {\n const canEnter = potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter({ from: this.currentState.name, eventData, data: this.data });\n if (canEnter === false) {\n return false;\n }\n }\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\n this.currentState = potentialNewState;\n if ((_b = this.currentState) === null || _b === void 0 ? void 0 : _b.onState) {\n this.currentState.onState();\n }\n return true;\n }\n return false;\n }\n update(elapsedMs) {\n if (this.currentState.onUpdate) {\n this.currentState.onUpdate(this.data, elapsedMs);\n }\n }\n save(saveKey) {\n localStorage.setItem(saveKey, JSON.stringify({\n currentState: this.currentState.name,\n data: this.data\n }));\n }\n restore(saveKey) {\n const state = JSON.parse(localStorage.getItem(saveKey));\n this.currentState = this.states.get(state.currentState);\n this.data = state.data;\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Sound/WebAudioInstance.ts\n\n\n\n\n/**\n * Internal class representing a Web Audio AudioBufferSourceNode instance\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\n */\nclass WebAudioInstance {\n _createNewBufferSource() {\n this._instance = this._audioContext.createBufferSource();\n this._instance.buffer = this._src;\n this._instance.loop = this.loop;\n this._instance.playbackRate.value = this._playbackRate;\n this._instance.connect(this._volumeNode);\n this._volumeNode.connect(this._audioContext.destination);\n }\n _handleEnd() {\n if (!this.loop) {\n this._instance.onended = () => {\n this._playingFuture.resolve(true);\n };\n }\n }\n set loop(value) {\n this._loop = value;\n if (this._instance) {\n this._instance.loop = value;\n if (!this.loop) {\n this._instance.onended = () => {\n this._playingFuture.resolve(true);\n };\n }\n }\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n value = clamp(value, 0, 1.0);\n this._volume = value;\n if (this._stateMachine.in('PLAYING') && this._volumeNode.gain.setTargetAtTime) {\n // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\n // This exponential ramp provides a more pleasant transition in gain\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\n }\n else {\n this._volumeNode.gain.value = value;\n }\n }\n get volume() {\n return this._volume;\n }\n /**\n * Returns the set duration to play, otherwise returns the total duration if unset\n */\n get duration() {\n var _a;\n return (_a = this._duration) !== null && _a !== void 0 ? _a : this.getTotalPlaybackDuration();\n }\n /**\n * Set the duration that this audio should play.\n *\n * Note: if you seek to a specific point the duration will start from that point, for example\n *\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\n */\n set duration(duration) {\n this._duration = duration;\n }\n constructor(_src) {\n this._src = _src;\n this._audioContext = AudioContextFactory.create();\n this._volumeNode = this._audioContext.createGain();\n this._playingFuture = new Future();\n this._stateMachine = StateMachine.create({\n start: 'STOPPED',\n states: {\n PLAYING: {\n onEnter: ({ data }) => {\n // Buffer nodes are single use\n this._createNewBufferSource();\n this._handleEnd();\n if (this.loop) {\n // when looping don't set a duration\n this._instance.start(0, data.pausedAt * this._playbackRate);\n }\n else {\n this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\n }\n data.startedAt = (this._audioContext.currentTime - data.pausedAt);\n data.pausedAt = 0;\n },\n onState: () => this._playStarted(),\n onExit: ({ to }) => {\n // If you've exited early only resolve if explicitly STOPPED\n if (to === 'STOPPED') {\n this._playingFuture.resolve(true);\n }\n // Whenever you're not playing... you stop!\n this._instance.onended = null; // disconnect the wired on-end handler\n this._instance.disconnect();\n this._instance.stop(0);\n this._instance = null;\n },\n transitions: ['STOPPED', 'PAUSED', 'SEEK']\n },\n SEEK: {\n onEnter: ({ eventData: position, data }) => {\n data.pausedAt = (position !== null && position !== void 0 ? position : 0) / this._playbackRate;\n data.startedAt = 0;\n },\n transitions: ['*']\n },\n STOPPED: {\n onEnter: ({ data }) => {\n data.pausedAt = 0;\n data.startedAt = 0;\n this._playingFuture.resolve(true);\n },\n transitions: ['PLAYING', 'PAUSED', 'SEEK']\n },\n PAUSED: {\n onEnter: ({ data }) => {\n // Playback rate will be a scale factor of how fast/slow the audio is being played\n // default is 1.0\n // we need to invert it to get the time scale\n data.pausedAt = (this._audioContext.currentTime - data.startedAt);\n },\n transitions: ['PLAYING', 'STOPPED', 'SEEK']\n }\n }\n }, {\n startedAt: 0,\n pausedAt: 0\n });\n this._volume = 1;\n this._loop = false;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n this._playStarted = () => { };\n this._playbackRate = 1.0;\n this._createNewBufferSource();\n }\n isPlaying() {\n return this._stateMachine.in('PLAYING');\n }\n isPaused() {\n return this._stateMachine.in('PAUSED') || this._stateMachine.in('SEEK');\n }\n isStopped() {\n return this._stateMachine.in('STOPPED');\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n play(playStarted = () => { }) {\n this._playStarted = playStarted;\n this._stateMachine.go('PLAYING');\n return this._playingFuture.promise;\n }\n pause() {\n this._stateMachine.go('PAUSED');\n }\n stop() {\n this._stateMachine.go('STOPPED');\n }\n seek(position) {\n this._stateMachine.go('PAUSED');\n this._stateMachine.go('SEEK', position);\n }\n getTotalPlaybackDuration() {\n return this._src.duration;\n }\n getPlaybackPosition() {\n const { pausedAt, startedAt } = this._stateMachine.data;\n if (pausedAt) {\n return pausedAt * this._playbackRate;\n }\n if (startedAt) {\n return (this._audioContext.currentTime - startedAt) * this._playbackRate;\n }\n return 0;\n }\n set playbackRate(playbackRate) {\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\n }\n get playbackRate() {\n return this._instance.playbackRate.value;\n }\n}\n\n;// CONCATENATED MODULE: ./Events.ts\nvar EventTypes;\n(function (EventTypes) {\n EventTypes[\"Kill\"] = \"kill\";\n EventTypes[\"PreKill\"] = \"prekill\";\n EventTypes[\"PostKill\"] = \"postkill\";\n EventTypes[\"PreDraw\"] = \"predraw\";\n EventTypes[\"PostDraw\"] = \"postdraw\";\n EventTypes[\"PreDebugDraw\"] = \"predebugdraw\";\n EventTypes[\"PostDebugDraw\"] = \"postdebugdraw\";\n EventTypes[\"PreUpdate\"] = \"preupdate\";\n EventTypes[\"PostUpdate\"] = \"postupdate\";\n EventTypes[\"PreFrame\"] = \"preframe\";\n EventTypes[\"PostFrame\"] = \"postframe\";\n EventTypes[\"PreCollision\"] = \"precollision\";\n EventTypes[\"CollisionStart\"] = \"collisionstart\";\n EventTypes[\"CollisionEnd\"] = \"collisionend\";\n EventTypes[\"PostCollision\"] = \"postcollision\";\n EventTypes[\"Initialize\"] = \"initialize\";\n EventTypes[\"Activate\"] = \"activate\";\n EventTypes[\"Deactivate\"] = \"deactivate\";\n EventTypes[\"ExitViewport\"] = \"exitviewport\";\n EventTypes[\"EnterViewport\"] = \"enterviewport\";\n EventTypes[\"ExitTrigger\"] = \"exit\";\n EventTypes[\"EnterTrigger\"] = \"enter\";\n EventTypes[\"Connect\"] = \"connect\";\n EventTypes[\"Disconnect\"] = \"disconnect\";\n EventTypes[\"Button\"] = \"button\";\n EventTypes[\"Axis\"] = \"axis\";\n EventTypes[\"Visible\"] = \"visible\";\n EventTypes[\"Hidden\"] = \"hidden\";\n EventTypes[\"Start\"] = \"start\";\n EventTypes[\"Stop\"] = \"stop\";\n EventTypes[\"PointerUp\"] = \"pointerup\";\n EventTypes[\"PointerDown\"] = \"pointerdown\";\n EventTypes[\"PointerMove\"] = \"pointermove\";\n EventTypes[\"PointerEnter\"] = \"pointerenter\";\n EventTypes[\"PointerLeave\"] = \"pointerleave\";\n EventTypes[\"PointerCancel\"] = \"pointercancel\";\n EventTypes[\"PointerWheel\"] = \"pointerwheel\";\n EventTypes[\"Up\"] = \"up\";\n EventTypes[\"Down\"] = \"down\";\n EventTypes[\"Move\"] = \"move\";\n EventTypes[\"Enter\"] = \"enter\";\n EventTypes[\"Leave\"] = \"leave\";\n EventTypes[\"Cancel\"] = \"cancel\";\n EventTypes[\"Wheel\"] = \"wheel\";\n EventTypes[\"Press\"] = \"press\";\n EventTypes[\"Release\"] = \"release\";\n EventTypes[\"Hold\"] = \"hold\";\n EventTypes[\"PointerDragStart\"] = \"pointerdragstart\";\n EventTypes[\"PointerDragEnd\"] = \"pointerdragend\";\n EventTypes[\"PointerDragEnter\"] = \"pointerdragenter\";\n EventTypes[\"PointerDragLeave\"] = \"pointerdragleave\";\n EventTypes[\"PointerDragMove\"] = \"pointerdragmove\";\n EventTypes[\"ActionStart\"] = \"actionstart\";\n EventTypes[\"ActionComplete\"] = \"actioncomplete\";\n})(EventTypes || (EventTypes = {}));\n/**\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\n * some events are unique to a type, others are not.\n *\n */\nclass GameEvent {\n constructor() {\n this._bubbles = true;\n }\n /**\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\n * to all actors that apply.\n */\n get bubbles() {\n return this._bubbles;\n }\n set bubbles(value) {\n this._bubbles = value;\n }\n /**\n * Prevents event from bubbling\n */\n stopPropagation() {\n this.bubbles = false;\n }\n}\n/**\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\n */\nclass KillEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'prekill' event is emitted directly before an actor is killed.\n */\nclass PreKillEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'postkill' event is emitted directly after the actor is killed.\n */\nclass PostKillEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'start' event is emitted on engine when has started and is ready for interaction.\n */\nclass GameStartEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\n */\nclass GameStopEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\n * transform so that all drawing takes place with the actor as the origin.\n *\n */\nclass PreDrawEvent extends GameEvent {\n constructor(ctx, delta, target) {\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\n * transform so that all drawing takes place with the actor as the origin.\n *\n */\nclass PostDrawEvent extends GameEvent {\n constructor(ctx, delta, target) {\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'pretransformdraw' event is emitted on actors/entities before any graphics transforms have taken place.\n * Useful if you need to completely customize the draw or modify the transform before drawing in the draw step (for example needing\n * latest camera positions)\n *\n */\nclass PreTransformDrawEvent extends GameEvent {\n constructor(ctx, delta, target) {\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'posttransformdraw' event is emitted on actors/entities after all graphics have been draw and transforms reset.\n * Useful if you need to completely custom the draw after everything is done.\n *\n */\nclass PostTransformDrawEvent extends GameEvent {\n constructor(ctx, delta, target) {\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\n */\nclass PreDebugDrawEvent extends GameEvent {\n constructor(ctx, target) {\n super();\n this.ctx = ctx;\n this.target = target;\n }\n}\n/**\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\n */\nclass PostDebugDrawEvent extends GameEvent {\n constructor(ctx, target) {\n super();\n this.ctx = ctx;\n this.target = target;\n }\n}\n/**\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\n */\nclass PreUpdateEvent extends GameEvent {\n constructor(engine, delta, target) {\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\n */\nclass PostUpdateEvent extends GameEvent {\n constructor(engine, delta, target) {\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n}\n/**\n * The 'preframe' event is emitted on the engine, before the frame begins.\n */\nclass PreFrameEvent extends GameEvent {\n constructor(engine, prevStats) {\n super();\n this.engine = engine;\n this.prevStats = prevStats;\n this.target = engine;\n }\n}\n/**\n * The 'postframe' event is emitted on the engine, after a frame ends.\n */\nclass PostFrameEvent extends GameEvent {\n constructor(engine, stats) {\n super();\n this.engine = engine;\n this.stats = stats;\n this.target = engine;\n }\n}\n/**\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\n */\nclass GamepadConnectEvent extends GameEvent {\n constructor(index, gamepad) {\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n}\n/**\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\n */\nclass GamepadDisconnectEvent extends GameEvent {\n constructor(index, gamepad) {\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n}\n/**\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\n */\nclass GamepadButtonEvent extends GameEvent {\n /**\n * @param button The Gamepad button\n * @param value A numeric value between 0 and 1\n */\n constructor(button, value, target) {\n super();\n this.button = button;\n this.value = value;\n this.target = target;\n }\n}\n/**\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\n */\nclass GamepadAxisEvent extends GameEvent {\n /**\n * @param axis The Gamepad axis\n * @param value A numeric value between -1 and 1\n */\n constructor(axis, value, target) {\n super();\n this.axis = axis;\n this.value = value;\n this.target = target;\n }\n}\n/**\n * Event received by the [[Engine]] when the browser window is visible on a screen.\n */\nclass VisibleEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\n */\nclass HiddenEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\n */\nclass PreCollisionEvent extends GameEvent {\n /**\n * @param actor The actor the event was thrown on\n * @param other The actor that will collided with the current actor\n * @param side The side that will be collided with the current actor\n * @param intersection Intersection vector\n */\n constructor(actor, other, side, intersection, contact) {\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n this.target = actor;\n }\n}\n/**\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\n */\nclass PostCollisionEvent extends GameEvent {\n /**\n * @param actor The actor the event was thrown on\n * @param other The actor that did collide with the current actor\n * @param side The side that did collide with the current actor\n * @param intersection Intersection vector\n */\n constructor(actor, other, side, intersection, contact) {\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n}\nclass ContactStartEvent {\n constructor(target, other, side, contact) {\n this.target = target;\n this.other = other;\n this.side = side;\n this.contact = contact;\n }\n}\nclass ContactEndEvent {\n constructor(target, other, side, lastContact) {\n this.target = target;\n this.other = other;\n this.side = side;\n this.lastContact = lastContact;\n }\n}\nclass CollisionPreSolveEvent {\n constructor(target, other, side, intersection, contact) {\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n}\nclass CollisionPostSolveEvent {\n constructor(target, other, side, intersection, contact) {\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n}\n/**\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\n */\nclass CollisionStartEvent extends GameEvent {\n /**\n *\n * @param actor\n * @param other\n * @param side\n * @param contact\n */\n constructor(actor, other, side, contact) {\n super();\n this.other = other;\n this.side = side;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n}\n/**\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\n */\nclass CollisionEndEvent extends GameEvent {\n /**\n *\n */\n constructor(actor, other, side, lastContact) {\n super();\n this.other = other;\n this.side = side;\n this.lastContact = lastContact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n}\n/**\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\n */\nclass InitializeEvent extends GameEvent {\n /**\n * @param engine The reference to the current engine\n */\n constructor(engine, target) {\n super();\n this.engine = engine;\n this.target = target;\n }\n}\n/**\n * Event thrown on a [[Scene]] on activation\n */\nclass ActivateEvent extends GameEvent {\n /**\n * @param context The context for the scene activation\n */\n constructor(context, target) {\n super();\n this.context = context;\n this.target = target;\n }\n}\n/**\n * Event thrown on a [[Scene]] on deactivation\n */\nclass DeactivateEvent extends GameEvent {\n /**\n * @param context The context for the scene deactivation\n */\n constructor(context, target) {\n super();\n this.context = context;\n this.target = target;\n }\n}\n/**\n * Event thrown on an [[Actor]] when the graphics bounds completely leaves the screen.\n */\nclass ExitViewPortEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\n/**\n * Event thrown on an [[Actor]] when any part of the graphics bounds are on screen.\n */\nclass EnterViewPortEvent extends GameEvent {\n constructor(target) {\n super();\n this.target = target;\n }\n}\nclass EnterTriggerEvent extends GameEvent {\n constructor(target, actor) {\n super();\n this.target = target;\n this.actor = actor;\n }\n}\nclass ExitTriggerEvent extends GameEvent {\n constructor(target, actor) {\n super();\n this.target = target;\n this.actor = actor;\n }\n}\n/**\n * Event thrown on an [[Actor]] when an action starts.\n */\nclass ActionStartEvent extends GameEvent {\n constructor(action, target) {\n super();\n this.action = action;\n this.target = target;\n }\n}\n/**\n * Event thrown on an [[Actor]] when an action completes.\n */\nclass ActionCompleteEvent extends GameEvent {\n constructor(action, target) {\n super();\n this.action = action;\n this.target = target;\n }\n}\n\n;// CONCATENATED MODULE: ./Events/MediaEvents.ts\n\nclass MediaEvent extends GameEvent {\n /**\n * Media event cannot bubble\n */\n set bubbles(_value) {\n // stubbed\n }\n /**\n * Media event cannot bubble\n */\n get bubbles() {\n return false;\n }\n /**\n * Media event cannot bubble, so they have no path\n */\n get _path() {\n return null;\n }\n /**\n * Media event cannot bubble, so they have no path\n */\n set _path(_val) {\n // stubbed\n }\n constructor(target, _name = 'MediaEvent') {\n super();\n this.target = target;\n this._name = _name;\n }\n /**\n * Prevents event from bubbling\n */\n stopPropagation() {\n /**\n * Stub\n */\n }\n /**\n * Action, that calls when event happens\n */\n action() {\n /**\n * Stub\n */\n }\n /**\n * Propagate event further through event path\n */\n propagate() {\n /**\n * Stub\n */\n }\n layPath(_actor) {\n /**\n * Stub\n */\n }\n}\nclass NativeSoundEvent extends MediaEvent {\n constructor(target, track) {\n super(target, 'NativeSoundEvent');\n this.track = track;\n }\n}\nclass NativeSoundProcessedEvent extends MediaEvent {\n constructor(target, _processedData) {\n super(target, 'NativeSoundProcessedEvent');\n this._processedData = _processedData;\n this.data = this._processedData;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Sound.ts\n\n/**\n * Whether or not the browser can play this file as HTML5 Audio\n */\nfunction canPlayFile(file) {\n try {\n const a = new Audio();\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\n const type = file.match(filetype)[1];\n if (a.canPlayType('audio/' + type)) {\n return true;\n }\n else {\n return false;\n }\n }\n catch (e) {\n Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e);\n return false;\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Sound/Sound.ts\n\n\n\n\n\n\n\n\nconst SoundEvents = {\n VolumeChange: 'volumechange',\n Processed: 'processed',\n Pause: 'pause',\n Stop: 'stop',\n PlaybackEnd: 'playbackend',\n Resume: 'resume',\n PlaybackStart: 'playbackstart'\n};\n/**\n * The [[Sound]] object allows games built in Excalibur to load audio\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\n */\nclass Sound {\n /**\n * Indicates whether the clip should loop when complete\n * @param value Set the looping flag\n */\n set loop(value) {\n this._loop = value;\n for (const track of this._tracks) {\n track.loop = this._loop;\n }\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._loop);\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n this._volume = value;\n for (const track of this._tracks) {\n track.volume = this._volume;\n }\n this.events.emit('volumechange', new NativeSoundEvent(this));\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._volume);\n }\n get volume() {\n return this._volume;\n }\n /**\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\n */\n get duration() {\n return this._duration;\n }\n /**\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\n *\n * Note: if you seek to a specific point the duration will start from that point, for example\n *\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\n */\n set duration(duration) {\n this._duration = duration;\n }\n /**\n * Return array of Current AudioInstances playing or being paused\n */\n get instances() {\n return this._tracks;\n }\n get path() {\n return this._resource.path;\n }\n set path(val) {\n this._resource.path = val;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */\n get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\n */\n constructor(...paths) {\n this.events = new EventEmitter();\n this.logger = Logger.getInstance();\n this._loop = false;\n this._volume = 1;\n this._isStopped = false;\n // private _isPaused = false;\n this._tracks = [];\n this._wasPlayingOnHidden = false;\n this._playbackRate = 1.0;\n this._audioContext = AudioContextFactory.create();\n this._resource = new Resource('', ExResponse.type.arraybuffer);\n /**\n * Chrome : MP3, WAV, Ogg\n * Firefox : WAV, Ogg,\n * IE : MP3, WAV coming soon\n * Safari MP3, WAV, Ogg\n */\n for (const path of paths) {\n if (canPlayFile(path)) {\n this.path = path;\n break;\n }\n }\n if (!this.path) {\n this.logger.warn('This browser does not support any of the audio files specified:', paths.join(', '));\n this.logger.warn('Attempting to use', paths[0]);\n this.path = paths[0]; // select the first specified\n }\n }\n isLoaded() {\n return !!this.data;\n }\n async load() {\n var _a, _b;\n if (this.data) {\n return this.data;\n }\n const arraybuffer = await this._resource.load();\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\n this._duration = (_b = (_a = this._duration) !== null && _a !== void 0 ? _a : audiobuffer === null || audiobuffer === void 0 ? void 0 : audiobuffer.duration) !== null && _b !== void 0 ? _b : undefined;\n this.events.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer));\n return this.data = audiobuffer;\n }\n async decodeAudio(data) {\n try {\n return await this._audioContext.decodeAudioData(data.slice(0));\n }\n catch (e) {\n this.logger.error('Unable to decode ' +\n ' this browser may not fully support this format, or the file may be corrupt, ' +\n 'if this is an mp3 try removing id3 tags and album art from the file.');\n return await Promise.reject();\n }\n }\n wireEngine(engine) {\n if (engine) {\n this._engine = engine;\n this._engine.on('hidden', () => {\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\n this._wasPlayingOnHidden = true;\n this.pause();\n }\n });\n this._engine.on('visible', () => {\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.play();\n this._wasPlayingOnHidden = false;\n }\n });\n this._engine.on('start', () => {\n this._isStopped = false;\n });\n this._engine.on('stop', () => {\n this.stop();\n this._isStopped = true;\n });\n }\n }\n /**\n * Returns how many instances of the sound are currently playing\n */\n instanceCount() {\n return this._tracks.length;\n }\n /**\n * Whether or not the sound is playing right now\n */\n isPlaying() {\n return this._tracks.some((t) => t.isPlaying());\n }\n isPaused() {\n return this._tracks.some(t => t.isPaused());\n }\n isStopped() {\n return this._tracks.some(t => t.isStopped());\n }\n /**\n * Play the sound, returns a promise that resolves when the sound is done playing\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\n */\n play(volume) {\n if (!this.isLoaded()) {\n this.logger.warn('Cannot start playing. Resource', this.path, 'is not loaded yet');\n return Promise.resolve(true);\n }\n if (this._isStopped) {\n this.logger.warn('Cannot start playing. Engine is in a stopped state.');\n return Promise.resolve(false);\n }\n this.volume = volume || this.volume;\n if (this.isPaused()) {\n return this._resumePlayback();\n }\n else {\n return this._startPlayback();\n }\n }\n /**\n * Stop the sound, and do not rewind\n */\n pause() {\n if (!this.isPlaying()) {\n return;\n }\n for (const track of this._tracks) {\n track.pause();\n }\n this.events.emit('pause', new NativeSoundEvent(this));\n this.logger.debug('Paused all instances of sound', this.path);\n }\n /**\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\n */\n stop() {\n for (const track of this._tracks) {\n track.stop();\n }\n this.events.emit('stop', new NativeSoundEvent(this));\n this._tracks.length = 0;\n this.logger.debug('Stopped all instances of sound', this.path);\n }\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(playbackRate) {\n this._playbackRate = playbackRate;\n this._tracks.forEach(t => {\n t.playbackRate = this._playbackRate;\n });\n }\n seek(position, trackId = 0) {\n if (this._tracks.length === 0) {\n this._getTrackInstance(this.data);\n }\n this._tracks[trackId].seek(position);\n }\n getTotalPlaybackDuration() {\n if (!this.isLoaded()) {\n this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.` +\n `Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`);\n return 0;\n }\n return this.data.duration;\n }\n /**\n * Return the current playback time of the playing track in seconds from the start.\n *\n * Optionally specify the track to query if multiple are playing at once.\n * @param trackId\n */\n getPlaybackPosition(trackId = 0) {\n if (this._tracks.length) {\n return this._tracks[trackId].getPlaybackPosition();\n }\n return 0;\n }\n /**\n * Get Id of provided AudioInstance in current trackList\n * @param track [[Audio]] which Id is to be given\n */\n getTrackId(track) {\n return this._tracks.indexOf(track);\n }\n async _resumePlayback() {\n if (this.isPaused) {\n const resumed = [];\n // ensure we resume *current* tracks (if paused)\n for (const track of this._tracks) {\n resumed.push(track.play().then(() => {\n this._tracks.splice(this.getTrackId(track), 1);\n return true;\n }));\n }\n this.events.emit('resume', new NativeSoundEvent(this));\n this.logger.debug('Resuming paused instances for sound', this.path, this._tracks);\n // resolve when resumed tracks are done\n await Promise.all(resumed);\n }\n return true;\n }\n /**\n * Starts playback, returns a promise that resolves when playback is complete\n */\n async _startPlayback() {\n const track = this._getTrackInstance(this.data);\n const complete = await track.play(() => {\n this.events.emit('playbackstart', new NativeSoundEvent(this, track));\n this.logger.debug('Playing new instance for sound', this.path);\n });\n this.events.emit('playbackend', new NativeSoundEvent(this, track));\n // cleanup any done tracks\n const trackId = this.getTrackId(track);\n if (trackId !== -1) {\n this._tracks.splice(trackId, 1);\n }\n return complete;\n }\n _getTrackInstance(data) {\n const newTrack = new WebAudioInstance(data);\n newTrack.loop = this.loop;\n newTrack.volume = this.volume;\n newTrack.duration = this.duration;\n newTrack.playbackRate = this._playbackRate;\n this._tracks.push(newTrack);\n return newTrack;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n}\n\n;// CONCATENATED MODULE: ./Director/DefaultLoader.ts\n\n\n\n\n\n\n\n\n\nconst LoaderEvents = {\n // Add event types here\n BeforeLoad: 'beforeload',\n AfterLoad: 'afterload',\n UserAction: 'useraction',\n LoadResourceStart: 'loadresourcestart',\n LoadResourceEnd: 'loadresourceend'\n};\n/**\n * Returns true if the constructor is for an Excalibur Loader\n */\nfunction isLoaderConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n}\nclass DefaultLoader {\n get resources() {\n return this._resources;\n }\n /**\n * @param options Optionally provide the list of resources you want to load at constructor time\n */\n constructor(options) {\n var _a;\n this.events = new EventEmitter();\n this.canvas = new Canvas({\n filtering: ImageFiltering.Blended,\n smoothing: true,\n cache: false,\n draw: this.onDraw.bind(this)\n });\n this._resources = [];\n this._numLoaded = 0;\n this._totalTimeMs = 0;\n this._loadingFuture = new Future();\n if (options && ((_a = options.loadables) === null || _a === void 0 ? void 0 : _a.length)) {\n this.addResources(options.loadables);\n }\n }\n /**\n * Called by the engine before loading\n * @param engine\n */\n onInitialize(engine) {\n this.engine = engine;\n this.canvas.width = this.engine.screen.canvasWidth;\n this.canvas.height = this.engine.screen.canvasHeight;\n }\n /**\n * Return a promise that resolves when the user interacts with the loading screen in some way, usually a click.\n *\n * It's important to implement this in order to unlock the audio context in the browser. Browsers automatically prevent\n * audio from playing until the user performs an action.\n *\n */\n async onUserAction() {\n return await Promise.resolve();\n }\n /**\n * Overridable lifecycle method, called directly before loading starts\n */\n async onBeforeLoad() {\n // override me\n }\n /**\n * Overridable lifecycle method, called after loading has completed\n */\n async onAfterLoad() {\n // override me\n await delay(500, this.engine.clock); // avoid a flicker\n }\n /**\n * Add a resource to the loader to load\n * @param loadable Resource to add\n */\n addResource(loadable) {\n this._resources.push(loadable);\n }\n /**\n * Add a list of resources to the loader to load\n * @param loadables The list of resources to load\n */\n addResources(loadables) {\n let i = 0;\n const len = loadables.length;\n for (i; i < len; i++) {\n this.addResource(loadables[i]);\n }\n }\n markResourceComplete() {\n this._numLoaded++;\n }\n /**\n * Returns the progress of the loader as a number between [0, 1] inclusive.\n */\n get progress() {\n const total = this._resources.length;\n return total > 0 ? clamp(this._numLoaded, 0, total) / total : 1;\n }\n /**\n * Returns true if the loader has completely loaded all resources\n */\n isLoaded() {\n return this._numLoaded === this._resources.length;\n }\n /**\n * Optionally override the onUpdate\n * @param engine\n * @param elapsedMilliseconds\n */\n onUpdate(engine, elapsedMilliseconds) {\n this._totalTimeMs += elapsedMilliseconds;\n // override me\n }\n /**\n * Optionally override the onDraw\n */\n onDraw(ctx) {\n const seconds = this._totalTimeMs / 1000;\n ctx.fillStyle = Color.Black.toRGBA();\n ctx.fillRect(0, 0, this.engine.screen.drawWidth, this.engine.screen.drawHeight);\n ctx.save();\n ctx.translate(this.engine.screen.center.x, this.engine.screen.center.y);\n const speed = seconds * 10;\n ctx.strokeStyle = 'white';\n ctx.lineWidth = 10;\n ctx.lineCap = 'round';\n ctx.arc(0, 0, 40, speed, speed + (Math.PI * 3 / 2));\n ctx.stroke();\n ctx.fillStyle = 'white';\n ctx.font = '16px sans-serif';\n const text = (this.progress * 100).toFixed(0) + '%';\n const textbox = ctx.measureText(text);\n const width = Math.abs(textbox.actualBoundingBoxLeft) + Math.abs(textbox.actualBoundingBoxRight);\n const height = Math.abs(textbox.actualBoundingBoxAscent) + Math.abs(textbox.actualBoundingBoxDescent);\n ctx.fillText(text, -width / 2, height / 2); // center\n ctx.restore();\n }\n areResourcesLoaded() {\n return this._loadingFuture.promise;\n }\n /**\n * Not meant to be overridden\n *\n * Begin loading all of the supplied resources, returning a promise\n * that resolves when loading of all is complete AND the user has interacted with the loading screen\n */\n async load() {\n await this.onBeforeLoad();\n this.events.emit('beforeload');\n this.canvas.flagDirty();\n await Promise.all(this._resources.map(async (r) => {\n this.events.emit('loadresourcestart', r);\n await r.load().finally(() => {\n // capture progress\n this._numLoaded++;\n this.canvas.flagDirty();\n this.events.emit('loadresourceend', r);\n });\n }));\n // Wire all sound to the engine\n for (const resource of this._resources) {\n if (resource instanceof Sound) {\n resource.wireEngine(this.engine);\n }\n }\n this._loadingFuture.resolve();\n this.canvas.flagDirty();\n // Unlock browser AudioContext in after user gesture\n // See: https://github.com/excaliburjs/Excalibur/issues/262\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\n await this.onUserAction();\n this.events.emit('useraction');\n await WebAudio.unlock();\n await this.onAfterLoad();\n this.events.emit('afterload');\n return (this.data = this._resources);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n}\n\n;// CONCATENATED MODULE: ./Util/DrawUtil.ts\n\n/* istanbul ignore next */\n/**\n * Draw a line on canvas context\n * @param ctx The canvas context\n * @param color The color of the line\n * @param x1 The start x coordinate\n * @param y1 The start y coordinate\n * @param x2 The ending x coordinate\n * @param y2 The ending y coordinate\n * @param thickness The line thickness\n * @param cap The [[LineCapStyle]] (butt, round, or square)\n */\nfunction line(ctx, color = Color.Red, x1, y1, x2, y2, thickness = 1, cap = 'butt') {\n ctx.save();\n ctx.beginPath();\n ctx.lineWidth = thickness;\n ctx.lineCap = cap;\n ctx.strokeStyle = color.toString();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.closePath();\n ctx.stroke();\n ctx.restore();\n}\n/* istanbul ignore next */\n/**\n * Draw the vector as a point onto the canvas.\n */\nfunction point(ctx, color = Color.Red, point) {\n ctx.beginPath();\n ctx.strokeStyle = color.toString();\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\n ctx.closePath();\n ctx.stroke();\n}\n/**\n * Draw the vector as a line onto the canvas starting a origin point.\n */\n/* istanbul ignore next */\n/**\n *\n */\nfunction vector(ctx, color, origin, vector, scale = 1.0) {\n const c = color ? color.toString() : 'blue';\n const v = vector.scale(scale);\n ctx.beginPath();\n ctx.strokeStyle = c;\n ctx.moveTo(origin.x, origin.y);\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\n ctx.closePath();\n ctx.stroke();\n}\n/**\n * Draw a round rectangle on a canvas context\n * @param ctx The canvas context\n * @param x The top-left x coordinate\n * @param y The top-left y coordinate\n * @param width The width of the rectangle\n * @param height The height of the rectangle\n * @param radius The border radius of the rectangle\n * @param stroke The [[Color]] to stroke rectangle with\n * @param fill The [[Color]] to fill rectangle with\n */\nfunction roundRect(ctx, x, y, width, height, radius = 5, stroke = Color.White, fill = null) {\n let br;\n if (typeof radius === 'number') {\n br = { tl: radius, tr: radius, br: radius, bl: radius };\n }\n else {\n const defaultRadius = { tl: 0, tr: 0, br: 0, bl: 0 };\n for (const prop in defaultRadius) {\n if (defaultRadius.hasOwnProperty(prop)) {\n const side = prop;\n br[side] = radius[side] || defaultRadius[side];\n }\n }\n }\n ctx.beginPath();\n ctx.moveTo(x + br.tl, y);\n ctx.lineTo(x + width - br.tr, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\n ctx.lineTo(x + width, y + height - br.br);\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\n ctx.lineTo(x + br.bl, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\n ctx.lineTo(x, y + br.tl);\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n}\n/**\n *\n */\nfunction circle(ctx, x, y, radius, stroke = Color.White, fill = null) {\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, Math.PI * 2);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n}\n\n;// CONCATENATED MODULE: ./Director/Loader.logo.png\n/* harmony default export */ const Loader_logo = (\"data:image/png;base64,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\");\n// EXTERNAL MODULE: ./Director/Loader.css\nvar Director_Loader = __webpack_require__(7835);\n;// CONCATENATED MODULE: ./Director/Loader.ts\n\n\n\n\n\n\n\n\n/**\n * Pre-loading assets\n *\n * The loader provides a mechanism to preload multiple resources at\n * one time. The loader must be passed to the engine in order to\n * trigger the loading progress bar.\n *\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\n *\n * ## Example: Pre-loading resources for a game\n *\n * ```js\n * // create a loader\n * var loader = new ex.Loader();\n *\n * // create a resource dictionary (best practice is to keep a separate file)\n * var resources = {\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\n * };\n *\n * // loop through dictionary and add to loader\n * for (var loadable in resources) {\n * if (resources.hasOwnProperty(loadable)) {\n * loader.addResource(resources[loadable]);\n * }\n * }\n *\n * // start game\n * game.start(loader).then(function () {\n * console.log(\"Game started!\");\n * });\n * ```\n *\n * ## Customize the Loader\n *\n * The loader can be customized to show different, text, logo, background color, and button.\n *\n * ```typescript\n * const loader = new ex.Loader([playerTexture]);\n *\n * // The loaders button text can simply modified using this\n * loader.playButtonText = 'Start the best game ever';\n *\n * // The logo can be changed by inserting a base64 image string here\n *\n * loader.logo = 'data:image/png;base64,iVBORw...';\n * loader.logoWidth = 15;\n * loader.logoHeight = 14;\n *\n * // The background color can be changed like so by supplying a valid CSS color string\n *\n * loader.backgroundColor = 'red'\n * loader.backgroundColor = '#176BAA'\n *\n * // To build a completely new button\n * loader.startButtonFactory = () => {\n * let myButton = document.createElement('button');\n * myButton.textContent = 'The best button';\n * return myButton;\n * };\n *\n * engine.start(loader).then(() => {});\n * ```\n */\nclass Loader extends DefaultLoader {\n get _image() {\n if (!this._imageElement) {\n this._imageElement = new Image();\n this._imageElement.src = this.logo;\n }\n return this._imageElement;\n }\n get playButtonRootElement() {\n return this._playButtonRootElement;\n }\n get playButtonElement() {\n return this._playButtonElement;\n }\n get _playButton() {\n const existingRoot = document.getElementById('excalibur-play-root');\n if (existingRoot) {\n this._playButtonRootElement = existingRoot;\n }\n if (!this._playButtonRootElement) {\n this._playButtonRootElement = document.createElement('div');\n this._playButtonRootElement.id = 'excalibur-play-root';\n this._playButtonRootElement.style.position = 'absolute';\n document.body.appendChild(this._playButtonRootElement);\n }\n if (!this._styleBlock) {\n this._styleBlock = document.createElement('style');\n this._styleBlock.textContent = this._playButtonStyles;\n document.head.appendChild(this._styleBlock);\n }\n if (!this._playButtonElement) {\n this._playButtonElement = this.startButtonFactory();\n this._playButtonRootElement.appendChild(this._playButtonElement);\n }\n return this._playButtonElement;\n }\n constructor(loadablesOrOptions) {\n const options = Array.isArray(loadablesOrOptions) ? {\n loadables: loadablesOrOptions\n } : loadablesOrOptions;\n super(options);\n this._logger = Logger.getInstance();\n this._originalOptions = { loadables: [] };\n this.events = new EventEmitter();\n this._playButtonShown = false;\n // logo drawing stuff\n // base64 string encoding of the excalibur logo (logo-white.png)\n this.logo = Loader_logo;\n this.logoWidth = 468;\n this.logoHeight = 118;\n /**\n * Gets or sets the color of the loading bar, default is [[Color.White]]\n */\n this.loadingBarColor = Color.White;\n /**\n * Gets or sets the background color of the loader as a hex string\n */\n this.backgroundColor = '#176BAA';\n this.suppressPlayButton = false;\n /** Loads the css from Loader.css */\n this._playButtonStyles = Director_Loader/* default */.Z.toString();\n /**\n * Get/set play button text\n */\n this.playButtonText = 'Play game';\n /**\n * Return a html button element for excalibur to use as a play button\n */\n this.startButtonFactory = () => {\n let buttonElement = document.getElementById('excalibur-play');\n if (!buttonElement) {\n buttonElement = document.createElement('button');\n }\n buttonElement.id = 'excalibur-play';\n buttonElement.textContent = this.playButtonText;\n buttonElement.style.display = 'none';\n return buttonElement;\n };\n this._configuredPixelRatio = null;\n this._originalOptions = { ...Loader._DEFAULT_LOADER_OPTIONS, ...options };\n }\n onInitialize(engine) {\n this.engine = engine;\n this.screen = engine.screen;\n this.canvas.width = this.engine.canvas.width;\n this.canvas.height = this.engine.canvas.height;\n }\n /**\n * Shows the play button and returns a promise that resolves when clicked\n */\n async showPlayButton() {\n var _a, _b;\n if (this.suppressPlayButton) {\n this.hidePlayButton();\n // Delay is to give the logo a chance to show, otherwise don't delay\n await delay(500, (_a = this.engine) === null || _a === void 0 ? void 0 : _a.clock);\n }\n else {\n const resizeHandler = () => {\n try {\n this._positionPlayButton();\n }\n catch (_a) {\n // swallow if can't position\n }\n ;\n };\n if ((_b = this.engine) === null || _b === void 0 ? void 0 : _b.browser) {\n this.engine.browser.window.on('resize', resizeHandler);\n }\n this._playButtonShown = true;\n this._playButton.style.display = 'block';\n document.body.addEventListener('keyup', (evt) => {\n if (evt.key === 'Enter') {\n this._playButton.click();\n }\n });\n this._positionPlayButton();\n const playButtonClicked = new Promise(resolve => {\n const startButtonHandler = (e) => {\n var _a;\n // We want to stop propagation to keep bubbling to the engine pointer handlers\n e.stopPropagation();\n // Hide Button after click\n this.hidePlayButton();\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.browser) {\n this.engine.browser.window.off('resize', resizeHandler);\n }\n if (this._originalOptions.fullscreenAfterLoad) {\n try {\n this._logger.info('requesting fullscreen');\n if (this._originalOptions.fullscreenContainer instanceof HTMLElement) {\n this._originalOptions.fullscreenContainer.requestFullscreen();\n }\n else {\n this.engine.screen.goFullScreen(this._originalOptions.fullscreenContainer);\n }\n }\n catch (error) {\n this._logger.error('could not go fullscreen', error);\n }\n }\n resolve();\n };\n this._playButton.addEventListener('click', startButtonHandler);\n this._playButton.addEventListener('touchend', startButtonHandler);\n this._playButton.addEventListener('pointerup', startButtonHandler);\n });\n return await playButtonClicked;\n }\n }\n hidePlayButton() {\n this._playButtonShown = false;\n this._playButton.style.display = 'none';\n }\n /**\n * Clean up generated elements for the loader\n */\n dispose() {\n if (this._playButtonRootElement.parentElement) {\n this._playButtonRootElement.removeChild(this._playButtonElement);\n document.body.removeChild(this._playButtonRootElement);\n document.head.removeChild(this._styleBlock);\n this._playButtonRootElement = null;\n this._playButtonElement = null;\n this._styleBlock = null;\n }\n }\n async onUserAction() {\n var _a;\n // short delay in showing the button for aesthetics\n await delay(200, (_a = this.engine) === null || _a === void 0 ? void 0 : _a.clock);\n this.canvas.flagDirty();\n // show play button\n await this.showPlayButton();\n }\n async onBeforeLoad() {\n var _a;\n this._configuredPixelRatio = this.screen.pixelRatioOverride;\n // Push the current user entered resolution/viewport\n this.screen.pushResolutionAndViewport();\n // Configure resolution for loader, it expects resolution === viewport\n this.screen.resolution = this.screen.viewport;\n this.screen.pixelRatioOverride = 1;\n this.screen.applyResolutionAndViewport();\n this.canvas.width = this.engine.canvas.width;\n this.canvas.height = this.engine.canvas.height;\n await ((_a = this._image) === null || _a === void 0 ? void 0 : _a.decode()); // decode logo if it exists\n }\n // eslint-disable-next-line require-await\n async onAfterLoad() {\n this.screen.pixelRatioOverride = this._configuredPixelRatio;\n this.screen.popResolutionAndViewport();\n this.screen.applyResolutionAndViewport();\n this.dispose();\n }\n _positionPlayButton() {\n if (this.engine) {\n const screenHeight = this.engine.screen.viewport.height;\n const screenWidth = this.engine.screen.viewport.width;\n if (this._playButtonRootElement) {\n const left = this.engine.canvas.offsetLeft;\n const top = this.engine.canvas.offsetTop;\n const buttonWidth = this._playButton.clientWidth;\n const buttonHeight = this._playButton.clientHeight;\n if (this.playButtonPosition) {\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\n }\n else {\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\n }\n }\n }\n }\n /**\n * Loader draw function. Draws the default Excalibur loading screen.\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\n * to customize the drawing, or just override entire method.\n */\n onDraw(ctx) {\n const canvasHeight = this.engine.canvasHeight / this.engine.pixelRatio;\n const canvasWidth = this.engine.canvasWidth / this.engine.pixelRatio;\n this._positionPlayButton();\n ctx.fillStyle = this.backgroundColor;\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\n let logoY = canvasHeight / 2;\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\n let logoX = canvasWidth / 2 - width / 2;\n if (this.logoPosition) {\n logoX = this.logoPosition.x;\n logoY = this.logoPosition.y;\n }\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\n const oldAntialias = this.engine.getAntialiasing();\n this.engine.setAntialiasing(true);\n if (!this.logoPosition) {\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\n }\n else {\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\n }\n // loading box\n if (!this.suppressPlayButton && this._playButtonShown) {\n this.engine.setAntialiasing(oldAntialias);\n return;\n }\n let loadingX = logoX;\n let loadingY = logoY;\n if (this.loadingBarPosition) {\n loadingX = this.loadingBarPosition.x;\n loadingY = this.loadingBarPosition.y;\n }\n ctx.lineWidth = 2;\n roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\n const progress = width * this.progress;\n const margin = 5;\n const progressWidth = progress - margin * 2;\n const height = 20 - margin * 2;\n roundRect(ctx, loadingX + margin, loadingY + margin, progressWidth > 10 ? progressWidth : 10, height, 5, null, this.loadingBarColor);\n this.engine.setAntialiasing(oldAntialias);\n }\n}\nLoader._DEFAULT_LOADER_OPTIONS = {\n loadables: [],\n fullscreenAfterLoad: false,\n fullscreenContainer: undefined\n};\n\n;// CONCATENATED MODULE: ./Util/Detector.ts\n\n/**\n * This is the list of features that will be used to log the supported\n * features to the console when Detector.logBrowserFeatures() is called.\n */\nconst REPORTED_FEATURES = {\n webgl: 'WebGL',\n webaudio: 'WebAudio',\n gamepadapi: 'Gamepad API'\n};\n/**\n * Excalibur internal feature detection helper class\n */\nclass Detector {\n constructor() {\n this._features = null;\n this.failedTests = [];\n // critical browser features required for ex to run\n this._criticalTests = {\n // Test canvas/2d context support\n canvasSupport: function () {\n const elem = document.createElement('canvas');\n return !!(elem.getContext && elem.getContext('2d'));\n },\n // Test array buffer support ex uses for downloading binary data\n arrayBufferSupport: function () {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', '/');\n try {\n xhr.responseType = 'arraybuffer';\n }\n catch (e) {\n return false;\n }\n return xhr.responseType === 'arraybuffer';\n },\n // Test data urls ex uses for sprites\n dataUrlSupport: function () {\n const canvas = document.createElement('canvas');\n return canvas.toDataURL('image/png').indexOf('data:image/png') === 0;\n },\n // Test object url support for loading\n objectUrlSupport: function () {\n return 'URL' in window && 'revokeObjectURL' in URL && 'createObjectURL' in URL;\n },\n // RGBA support for colors\n rgbaSupport: function () {\n const style = document.createElement('a').style;\n style.cssText = 'background-color:rgba(150,255,150,.5)';\n return ('' + style.backgroundColor).indexOf('rgba') > -1;\n }\n };\n // warnings excalibur performance will be degraded\n this._warningTest = {\n webAudioSupport: function () {\n return !!(window.AudioContext ||\n window.webkitAudioContext ||\n window.mozAudioContext ||\n window.msAudioContext ||\n window.oAudioContext);\n },\n webglSupport: function () {\n const elem = document.createElement('canvas');\n return !!(elem.getContext && elem.getContext('webgl'));\n }\n };\n this._features = this._loadBrowserFeatures();\n }\n /**\n * Returns a map of currently supported browser features. This method\n * treats the features as a singleton and will only calculate feature\n * support if it has not previously been done.\n */\n getBrowserFeatures() {\n if (this._features === null) {\n this._features = this._loadBrowserFeatures();\n }\n return this._features;\n }\n /**\n * Report on non-critical browser support for debugging purposes.\n * Use native browser console colors for visibility.\n */\n logBrowserFeatures() {\n let msg = '%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n';\n const args = ['font-weight: bold; color: navy', 'font-weight: normal; color: inherit'];\n const supported = this.getBrowserFeatures();\n for (const feature of Object.keys(REPORTED_FEATURES)) {\n if (supported[feature]) {\n msg += '(%c\\u2713%c)'; // (✓)\n args.push('font-weight: bold; color: green');\n args.push('font-weight: normal; color: inherit');\n }\n else {\n msg += '(%c\\u2717%c)'; // (✗)\n args.push('font-weight: bold; color: red');\n args.push('font-weight: normal; color: inherit');\n }\n msg += ' ' + REPORTED_FEATURES[feature] + '\\n';\n }\n args.unshift(msg);\n // eslint-disable-next-line no-console\n console.log.apply(console, args);\n }\n /**\n * Executes several IIFE's to get a constant reference to supported\n * features within the current execution context.\n */\n _loadBrowserFeatures() {\n return {\n // IIFE to check canvas support\n canvas: (() => {\n return this._criticalTests.canvasSupport();\n })(),\n // IIFE to check arraybuffer support\n arraybuffer: (() => {\n return this._criticalTests.arrayBufferSupport();\n })(),\n // IIFE to check dataurl support\n dataurl: (() => {\n return this._criticalTests.dataUrlSupport();\n })(),\n // IIFE to check objecturl support\n objecturl: (() => {\n return this._criticalTests.objectUrlSupport();\n })(),\n // IIFE to check rgba support\n rgba: (() => {\n return this._criticalTests.rgbaSupport();\n })(),\n // IIFE to check webaudio support\n webaudio: (() => {\n return this._warningTest.webAudioSupport();\n })(),\n // IIFE to check webgl support\n webgl: (() => {\n return this._warningTest.webglSupport();\n })(),\n // IIFE to check gamepadapi support\n gamepadapi: (() => {\n return !!navigator.getGamepads;\n })()\n };\n }\n test() {\n // Critical test will for ex not to run\n let failedCritical = false;\n for (const test in this._criticalTests) {\n if (!this._criticalTests[test].call(this)) {\n this.failedTests.push(test);\n Logger.getInstance().error('Critical browser feature missing, Excalibur requires:', test);\n failedCritical = true;\n }\n }\n if (failedCritical) {\n return false;\n }\n // Warning tests do not for ex to return false to compatibility\n for (const warning in this._warningTest) {\n if (!this._warningTest[warning]()) {\n Logger.getInstance().warn('Warning browser feature missing, Excalibur will have reduced performance:', warning);\n }\n }\n return true;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/CollisionType.ts\n/**\n * An enum that describes the types of collisions bodies can participate in\n */\nvar CollisionType;\n(function (CollisionType) {\n /**\n * Bodies with the `PreventCollision` setting do not participate in any\n * collisions and do not raise collision events.\n */\n CollisionType[\"PreventCollision\"] = \"PreventCollision\";\n /**\n * Bodies with the `Passive` setting only raise collision events, but are not\n * influenced or moved by other bodies and do not influence or move other bodies.\n * This is useful for use in trigger type behavior.\n */\n CollisionType[\"Passive\"] = \"Passive\";\n /**\n * Bodies with the `Active` setting raise collision events and participate\n * in collisions with other bodies and will be push or moved by bodies sharing\n * the `Active` or `Fixed` setting.\n */\n CollisionType[\"Active\"] = \"Active\";\n /**\n * Bodies with the `Fixed` setting raise collision events and participate in\n * collisions with other bodies. Actors with the `Fixed` setting will not be\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\n * not be pushed or moved by each other, they will not interact except to throw\n * collision events.\n */\n CollisionType[\"Fixed\"] = \"Fixed\";\n})(CollisionType || (CollisionType = {}));\n\n;// CONCATENATED MODULE: ./Math/coord-plane.ts\n/**\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\n */\nvar CoordPlane;\n(function (CoordPlane) {\n /**\n * The world coordinate plane (default) represents world space, any entities drawn with world\n * space move when the camera moves.\n */\n CoordPlane[\"World\"] = \"world\";\n /**\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\n * to screen coordinates ignoring the camera.\n */\n CoordPlane[\"Screen\"] = \"screen\";\n})(CoordPlane || (CoordPlane = {}));\n\n;// CONCATENATED MODULE: ./Math/vector-view.ts\n\nclass VectorView extends Vector {\n constructor(options) {\n super(0, 0);\n this._getX = options.getX;\n this._getY = options.getY;\n this._setX = options.setX;\n this._setY = options.setY;\n }\n get x() {\n return (this._x = this._getX());\n }\n set x(val) {\n this._setX(val);\n this._x = val;\n }\n get y() {\n return (this._y = this._getY());\n }\n set y(val) {\n this._setY(val);\n this._y = val;\n }\n}\n\n;// CONCATENATED MODULE: ./Math/watch-vector.ts\n\n/**\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\n */\nclass WatchVector extends Vector {\n constructor(original, change) {\n super(original.x, original.y);\n this.original = original;\n this.change = change;\n }\n get x() {\n return this._x = this.original.x;\n }\n set x(newX) {\n this.change(newX, this._y);\n this._x = this.original.x = newX;\n }\n get y() {\n return this._y = this.original.y;\n }\n set y(newY) {\n this.change(this._x, newY);\n this._y = this.original.y = newY;\n }\n}\n\n;// CONCATENATED MODULE: ./Math/transform.ts\n\n\n\n\n\nclass transform_Transform {\n constructor() {\n this._parent = null;\n this._children = [];\n this._pos = vec(0, 0);\n this._rotation = 0;\n this._scale = vec(1, 1);\n this._isDirty = false;\n this._isInverseDirty = false;\n this._matrix = AffineMatrix.identity();\n this._inverse = AffineMatrix.identity();\n }\n get parent() {\n return this._parent;\n }\n set parent(transform) {\n if (this._parent) {\n const index = this._parent._children.indexOf(this);\n if (index > -1) {\n this._parent._children.splice(index, 1);\n }\n }\n this._parent = transform;\n if (this._parent) {\n this._parent._children.push(this);\n }\n this.flagDirty();\n }\n get children() {\n return this._children;\n }\n set pos(v) {\n if (!v.equals(this._pos)) {\n this._pos.x = v.x;\n this._pos.y = v.y;\n this.flagDirty();\n }\n }\n get pos() {\n return new WatchVector(this._pos, (x, y) => {\n if (x !== this._pos.x || y !== this._pos.y) {\n this.flagDirty();\n }\n });\n }\n set globalPos(v) {\n let localPos = v.clone();\n if (this.parent) {\n localPos = this.parent.inverse.multiply(v);\n }\n if (!localPos.equals(this._pos)) {\n this._pos = localPos;\n this.flagDirty();\n }\n }\n get globalPos() {\n return new VectorView({\n getX: () => this.matrix.data[4],\n getY: () => this.matrix.data[5],\n setX: (x) => {\n if (this.parent) {\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\n this.pos.x = newX;\n }\n else {\n this.pos.x = x;\n }\n if (x !== this.matrix.data[4]) {\n this.flagDirty();\n }\n },\n setY: (y) => {\n if (this.parent) {\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\n this.pos.y = newY;\n }\n else {\n this.pos.y = y;\n }\n if (y !== this.matrix.data[5]) {\n this.flagDirty();\n }\n }\n });\n }\n set rotation(rotation) {\n const canonRotation = canonicalizeAngle(rotation);\n if (canonRotation !== this._rotation) {\n this.flagDirty();\n }\n this._rotation = canonRotation;\n }\n get rotation() {\n return this._rotation;\n }\n set globalRotation(rotation) {\n let inverseRotation = 0;\n if (this.parent) {\n inverseRotation = this.parent.globalRotation;\n }\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\n if (canonRotation !== this._rotation) {\n this.flagDirty();\n }\n this._rotation = canonRotation;\n }\n get globalRotation() {\n if (this.parent) {\n return this.matrix.getRotation();\n }\n return this.rotation;\n }\n set scale(v) {\n if (!v.equals(this._scale)) {\n this._scale.x = v.x;\n this._scale.y = v.y;\n this.flagDirty();\n }\n }\n get scale() {\n return new WatchVector(this._scale, (x, y) => {\n if (x !== this._scale.x || y !== this._scale.y) {\n this.flagDirty();\n }\n });\n }\n set globalScale(v) {\n let inverseScale = vec(1, 1);\n if (this.parent) {\n inverseScale = this.parent.globalScale;\n }\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\n }\n get globalScale() {\n return new VectorView({\n getX: () => this.parent ? this.matrix.getScaleX() : this.scale.x,\n getY: () => this.parent ? this.matrix.getScaleY() : this.scale.y,\n setX: (x) => {\n if (this.parent) {\n const globalScaleX = this.parent.globalScale.x;\n this.scale.x = x / globalScaleX;\n }\n else {\n this.scale.x = x;\n }\n },\n setY: (y) => {\n if (this.parent) {\n const globalScaleY = this.parent.globalScale.y;\n this.scale.y = y / globalScaleY;\n }\n else {\n this.scale.y = y;\n }\n }\n });\n }\n get matrix() {\n if (this._isDirty) {\n if (this.parent === null) {\n this._matrix = this._calculateMatrix();\n }\n else {\n this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\n }\n this._isDirty = false;\n }\n return this._matrix;\n }\n get inverse() {\n if (this._isInverseDirty) {\n this._inverse = this.matrix.inverse();\n this._isInverseDirty = false;\n }\n return this._inverse;\n }\n _calculateMatrix() {\n const matrix = AffineMatrix.identity()\n .translate(this.pos.x, this.pos.y)\n .rotate(this.rotation)\n .scale(this.scale.x, this.scale.y);\n return matrix;\n }\n flagDirty() {\n this._isDirty = true;\n this._isInverseDirty = true;\n for (let i = 0; i < this._children.length; i++) {\n this._children[i].flagDirty();\n }\n }\n apply(point) {\n return this.matrix.multiply(point);\n }\n applyInverse(point) {\n return this.inverse.multiply(point);\n }\n setTransform(pos, rotation, scale) {\n this._pos.x = pos.x;\n this._pos.y = pos.y;\n this._rotation = canonicalizeAngle(rotation);\n this._scale.x = scale.x;\n this._scale.y = scale.y;\n this.flagDirty();\n }\n /**\n * Clones the current transform\n * **Warning does not clone the parent**\n * @param dest\n */\n clone(dest) {\n const target = dest !== null && dest !== void 0 ? dest : new transform_Transform();\n this._pos.clone(target._pos);\n target._rotation = this._rotation;\n this._scale.clone(target._scale);\n target.flagDirty();\n return target;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Component.ts\n/**\n *\n */\nfunction isComponentCtor(value) {\n return !!value && !!value.prototype && !!value.prototype.constructor;\n}\n/**\n * Type guard to check if a component implements clone\n * @param x\n */\nfunction hasClone(x) {\n return !!(x === null || x === void 0 ? void 0 : x.clone);\n}\n/**\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\n *\n * Implementations of Component must have a zero-arg constructor to support dependencies\n *\n * ```typescript\n * class MyComponent extends ex.Component {\n * // zero arg support required if you want to use component dependencies\n * constructor(public optionalPos?: ex.Vector) {}\n * }\n * ```\n */\nclass Component {\n constructor() {\n // TODO maybe generate a unique id?\n /**\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\n */\n this.owner = undefined;\n }\n /**\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\n */\n clone() {\n const newComponent = new this.constructor();\n for (const prop in this) {\n if (this.hasOwnProperty(prop)) {\n const val = this[prop];\n if (hasClone(val) && prop !== 'owner' && prop !== 'clone') {\n newComponent[prop] = val.clone();\n }\n else {\n newComponent[prop] = val;\n }\n }\n }\n return newComponent;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Observable.ts\n/**\n * Simple Observable implementation\n * @template T is the typescript Type that defines the data being observed\n */\nclass Observable {\n constructor() {\n this.observers = [];\n this.subscriptions = [];\n }\n /**\n * Register an observer to listen to this observable\n * @param observer\n */\n register(observer) {\n this.observers.push(observer);\n }\n /**\n * Register a callback to listen to this observable\n * @param func\n */\n subscribe(func) {\n this.subscriptions.push(func);\n }\n /**\n * Remove an observer from the observable\n * @param observer\n */\n unregister(observer) {\n const i = this.observers.indexOf(observer);\n if (i !== -1) {\n this.observers.splice(i, 1);\n }\n }\n /**\n * Remove a callback that is listening to this observable\n * @param func\n */\n unsubscribe(func) {\n const i = this.subscriptions.indexOf(func);\n if (i !== -1) {\n this.subscriptions.splice(i, 1);\n }\n }\n /**\n * Broadcasts a message to all observers and callbacks\n * @param message\n */\n notifyAll(message) {\n const observersLength = this.observers.length;\n for (let i = 0; i < observersLength; i++) {\n this.observers[i].notify(message);\n }\n const subscriptionsLength = this.subscriptions.length;\n for (let i = 0; i < subscriptionsLength; i++) {\n this.subscriptions[i](message);\n }\n }\n /**\n * Removes all observers and callbacks\n */\n clear() {\n this.observers.length = 0;\n this.subscriptions.length = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Components/TransformComponent.ts\n\n\n\n\n\nclass TransformComponent extends Component {\n constructor() {\n super(...arguments);\n this._logger = Logger.getInstance();\n this._parentComponent = null;\n this._transform = new transform_Transform();\n this._addChildTransform = (child) => {\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) {\n childTxComponent._transform.parent = this._transform;\n childTxComponent._parentComponent = this;\n }\n };\n /**\n * Observable that emits when the z index changes on this component\n */\n this.zIndexChanged$ = new Observable();\n this._z = 0;\n this._coordPlane = CoordPlane.World;\n }\n get() {\n return this._transform;\n }\n onAdd(owner) {\n for (const child of owner.children) {\n this._addChildTransform(child);\n }\n owner.childrenAdded$.subscribe(child => this._addChildTransform(child));\n owner.childrenRemoved$.subscribe(child => {\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) {\n childTxComponent._transform.parent = null;\n childTxComponent._parentComponent = null;\n }\n });\n }\n onRemove(_previousOwner) {\n this._transform.parent = null;\n this._parentComponent = null;\n }\n /**\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\n * For example z=99 would be drawn on top of z=0.\n */\n get z() {\n return this._z;\n }\n set z(val) {\n const oldz = this._z;\n this._z = val;\n if (oldz !== val) {\n this.zIndexChanged$.notifyAll(val);\n }\n }\n /**\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\n */\n get coordPlane() {\n if (this._parentComponent) {\n return this._parentComponent.coordPlane;\n }\n return this._coordPlane;\n }\n set coordPlane(value) {\n var _a;\n if (!this._parentComponent) {\n this._coordPlane = value;\n }\n else {\n this._logger.warn(`Cannot set coordinate plane on child entity ${(_a = this.owner) === null || _a === void 0 ? void 0 : _a.name}, children inherit their coordinate plane from their parents.`);\n }\n }\n get pos() {\n return this._transform.pos;\n }\n set pos(v) {\n this._transform.pos = v;\n }\n get globalPos() {\n return this._transform.globalPos;\n }\n set globalPos(v) {\n this._transform.globalPos = v;\n }\n get rotation() {\n return this._transform.rotation;\n }\n set rotation(rotation) {\n this._transform.rotation = rotation;\n }\n get globalRotation() {\n return this._transform.globalRotation;\n }\n set globalRotation(rotation) {\n this._transform.globalRotation = rotation;\n }\n get scale() {\n return this._transform.scale;\n }\n set scale(v) {\n this._transform.scale = v;\n }\n get globalScale() {\n return this._transform.globalScale;\n }\n set globalScale(v) {\n this._transform.globalScale = v;\n }\n applyInverse(v) {\n return this._transform.applyInverse(v);\n }\n apply(v) {\n return this._transform.apply(v);\n }\n clone() {\n const component = new TransformComponent();\n component._transform = this._transform.clone();\n component._z = this._z;\n return component;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Components/MotionComponent.ts\n\n\nclass MotionComponent extends Component {\n constructor() {\n super(...arguments);\n /**\n * The velocity of an entity in pixels per second\n */\n this.vel = Vector.Zero;\n /**\n * The acceleration of entity in pixels per second^2\n */\n this.acc = Vector.Zero;\n /**\n * The scale rate of change in scale units per second\n */\n this.scaleFactor = Vector.Zero;\n /**\n * The angular velocity which is how quickly the entity is rotating in radians per second\n */\n this.angularVelocity = 0;\n /**\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\n */\n this.torque = 0;\n /**\n * Inertia can be thought of as the resistance to motion\n */\n this.inertia = 1;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Group/CollisionGroupManager.ts\n\n/**\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\n */\nclass CollisionGroupManager {\n /**\n * Create a new named collision group up to a max of 32.\n * @param name Name for the collision group\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\n */\n static create(name, mask) {\n if (this._CURRENT_GROUP > this._MAX_GROUPS) {\n throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\n }\n if (this._GROUPS.get(name)) {\n const existingGroup = this._GROUPS.get(name);\n if (existingGroup.mask === mask) {\n return existingGroup;\n }\n throw new Error(`Collision group ${name} already exists with a different mask!`);\n }\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\n this._CURRENT_BIT = (this._CURRENT_BIT << 1) | 0;\n this._CURRENT_GROUP++;\n this._GROUPS.set(name, group);\n return group;\n }\n /**\n * Get all collision groups currently tracked by excalibur\n */\n static get groups() {\n return Array.from(this._GROUPS.values());\n }\n /**\n * Get a collision group by it's name\n * @param name\n */\n static groupByName(name) {\n return this._GROUPS.get(name);\n }\n /**\n * Resets the managers internal group management state\n */\n static reset() {\n this._GROUPS = new Map();\n this._CURRENT_BIT = this._STARTING_BIT;\n this._CURRENT_GROUP = 1;\n }\n}\n// using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\nCollisionGroupManager._STARTING_BIT = 0b1 | 0;\nCollisionGroupManager._MAX_GROUPS = 32;\nCollisionGroupManager._CURRENT_GROUP = 1;\nCollisionGroupManager._CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\nCollisionGroupManager._GROUPS = new Map();\n\n;// CONCATENATED MODULE: ./Collision/Group/CollisionGroup.ts\n\n/**\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\n *\n * For example:\n *\n * Players have collision group \"player\"\n *\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\n *\n * Enemies have collision group \"enemy\"\n *\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\n *\n * Blocks have collision group \"ground\"\n *\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\n *\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\n * with players and blocks.\n *\n * This is done with bitmasking, see the following pseudo-code\n *\n * PlayerGroup = `0b001`\n * PlayerGroupMask = `0b110`\n *\n * EnemyGroup = `0b010`\n * EnemyGroupMask = `0b101`\n *\n * BlockGroup = `0b100`\n * BlockGroupMask = `0b011`\n *\n * Should Players collide? No because the bitwise mask evaluates to 0\n * `(player1.group & player2.mask) === 0`\n * `(0b001 & 0b110) === 0`\n *\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\n * `(player1.group & enemy1.mask) === 1`\n * `(0b001 & 0b101) === 1`\n *\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\n * `(player1.group & blocks1.mask) === 1`\n * `(0b001 & 0b011) === 1`\n */\nclass CollisionGroup {\n /**\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\n * @param name Name of the collision group\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\n */\n constructor(name, category, mask) {\n this._name = name;\n this._category = category;\n this._mask = mask;\n }\n /**\n * Get the name of the collision group\n */\n get name() {\n return this._name;\n }\n /**\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\n */\n get category() {\n return this._category;\n }\n /**\n * Get the mask for this collision group\n */\n get mask() {\n return this._mask;\n }\n /**\n * Evaluates whether 2 collision groups can collide\n *\n * This means the mask has the same bit set the other category and vice versa\n * @param other CollisionGroup\n */\n canCollide(other) {\n const overlap1 = this.category & other.mask;\n const overlap2 = this.mask & other.category;\n return (overlap1 !== 0) && (overlap2 !== 0);\n }\n /**\n * Inverts the collision group. For example, if before the group specified \"players\",\n * inverting would specify all groups except players\n * @returns CollisionGroup\n */\n invert() {\n const group = CollisionGroupManager.create('~(' + this.name + ')', ~this.mask | 0);\n group._category = ~this.category;\n return group;\n }\n /**\n * Combine collision groups with each other. The new group includes all of the previous groups.\n * @param collisionGroups\n */\n static combine(collisionGroups) {\n const combinedName = collisionGroups.map((c) => c.name).join('+');\n const combinedCategory = collisionGroups.reduce((current, g) => g.category | current, 0b0);\n const combinedMask = ~combinedCategory;\n return CollisionGroupManager.create(combinedName, combinedMask);\n }\n /**\n * Creates a collision group that collides with the listed groups\n * @param collisionGroups\n */\n static collidesWith(collisionGroups) {\n const combinedName = `collidesWith(${collisionGroups.map((c) => c.name).join('+')})`;\n const combinedMask = collisionGroups.reduce((current, g) => g.category | current, 0b0);\n return CollisionGroupManager.create(combinedName, combinedMask);\n }\n toString() {\n return `\r\ncategory: ${this.category.toString(2).padStart(32, '0')}\r\nmask: ${(this.mask >>> 0).toString(2).padStart(32, '0')}\r\n `;\n }\n}\n/**\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\n * it is the default collision group on colliders.\n */\nCollisionGroup.All = new CollisionGroup('Collide with all groups', -1, -1);\n\n;// CONCATENATED MODULE: ./Collision/Detection/Pair.ts\n\n\n/**\n * Models a potential collision between 2 colliders\n */\nclass Pair {\n constructor(colliderA, colliderB) {\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.id = null;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n }\n /**\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\n * @param colliderA\n * @param colliderB\n */\n static canCollide(colliderA, colliderB) {\n var _a, _b;\n const bodyA = (_a = colliderA === null || colliderA === void 0 ? void 0 : colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB === null || colliderB === void 0 ? void 0 : colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n // Prevent self collision\n if (colliderA.id === colliderB.id) {\n return false;\n }\n // Colliders with the same owner do not collide (composite colliders)\n if (colliderA.owner &&\n colliderB.owner &&\n colliderA.owner.id === colliderB.owner.id) {\n return false;\n }\n // if the pair has a member with zero dimension don't collide\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) {\n return false;\n }\n // Body's needed for collision in the current state\n // TODO can we collide without a body?\n if (!bodyA || !bodyB) {\n return false;\n }\n // If both are in the same collision group short circuit\n if (!bodyA.group.canCollide(bodyB.group)) {\n return false;\n }\n // if both are fixed short circuit\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) {\n return false;\n }\n // if the either is prevent collision short circuit\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) {\n return false;\n }\n // if either is dead short circuit\n if (!bodyA.active || !bodyB.active) {\n return false;\n }\n return true;\n }\n /**\n * Returns whether or not it is possible for the pairs to collide\n */\n get canCollide() {\n const colliderA = this.colliderA;\n const colliderB = this.colliderB;\n return Pair.canCollide(colliderA, colliderB);\n }\n /**\n * Runs the collision intersection logic on the members of this pair\n */\n collide() {\n return this.colliderA.collide(this.colliderB);\n }\n /**\n * Check if the collider is part of the pair\n * @param collider\n */\n hasCollider(collider) {\n return collider === this.colliderA || collider === this.colliderB;\n }\n /**\n * Calculates the unique pair hash id for this collision pair (owning id)\n */\n static calculatePairHash(idA, idB) {\n if (idA.value < idB.value) {\n return `#${idA.value}+${idB.value}`;\n }\n else {\n return `#${idB.value}+${idA.value}`;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Math/projection.ts\n/**\n * A 1 dimensional projection on an axis, used to test overlaps\n */\nclass Projection {\n constructor(min, max) {\n this.min = min;\n this.max = max;\n }\n overlaps(projection) {\n return this.max > projection.min && projection.max > this.min;\n }\n getOverlap(projection) {\n if (this.overlaps(projection)) {\n if (this.max > projection.max) {\n return projection.max - this.min;\n }\n else {\n return this.max - projection.min;\n }\n }\n return 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Detection/DynamicTree.ts\n\n\n\n\n/**\n * Dynamic Tree Node used for tracking bounds within the tree\n */\nclass TreeNode {\n constructor(parent) {\n this.parent = parent;\n this.parent = parent || null;\n this.data = null;\n this.bounds = new BoundingBox();\n this.left = null;\n this.right = null;\n this.height = 0;\n }\n isLeaf() {\n return !this.left && !this.right;\n }\n}\n/**\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\n *\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\n * Every non-leaf node is a bounding box that contains child bounding boxes.\n */\nclass DynamicTree {\n constructor(_config, worldBounds = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)) {\n this._config = _config;\n this.worldBounds = worldBounds;\n this.root = null;\n this.nodes = {};\n }\n /**\n * Inserts a node into the dynamic tree\n */\n _insert(leaf) {\n // If there are no nodes in the tree, make this the root leaf\n if (this.root === null) {\n this.root = leaf;\n this.root.parent = null;\n return;\n }\n // Search the tree for a node that is not a leaf and find the best place to insert\n const leafAABB = leaf.bounds;\n let currentRoot = this.root;\n while (!currentRoot.isLeaf()) {\n const left = currentRoot.left;\n const right = currentRoot.right;\n const area = currentRoot.bounds.getPerimeter();\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\n const combinedArea = combinedAABB.getPerimeter();\n // Calculate cost heuristic for creating a new parent and leaf\n const cost = 2 * combinedArea;\n // Minimum cost of pushing the leaf down the tree\n const inheritanceCost = 2 * (combinedArea - area);\n // Cost of descending\n let leftCost = 0;\n const leftCombined = leafAABB.combine(left.bounds);\n let newArea;\n let oldArea;\n if (left.isLeaf()) {\n leftCost = leftCombined.getPerimeter() + inheritanceCost;\n }\n else {\n oldArea = left.bounds.getPerimeter();\n newArea = leftCombined.getPerimeter();\n leftCost = newArea - oldArea + inheritanceCost;\n }\n let rightCost = 0;\n const rightCombined = leafAABB.combine(right.bounds);\n if (right.isLeaf()) {\n rightCost = rightCombined.getPerimeter() + inheritanceCost;\n }\n else {\n oldArea = right.bounds.getPerimeter();\n newArea = rightCombined.getPerimeter();\n rightCost = newArea - oldArea + inheritanceCost;\n }\n // cost is acceptable\n if (cost < leftCost && cost < rightCost) {\n break;\n }\n // Descend to the depths\n if (leftCost < rightCost) {\n currentRoot = left;\n }\n else {\n currentRoot = right;\n }\n }\n // Create the new parent node and insert into the tree\n const oldParent = currentRoot.parent;\n const newParent = new TreeNode(oldParent);\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\n newParent.height = currentRoot.height + 1;\n if (oldParent !== null) {\n // The sibling node was not the root\n if (oldParent.left === currentRoot) {\n oldParent.left = newParent;\n }\n else {\n oldParent.right = newParent;\n }\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n }\n else {\n // The sibling node was the root\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n this.root = newParent;\n }\n // Walk up the tree fixing heights and AABBs\n let currentNode = leaf.parent;\n while (currentNode) {\n currentNode = this._balance(currentNode);\n if (!currentNode.left) {\n throw new Error('Parent of current leaf cannot have a null left child' + currentNode);\n }\n if (!currentNode.right) {\n throw new Error('Parent of current leaf cannot have a null right child' + currentNode);\n }\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode = currentNode.parent;\n }\n }\n /**\n * Removes a node from the dynamic tree\n */\n _remove(leaf) {\n if (leaf === this.root) {\n this.root = null;\n return;\n }\n const parent = leaf.parent;\n const grandParent = parent.parent;\n let sibling;\n if (parent.left === leaf) {\n sibling = parent.right;\n }\n else {\n sibling = parent.left;\n }\n if (grandParent) {\n if (grandParent.left === parent) {\n grandParent.left = sibling;\n }\n else {\n grandParent.right = sibling;\n }\n sibling.parent = grandParent;\n let currentNode = grandParent;\n while (currentNode) {\n currentNode = this._balance(currentNode);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode = currentNode.parent;\n }\n }\n else {\n this.root = sibling;\n sibling.parent = null;\n }\n }\n /**\n * Tracks a body in the dynamic tree\n */\n trackCollider(collider) {\n const node = new TreeNode();\n node.data = collider;\n node.bounds = collider.bounds;\n node.bounds.left -= 2;\n node.bounds.top -= 2;\n node.bounds.right += 2;\n node.bounds.bottom += 2;\n this.nodes[collider.id.value] = node;\n this._insert(node);\n }\n /**\n * Updates the dynamic tree given the current bounds of each body being tracked\n */\n updateCollider(collider) {\n var _a;\n const node = this.nodes[collider.id.value];\n if (!node) {\n return false;\n }\n const b = collider.bounds;\n // if the body is outside the world no longer update it\n if (!this.worldBounds.contains(b)) {\n Logger.getInstance().warn('Collider with id ' + collider.id.value + ' is outside the world bounds and will no longer be tracked for physics');\n this.untrackCollider(collider);\n return false;\n }\n if (node.bounds.contains(b)) {\n return false;\n }\n this._remove(node);\n b.left -= this._config.boundsPadding;\n b.top -= this._config.boundsPadding;\n b.right += this._config.boundsPadding;\n b.bottom += this._config.boundsPadding;\n // THIS IS CAUSING UNNECESSARY CHECKS\n if (collider.owner) {\n const body = (_a = collider.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n if (body) {\n const multdx = ((body.vel.x * 32) / 1000) * this._config.velocityMultiplier;\n const multdy = ((body.vel.y * 32) / 1000) * this._config.velocityMultiplier;\n if (multdx < 0) {\n b.left += multdx;\n }\n else {\n b.right += multdx;\n }\n if (multdy < 0) {\n b.top += multdy;\n }\n else {\n b.bottom += multdy;\n }\n }\n }\n node.bounds = b;\n this._insert(node);\n return true;\n }\n /**\n * Untracks a body from the dynamic tree\n */\n untrackCollider(collider) {\n const node = this.nodes[collider.id.value];\n if (!node) {\n return;\n }\n this._remove(node);\n this.nodes[collider.id.value] = null;\n delete this.nodes[collider.id.value];\n }\n /**\n * Balances the tree about a node\n */\n _balance(node) {\n if (node === null) {\n throw new Error('Cannot balance at null node');\n }\n if (node.isLeaf() || node.height < 2) {\n return node;\n }\n const left = node.left;\n const right = node.right;\n const a = node;\n const b = left;\n const c = right;\n const d = left.left;\n const e = left.right;\n const f = right.left;\n const g = right.right;\n const balance = c.height - b.height;\n // Rotate c node up\n if (balance > 1) {\n // Swap the right node with it's parent\n c.left = a;\n c.parent = a.parent;\n a.parent = c;\n // The original node's old parent should point to the right node\n // this is mega confusing\n if (c.parent) {\n if (c.parent.left === a) {\n c.parent.left = c;\n }\n else {\n c.parent.right = c;\n }\n }\n else {\n this.root = c;\n }\n // Rotate\n if (f.height > g.height) {\n c.right = f;\n a.right = g;\n g.parent = a;\n a.bounds = b.bounds.combine(g.bounds);\n c.bounds = a.bounds.combine(f.bounds);\n a.height = 1 + Math.max(b.height, g.height);\n c.height = 1 + Math.max(a.height, f.height);\n }\n else {\n c.right = g;\n a.right = f;\n f.parent = a;\n a.bounds = b.bounds.combine(f.bounds);\n c.bounds = a.bounds.combine(g.bounds);\n a.height = 1 + Math.max(b.height, f.height);\n c.height = 1 + Math.max(a.height, g.height);\n }\n return c;\n }\n // Rotate left node up\n if (balance < -1) {\n // swap\n b.left = a;\n b.parent = a.parent;\n a.parent = b;\n // node's old parent should point to b\n if (b.parent) {\n if (b.parent.left === a) {\n b.parent.left = b;\n }\n else {\n if (b.parent.right !== a) {\n throw 'Error rotating Dynamic Tree';\n }\n b.parent.right = b;\n }\n }\n else {\n this.root = b;\n }\n // rotate\n if (d.height > e.height) {\n b.right = d;\n a.left = e;\n e.parent = a;\n a.bounds = c.bounds.combine(e.bounds);\n b.bounds = a.bounds.combine(d.bounds);\n a.height = 1 + Math.max(c.height, e.height);\n b.height = 1 + Math.max(a.height, d.height);\n }\n else {\n b.right = e;\n a.left = d;\n d.parent = a;\n a.bounds = c.bounds.combine(d.bounds);\n b.bounds = a.bounds.combine(e.bounds);\n a.height = 1 + Math.max(c.height, d.height);\n b.height = 1 + Math.max(a.height, e.height);\n }\n return b;\n }\n return node;\n }\n /**\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\n */\n getHeight() {\n if (this.root === null) {\n return 0;\n }\n return this.root.height;\n }\n /**\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\n *\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\n * the tree until all possible colliders have been returned.\n */\n query(collider, callback) {\n const bounds = collider.bounds;\n const helper = (currentNode) => {\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\n if (currentNode.isLeaf() && currentNode.data !== collider) {\n if (callback.call(collider, currentNode.data)) {\n return true;\n }\n }\n else {\n return helper(currentNode.left) || helper(currentNode.right);\n }\n }\n return false;\n };\n helper(this.root);\n }\n /**\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\n * long ray to test the tree specified by `max`.\n *\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\n * the tree until all possible bodies that would intersect with the ray have been returned.\n */\n rayCastQuery(ray, max = Infinity, callback) {\n const helper = (currentNode) => {\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\n if (currentNode.isLeaf()) {\n if (callback.call(ray, currentNode.data)) {\n // ray hit a leaf! return the body\n return true;\n }\n }\n else {\n // ray hit but not at a leaf, recurse deeper\n return helper(currentNode.left) || helper(currentNode.right);\n }\n }\n return false; // ray missed\n };\n helper(this.root);\n }\n getNodes() {\n const helper = (currentNode) => {\n if (currentNode) {\n return [currentNode].concat(helper(currentNode.left), helper(currentNode.right));\n }\n else {\n return [];\n }\n };\n return helper(this.root);\n }\n debug(ex) {\n // draw all the nodes in the Dynamic Tree\n const helper = (currentNode) => {\n if (currentNode) {\n if (currentNode.isLeaf()) {\n currentNode.bounds.draw(ex, Color.Green);\n }\n else {\n currentNode.bounds.draw(ex, Color.White);\n }\n if (currentNode.left) {\n helper(currentNode.left);\n }\n if (currentNode.right) {\n helper(currentNode.right);\n }\n }\n };\n helper(this.root);\n }\n}\n\n;// CONCATENATED MODULE: ./Math/ray.ts\n/**\n * A 2D ray that can be cast into the scene to do collision detection\n */\nclass Ray {\n /**\n * @param pos The starting position for the ray\n * @param dir The vector indicating the direction of the ray\n */\n constructor(pos, dir) {\n this.pos = pos;\n this.dir = dir.normalize();\n }\n /**\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\n * This number indicates the mathematical intersection time.\n * @param line The line to test\n */\n intersect(line) {\n const numerator = line.begin.sub(this.pos);\n // Test is line and ray are parallel and non intersecting\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) {\n return -1;\n }\n // Lines are parallel\n const divisor = this.dir.cross(line.getSlope());\n if (divisor === 0) {\n return -1;\n }\n const t = numerator.cross(line.getSlope()) / divisor;\n if (t >= 0) {\n const u = numerator.cross(this.dir) / divisor / line.getLength();\n if (u >= 0 && u <= 1) {\n return t;\n }\n }\n return -1;\n }\n intersectPoint(line) {\n const time = this.intersect(line);\n if (time < 0) {\n return null;\n }\n return this.getPoint(time);\n }\n /**\n * Returns the point of intersection given the intersection time\n */\n getPoint(time) {\n return this.pos.add(this.dir.scale(time));\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Detection/DynamicTreeCollisionProcessor.ts\n\n\n\n\n\n\n\n\n\n/**\n * Responsible for performing the collision broadphase (locating potential collisions) and\n * the narrowphase (actual collision contacts)\n */\nclass DynamicTreeCollisionProcessor {\n constructor(_config) {\n this._config = _config;\n this._pairs = new Set();\n this._collisionPairCache = [];\n this._colliders = [];\n this._dynamicCollisionTree = new DynamicTree(_config.dynamicTree);\n }\n getColliders() {\n return this._colliders;\n }\n rayCast(ray, options) {\n var _a, _b, _c;\n const results = [];\n const maxDistance = (_a = options === null || options === void 0 ? void 0 : options.maxDistance) !== null && _a !== void 0 ? _a : Infinity;\n const collisionGroup = options === null || options === void 0 ? void 0 : options.collisionGroup;\n const collisionMask = !collisionGroup ? (_b = options === null || options === void 0 ? void 0 : options.collisionMask) !== null && _b !== void 0 ? _b : CollisionGroup.All.category : collisionGroup.category;\n const searchAllColliders = (_c = options === null || options === void 0 ? void 0 : options.searchAllColliders) !== null && _c !== void 0 ? _c : false;\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider) => {\n const owner = collider.owner;\n const maybeBody = owner.get(BodyComponent);\n if ((options === null || options === void 0 ? void 0 : options.ignoreCollisionGroupAll) && maybeBody.group === CollisionGroup.All) {\n return false;\n }\n const canCollide = (collisionMask & maybeBody.group.category) !== 0;\n // Early exit if not the right group\n if ((maybeBody === null || maybeBody === void 0 ? void 0 : maybeBody.group) && !canCollide) {\n return false;\n }\n const hit = collider.rayCast(ray, maxDistance);\n if (hit) {\n if (options === null || options === void 0 ? void 0 : options.filter) {\n if (options.filter(hit)) {\n results.push(hit);\n if (!searchAllColliders) {\n // returning true exits the search\n return true;\n }\n }\n }\n else {\n results.push(hit);\n if (!searchAllColliders) {\n // returning true exits the search\n return true;\n }\n }\n }\n return false;\n });\n return results;\n }\n /**\n * Tracks a physics body for collisions\n */\n track(target) {\n if (!target) {\n Logger.getInstance().warn('Cannot track null collider');\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders) {\n c.owner = target.owner;\n this._colliders.push(c);\n this._dynamicCollisionTree.trackCollider(c);\n }\n }\n else {\n this._colliders.push(target);\n this._dynamicCollisionTree.trackCollider(target);\n }\n }\n /**\n * Untracks a physics body\n */\n untrack(target) {\n if (!target) {\n Logger.getInstance().warn('Cannot untrack a null collider');\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders) {\n const index = this._colliders.indexOf(c);\n if (index !== -1) {\n this._colliders.splice(index, 1);\n }\n this._dynamicCollisionTree.untrackCollider(c);\n }\n }\n else {\n const index = this._colliders.indexOf(target);\n if (index !== -1) {\n this._colliders.splice(index, 1);\n }\n this._dynamicCollisionTree.untrackCollider(target);\n }\n }\n _pairExists(colliderA, colliderB) {\n // if the collision pair has been calculated already short circuit\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\n return this._pairs.has(hash);\n }\n /**\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\n */\n broadphase(targets, delta, stats) {\n const seconds = delta / 1000;\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\n const potentialColliders = targets.filter((other) => {\n var _a, _b;\n const body = (_a = other.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n return ((_b = other.owner) === null || _b === void 0 ? void 0 : _b.active) && body.collisionType !== CollisionType.PreventCollision;\n });\n // clear old list of collision pairs\n this._collisionPairCache = [];\n this._pairs.clear();\n // check for normal collision pairs\n let collider;\n for (let j = 0, l = potentialColliders.length; j < l; j++) {\n collider = potentialColliders[j];\n // Query the collision tree for potential colliders\n this._dynamicCollisionTree.query(collider, (other) => {\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const pair = new Pair(collider, other);\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // Always return false, to query whole tree. Returning true in the query method stops searching\n return false;\n });\n }\n if (stats) {\n stats.physics.pairs = this._collisionPairCache.length;\n }\n // Check dynamic tree for fast moving objects\n // Fast moving objects are those moving at least there smallest bound per frame\n if (this._config.continuous.checkForFastBodies) {\n for (const collider of potentialColliders) {\n const body = collider.owner.get(BodyComponent);\n // Skip non-active objects. Does not make sense on other collision types\n if (body.collisionType !== CollisionType.Active) {\n continue;\n }\n // Maximum travel distance next frame\n const updateDistance = body.vel.size * seconds + // velocity term\n body.acc.size * 0.5 * seconds * seconds; // acc term\n // Find the minimum dimension\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\n if (this._config.continuous.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\n if (stats) {\n stats.physics.fastBodies++;\n }\n // start with the oldPos because the integration for actors has already happened\n // objects resting on a surface may be slightly penetrating in the current position\n const updateVec = body.globalPos.sub(body.oldPos);\n const centerPoint = collider.center;\n const furthestPoint = collider.getFurthestPoint(body.vel);\n const origin = furthestPoint.sub(updateVec);\n const ray = new Ray(origin, body.vel);\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\n ray.pos = ray.pos.add(ray.dir.scale(-2 * this._config.continuous.surfaceEpsilon));\n let minCollider;\n let minTranslate = new Vector(Infinity, Infinity);\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + this._config.continuous.surfaceEpsilon * 2, (other) => {\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const hit = other.rayCast(ray, updateDistance + this._config.continuous.surfaceEpsilon * 10);\n if (hit) {\n const translate = hit.point.sub(origin);\n if (translate.size < minTranslate.size) {\n minTranslate = translate;\n minCollider = other;\n }\n }\n }\n return false;\n });\n if (minCollider && Vector.isValid(minTranslate)) {\n const pair = new Pair(collider, minCollider);\n if (!this._pairs.has(pair.id)) {\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // move the fast moving object to the other body\n // need to push into the surface by ex.Physics.surfaceEpsilon\n const shift = centerPoint.sub(furthestPoint);\n body.globalPos = origin\n .add(shift)\n .add(minTranslate)\n .add(ray.dir.scale(10 * this._config.continuous.surfaceEpsilon)); // needed to push the shape slightly into contact\n collider.update(body.transform.get());\n if (stats) {\n stats.physics.fastBodyCollisions++;\n }\n }\n }\n }\n }\n // return cache\n return this._collisionPairCache;\n }\n /**\n * Applies narrow phase on collision pairs to find actual area intersections\n * Adds actual colliding pairs to stats' Frame data\n */\n narrowphase(pairs, stats) {\n let contacts = [];\n for (let i = 0; i < pairs.length; i++) {\n const newContacts = pairs[i].collide();\n contacts = contacts.concat(newContacts);\n if (stats && newContacts.length > 0) {\n for (const c of newContacts) {\n stats.physics.contacts.set(c.id, c);\n }\n }\n }\n if (stats) {\n stats.physics.collisions += contacts.length;\n }\n return contacts;\n }\n /**\n * Update the dynamic tree positions\n */\n update(targets) {\n let updated = 0;\n const len = targets.length;\n for (let i = 0; i < len; i++) {\n if (this._dynamicCollisionTree.updateCollider(targets[i])) {\n updated++;\n }\n }\n return updated;\n }\n debug(ex) {\n this._dynamicCollisionTree.debug(ex);\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/Collider.ts\n\n\n\n/**\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\n * for the purposes of colliding 2 objects in excalibur.\n */\nclass Collider {\n constructor() {\n this.id = createId('collider', Collider._ID++);\n /**\n * Composite collider if any this collider is attached to\n *\n * **WARNING** do not tamper with this property\n */\n this.composite = null;\n this.events = new EventEmitter();\n /**\n * Pixel offset of the collision collider relative to the collider, by default (0, 0) meaning the collider is positioned\n * on top of the collider.\n */\n this.offset = Vector.Zero;\n }\n /**\n * Returns a boolean indicating whether this body collided with\n * or was in stationary contact with\n * the body of the other [[Collider]]\n */\n touching(other) {\n const contact = this.collide(other);\n if (contact) {\n return true;\n }\n return false;\n }\n}\nCollider._ID = 0;\n\n;// CONCATENATED MODULE: ./Collision/SolverStrategy.ts\n/**\n * Possible collision resolution strategies\n *\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\n * like platformers or top down games.\n *\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\n * simulated physical interactions.\n */\nvar SolverStrategy;\n(function (SolverStrategy) {\n SolverStrategy[\"Arcade\"] = \"arcade\";\n SolverStrategy[\"Realistic\"] = \"realistic\";\n})(SolverStrategy || (SolverStrategy = {}));\n\n;// CONCATENATED MODULE: ./Collision/Physics.ts\n\n\n/**\n * Possible broadphase collision pair identification strategies\n *\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\n * potential collision pairs which is O(nlog(n)) faster.\n * @deprecated Unused in Excalibur, will be removed in v0.30\n */\nvar BroadphaseStrategy;\n(function (BroadphaseStrategy) {\n BroadphaseStrategy[BroadphaseStrategy[\"DynamicAABBTree\"] = 0] = \"DynamicAABBTree\";\n})(BroadphaseStrategy || (BroadphaseStrategy = {}));\n/**\n * Possible numerical integrators for position and velocity\n * @deprecated Unused in Excalibur, will be removed in v0.30\n */\nvar Integrator;\n(function (Integrator) {\n Integrator[Integrator[\"Euler\"] = 0] = \"Euler\";\n})(Integrator || (Integrator = {}));\n/**\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\n/* istanbul ignore next */\nclass Physics {\n /**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\n static get gravity() {\n return Physics.acc;\n }\n static set gravity(v) {\n Physics.acc = v;\n }\n /**\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\n static useArcadePhysics() {\n Physics.collisionResolutionStrategy = SolverStrategy.Arcade;\n }\n /**\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\n * simulated physical interactions.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\n static useRealisticPhysics() {\n Physics.collisionResolutionStrategy = SolverStrategy.Realistic;\n }\n}\n/**\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\n *\n * This is a great way to globally simulate effects like gravity.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.acc = new Vector(0, 0);\n/**\n * Globally switches all Excalibur physics behavior on or off.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.enabled = true;\n/**\n * Gets or sets the broadphase pair identification strategy.\n *\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\n * potential collision pairs which is O(nlog(n)) faster.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.broadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\n/**\n * Gets or sets the global collision resolution strategy (narrowphase).\n *\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics.\n *\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\n * simulated physical interactions.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.collisionResolutionStrategy = SolverStrategy.Arcade;\n/**\n * The default mass to use if none is specified\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.defaultMass = 10;\n/**\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.integrator = Integrator.Euler;\n/**\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.dynamicTreeVelocityMultiplier = 2;\n/**\n * Pad RigidBody BoundingBox by a constant amount\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.boundsPadding = 5;\n/**\n * Number of position iterations (overlap) to run in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.positionIterations = 3;\n/**\n * Number of velocity iteration (response) to run in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.velocityIterations = 8;\n/**\n * Amount of overlap to tolerate in pixels\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.slop = 1;\n/**\n * Amount of positional overlap correction to apply each position iteration of the solver\n * O - meaning no correction, 1 - meaning correct all overlap\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.steeringFactor = 0.2;\n/**\n * Warm start set to true re-uses impulses from previous frames back in the solver\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.warmStart = true;\n/**\n * By default bodies do not sleep\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.bodiesCanSleepByDefault = false;\n/**\n * Surface epsilon is used to help deal with surface penetration\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.surfaceEpsilon = 0.1;\n/**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.sleepEpsilon = 0.07;\n/**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.wakeThreshold = Physics.sleepEpsilon * 3;\n/**\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.sleepBias = 0.9;\n/**\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\n * bodies from tunneling through one another.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.checkForFastBodies = true;\n/**\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\n * Excalibur will always perform the fast body raycast regardless of speed.\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\n */\nPhysics.disableMinimumSpeedForFastBody = false;\n\n;// CONCATENATED MODULE: ./Collision/Solver/ContactBias.ts\n/**\n * Tells the Arcade collision solver to prefer certain contacts over others\n */\nvar ContactSolveBias;\n(function (ContactSolveBias) {\n ContactSolveBias[\"None\"] = \"none\";\n ContactSolveBias[\"VerticalFirst\"] = \"vertical-first\";\n ContactSolveBias[\"HorizontalFirst\"] = \"horizontal-first\";\n})(ContactSolveBias || (ContactSolveBias = {}));\n/**\n * Vertical First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\n */\nconst VerticalFirst = {\n 'vertical': 1,\n 'horizontal': 2\n};\n/**\n * Horizontal First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\n */\nconst HorizontalFirst = {\n 'horizontal': 1,\n 'vertical': 2\n};\n/**\n * None value, [[ArcadeSolver]] sorts contacts using distance by default\n */\nconst None = {\n 'horizontal': 0,\n 'vertical': 0\n};\n\n;// CONCATENATED MODULE: ./Collision/PhysicsConfig.ts\n\n\n\n\nconst DefaultPhysicsConfig = {\n enabled: true,\n gravity: vec(0, 0),\n solver: SolverStrategy.Arcade,\n colliders: {\n compositeStrategy: 'together'\n },\n continuous: {\n checkForFastBodies: true,\n disableMinimumSpeedForFastBody: false,\n surfaceEpsilon: 0.1\n },\n bodies: {\n canSleepByDefault: false,\n sleepEpsilon: 0.07,\n wakeThreshold: 0.07 * 3,\n sleepBias: 0.9,\n defaultMass: 10\n },\n dynamicTree: {\n boundsPadding: 5,\n velocityMultiplier: 2\n },\n arcade: {\n contactSolveBias: ContactSolveBias.None\n },\n realistic: {\n positionIterations: 3,\n velocityIterations: 8,\n slop: 1,\n steeringFactor: 0.2,\n warmStart: true\n }\n};\n/**\n * @deprecated will be removed in v0.30\n */\nfunction DeprecatedStaticToConfig() {\n return {\n enabled: Physics.enabled,\n gravity: Physics.gravity,\n solver: Physics.collisionResolutionStrategy,\n continuous: {\n checkForFastBodies: Physics.checkForFastBodies,\n disableMinimumSpeedForFastBody: Physics.disableMinimumSpeedForFastBody,\n surfaceEpsilon: Physics.surfaceEpsilon\n },\n colliders: {\n compositeStrategy: 'together'\n },\n bodies: {\n canSleepByDefault: Physics.bodiesCanSleepByDefault,\n sleepEpsilon: Physics.sleepEpsilon,\n wakeThreshold: Physics.wakeThreshold,\n sleepBias: Physics.sleepBias,\n defaultMass: Physics.defaultMass\n },\n dynamicTree: {\n boundsPadding: Physics.boundsPadding,\n velocityMultiplier: Physics.dynamicTreeVelocityMultiplier\n },\n arcade: {\n contactSolveBias: ContactSolveBias.None\n },\n realistic: {\n positionIterations: Physics.positionIterations,\n velocityIterations: Physics.velocityIterations,\n slop: Physics.slop,\n steeringFactor: Physics.steeringFactor,\n warmStart: Physics.warmStart\n }\n };\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CompositeCollider.ts\n\n\n\n\n\n\n\n\n\nclass CompositeCollider extends Collider {\n /**\n * Treat composite collider's member colliders as either separate colliders for the purposes of onCollisionStart/onCollision\n * or as a single collider together.\n *\n * This property can be overridden on individual [[CompositeColliders]].\n *\n * For composites without gaps or small groups of colliders, you probably want 'together'\n *\n * For composites with deliberate gaps, like a platforming level layout, you probably want 'separate'\n *\n * Default is 'together' if unset\n */\n set compositeStrategy(value) {\n this._compositeStrategy = value;\n }\n get compositeStrategy() {\n return this._compositeStrategy;\n }\n constructor(colliders) {\n super();\n this._collisionProcessor = new DynamicTreeCollisionProcessor(DefaultPhysicsConfig);\n this._dynamicAABBTree = new DynamicTree(DefaultPhysicsConfig.dynamicTree);\n this._colliders = [];\n for (const c of colliders) {\n this.addCollider(c);\n }\n }\n clearColliders() {\n this._colliders = [];\n }\n addCollider(collider) {\n let colliders;\n if (collider instanceof CompositeCollider) {\n colliders = collider.getColliders();\n colliders.forEach(c => c.offset.addEqual(collider.offset));\n }\n else {\n colliders = [collider];\n }\n // Flatten composites\n for (const c of colliders) {\n c.events.pipe(this.events);\n c.composite = this;\n this._colliders.push(c);\n this._collisionProcessor.track(c);\n this._dynamicAABBTree.trackCollider(c);\n }\n }\n removeCollider(collider) {\n collider.events.pipe(this.events);\n collider.composite = null;\n removeItemFromArray(collider, this._colliders);\n this._collisionProcessor.untrack(collider);\n this._dynamicAABBTree.untrackCollider(collider);\n }\n getColliders() {\n return this._colliders;\n }\n get worldPos() {\n var _a, _b;\n return ((_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero).add(this.offset);\n }\n get center() {\n var _a, _b;\n return ((_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero).add(this.offset);\n }\n get bounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider) => acc.combine(collider.bounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox().translate(this.worldPos));\n return results.translate(this.offset);\n }\n get localBounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider) => acc.combine(collider.localBounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox());\n return results;\n }\n get axes() {\n // TODO cache this\n const colliders = this.getColliders();\n let axes = [];\n for (const collider of colliders) {\n axes = axes.concat(collider.axes);\n }\n return axes;\n }\n getFurthestPoint(direction) {\n const colliders = this.getColliders();\n const furthestPoints = [];\n for (const collider of colliders) {\n furthestPoints.push(collider.getFurthestPoint(direction));\n }\n // Pick best point from all colliders\n let bestPoint = furthestPoints[0];\n let maxDistance = -Number.MAX_VALUE;\n for (const point of furthestPoints) {\n const distance = point.dot(direction);\n if (distance > maxDistance) {\n bestPoint = point;\n maxDistance = distance;\n }\n }\n return bestPoint;\n }\n getInertia(mass) {\n const colliders = this.getColliders();\n let totalInertia = 0;\n for (const collider of colliders) {\n totalInertia += collider.getInertia(mass);\n }\n return totalInertia;\n }\n collide(other) {\n let otherColliders = [other];\n if (other instanceof CompositeCollider) {\n otherColliders = other.getColliders();\n }\n const pairs = [];\n for (const c of otherColliders) {\n this._dynamicAABBTree.query(c, (potentialCollider) => {\n pairs.push(new Pair(c, potentialCollider));\n return false;\n });\n }\n let contacts = [];\n for (const p of pairs) {\n contacts = contacts.concat(p.collide());\n }\n return contacts;\n }\n getClosestLineBetween(other) {\n const colliders = this.getColliders();\n const lines = [];\n if (other instanceof CompositeCollider) {\n const otherColliders = other.getColliders();\n for (const colliderA of colliders) {\n for (const colliderB of otherColliders) {\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\n if (maybeLine) {\n lines.push(maybeLine);\n }\n }\n }\n }\n else {\n for (const collider of colliders) {\n const maybeLine = other.getClosestLineBetween(collider);\n if (maybeLine) {\n lines.push(maybeLine);\n }\n }\n }\n if (lines.length) {\n let minLength = lines[0].getLength();\n let minLine = lines[0];\n for (const line of lines) {\n const length = line.getLength();\n if (length < minLength) {\n minLength = length;\n minLine = line;\n }\n }\n return minLine;\n }\n return null;\n }\n contains(point) {\n const colliders = this.getColliders();\n for (const collider of colliders) {\n if (collider.contains(point)) {\n return true;\n }\n }\n return false;\n }\n rayCast(ray, max) {\n const colliders = this.getColliders();\n const hits = [];\n for (const collider of colliders) {\n const hit = collider.rayCast(ray, max);\n if (hit) {\n hits.push(hit);\n }\n }\n if (hits.length) {\n let minHit = hits[0];\n let minDistance = minHit.point.dot(ray.dir);\n for (const hit of hits) {\n const distance = ray.dir.dot(hit.point);\n if (distance < minDistance) {\n minHit = hit;\n minDistance = distance;\n }\n }\n return minHit;\n }\n return null;\n }\n project(axis) {\n const colliders = this.getColliders();\n const projections = [];\n for (const collider of colliders) {\n const proj = collider.project(axis);\n if (proj) {\n projections.push(proj);\n }\n }\n // Merge all proj's on the same axis\n if (projections.length) {\n const newProjection = new Projection(projections[0].min, projections[0].max);\n for (const proj of projections) {\n newProjection.min = Math.min(proj.min, newProjection.min);\n newProjection.max = Math.max(proj.max, newProjection.max);\n }\n return newProjection;\n }\n return null;\n }\n update(transform) {\n if (transform) {\n const colliders = this.getColliders();\n for (const collider of colliders) {\n collider.owner = this.owner;\n collider.update(transform);\n }\n }\n }\n debug(ex, color, options) {\n const colliders = this.getColliders();\n ex.save();\n ex.translate(this.offset.x, this.offset.y);\n for (const collider of colliders) {\n collider.debug(ex, color, options);\n }\n ex.restore();\n }\n clone() {\n const result = new CompositeCollider(this._colliders.map((c) => c.clone()));\n result.offset = this.offset.clone();\n return result;\n }\n}\n\n;// CONCATENATED MODULE: ./Math/line-segment.ts\n\n/**\n * A 2D line segment\n */\nclass LineSegment {\n /**\n * @param begin The starting point of the line segment\n * @param end The ending point of the line segment\n */\n constructor(begin, end) {\n this.begin = begin;\n this.end = end;\n }\n /**\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\n */\n get slope() {\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\n }\n /**\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\n */\n get intercept() {\n return this.begin.y - this.slope * this.begin.x;\n }\n /**\n * Gets the normal of the line\n */\n normal() {\n if (this._normal) {\n return this._normal;\n }\n return this._normal = this.end.sub(this.begin).normal();\n }\n dir() {\n if (this._dir) {\n return this._dir;\n }\n return this._dir = this.end.sub(this.begin);\n }\n getPoints() {\n return [this.begin, this.end];\n }\n /**\n * Returns the slope of the line in the form of a vector of length 1\n */\n getSlope() {\n if (this._slope) {\n return this._slope;\n }\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._slope = end.sub(begin).scale(1 / distance);\n }\n /**\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\n */\n getEdge() {\n const begin = this.begin;\n const end = this.end;\n return end.sub(begin);\n }\n /**\n * Returns the length of the line segment in pixels\n */\n getLength() {\n if (this._length) {\n return this._length;\n }\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._length = distance;\n }\n /**\n * Returns the midpoint of the edge\n */\n get midpoint() {\n return this.begin.add(this.end).scale(0.5);\n }\n /**\n * Flips the direction of the line segment\n */\n flip() {\n return new LineSegment(this.end, this.begin);\n }\n /**\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\n * @param point\n */\n below(point) {\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\n return above2 >= 0;\n }\n /**\n * Returns the clip point\n * @param sideVector Vector that traces the line\n * @param length Length to clip along side\n */\n clip(sideVector, length) {\n let dir = sideVector;\n dir = dir.normalize();\n const near = dir.dot(this.begin) - length;\n const far = dir.dot(this.end) - length;\n const results = [];\n if (near <= 0) {\n results.push(this.begin);\n }\n if (far <= 0) {\n results.push(this.end);\n }\n if (near * far < 0) {\n const clipTime = near / (near - far);\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\n }\n if (results.length !== 2) {\n return null;\n }\n return new LineSegment(results[0], results[1]);\n }\n /**\n * Find the perpendicular distance from the line to a point\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\n * @param point\n */\n distanceToPoint(point, signed = false) {\n const x0 = point.x;\n const y0 = point.y;\n const l = this.getLength();\n const dy = this.end.y - this.begin.y;\n const dx = this.end.x - this.begin.x;\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\n return signed ? distance : Math.abs(distance);\n }\n /**\n * Find the perpendicular line from the line to a point\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\n * (a - p) - ((a - p) * n)n\n * a is a point on the line\n * p is the arbitrary point above the line\n * n is a unit vector in direction of the line\n * @param point\n */\n findVectorToPoint(point) {\n const aMinusP = this.begin.sub(point);\n const n = this.getSlope();\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\n }\n /**\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\n * a new point with the calculated Y value and vice-versa.\n * @param x The known X value of the target point\n * @param y The known Y value of the target point\n * @returns A new point with the other calculated axis value\n */\n findPoint(x = null, y = null) {\n const m = this.slope;\n const b = this.intercept;\n if (x !== null) {\n return new Vector(x, m * x + b);\n }\n else if (y !== null) {\n return new Vector((y - b) / m, y);\n }\n else {\n throw new Error('You must provide an X or a Y value');\n }\n }\n /**\n * @see http://stackoverflow.com/a/11908158/109458\n */\n hasPoint() {\n let currPoint;\n let threshold = 0;\n if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') {\n currPoint = new Vector(arguments[0], arguments[1]);\n threshold = arguments[2] || 0;\n }\n else if (arguments[0] instanceof Vector) {\n currPoint = arguments[0];\n threshold = arguments[1] || 0;\n }\n else {\n throw 'Could not determine the arguments for Vector.hasPoint';\n }\n const dxc = currPoint.x - this.begin.x;\n const dyc = currPoint.y - this.begin.y;\n const dx1 = this.end.x - this.begin.x;\n const dy1 = this.end.y - this.begin.y;\n const cross = dxc * dy1 - dyc * dx1;\n // check whether point lines on the line\n if (Math.abs(cross) > threshold) {\n return false;\n }\n // check whether point lies in-between start and end\n if (Math.abs(dx1) >= Math.abs(dy1)) {\n return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\n }\n else {\n return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/ClosestLineJumpTable.ts\n\n\n\n/**\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n * @param p0 Point where L1 begins\n * @param u Direction and length of L1\n * @param q0 Point were L2 begins\n * @param v Direction and length of L2\n */\nfunction ClosestLine(p0, u, q0, v) {\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\n // w(s, t) = P(s) - Q(t)\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\n //\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\n //\n // The closest point between 2 lines then satisfies this pair of equations\n // 1: u * wClosest = 0\n // 2: v * wClosest = 0\n //\n // Substituting wClosest into the equations we get\n //\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\n // simplify w0\n const w0 = p0.sub(q0);\n // simplify (u * u);\n const a = u.dot(u);\n // simplify (u * v);\n const b = u.dot(v);\n // simplify (v * v)\n const c = v.dot(v);\n // simplify (u * w0)\n const d = u.dot(w0);\n // simplify (v * w0)\n const e = v.dot(w0);\n // denominator ac - b^2\n const denom = a * c - b * b;\n let sDenom = denom;\n let tDenom = denom;\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\n if (denom === 0 || denom <= 0.01) {\n const tClosestParallel = d / b;\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\n }\n // Solve for sClosest for infinite line\n let sClosest = b * e - c * d; // / denom;\n // Solve for tClosest for infinite line\n let tClosest = a * e - b * d; // / denom;\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\n if (sClosest < 0) {\n sClosest = 0;\n tClosest = e;\n tDenom = c;\n }\n else if (sClosest > sDenom) {\n sClosest = sDenom;\n tClosest = e + b;\n tDenom = c;\n }\n if (tClosest < 0) {\n tClosest = 0;\n if (-d < 0) {\n sClosest = 0;\n }\n else if (-d > a) {\n sClosest = sDenom;\n }\n else {\n sClosest = -d;\n sDenom = a;\n }\n }\n else if (tClosest > tDenom) {\n tClosest = tDenom;\n if (-d + b < 0) {\n sClosest = 0;\n }\n else if (-d + b > a) {\n sClosest = sDenom;\n }\n else {\n sClosest = -d + b;\n sDenom = a;\n }\n }\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\n}\nconst ClosestLineJumpTable = {\n PolygonPolygonClosestLine(polygonA, polygonB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = polygonB.worldPos;\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\n const thisDirection = otherDirection.negate();\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\n const thisPoint = polygonA.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const otherPoint = polygonB.rayCast(rayTowardsThis).point.add(rayTowardsThis.dir.scale(0.1));\n const thisFace = polygonA.getClosestFace(thisPoint);\n const otherFace = polygonB.getClosestFace(otherPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const q0 = otherFace.face.begin;\n const v = otherFace.face.getEdge();\n return ClosestLine(p0, u, q0, v);\n },\n PolygonEdgeClosestLine(polygon, edge) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = edge.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const q0 = edgeStart;\n const v = edgeVector;\n return ClosestLine(p0, u, q0, v);\n },\n PolygonCircleClosestLine(polygon, circle) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circle.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // Time of minimum distance\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp\n if (t > 1) {\n t = 1;\n }\n else if (t < 0) {\n t = 0;\n }\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\n const circlex = ((p0.x + u.x * t - otherWorldPos.x) * circle.radius) / (circle.radius + d);\n const circley = ((p0.y + u.y * t - otherWorldPos.y) * circle.radius) / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\n },\n CircleCircleClosestLine(circleA, circleB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circleB.worldPos;\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\n const thisWorldPos = circleA.worldPos;\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\n const thisPoint = circleA.rayCast(rayTowardsOther);\n const otherPoint = circleB.rayCast(rayTowardsThis);\n return new LineSegment(thisPoint.point, otherPoint.point);\n },\n CircleEdgeClosestLine(circle, edge) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n const circleWorldPos = circle.worldPos;\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const p0 = edgeStart;\n const u = edgeVector;\n // Time of minimum distance\n let t = (u.x * (circleWorldPos.x - p0.x) + u.y * (circleWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp to edge\n if (t > 1) {\n t = 1;\n }\n else if (t < 0) {\n t = 0;\n }\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorldPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorldPos.y, 2)) - circle.radius;\n const circlex = ((p0.x + u.x * t - circleWorldPos.x) * circle.radius) / (circle.radius + d);\n const circley = ((p0.y + u.y * t - circleWorldPos.y) * circle.radius) / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorldPos.x + circlex, circleWorldPos.y + circley));\n },\n EdgeEdgeClosestLine(edgeA, edgeB) {\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLineA = edgeA.asLine();\n const edgeStartA = edgeLineA.begin;\n const edgeVectorA = edgeLineA.getEdge();\n const p0 = edgeStartA;\n const u = edgeVectorA;\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLineB = edgeB.asLine();\n const edgeStartB = edgeLineB.begin;\n const edgeVectorB = edgeLineB.getEdge();\n const q0 = edgeStartB;\n const v = edgeVectorB;\n return ClosestLine(p0, u, q0, v);\n }\n};\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CircleCollider.ts\n\n\n\n\n\n\n\n\n\n\n\n/**\n * This is a circle collider for the excalibur rigid body physics simulation\n */\nclass CircleCollider extends Collider {\n get worldPos() {\n return this._globalMatrix.getPosition();\n }\n /**\n * Get the radius of the circle\n */\n get radius() {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n return this._naturalRadius * Math.min(scale.x, scale.y);\n }\n /**\n * Set the radius of the circle\n */\n set radius(val) {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n this._naturalRadius = val / Math.min(scale.x, scale.y);\n }\n constructor(options) {\n super();\n /**\n * Position of the circle relative to the collider, by default (0, 0).\n */\n this.offset = Vector.Zero;\n this._globalMatrix = AffineMatrix.identity();\n this.offset = options.offset || Vector.Zero;\n this.radius = options.radius || 0;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Returns a clone of this shape, not associated with any collider\n */\n clone() {\n return new CircleCollider({\n offset: this.offset.clone(),\n radius: this.radius\n });\n }\n /**\n * Get the center of the collider in world coordinates\n */\n get center() {\n return this._globalMatrix.getPosition();\n }\n /**\n * Tests if a point is contained in this collider\n */\n contains(point) {\n var _a, _b;\n const pos = (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : this.offset;\n const distance = pos.distance(point);\n if (distance <= this.radius) {\n return true;\n }\n return false;\n }\n /**\n * Casts a ray at the Circle collider and returns the nearest point of collision\n * @param ray\n */\n rayCast(ray, max = Infinity) {\n var _a, _b;\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\n const c = this.center;\n const dir = ray.dir;\n const orig = ray.pos;\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\n if (discriminant < 0) {\n // no intersection\n return null;\n }\n else {\n let toi = 0;\n // tangent case\n if (discriminant === 0) {\n toi = -dir.dot(orig.sub(c));\n if (toi > 0 && toi < max) {\n const point = ray.getPoint(toi);\n return {\n point,\n normal: point.sub(c).normalize(),\n collider: this,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n distance: toi\n };\n }\n return null;\n }\n else { // two point\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\n const positiveToi = [];\n if (toi1 >= 0) {\n positiveToi.push(toi1);\n }\n if (toi2 >= 0) {\n positiveToi.push(toi2);\n }\n const minToi = Math.min(...positiveToi);\n if (minToi <= max) {\n const point = ray.getPoint(minToi);\n return {\n point,\n normal: point.sub(c).normalize(),\n collider: this,\n body: (_b = this.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent),\n distance: minToi\n };\n }\n return null;\n }\n }\n }\n getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) {\n return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\n }\n else if (shape instanceof PolygonCollider) {\n return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\n }\n else if (shape instanceof EdgeCollider) {\n return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\n }\n else {\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n }\n /**\n * @inheritdoc\n */\n collide(collider) {\n if (collider instanceof CircleCollider) {\n return CollisionJumpTable.CollideCircleCircle(this, collider);\n }\n else if (collider instanceof PolygonCollider) {\n return CollisionJumpTable.CollideCirclePolygon(this, collider);\n }\n else if (collider instanceof EdgeCollider) {\n return CollisionJumpTable.CollideCircleEdge(this, collider);\n }\n else {\n throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\n }\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */\n getFurthestPoint(direction) {\n return this.center.add(direction.normalize().scale(this.radius));\n }\n /**\n * Find the local point on the shape in the direction specified\n * @param direction\n */\n getFurthestLocalPoint(direction) {\n const dir = direction.normalize();\n return dir.scale(this.radius);\n }\n /**\n * Get the axis aligned bounding box for the circle collider in world coordinates\n */\n get bounds() {\n var _a, _b, _c;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = ((_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero);\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius).rotate(rotation).scale(scale).translate(pos);\n }\n /**\n * Get the axis aligned bounding box for the circle collider in local coordinates\n */\n get localBounds() {\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius);\n }\n /**\n * Get axis not implemented on circles, since there are infinite axis in a circle\n */\n get axes() {\n return [];\n }\n /**\n * Returns the moment of inertia of a circle given it's mass\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */\n getInertia(mass) {\n return (mass * this.radius * this.radius) / 2;\n }\n /* istanbul ignore next */\n update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Project the circle along a specified axis\n */\n project(axis) {\n const scalars = [];\n const point = this.center;\n const dotProduct = point.dot(axis);\n scalars.push(dotProduct);\n scalars.push(dotProduct + this.radius);\n scalars.push(dotProduct - this.radius);\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color, options) {\n var _a, _b, _c, _d;\n const { lineWidth } = { ...{ lineWidth: 1 }, ...options };\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = ((_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero);\n ex.save();\n ex.translate(pos.x, pos.y);\n ex.rotate(rotation);\n ex.scale(scale.x, scale.y);\n ex.drawCircle(((_d = this.offset) !== null && _d !== void 0 ? _d : Vector.Zero), this._naturalRadius, Color.Transparent, color, lineWidth);\n ex.restore();\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Detection/CollisionContact.ts\n\n\n\n/**\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\n * Pair prevents collisions from being evaluated more than one time\n */\nclass CollisionContact {\n constructor(colliderA, colliderB, mtv, normal, tangent, points, localPoints, info) {\n var _a, _b, _c, _d, _e, _f;\n this._canceled = false;\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.mtv = mtv;\n this.normal = normal;\n this.tangent = tangent;\n this.points = points;\n this.localPoints = localPoints;\n this.info = info;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n if (colliderA.composite || colliderB.composite) {\n // Add on the parent composite pair for start/end contact if 'together\n const colliderAId = ((_a = colliderA.composite) === null || _a === void 0 ? void 0 : _a.compositeStrategy) === 'separate' ? colliderA.id : (_c = (_b = colliderA.composite) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : colliderA.id;\n const colliderBId = ((_d = colliderB.composite) === null || _d === void 0 ? void 0 : _d.compositeStrategy) === 'separate' ? colliderB.id : (_f = (_e = colliderB.composite) === null || _e === void 0 ? void 0 : _e.id) !== null && _f !== void 0 ? _f : colliderB.id;\n this.id += '|' + Pair.calculatePairHash(colliderAId, colliderBId);\n }\n }\n /**\n * Match contact awake state, except if body's are Fixed\n */\n matchAwake() {\n const bodyA = this.colliderA.owner.get(BodyComponent);\n const bodyB = this.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.sleeping !== bodyB.sleeping) {\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= bodyA.wakeThreshold) {\n bodyA.setSleeping(false);\n }\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= bodyB.wakeThreshold) {\n bodyB.setSleeping(false);\n }\n }\n }\n }\n isCanceled() {\n return this._canceled;\n }\n cancel() {\n this._canceled = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/SeparatingAxis.ts\nclass SeparatingAxis {\n static findPolygonPolygonSeparation(polyA, polyB) {\n let bestSeparation = -Number.MAX_VALUE;\n let bestSide = null;\n let bestAxis = null;\n let bestSideIndex = -1;\n let bestOtherPoint = null;\n const sides = polyA.getSides();\n const localSides = polyA.getLocalSides();\n for (let i = 0; i < sides.length; i++) {\n const side = sides[i];\n const axis = side.normal();\n const vertB = polyB.getFurthestPoint(axis.negate());\n // Separation on side i's axis\n // We are looking for the largest separation between poly A's sides\n const vertSeparation = side.distanceToPoint(vertB, true);\n if (vertSeparation > bestSeparation) {\n bestSeparation = vertSeparation;\n bestSide = side;\n bestAxis = axis;\n bestSideIndex = i;\n bestOtherPoint = vertB;\n }\n }\n return {\n collider: polyA,\n separation: bestAxis ? bestSeparation : 99,\n axis: bestAxis,\n side: bestSide,\n localSide: localSides[bestSideIndex],\n sideId: bestSideIndex,\n point: bestOtherPoint,\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis.negate()) : null\n };\n }\n static findCirclePolygonSeparation(circle, polygon) {\n const axes = polygon.axes;\n const pc = polygon.center;\n // Special SAT with circles\n const polyDir = pc.sub(circle.worldPos);\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\n let minOverlap = Number.MAX_VALUE;\n let minAxis = null;\n let minIndex = -1;\n for (let i = 0; i < axes.length; i++) {\n const proj1 = polygon.project(axes[i]);\n const proj2 = circle.project(axes[i]);\n const overlap = proj1.getOverlap(proj2);\n if (overlap <= 0) {\n return null;\n }\n else {\n if (overlap < minOverlap) {\n minOverlap = overlap;\n minAxis = axes[i];\n minIndex = i;\n }\n }\n }\n if (minIndex < 0) {\n return null;\n }\n return minAxis.normalize().scale(minOverlap);\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CollisionJumpTable.ts\n\n\n\n\n\n\n\n\nconst CollisionJumpTable = {\n CollideCircleCircle(circleA, circleB) {\n const circleAPos = circleA.worldPos;\n const circleBPos = circleB.worldPos;\n const combinedRadius = circleA.radius + circleB.radius;\n const distance = circleAPos.distance(circleBPos);\n if (distance > combinedRadius) {\n return [];\n }\n // negative means overlap\n const separation = combinedRadius - distance;\n // Normal points from A -> B\n const normal = circleBPos.sub(circleAPos).normalize();\n const tangent = normal.perpendicular();\n const mvt = normal.scale(separation);\n const point = circleA.getFurthestPoint(normal);\n const local = circleA.getFurthestLocalPoint(normal);\n const info = {\n collider: circleA,\n separation,\n axis: normal,\n point: point\n };\n return [new CollisionContact(circleA, circleB, mvt, normal, tangent, [point], [local], info)];\n },\n CollideCirclePolygon(circle, polygon) {\n var _a, _b;\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\n if (!minAxis) {\n return [];\n }\n // make sure that the minAxis is pointing away from circle\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\n const point = circle.getFurthestPoint(minAxis);\n const xf = (_b = (_a = circle.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const local = xf.applyInverse(point);\n const normal = minAxis.normalize();\n const info = {\n collider: circle,\n separation: -minAxis.size,\n axis: normal,\n point: point,\n localPoint: local,\n side: polygon.findSide(normal.negate()),\n localSide: polygon.findLocalSide(normal.negate())\n };\n return [new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [point], [local], info)];\n },\n CollideCircleEdge(circle, edge) {\n // TODO not sure this actually abides by local/world collisions\n // Are edge.begin and edge.end local space or world space? I think they should be local\n // center of the circle in world pos\n const cc = circle.center;\n // vector in the direction of the edge\n const edgeWorld = edge.asLine();\n const e = edgeWorld.end.sub(edgeWorld.begin);\n // amount of overlap with the circle's center along the edge direction\n const u = e.dot(edgeWorld.end.sub(cc));\n const v = e.dot(cc.sub(edgeWorld.begin));\n const side = edge.asLine();\n const localSide = edge.asLocalLine();\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\n if (v <= 0) {\n const da = edgeWorld.begin.sub(cc);\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\n // save some sqrts\n if (dda > circle.radius * circle.radius) {\n return []; // no collision\n }\n const normal = da.normalize();\n const separation = circle.radius - Math.sqrt(dda);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.begin,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.begin], [localSide.begin], info)\n ];\n }\n // Potential region B collision (circle is on the right side of the edge, after the end)\n if (u <= 0) {\n const db = edgeWorld.end.sub(cc);\n const ddb = db.dot(db);\n if (ddb > circle.radius * circle.radius) {\n return [];\n }\n const normal = db.normalize();\n const separation = circle.radius - Math.sqrt(ddb);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.end,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.end], [localSide.end], info)\n ];\n }\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\n const den = e.dot(e);\n const pointOnEdge = edgeWorld.begin\n .scale(u)\n .add(edgeWorld.end.scale(v))\n .scale(1 / den);\n const d = cc.sub(pointOnEdge);\n const dd = d.dot(d);\n if (dd > circle.radius * circle.radius) {\n return []; // no collision\n }\n let normal = e.perpendicular();\n // flip correct direction\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\n normal.x = -normal.x;\n normal.y = -normal.y;\n }\n normal = normal.normalize();\n const separation = circle.radius - Math.sqrt(dd);\n const mvt = normal.scale(separation);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: pointOnEdge,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, mvt, normal.negate(), normal.negate().perpendicular(), [pointOnEdge], [pointOnEdge.sub(edge.worldPos)], info)\n ];\n },\n CollideEdgeEdge() {\n // Edge-edge collision doesn't make sense\n return [];\n },\n CollidePolygonEdge(polygon, edge) {\n var _a;\n const pc = polygon.center;\n const ec = edge.center;\n const dir = ec.sub(pc).normalize();\n // build a temporary polygon from the edge to use SAT\n const linePoly = new PolygonCollider({\n points: [edge.begin, edge.end, edge.end.add(dir.scale(100)), edge.begin.add(dir.scale(100))],\n offset: edge.offset\n });\n linePoly.owner = edge.owner;\n const tx = (_a = edge.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (tx) {\n linePoly.update(edge.owner.get(TransformComponent).get());\n }\n // Gross hack but poly-poly works well\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\n if (contact.length) {\n // Fudge the contact back to edge\n contact[0].colliderB = edge;\n contact[0].id = Pair.calculatePairHash(polygon.id, edge.id);\n }\n return contact;\n },\n CollidePolygonPolygon(polyA, polyB) {\n var _a, _b, _c, _d;\n // Multi contact from SAT\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\n // do a SAT test to find a min axis if it exists\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\n // If there is no overlap from boxA's perspective we can end early\n if (separationA.separation > 0) {\n return [];\n }\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\n // If there is no overlap from boxB's perspective exit now\n if (separationB.separation > 0) {\n return [];\n }\n // Separations are both negative, we want to pick the least negative (minimal movement)\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\n // The incident side is the most opposite from the axes of collision on the other collider\n const other = separation.collider === polyA ? polyB : polyA;\n const incident = other.findSide(separation.axis.negate());\n // Clip incident side by the perpendicular lines at each end of the reference side\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\n const reference = separation.side;\n const refDir = reference.dir().normalize();\n // Find our contact points by clipping the incident by the collision side\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\n let clipLeft = null;\n if (clipRight) {\n clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\n }\n // If there is no left there is no collision\n if (clipLeft) {\n // We only want clip points below the reference edge, discard the others\n const points = clipLeft.getPoints().filter((p) => {\n return reference.below(p);\n });\n let normal = separation.axis;\n let tangent = normal.perpendicular();\n // Point Contact A -> B\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\n normal = normal.negate();\n tangent = normal.perpendicular();\n }\n // Points are clipped from incident which is the other collider\n // Store those as locals\n let localPoints = [];\n if (separation.collider === polyA) {\n const xf = (_b = (_a = polyB.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n localPoints = points.map((p) => xf.applyInverse(p));\n }\n else {\n const xf = (_d = (_c = polyA.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n localPoints = points.map((p) => xf.applyInverse(p));\n }\n return [new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)];\n }\n return [];\n },\n FindContactSeparation(contact, localPoint) {\n var _a, _b, _c, _d;\n const shapeA = contact.colliderA;\n const txA = (_b = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const shapeB = contact.colliderB;\n const txB = (_d = (_c = contact.colliderB.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n // both are circles\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\n const combinedRadius = shapeA.radius + shapeB.radius;\n const distance = txA.pos.distance(txB.pos);\n const separation = combinedRadius - distance;\n return -separation;\n }\n // both are polygons\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\n if (contact.info.localSide) {\n let side;\n let worldPoint;\n if (contact.info.collider === shapeA) {\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\n worldPoint = txB.apply(localPoint);\n }\n else {\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\n worldPoint = txA.apply(localPoint);\n }\n return side.distanceToPoint(worldPoint, true);\n }\n }\n // polygon v circle\n if ((shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider) ||\n (shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider)) {\n const worldPoint = txA.apply(localPoint);\n if (contact.info.side) {\n return contact.info.side.distanceToPoint(worldPoint, true);\n }\n }\n // polygon v edge\n if ((shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider) ||\n (shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider)) {\n let worldPoint;\n if (contact.info.collider === shapeA) {\n worldPoint = txB.apply(localPoint);\n }\n else {\n worldPoint = txA.apply(localPoint);\n }\n if (contact.info.side) {\n return contact.info.side.distanceToPoint(worldPoint, true);\n }\n }\n // circle v edge\n if ((shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider) ||\n (shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider)) {\n // Local point is always on the edge which is always shapeB\n const worldPoint = txB.apply(localPoint);\n let circlePoint;\n if (shapeA instanceof CircleCollider) {\n circlePoint = shapeA.getFurthestPoint(contact.normal);\n }\n const dist = worldPoint.distance(circlePoint);\n if (contact.info.side) {\n return dist > 0 ? -dist : 0;\n }\n }\n return 0;\n }\n};\n\n;// CONCATENATED MODULE: ./Collision/Colliders/EdgeCollider.ts\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Edge is a single line collider to create collisions with a single line.\n */\nclass EdgeCollider extends Collider {\n constructor(options) {\n var _a;\n super();\n this._globalMatrix = AffineMatrix.identity();\n this.begin = options.begin || Vector.Zero;\n this.end = options.end || Vector.Zero;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n }\n /**\n * Returns a clone of this Edge, not associated with any collider\n */\n clone() {\n return new EdgeCollider({\n begin: this.begin.clone(),\n end: this.end.clone()\n });\n }\n get worldPos() {\n var _a;\n const tx = this._transform;\n return (_a = tx === null || tx === void 0 ? void 0 : tx.globalPos.add(this.offset)) !== null && _a !== void 0 ? _a : this.offset;\n }\n /**\n * Get the center of the collision area in world coordinates\n */\n get center() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const pos = begin.average(end);\n return pos;\n }\n _getTransformedBegin() {\n return this._globalMatrix.multiply(this.begin);\n }\n _getTransformedEnd() {\n return this._globalMatrix.multiply(this.end);\n }\n /**\n * Returns the slope of the line in the form of a vector\n */\n getSlope() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return end.sub(begin).scale(1 / distance);\n }\n /**\n * Returns the length of the line segment in pixels\n */\n getLength() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return distance;\n }\n /**\n * Tests if a point is contained in this collision area\n */\n contains() {\n return false;\n }\n /**\n * @inheritdoc\n */\n rayCast(ray, max = Infinity) {\n var _a;\n const numerator = this._getTransformedBegin().sub(ray.pos);\n // Test is line and ray are parallel and non intersecting\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) {\n return null;\n }\n // Lines are parallel\n const divisor = ray.dir.cross(this.getSlope());\n if (divisor === 0) {\n return null;\n }\n const t = numerator.cross(this.getSlope()) / divisor;\n if (t >= 0 && t <= max) {\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\n if (u >= 0 && u <= 1) {\n return {\n distance: t,\n normal: this.asLine().normal(),\n collider: this,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n point: ray.getPoint(t)\n };\n }\n }\n return null;\n }\n /**\n * Returns the closes line between this and another collider, from this -> collider\n * @param shape\n */\n getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) {\n return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\n }\n else if (shape instanceof PolygonCollider) {\n return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\n }\n else if (shape instanceof EdgeCollider) {\n return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\n }\n else {\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n }\n /**\n * @inheritdoc\n */\n collide(shape) {\n if (shape instanceof CircleCollider) {\n return CollisionJumpTable.CollideCircleEdge(shape, this);\n }\n else if (shape instanceof PolygonCollider) {\n return CollisionJumpTable.CollidePolygonEdge(shape, this);\n }\n else if (shape instanceof EdgeCollider) {\n return CollisionJumpTable.CollideEdgeEdge();\n }\n else {\n throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\n }\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */\n getFurthestPoint(direction) {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n if (direction.dot(transformedBegin) > 0) {\n return transformedBegin;\n }\n else {\n return transformedEnd;\n }\n }\n _boundsFromBeginEnd(begin, end, padding = 10) {\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\n // this causes problems for the collision system so we give them some padding\n return new BoundingBox(Math.min(begin.x, end.x) - padding, Math.min(begin.y, end.y) - padding, Math.max(begin.x, end.x) + padding, Math.max(begin.y, end.y) + padding);\n }\n /**\n * Get the axis aligned bounding box for the edge collider in world space\n */\n get bounds() {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\n }\n /**\n * Get the axis aligned bounding box for the edge collider in local space\n */\n get localBounds() {\n return this._boundsFromBeginEnd(this.begin, this.end);\n }\n /**\n * Returns this edge represented as a line in world coordinates\n */\n asLine() {\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\n }\n /**\n * Return this edge as a line in local line coordinates (relative to the position)\n */\n asLocalLine() {\n return new LineSegment(this.begin, this.end);\n }\n /**\n * Get the axis associated with the edge\n */\n get axes() {\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\n const edgeNormal = e.normal();\n const axes = [];\n axes.push(edgeNormal);\n axes.push(edgeNormal.negate());\n axes.push(edgeNormal.normal());\n axes.push(edgeNormal.normal().negate());\n return axes;\n }\n /**\n * Get the moment of inertia for an edge\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */\n getInertia(mass) {\n const length = this.end.sub(this.begin).distance() / 2;\n return mass * length * length;\n }\n /**\n * @inheritdoc\n */\n update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\n * Project the edge along a specified axis\n */\n project(axis) {\n const scalars = [];\n const points = [this._getTransformedBegin(), this._getTransformedEnd()];\n const len = points.length;\n for (let i = 0; i < len; i++) {\n scalars.push(points[i].dot(axis));\n }\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color) {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n ex.drawLine(begin, end, color, 2);\n ex.drawCircle(begin, 2, color);\n ex.drawCircle(end, 2, color);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Debug.ts\n\nclass Debug {\n static registerGraphicsContext(ctx) {\n Debug._ctx = ctx;\n }\n static draw(debugDrawCall) {\n this._drawCalls.push(debugDrawCall);\n }\n static drawPoint(point, options) {\n Debug.draw(ctx => {\n ctx.debug.drawPoint(point, options);\n });\n }\n static drawLine(start, end, options) {\n Debug.draw(ctx => {\n ctx.debug.drawLine(start, end, options);\n });\n }\n static drawLines(points, options) {\n if (points.length > 1) {\n Debug.draw(ctx => {\n for (let i = 0; i < points.length - 1; i++) {\n ctx.debug.drawLine(points[i], points[i + 1], options);\n }\n });\n }\n }\n static drawText(text, pos) {\n Debug.draw(ctx => {\n ctx.debug.drawText(text, pos);\n });\n }\n static drawPolygon(points, options) {\n if (points.length > 1) {\n Debug.draw(ctx => {\n const firstPoint = points[0];\n const polygon = [...points, firstPoint];\n for (let i = 0; i < polygon.length - 1; i++) {\n ctx.debug.drawLine(polygon[i], polygon[i + 1], options);\n }\n });\n }\n }\n static drawCircle(center, radius, options) {\n const { color, strokeColor, width } = {\n color: Color.Black,\n strokeColor: undefined,\n width: undefined,\n ...options\n };\n Debug.draw(ctx => {\n ctx.drawCircle(center, radius, color, strokeColor, width);\n });\n }\n static drawBounds(boundingBox, options) {\n Debug.draw(ctx => {\n ctx.debug.drawRect(boundingBox.left, boundingBox.top, boundingBox.width, boundingBox.height, options);\n });\n }\n static drawRay(ray, options) {\n const { distance, color } = {\n color: Color.Blue,\n distance: 10,\n ...options\n };\n Debug.draw((ctx) => {\n const start = ray.pos;\n const end = ray.pos.add(ray.dir.scale(distance));\n ctx.debug.drawLine(start, end, { color });\n });\n }\n static flush(ctx) {\n ctx.save();\n ctx.z = Debug.z;\n for (const drawCall of Debug._drawCalls) {\n drawCall(ctx);\n }\n ctx.restore();\n Debug.clear();\n }\n static clear() {\n Debug._drawCalls.length = 0;\n }\n}\nDebug._drawCalls = [];\nDebug.z = Infinity;\n\n;// CONCATENATED MODULE: ./Collision/Colliders/PolygonCollider.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Polygon collider for detecting collisions\n */\nclass PolygonCollider extends Collider {\n flagDirty() {\n this._localBoundsDirty = true;\n this._localSidesDirty = true;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n }\n /**\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\n * Excalibur stores these in counter-clockwise order\n */\n set points(points) {\n this._points = points;\n this.flagDirty();\n }\n /**\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\n * Excalibur stores these in counter-clockwise order\n */\n get points() {\n return this._points;\n }\n constructor(options) {\n var _a, _b;\n super();\n this._logger = Logger.getInstance();\n this._transformedPoints = [];\n this._sides = [];\n this._localSides = [];\n this._globalMatrix = AffineMatrix.identity();\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n this._localSidesDirty = true;\n this._localBoundsDirty = true;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n this.points = (_b = options.points) !== null && _b !== void 0 ? _b : [];\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\n if (!counterClockwise) {\n this.points.reverse();\n }\n if (!this.isConvex()) {\n if (!options.suppressConvexWarning) {\n this._logger.warn('Excalibur only supports convex polygon colliders and will not behave properly.' +\n 'Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles');\n }\n }\n // calculate initial transformation\n this._calculateTransformation();\n }\n _isCounterClockwiseWinding(points) {\n // https://stackoverflow.com/a/1165943\n let sum = 0;\n for (let i = 0; i < points.length; i++) {\n sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\n }\n return sum < 0;\n }\n /**\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\n */\n isConvex() {\n // From SO: https://stackoverflow.com/a/45372025\n if (this.points.length < 3) {\n return false;\n }\n let oldPoint = this.points[this.points.length - 2];\n let newPoint = this.points[this.points.length - 1];\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n let oldDirection = 0;\n let orientation = 0;\n let angleSum = 0;\n for (const [i, point] of this.points.entries()) {\n oldPoint = newPoint;\n oldDirection = direction;\n newPoint = point;\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n if (oldPoint.equals(newPoint)) {\n return false; // repeat point\n }\n let angle = direction - oldDirection;\n if (angle <= -Math.PI) {\n angle += Math.PI * 2;\n }\n else if (angle > Math.PI) {\n angle -= Math.PI * 2;\n }\n if (i === 0) {\n if (angle === 0.0) {\n return false;\n }\n orientation = angle > 0 ? 1 : -1;\n }\n else {\n if (orientation * angle <= 0) {\n return false;\n }\n }\n angleSum += angle;\n }\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\n }\n /**\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\n */\n tessellate() {\n const polygons = [];\n for (let i = 1; i < this.points.length - 2; i++) {\n polygons.push([this.points[0], this.points[i + 1], this.points[i + 2]]);\n }\n polygons.push([this.points[0], this.points[1], this.points[2]]);\n return new CompositeCollider(polygons.map(points => Shape.Polygon(points)));\n }\n /**\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\n */\n triangulate() {\n // https://www.youtube.com/watch?v=hTJFcHutls8\n if (this.points.length < 3) {\n throw Error('Invalid polygon');\n }\n const triangles = [];\n // algorithm likes clockwise\n const vertices = [...this.points].reverse();\n let vertexCount = vertices.length;\n /**\n * Returns the previous index based on the current vertex\n */\n function getPrevIndex(index) {\n return index === 0 ? vertexCount - 1 : index - 1;\n }\n /**\n * Retrieves the next index based on the current vertex\n */\n function getNextIndex(index) {\n return index === vertexCount - 1 ? 0 : index + 1;\n }\n /**\n * Whether or not the angle at this vertex index is convex\n */\n function isConvex(index) {\n const prev = getPrevIndex(index);\n const next = getNextIndex(index);\n const va = vertices[prev];\n const vb = vertices[index];\n const vc = vertices[next];\n // Check convexity\n const leftArm = va.sub(vb);\n const rightArm = vc.sub(vb);\n // Positive cross product is convex\n if (leftArm.cross(rightArm) < 0) {\n return false;\n }\n return true;\n }\n const convexVertices = vertices.map((_, i) => isConvex(i));\n /**\n * Quick test for point in triangle\n */\n function isPointInTriangle(point, a, b, c) {\n const ab = b.sub(a);\n const bc = c.sub(b);\n const ca = a.sub(c);\n const ap = point.sub(a);\n const bp = point.sub(b);\n const cp = point.sub(c);\n const cross1 = ab.cross(ap);\n const cross2 = bc.cross(bp);\n const cross3 = ca.cross(cp);\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) {\n return false;\n }\n return true;\n }\n /**\n * Calculate the area of the triangle\n */\n // function triangleArea(a: Vector, b: Vector, c: Vector) {\n // return Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - c.y))/2;\n // }\n /**\n * Find the next suitable ear tip\n */\n function findEarTip() {\n for (let i = 0; i < vertexCount; i++) {\n if (convexVertices[i]) {\n const prev = getPrevIndex(i);\n const next = getNextIndex(i);\n const va = vertices[prev];\n const vb = vertices[i];\n const vc = vertices[next];\n let isEar = true;\n // Check that if any vertices are in the triangle a, b, c\n for (let j = 0; j < vertexCount; j++) {\n // We can skip these verts because they are the triangle we are testing\n if (j === i || j === prev || j === next) {\n continue;\n }\n const point = vertices[j];\n if (isPointInTriangle(point, va, vb, vc)) {\n isEar = false;\n break;\n }\n }\n // Add ear to polygon list and remove from list\n if (isEar) {\n return i;\n }\n }\n }\n // Fall back to any convex vertex\n for (let i = 0; i < vertexCount; i++) {\n if (convexVertices[i]) {\n return i;\n }\n }\n // bail and return the first one?\n return 0;\n }\n /**\n * Cut the ear and produce a triangle, update internal state\n */\n function cutEarTip(index) {\n const prev = getPrevIndex(index);\n const next = getNextIndex(index);\n const va = vertices[prev];\n const vb = vertices[index];\n const vc = vertices[next];\n // Clockwise winding\n // if (triangleArea(va, vb, vc) > 0) {\n triangles.push([va, vb, vc]);\n // }\n vertices.splice(index, 1);\n convexVertices.splice(index, 1);\n vertexCount--;\n }\n // Loop over all the vertices finding ears\n while (vertexCount > 3) {\n const earIndex = findEarTip();\n cutEarTip(earIndex);\n // reclassify vertices\n for (let i = 0; i < vertexCount; i++) {\n convexVertices[i] = isConvex(i);\n }\n }\n // Last triangle after the loop\n triangles.push([vertices[0], vertices[1], vertices[2]]);\n // FIXME: there is a colinear triangle that sneaks in here sometimes\n return new CompositeCollider(triangles.map(points => Shape.Polygon(points, Vector.Zero, true)));\n }\n /**\n * Returns a clone of this ConvexPolygon, not associated with any collider\n */\n clone() {\n return new PolygonCollider({\n offset: this.offset.clone(),\n points: this.points.map((p) => p.clone())\n });\n }\n /**\n * Returns the world position of the collider, which is the current body transform plus any defined offset\n */\n get worldPos() {\n if (this._transform) {\n return this._transform.pos.add(this.offset);\n }\n return this.offset;\n }\n /**\n * Get the center of the collider in world coordinates\n */\n get center() {\n return this.bounds.center;\n }\n /**\n * Calculates the underlying transformation from the body relative space to world space\n */\n _calculateTransformation() {\n const points = this.points;\n const len = points.length;\n this._transformedPoints.length = 0; // clear out old transform\n for (let i = 0; i < len; i++) {\n this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\n }\n }\n /**\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\n */\n getTransformedPoints() {\n if (this._transformedPointsDirty) {\n this._calculateTransformation();\n this._transformedPointsDirty = false;\n }\n return this._transformedPoints;\n }\n /**\n * Gets the sides of the polygon in world space\n */\n getSides() {\n if (this._sidesDirty) {\n const lines = [];\n const points = this.getTransformedPoints();\n const len = points.length;\n for (let i = 0; i < len; i++) {\n // This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n }\n this._sides = lines;\n this._sidesDirty = false;\n }\n return this._sides;\n }\n /**\n * Returns the local coordinate space sides\n */\n getLocalSides() {\n if (this._localSidesDirty) {\n const lines = [];\n const points = this.points;\n const len = points.length;\n for (let i = 0; i < len; i++) {\n // This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n }\n this._localSides = lines;\n this._localSidesDirty = false;\n }\n return this._localSides;\n }\n /**\n * Given a direction vector find the world space side that is most in that direction\n * @param direction\n */\n findSide(direction) {\n const sides = this.getSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for (let side = 0; side < sides.length; side++) {\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\n * Given a direction vector find the local space side that is most in that direction\n * @param direction\n */\n findLocalSide(direction) {\n const sides = this.getLocalSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for (let side = 0; side < sides.length; side++) {\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\n * Get the axis associated with the convex polygon\n */\n get axes() {\n const axes = [];\n const sides = this.getSides();\n for (let i = 0; i < sides.length; i++) {\n axes.push(sides[i].normal());\n }\n return axes;\n }\n /**\n * Updates the transform for the collision geometry\n *\n * Collision geometry (points/bounds) will not change until this is called.\n * @param transform\n */\n update(transform) {\n var _a;\n if (transform) {\n this._transform = transform;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n // This change means an update must be performed in order for geometry to update\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n }\n /**\n * Tests if a point is contained in this collider in world space\n */\n contains(point) {\n // Always cast to the right, as long as we cast in a consistent fixed direction we\n // will be fine\n const testRay = new Ray(point, new Vector(1, 0));\n const intersectCount = this.getSides().reduce(function (accum, side) {\n if (testRay.intersect(side) >= 0) {\n return accum + 1;\n }\n return accum;\n }, 0);\n if (intersectCount % 2 === 0) {\n return false;\n }\n return true;\n }\n getClosestLineBetween(collider) {\n if (collider instanceof CircleCollider) {\n return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\n }\n else if (collider instanceof PolygonCollider) {\n return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\n }\n else if (collider instanceof EdgeCollider) {\n return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\n }\n else {\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n }\n /**\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\n * return null.\n * @param collider\n */\n collide(collider) {\n if (collider instanceof CircleCollider) {\n return CollisionJumpTable.CollideCirclePolygon(collider, this);\n }\n else if (collider instanceof PolygonCollider) {\n return CollisionJumpTable.CollidePolygonPolygon(this, collider);\n }\n else if (collider instanceof EdgeCollider) {\n return CollisionJumpTable.CollidePolygonEdge(this, collider);\n }\n else {\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n }\n /**\n * Find the point on the collider furthest in the direction specified\n */\n getFurthestPoint(direction) {\n const pts = this.getTransformedPoints();\n let furthestPoint = null;\n let maxDistance = -Number.MAX_VALUE;\n for (let i = 0; i < pts.length; i++) {\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\n * Find the local point on the collider furthest in the direction specified\n * @param direction\n */\n getFurthestLocalPoint(direction) {\n const pts = this.points;\n let furthestPoint = pts[0];\n let maxDistance = -Number.MAX_VALUE;\n for (let i = 0; i < pts.length; i++) {\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\n * Finds the closes face to the point using perpendicular distance\n * @param point point to test against polygon\n */\n getClosestFace(point) {\n const sides = this.getSides();\n let min = Number.POSITIVE_INFINITY;\n let faceIndex = -1;\n let distance = -1;\n for (let i = 0; i < sides.length; i++) {\n const dist = sides[i].distanceToPoint(point);\n if (dist < min) {\n min = dist;\n faceIndex = i;\n distance = dist;\n }\n }\n if (faceIndex !== -1) {\n return {\n distance: sides[faceIndex].normal().scale(distance),\n face: sides[faceIndex]\n };\n }\n return null;\n }\n /**\n * Get the axis aligned bounding box for the polygon collider in world coordinates\n */\n get bounds() {\n return this.localBounds.transform(this._globalMatrix);\n }\n /**\n * Get the axis aligned bounding box for the polygon collider in local coordinates\n */\n get localBounds() {\n if (this._localBoundsDirty) {\n this._localBounds = BoundingBox.fromPoints(this.points);\n this._localBoundsDirty = false;\n }\n return this._localBounds;\n }\n /**\n * Get the moment of inertia for an arbitrary polygon\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\n */\n getInertia(mass) {\n if (this._cachedMass === mass && this._cachedInertia) {\n return this._cachedInertia;\n }\n let numerator = 0;\n let denominator = 0;\n const points = this.points;\n for (let i = 0; i < points.length; i++) {\n const iplusone = (i + 1) % points.length;\n const crossTerm = points[iplusone].cross(points[i]);\n numerator +=\n crossTerm *\n (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\n denominator += crossTerm;\n }\n this._cachedMass = mass;\n return this._cachedInertia = (mass / 6) * (numerator / denominator);\n }\n /**\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\n */\n rayCast(ray, max = Infinity) {\n var _a;\n // find the minimum contact time greater than 0\n // contact times less than 0 are behind the ray and we don't want those\n const sides = this.getSides();\n const len = sides.length;\n let minContactTime = Number.MAX_VALUE;\n let contactSide;\n let contactIndex = -1;\n for (let i = 0; i < len; i++) {\n const contactTime = ray.intersect(sides[i]);\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\n minContactTime = contactTime;\n contactSide = sides[i];\n contactIndex = i;\n }\n }\n // contact was found\n if (contactIndex >= 0) {\n return {\n collider: this,\n distance: minContactTime,\n body: (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent),\n point: ray.getPoint(minContactTime),\n normal: contactSide.normal()\n };\n }\n // no contact found\n return null;\n }\n /**\n * Project the edges of the polygon along a specified axis\n */\n project(axis) {\n const points = this.getTransformedPoints();\n const len = points.length;\n let min = Number.MAX_VALUE;\n let max = -Number.MAX_VALUE;\n for (let i = 0; i < len; i++) {\n const scalar = points[i].dot(axis);\n min = Math.min(min, scalar);\n max = Math.max(max, scalar);\n }\n return new Projection(min, max);\n }\n debug(ex, color, options) {\n const points = this.getTransformedPoints();\n Debug.drawPolygon(points, { color });\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Colliders/Shape.ts\n\n\n\n\n\n\n\n/**\n * Excalibur helper for defining colliders quickly\n */\nclass Shape {\n /**\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\n * @param width Width of the box\n * @param height Height of the box\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\n * @param offset Optional offset relative to the collider in local coordinates\n */\n static Box(width, height, anchor = Vector.Half, offset = Vector.Zero) {\n return new PolygonCollider({\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\n offset: offset\n });\n }\n /**\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\n *\n * PolygonColliders are useful for creating convex polygon shapes\n * @param points Points specified in counter clockwise\n * @param offset Optional offset relative to the collider in local coordinates\n */\n static Polygon(points, offset = Vector.Zero, suppressConvexWarning = false) {\n return new PolygonCollider({\n points: points,\n offset: offset,\n suppressConvexWarning\n });\n }\n /**\n * Creates a new [[CircleCollider|circle]] collider\n *\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\n * @param radius Radius of the circle collider\n * @param offset Optional offset relative to the collider in local coordinates\n */\n static Circle(radius, offset = Vector.Zero) {\n return new CircleCollider({\n radius: radius,\n offset: offset\n });\n }\n /**\n * Creates a new [[EdgeCollider|edge]] collider\n *\n * Edge colliders are useful for floors, walls, and other barriers\n * @param begin Beginning of the edge in local coordinates to the collider\n * @param end Ending of the edge in local coordinates to the collider\n */\n static Edge(begin, end) {\n return new EdgeCollider({\n begin: begin,\n end: end\n });\n }\n /**\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\n *\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\n * player experience.\n * @param width\n * @param height\n * @param offset Optional offset\n */\n static Capsule(width, height, offset = Vector.Zero) {\n const logger = Logger.getInstance();\n if (width === height) {\n logger.warn('A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider');\n }\n const vertical = height >= width;\n if (vertical) {\n // height > width, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\n Shape.Box(width, height - width, Vector.Half, offset),\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\n ]);\n return capsule;\n }\n else {\n // width > height, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\n Shape.Box(width - height, height, Vector.Half, offset),\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\n ]);\n return capsule;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/ColliderComponent.ts\n\n\n\n\n\n\n\n\n\n\nclass ColliderComponent extends Component {\n constructor(collider) {\n super();\n this.events = new EventEmitter();\n /**\n * Observable that notifies when a collider is added to the body\n */\n this.$colliderAdded = new Observable();\n /**\n * Observable that notifies when a collider is removed from the body\n */\n this.$colliderRemoved = new Observable();\n this._collidersToRemove = [];\n this.set(collider);\n }\n /**\n * Get the current collider geometry\n */\n get() {\n return this._collider;\n }\n /**\n * Set the collider geometry\n * @param collider\n * @returns the collider you set\n */\n set(collider) {\n this.clear();\n if (collider) {\n this._collider = collider;\n this._collider.owner = this.owner;\n collider.events.pipe(this.events);\n this.$colliderAdded.notifyAll(collider);\n this.update();\n }\n return collider;\n }\n /**\n * Remove collider geometry from collider component\n */\n clear() {\n if (this._collider) {\n this._collidersToRemove.push(this._collider);\n this._collider = null;\n }\n }\n processColliderRemoval() {\n for (const collider of this._collidersToRemove) {\n collider.events.unpipe(this.events);\n this.$colliderRemoved.notifyAll(collider);\n collider.owner = null;\n }\n }\n clone() {\n const clone = new ColliderComponent(this._collider.clone());\n return clone;\n }\n /**\n * Return world space bounds\n */\n get bounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\n * Return local space bounds\n */\n get localBounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\n * Update the collider's transformed geometry\n */\n update() {\n var _a;\n const tx = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (this._collider) {\n this._collider.owner = this.owner;\n if (tx) {\n this._collider.update(tx.get());\n }\n }\n }\n /**\n * Collide component with another\n * @param other\n */\n collide(other) {\n let colliderA = this._collider;\n let colliderB = other._collider;\n if (!colliderA || !colliderB) {\n return [];\n }\n // If we have a composite left hand side :(\n // Might bite us, but to avoid updating all the handlers make composite always left side\n let flipped = false;\n if (colliderB instanceof CompositeCollider) {\n colliderA = colliderB;\n colliderB = this._collider;\n flipped = true;\n }\n if (this._collider) {\n const contacts = colliderA.collide(colliderB);\n if (contacts) {\n if (flipped) {\n contacts.forEach((contact) => {\n contact.mtv = contact.mtv.negate();\n contact.normal = contact.normal.negate();\n contact.tangent = contact.normal.perpendicular();\n contact.colliderA = this._collider;\n contact.colliderB = other._collider;\n });\n }\n return contacts;\n }\n return [];\n }\n return [];\n }\n onAdd(entity) {\n if (this._collider) {\n this.update();\n }\n // Wire up the collider events to the owning entity\n this.events.on('precollision', (evt) => {\n const precollision = evt;\n entity.events.emit('precollision', new PreCollisionEvent(precollision.target.owner, precollision.other.owner, precollision.side, precollision.intersection, precollision.contact));\n if (entity instanceof Actor) {\n entity.onPreCollisionResolve(precollision.target, precollision.other, precollision.side, precollision.contact);\n }\n });\n this.events.on('postcollision', (evt) => {\n const postcollision = evt;\n entity.events.emit('postcollision', new PostCollisionEvent(postcollision.target.owner, postcollision.other.owner, postcollision.side, postcollision.intersection, postcollision.contact));\n if (entity instanceof Actor) {\n entity.onPostCollisionResolve(postcollision.target, postcollision.other, postcollision.side, postcollision.contact);\n }\n });\n this.events.on('collisionstart', (evt) => {\n const start = evt;\n entity.events.emit('collisionstart', new CollisionStartEvent(start.target.owner, start.other.owner, start.side, start.contact));\n if (entity instanceof Actor) {\n entity.onCollisionStart(start.target, start.other, start.side, start.contact);\n }\n });\n this.events.on('collisionend', (evt) => {\n const end = evt;\n entity.events.emit('collisionend', new CollisionEndEvent(end.target.owner, end.other.owner, end.side, end.lastContact));\n if (entity instanceof Actor) {\n entity.onCollisionEnd(end.target, end.other, end.side, end.lastContact);\n }\n });\n }\n onRemove() {\n this.events.clear();\n this.$colliderRemoved.notifyAll(this._collider);\n }\n /**\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\n *\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */\n useBoxCollider(width, height, anchor = Vector.Half, center = Vector.Zero) {\n const collider = Shape.Box(width, height, anchor, center);\n return (this.set(collider));\n }\n /**\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\n * to the anchor of the associated actor\n * of this physics body.\n *\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */\n usePolygonCollider(points, center = Vector.Zero) {\n const poly = Shape.Polygon(points, center);\n return (this.set(poly));\n }\n /**\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */\n useCircleCollider(radius, center = Vector.Zero) {\n const collider = Shape.Circle(radius, center);\n return (this.set(collider));\n }\n /**\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\n * of this physics body.\n *\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\n */\n useEdgeCollider(begin, end) {\n const collider = Shape.Edge(begin, end);\n return (this.set(collider));\n }\n /**\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\n * @param colliders\n */\n useCompositeCollider(colliders) {\n return (this.set(new CompositeCollider(colliders)));\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/BodyComponent.ts\n\n\n\n\n\n\n\n\n\n\n\n\nvar DegreeOfFreedom;\n(function (DegreeOfFreedom) {\n DegreeOfFreedom[\"Rotation\"] = \"rotation\";\n DegreeOfFreedom[\"X\"] = \"x\";\n DegreeOfFreedom[\"Y\"] = \"y\";\n})(DegreeOfFreedom || (DegreeOfFreedom = {}));\n/**\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\n * of physics simulation.\n */\nclass BodyComponent extends Component {\n constructor(options) {\n var _a, _b, _c;\n super();\n this.dependencies = [TransformComponent, MotionComponent];\n this.id = createId('body', BodyComponent._ID++);\n this.events = new EventEmitter();\n this.oldTransform = new transform_Transform();\n /**\n * Indicates whether the old transform has been captured at least once for interpolation\n * @internal\n */\n this.__oldTransformCaptured = false;\n /**\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\n */\n this.enableFixedUpdateInterpolate = true;\n /**\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\n */\n this.collisionType = CollisionType.PreventCollision;\n /**\n * The collision group for the body's colliders, by default body colliders collide with everything\n */\n this.group = CollisionGroup.All;\n this._sleeping = false;\n /**\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\n */\n this.bounciness = 0.2;\n /**\n * The coefficient of friction on this actor\n */\n this.friction = 0.99;\n /**\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\n */\n this.useGravity = true;\n /**\n * Degrees of freedom to limit\n *\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\n */\n this.limitDegreeOfFreedom = [];\n /**\n * The velocity of the actor last frame (vx, vy) in pixels/second\n */\n this.oldVel = new Vector(0, 0);\n /**\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */\n this.oldAcc = Vector.Zero;\n if (options) {\n this.collisionType = (_a = options.type) !== null && _a !== void 0 ? _a : this.collisionType;\n this.group = (_b = options.group) !== null && _b !== void 0 ? _b : this.group;\n this.useGravity = (_c = options.useGravity) !== null && _c !== void 0 ? _c : this.useGravity;\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies,\n ...options.config\n };\n }\n else {\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies\n };\n }\n this.updatePhysicsConfig(this._bodyConfig);\n this._mass = BodyComponent._DEFAULT_CONFIG.defaultMass;\n }\n get matrix() {\n return this.transform.get().matrix;\n }\n /**\n * Called by excalibur to update physics config defaults if they change\n * @param config\n */\n updatePhysicsConfig(config) {\n this._bodyConfig = {\n ...DefaultPhysicsConfig.bodies,\n ...config\n };\n this.canSleep = this._bodyConfig.canSleepByDefault;\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\n this.wakeThreshold = this._bodyConfig.wakeThreshold;\n }\n /**\n * Called by excalibur to update defaults\n * @param config\n */\n static updateDefaultPhysicsConfig(config) {\n BodyComponent._DEFAULT_CONFIG = config;\n }\n get mass() {\n return this._mass;\n }\n set mass(newMass) {\n this._mass = newMass;\n this._cachedInertia = undefined;\n this._cachedInverseInertia = undefined;\n }\n /**\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\n */\n get inverseMass() {\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\n }\n ;\n /**\n * Whether this body is sleeping or not\n */\n get sleeping() {\n return this._sleeping;\n }\n /**\n * Set the sleep state of the body\n * @param sleeping\n */\n setSleeping(sleeping) {\n this._sleeping = sleeping;\n if (!sleeping) {\n // Give it a kick to keep it from falling asleep immediately\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\n }\n else {\n this.vel = Vector.Zero;\n this.acc = Vector.Zero;\n this.angularVelocity = 0;\n this.sleepMotion = 0;\n }\n }\n /**\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\n */\n updateMotion() {\n if (this._sleeping) {\n this.setSleeping(true);\n }\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\n const bias = this._bodyConfig.sleepBias;\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * this._bodyConfig.sleepEpsilon);\n if (this.canSleep && this.sleepMotion < this._bodyConfig.sleepEpsilon) {\n this.setSleeping(true);\n }\n }\n /**\n * Get the moment of inertia from the [[ColliderComponent]]\n */\n get inertia() {\n if (this._cachedInertia) {\n return this._cachedInertia;\n }\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\n const collider = this.owner.get(ColliderComponent);\n if (collider) {\n collider.$colliderAdded.subscribe(() => {\n this._cachedInertia = null;\n });\n collider.$colliderRemoved.subscribe(() => {\n this._cachedInertia = null;\n });\n const maybeCollider = collider.get();\n if (maybeCollider) {\n return this._cachedInertia = maybeCollider.getInertia(this.mass);\n }\n }\n return 0;\n }\n /**\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\n */\n get inverseInertia() {\n if (this._cachedInverseInertia) {\n return this._cachedInverseInertia;\n }\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\n }\n /**\n * Returns if the owner is active\n */\n get active() {\n var _a;\n return !!((_a = this.owner) === null || _a === void 0 ? void 0 : _a.active);\n }\n /**\n * @deprecated Use globalP0s\n */\n get center() {\n return this.globalPos;\n }\n get transform() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n }\n get motion() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(MotionComponent);\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n /**\n * The (x, y) position of the actor this will be in the middle of the actor if the\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\n */\n get globalPos() {\n return this.transform.globalPos;\n }\n set globalPos(val) {\n this.transform.globalPos = val;\n }\n /**\n * The position of the actor last frame (x, y) in pixels\n */\n get oldPos() {\n return this.oldTransform.pos;\n }\n /**\n * The current velocity vector (vx, vy) of the actor in pixels/second\n */\n get vel() {\n return this.motion.vel;\n }\n set vel(val) {\n this.motion.vel = val;\n }\n /**\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\n * be useful to simulate a gravitational effect.\n */\n get acc() {\n return this.motion.acc;\n }\n set acc(val) {\n this.motion.acc = val;\n }\n /**\n * The current torque applied to the actor\n */\n get torque() {\n return this.motion.torque;\n }\n set torque(val) {\n this.motion.torque = val;\n }\n /**\n * Gets/sets the rotation of the body from the last frame.\n */\n get oldRotation() {\n return this.oldTransform.rotation;\n }\n /**\n * The rotation of the body in radians\n */\n get rotation() {\n return this.transform.globalRotation;\n }\n set rotation(val) {\n this.transform.globalRotation = val;\n }\n /**\n * The scale vector of the actor\n */\n get scale() {\n return this.transform.globalScale;\n }\n set scale(val) {\n this.transform.globalScale = val;\n }\n /**\n * The scale of the actor last frame\n */\n get oldScale() {\n return this.oldTransform.scale;\n }\n /**\n * The scale rate of change of the actor in scale/second\n */\n get scaleFactor() {\n return this.motion.scaleFactor;\n }\n set scaleFactor(scaleFactor) {\n this.motion.scaleFactor = scaleFactor;\n }\n /**\n * Get the angular velocity in radians/second\n */\n get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\n * Set the angular velocity in radians/second\n */\n set angularVelocity(value) {\n this.motion.angularVelocity = value;\n }\n /**\n * Apply a specific impulse to the body\n * @param point\n * @param impulse\n */\n applyImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) {\n return; // only active objects participate in the simulation\n }\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\n finalImpulse.x = 0;\n }\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\n finalImpulse.y = 0;\n }\n this.vel.addEqual(finalImpulse);\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\n * Apply only linear impulse to the body\n * @param impulse\n */\n applyLinearImpulse(impulse) {\n if (this.collisionType !== CollisionType.Active) {\n return; // only active objects participate in the simulation\n }\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\n finalImpulse.x = 0;\n }\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\n finalImpulse.y = 0;\n }\n this.vel = this.vel.add(finalImpulse);\n }\n /**\n * Apply only angular impulse to the body\n * @param point\n * @param impulse\n */\n applyAngularImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) {\n return; // only active objects participate in the simulation\n }\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\n * Sets the old versions of pos, vel, acc, and scale.\n */\n captureOldTransform() {\n // Capture old values before integration step updates them\n this.__oldTransformCaptured = true;\n const tx = this.transform.get();\n tx.clone(this.oldTransform);\n this.oldTransform.parent = tx.parent; // also grab parent\n this.oldVel.setTo(this.vel.x, this.vel.y);\n this.oldAcc.setTo(this.acc.x, this.acc.y);\n }\n clone() {\n const component = super.clone();\n return component;\n }\n}\nBodyComponent._ID = 0;\nBodyComponent._DEFAULT_CONFIG = {\n ...DefaultPhysicsConfig.bodies\n};\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Entity.ts\n\n\n\n\n\n\n/**\n * AddedComponent message\n */\nclass AddedComponent {\n constructor(data) {\n this.data = data;\n this.type = 'Component Added';\n }\n}\n/**\n * Type guard to know if message is f an Added Component\n */\nfunction isAddedComponent(x) {\n return !!x && x.type === 'Component Added';\n}\n/**\n * RemovedComponent message\n */\nclass RemovedComponent {\n constructor(data) {\n this.data = data;\n this.type = 'Component Removed';\n }\n}\n/**\n * Type guard to know if message is for a Removed Component\n */\nfunction isRemovedComponent(x) {\n return !!x && x.type === 'Component Removed';\n}\nconst EntityEvents = {\n Initialize: 'initialize',\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate',\n Kill: 'kill'\n};\n/**\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\n *\n * Entities can be strongly typed with the components they contain\n *\n * ```typescript\n * const entity = new Entity();\n * entity.components.a; // Type ComponentA\n * entity.components.b; // Type ComponentB\n * ```\n */\nclass Entity {\n constructor(componentsOrOptions, name) {\n /**\n * The unique identifier for the entity\n */\n this.id = Entity._ID++;\n this.name = `Entity#${this.id}`;\n /**\n * Listen to or emit events for an entity\n */\n this.events = new EventEmitter();\n this._tags = new Set();\n this.componentAdded$ = new Observable;\n this.componentRemoved$ = new Observable;\n this.tagAdded$ = new Observable;\n this.tagRemoved$ = new Observable;\n /**\n * Current components on the entity\n *\n * **Do not modify**\n *\n * Use addComponent/removeComponent otherwise the ECS will not be notified of changes.\n */\n this.components = new Map();\n this._componentsToRemove = [];\n this._instanceOfComponentCacheDirty = true;\n this._instanceOfComponentCache = new Map();\n /**\n * The current scene that the entity is in, if any\n */\n this.scene = null;\n /**\n * Whether this entity is active, if set to false it will be reclaimed\n */\n this.active = true;\n this._parent = null;\n this.childrenAdded$ = new Observable();\n this.childrenRemoved$ = new Observable();\n this._children = [];\n this._isInitialized = false;\n let componentsToAdd;\n let nameToAdd;\n if (Array.isArray(componentsOrOptions)) {\n componentsToAdd = componentsOrOptions;\n nameToAdd = name;\n }\n else if (componentsOrOptions && typeof componentsOrOptions === 'object') {\n const { components, name } = componentsOrOptions;\n componentsToAdd = components;\n nameToAdd = name;\n }\n if (nameToAdd) {\n this.name = nameToAdd;\n }\n if (componentsToAdd) {\n for (const component of componentsToAdd) {\n this.addComponent(component);\n }\n }\n // this.addComponent(this.tagsComponent);\n }\n /**\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\n * If parented it will be removed from the parent when killed.\n */\n kill() {\n if (this.active) {\n this.active = false;\n this.unparent();\n }\n this.emit('kill', new KillEvent(this));\n }\n isKilled() {\n return !this.active;\n }\n /**\n * Specifically get the tags on the entity from [[TagsComponent]]\n */\n get tags() {\n return this._tags;\n }\n /**\n * Check if a tag exists on the entity\n * @param tag name to check for\n */\n hasTag(tag) {\n return this._tags.has(tag);\n }\n /**\n * Adds a tag to an entity\n * @param tag\n */\n addTag(tag) {\n this._tags.add(tag);\n this.tagAdded$.notifyAll(tag);\n }\n /**\n * Removes a tag on the entity\n *\n * Removals are deferred until the end of update\n * @param tag\n */\n removeTag(tag) {\n this._tags.delete(tag);\n this.tagRemoved$.notifyAll(tag);\n }\n /**\n * The types of the components on the Entity\n */\n get types() {\n return Array.from(this.components.keys());\n }\n /**\n * Returns all component instances on entity\n */\n getComponents() {\n return Array.from(this.components.values());\n }\n /**\n * Verifies that an entity has all the required types\n * @param requiredTypes\n */\n hasAll(requiredTypes) {\n for (let i = 0; i < requiredTypes.length; i++) {\n if (!this.components.has(requiredTypes[i])) {\n return false;\n }\n }\n return true;\n }\n /**\n * Verifies that an entity has all the required tags\n * @param requiredTags\n */\n hasAllTags(requiredTags) {\n for (let i = 0; i < requiredTags.length; i++) {\n if (!this.tags.has(requiredTags[i])) {\n return false;\n }\n }\n return true;\n }\n _getCachedInstanceOfType(type) {\n if (this._instanceOfComponentCacheDirty) {\n this._instanceOfComponentCacheDirty = false;\n this._instanceOfComponentCache.clear();\n }\n if (this._instanceOfComponentCache.has(type)) {\n return this._instanceOfComponentCache.get(type);\n }\n for (const instance of this.components.values()) {\n if (instance instanceof type) {\n this._instanceOfComponentCache.set(type, instance);\n return instance;\n }\n }\n return undefined;\n }\n get(type) {\n const maybeComponent = this._getCachedInstanceOfType(type);\n return maybeComponent !== null && maybeComponent !== void 0 ? maybeComponent : this.components.get(type);\n }\n get parent() {\n return this._parent;\n }\n /**\n * Get the direct children of this entity\n */\n get children() {\n return this._children;\n }\n /**\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\n */\n unparent() {\n if (this._parent) {\n this._parent.removeChild(this);\n this._parent = null;\n }\n }\n /**\n * Adds an entity to be a child of this entity\n * @param entity\n */\n addChild(entity) {\n if (entity.parent === null) {\n if (this.getAncestors().includes(entity)) {\n throw new Error('Cycle detected, cannot add entity');\n }\n this._children.push(entity);\n entity._parent = this;\n this.childrenAdded$.notifyAll(entity);\n }\n else {\n throw new Error('Entity already has a parent, cannot add without unparenting');\n }\n return this;\n }\n /**\n * Remove an entity from children if it exists\n * @param entity\n */\n removeChild(entity) {\n if (entity.parent === this) {\n removeItemFromArray(entity, this._children);\n entity._parent = null;\n this.childrenRemoved$.notifyAll(entity);\n }\n return this;\n }\n /**\n * Removes all children from this entity\n */\n removeAllChildren() {\n // Avoid modifying the array issue by walking backwards\n for (let i = this.children.length - 1; i >= 0; i--) {\n this.removeChild(this.children[i]);\n }\n return this;\n }\n /**\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\n */\n getAncestors() {\n const result = [this];\n let current = this.parent;\n while (current) {\n result.push(current);\n current = current.parent;\n }\n return result.reverse();\n }\n /**\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\n */\n getDescendants() {\n let result = [this];\n let queue = [this];\n while (queue.length > 0) {\n const curr = queue.pop();\n if (curr) {\n queue = queue.concat(curr.children);\n result = result.concat(curr.children);\n }\n }\n return result;\n }\n /**\n * Creates a deep copy of the entity and a copy of all its components\n */\n clone() {\n const newEntity = new Entity();\n for (const c of this.types) {\n const componentInstance = this.get(c);\n if (componentInstance) {\n newEntity.addComponent(componentInstance.clone());\n }\n }\n for (const child of this.children) {\n newEntity.addChild(child.clone());\n }\n return newEntity;\n }\n /**\n * Adds a copy of all the components from another template entity as a \"prefab\"\n * @param templateEntity Entity to use as a template\n * @param force Force component replacement if it already exists on the target entity\n */\n addTemplate(templateEntity, force = false) {\n for (const c of templateEntity.getComponents()) {\n this.addComponent(c.clone(), force);\n }\n for (const child of templateEntity.children) {\n this.addChild(child.clone().addTemplate(child));\n }\n return this;\n }\n /**\n * Adds a component to the entity\n * @param component Component or Entity to add copy of components from\n * @param force Optionally overwrite any existing components of the same type\n */\n addComponent(component, force = false) {\n this._instanceOfComponentCacheDirty = true;\n // if component already exists, skip if not forced\n if (this.has(component.constructor)) {\n if (force) {\n // Remove existing component type if exists when forced\n this.removeComponent(component.constructor, true);\n }\n else {\n // early exit component exits\n return this;\n }\n }\n // TODO circular dependencies will be a problem\n if (component.dependencies && component.dependencies.length) {\n for (const ctor of component.dependencies) {\n this.addComponent(new ctor());\n }\n }\n component.owner = this;\n this.components.set(component.constructor, component);\n if (component.onAdd) {\n component.onAdd(this);\n }\n this.componentAdded$.notifyAll(component);\n return this;\n }\n /**\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\n *\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\n * @param typeOrInstance\n * @param force\n */\n removeComponent(typeOrInstance, force = false) {\n let type;\n if (isComponentCtor(typeOrInstance)) {\n type = typeOrInstance;\n }\n else {\n type = typeOrInstance.constructor;\n }\n if (force) {\n const componentToRemove = this.components.get(type);\n if (componentToRemove) {\n this.componentRemoved$.notifyAll(componentToRemove);\n componentToRemove.owner = undefined;\n if (componentToRemove.onRemove) {\n componentToRemove.onRemove(this);\n }\n }\n this.components.delete(type); // remove after the notify to preserve typing\n this._instanceOfComponentCacheDirty = true;\n }\n else {\n this._componentsToRemove.push(type);\n }\n return this;\n }\n clearComponents() {\n const components = this.types;\n for (const c of components) {\n this.removeComponent(c);\n }\n }\n /**\n * @hidden\n * @internal\n */\n processComponentRemoval() {\n for (const type of this._componentsToRemove) {\n this.removeComponent(type, true);\n }\n this._componentsToRemove.length = 0;\n }\n /**\n * Check if a component type exists\n * @param type\n */\n has(type) {\n return this.components.has(type);\n }\n /**\n * Gets whether the actor is Initialized\n */\n get isInitialized() {\n return this._isInitialized;\n }\n /**\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\n *\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n * @internal\n */\n _initialize(engine) {\n if (!this.isInitialized) {\n this.onInitialize(engine);\n this.events.emit('initialize', new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */\n _preupdate(engine, delta) {\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */\n _postupdate(engine, delta) {\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * `onInitialize` is called before the first update of the entity. This method is meant to be\n * overridden.\n *\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\n */\n onInitialize(engine) {\n // Override me\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before an entity is updated.\n */\n onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after an entity is updated.\n */\n onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n *\n * Entity update lifecycle, called internally\n * @internal\n * @param engine\n * @param delta\n */\n update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n for (const child of this.children) {\n child.update(engine, delta);\n }\n this._postupdate(engine, delta);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n if (handler) {\n this.events.off(eventName, handler);\n }\n else {\n this.events.off(eventName);\n }\n }\n}\nEntity._ID = 0;\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsComponent.ts\n\n\n\n\n\n\n/**\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\n * @param graphic\n */\nfunction hasGraphicsTick(graphic) {\n return !!graphic.tick;\n}\n/**\n * Component to manage drawings, using with the position component\n */\nclass GraphicsComponent extends Component {\n /**\n * Offset to apply to graphics by default\n */\n get offset() {\n return new WatchVector(this._offset, () => {\n this.recalculateBounds();\n });\n }\n set offset(value) {\n this._offset = value;\n this.recalculateBounds();\n }\n /**\n * Anchor to apply to graphics by default\n */\n get anchor() {\n return new WatchVector(this._anchor, () => {\n this.recalculateBounds();\n });\n }\n set anchor(value) {\n this._anchor = value;\n this.recalculateBounds();\n }\n constructor(options) {\n super();\n this._logger = Logger.getInstance();\n this._current = 'default';\n this._graphics = {};\n this._options = {};\n this.material = null;\n /**\n * Sets or gets wether any drawing should be visible in this component\n */\n this.visible = true;\n /**\n * Sets or gets wither all drawings should have an opacity applied\n */\n this.opacity = 1;\n this._offset = Vector.Zero;\n this._anchor = Vector.Half;\n /**\n * Flip all graphics horizontally along the y-axis\n */\n this.flipHorizontal = false;\n /**\n * Flip all graphics vertically along the x-axis\n */\n this.flipVertical = false;\n /**\n * If set to true graphics added to the component will be copied. This can effect performance, but is useful if you don't want\n * changes to a graphic to effect all the places it is used.\n */\n this.copyGraphics = false;\n this._localBounds = null;\n // Defaults\n options = {\n visible: this.visible,\n graphics: {},\n ...options\n };\n const { current, anchor, opacity, visible, graphics, offset, copyGraphics, onPreDraw, onPostDraw, onPreTransformDraw, onPostTransformDraw } = options;\n for (const [key, graphicOrOptions] of Object.entries(graphics)) {\n if (graphicOrOptions instanceof Graphic) {\n this._graphics[key] = graphicOrOptions;\n }\n else {\n this._graphics[key] = graphicOrOptions.graphic;\n this._options[key] = graphicOrOptions.options;\n }\n }\n this.offset = offset !== null && offset !== void 0 ? offset : this.offset;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : this.anchor;\n this.copyGraphics = copyGraphics !== null && copyGraphics !== void 0 ? copyGraphics : this.copyGraphics;\n this.onPreDraw = onPreDraw !== null && onPreDraw !== void 0 ? onPreDraw : this.onPreDraw;\n this.onPostDraw = onPostDraw !== null && onPostDraw !== void 0 ? onPostDraw : this.onPostDraw;\n this.onPreDraw = onPreTransformDraw !== null && onPreTransformDraw !== void 0 ? onPreTransformDraw : this.onPreTransformDraw;\n this.onPostTransformDraw = onPostTransformDraw !== null && onPostTransformDraw !== void 0 ? onPostTransformDraw : this.onPostTransformDraw;\n this.visible = !!visible;\n this._current = current !== null && current !== void 0 ? current : this._current;\n if (current && this._graphics[current]) {\n this.use(current);\n }\n }\n getGraphic(name) {\n return this._graphics[name];\n }\n getOptions(name) {\n return this._options[name];\n }\n /**\n * Get registered graphics names\n */\n getNames() {\n return Object.keys(this._graphics);\n }\n /**\n * Returns the currently displayed graphic\n */\n get current() {\n return this._graphics[this._current];\n }\n /**\n * Returns the currently displayed graphic offsets\n */\n get currentOptions() {\n return this._options[this._current];\n }\n /**\n * Returns all graphics associated with this component\n */\n get graphics() {\n return this._graphics;\n }\n /**\n * Returns all graphics options associated with this component\n */\n get options() {\n return this._options;\n }\n add(nameOrGraphic, graphicOrOptions, options) {\n let name = 'default';\n let graphicToSet = null;\n let optionsToSet = undefined;\n if (typeof nameOrGraphic === 'string' && graphicOrOptions instanceof Graphic) {\n name = nameOrGraphic;\n graphicToSet = graphicOrOptions;\n optionsToSet = options;\n }\n if (nameOrGraphic instanceof Graphic && !(graphicOrOptions instanceof Graphic)) {\n graphicToSet = nameOrGraphic;\n optionsToSet = graphicOrOptions;\n }\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\n this._options[name] = this.copyGraphics ? { ...optionsToSet } : optionsToSet;\n if (name === 'default') {\n this.use('default');\n }\n return graphicToSet;\n }\n /**\n * Removes a registered graphic, if the removed graphic is the current it will switch to the default\n * @param name\n */\n remove(name) {\n delete this._graphics[name];\n delete this._options[name];\n if (this._current === name) {\n this._current = 'default';\n this.recalculateBounds();\n }\n }\n /**\n * Shows a graphic, will be removed\n * @param nameOrGraphic\n * @param options\n * @deprecated will be removed in v0.30.0, use `graphics.use(...)`\n */\n show(nameOrGraphic, options) {\n return this.use(nameOrGraphic, options);\n }\n /**\n * Use a graphic only, will set the default graphic. Returns the new [[Graphic]]\n *\n * Optionally override the stored options\n * @param nameOrGraphic\n * @param options\n */\n use(nameOrGraphic, options) {\n var _a;\n if (nameOrGraphic instanceof Graphic) {\n let graphic = nameOrGraphic;\n if (this.copyGraphics) {\n graphic = nameOrGraphic.clone();\n }\n this._current = 'default';\n this._graphics[this._current] = graphic;\n this._options[this._current] = options;\n }\n else {\n this._current = nameOrGraphic;\n this._options[this._current] = options;\n if (!(this._current in this._graphics)) {\n this._logger.warn(`Graphic ${this._current} is not registered with the graphics component owned by ${(_a = this.owner) === null || _a === void 0 ? void 0 : _a.name}. Nothing will be drawn.`);\n }\n }\n this.recalculateBounds();\n return this.current;\n }\n /**\n * Hide currently shown graphic\n */\n hide() {\n this._current = 'ex.none';\n }\n set localBounds(bounds) {\n this._localBounds = bounds;\n }\n recalculateBounds() {\n let bb = new BoundingBox();\n const graphic = this._graphics[this._current];\n const options = this._options[this._current];\n if (!graphic) {\n this._localBounds = bb;\n return;\n }\n let anchor = this.anchor;\n let offset = this.offset;\n if (options === null || options === void 0 ? void 0 : options.anchor) {\n anchor = options.anchor;\n }\n if (options === null || options === void 0 ? void 0 : options.offset) {\n offset = options.offset;\n }\n const bounds = graphic.localBounds;\n const offsetX = -bounds.width * anchor.x + offset.x;\n const offsetY = -bounds.height * anchor.y + offset.y;\n bb = graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(vec(offsetX, offsetY)).combine(bb);\n this._localBounds = bb;\n }\n get localBounds() {\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) {\n this.recalculateBounds();\n }\n return this._localBounds;\n }\n /**\n * Update underlying graphics if necessary, called internally\n * @param elapsed\n * @internal\n */\n update(elapsed, idempotencyToken = 0) {\n const graphic = this.current;\n if (graphic && hasGraphicsTick(graphic)) {\n graphic.tick(elapsed, idempotencyToken);\n }\n }\n clone() {\n const graphics = new GraphicsComponent();\n graphics._graphics = { ...this._graphics };\n graphics._options = { ...this._options };\n graphics.offset = this.offset.clone();\n graphics.opacity = this.opacity;\n graphics.anchor = this.anchor.clone();\n graphics.copyGraphics = this.copyGraphics;\n graphics.onPreDraw = this.onPreDraw;\n graphics.onPostDraw = this.onPostDraw;\n graphics.visible = this.visible;\n return graphics;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Rectangle.ts\n\n/**\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\n */\nclass Rectangle extends Raster {\n constructor(options) {\n super(options);\n this.width = options.width;\n this.height = options.height;\n this.rasterize();\n }\n clone() {\n return new Rectangle({\n width: this.width,\n height: this.height,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.color) {\n ctx.fillRect(0, 0, this.width, this.height);\n }\n if (this.strokeColor) {\n ctx.strokeRect(0, 0, this.width, this.height);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Circle.ts\n\n\n/**\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\n *\n * Circles default to [[ImageFiltering.Blended]]\n */\nclass Circle extends Raster {\n get radius() {\n return this._radius;\n }\n set radius(value) {\n this._radius = value;\n this.width = this._radius * 2;\n this.height = this._radius * 2;\n this.flagDirty();\n }\n constructor(options) {\n var _a, _b, _c;\n super(options);\n this._radius = 0;\n const lineWidth = (_a = options.lineWidth) !== null && _a !== void 0 ? _a : (options.strokeColor ? 1 : 0); // default lineWidth in canvas is 1px\n this.padding = (_b = options.padding) !== null && _b !== void 0 ? _b : 2 + (lineWidth / 2); // default 2 padding for circles looks nice\n this.radius = options.radius;\n this.filtering = (_c = options.filtering) !== null && _c !== void 0 ? _c : ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Circle({\n radius: this.radius,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.radius > 0) {\n ctx.beginPath();\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\n if (this.color) {\n ctx.fill();\n }\n if (this.strokeColor) {\n ctx.stroke();\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerComponent.ts\n\n/**\n * Add this component to optionally configure how the pointer\n * system detects pointer events.\n *\n * By default the collider shape is used and graphics bounds is not.\n *\n * If both collider shape and graphics bounds are enabled it will fire events if either or\n * are intersecting the pointer.\n */\nclass PointerComponent extends Component {\n constructor() {\n super(...arguments);\n /**\n * Use any existing Collider component geometry for pointer events. This is useful if you want\n * user pointer events only to trigger on the same collision geometry used in the collider component\n * for collision resolution. Default is `true`.\n */\n this.useColliderShape = true;\n /**\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\n * bounds around the graphic to trigger pointer events. Default is `true`.\n */\n this.useGraphicsBounds = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/EasingFunctions.ts\n\n/**\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\n * Given a time, the function will return a value from positive startValue to positive endValue.\n *\n * ```js\n * function Linear (t) {\n * return t * t;\n * }\n *\n * // accelerating from zero velocity\n * function EaseInQuad (t) {\n * return t * t;\n * }\n *\n * // decelerating to zero velocity\n * function EaseOutQuad (t) {\n * return t * (2 - t);\n * }\n *\n * // acceleration until halfway, then deceleration\n * function EaseInOutQuad (t) {\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n * }\n *\n * // accelerating from zero velocity\n * function EaseInCubic (t) {\n * return t * t * t;\n * }\n *\n * // decelerating to zero velocity\n * function EaseOutCubic (t) {\n * return (--t) * t * t + 1;\n * }\n *\n * // acceleration until halfway, then deceleration\n * function EaseInOutCubic (t) {\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n * }\n * ```\n */\nclass EasingFunctions {\n static CreateReversibleEasingFunction(easing) {\n return (time, start, end, duration) => {\n if (end < start) {\n return start - (easing(time, end, start, duration) - end);\n }\n else {\n return easing(time, start, end, duration);\n }\n };\n }\n static CreateVectorEasingFunction(easing) {\n return (time, start, end, duration) => {\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\n };\n }\n}\nEasingFunctions.Linear = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n return (endValue * currentTime) / duration + startValue;\n});\nEasingFunctions.EaseInQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime + startValue;\n});\nEasingFunctions.EaseOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration;\n return -endValue * currentTime * (currentTime - 2) + startValue;\n});\nEasingFunctions.EaseInOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) {\n return (endValue / 2) * currentTime * currentTime + startValue;\n }\n currentTime--;\n return (-endValue / 2) * (currentTime * (currentTime - 2) - 1) + startValue;\n});\nEasingFunctions.EaseInCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime * currentTime + startValue;\n});\nEasingFunctions.EaseOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration;\n currentTime--;\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\n});\nEasingFunctions.EaseInOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) {\n return (endValue / 2) * currentTime * currentTime * currentTime + startValue;\n }\n currentTime -= 2;\n return (endValue / 2) * (currentTime * currentTime * currentTime + 2) + startValue;\n});\n\n;// CONCATENATED MODULE: ./Actions/ActionQueue.ts\n\n/**\n * Action Queues represent an ordered sequence of actions\n *\n * Action queues are part of the [[ActionContext|Action API]] and\n * store the list of actions to be executed for an [[Actor]].\n *\n * Actors implement [[Actor.actions]] which can be manipulated by\n * advanced users to adjust the actions currently being executed in the\n * queue.\n */\nclass ActionQueue {\n constructor(entity) {\n this._actions = [];\n this._currentAction = null;\n this._completedActions = [];\n this._entity = entity;\n }\n /**\n * Add an action to the sequence\n * @param action\n */\n add(action) {\n this._actions.push(action);\n }\n /**\n * Remove an action by reference from the sequence\n * @param action\n */\n remove(action) {\n const index = this._actions.indexOf(action);\n this._actions.splice(index, 1);\n }\n /**\n * Removes all actions from this sequence\n */\n clearActions() {\n this._actions.length = 0;\n this._completedActions.length = 0;\n if (this._currentAction) {\n this._currentAction.stop();\n }\n }\n /**\n *\n * @returns The total list of actions in this sequence complete or not\n */\n getActions() {\n return this._actions.concat(this._completedActions);\n }\n /**\n *\n * @returns `true` if there are more actions to process in the sequence\n */\n hasNext() {\n return this._actions.length > 0;\n }\n /**\n * @returns `true` if the current sequence of actions is done\n */\n isComplete() {\n return this._actions.length === 0;\n }\n /**\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\n */\n reset() {\n this._actions = this.getActions();\n const len = this._actions.length;\n for (let i = 0; i < len; i++) {\n this._actions[i].reset();\n }\n this._completedActions = [];\n }\n /**\n * Update the queue which updates actions and handles completing actions\n * @param elapsedMs\n */\n update(elapsedMs) {\n if (this._actions.length > 0) {\n if (this._currentAction !== this._actions[0]) {\n this._currentAction = this._actions[0];\n this._entity.emit('actionstart', new ActionStartEvent(this._currentAction, this._entity));\n }\n this._currentAction.update(elapsedMs);\n if (this._currentAction.isComplete(this._entity)) {\n this._entity.emit('actioncomplete', new ActionCompleteEvent(this._currentAction, this._entity));\n const complete = this._actions.shift();\n if (complete) {\n this._completedActions.push(complete);\n }\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Repeat.ts\n\nclass Repeat {\n constructor(entity, repeatBuilder, repeat) {\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeat = repeat;\n this._originalRepeat = repeat;\n this._repeatBuilder(this._repeatContext);\n this._repeat--; // current execution is the first repeat\n }\n update(delta) {\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n this._repeat--;\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || (this._repeat <= 0 && this._actionQueue.isComplete());\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._repeat = this._originalRepeat;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/RepeatForever.ts\n\n/**\n * RepeatForever Action implementation, it is recommended you use the fluent action\n * context API.\n *\n *\n */\nclass RepeatForever {\n constructor(entity, repeatBuilder) {\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeatBuilder(this._repeatContext);\n }\n update(delta) {\n if (this._stopped) {\n return;\n }\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n this._stopped = true;\n this._actionQueue.clearActions();\n }\n reset() {\n return;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/MoveBy.ts\n\n\n\n\nclass MoveBy {\n constructor(entity, offsetX, offsetY, speed) {\n this._started = false;\n this._stopped = false;\n this._entity = entity;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = new Vector(offsetX, offsetY);\n if (speed <= 0) {\n Logger.getInstance().error('Attempted to moveBy with speed less than or equal to zero : ' + speed);\n throw new Error('Speed must be greater than 0 pixels per second');\n }\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = this._start.add(this._offset);\n this._distance = this._offset.size;\n this._dir = this._end.sub(this._start).normalize();\n }\n if (this.isComplete(this._entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n else {\n this._motion.vel = this._dir.scale(this._speed);\n }\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/MoveTo.ts\n\n\n\nclass MoveTo {\n constructor(entity, destx, desty, speed) {\n this.entity = entity;\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = new Vector(destx, desty);\n this._speed = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._distance = this._start.distance(this._end);\n this._dir = this._end.sub(this._start).normalize();\n }\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete(this.entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/RotationType.ts\n/**\n * An enum that describes the strategies that rotation actions can use\n */\nvar RotationType;\n(function (RotationType) {\n /**\n * Rotation via `ShortestPath` will use the smallest angle\n * between the starting and ending points. This strategy is the default behavior.\n */\n RotationType[RotationType[\"ShortestPath\"] = 0] = \"ShortestPath\";\n /**\n * Rotation via `LongestPath` will use the largest angle\n * between the starting and ending points.\n */\n RotationType[RotationType[\"LongestPath\"] = 1] = \"LongestPath\";\n /**\n * Rotation via `Clockwise` will travel in a clockwise direction,\n * regardless of the starting and ending points.\n */\n RotationType[RotationType[\"Clockwise\"] = 2] = \"Clockwise\";\n /**\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\n * regardless of the starting and ending points.\n */\n RotationType[RotationType[\"CounterClockwise\"] = 3] = \"CounterClockwise\";\n})(RotationType || (RotationType = {}));\n\n;// CONCATENATED MODULE: ./Actions/Action/RotateTo.ts\n\n\n\n\nclass RotateTo {\n constructor(entity, angleRadians, speed, rotationType) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = angleRadians;\n this._speed = speed;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n }\n else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch (this._rotationType) {\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) {\n this._direction = 1;\n }\n else {\n this._direction = -1;\n }\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) {\n this._direction = -1;\n }\n else {\n this._direction = 1;\n }\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortestPathIsPositive) {\n this._distance = this._shortDistance;\n }\n else {\n this._distance = this._longDistance;\n }\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (!this._shortestPathIsPositive) {\n this._distance = this._shortDistance;\n }\n else {\n this._distance = this._longDistance;\n }\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/RotateBy.ts\n\n\n\n\nclass RotateBy {\n constructor(entity, angleRadiansOffset, speed, rotationType) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = angleRadiansOffset;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n this._end = this._start + this._offset;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n }\n else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch (this._rotationType) {\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) {\n this._direction = 1;\n }\n else {\n this._direction = -1;\n }\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) {\n this._direction = -1;\n }\n else {\n this._direction = 1;\n }\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortDistance >= 0) {\n this._distance = this._shortDistance;\n }\n else {\n this._distance = this._longDistance;\n }\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (this._shortDistance <= 0) {\n this._distance = this._shortDistance;\n }\n else {\n this._distance = this._longDistance;\n }\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._start = undefined;\n this._currentNonCannonAngle = undefined;\n this._distance = undefined;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/ScaleTo.ts\n\n\n\nclass ScaleTo {\n constructor(entity, scaleX, scaleY, speedX, speedY) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._endX = scaleX;\n this._endY = scaleY;\n this._speedX = speedX;\n this._speedY = speedY;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startX = this._tx.scale.x;\n this._startY = this._tx.scale.y;\n this._distanceX = Math.abs(this._endX - this._startX);\n this._distanceY = Math.abs(this._endY - this._startY);\n }\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\n const directionX = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.x = this._speedX * directionX;\n }\n else {\n this._motion.scaleFactor.x = 0;\n }\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\n const directionY = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.y = this._speedY * directionY;\n }\n else {\n this._motion.scaleFactor.y = 0;\n }\n if (this.isComplete()) {\n this._tx.scale = vec(this._endX, this._endY);\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return (this._stopped ||\n (Math.abs(this._tx.scale.x - this._startX) >= (this._distanceX - 0.01) &&\n Math.abs(this._tx.scale.y - this._startY) >= (this._distanceY - 0.01)));\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/ScaleBy.ts\n\n\n\nclass ScaleBy {\n constructor(entity, scaleOffsetX, scaleOffsetY, speed) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\n this._speedX = this._speedY = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startScale = this._tx.scale.clone();\n this._endScale = this._startScale.add(this._offset);\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\n }\n this._motion.scaleFactor.x = this._speedX * this._directionX;\n this._motion.scaleFactor.y = this._speedY * this._directionY;\n if (this.isComplete()) {\n this._tx.scale = this._endScale;\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return (this._stopped ||\n (Math.abs(this._tx.scale.x - this._startScale.x) >= (this._distanceX - 0.01) &&\n Math.abs(this._tx.scale.y - this._startScale.y) >= (this._distanceY - 0.01)));\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/CallMethod.ts\nclass CallMethod {\n constructor(method) {\n this._method = null;\n this._hasBeenCalled = false;\n this._method = method;\n }\n update(_delta) {\n this._method();\n this._hasBeenCalled = true;\n }\n isComplete() {\n return this._hasBeenCalled;\n }\n reset() {\n this._hasBeenCalled = false;\n }\n stop() {\n this._hasBeenCalled = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/EaseTo.ts\n\n\n\nclass EaseTo {\n constructor(entity, x, y, duration, easingFcn) {\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1 * 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._lerpEnd = new Vector(x, y);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) {\n newX =\n this._lerpStart.x -\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n }\n else {\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n }\n if (this._lerpEnd.y < this._lerpStart.y) {\n newY =\n this._lerpStart.y -\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n }\n else {\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n }\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n }\n else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/EaseBy.ts\n\n\n\nclass EaseBy {\n constructor(entity, offsetX, offsetY, duration, easingFcn) {\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1 * 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._offset = new Vector(offsetX, offsetY);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n this._lerpEnd = this._lerpStart.add(this._offset);\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) {\n newX =\n this._lerpStart.x -\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n }\n else {\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n }\n if (this._lerpEnd.y < this._lerpStart.y) {\n newY =\n this._lerpStart.y -\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n }\n else {\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n }\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n }\n else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Blink.ts\n\nclass Blink {\n constructor(entity, timeVisible, timeNotVisible, numBlinks = 1) {\n this._timeVisible = 0;\n this._timeNotVisible = 0;\n this._elapsedTime = 0;\n this._totalTime = 0;\n this._stopped = false;\n this._started = false;\n this._graphics = entity.get(GraphicsComponent);\n this._timeVisible = timeVisible;\n this._timeNotVisible = timeNotVisible;\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\n }\n update(delta) {\n if (!this._started) {\n this._started = true;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n if (!this._graphics) {\n return;\n }\n this._elapsedTime += delta;\n this._totalTime += delta;\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\n this._graphics.visible = false;\n this._elapsedTime = 0;\n }\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\n this._graphics.visible = true;\n this._elapsedTime = 0;\n }\n if (this.isComplete()) {\n this._graphics.visible = true;\n }\n }\n isComplete() {\n return this._stopped || this._totalTime >= this._duration;\n }\n stop() {\n if (this._graphics) {\n this._graphics.visible = true;\n }\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Fade.ts\n\n\nclass Fade {\n constructor(entity, endOpacity, speed) {\n this._multiplier = 1;\n this._started = false;\n this._stopped = false;\n this._graphics = entity.get(GraphicsComponent);\n this._endOpacity = endOpacity;\n this._speed = this._ogspeed = speed;\n }\n update(delta) {\n if (!this._graphics) {\n return;\n }\n if (!this._started) {\n this._started = true;\n this._speed = this._ogspeed;\n // determine direction when we start\n if (this._endOpacity < this._graphics.opacity) {\n this._multiplier = -1;\n }\n else {\n this._multiplier = 1;\n }\n }\n if (this._speed > 0) {\n this._graphics.opacity += (this._multiplier *\n (Math.abs(this._graphics.opacity - this._endOpacity) * delta)) / this._speed;\n }\n this._speed -= delta;\n if (this.isComplete()) {\n this._graphics.opacity = this._endOpacity;\n }\n Logger.getInstance().debug('[Action fade] Actor opacity:', this._graphics.opacity);\n }\n isComplete() {\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Delay.ts\nclass Delay {\n constructor(delay) {\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n this._delay = delay;\n }\n update(delta) {\n if (!this._started) {\n this._started = true;\n }\n this._elapsedTime += delta;\n }\n isComplete() {\n return this._stopped || this._elapsedTime >= this._delay;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Die.ts\n\nclass Die {\n constructor(entity) {\n this._stopped = false;\n this._entity = entity;\n }\n update(_delta) {\n this._entity.get(ActionsComponent).clearActions();\n this._entity.kill();\n this._stopped = true;\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n return;\n }\n reset() {\n return;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Follow.ts\n\n\n\nclass Follow {\n constructor(entity, entityToFollow, followDistance) {\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._followTx = entityToFollow.get(TransformComponent);\n this._followMotion = entityToFollow.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\n this._speed = 0;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\n if (actorToFollowSpeed !== 0) {\n this._speed = actorToFollowSpeed;\n }\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n if (this._distanceBetween >= this._maximumDistance) {\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n }\n else {\n this._motion.vel = vec(0, 0);\n }\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n isComplete() {\n // the actor following should never stop unless specified to do so\n return this._stopped;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/Meet.ts\n\n\n\nclass Meet {\n constructor(actor, actorToMeet, speed) {\n this._started = false;\n this._stopped = false;\n this._speedWasSpecified = false;\n this._tx = actor.get(TransformComponent);\n this._motion = actor.get(MotionComponent);\n this._meetTx = actorToMeet.get(TransformComponent);\n this._meetMotion = actorToMeet.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\n this._speed = speed || 0;\n if (speed !== undefined) {\n this._speedWasSpecified = true;\n }\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) {\n this._speed = actorToMeetSpeed;\n }\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete() {\n return this._stopped || this._distanceBetween <= 1;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._distanceBetween = undefined;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/ActionContext.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * The fluent Action API allows you to perform \"actions\" on\n * [[Actor|Actors]] such as following, moving, rotating, and\n * more. You can implement your own actions by implementing\n * the [[Action]] interface.\n */\nclass ActionContext {\n constructor(entity) {\n this._entity = entity;\n this._queue = new ActionQueue(entity);\n }\n getQueue() {\n return this._queue;\n }\n update(elapsedMs) {\n this._queue.update(elapsedMs);\n }\n /**\n * Clears all queued actions from the Actor\n */\n clearActions() {\n this._queue.clearActions();\n }\n runAction(action) {\n action.reset();\n this._queue.add(action);\n return this;\n }\n easeTo(...args) {\n var _a, _b;\n let x = 0;\n let y = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n x = args[0].x;\n y = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n }\n else {\n x = args[0];\n y = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\n return this;\n }\n easeBy(...args) {\n var _a, _b;\n let offsetX = 0;\n let offsetY = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n offsetX = args[0].x;\n offsetY = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n }\n else {\n offsetX = args[0];\n offsetY = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\n return this;\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n let x = 0;\n let y = 0;\n let speed = 0;\n if (xOrPos instanceof Vector) {\n x = xOrPos.x;\n y = xOrPos.y;\n speed = yOrSpeed;\n }\n else {\n x = xOrPos;\n y = yOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveTo(this._entity, x, y, speed));\n return this;\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n let xOffset = 0;\n let yOffset = 0;\n let speed = 0;\n if (xOffsetOrVector instanceof Vector) {\n xOffset = xOffsetOrVector.x;\n yOffset = xOffsetOrVector.y;\n speed = yOffsetOrSpeed;\n }\n else {\n xOffset = xOffsetOrVector;\n yOffset = yOffsetOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\n return this;\n }\n /**\n * This method will rotate an actor to the specified angle at the speed\n * specified (in radians per second) and return back the actor. This\n * method is part of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadians The angle to rotate to in radians\n * @param speed The angular velocity of the rotation specified in radians per second\n * @param rotationType The [[RotationType]] to use for this rotation\n */\n rotateTo(angleRadians, speed, rotationType) {\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\n return this;\n }\n /**\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\n * in radians/sec and return back the actor. This method is part\n * of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\n * @param speed The speed in radians/sec the actor should rotate at\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\n */\n rotateBy(angleRadiansOffset, speed, rotationType) {\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\n return this;\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n let sizeX = 1;\n let sizeY = 1;\n let speedX = 0;\n let speedY = 0;\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\n sizeX = sizeXOrVector.x;\n sizeY = sizeXOrVector.y;\n speedX = sizeYOrSpeed.x;\n speedY = sizeYOrSpeed.y;\n }\n if (typeof sizeXOrVector === 'number' && typeof sizeYOrSpeed === 'number') {\n sizeX = sizeXOrVector;\n sizeY = sizeYOrSpeed;\n speedX = speedXOrUndefined;\n speedY = speedYOrUndefined;\n }\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\n return this;\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n let sizeOffsetX = 1;\n let sizeOffsetY = 1;\n if (sizeOffsetXOrVector instanceof Vector) {\n sizeOffsetX = sizeOffsetXOrVector.x;\n sizeOffsetY = sizeOffsetXOrVector.y;\n speed = sizeOffsetYOrSpeed;\n }\n if (typeof sizeOffsetXOrVector === 'number' && typeof sizeOffsetYOrSpeed === 'number') {\n sizeOffsetX = sizeOffsetXOrVector;\n sizeOffsetY = sizeOffsetYOrSpeed;\n }\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\n return this;\n }\n /**\n * This method will cause an actor to blink (become visible and not\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\n * the actor should be visible per blink, and the amount of time not visible.\n * This method is part of the actor 'Action' fluent API allowing action chaining.\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\n * @param numBlinks The number of times to blink\n */\n blink(timeVisible, timeNotVisible, numBlinks = 1) {\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\n return this;\n }\n /**\n * This method will cause an actor's opacity to change from its current value\n * to the provided value by a specified time (in milliseconds). This method is\n * part of the actor 'Action' fluent API allowing action chaining.\n * @param opacity The ending opacity\n * @param time The time it should take to fade the actor (in milliseconds)\n */\n fade(opacity, time) {\n this._queue.add(new Fade(this._entity, opacity, time));\n return this;\n }\n /**\n * This method will delay the next action from executing for a certain\n * amount of time (in milliseconds). This method is part of the actor\n * 'Action' fluent API allowing action chaining.\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\n */\n delay(time) {\n this._queue.add(new Delay(time));\n return this;\n }\n /**\n * This method will add an action to the queue that will remove the actor from the\n * scene once it has completed its previous Any actions on the\n * action queue after this action will not be executed.\n */\n die() {\n this._queue.add(new Die(this._entity));\n return this;\n }\n /**\n * This method allows you to call an arbitrary method as the next action in the\n * action queue. This is useful if you want to execute code in after a specific\n * action, i.e An actor arrives at a destination after traversing a path\n */\n callMethod(method) {\n this._queue.add(new CallMethod(method));\n return this;\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\n * will repeat forever\n */\n repeat(repeatBuilder, times) {\n if (!times) {\n this.repeatForever(repeatBuilder);\n return this;\n }\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\n return this;\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n */\n repeatForever(repeatBuilder) {\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\n return this;\n }\n /**\n * This method will cause the entity to follow another at a specified distance\n * @param entity The entity to follow\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\n */\n follow(entity, followDistance) {\n if (followDistance === undefined) {\n this._queue.add(new Follow(this._entity, entity));\n }\n else {\n this._queue.add(new Follow(this._entity, entity, followDistance));\n }\n return this;\n }\n /**\n * This method will cause the entity to move towards another until they\n * collide \"meet\" at a specified speed.\n * @param entity The entity to meet\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\n */\n meet(entity, speed) {\n if (speed === undefined) {\n this._queue.add(new Meet(this._entity, entity));\n }\n else {\n this._queue.add(new Meet(this._entity, entity, speed));\n }\n return this;\n }\n /**\n * Returns a promise that resolves when the current action queue up to now\n * is finished.\n */\n toPromise() {\n const temp = new Promise((resolve) => {\n this._queue.add(new CallMethod(() => {\n resolve();\n }));\n });\n return temp;\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/ActionsComponent.ts\n\n\n\n\n;\nclass ActionsComponent extends Component {\n constructor() {\n super(...arguments);\n this.dependencies = [TransformComponent, MotionComponent];\n this._ctx = null;\n }\n onAdd(entity) {\n this._ctx = new ActionContext(entity);\n }\n onRemove() {\n this._ctx = null;\n }\n _getCtx() {\n if (!this._ctx) {\n throw new Error('Actions component not attached to an entity, no context available');\n }\n return this._ctx;\n }\n /**\n * Returns the internal action queue\n * @returns action queue\n */\n getQueue() {\n if (!this._ctx) {\n throw new Error('Actions component not attached to an entity, no queue available');\n }\n return this._ctx.getQueue();\n }\n runAction(action) {\n if (!this._ctx) {\n throw new Error('Actions component not attached to an entity, cannot run action');\n }\n return this._ctx.runAction(action);\n }\n /**\n * Updates the internal action context, performing action and moving through the internal queue\n * @param elapsedMs\n */\n update(elapsedMs) {\n var _a;\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.update(elapsedMs);\n }\n /**\n * Clears all queued actions from the Actor\n */\n clearActions() {\n var _a;\n (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.clearActions();\n }\n easeTo(...args) {\n return this._getCtx().easeTo.apply(this._ctx, args);\n }\n easeBy(...args) {\n return this._getCtx().easeBy.apply(this._ctx, args);\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n return this._getCtx().moveTo.apply(this._ctx, [xOrPos, yOrSpeed, speedOrUndefined]);\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n return this._getCtx().moveBy.apply(this._ctx, [xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined]);\n }\n /**\n * This method will rotate an actor to the specified angle at the speed\n * specified (in radians per second) and return back the actor. This\n * method is part of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadians The angle to rotate to in radians\n * @param speed The angular velocity of the rotation specified in radians per second\n * @param rotationType The [[RotationType]] to use for this rotation\n */\n rotateTo(angleRadians, speed, rotationType) {\n return this._getCtx().rotateTo(angleRadians, speed, rotationType);\n }\n /**\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\n * in radians/sec and return back the actor. This method is part\n * of the actor 'Action' fluent API allowing action chaining.\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\n * @param speed The speed in radians/sec the actor should rotate at\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\n */\n rotateBy(angleRadiansOffset, speed, rotationType) {\n return this._getCtx().rotateBy(angleRadiansOffset, speed, rotationType);\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n return this._getCtx().scaleTo.apply(this._ctx, [sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined]);\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n return this._getCtx().scaleBy.apply(this._ctx, [sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed]);\n }\n /**\n * This method will cause an actor to blink (become visible and not\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\n * the actor should be visible per blink, and the amount of time not visible.\n * This method is part of the actor 'Action' fluent API allowing action chaining.\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\n * @param numBlinks The number of times to blink\n */\n blink(timeVisible, timeNotVisible, numBlinks) {\n return this._getCtx().blink(timeVisible, timeNotVisible, numBlinks);\n }\n /**\n * This method will cause an actor's opacity to change from its current value\n * to the provided value by a specified time (in milliseconds). This method is\n * part of the actor 'Action' fluent API allowing action chaining.\n * @param opacity The ending opacity\n * @param time The time it should take to fade the actor (in milliseconds)\n */\n fade(opacity, time) {\n return this._getCtx().fade(opacity, time);\n }\n /**\n * This method will delay the next action from executing for a certain\n * amount of time (in milliseconds). This method is part of the actor\n * 'Action' fluent API allowing action chaining.\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\n */\n delay(time) {\n return this._getCtx().delay(time);\n }\n /**\n * This method will add an action to the queue that will remove the actor from the\n * scene once it has completed its previous Any actions on the\n * action queue after this action will not be executed.\n */\n die() {\n return this._getCtx().die();\n }\n /**\n * This method allows you to call an arbitrary method as the next action in the\n * action queue. This is useful if you want to execute code in after a specific\n * action, i.e An actor arrives at a destination after traversing a path\n */\n callMethod(method) {\n return this._getCtx().callMethod(method);\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\n * will repeat forever\n */\n repeat(repeatBuilder, times) {\n return this._getCtx().repeat(repeatBuilder, times);\n }\n /**\n * This method will cause the actor to repeat all of the actions built in\n * the `repeatBuilder` callback. If the number of repeats\n * is not specified it will repeat forever. This method is part of\n * the actor 'Action' fluent API allowing action chaining\n *\n * ```typescript\n * // Move up in a zig-zag by repeated moveBy's\n * actor.actions.repeat(repeatCtx => {\n * repeatCtx.moveBy(10, 0, 10);\n * repeatCtx.moveBy(0, 10, 10);\n * }, 5);\n * ```\n * @param repeatBuilder The builder to specify the repeatable list of actions\n */\n repeatForever(repeatBuilder) {\n return this._getCtx().repeatForever(repeatBuilder);\n }\n /**\n * This method will cause the entity to follow another at a specified distance\n * @param entity The entity to follow\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\n */\n follow(entity, followDistance) {\n return this._getCtx().follow(entity, followDistance);\n }\n /**\n * This method will cause the entity to move towards another until they\n * collide \"meet\" at a specified speed.\n * @param entity The entity to meet\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\n */\n meet(entity, speed) {\n return this._getCtx().meet(entity, speed);\n }\n /**\n * Returns a promise that resolves when the current action queue up to now\n * is finished.\n */\n toPromise() {\n return this._getCtx().toPromise();\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/FontCommon.ts\n/**\n * Enum representing the different font size units\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\n */\nvar FontUnit;\n(function (FontUnit) {\n /**\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\n */\n FontUnit[\"Em\"] = \"em\";\n /**\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\n */\n FontUnit[\"Rem\"] = \"rem\";\n /**\n * Pixel is a unit of length in screen pixels\n */\n FontUnit[\"Px\"] = \"px\";\n /**\n * Point is a physical unit length (1/72 of an inch)\n */\n FontUnit[\"Pt\"] = \"pt\";\n /**\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\n */\n FontUnit[\"Percent\"] = \"%\";\n})(FontUnit || (FontUnit = {}));\n/**\n * Enum representing the different horizontal text alignments\n */\nvar TextAlign;\n(function (TextAlign) {\n /**\n * The text is left-aligned.\n */\n TextAlign[\"Left\"] = \"left\";\n /**\n * The text is right-aligned.\n */\n TextAlign[\"Right\"] = \"right\";\n /**\n * The text is centered.\n */\n TextAlign[\"Center\"] = \"center\";\n /**\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\n * right-aligned for right-to-left locales).\n */\n TextAlign[\"Start\"] = \"start\";\n /**\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\n * left-aligned for right-to-left locales).\n */\n TextAlign[\"End\"] = \"end\";\n})(TextAlign || (TextAlign = {}));\n/**\n * Enum representing the different baseline text alignments\n */\nvar BaseAlign;\n(function (BaseAlign) {\n /**\n * The text baseline is the top of the em square.\n */\n BaseAlign[\"Top\"] = \"top\";\n /**\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\n * alphabetic.\n */\n BaseAlign[\"Hanging\"] = \"hanging\";\n /**\n * The text baseline is the middle of the em square.\n */\n BaseAlign[\"Middle\"] = \"middle\";\n /**\n * The text baseline is the normal alphabetic baseline.\n */\n BaseAlign[\"Alphabetic\"] = \"alphabetic\";\n /**\n * The text baseline is the ideographic baseline; this is the bottom of\n * the body of the characters, if the main body of characters protrudes\n * beneath the alphabetic baseline. Currently unsupported; this will\n * act like alphabetic.\n */\n BaseAlign[\"Ideographic\"] = \"ideographic\";\n /**\n * The text baseline is the bottom of the bounding box. This differs\n * from the ideographic baseline in that the ideographic baseline\n * doesn't consider descenders.\n */\n BaseAlign[\"Bottom\"] = \"bottom\";\n})(BaseAlign || (BaseAlign = {}));\n/**\n * Enum representing the different possible font styles\n */\nvar FontStyle;\n(function (FontStyle) {\n FontStyle[\"Normal\"] = \"normal\";\n FontStyle[\"Italic\"] = \"italic\";\n FontStyle[\"Oblique\"] = \"oblique\";\n})(FontStyle || (FontStyle = {}));\n/**\n * Enum representing the text direction, useful for other languages, or writing text in reverse\n */\nvar Direction;\n(function (Direction) {\n Direction[\"LeftToRight\"] = \"ltr\";\n Direction[\"RightToLeft\"] = \"rtl\";\n})(Direction || (Direction = {}));\n\n;// CONCATENATED MODULE: ./Graphics/FontTextInstance.ts\n\n\n\n\nclass FontTextInstance {\n constructor(font, text, color, maxWidth) {\n this.font = font;\n this.text = text;\n this.color = color;\n this.maxWidth = maxWidth;\n this._textFragments = [];\n this.disposed = false;\n this._dirty = true;\n this.canvas = document.createElement('canvas');\n this.ctx = this.canvas.getContext('2d');\n this.dimensions = this.measureText(text);\n this._setDimension(this.dimensions, this.ctx);\n this._lastHashCode = this.getHashCode();\n }\n measureText(text, maxWidth) {\n if (this.disposed) {\n throw Error('Accessing disposed text instance! ' + this.text);\n }\n let lines = null;\n if (maxWidth != null) {\n lines = this._getLinesFromText(text, maxWidth);\n }\n else {\n lines = text.split('\\n');\n }\n const maxWidthLine = lines.reduce((a, b) => {\n return a.length > b.length ? a : b;\n });\n this._applyFont(this.ctx); // font must be applied to the context to measure it\n const metrics = this.ctx.measureText(maxWidthLine);\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\n // TODO lineheight makes the text bounds wonky\n const lineAdjustedHeight = textHeight * lines.length;\n textHeight = lineAdjustedHeight;\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\n const x = 0;\n const y = 0;\n const measurement = new BoundingBox({\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\n bottom: y + bottomBounds + this.font.padding,\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\n });\n return measurement;\n }\n _setDimension(textBounds, bitmap) {\n let lineHeightRatio = 1;\n if (this.font.lineHeight) {\n lineHeightRatio = (this.font.lineHeight / this.font.size);\n }\n // Changing the width and height clears the context properties\n // We double the bitmap width to account for all possible alignment\n // We scale by \"quality\" so we render text without jaggies\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality * lineHeightRatio;\n }\n static getHashCode(font, text, color) {\n var _a;\n const hash = text +\n '__hashcode__' +\n font.fontString +\n font.showDebug +\n font.textAlign +\n font.baseAlign +\n font.direction +\n font.lineHeight +\n JSON.stringify(font.shadow) +\n (font.padding.toString() +\n font.smoothing.toString() +\n font.lineWidth.toString() +\n font.lineDash.toString() +\n ((_a = font.strokeColor) === null || _a === void 0 ? void 0 : _a.toString()) +\n (color ? color.toString() : font.color.toString()));\n return hash;\n }\n getHashCode(includeColor = true) {\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\n }\n _applyRasterProperties(ctx) {\n var _a, _b;\n ctx.translate(this.font.padding, this.font.padding);\n ctx.imageSmoothingEnabled = this.font.smoothing;\n ctx.lineWidth = this.font.lineWidth;\n ctx.setLineDash((_a = this.font.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.strokeStyle = (_b = this.font.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = this.color.toString();\n }\n _applyFont(ctx) {\n ctx.resetTransform();\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\n ctx.scale(this.font.quality, this.font.quality);\n ctx.textAlign = this.font.textAlign;\n ctx.textBaseline = this.font.baseAlign;\n ctx.font = this.font.fontString;\n ctx.direction = this.font.direction;\n if (this.font.shadow) {\n ctx.shadowColor = this.font.shadow.color.toString();\n ctx.shadowBlur = this.font.shadow.blur;\n ctx.shadowOffsetX = this.font.shadow.offset.x;\n ctx.shadowOffsetY = this.font.shadow.offset.y;\n }\n }\n _drawText(ctx, lines, lineHeight) {\n this._applyRasterProperties(ctx);\n this._applyFont(ctx);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (this.color) {\n ctx.fillText(line, 0, i * lineHeight);\n }\n if (this.font.strokeColor) {\n ctx.strokeText(line, 0, i * lineHeight);\n }\n }\n if (this.font.showDebug) {\n // Horizontal line\n /* istanbul ignore next */\n line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\n // Vertical line\n /* istanbul ignore next */\n line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\n }\n }\n _splitTextBitmap(bitmap) {\n const textImages = [];\n let currentX = 0;\n let currentY = 0;\n // 4k is the max for mobile devices\n const width = Math.min(4096, bitmap.canvas.width);\n const height = Math.min(4096, bitmap.canvas.height);\n // Splits the original bitmap into 4k max chunks\n while (currentX < bitmap.canvas.width) {\n while (currentY < bitmap.canvas.height) {\n // create new bitmap\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n // draw current slice to new bitmap in < 4k chunks\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\n textImages.push({ x: currentX, y: currentY, canvas });\n currentY += height;\n }\n currentX += width;\n currentY = 0;\n }\n return textImages;\n }\n flagDirty() {\n this._dirty = true;\n }\n render(ex, x, y, maxWidth) {\n var _a;\n if (this.disposed) {\n throw Error('Accessing disposed text instance! ' + this.text);\n }\n this._ex = ex;\n const hashCode = this.getHashCode();\n if (this._lastHashCode !== hashCode) {\n this._dirty = true;\n }\n // Calculate image chunks\n if (this._dirty) {\n this.dimensions = this.measureText(this.text, maxWidth);\n this._setDimension(this.dimensions, this.ctx);\n const lines = this._getLinesFromText(this.text, maxWidth);\n const lineHeight = (_a = this.font.lineHeight) !== null && _a !== void 0 ? _a : this.dimensions.height / lines.length;\n // draws the text to the main bitmap\n this._drawText(this.ctx, lines, lineHeight);\n // clear any out old fragments\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\n for (const frag of this._textFragments) {\n ex.textureLoader.delete(frag.canvas);\n }\n }\n // splits to < 4k fragments for large text\n this._textFragments = this._splitTextBitmap(this.ctx);\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\n for (const frag of this._textFragments) {\n ex.textureLoader.load(frag.canvas, this.font.filtering, true);\n }\n }\n this._lastHashCode = hashCode;\n this._dirty = false;\n }\n // draws the bitmap fragments to excalibur graphics context\n for (const frag of this._textFragments) {\n ex.drawImage(frag.canvas, 0, 0, frag.canvas.width, frag.canvas.height, frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2, frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2, frag.canvas.width / this.font.quality, frag.canvas.height / this.font.quality);\n }\n }\n dispose() {\n this.disposed = true;\n this.dimensions = undefined;\n this.canvas = undefined;\n this.ctx = undefined;\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) {\n for (const frag of this._textFragments) {\n this._ex.textureLoader.delete(frag.canvas);\n }\n }\n this._textFragments.length = 0;\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\n return this._cachedLines;\n }\n const lines = text.split('\\n');\n if (maxWidth == null) {\n return lines;\n }\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i];\n let newLine = '';\n if (this.measureText(line).width > maxWidth) {\n while (this.measureText(line).width > maxWidth) {\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/FontCache.ts\n\n\nclass FontCache {\n static measureText(text, font, maxWidth) {\n const hash = FontTextInstance.getHashCode(font, text);\n if (FontCache._MEASURE_CACHE.has(hash)) {\n return FontCache._MEASURE_CACHE.get(hash);\n }\n FontCache._LOGGER.debug('Font text measurement cache miss');\n const measurement = font.measureTextWithoutCache(text, maxWidth);\n FontCache._MEASURE_CACHE.set(hash, measurement);\n return measurement;\n }\n static getTextInstance(text, font, color) {\n const hash = FontTextInstance.getHashCode(font, text, color);\n let textInstance = FontCache._TEXT_CACHE.get(hash);\n if (!textInstance) {\n textInstance = new FontTextInstance(font, text, color);\n FontCache._TEXT_CACHE.set(hash, textInstance);\n FontCache._LOGGER.debug('Font text instance cache miss');\n }\n // Cache the bitmap for certain amount of time\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\n return textInstance;\n }\n static checkAndClearCache() {\n const deferred = [];\n const currentHashCodes = new Set();\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries()) {\n // if bitmap hasn't been used in 100 ms clear it\n if (time + FontCache.FONT_TIMEOUT < performance.now()) {\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\n deferred.push(textInstance);\n textInstance.dispose();\n }\n else {\n const hash = textInstance.getHashCode(false);\n currentHashCodes.add(hash);\n }\n }\n // Deferred removal of text instances\n deferred.forEach((t) => {\n FontCache._TEXT_USAGE.delete(t);\n });\n // Regenerate text instance cache\n this._TEXT_CACHE.clear();\n for (const [textInstance] of this._TEXT_USAGE.entries()) {\n this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\n }\n // Regenerated measurement cache\n const newTextMeasurementCache = new Map();\n for (const current of currentHashCodes) {\n if (FontCache._MEASURE_CACHE.has(current)) {\n newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\n }\n }\n this._MEASURE_CACHE.clear();\n this._MEASURE_CACHE = newTextMeasurementCache;\n }\n static get cacheSize() {\n return FontCache._TEXT_USAGE.size;\n }\n /**\n * Force clear all cached text bitmaps\n */\n static clearCache() {\n for (const [textInstance] of FontCache._TEXT_USAGE.entries()) {\n textInstance.dispose();\n }\n FontCache._TEXT_USAGE.clear();\n FontCache._TEXT_CACHE.clear();\n FontCache._MEASURE_CACHE.clear();\n }\n}\nFontCache.FONT_TIMEOUT = 500;\nFontCache._LOGGER = Logger.getInstance();\nFontCache._TEXT_USAGE = new Map();\nFontCache._TEXT_CACHE = new Map();\nFontCache._MEASURE_CACHE = new Map();\n\n;// CONCATENATED MODULE: ./Graphics/Font.ts\n\n\n\n\n\n\n\n/**\n * Represents a system or web font in Excalibur\n *\n * If no options specified, the system sans-serif 10 pixel is used\n *\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\n */\nclass Font extends Graphic {\n constructor(options = {}) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;\n super(options); // <- Graphics properties\n /**\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\n *\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\n */\n this.filtering = ImageFiltering.Blended;\n /**\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\n *\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\n *\n * (Default 2)\n */\n this.quality = 2;\n // Raster properties for fonts\n this.padding = 2;\n this.smoothing = false;\n this.lineWidth = 1;\n this.lineDash = [];\n this.color = Color.Black;\n this.family = 'sans-serif';\n this.style = FontStyle.Normal;\n this.bold = false;\n this.unit = FontUnit.Px;\n this.textAlign = TextAlign.Left;\n this.baseAlign = BaseAlign.Top;\n this.direction = Direction.LeftToRight;\n /**\n * Font line height in pixels, default line height if unset\n */\n this.lineHeight = undefined;\n this.size = 10;\n this.shadow = null;\n this._textBounds = new BoundingBox();\n this._textMeasurement = new FontTextInstance(this, '', Color.Black);\n // Raster properties\n this.smoothing = (_a = options === null || options === void 0 ? void 0 : options.smoothing) !== null && _a !== void 0 ? _a : this.smoothing;\n this.padding = (_b = options === null || options === void 0 ? void 0 : options.padding) !== null && _b !== void 0 ? _b : this.padding;\n this.color = (_c = options === null || options === void 0 ? void 0 : options.color) !== null && _c !== void 0 ? _c : this.color;\n this.strokeColor = (_d = options === null || options === void 0 ? void 0 : options.strokeColor) !== null && _d !== void 0 ? _d : this.strokeColor;\n this.lineDash = (_e = options === null || options === void 0 ? void 0 : options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineWidth = (_f = options === null || options === void 0 ? void 0 : options.lineWidth) !== null && _f !== void 0 ? _f : this.lineWidth;\n this.filtering = (_g = options === null || options === void 0 ? void 0 : options.filtering) !== null && _g !== void 0 ? _g : this.filtering;\n // Font specific properties\n this.family = (_h = options === null || options === void 0 ? void 0 : options.family) !== null && _h !== void 0 ? _h : this.family;\n this.style = (_j = options === null || options === void 0 ? void 0 : options.style) !== null && _j !== void 0 ? _j : this.style;\n this.bold = (_k = options === null || options === void 0 ? void 0 : options.bold) !== null && _k !== void 0 ? _k : this.bold;\n this.size = (_l = options === null || options === void 0 ? void 0 : options.size) !== null && _l !== void 0 ? _l : this.size;\n this.unit = (_m = options === null || options === void 0 ? void 0 : options.unit) !== null && _m !== void 0 ? _m : this.unit;\n this.textAlign = (_o = options === null || options === void 0 ? void 0 : options.textAlign) !== null && _o !== void 0 ? _o : this.textAlign;\n this.baseAlign = (_p = options === null || options === void 0 ? void 0 : options.baseAlign) !== null && _p !== void 0 ? _p : this.baseAlign;\n this.direction = (_q = options === null || options === void 0 ? void 0 : options.direction) !== null && _q !== void 0 ? _q : this.direction;\n this.lineHeight = (_r = options === null || options === void 0 ? void 0 : options.lineHeight) !== null && _r !== void 0 ? _r : this.lineHeight;\n this.quality = (_s = options === null || options === void 0 ? void 0 : options.quality) !== null && _s !== void 0 ? _s : this.quality;\n if (options === null || options === void 0 ? void 0 : options.shadow) {\n this.shadow = {};\n this.shadow.blur = (_t = options.shadow.blur) !== null && _t !== void 0 ? _t : this.shadow.blur;\n this.shadow.offset = (_u = options.shadow.offset) !== null && _u !== void 0 ? _u : this.shadow.offset;\n this.shadow.color = (_v = options.shadow.color) !== null && _v !== void 0 ? _v : this.shadow.color;\n }\n }\n clone() {\n return new Font({\n ...this.cloneGraphicOptions(),\n size: this.size,\n unit: this.unit,\n family: this.family,\n style: this.style,\n bold: this.bold,\n textAlign: this.textAlign,\n baseAlign: this.baseAlign,\n direction: this.direction,\n shadow: this.shadow\n ? {\n blur: this.shadow.blur,\n offset: this.shadow.offset,\n color: this.shadow.color\n }\n : null\n });\n }\n get fontString() {\n return `${this.style} ${this.bold ? 'bold' : ''} ${this.size}${this.unit} ${this.family}`;\n }\n get localBounds() {\n return this._textBounds;\n }\n _drawImage(_ex, _x, _y) {\n // TODO weird vestigial drawimage\n }\n _rotate(ex) {\n var _a;\n // TODO this needs to change depending on the bounding box...\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : this._textBounds.center;\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this._textBounds.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\n ex.scale(1, -1);\n }\n }\n measureTextWithoutCache(text, maxWidth) {\n return this._textMeasurement.measureText(text, maxWidth);\n }\n /**\n * Returns a BoundingBox that is the total size of the text including multiple lines\n *\n * Does not include any padding or adjustment\n * @param text\n * @returns BoundingBox\n */\n measureText(text, maxWidth) {\n return FontCache.measureText(text, this, maxWidth);\n }\n _postDraw(ex) {\n ex.restore();\n }\n render(ex, text, colorOverride, x, y, maxWidth) {\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\n // Apply affine transformations\n this._textBounds = textInstance.dimensions;\n this._preDraw(ex, x, y);\n textInstance.render(ex, x, y, maxWidth);\n this._postDraw(ex);\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Text.ts\n\n\n\n/**\n * Represent Text graphics in excalibur\n *\n * Useful for in game labels, ui, or overlays\n */\nclass Text extends Graphic {\n constructor(options) {\n var _a, _b;\n super(options);\n this._text = '';\n this._textWidth = 0;\n this._textHeight = 0;\n // This order is important font, color, then text\n this.font = (_a = options.font) !== null && _a !== void 0 ? _a : new Font();\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : this.color;\n this.text = options.text;\n this.maxWidth = options.maxWidth;\n }\n clone() {\n var _a, _b;\n return new Text({\n text: this.text.slice(),\n color: (_b = (_a = this.color) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : Color.Black,\n font: this.font.clone(),\n maxWidth: this.maxWidth\n });\n }\n get text() {\n return this._text;\n }\n set text(value) {\n this._text = value;\n this._calculateDimension();\n }\n get font() {\n return this._font;\n }\n set font(font) {\n this._font = font;\n }\n get width() {\n if (this._textWidth === 0) {\n this._calculateDimension();\n }\n return this._textWidth * this.scale.x;\n }\n get height() {\n if (this._textHeight === 0) {\n this._calculateDimension();\n }\n return this._textHeight * this.scale.y;\n }\n _calculateDimension() {\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n }\n get localBounds() {\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\n }\n _rotate(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _flip(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _preDraw(ex, x, y) {\n if (this.isStale() || this.font.isStale()) {\n this.font.flipHorizontal = this.flipHorizontal;\n this.font.flipVertical = this.flipVertical;\n this.font.rotation = this.rotation;\n this.font.origin = this.origin;\n this.font.opacity = this.opacity;\n }\n this.font.tint = this.tint;\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n var _a;\n let color = Color.Black;\n if (this.font instanceof Font) {\n color = (_a = this.color) !== null && _a !== void 0 ? _a : this.font.color;\n }\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\n if (this.font.showDebug) {\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\n if (this.maxWidth != null) {\n ex.debug.drawRect(x, y, this.maxWidth, this.height, {\n color: Color.Yellow\n });\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Actor.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Type guard for checking if something is an Actor\n * @param x\n */\nfunction isActor(x) {\n return x instanceof Actor;\n}\nconst ActorEvents = {\n CollisionStart: 'collisionstart',\n CollisionEnd: 'collisionend',\n PreCollision: 'precollision',\n PostCollision: 'postcollision',\n Kill: 'kill',\n PreKill: 'prekill',\n PostKill: 'postkill',\n PreDraw: 'predraw',\n PostDraw: 'postdraw',\n PreTransformDraw: 'pretransformdraw',\n PostTransformDraw: 'posttransformdraw',\n PreDebugDraw: 'predebugdraw',\n PostDebugDraw: 'postdebugdraw',\n PointerUp: 'pointerup',\n PointerDown: 'pointerdown',\n PointerEnter: 'pointerenter',\n PointerLeave: 'pointerleave',\n PointerMove: 'pointermove',\n PointerCancel: 'pointercancel',\n Wheel: 'pointerwheel',\n PointerDrag: 'pointerdragstart',\n PointerDragEnd: 'pointerdragend',\n PointerDragEnter: 'pointerdragenter',\n PointerDragLeave: 'pointerdragleave',\n PointerDragMove: 'pointerdragmove',\n EnterViewPort: 'enterviewport',\n ExitViewPort: 'exitviewport',\n ActionStart: 'actionstart',\n ActionComplete: 'actioncomplete'\n};\n/**\n * The most important primitive in Excalibur is an `Actor`. Anything that\n * can move on the screen, collide with another `Actor`, respond to events,\n * or interact with the current scene, must be an actor. An `Actor` **must**\n * be part of a [[Scene]] for it to be drawn to the screen.\n */\nclass Actor extends Entity {\n /**\n * Gets the position vector of the actor in pixels\n */\n get pos() {\n return this.transform.pos;\n }\n /**\n * Sets the position vector of the actor in pixels\n */\n set pos(thePos) {\n this.transform.pos = thePos.clone();\n }\n /**\n * Gets the position vector of the actor from the last frame\n */\n get oldPos() {\n return this.body.oldPos;\n }\n /**\n * Sets the position vector of the actor in the last frame\n */\n set oldPos(thePos) {\n this.body.oldPos.setTo(thePos.x, thePos.y);\n }\n /**\n * Gets the velocity vector of the actor in pixels/sec\n */\n get vel() {\n return this.motion.vel;\n }\n /**\n * Sets the velocity vector of the actor in pixels/sec\n */\n set vel(theVel) {\n this.motion.vel = theVel.clone();\n }\n /**\n * Gets the velocity vector of the actor from the last frame\n */\n get oldVel() {\n return this.body.oldVel;\n }\n /**\n * Sets the velocity vector of the actor from the last frame\n */\n set oldVel(theVel) {\n this.body.oldVel.setTo(theVel.x, theVel.y);\n }\n /**\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\n * useful to simulate a gravitational effect.\n */\n get acc() {\n return this.motion.acc;\n }\n /**\n * Sets the acceleration vector of teh actor in pixels/second/second\n */\n set acc(theAcc) {\n this.motion.acc = theAcc.clone();\n }\n /**\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */\n set oldAcc(theAcc) {\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\n }\n /**\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\n */\n get oldAcc() {\n return this.body.oldAcc;\n }\n /**\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\n */\n get rotation() {\n return this.transform.rotation;\n }\n /**\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\n */\n set rotation(theAngle) {\n this.transform.rotation = theAngle;\n }\n /**\n * Gets the rotational velocity of the actor in radians/second\n */\n get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\n * Sets the rotational velocity of the actor in radians/sec\n */\n set angularVelocity(angularVelocity) {\n this.motion.angularVelocity = angularVelocity;\n }\n get scale() {\n return this.get(TransformComponent).scale;\n }\n set scale(scale) {\n this.get(TransformComponent).scale = scale;\n }\n /**\n * The anchor to apply all actor related transformations like rotation,\n * translation, and scaling. By default the anchor is in the center of\n * the actor. By default it is set to the center of the actor (.5, .5)\n *\n * An anchor of (.5, .5) will ensure that drawings are centered.\n *\n * Use `anchor.setTo` to set the anchor to a different point using\n * values between 0 and 1. For example, anchoring to the top-left would be\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\n */\n get anchor() {\n return this._anchor;\n }\n set anchor(vec) {\n this._anchor = watch(vec, (v) => this._handleAnchorChange(v));\n this._handleAnchorChange(vec);\n }\n _handleAnchorChange(v) {\n if (this.graphics) {\n this.graphics.anchor = v;\n }\n }\n /**\n * The offset in pixels to apply to all actor graphics\n *\n * Default offset of (0, 0)\n */\n get offset() {\n return this._offset;\n }\n set offset(vec) {\n this._offset = watch(vec, (v) => this._handleOffsetChange(v));\n this._handleOffsetChange(vec);\n }\n _handleOffsetChange(v) {\n if (this.graphics) {\n this.graphics.offset = v;\n }\n }\n /**\n * Indicates whether the actor is physically in the viewport\n */\n get isOffScreen() {\n return this.hasTag('ex.offscreen');\n }\n get draggable() {\n return this._draggable;\n }\n set draggable(isDraggable) {\n if (isDraggable) {\n if (isDraggable && !this._draggable) {\n this.events.on('pointerdragstart', this._pointerDragStartHandler);\n this.events.on('pointerdragend', this._pointerDragEndHandler);\n this.events.on('pointerdragmove', this._pointerDragMoveHandler);\n this.events.on('pointerdragleave', this._pointerDragLeaveHandler);\n }\n else if (!isDraggable && this._draggable) {\n this.events.off('pointerdragstart', this._pointerDragStartHandler);\n this.events.off('pointerdragend', this._pointerDragEndHandler);\n this.events.off('pointerdragmove', this._pointerDragMoveHandler);\n this.events.off('pointerdragleave', this._pointerDragLeaveHandler);\n }\n this._draggable = isDraggable;\n }\n }\n /**\n * Sets the color of the actor's current graphic\n */\n get color() {\n return this._color;\n }\n set color(v) {\n this._color = v.clone();\n const currentGraphic = this.graphics.current;\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) {\n currentGraphic.color = this._color;\n }\n }\n // #endregion\n /**\n *\n * @param config\n */\n constructor(config) {\n super();\n this.events = new EventEmitter();\n this._anchor = watch(Vector.Half, (v) => this._handleAnchorChange(v));\n this._offset = watch(Vector.Zero, (v) => this._handleOffsetChange(v));\n /**\n * Convenience reference to the global logger\n */\n this.logger = Logger.getInstance();\n /**\n * Draggable helper\n */\n this._draggable = false;\n this._dragging = false;\n this._pointerDragStartHandler = () => {\n this._dragging = true;\n };\n this._pointerDragEndHandler = () => {\n this._dragging = false;\n };\n this._pointerDragMoveHandler = (pe) => {\n if (this._dragging) {\n this.pos = pe.worldPos;\n }\n };\n this._pointerDragLeaveHandler = (pe) => {\n if (this._dragging) {\n this.pos = pe.worldPos;\n }\n };\n const { name, x, y, pos, coordPlane, scale, width, height, radius, collider, vel, acc, rotation, angularVelocity, z, color, visible, opacity, anchor, offset, collisionType, collisionGroup } = {\n ...config\n };\n this.name = name !== null && name !== void 0 ? name : this.name;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : Actor.defaults.anchor.clone();\n this.offset = offset !== null && offset !== void 0 ? offset : Vector.Zero;\n this.transform = new TransformComponent();\n this.addComponent(this.transform);\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.rotation = rotation !== null && rotation !== void 0 ? rotation : 0;\n this.scale = scale !== null && scale !== void 0 ? scale : vec(1, 1);\n this.z = z !== null && z !== void 0 ? z : 0;\n this.transform.coordPlane = coordPlane !== null && coordPlane !== void 0 ? coordPlane : CoordPlane.World;\n this.pointer = new PointerComponent;\n this.addComponent(this.pointer);\n this.graphics = new GraphicsComponent({\n anchor: this.anchor,\n offset: this.offset,\n opacity: opacity\n });\n this.addComponent(this.graphics);\n this.motion = new MotionComponent;\n this.addComponent(this.motion);\n this.vel = vel !== null && vel !== void 0 ? vel : Vector.Zero;\n this.acc = acc !== null && acc !== void 0 ? acc : Vector.Zero;\n this.angularVelocity = angularVelocity !== null && angularVelocity !== void 0 ? angularVelocity : 0;\n this.actions = new ActionsComponent;\n this.addComponent(this.actions);\n this.body = new BodyComponent;\n this.addComponent(this.body);\n this.body.collisionType = collisionType !== null && collisionType !== void 0 ? collisionType : CollisionType.Passive;\n if (collisionGroup) {\n this.body.group = collisionGroup;\n }\n if (collider) {\n this.collider = new ColliderComponent(collider);\n this.addComponent(this.collider);\n }\n else if (radius) {\n this.collider = new ColliderComponent(Shape.Circle(radius));\n this.addComponent(this.collider);\n }\n else {\n if (width > 0 && height > 0) {\n this.collider = new ColliderComponent(Shape.Box(width, height, this.anchor));\n this.addComponent(this.collider);\n }\n else {\n this.collider = new ColliderComponent();\n this.addComponent(this.collider); // no collider\n }\n }\n this.graphics.visible = visible !== null && visible !== void 0 ? visible : true;\n if (color) {\n this.color = color;\n if (width && height) {\n this.graphics.add(new Rectangle({\n color: color,\n width,\n height\n }));\n }\n else if (radius) {\n this.graphics.add(new Circle({\n color: color,\n radius\n }));\n }\n }\n }\n clone() {\n const clone = new Actor({\n color: this.color.clone(),\n anchor: this.anchor.clone(),\n offset: this.offset.clone()\n });\n clone.clearComponents();\n clone.processComponentRemoval();\n // Clone builtins, order is important, same as ctor\n clone.addComponent(clone.transform = this.transform.clone(), true);\n clone.addComponent(clone.pointer = this.pointer.clone(), true);\n clone.addComponent(clone.graphics = this.graphics.clone(), true);\n clone.addComponent(clone.motion = this.motion.clone(), true);\n clone.addComponent(clone.actions = this.actions.clone(), true);\n clone.addComponent(clone.body = this.body.clone(), true);\n clone.addComponent(clone.collider = this.collider.clone(), true);\n const builtInComponents = [\n this.transform,\n this.pointer,\n this.graphics,\n this.motion,\n this.actions,\n this.body,\n this.collider\n ];\n // Clone non-builtin the current actors components\n const components = this.getComponents();\n for (const c of components) {\n if (!builtInComponents.includes(c)) {\n clone.addComponent(c.clone(), true);\n }\n }\n return clone;\n }\n /**\n * `onInitialize` is called before the first update of the actor. This method is meant to be\n * overridden. This is where initialization of child actors should take place.\n *\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\n */\n onInitialize(engine) {\n // Override me\n }\n /**\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\n *\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n * @internal\n */\n _initialize(engine) {\n super._initialize(engine);\n for (const child of this.children) {\n child._initialize(engine);\n }\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n // #endregion\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _prekill handler for [[onPreKill]] lifecycle event\n * @internal\n */\n _prekill(scene) {\n this.events.emit('prekill', new PreKillEvent(this));\n this.onPreKill(scene);\n }\n /**\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\n *\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\n */\n onPreKill(scene) {\n // Override me\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _prekill handler for [[onPostKill]] lifecycle event\n * @internal\n */\n _postkill(scene) {\n this.events.emit('postkill', new PostKillEvent(this));\n this.onPostKill(scene);\n }\n /**\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\n *\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\n */\n onPostKill(scene) {\n // Override me\n }\n /**\n * If the current actor is a member of the scene, this will remove\n * it from the scene graph. It will no longer be drawn or updated.\n */\n kill() {\n if (this.scene) {\n this._prekill(this.scene);\n this.events.emit('kill', new KillEvent(this));\n super.kill();\n this._postkill(this.scene);\n }\n else {\n this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\n }\n }\n /**\n * If the current actor is killed, it will now not be killed.\n */\n unkill() {\n this.active = true;\n }\n /**\n * Indicates wether the actor has been killed.\n */\n isKilled() {\n return !this.active;\n }\n /**\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\n */\n get z() {\n return this.get(TransformComponent).z;\n }\n /**\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\n * The z-index determines the relative order an actor is drawn in.\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\n * @param newZ new z-index to assign\n */\n set z(newZ) {\n this.get(TransformComponent).z = newZ;\n }\n /**\n * Get the center point of an actor (global position)\n */\n get center() {\n const globalPos = this.getGlobalPos();\n return new Vector(globalPos.x + this.width / 2 - this.anchor.x * this.width, globalPos.y + this.height / 2 - this.anchor.y * this.height);\n }\n /**\n * Get the local center point of an actor\n */\n get localCenter() {\n return new Vector(this.pos.x + this.width / 2 - this.anchor.x * this.width, this.pos.y + this.height / 2 - this.anchor.y * this.height);\n }\n get width() {\n return this.collider.localBounds.width * this.getGlobalScale().x;\n }\n get height() {\n return this.collider.localBounds.height * this.getGlobalScale().y;\n }\n /**\n * Gets this actor's rotation taking into account any parent relationships\n * @returns Rotation angle in radians\n */\n getGlobalRotation() {\n return this.get(TransformComponent).globalRotation;\n }\n /**\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\n * @returns Position in world coordinates\n */\n getGlobalPos() {\n return this.get(TransformComponent).globalPos;\n }\n /**\n * Gets the global scale of the Actor\n */\n getGlobalScale() {\n return this.get(TransformComponent).globalScale;\n }\n // #region Collision\n /**\n * Tests whether the x/y specified are contained in the actor\n * @param x X coordinate to test (in world coordinates)\n * @param y Y coordinate to test (in world coordinates)\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\n */\n contains(x, y, recurse = false) {\n const point = vec(x, y);\n const collider = this.get(ColliderComponent);\n collider.update();\n const geom = collider.get();\n if (!geom) {\n return false;\n }\n const containment = geom.contains(point);\n if (recurse) {\n return (containment ||\n this.children.some((child) => {\n return child.contains(x, y, true);\n }));\n }\n return containment;\n }\n /**\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\n * @param actor Actor to test\n * @param distance Distance in pixels to test\n */\n within(actor, distance) {\n const collider = this.get(ColliderComponent);\n const otherCollider = actor.get(ColliderComponent);\n const me = collider.get();\n const other = otherCollider.get();\n if (me && other) {\n return me.getClosestLineBetween(other).getLength() <= distance;\n }\n return false;\n }\n // #endregion\n // #region Update\n /**\n * Called by the Engine, updates the state of the actor\n * @internal\n * @param engine The reference to the current game engine\n * @param delta The time elapsed since the last update in milliseconds\n */\n update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this._postupdate(engine, delta);\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before an actor is updated.\n */\n onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after an actor is updated.\n */\n onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n * Fires before every collision resolution for a confirmed contact\n * @param self\n * @param other\n * @param side\n * @param contact\n */\n onPreCollisionResolve(self, other, side, contact) {\n // Override me\n }\n /**\n * Fires after every resolution for a confirmed contact.\n * @param self\n * @param other\n * @param side\n * @param contact\n */\n onPostCollisionResolve(self, other, side, contact) {\n // Override me\n }\n /**\n * Fires once when 2 entities with a ColliderComponent first start colliding or touching, if the Colliders stay in contact this\n * does not continue firing until they separate and re-collide.\n * @param self\n * @param other\n * @param side\n * @param contact\n */\n onCollisionStart(self, other, side, contact) {\n // Override me\n }\n /**\n * Fires once when 2 entities with a ColliderComponent separate after having been in contact.\n * @param self\n * @param other\n * @param side\n * @param lastContact\n */\n onCollisionEnd(self, other, side, lastContact) {\n // Override me\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */\n _preupdate(engine, delta) {\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */\n _postupdate(engine, delta) {\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n}\n// #region Properties\n/**\n * Set defaults for all Actors\n */\nActor.defaults = {\n anchor: Vector.Half\n};\n\n;// CONCATENATED MODULE: ./ScreenElement.ts\n\n\n\n\n\n/**\n * Type guard to detect a screen element\n */\nfunction isScreenElement(actor) {\n return actor instanceof ScreenElement;\n}\n/**\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\n * not participate in collisions. Drawn on top of all other actors.\n */\nclass ScreenElement extends Actor {\n constructor(config) {\n var _a, _b;\n super({ ...config });\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\n this.anchor = (_a = config === null || config === void 0 ? void 0 : config.anchor) !== null && _a !== void 0 ? _a : vec(0, 0);\n this.body.collisionType = (_b = config === null || config === void 0 ? void 0 : config.collisionType) !== null && _b !== void 0 ? _b : CollisionType.PreventCollision;\n this.pointer.useGraphicsBounds = true;\n this.pointer.useColliderShape = false;\n if (!(config === null || config === void 0 ? void 0 : config.collider) &&\n (config === null || config === void 0 ? void 0 : config.width) > 0 &&\n (config === null || config === void 0 ? void 0 : config.height) > 0) {\n this.collider.useBoxCollider(this.width, this.height, this.anchor);\n }\n }\n _initialize(engine) {\n this._engine = engine;\n super._initialize(engine);\n }\n contains(x, y, useWorld = true) {\n if (useWorld) {\n return super.contains(x, y);\n }\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\n return super.contains(coords.x, coords.y);\n }\n}\n\n;// CONCATENATED MODULE: ./Timer.ts\n\n\n/**\n * The Excalibur timer hooks into the internal timer and fires callbacks,\n * after a certain interval, optionally repeating.\n */\nclass Timer {\n get complete() {\n return this._complete;\n }\n constructor(fcn, interval, repeats, numberOfRepeats, randomRange, random) {\n this._logger = Logger.getInstance();\n this.id = 0;\n this._elapsedTime = 0;\n this._totalTimeAlive = 0;\n this._running = false;\n this._numberOfTicks = 0;\n this.interval = 10;\n this.repeats = false;\n this.maxNumberOfRepeats = -1;\n this.randomRange = [0, 0];\n this._baseInterval = 10;\n this._generateRandomInterval = () => {\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\n };\n this._complete = false;\n this.scene = null;\n if (typeof fcn !== 'function') {\n const options = fcn;\n fcn = options.fcn;\n interval = options.interval;\n repeats = options.repeats;\n numberOfRepeats = options.numberOfRepeats;\n randomRange = options.randomRange;\n random = options.random;\n }\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\n this.maxNumberOfRepeats = numberOfRepeats;\n if (!repeats) {\n throw new Error('repeats must be set to true if numberOfRepeats is set');\n }\n }\n this.id = Timer._MAX_ID++;\n this._callbacks = [];\n this._baseInterval = this.interval = interval;\n if (!!randomRange) {\n if (randomRange[0] > randomRange[1]) {\n throw new Error('min value must be lower than max value for range');\n }\n //We use the instance of ex.Random to generate the range\n this.random = random !== null && random !== void 0 ? random : new Random();\n this.randomRange = randomRange;\n this.interval = this._generateRandomInterval();\n this.on(() => {\n this.interval = this._generateRandomInterval();\n });\n }\n ;\n this.repeats = repeats || this.repeats;\n if (fcn) {\n this.on(fcn);\n }\n }\n /**\n * Adds a new callback to be fired after the interval is complete\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\n */\n on(fcn) {\n this._callbacks.push(fcn);\n }\n /**\n * Removes a callback from the callback list to be fired after the interval is complete.\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\n */\n off(fcn) {\n const index = this._callbacks.indexOf(fcn);\n this._callbacks.splice(index, 1);\n }\n /**\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\n * @param delta Number of elapsed milliseconds since the last update.\n */\n update(delta) {\n if (this._running) {\n this._totalTimeAlive += delta;\n this._elapsedTime += delta;\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n if (!this.complete && this._elapsedTime >= this.interval) {\n this._callbacks.forEach((c) => {\n c.call(this);\n });\n this._numberOfTicks++;\n if (this.repeats) {\n this._elapsedTime = 0;\n }\n else {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n }\n }\n }\n /**\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\n *\n * Warning** you may need to call `timer.start()` again if the timer had completed\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\n */\n reset(newInterval, newNumberOfRepeats) {\n if (!!newInterval && newInterval >= 0) {\n this._baseInterval = this.interval = newInterval;\n }\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\n this.maxNumberOfRepeats = newNumberOfRepeats;\n if (!this.repeats) {\n throw new Error('repeats must be set to true if numberOfRepeats is set');\n }\n }\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n get timesRepeated() {\n return this._numberOfTicks;\n }\n getTimeRunning() {\n return this._totalTimeAlive;\n }\n /**\n * @returns milliseconds until the next action callback, if complete will return 0\n */\n get timeToNextAction() {\n if (this.complete) {\n return 0;\n }\n return this.interval - this._elapsedTime;\n }\n /**\n * @returns milliseconds elapsed toward the next action\n */\n get timeElapsedTowardNextAction() {\n return this._elapsedTime;\n }\n get isRunning() {\n return this._running;\n }\n /**\n * Pauses the timer, time will no longer increment towards the next call\n */\n pause() {\n this._running = false;\n return this;\n }\n /**\n * Resumes the timer, time will now increment towards the next call.\n */\n resume() {\n this._running = true;\n return this;\n }\n /**\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\n */\n start() {\n if (!this.scene) {\n this._logger.warn('Cannot start a timer not part of a scene, timer wont start until added');\n }\n this._running = true;\n if (this.complete) {\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n return this;\n }\n /**\n * Stops the timer and resets the elapsed time counter towards the next action invocation\n */\n stop() {\n this._running = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n return this;\n }\n /**\n * Cancels the timer, preventing any further executions.\n */\n cancel() {\n this.pause();\n if (this.scene) {\n this.scene.cancelTimer(this);\n }\n }\n}\nTimer._MAX_ID = 0;\n\n;// CONCATENATED MODULE: ./Graphics/ParallaxComponent.ts\n\n\nclass ParallaxComponent extends Component {\n constructor(parallaxFactor) {\n super();\n this.parallaxFactor = vec(1.0, 1.0);\n this.parallaxFactor = parallaxFactor !== null && parallaxFactor !== void 0 ? parallaxFactor : this.parallaxFactor;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/DebugGraphicsComponent.ts\n\n/**\n * Provide arbitrary drawing for the purposes of debugging your game\n *\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\n *\n */\nclass DebugGraphicsComponent extends Component {\n constructor(draw, useTransform = true) {\n super();\n this.draw = draw;\n this.useTransform = useTransform;\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/TileMap.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst TileMapEvents = {\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate',\n PreDraw: 'predraw',\n PostDraw: 'postdraw'\n};\n/**\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\n *\n * TileMaps are useful for top down or side scrolling grid oriented games.\n */\nclass TileMap extends Entity {\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n flagTilesDirty() {\n for (let i = 0; i < this.tiles.length; i++) {\n if (this.tiles[i]) {\n this.tiles[i].flagDirty();\n }\n }\n }\n get x() {\n var _a;\n return (_a = this.transform.pos.x) !== null && _a !== void 0 ? _a : 0;\n }\n set x(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos) {\n this.get(TransformComponent).pos = vec(val, this.y);\n }\n }\n get y() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos.y) !== null && _b !== void 0 ? _b : 0;\n }\n set y(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.pos) {\n this.transform.pos = vec(this.x, val);\n }\n }\n get z() {\n var _a;\n return (_a = this.transform.z) !== null && _a !== void 0 ? _a : 0;\n }\n set z(val) {\n if (this.transform) {\n this.transform.z = val;\n }\n }\n get rotation() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.rotation) !== null && _b !== void 0 ? _b : 0;\n }\n set rotation(val) {\n if (this.transform) {\n this.transform.rotation = val;\n }\n }\n get scale() {\n var _a, _b;\n return (_b = (_a = this.transform) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : Vector.One;\n }\n set scale(val) {\n var _a;\n if ((_a = this.transform) === null || _a === void 0 ? void 0 : _a.scale) {\n this.transform.scale = val;\n }\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n get vel() {\n return this._motion.vel;\n }\n set vel(val) {\n this._motion.vel = val;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * @param options\n */\n constructor(options) {\n var _a, _b, _c;\n super([], options.name);\n this.events = new EventEmitter();\n this._token = 0;\n this.logger = Logger.getInstance();\n this.tiles = [];\n this._rows = [];\n this._cols = [];\n this.renderFromTopOfGraphic = false;\n this.meshingLookBehind = 10;\n this._collidersDirty = true;\n this._originalOffsets = new WeakMap();\n this.meshingLookBehind = (_a = options.meshingLookBehind) !== null && _a !== void 0 ? _a : this.meshingLookBehind;\n this.addComponent(new TransformComponent());\n this.addComponent(new MotionComponent());\n this.addComponent(new BodyComponent({\n type: CollisionType.Fixed\n }));\n this.addComponent(new GraphicsComponent({\n onPostDraw: (ctx, delta) => this.draw(ctx, delta)\n }));\n this.addComponent(new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false));\n this.addComponent(new ColliderComponent());\n this._graphics = this.get(GraphicsComponent);\n this.transform = this.get(TransformComponent);\n this._motion = this.get(MotionComponent);\n this.collider = this.get(ColliderComponent);\n this._composite = this.collider.useCompositeCollider([]);\n this.transform.pos = (_b = options.pos) !== null && _b !== void 0 ? _b : Vector.Zero;\n this._oldPos = this.transform.pos.clone();\n this._oldScale = this.transform.scale.clone();\n this.renderFromTopOfGraphic = (_c = options.renderFromTopOfGraphic) !== null && _c !== void 0 ? _c : this.renderFromTopOfGraphic;\n this.tileWidth = options.tileWidth;\n this.tileHeight = options.tileHeight;\n this.rows = options.rows;\n this.columns = options.columns;\n this.tiles = new Array(this.rows * this.columns);\n this._rows = new Array(this.rows);\n this._cols = new Array(this.columns);\n let currentCol = [];\n for (let i = 0; i < this.columns; i++) {\n for (let j = 0; j < this.rows; j++) {\n const tile = new Tile({\n x: i,\n y: j,\n map: this\n });\n tile.map = this;\n this.tiles[i + j * this.columns] = tile;\n currentCol.push(tile);\n if (!this._rows[j]) {\n this._rows[j] = [];\n }\n this._rows[j].push(tile);\n }\n this._cols[i] = currentCol;\n currentCol = [];\n }\n this._graphics.localBounds = new BoundingBox({\n left: 0,\n top: 0,\n right: this.columns * this.tileWidth * this.scale.x,\n bottom: this.rows * this.tileHeight * this.scale.y\n });\n }\n _initialize(engine) {\n super._initialize(engine);\n this._engine = engine;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n }\n else {\n return this._originalOffsets.get(collider);\n }\n }\n /**\n * Tiles colliders based on the solid tiles in the tilemap.\n */\n _updateColliders() {\n this.collider.$colliderRemoved.notifyAll(this._composite);\n this._composite.clearColliders();\n const colliders = [];\n this._composite = this.collider.useCompositeCollider([]);\n let current;\n /**\n * Returns wether or not the 2 boxes share an edge and are the same height\n * @param prev\n * @param next\n * @returns true if they share and edge, false if not\n */\n const shareEdges = (prev, next) => {\n if (prev && next) {\n // same top/bottom\n return prev.top === next.top &&\n prev.bottom === next.bottom &&\n // Shared right/left edge\n prev.right === next.left;\n }\n return false;\n };\n /**\n * Potentially merges the current collider into a list of previous ones, mutating the list\n * If checkAndCombine returns true, the collider was successfully merged and should be thrown away\n * @param current current collider to test\n * @param colliders List of colliders to consider merging with\n * @param maxLookBack The amount of colliders to look back for combination\n * @returns false when no combination found, true when successfully combined\n */\n const checkAndCombine = (current, colliders, maxLookBack = this.meshingLookBehind) => {\n if (!current) {\n return false;\n }\n // walk backwards through the list of colliders and combine with the first that shares an edge\n for (let i = colliders.length - 1; i >= 0; i--) {\n if (maxLookBack-- < 0) {\n // blunt the O(n^2) algorithm a bit\n return false;\n }\n const prev = colliders[i];\n if (shareEdges(prev, current)) {\n colliders[i] = prev.combine(current);\n return true;\n }\n }\n return false;\n };\n // ? configurable bias perhaps, horizontal strips vs. vertical ones\n // Bad tile collider packing algorithm\n for (let i = 0; i < this.columns; i++) {\n // Scan column for colliders\n for (let j = 0; j < this.rows; j++) {\n const tile = this.tiles[i + j * this.columns];\n // Current tile in column is solid build up current collider\n if (tile.solid) {\n // Use custom collider otherwise bounding box\n if (tile.getColliders().length > 0) {\n // tile with custom collider interrupting the current run\n for (const collider of tile.getColliders()) {\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n //we push any current collider before nulling the current run\n if (current && !checkAndCombine(current, colliders)) {\n colliders.push(current);\n }\n current = null;\n // Use the bounding box\n }\n else {\n if (!current) {\n // no current run, start one\n current = tile.defaultGeometry;\n }\n else {\n // combine with current run\n current = current.combine(tile.defaultGeometry);\n }\n }\n }\n else {\n // Not solid skip and cut off the current collider\n // End of run check and combine\n if (current && !checkAndCombine(current, colliders)) {\n colliders.push(current);\n }\n current = null;\n }\n }\n // After a column is complete check to see if it can be merged into the last one\n // Eno of run check and combine\n if (current && !checkAndCombine(current, colliders)) {\n // else new collider if no combination\n colliders.push(current);\n }\n current = null;\n }\n for (const c of colliders) {\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n this.collider.update();\n // Notify that colliders have been updated\n this.collider.$colliderAdded.notifyAll(this._composite);\n }\n /**\n * Returns the [[Tile]] by index (row major order)\n */\n getTileByIndex(index) {\n return this.tiles[index];\n }\n /**\n * Returns the [[Tile]] by its x and y integer coordinates\n *\n * For example, if I want the tile in fifth column (x), and second row (y):\n * `getTile(4, 1)` 0 based, so 0 is the first in row/column\n */\n getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\n return null;\n }\n return this.tiles[x + y * this.columns];\n }\n /**\n * Returns the [[Tile]] by testing a point in world coordinates,\n * returns `null` if no Tile was found.\n */\n getTileByPoint(point) {\n const { x, y } = this._getTileCoordinates(point);\n const tile = this.getTile(x, y);\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) {\n return tile;\n }\n return null;\n }\n _getTileCoordinates(point) {\n // Convert to Tile Space point\n point = this.transform.applyInverse(point);\n const x = Math.floor(point.x / this.tileWidth);\n const y = Math.floor(point.y / this.tileHeight);\n return { x, y };\n }\n getRows() {\n return this._rows;\n }\n getColumns() {\n return this._cols;\n }\n /**\n * Returns the on screen tiles for a tilemap, this will overshoot by a small amount because of the internal quad tree data structure.\n *\n * Useful if you need to perform specific logic on onscreen tiles\n */\n getOnScreenTiles() {\n let worldBounds = this._engine.screen.getWorldBounds();\n const maybeParallax = this.get(ParallaxComponent);\n if (maybeParallax && this.isInitialized) {\n let pos = this.pos;\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\n pos = pos.sub(parallaxOffset);\n // adjust world bounds by parallax factor\n worldBounds = worldBounds.translate(pos);\n }\n const bounds = this.transform.coordPlane === CoordPlane.Screen ?\n this._engine.screen.getScreenBounds() :\n worldBounds;\n const topLeft = this._getTileCoordinates(bounds.topLeft);\n const topRight = this._getTileCoordinates(bounds.topRight);\n const bottomRight = this._getTileCoordinates(bounds.bottomRight);\n const bottomLeft = this._getTileCoordinates(bounds.bottomLeft);\n const tileStartX = Math.min(clamp(topLeft.x, 0, this.columns - 1), clamp(topRight.x, 0, this.columns - 1));\n const tileStartY = Math.min(clamp(topLeft.y, 0, this.rows - 1), clamp(topRight.y, 0, this.rows - 1));\n const tileEndX = Math.max(clamp(bottomRight.x, 0, this.columns - 1), clamp(bottomLeft.x, 0, this.columns - 1));\n const tileEndY = Math.max(clamp(bottomRight.y, 0, this.rows - 1), clamp(bottomLeft.y, 0, this.rows - 1));\n const tiles = [];\n for (let x = tileStartX; x <= tileEndX; x++) {\n for (let y = tileStartY; y <= tileEndY; y++) {\n tiles.push(this.getTile(x, y));\n }\n }\n return tiles;\n }\n update(engine, delta) {\n this._initialize(engine);\n this.onPreUpdate(engine, delta);\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n if (!this._oldPos.equals(this.pos) ||\n this._oldRotation !== this.rotation ||\n !this._oldScale.equals(this.scale)) {\n this.flagCollidersDirty();\n this.flagTilesDirty();\n }\n if (this._collidersDirty) {\n this._collidersDirty = false;\n this._updateColliders();\n }\n this._token++;\n this.pos.clone(this._oldPos);\n this._oldRotation = this.rotation;\n this.scale.clone(this._oldScale);\n this.transform.pos = this.pos;\n this.onPostUpdate(engine, delta);\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n }\n /**\n * Draws the tile map to the screen. Called by the [[Scene]].\n * @param ctx ExcaliburGraphicsContext\n * @param delta The number of milliseconds since the last draw\n */\n draw(ctx, delta) {\n if (!this.isInitialized) {\n return;\n }\n this.emit('predraw', new PreDrawEvent(ctx, delta, this)); // TODO fix event\n let graphics, graphicsIndex, graphicsLen;\n const tiles = this.getOnScreenTiles();\n for (let i = 0; i < tiles.length; i++) {\n const tile = tiles[i];\n // get non-negative tile sprites\n const offsets = tile.getGraphicsOffsets();\n graphics = tile.getGraphics();\n for (graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++) {\n // draw sprite, warning if sprite doesn't exist\n const graphic = graphics[graphicsIndex];\n const offset = offsets[graphicsIndex];\n if (graphic) {\n if (hasGraphicsTick(graphic)) {\n graphic === null || graphic === void 0 ? void 0 : graphic.tick(delta, this._token);\n }\n const offsetY = this.renderFromTopOfGraphic ? 0 : (graphic.height - this.tileHeight);\n graphic.draw(ctx, tile.x * this.tileWidth + offset.x, tile.y * this.tileHeight - offsetY + offset.y);\n }\n }\n }\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\n }\n debug(gfx, debugFlags) {\n const { showAll, showGrid, gridColor, gridWidth, showSolidBounds: showColliderBounds, solidBoundsColor: colliderBoundsColor, showColliderGeometry } = debugFlags.tilemap;\n const { geometryColor, geometryLineWidth, geometryPointSize } = debugFlags.collider;\n const width = this.tileWidth * this.columns * this.scale.x;\n const height = this.tileHeight * this.rows * this.scale.y;\n const pos = this.pos;\n if (showGrid || showAll) {\n for (let r = 0; r < this.rows + 1; r++) {\n const yOffset = vec(0, r * this.tileHeight * this.scale.y);\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), gridColor, gridWidth);\n }\n for (let c = 0; c < this.columns + 1; c++) {\n const xOffset = vec(c * this.tileWidth * this.scale.x, 0);\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), gridColor, gridWidth);\n }\n }\n if (showAll || showColliderBounds || showColliderGeometry) {\n const colliders = this._composite.getColliders();\n gfx.save();\n gfx.translate(this.pos.x, this.pos.y);\n gfx.scale(this.scale.x, this.scale.y);\n for (const collider of colliders) {\n const bounds = collider.localBounds;\n const pos = collider.worldPos.sub(this.pos);\n if (showColliderBounds) {\n gfx.drawRectangle(pos, bounds.width, bounds.height, colliderBoundsColor);\n }\n }\n gfx.restore();\n if (showColliderGeometry) {\n for (const collider of colliders) {\n collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize });\n }\n }\n }\n if (showAll || showColliderBounds) {\n gfx.save();\n gfx.z = 999;\n if (showColliderBounds) {\n for (let i = 0; i < this.tiles.length; i++) {\n this.tiles[i].bounds.draw(gfx);\n }\n }\n gfx.restore();\n }\n }\n}\n/**\n * TileMap Tile\n *\n * A light-weight object that occupies a space in a collision map. Generally\n * created by a [[TileMap]].\n *\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\n * of the sprites in the array so the last one will be drawn on top. You can\n * use transparency to create layers this way.\n */\nclass Tile extends Entity {\n /**\n * Return the world position of the top left corner of the tile\n */\n get pos() {\n if (this._posDirty) {\n this._recalculate();\n this._posDirty = false;\n }\n return this._pos;\n }\n /**\n * Width of the tile in pixels\n */\n get width() {\n return this._width;\n }\n /**\n * Height of the tile in pixels\n */\n get height() {\n return this._height;\n }\n /**\n * Wether this tile should be treated as solid by the tilemap\n */\n get solid() {\n return this._solid;\n }\n /**\n * Wether this tile should be treated as solid by the tilemap\n */\n set solid(val) {\n var _a;\n (_a = this.map) === null || _a === void 0 ? void 0 : _a.flagCollidersDirty();\n this._solid = val;\n }\n /**\n * Current list of graphics for this tile\n */\n getGraphics() {\n return this._graphics;\n }\n /**\n * Current list of offsets for this tile's graphics\n */\n getGraphicsOffsets() {\n return this._offsets;\n }\n /**\n * Add another [[Graphic]] to this TileMap tile\n * @param graphic\n */\n addGraphic(graphic, options) {\n this._graphics.push(graphic);\n if (options === null || options === void 0 ? void 0 : options.offset) {\n this._offsets.push(options.offset);\n }\n else {\n this._offsets.push(Vector.Zero);\n }\n }\n /**\n * Remove an instance of a [[Graphic]] from this tile\n */\n removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) {\n this._graphics.splice(index, 1);\n this._offsets.splice(index, 1);\n }\n }\n /**\n * Clear all graphics from this tile\n */\n clearGraphics() {\n this._graphics.length = 0;\n this._offsets.length = 0;\n }\n /**\n * Returns the list of colliders\n */\n getColliders() {\n return this._colliders;\n }\n /**\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\n *\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\n *\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\n * @param collider\n */\n addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\n * Removes a collider from the [[Tile]]\n * @param collider\n */\n removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) {\n this._colliders.splice(index, 1);\n }\n this.map.flagCollidersDirty();\n }\n /**\n * Clears all colliders from the [[Tile]]\n */\n clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n constructor(options) {\n var _a, _b;\n super();\n this._posDirty = false;\n this._solid = false;\n this._graphics = [];\n this._offsets = [];\n /**\n * Current list of colliders for this tile\n */\n this._colliders = [];\n /**\n * Arbitrary data storage per tile, useful for any game specific data\n */\n this.data = new Map();\n this.x = options.x;\n this.y = options.y;\n this.map = options.map;\n this._width = options.map.tileWidth * this.map.scale.x;\n this._height = options.map.tileHeight * this.map.scale.y;\n this.solid = (_a = options.solid) !== null && _a !== void 0 ? _a : this.solid;\n this._graphics = (_b = options.graphics) !== null && _b !== void 0 ? _b : [];\n this._recalculate();\n }\n flagDirty() {\n return this._posDirty = true;\n }\n _recalculate() {\n const geometryPos = this.map.pos.add(vec(this.x * this.map.tileWidth, this.y * this.map.tileHeight));\n this._geometry = new BoundingBox(geometryPos.x, geometryPos.y, geometryPos.x + this.map.tileWidth, geometryPos.y + this.map.tileHeight);\n this._width = this.map.tileWidth * this.map.scale.x;\n this._height = this.map.tileHeight * this.map.scale.y;\n this._pos = this.map.pos.add(vec(this.x * this._width, this.y * this._height));\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\n if (this.map.rotation) {\n this._bounds = this._bounds.rotate(this.map.rotation, this.map.pos);\n }\n this._posDirty = false;\n }\n /**\n * Tile bounds in world space\n */\n get bounds() {\n if (this._posDirty) {\n this._recalculate();\n }\n return this._bounds;\n }\n get defaultGeometry() {\n return this._geometry;\n }\n /**\n * Tile position in world space\n */\n get center() {\n if (this._posDirty) {\n this._recalculate();\n }\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\n }\n}\n\n;// CONCATENATED MODULE: ./Camera.ts\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Container to house convenience strategy methods\n * @internal\n */\nclass StrategyContainer {\n constructor(camera) {\n this.camera = camera;\n }\n /**\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\n * @param actor The actor to lock the camera to\n */\n lockToActor(actor) {\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\n }\n /**\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\n * @param actor The actor to lock the camera to\n * @param axis The axis to follow the actor on\n */\n lockToActorAxis(actor, axis) {\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\n }\n /**\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\n * correct and bounce around the target\n * @param actor Target actor to elastically follow\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\n */\n elasticToActor(actor, cameraElasticity, cameraFriction) {\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\n }\n /**\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\n * @param actor Target actor to follow when it is \"radius\" pixels away\n * @param radius Number of pixels away before the camera will follow\n */\n radiusAroundActor(actor, radius) {\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\n }\n /**\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\n * @param box The bounding box to limit the camera to.\n */\n limitCameraBounds(box) {\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\n }\n}\n/**\n * Camera axis enum\n */\nvar Axis;\n(function (Axis) {\n Axis[Axis[\"X\"] = 0] = \"X\";\n Axis[Axis[\"Y\"] = 1] = \"Y\";\n})(Axis || (Axis = {}));\n/**\n * Lock a camera to the exact x/y position of an actor.\n */\nclass LockCameraToActorStrategy {\n constructor(target) {\n this.target = target;\n this.action = (target, camera, engine, delta) => {\n const center = target.center;\n return center;\n };\n }\n}\n/**\n * Lock a camera to a specific axis around an actor.\n */\nclass LockCameraToActorAxisStrategy {\n constructor(target, axis) {\n this.target = target;\n this.axis = axis;\n this.action = (target, cam, _eng, _delta) => {\n const center = target.center;\n const currentFocus = cam.getFocus();\n if (this.axis === Axis.X) {\n return new Vector(center.x, currentFocus.y);\n }\n else {\n return new Vector(currentFocus.x, center.y);\n }\n };\n }\n}\n/**\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\n */\nclass ElasticToActorStrategy {\n /**\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\n * correct and bounce around the target\n * @param target Target actor to elastically follow\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\n */\n constructor(target, cameraElasticity, cameraFriction) {\n this.target = target;\n this.cameraElasticity = cameraElasticity;\n this.cameraFriction = cameraFriction;\n this.action = (target, cam, _eng, _delta) => {\n const position = target.center;\n let focus = cam.getFocus();\n let cameraVel = cam.vel.clone();\n // Calculate the stretch vector, using the spring equation\n // F = kX\n // https://en.wikipedia.org/wiki/Hooke's_law\n // Apply to the current camera velocity\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\n cameraVel = cameraVel.add(stretch);\n // Calculate the friction (-1 to apply a force in the opposition of motion)\n // Apply to the current camera velocity\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\n cameraVel = cameraVel.add(friction);\n // Update position by velocity deltas\n focus = focus.add(cameraVel);\n return focus;\n };\n }\n}\nclass RadiusAroundActorStrategy {\n /**\n *\n * @param target Target actor to follow when it is \"radius\" pixels away\n * @param radius Number of pixels away before the camera will follow\n */\n constructor(target, radius) {\n this.target = target;\n this.radius = radius;\n this.action = (target, cam, _eng, _delta) => {\n const position = target.center;\n const focus = cam.getFocus();\n const direction = position.sub(focus);\n const distance = direction.size;\n if (distance >= this.radius) {\n const offset = distance - this.radius;\n return focus.add(direction.normalize().scale(offset));\n }\n return focus;\n };\n }\n}\n/**\n * Prevent a camera from going beyond the given camera dimensions.\n */\nclass LimitCameraBoundsStrategy {\n constructor(target) {\n this.target = target;\n /**\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\n *\n * Note that this strategy does not perform any movement by itself.\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\n *\n * Make sure that the camera bounds are at least as large as the viewport size.\n * @param target The bounding box to limit the camera to\n */\n this.boundSizeChecked = false; // Check and warn only once\n this.action = (target, cam, _eng, _delta) => {\n const focus = cam.getFocus();\n if (!this.boundSizeChecked) {\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) {\n Logger.getInstance().warn('Camera bounds should not be smaller than the engine viewport');\n }\n this.boundSizeChecked = true;\n }\n let focusX = focus.x;\n let focusY = focus.y;\n if (focus.x < target.left + _eng.halfDrawWidth) {\n focusX = target.left + _eng.halfDrawWidth;\n }\n else if (focus.x > target.right - _eng.halfDrawWidth) {\n focusX = target.right - _eng.halfDrawWidth;\n }\n if (focus.y < target.top + _eng.halfDrawHeight) {\n focusY = target.top + _eng.halfDrawHeight;\n }\n else if (focus.y > target.bottom - _eng.halfDrawHeight) {\n focusY = target.bottom - _eng.halfDrawHeight;\n }\n return vec(focusX, focusY);\n };\n }\n}\nconst CameraEvents = {\n Initialize: 'initialize',\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate'\n};\n/**\n * Cameras\n *\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\n * to move around your game and set focus. They are used to determine\n * what is \"off screen\" and can be used to scale the game.\n *\n */\nclass Camera {\n constructor() {\n this.events = new EventEmitter();\n this.transform = AffineMatrix.identity();\n this.inverse = AffineMatrix.identity();\n this._cameraStrategies = [];\n this.strategy = new StrategyContainer(this);\n /**\n * Get or set current zoom of the camera, defaults to 1\n */\n this._z = 1;\n /**\n * Get or set rate of change in zoom, defaults to 0\n */\n this.dz = 0;\n /**\n * Get or set zoom acceleration\n */\n this.az = 0;\n /**\n * Current rotation of the camera\n */\n this.rotation = 0;\n this._angularVelocity = 0;\n /**\n * Get or set the camera's position\n */\n this._posChanged = false;\n this._pos = watchAny(Vector.Zero, () => (this._posChanged = true));\n /**\n * Interpolated camera position if more draws are running than updates\n *\n * Enabled when `Engine.fixedUpdateFps` is enabled, in all other cases this will be the same as pos\n */\n this.drawPos = this.pos.clone();\n this._oldPos = this.pos.clone();\n /**\n * Get or set the camera's velocity\n */\n this.vel = Vector.Zero;\n /**\n * Get or set the camera's acceleration\n */\n this.acc = Vector.Zero;\n this._cameraMoving = false;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = null;\n this._lerpEnd = null;\n //camera effects\n this._isShaking = false;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._elapsedShakeTime = 0;\n this._xShake = 0;\n this._yShake = 0;\n this._isZooming = false;\n this._zoomStart = 1;\n this._zoomEnd = 1;\n this._currentZoomTime = 0;\n this._zoomDuration = 0;\n this._zoomEasing = EasingFunctions.EaseInOutCubic;\n this._easing = EasingFunctions.EaseInOutCubic;\n this._halfWidth = 0;\n this._halfHeight = 0;\n this._viewport = null;\n this._isInitialized = false;\n this._snapPos = vec(0, 0);\n }\n get zoom() {\n return this._z;\n }\n set zoom(val) {\n this._z = val;\n if (this._engine) {\n this._halfWidth = this._engine.halfDrawWidth;\n this._halfHeight = this._engine.halfDrawHeight;\n }\n }\n /**\n * Get or set the camera's angular velocity\n */\n get angularVelocity() {\n return this._angularVelocity;\n }\n set angularVelocity(value) {\n this._angularVelocity = value;\n }\n get pos() {\n return this._pos;\n }\n set pos(vec) {\n this._pos = watchAny(vec, () => (this._posChanged = true));\n this._posChanged = true;\n }\n /**\n * Get the camera's x position\n */\n get x() {\n return this.pos.x;\n }\n /**\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\n */\n set x(value) {\n if (!this._follow && !this._cameraMoving) {\n this.pos = vec(value, this.pos.y);\n }\n }\n /**\n * Get the camera's y position\n */\n get y() {\n return this.pos.y;\n }\n /**\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\n */\n set y(value) {\n if (!this._follow && !this._cameraMoving) {\n this.pos = vec(this.pos.x, value);\n }\n }\n /**\n * Get or set the camera's x velocity\n */\n get dx() {\n return this.vel.x;\n }\n set dx(value) {\n this.vel = vec(value, this.vel.y);\n }\n /**\n * Get or set the camera's y velocity\n */\n get dy() {\n return this.vel.y;\n }\n set dy(value) {\n this.vel = vec(this.vel.x, value);\n }\n /**\n * Get or set the camera's x acceleration\n */\n get ax() {\n return this.acc.x;\n }\n set ax(value) {\n this.acc = vec(value, this.acc.y);\n }\n /**\n * Get or set the camera's y acceleration\n */\n get ay() {\n return this.acc.y;\n }\n set ay(value) {\n this.acc = vec(this.acc.x, value);\n }\n /**\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\n */\n getFocus() {\n return this.pos;\n }\n /**\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\n * @param pos The target position to move to\n * @param duration The duration in milliseconds the move should last\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\n */\n move(pos, duration, easingFn = EasingFunctions.EaseInOutCubic) {\n if (typeof easingFn !== 'function') {\n throw 'Please specify an EasingFunction';\n }\n // cannot move when following an actor\n if (this._follow) {\n return Promise.reject(pos);\n }\n // resolve existing promise, if any\n if (this._lerpPromise && this._lerpResolve) {\n this._lerpResolve(pos);\n }\n this._lerpPromise = new Promise((resolve) => {\n this._lerpResolve = resolve;\n });\n this._lerpStart = this.getFocus().clone();\n this._lerpDuration = duration;\n this._lerpEnd = pos;\n this._currentLerpTime = 0;\n this._cameraMoving = true;\n this._easing = easingFn;\n return this._lerpPromise;\n }\n /**\n * Sets the camera to shake at the specified magnitudes for the specified duration\n * @param magnitudeX The x magnitude of the shake\n * @param magnitudeY The y magnitude of the shake\n * @param duration The duration of the shake in milliseconds\n */\n shake(magnitudeX, magnitudeY, duration) {\n this._isShaking = true;\n this._shakeMagnitudeX = magnitudeX;\n this._shakeMagnitudeY = magnitudeY;\n this._shakeDuration = duration;\n }\n /**\n * Zooms the camera in or out by the specified scale over the specified duration.\n * If no duration is specified, it take effect immediately.\n * @param scale The scale of the zoom\n * @param duration The duration of the zoom in milliseconds\n */\n zoomOverTime(scale, duration = 0, easingFn = EasingFunctions.EaseInOutCubic) {\n this._zoomPromise = new Promise((resolve) => {\n this._zoomResolve = resolve;\n });\n if (duration) {\n this._isZooming = true;\n this._zoomEasing = easingFn;\n this._currentZoomTime = 0;\n this._zoomDuration = duration;\n this._zoomStart = this.zoom;\n this._zoomEnd = scale;\n }\n else {\n this._isZooming = false;\n this.zoom = scale;\n return Promise.resolve(true);\n }\n return this._zoomPromise;\n }\n /**\n * Gets the bounding box of the viewport of this camera in world coordinates\n */\n get viewport() {\n if (this._viewport) {\n return this._viewport;\n }\n return new BoundingBox(0, 0, 0, 0);\n }\n /**\n * Adds a new camera strategy to this camera\n * @param cameraStrategy Instance of an [[CameraStrategy]]\n */\n addStrategy(cameraStrategy) {\n this._cameraStrategies.push(cameraStrategy);\n }\n /**\n * Removes a camera strategy by reference\n * @param cameraStrategy Instance of an [[CameraStrategy]]\n */\n removeStrategy(cameraStrategy) {\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\n }\n /**\n * Clears all camera strategies from the camera\n */\n clearAllStrategies() {\n this._cameraStrategies.length = 0;\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */\n _preupdate(engine, delta) {\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before a scene is updated.\n */\n onPreUpdate(engine, delta) {\n // Overridable\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */\n _postupdate(engine, delta) {\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */\n onPostUpdate(engine, delta) {\n // Overridable\n }\n get isInitialized() {\n return this._isInitialized;\n }\n _initialize(engine) {\n if (!this.isInitialized) {\n this._engine = engine;\n this._screen = engine.screen;\n const currentRes = this._screen.contentArea;\n let center = vec(currentRes.width / 2, currentRes.height / 2);\n if (!this._engine.loadingComplete) {\n // If there was a loading screen, we peek the configured resolution\n const res = this._screen.peekResolution();\n if (res) {\n center = vec(res.width / 2, res.height / 2);\n }\n }\n this._halfWidth = center.x;\n this._halfHeight = center.y;\n // If the user has not set the camera pos, apply default center screen position\n if (!this._posChanged) {\n this.pos = center;\n }\n this.pos.clone(this.drawPos);\n // First frame bootstrap\n // Ensure camera tx is correct\n // Run update twice to ensure properties are init'd\n this.updateTransform(this.pos);\n // Run strategies for first frame\n this.runStrategies(engine, engine.clock.elapsed());\n // Setup the first frame viewport\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform(this.pos);\n this.pos.clone(this._oldPos);\n this.onInitialize(engine);\n this.events.emit('initialize', new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */\n onInitialize(engine) {\n // Overridable\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n runStrategies(engine, delta) {\n for (const s of this._cameraStrategies) {\n this.pos = s.action.call(s, s.target, this, engine, delta);\n }\n }\n updateViewport() {\n // recalculate viewport\n this._viewport = new BoundingBox(this.x - this._halfWidth, this.y - this._halfHeight, this.x + this._halfWidth, this.y + this._halfHeight);\n }\n update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this.pos.clone(this._oldPos);\n // Update placements based on linear algebra\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\n this.zoom += (this.dz * delta) / 1000;\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\n this.dz += (this.az * delta) / 1000;\n this.rotation += (this.angularVelocity * delta) / 1000;\n if (this._isZooming) {\n if (this._currentZoomTime < this._zoomDuration) {\n const zoomEasing = this._zoomEasing;\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\n this.zoom = newZoom;\n this._currentZoomTime += delta;\n }\n else {\n this._isZooming = false;\n this.zoom = this._zoomEnd;\n this._currentZoomTime = 0;\n this._zoomResolve(true);\n }\n }\n if (this._cameraMoving) {\n if (this._currentLerpTime < this._lerpDuration) {\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\n this.pos = lerpPoint;\n this._currentLerpTime += delta;\n }\n else {\n this.pos = this._lerpEnd;\n const end = this._lerpEnd.clone();\n this._lerpStart = null;\n this._lerpEnd = null;\n this._currentLerpTime = 0;\n this._cameraMoving = false;\n // Order matters here, resolve should be last so any chain promises have a clean slate\n this._lerpResolve(end);\n }\n }\n if (this._isDoneShaking()) {\n this._isShaking = false;\n this._elapsedShakeTime = 0;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._xShake = 0;\n this._yShake = 0;\n }\n else {\n this._elapsedShakeTime += delta;\n this._xShake = ((Math.random() * this._shakeMagnitudeX) | 0) + 1;\n this._yShake = ((Math.random() * this._shakeMagnitudeY) | 0) + 1;\n }\n this.runStrategies(engine, delta);\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform(this.pos);\n this._postupdate(engine, delta);\n }\n /**\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\n * @param ctx Canvas context to apply transformations\n */\n draw(ctx) {\n // default to the current position\n this.pos.clone(this.drawPos);\n // interpolation if fixed update is on\n // must happen on the draw, because more draws are potentially happening than updates\n if (this._engine.fixedUpdateFps) {\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n const interpolatedPos = this.pos.scale(blend).add(this._oldPos.scale(1.0 - blend));\n interpolatedPos.clone(this.drawPos);\n this.updateTransform(interpolatedPos);\n }\n // Snap camera to pixel\n if (ctx.snapToPixel) {\n const snapPos = this.drawPos.clone(this._snapPos);\n snapPos.x = ~~(snapPos.x + pixelSnapEpsilon * sign(snapPos.x));\n snapPos.y = ~~(snapPos.y + pixelSnapEpsilon * sign(snapPos.y));\n snapPos.clone(this.drawPos);\n this.updateTransform(snapPos);\n }\n ctx.multiply(this.transform);\n }\n updateTransform(pos) {\n // center the camera\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\n const cameraPos = vec(-pos.x + newCanvasWidth / 2 + this._xShake, -pos.y + newCanvasHeight / 2 + this._yShake);\n // Calculate camera transform\n this.transform.reset();\n this.transform.scale(this.zoom, this.zoom);\n // rotate about the focus\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\n this.transform.rotate(this.rotation);\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\n this.transform.translate(cameraPos.x, cameraPos.y);\n this.transform.inverse(this.inverse);\n }\n _isDoneShaking() {\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\n }\n}\n\n;// CONCATENATED MODULE: ./Trigger.ts\n\n\n\n\n\nconst TriggerEvents = {\n ExitTrigger: 'exit',\n EnterTrigger: 'enter'\n};\nconst triggerDefaults = {\n pos: Vector.Zero,\n width: 10,\n height: 10,\n visible: false,\n action: () => {\n return;\n },\n filter: () => true,\n repeat: -1\n};\n/**\n * Triggers are a method of firing arbitrary code on collision. These are useful\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\n */\nclass Trigger extends Actor {\n /**\n *\n * @param opts Trigger options\n */\n constructor(opts) {\n super({ x: opts.pos.x, y: opts.pos.y, width: opts.width, height: opts.height });\n this.events = new EventEmitter();\n /**\n * Action to fire when triggered by collision\n */\n this.action = () => {\n return;\n };\n /**\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\n * filter return true for the collided actor.\n */\n this.filter = () => true;\n /**\n * Number of times to repeat before killing the trigger,\n */\n this.repeat = -1;\n opts = {\n ...triggerDefaults,\n ...opts\n };\n this.filter = opts.filter || this.filter;\n this.repeat = opts.repeat || this.repeat;\n this.action = opts.action || this.action;\n if (opts.target) {\n this.target = opts.target;\n }\n this.graphics.visible = opts.visible;\n this.body.collisionType = CollisionType.Passive;\n this.events.on('collisionstart', (evt) => {\n if (this.filter(evt.other)) {\n this.events.emit('enter', new EnterTriggerEvent(this, evt.other));\n this._dispatchAction();\n // remove trigger if its done, -1 repeat forever\n if (this.repeat === 0) {\n this.kill();\n }\n }\n });\n this.events.on('collisionend', (evt) => {\n if (this.filter(evt.other)) {\n this.events.emit('exit', new ExitTriggerEvent(this, evt.other));\n }\n });\n }\n set target(target) {\n this._target = target;\n this.filter = (actor) => actor === target;\n }\n get target() {\n return this._target;\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n _dispatchAction() {\n if (this.repeat !== 0) {\n this.action.call(this);\n this.repeat--;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Priority.ts\n/**\n * Higher priorities run earlier than others in the system update\n */\nconst SystemPriority = {\n Highest: -Infinity,\n Higher: -5,\n Average: 0,\n Lower: 5,\n Lowest: Infinity\n};\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/System.ts\n\n/**\n * Enum that determines whether to run the system in the update or draw phase\n */\nvar SystemType;\n(function (SystemType) {\n SystemType[\"Update\"] = \"update\";\n SystemType[\"Draw\"] = \"draw\";\n})(SystemType || (SystemType = {}));\n/**\n * An Excalibur [[System]] that updates entities of certain types.\n * Systems are scene specific\n *\n *\n *\n * Excalibur Systems currently require at least 1 Component type to operated\n *\n * Multiple types are declared as a type union\n * For example:\n *\n * ```typescript\n * class MySystem extends System {\n * public readonly types = ['a', 'b'] as const;\n * public readonly systemType = SystemType.Update;\n * public update(entities: Entity) {\n * ...\n * }\n * }\n * ```\n */\nclass System {\n constructor() {\n /**\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\n * For a system to execute after all other a higher priority value (10 for example) must be set.\n */\n this.priority = SystemPriority.Average;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/EntityManager.ts\n\n\n// Add/Remove entities and components\nclass EntityManager {\n constructor(_world) {\n this._world = _world;\n this.entities = [];\n this._entityIndex = {};\n this._entitiesToRemove = [];\n }\n /**\n * Runs the entity lifecycle\n * @param scene\n * @param elapsed\n */\n updateEntities(scene, elapsed) {\n for (const entity of this.entities) {\n entity.update(scene.engine, elapsed);\n if (!entity.active) {\n this.removeEntity(entity);\n }\n }\n }\n findEntitiesForRemoval() {\n for (const entity of this.entities) {\n if (!entity.active) {\n this.removeEntity(entity);\n }\n }\n }\n /**\n * Adds an entity to be tracked by the EntityManager\n * @param entity\n */\n addEntity(entity) {\n entity.active = true;\n entity.scene = this._world.scene;\n if (entity && !this._entityIndex[entity.id]) {\n this._entityIndex[entity.id] = entity;\n this.entities.push(entity);\n this._world.queryManager.addEntity(entity);\n // if entity has children\n entity.children.forEach((c) => {\n c.scene = entity.scene;\n this.addEntity(c);\n });\n entity.childrenAdded$.register({\n notify: (e) => {\n this.addEntity(e);\n }\n });\n entity.childrenRemoved$.register({\n notify: (e) => {\n this.removeEntity(e, false);\n }\n });\n }\n }\n removeEntity(idOrEntity, deferred = true) {\n var _a, _b;\n let id = 0;\n if (idOrEntity instanceof Entity) {\n id = idOrEntity.id;\n }\n else {\n id = idOrEntity;\n }\n const entity = this._entityIndex[id];\n if (entity && entity.active) {\n entity.active = false;\n }\n if (entity && deferred) {\n this._entitiesToRemove.push(entity);\n return;\n }\n delete this._entityIndex[id];\n if (entity) {\n entity.scene = null;\n removeItemFromArray(entity, this.entities);\n this._world.queryManager.removeEntity(entity);\n // if entity has children\n entity.children.forEach((c) => {\n c.scene = null;\n this.removeEntity(c, deferred);\n });\n entity.childrenAdded$.clear();\n entity.childrenRemoved$.clear();\n // stats\n if ((_b = (_a = this._world) === null || _a === void 0 ? void 0 : _a.scene) === null || _b === void 0 ? void 0 : _b.engine) {\n this._world.scene.engine.stats.currFrame.actors.killed++;\n }\n }\n }\n processEntityRemovals() {\n for (const entity of this._entitiesToRemove) {\n if (entity.active) {\n continue;\n }\n this.removeEntity(entity, false);\n }\n this._entitiesToRemove.length = 0;\n }\n processComponentRemovals() {\n for (const entity of this.entities) {\n entity.processComponentRemoval();\n }\n }\n getById(id) {\n return this._entityIndex[id];\n }\n getByName(name) {\n return this.entities.filter(e => e.name === name);\n }\n clear() {\n for (let i = this.entities.length - 1; i >= 0; i--) {\n this.removeEntity(this.entities[i]);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Query.ts\n\n/**\n * Represents query for entities that match a list of types that is cached and observable\n *\n * Queries can be strongly typed by supplying a type union in the optional type parameter\n * ```typescript\n * const queryAB = new ex.Query(['A', 'B']);\n * ```\n */\nclass Query {\n constructor(requiredComponents) {\n this.requiredComponents = requiredComponents;\n this.components = new Set();\n this.entities = [];\n /**\n * This fires right after the component is added\n */\n this.entityAdded$ = new Observable();\n /**\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\n */\n this.entityRemoved$ = new Observable();\n if (requiredComponents.length === 0) {\n throw new Error('Cannot create query without components');\n }\n for (const type of requiredComponents) {\n this.components.add(type);\n }\n this.id = Query.createId(requiredComponents);\n }\n static createId(requiredComponents) {\n // TODO what happens if a user defines the same type name as a built in type\n // ! TODO this could be dangerous depending on the bundler's settings for names\n // Maybe some kind of hash function is better here?\n return requiredComponents.slice().map(c => c.name).sort().join('-');\n }\n /**\n * Potentially adds an entity to a query index, returns true if added, false if not\n * @param entity\n */\n checkAndAdd(entity) {\n if (!this.entities.includes(entity) && entity.hasAll(Array.from(this.components))) {\n this.entities.push(entity);\n this.entityAdded$.notifyAll(entity);\n return true;\n }\n return false;\n }\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index > -1) {\n this.entities.splice(index, 1);\n this.entityRemoved$.notifyAll(entity);\n }\n }\n /**\n * Returns a list of entities that match the query\n * @param sort Optional sorting function to sort entities returned from the query\n */\n getEntities(sort) {\n if (sort) {\n this.entities.sort(sort);\n }\n return this.entities;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/TagQuery.ts\n\nclass TagQuery {\n constructor(requiredTags) {\n this.requiredTags = requiredTags;\n this.tags = new Set();\n this.entities = [];\n /**\n * This fires right after the component is added\n */\n this.entityAdded$ = new Observable();\n /**\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\n */\n this.entityRemoved$ = new Observable();\n if (requiredTags.length === 0) {\n throw new Error('Cannot create tag query without tags');\n }\n for (const tag of requiredTags) {\n this.tags.add(tag);\n }\n this.id = TagQuery.createId(requiredTags);\n }\n static createId(requiredComponents) {\n return requiredComponents.slice().sort().join('-');\n }\n checkAndAdd(entity) {\n if (!this.entities.includes(entity) && entity.hasAllTags(Array.from(this.tags))) {\n this.entities.push(entity);\n this.entityAdded$.notifyAll(entity);\n return true;\n }\n return false;\n }\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index > -1) {\n this.entities.splice(index, 1);\n this.entityRemoved$.notifyAll(entity);\n }\n }\n /**\n * Returns a list of entities that match the query\n * @param sort Optional sorting function to sort entities returned from the query\n */\n getEntities(sort) {\n if (sort) {\n this.entities.sort(sort);\n }\n return this.entities;\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/QueryManager.ts\n\n\n/**\n * The query manager is responsible for updating all queries when entities/components change\n */\nclass QueryManager {\n constructor(_world) {\n this._world = _world;\n this._queries = new Map();\n this._addComponentHandlers = new Map();\n this._removeComponentHandlers = new Map();\n this._componentToQueriesIndex = new Map();\n this._tagQueries = new Map();\n this._addTagHandlers = new Map();\n this._removeTagHandlers = new Map();\n this._tagToQueriesIndex = new Map();\n this._createAddComponentHandler = (entity) => (c) => {\n this.addComponent(entity, c);\n };\n this._createRemoveComponentHandler = (entity) => (c) => {\n this.removeComponent(entity, c);\n };\n this._createAddTagHandler = (entity) => (tag) => {\n this.addTag(entity, tag);\n };\n this._createRemoveTagHandler = (entity) => (tag) => {\n this.removeTag(entity, tag);\n };\n }\n createQuery(requiredComponents) {\n const id = Query.createId(requiredComponents);\n if (this._queries.has(id)) {\n // short circuit if query is already created\n return this._queries.get(id);\n }\n const query = new Query(requiredComponents);\n this._queries.set(query.id, query);\n // index maintenance\n for (const component of requiredComponents) {\n const queries = this._componentToQueriesIndex.get(component);\n if (!queries) {\n this._componentToQueriesIndex.set(component, [query]);\n }\n else {\n queries.push(query);\n }\n }\n for (const entity of this._world.entities) {\n this.addEntity(entity);\n }\n return query;\n }\n createTagQuery(requiredTags) {\n const id = TagQuery.createId(requiredTags);\n if (this._tagQueries.has(id)) {\n // short circuit if query is already created\n return this._tagQueries.get(id);\n }\n const query = new TagQuery(requiredTags);\n this._tagQueries.set(query.id, query);\n // index maintenance\n for (const tag of requiredTags) {\n const queries = this._tagToQueriesIndex.get(tag);\n if (!queries) {\n this._tagToQueriesIndex.set(tag, [query]);\n }\n else {\n queries.push(query);\n }\n }\n for (const entity of this._world.entities) {\n this.addEntity(entity);\n }\n return query;\n }\n /**\n * Scans queries and locates any that need this entity added\n * @param entity\n */\n addEntity(entity) {\n const maybeAddComponent = this._addComponentHandlers.get(entity);\n const maybeRemoveComponent = this._removeComponentHandlers.get(entity);\n const addComponent = maybeAddComponent !== null && maybeAddComponent !== void 0 ? maybeAddComponent : this._createAddComponentHandler(entity);\n const removeComponent = maybeRemoveComponent !== null && maybeRemoveComponent !== void 0 ? maybeRemoveComponent : this._createRemoveComponentHandler(entity);\n this._addComponentHandlers.set(entity, addComponent);\n this._removeComponentHandlers.set(entity, removeComponent);\n const maybeAddTag = this._addTagHandlers.get(entity);\n const maybeRemoveTag = this._removeTagHandlers.get(entity);\n const addTag = maybeAddTag !== null && maybeAddTag !== void 0 ? maybeAddTag : this._createAddTagHandler(entity);\n const removeTag = maybeRemoveTag !== null && maybeRemoveTag !== void 0 ? maybeRemoveTag : this._createRemoveTagHandler(entity);\n this._addTagHandlers.set(entity, addTag);\n this._removeTagHandlers.set(entity, removeTag);\n for (const query of this._queries.values()) {\n query.checkAndAdd(entity);\n }\n for (const tagQuery of this._tagQueries.values()) {\n tagQuery.checkAndAdd(entity);\n }\n entity.componentAdded$.subscribe(addComponent);\n entity.componentRemoved$.subscribe(removeComponent);\n entity.tagAdded$.subscribe(addTag);\n entity.tagRemoved$.subscribe(removeTag);\n }\n /**\n * Scans queries and locates any that need this entity removed\n * @param entity\n */\n removeEntity(entity) {\n // Handle components\n const addComponent = this._addComponentHandlers.get(entity);\n const removeComponent = this._removeComponentHandlers.get(entity);\n for (const query of this._queries.values()) {\n query.removeEntity(entity);\n }\n if (addComponent) {\n entity.componentAdded$.unsubscribe(addComponent);\n }\n if (removeComponent) {\n entity.componentRemoved$.unsubscribe(removeComponent);\n }\n // Handle tags\n const addTag = this._addTagHandlers.get(entity);\n const removeTag = this._removeTagHandlers.get(entity);\n for (const tagQuery of this._tagQueries.values()) {\n tagQuery.removeEntity(entity);\n }\n if (addTag) {\n entity.tagAdded$.unsubscribe(addTag);\n }\n if (removeTag) {\n entity.tagRemoved$.unsubscribe(removeTag);\n }\n }\n /**\n * Updates any queries when a component is added to an entity\n * @param entity\n * @param component\n */\n addComponent(entity, component) {\n var _a;\n const queries = (_a = this._componentToQueriesIndex.get(component.constructor)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries) {\n query.checkAndAdd(entity);\n }\n }\n /**\n * Updates any queries when a component is removed from an entity\n * @param entity\n * @param component\n */\n removeComponent(entity, component) {\n var _a;\n const queries = (_a = this._componentToQueriesIndex.get(component.constructor)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries) {\n query.removeEntity(entity);\n }\n }\n /**\n * Updates any queries when a tag is added to an entity\n * @param entity\n * @param tag\n */\n addTag(entity, tag) {\n var _a;\n const queries = (_a = this._tagToQueriesIndex.get(tag)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries) {\n query.checkAndAdd(entity);\n }\n }\n /**\n * Updates any queries when a component is removed from an entity\n * @param entity\n * @param tag\n */\n removeTag(entity, tag) {\n var _a;\n const queries = (_a = this._tagToQueriesIndex.get(tag)) !== null && _a !== void 0 ? _a : [];\n for (const query of queries) {\n query.removeEntity(entity);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/SystemManager.ts\n\n\n/**\n *\n */\nfunction isSystemConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n}\n/**\n * The SystemManager is responsible for keeping track of all systems in a scene.\n * Systems are scene specific\n */\nclass SystemManager {\n constructor(_world) {\n this._world = _world;\n /**\n * List of systems, to add a new system call [[SystemManager.addSystem]]\n */\n this.systems = [];\n this.initialized = false;\n }\n /**\n * Get a system registered in the manager by type\n * @param systemType\n */\n get(systemType) {\n return this.systems.find((s) => s instanceof systemType);\n }\n /**\n * Adds a system to the manager, it will now be updated every frame\n * @param systemOrCtor\n */\n addSystem(systemOrCtor) {\n let system;\n if (systemOrCtor instanceof System) {\n system = systemOrCtor;\n }\n else {\n system = new systemOrCtor(this._world);\n }\n this.systems.push(system);\n this.systems.sort((a, b) => a.priority - b.priority);\n // If systems are added and the manager has already been init'd\n // then immediately init the system\n if (this.initialized && system.initialize) {\n system.initialize(this._world, this._world.scene);\n }\n }\n /**\n * Removes a system from the manager, it will no longer be updated\n * @param system\n */\n removeSystem(system) {\n removeItemFromArray(system, this.systems);\n }\n /**\n * Initialize all systems in the manager\n *\n * Systems added after initialize() will be initialized on add\n */\n initialize() {\n if (!this.initialized) {\n this.initialized = true;\n for (const s of this.systems) {\n if (s.initialize) {\n s.initialize(this._world, this._world.scene);\n }\n }\n }\n }\n /**\n * Updates all systems\n * @param type whether this is an update or draw system\n * @param scene context reference\n * @param delta time in milliseconds\n */\n updateSystems(type, scene, delta) {\n const systems = this.systems.filter((s) => s.systemType === type);\n for (const s of systems) {\n if (s.preupdate) {\n s.preupdate(scene, delta);\n }\n }\n for (const s of systems) {\n s.update(delta);\n }\n for (const s of systems) {\n if (s.postupdate) {\n s.postupdate(scene, delta);\n }\n }\n }\n clear() {\n for (let i = this.systems.length - 1; i >= 0; i--) {\n this.removeSystem(this.systems[i]);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/World.ts\n\n\n\n\n\n/**\n * The World is a self-contained entity component system for a particular context.\n */\nclass World {\n /**\n * The context type is passed to the system updates\n * @param scene\n */\n constructor(scene) {\n this.scene = scene;\n this.queryManager = new QueryManager(this);\n this.entityManager = new EntityManager(this);\n this.systemManager = new SystemManager(this);\n }\n /**\n * Query the ECS world for entities that match your components\n * @param requiredTypes\n */\n query(requiredTypes) {\n return this.queryManager.createQuery(requiredTypes);\n }\n queryTags(requiredTags) {\n return this.queryManager.createTagQuery(requiredTags);\n }\n /**\n * Update systems by type and time elapsed in milliseconds\n */\n update(type, delta) {\n if (type === SystemType.Update) {\n this.entityManager.updateEntities(this.scene, delta);\n }\n this.systemManager.updateSystems(type, this.scene, delta);\n this.entityManager.findEntitiesForRemoval();\n this.entityManager.processComponentRemovals();\n this.entityManager.processEntityRemovals();\n }\n add(entityOrSystem) {\n if (entityOrSystem instanceof Entity) {\n this.entityManager.addEntity(entityOrSystem);\n }\n if (entityOrSystem instanceof System || isSystemConstructor(entityOrSystem)) {\n this.systemManager.addSystem(entityOrSystem);\n }\n }\n /**\n * Get a system out of the ECS world\n */\n get(system) {\n return this.systemManager.get(system);\n }\n remove(entityOrSystem, deferred = true) {\n if (entityOrSystem instanceof Entity) {\n this.entityManager.removeEntity(entityOrSystem, deferred);\n }\n if (entityOrSystem instanceof System) {\n this.systemManager.removeSystem(entityOrSystem);\n }\n }\n get entities() {\n return this.entityManager.entities;\n }\n clearEntities() {\n this.entityManager.clear();\n }\n clearSystems() {\n this.systemManager.clear();\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Integrator.ts\n\nclass EulerIntegrator {\n static integrate(transform, motion, totalAcc, elapsedMs) {\n const seconds = elapsedMs / 1000;\n // This code looks a little wild, but it's to avoid creating any new Vector instances\n // integration is done in a tight loop so this is key to avoid GC'ing\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\n transform.pos\n .add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS)\n .addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\n const rotation = transform.rotation + motion.angularVelocity * seconds;\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\n const tx = transform.get();\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\n }\n}\n// Scratch vectors to avoid allocation\nEulerIntegrator._POS = new Vector(0, 0);\nEulerIntegrator._SCALE = new Vector(1, 1);\nEulerIntegrator._ACC = new Vector(0, 0);\nEulerIntegrator._VEL = new Vector(0, 0);\nEulerIntegrator._VEL_ACC = new Vector(0, 0);\nEulerIntegrator._SCALE_FACTOR = new Vector(0, 0);\n\n;// CONCATENATED MODULE: ./Collision/MotionSystem.ts\n\n\n\n\n\n\n\nclass MotionSystem extends System {\n constructor(world, physics) {\n super();\n this.world = world;\n this.physics = physics;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._physicsConfigDirty = false;\n physics.$configUpdate.subscribe(() => this._physicsConfigDirty = true);\n this.query = this.world.query([TransformComponent, MotionComponent]);\n }\n update(elapsedMs) {\n let transform;\n let motion;\n const entities = this.query.entities;\n for (let i = 0; i < entities.length; i++) {\n transform = entities[i].get(TransformComponent);\n motion = entities[i].get(MotionComponent);\n const optionalBody = entities[i].get(BodyComponent);\n if (this._physicsConfigDirty && optionalBody) {\n optionalBody.updatePhysicsConfig(this.physics.config.bodies);\n }\n if (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.sleeping) {\n continue;\n }\n const totalAcc = motion.acc.clone();\n if ((optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.collisionType) === CollisionType.Active && (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.useGravity)) {\n totalAcc.addEqual(this.physics.config.gravity);\n }\n optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.captureOldTransform();\n // Update transform and motion based on Euler linear algebra\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Solver/ArcadeSolver.ts\n\n\n\n\n\n/**\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\n * and negates velocity along the collision normal.\n *\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\n *\n */\nclass ArcadeSolver {\n constructor(config) {\n this.config = config;\n this.directionMap = new Map();\n this.distanceMap = new Map();\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter(c => !c.isCanceled());\n // Locate collision bias order\n let bias;\n switch (this.config.contactSolveBias) {\n case ContactSolveBias.HorizontalFirst: {\n bias = HorizontalFirst;\n break;\n }\n case ContactSolveBias.VerticalFirst: {\n bias = VerticalFirst;\n break;\n }\n default: {\n bias = None;\n }\n }\n // Sort by bias (None, VerticalFirst, HorizontalFirst) to avoid artifacts with seams\n // Sort contacts by distance to avoid artifacts with seams\n // It's important to solve in a specific order\n contacts.sort((a, b) => {\n const aDir = this.directionMap.get(a.id);\n const bDir = this.directionMap.get(b.id);\n const aDist = this.distanceMap.get(a.id);\n const bDist = this.distanceMap.get(b.id);\n return (bias[aDir] - bias[bDir]) || (aDist - bDist);\n });\n for (const contact of contacts) {\n // Solve position first in arcade\n this.solvePosition(contact);\n // Solve velocity second in arcade\n this.solveVelocity(contact);\n }\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n const epsilon = .0001;\n for (const contact of contacts) {\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\n this.distanceMap.set(contact.id, distance);\n this.directionMap.set(contact.id, side === Side.Left || side === Side.Right ? 'horizontal' : 'vertical');\n // Publish collision events on both participants\n contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\n contact.colliderB.events.emit('precollision', new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact));\n }\n }\n postSolve(contacts) {\n var _a, _b;\n for (const contact of contacts) {\n if (contact.isCanceled()) {\n continue;\n }\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n continue;\n }\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n // Publish collision events on both participants\n contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\n contact.colliderB.events.emit('postcollision', new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact));\n }\n }\n solvePosition(contact) {\n var _a, _b;\n const epsilon = .0001;\n // if bounds no longer intersect skip to the next\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\n // Cancel the contact to prevent and solving\n contact.cancel();\n return;\n }\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n return;\n }\n let mtv = contact.mtv;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n return;\n }\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) {\n // split overlaps if both are Active\n mtv = mtv.scale(0.5);\n }\n // Resolve overlaps\n if (bodyA.collisionType === CollisionType.Active) {\n bodyA.globalPos.x -= mtv.x;\n bodyA.globalPos.y -= mtv.y;\n colliderA.update(bodyA.transform.get());\n }\n if (bodyB.collisionType === CollisionType.Active) {\n bodyB.globalPos.x += mtv.x;\n bodyB.globalPos.y += mtv.y;\n colliderB.update(bodyB.transform.get());\n }\n }\n }\n solveVelocity(contact) {\n var _a, _b;\n if (contact.isCanceled()) {\n return;\n }\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n return;\n }\n const normal = contact.normal;\n const opposite = normal.negate();\n if (bodyA.collisionType === CollisionType.Active) {\n // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform when sliding off\n if (bodyA.vel.normalize().dot(opposite) < 0) {\n // Cancel out velocity opposite direction of collision normal\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\n bodyA.vel = bodyA.vel.add(velAdj);\n }\n }\n if (bodyB.collisionType === CollisionType.Active) {\n // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform\n if (bodyB.vel.normalize().dot(normal) < 0) {\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\n bodyB.vel = bodyB.vel.add(velAdj);\n }\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Solver/ContactConstraintPoint.ts\n\n\n/**\n * Holds information about contact points, meant to be reused over multiple frames of contact\n */\nclass ContactConstraintPoint {\n constructor(point, local, contact) {\n this.point = point;\n this.local = local;\n this.contact = contact;\n /**\n * Impulse accumulated over time in normal direction\n */\n this.normalImpulse = 0;\n /**\n * Impulse accumulated over time in the tangent direction\n */\n this.tangentImpulse = 0;\n /**\n * Effective mass seen in the normal direction\n */\n this.normalMass = 0;\n /**\n * Effective mass seen in the tangent direction\n */\n this.tangentMass = 0;\n /**\n * Direction from center of mass of bodyA to contact point\n */\n this.aToContact = new Vector(0, 0);\n /**\n * Direction from center of mass of bodyB to contact point\n */\n this.bToContact = new Vector(0, 0);\n /**\n * Original contact velocity combined with bounciness\n */\n this.originalVelocityAndRestitution = 0;\n this.update();\n }\n /**\n * Updates the contact information\n */\n update() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const normal = this.contact.normal;\n const tangent = this.contact.tangent;\n this.aToContact = this.point.sub(bodyA.globalPos);\n this.bToContact = this.point.sub(bodyB.globalPos);\n const aToContactNormal = this.aToContact.cross(normal);\n const bToContactNormal = this.bToContact.cross(normal);\n this.normalMass =\n bodyA.inverseMass +\n bodyB.inverseMass +\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = this.aToContact.cross(tangent);\n const bToContactTangent = this.bToContact.cross(tangent);\n this.tangentMass =\n bodyA.inverseMass +\n bodyB.inverseMass +\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n }\n return this;\n }\n /**\n * Returns the relative velocity between bodyA and bodyB\n */\n getRelativeVelocity() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Relative velocity in linear terms\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\n return velB.sub(velA);\n }\n return Vector.Zero;\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Solver/RealisticSolver.ts\n\n\n\n\n\n\n\nclass RealisticSolver {\n constructor(config) {\n this.config = config;\n this.lastFrameContacts = new Map();\n // map contact id to contact points\n this.idToContactConstraint = new Map();\n }\n getContactConstraints(id) {\n var _a;\n return (_a = this.idToContactConstraint.get(id)) !== null && _a !== void 0 ? _a : [];\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter(c => !c.isCanceled());\n // Solve velocity first\n this.solveVelocity(contacts);\n // Solve position last because non-overlap is the most important\n this.solvePosition(contacts);\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n var _a, _b, _c;\n const epsilon = .0001;\n for (const contact of contacts) {\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderA.events.emit('beforecollisionresolve', new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit('precollision', new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n contact.colliderB.events.emit('beforecollisionresolve', new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n // Match awake state for sleeping\n contact.matchAwake();\n }\n // Keep track of contacts that done\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\n for (const contact of contacts) {\n // Remove all current contacts that are not done\n const index = finishedContactIds.indexOf(contact.id);\n if (index > -1) {\n finishedContactIds.splice(index, 1);\n }\n const contactPoints = (_a = this.idToContactConstraint.get(contact.id)) !== null && _a !== void 0 ? _a : [];\n let pointIndex = 0;\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n for (const point of contact.points) {\n const normal = contact.normal;\n const tangent = contact.tangent;\n const aToContact = point.sub(bodyA.globalPos);\n const bToContact = point.sub(bodyB.globalPos);\n const aToContactNormal = aToContact.cross(normal);\n const bToContactNormal = bToContact.cross(normal);\n const normalMass = bodyA.inverseMass +\n bodyB.inverseMass +\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = aToContact.cross(tangent);\n const bToContactTangent = bToContact.cross(tangent);\n const tangentMass = bodyA.inverseMass +\n bodyB.inverseMass +\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n // Preserve normal/tangent impulse by re-using the contact point if it's close\n if (contactPoints[pointIndex] && ((_c = (_b = contactPoints[pointIndex]) === null || _b === void 0 ? void 0 : _b.point) === null || _c === void 0 ? void 0 : _c.squareDistance(point)) < 4) {\n contactPoints[pointIndex].point = point;\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\n }\n else {\n // new contact if it's not close or doesn't exist\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\n }\n // Update contact point calculations\n contactPoints[pointIndex].aToContact = aToContact;\n contactPoints[pointIndex].bToContact = bToContact;\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\n // Calculate relative velocity before solving to accurately do restitution\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\n if (relativeVelocity < -0.1) { // TODO what's a good threshold here?\n contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\n }\n pointIndex++;\n }\n }\n this.idToContactConstraint.set(contact.id, contactPoints);\n }\n // Clean up any contacts that did not occur last frame\n for (const id of finishedContactIds) {\n this.idToContactConstraint.delete(id);\n }\n // Warm contacts with accumulated impulse\n // Useful for tall stacks\n if (this.config.warmStart) {\n this.warmStart(contacts);\n }\n else {\n for (const contact of contacts) {\n const contactPoints = this.getContactConstraints(contact.id);\n for (const point of contactPoints) {\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n }\n postSolve(contacts) {\n for (const contact of contacts) {\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip post solve for active+passive collisions\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n continue;\n }\n // Update motion values for sleeping\n bodyA.updateMotion();\n bodyB.updateMotion();\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderA.events.emit('aftercollisionresolve', new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit('postcollision', new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n contact.colliderB.events.emit('aftercollisionresolve', new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n }\n // Store contacts\n this.lastFrameContacts.clear();\n for (const c of contacts) {\n this.lastFrameContacts.set(c.id, c);\n }\n }\n /**\n * Warm up body's based on previous frame contact points\n * @param contacts\n */\n warmStart(contacts) {\n var _a, _b, _c;\n for (const contact of contacts) {\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const contactPoints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of contactPoints) {\n if (this.config.warmStart) {\n const normalImpulse = contact.normal.scale(point.normalImpulse);\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\n const impulse = normalImpulse.add(tangentImpulse);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n else {\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n }\n }\n /**\n * Iteratively solve the position overlap constraint\n * @param contacts\n */\n solvePosition(contacts) {\n var _a, _b, _c;\n for (let i = 0; i < this.config.positionIterations; i++) {\n for (const contact of contacts) {\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n continue;\n }\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of constraints) {\n const normal = contact.normal;\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\n const steeringConstant = this.config.steeringFactor; //0.2;\n const maxCorrection = -5;\n const slop = this.config.slop; //1;\n // Clamp to avoid over-correction\n // Remember that we are shooting for 0 overlap in the end\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\n const impulse = normal.scale(-steeringForce * point.normalMass);\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\n // We adjust position and rotation instead of doing the velocity\n if (bodyA.collisionType === CollisionType.Active) {\n // TODO make applyPseudoImpulse function?\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\n impulseForce.x = 0;\n }\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\n impulseForce.y = 0;\n }\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\n }\n }\n if (bodyB.collisionType === CollisionType.Active) {\n const impulseForce = impulse.scale(bodyB.inverseMass);\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\n impulseForce.x = 0;\n }\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\n impulseForce.y = 0;\n }\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\n }\n }\n }\n }\n }\n }\n }\n solveVelocity(contacts) {\n var _a, _b, _c;\n for (let i = 0; i < this.config.velocityIterations; i++) {\n for (const contact of contacts) {\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\n continue;\n }\n const friction = Math.min(bodyA.friction, bodyB.friction);\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n // Friction constraint\n for (const point of constraints) {\n const relativeVelocity = point.getRelativeVelocity();\n // Negate velocity in tangent direction to simulate friction\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\n let impulseDelta = tangentVelocity * point.tangentMass;\n // Clamping based in Erin Catto's GDC 2006 talk\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\n // But deltas can vary\n const maxFriction = friction * point.normalImpulse;\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\n impulseDelta = newImpulse - point.tangentImpulse;\n point.tangentImpulse = newImpulse;\n const impulse = contact.tangent.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n // Bounce constraint\n for (const point of constraints) {\n // Need to recalc relative velocity because the previous step could have changed vel\n const relativeVelocity = point.getRelativeVelocity();\n // Compute impulse in normal direction\n const normalVelocity = relativeVelocity.dot(contact.normal);\n // Per Erin it is a mistake to apply the restitution inside the iteration\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\n // Clamping based in Erin Catto's GDC 2014 talk\n // Accumulated impulse stored in the contact is always positive (dV > 0)\n // But deltas can be negative\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\n impulseDelta = newImpulse - point.normalImpulse;\n point.normalImpulse = newImpulse;\n const impulse = contact.normal.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n }\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/CollisionSystem.ts\n\n\n\n\n\n\n\n\n\n\n\nclass CollisionSystem extends System {\n get _processor() {\n return this._physics.collisionProcessor;\n }\n ;\n constructor(world, _physics) {\n super();\n this._physics = _physics;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._configDirty = false;\n this._lastFrameContacts = new Map();\n this._currentFrameContacts = new Map();\n this._arcadeSolver = new ArcadeSolver(_physics.config.arcade);\n this._realisticSolver = new RealisticSolver(_physics.config.realistic);\n this._physics.$configUpdate.subscribe(() => this._configDirty = true);\n this._trackCollider = (c) => this._processor.track(c);\n this._untrackCollider = (c) => this._processor.untrack(c);\n this.query = world.query([TransformComponent, MotionComponent, ColliderComponent]);\n this.query.entityAdded$.subscribe(e => {\n const colliderComponent = e.get(ColliderComponent);\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\n const collider = colliderComponent.get();\n if (collider) {\n this._processor.track(collider);\n }\n });\n this.query.entityRemoved$.subscribe(e => {\n const colliderComponent = e.get(ColliderComponent);\n const collider = colliderComponent.get();\n if (colliderComponent && collider) {\n this._processor.untrack(collider);\n }\n });\n }\n initialize(world, scene) {\n this._engine = scene.engine;\n }\n update(elapsedMs) {\n var _a, _b, _c, _d;\n if (!this._physics.config.enabled) {\n return;\n }\n // Collect up all the colliders and update them\n let colliders = [];\n for (const entity of this.query.entities) {\n const colliderComp = entity.get(ColliderComponent);\n const collider = colliderComp === null || colliderComp === void 0 ? void 0 : colliderComp.get();\n if (colliderComp && ((_a = colliderComp.owner) === null || _a === void 0 ? void 0 : _a.active) && collider) {\n colliderComp.update();\n if (collider instanceof CompositeCollider) {\n const compositeColliders = collider.getColliders();\n if (!collider.compositeStrategy) {\n collider.compositeStrategy = this._physics.config.colliders.compositeStrategy;\n }\n colliders = colliders.concat(compositeColliders);\n }\n else {\n colliders.push(collider);\n }\n }\n }\n // Update the spatial partitioning data structures\n // TODO if collider invalid it will break the processor\n // TODO rename \"update\" to something more specific\n this._processor.update(colliders);\n // Run broadphase on all colliders and locates potential collisions\n const pairs = this._processor.broadphase(colliders, elapsedMs);\n this._currentFrameContacts.clear();\n // Given possible pairs find actual contacts\n let contacts = this._processor.narrowphase(pairs, (_d = (_c = (_b = this._engine) === null || _b === void 0 ? void 0 : _b.debug) === null || _c === void 0 ? void 0 : _c.stats) === null || _d === void 0 ? void 0 : _d.currFrame);\n const solver = this.getSolver();\n // Solve, this resolves the position/velocity so entities aren't overlapping\n contacts = solver.solve(contacts);\n // Record contacts for start/end\n for (const contact of contacts) {\n if (contact.isCanceled()) {\n continue;\n }\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\n const index = contact.id.indexOf('|');\n if (index > 0) {\n const compositeId = contact.id.substring(index + 1);\n this._currentFrameContacts.set(compositeId, contact);\n }\n else {\n this._currentFrameContacts.set(contact.id, contact);\n }\n }\n // Emit contact start/end events\n this.runContactStartEnd();\n // reset the last frame cache\n this._lastFrameContacts.clear();\n // Keep track of collisions contacts that have started or ended\n this._lastFrameContacts = new Map(this._currentFrameContacts);\n // Process deferred collider removals\n for (const entity of this.query.entities) {\n const collider = entity.get(ColliderComponent);\n if (collider) {\n collider.processColliderRemoval();\n }\n }\n }\n getSolver() {\n if (this._configDirty) {\n this._configDirty = false;\n this._arcadeSolver = new ArcadeSolver(this._physics.config.arcade);\n this._realisticSolver = new RealisticSolver(this._physics.config.realistic);\n }\n return this._physics.config.solver === SolverStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\n }\n debug(ex) {\n this._processor.debug(ex);\n }\n runContactStartEnd() {\n // If composite colliders are 'together' collisions may have a duplicate id because we want to treat those as a singular start/end\n for (const [id, c] of this._currentFrameContacts) {\n // find all new contacts\n if (!this._lastFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n const side = Side.fromDirection(c.mtv);\n const opposite = Side.getOpposite(side);\n colliderA.events.emit('collisionstart', new CollisionStartEvent(colliderA, colliderB, side, c));\n colliderA.events.emit('contactstart', new ContactStartEvent(colliderA, colliderB, side, c));\n colliderB.events.emit('collisionstart', new CollisionStartEvent(colliderB, colliderA, opposite, c));\n colliderB.events.emit('contactstart', new ContactStartEvent(colliderB, colliderA, opposite, c));\n }\n }\n // find all contacts that have ceased\n for (const [id, c] of this._lastFrameContacts) {\n if (!this._currentFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n const side = Side.fromDirection(c.mtv);\n const opposite = Side.getOpposite(side);\n colliderA.events.emit('collisionend', new CollisionEndEvent(colliderA, colliderB, side, c));\n colliderA.events.emit('contactend', new ContactEndEvent(colliderA, colliderB, side, c));\n colliderB.events.emit('collisionend', new CollisionEndEvent(colliderB, colliderA, opposite, c));\n colliderB.events.emit('contactend', new ContactEndEvent(colliderB, colliderA, opposite, c));\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Animation.ts\n\n\n\n\nvar AnimationDirection;\n(function (AnimationDirection) {\n /**\n * Animation is playing forwards\n */\n AnimationDirection[\"Forward\"] = \"forward\";\n /**\n * Animation is playing backwards\n */\n AnimationDirection[\"Backward\"] = \"backward\";\n})(AnimationDirection || (AnimationDirection = {}));\nvar AnimationStrategy;\n(function (AnimationStrategy) {\n /**\n * Animation ends without displaying anything\n */\n AnimationStrategy[\"End\"] = \"end\";\n /**\n * Animation loops to the first frame after the last frame\n */\n AnimationStrategy[\"Loop\"] = \"loop\";\n /**\n * Animation plays to the last frame, then backwards to the first frame, then repeats\n */\n AnimationStrategy[\"PingPong\"] = \"pingpong\";\n /**\n * Animation ends stopping on the last frame\n */\n AnimationStrategy[\"Freeze\"] = \"freeze\";\n})(AnimationStrategy || (AnimationStrategy = {}));\nconst AnimationEvents = {\n Frame: 'frame',\n Loop: 'loop',\n End: 'end'\n};\n/**\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\n *\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\n */\nclass Animation extends Graphic {\n constructor(options) {\n var _a, _b, _c;\n super(options);\n this.events = new EventEmitter();\n this.frames = [];\n this.strategy = AnimationStrategy.Loop;\n this.frameDuration = 100;\n this._idempotencyToken = -1;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = 0;\n this._pingPongDirection = 1;\n this._done = false;\n this._playing = true;\n this._speed = 1;\n this._reversed = false;\n this.frames = options.frames;\n this.speed = (_a = options.speed) !== null && _a !== void 0 ? _a : this.speed;\n this.strategy = (_b = options.strategy) !== null && _b !== void 0 ? _b : this.strategy;\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : (_c = options.frameDuration) !== null && _c !== void 0 ? _c : this.frameDuration;\n if (options.reverse) {\n this.reverse();\n }\n this.goToFrame(0);\n }\n clone() {\n return new Animation({\n frames: this.frames.map((f) => ({ ...f })),\n frameDuration: this.frameDuration,\n speed: this.speed,\n reverse: this._reversed,\n strategy: this.strategy,\n ...this.cloneGraphicOptions()\n });\n }\n get width() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) {\n return Math.abs(maybeFrame.graphic.width * this.scale.x);\n }\n return 0;\n }\n get height() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) {\n return Math.abs(maybeFrame.graphic.height * this.scale.y);\n }\n return 0;\n }\n /**\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\n * and optional [[AnimationStrategy]]\n *\n * Example:\n * ```typescript\n * const spriteSheet = SpriteSheet.fromImageSource({...});\n *\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\n * ```\n * @param spriteSheet\n * @param frameIndices\n * @param durationPerFrameMs\n * @param strategy\n */\n static fromSpriteSheet(spriteSheet, frameIndices, durationPerFrameMs, strategy = AnimationStrategy.Loop) {\n const maxIndex = spriteSheet.sprites.length - 1;\n const invalidIndices = frameIndices.filter((index) => index < 0 || index > maxIndex);\n if (invalidIndices.length) {\n Animation._LOGGER.warn(`Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(',')} no frame will be shown`);\n }\n return new Animation({\n frames: spriteSheet.sprites\n .filter((_, index) => frameIndices.indexOf(index) > -1)\n .map((f) => ({\n graphic: f,\n duration: durationPerFrameMs\n })),\n strategy: strategy\n });\n }\n /**\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\n *\n * Example:\n * ```typescript\n * const spriteSheet = SpriteSheet.fromImageSource({...});\n *\n * const anim = Animation.fromSpriteSheetCoordinates({\n * spriteSheet,\n * frameCoordinates: [\n * {x: 0, y: 5, duration: 100, options { flipHorizontal: true }},\n * {x: 1, y: 5, duration: 200},\n * {x: 2, y: 5, duration: 100},\n * {x: 3, y: 5, duration: 500}\n * ],\n * strategy: AnimationStrategy.PingPong\n * });\n * ```\n * @param options\n * @returns Animation\n */\n static fromSpriteSheetCoordinates(options) {\n const { spriteSheet, frameCoordinates, durationPerFrameMs, speed, strategy, reverse } = options;\n const defaultDuration = durationPerFrameMs !== null && durationPerFrameMs !== void 0 ? durationPerFrameMs : 100;\n const frames = [];\n for (const coord of frameCoordinates) {\n const { x, y, duration, options } = coord;\n const sprite = spriteSheet.getSprite(x, y, options);\n if (sprite) {\n frames.push({\n graphic: sprite,\n duration: duration !== null && duration !== void 0 ? duration : defaultDuration\n });\n }\n else {\n Animation._LOGGER.warn(`Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`);\n }\n }\n return new Animation({\n frames,\n strategy,\n speed,\n reverse\n });\n }\n /**\n * Current animation speed\n *\n * 1 meaning normal 1x speed.\n * 2 meaning 2x speed and so on.\n */\n get speed() {\n return this._speed;\n }\n /**\n * Current animation speed\n *\n * 1 meaning normal 1x speed.\n * 2 meaning 2x speed and so on.\n */\n set speed(val) {\n this._speed = clamp(Math.abs(val), 0, Infinity);\n }\n /**\n * Returns the current Frame of the animation\n *\n * Use [[Animation.currentFrameIndex]] to get the frame number and\n * [[Animation.goToFrame]] to set the current frame index\n */\n get currentFrame() {\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) {\n return this.frames[this._currentFrame];\n }\n return null;\n }\n /**\n * Returns the current frame index of the animation\n *\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\n */\n get currentFrameIndex() {\n return this._currentFrame;\n }\n /**\n * Returns the amount of time in milliseconds left in the current frame\n */\n get currentFrameTimeLeft() {\n return this._timeLeftInFrame;\n }\n /**\n * Returns `true` if the animation is playing\n */\n get isPlaying() {\n return this._playing;\n }\n /**\n * Reverses the play direction of the Animation, this preserves the current frame\n */\n reverse() {\n // Don't mutate with the original frame list, create a copy\n this.frames = this.frames.slice().reverse();\n this._reversed = !this._reversed;\n }\n /**\n * Returns the current play direction of the animation\n */\n get direction() {\n // Keep logically consistent with ping-pong direction\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\n const reversed = (this._reversed && this._pingPongDirection === 1) ? true : false;\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\n }\n /**\n * Plays or resumes the animation from the current frame\n */\n play() {\n this._playing = true;\n }\n /**\n * Pauses the animation on the current frame\n */\n pause() {\n this._playing = false;\n this._firstTick = true; // firstTick must be set to emit the proper frame event\n }\n /**\n * Reset the animation back to the beginning, including if the animation were done\n */\n reset() {\n this._done = false;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame) {\n this._timeLeftInFrame = ((maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration);\n }\n }\n /**\n * Returns `true` if the animation can end\n */\n get canFinish() {\n switch (this.strategy) {\n case AnimationStrategy.End:\n case AnimationStrategy.Freeze: {\n return true;\n }\n default: {\n return false;\n }\n }\n }\n /**\n * Returns `true` if the animation is done, for looping type animations\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\n *\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\n */\n get done() {\n return this._done;\n }\n /**\n * Jump the animation immediately to a specific frame if it exists\n *\n * Optionally specify an override for the duration of the frame, useful for\n * keeping multiple animations in sync with one another.\n * @param frameNumber\n * @param duration\n */\n goToFrame(frameNumber, duration) {\n this._currentFrame = frameNumber;\n this._timeLeftInFrame = duration !== null && duration !== void 0 ? duration : this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame && !this._done) {\n this._timeLeftInFrame = duration !== null && duration !== void 0 ? duration : ((maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration);\n this.events.emit('frame', { ...maybeFrame, frameIndex: this.currentFrameIndex });\n }\n }\n _nextFrame() {\n const currentFrame = this._currentFrame;\n if (this._done) {\n return currentFrame;\n }\n let next = -1;\n switch (this.strategy) {\n case AnimationStrategy.Loop: {\n next = (currentFrame + 1) % this.frames.length;\n if (next === 0) {\n this.events.emit('loop', this);\n }\n break;\n }\n case AnimationStrategy.End: {\n next = currentFrame + 1;\n if (next >= this.frames.length) {\n this._done = true;\n this._currentFrame = this.frames.length;\n this.events.emit('end', this);\n }\n break;\n }\n case AnimationStrategy.Freeze: {\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\n if (next >= this.frames.length - 1) {\n this._done = true;\n this.events.emit('end', this);\n }\n break;\n }\n case AnimationStrategy.PingPong: {\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\n this._pingPongDirection = -1;\n this.events.emit('loop', this);\n }\n if (currentFrame + this._pingPongDirection < 0) {\n this._pingPongDirection = 1;\n this.events.emit('loop', this);\n }\n next = currentFrame + (this._pingPongDirection % this.frames.length);\n break;\n }\n }\n return next;\n }\n /**\n * Called internally by Excalibur to update the state of the animation potential update the current frame\n * @param elapsedMilliseconds Milliseconds elapsed\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\n */\n tick(elapsedMilliseconds, idempotencyToken = 0) {\n if (this._idempotencyToken === idempotencyToken) {\n return;\n }\n this._idempotencyToken = idempotencyToken;\n if (!this._playing) {\n return;\n }\n // if it's the first frame emit frame event\n if (this._firstTick) {\n this._firstTick = false;\n this.events.emit('frame', { ...this.currentFrame, frameIndex: this.currentFrameIndex });\n }\n this._timeLeftInFrame -= elapsedMilliseconds * this._speed;\n if (this._timeLeftInFrame <= 0) {\n this.goToFrame(this._nextFrame());\n }\n }\n _drawImage(ctx, x, y) {\n if (this.currentFrame) {\n this.currentFrame.graphic.draw(ctx, x, y);\n }\n }\n}\nAnimation._LOGGER = Logger.getInstance();\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsGroup.ts\n\n\n\n\n\nclass GraphicsGroup extends Graphic {\n constructor(options) {\n super(options);\n this._logger = Logger.getInstance();\n this.members = [];\n this.members = options.members;\n this._updateDimensions();\n }\n clone() {\n return new GraphicsGroup({\n members: [...this.members],\n ...this.cloneGraphicOptions()\n });\n }\n _updateDimensions() {\n const bb = this.localBounds;\n this.width = bb.width;\n this.height = bb.height;\n return bb;\n }\n get localBounds() {\n let bb = new BoundingBox();\n for (const member of this.members) {\n if (member instanceof Graphic) {\n bb = member.localBounds.combine(bb);\n }\n else {\n const { graphic, offset: pos, useBounds } = member;\n const shouldUseBounds = useBounds === undefined ? true : useBounds;\n if (graphic) {\n if (shouldUseBounds) {\n bb = graphic.localBounds.translate(pos).combine(bb);\n }\n }\n else {\n this._logger.warnOnce(`Graphics group member has an null or undefined graphic, member definition: ${JSON.stringify(member)}.`);\n }\n }\n }\n return bb;\n }\n _isAnimationOrGroup(graphic) {\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\n }\n tick(elapsedMilliseconds, idempotencyToken) {\n for (const member of this.members) {\n let graphic;\n if (member instanceof Graphic) {\n graphic = member;\n }\n else {\n graphic = member.graphic;\n }\n if (this._isAnimationOrGroup(graphic)) {\n graphic.tick(elapsedMilliseconds, idempotencyToken);\n }\n }\n }\n reset() {\n for (const member of this.members) {\n let graphic;\n if (member instanceof Graphic) {\n graphic = member;\n }\n else {\n graphic = member.graphic;\n }\n if (this._isAnimationOrGroup(graphic)) {\n graphic.reset();\n }\n }\n }\n _preDraw(ex, x, y) {\n this._updateDimensions();\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n const pos = Vector.Zero;\n for (const member of this.members) {\n let graphic;\n if (member instanceof Graphic) {\n graphic = member;\n }\n else {\n graphic = member.graphic;\n member.offset.clone(pos);\n }\n if (!graphic) {\n continue;\n }\n ex.save();\n ex.translate(x, y);\n graphic.draw(ex, pos.x, pos.y);\n if (this.showDebug) {\n /* istanbul ignore next */\n ex.debug.drawRect(0, 0, this.width, this.height);\n }\n ex.restore();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Configurable.ts\n/**\n * Configurable helper extends base type and makes all properties available as option bag arguments\n * @internal\n * @param base\n */\nfunction Configurable(base) {\n return class extends base {\n assign(props) {\n //set the value of every property that was passed in,\n //if the constructor previously set this value, it will be overridden here\n for (const k in props) {\n // eslint-disable-next-line\n if (typeof this[k] !== 'function') {\n // eslint-disable-next-line\n this[k] = props[k];\n }\n }\n }\n constructor(...args) {\n super(...args);\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\n //of whatever ctor is the implementation, so args.length doesn't work here.\n const size = args.filter(function (value) {\n return value !== undefined;\n }).length;\n if (size === 1 && args[0] && typeof args[0] === 'object' && !(args[0] instanceof Array)) {\n this.assign(args[0]);\n }\n }\n };\n}\n\n;// CONCATENATED MODULE: ./Particles.ts\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * An enum that represents the types of emitter nozzles\n */\nvar EmitterType;\n(function (EmitterType) {\n /**\n * Constant for the circular emitter type\n */\n EmitterType[EmitterType[\"Circle\"] = 0] = \"Circle\";\n /**\n * Constant for the rectangular emitter type\n */\n EmitterType[EmitterType[\"Rectangle\"] = 1] = \"Rectangle\";\n})(EmitterType || (EmitterType = {}));\n/**\n * @hidden\n */\nclass ParticleImpl extends Entity {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite) {\n super();\n this.position = new Vector(0, 0);\n this.velocity = new Vector(0, 0);\n this.acceleration = new Vector(0, 0);\n this.particleRotationalVelocity = 0;\n this.currentRotation = 0;\n this.focus = null;\n this.focusAccel = 0;\n this.opacity = 1;\n this.beginColor = Color.White;\n this.endColor = Color.White;\n // Life is counted in ms\n this.life = 300;\n this.fadeFlag = false;\n // Color transitions\n this._rRate = 1;\n this._gRate = 1;\n this._bRate = 1;\n this._aRate = 0;\n this._currentColor = Color.White;\n this.emitter = null;\n this.particleSize = 5;\n this.particleSprite = null;\n this.sizeRate = 0;\n this.elapsedMultiplier = 0;\n this.visible = true;\n this.isOffscreen = false;\n let emitter = emitterOrConfig;\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\n const config = emitterOrConfig;\n emitter = config.emitter;\n life = config.life;\n opacity = config.opacity;\n endColor = config.endColor;\n beginColor = config.beginColor;\n position = config.position;\n velocity = config.velocity;\n acceleration = config.acceleration;\n startSize = config.startSize;\n endSize = config.endSize;\n particleSprite = config.particleSprite;\n }\n this.emitter = emitter;\n this.life = life || this.life;\n this.opacity = opacity || this.opacity;\n this.endColor = endColor || this.endColor.clone();\n this.beginColor = beginColor || this.beginColor.clone();\n this._currentColor = this.beginColor.clone();\n this.particleSprite = particleSprite;\n if (this.emitter.particleTransform === ParticleTransform.Global) {\n const globalPos = this.emitter.transform.globalPos;\n this.position = (position || this.position).add(globalPos);\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\n }\n else {\n this.velocity = velocity || this.velocity;\n this.position = (position || this.position);\n }\n this.acceleration = acceleration || this.acceleration;\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\n this._aRate = this.opacity / this.life;\n this.startSize = startSize || 0;\n this.endSize = endSize || 0;\n if (this.endSize > 0 && this.startSize > 0) {\n this.sizeRate = (this.endSize - this.startSize) / this.life;\n this.particleSize = this.startSize;\n }\n this.addComponent((this.transform = new TransformComponent()));\n this.addComponent((this.graphics = new GraphicsComponent()));\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // TODO wut\n if (this.particleSprite) {\n this.graphics.opacity = this.opacity;\n this.graphics.use(this.particleSprite);\n }\n else {\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\n this.graphics.onPostDraw = (ctx) => {\n ctx.save();\n this.graphics.opacity = this.opacity;\n const tmpColor = this._currentColor.clone();\n tmpColor.a = 1;\n ctx.debug.drawPoint(vec(0, 0), { color: tmpColor, size: this.particleSize });\n ctx.restore();\n };\n }\n }\n kill() {\n this.emitter.removeParticle(this);\n }\n update(engine, delta) {\n this.life = this.life - delta;\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\n if (this.life < 0) {\n this.kill();\n }\n if (this.fadeFlag) {\n this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\n }\n if (this.startSize > 0 && this.endSize > 0) {\n this.particleSize = clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize));\n }\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\n if (this.focus) {\n const accel = this.focus\n .sub(this.position)\n .normalize()\n .scale(this.focusAccel)\n .scale(delta / 1000);\n this.velocity = this.velocity.add(accel);\n }\n else {\n this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\n }\n this.position = this.position.add(this.velocity.scale(delta / 1000));\n if (this.particleRotationalVelocity) {\n this.currentRotation = (this.currentRotation + (this.particleRotationalVelocity * delta) / 1000) % (2 * Math.PI);\n }\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // todo wut\n this.graphics.opacity = this.opacity;\n }\n}\n/**\n * Particle is used in a [[ParticleEmitter]]\n */\nclass Particle extends Configurable(ParticleImpl) {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite) {\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite);\n }\n}\nvar ParticleTransform;\n(function (ParticleTransform) {\n /**\n * [[ParticleTransform.Global]] is the default and emits particles as if\n * they were world space objects, useful for most effects.\n */\n ParticleTransform[\"Global\"] = \"global\";\n /**\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\n * as they would in a parent/child actor relationship.\n */\n ParticleTransform[\"Local\"] = \"local\";\n})(ParticleTransform || (ParticleTransform = {}));\n/**\n * Using a particle emitter is a great way to create interesting effects\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\n * extend [[Actor]] allowing you to use all of the features that come with.\n */\nclass ParticleEmitter extends Actor {\n /**\n * Gets the opacity of each particle from 0 to 1.0\n */\n get opacity() {\n return this.graphics.opacity;\n }\n /**\n * Gets the opacity of each particle from 0 to 1.0\n */\n set opacity(opacity) {\n this.graphics.opacity = opacity;\n }\n /**\n * Gets or sets the sprite that a particle should use\n */\n get particleSprite() {\n return this._sprite;\n }\n set particleSprite(val) {\n if (val) {\n this._sprite = val;\n }\n }\n /**\n * @param config particle emitter options bag\n */\n constructor(config) {\n var _a, _b;\n super({ width: (_a = config.width) !== null && _a !== void 0 ? _a : 0, height: (_b = config.height) !== null && _b !== void 0 ? _b : 0 });\n this._particlesToEmit = 0;\n this.numParticles = 0;\n /**\n * Gets or sets the isEmitting flag\n */\n this.isEmitting = true;\n /**\n * Gets or sets the backing particle collection\n */\n this.particles = [];\n /**\n * Gets or sets the backing deadParticle collection\n */\n this.deadParticles = [];\n /**\n * Gets or sets the minimum particle velocity\n */\n this.minVel = 0;\n /**\n * Gets or sets the maximum particle velocity\n */\n this.maxVel = 0;\n /**\n * Gets or sets the acceleration vector for all particles\n */\n this.acceleration = new Vector(0, 0);\n /**\n * Gets or sets the minimum angle in radians\n */\n this.minAngle = 0;\n /**\n * Gets or sets the maximum angle in radians\n */\n this.maxAngle = 0;\n /**\n * Gets or sets the emission rate for particles (particles/sec)\n */\n this.emitRate = 1; //particles/sec\n /**\n * Gets or sets the life of each particle in milliseconds\n */\n this.particleLife = 2000;\n /**\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\n */\n this.fadeFlag = false;\n /**\n * Gets or sets the optional focus where all particles should accelerate towards\n */\n this.focus = null;\n /**\n * Gets or sets the acceleration for focusing particles if a focus has been specified\n */\n this.focusAccel = null;\n /**\n * Gets or sets the optional starting size for the particles\n */\n this.startSize = null;\n /**\n * Gets or sets the optional ending size for the particles\n */\n this.endSize = null;\n /**\n * Gets or sets the minimum size of all particles\n */\n this.minSize = 5;\n /**\n * Gets or sets the maximum size of all particles\n */\n this.maxSize = 5;\n /**\n * Gets or sets the beginning color of all particles\n */\n this.beginColor = Color.White;\n /**\n * Gets or sets the ending color of all particles\n */\n this.endColor = Color.White;\n this._sprite = null;\n /**\n * Gets or sets the emitter type for the particle emitter\n */\n this.emitterType = EmitterType.Rectangle;\n /**\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\n */\n this.radius = 0;\n /**\n * Gets or sets the particle rotational speed velocity\n */\n this.particleRotationalVelocity = 0;\n /**\n * Indicates whether particles should start with a random rotation\n */\n this.randomRotation = false;\n /**\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\n * they were world space objects, useful for most effects.\n *\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\n * as they would in a parent/child actor relationship.\n */\n this.particleTransform = ParticleTransform.Global;\n const { x, y, pos, isEmitting, minVel, maxVel, acceleration, minAngle, maxAngle, emitRate, particleLife, opacity, fadeFlag, focus, focusAccel, startSize, endSize, minSize, maxSize, beginColor, endColor, particleSprite, emitterType, radius, particleRotationalVelocity, particleTransform, randomRotation, random } = { ...config };\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.isEmitting = isEmitting !== null && isEmitting !== void 0 ? isEmitting : this.isEmitting;\n this.minVel = minVel !== null && minVel !== void 0 ? minVel : this.minVel;\n this.maxVel = maxVel !== null && maxVel !== void 0 ? maxVel : this.maxVel;\n this.acceleration = acceleration !== null && acceleration !== void 0 ? acceleration : this.acceleration;\n this.minAngle = minAngle !== null && minAngle !== void 0 ? minAngle : this.minAngle;\n this.maxAngle = maxAngle !== null && maxAngle !== void 0 ? maxAngle : this.maxAngle;\n this.emitRate = emitRate !== null && emitRate !== void 0 ? emitRate : this.emitRate;\n this.particleLife = particleLife !== null && particleLife !== void 0 ? particleLife : this.particleLife;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.fadeFlag = fadeFlag !== null && fadeFlag !== void 0 ? fadeFlag : this.fadeFlag;\n this.focus = focus !== null && focus !== void 0 ? focus : this.focus;\n this.focusAccel = focusAccel !== null && focusAccel !== void 0 ? focusAccel : this.focusAccel;\n this.startSize = startSize !== null && startSize !== void 0 ? startSize : this.startSize;\n this.endSize = endSize !== null && endSize !== void 0 ? endSize : this.endSize;\n this.minSize = minSize !== null && minSize !== void 0 ? minSize : this.minSize;\n this.maxSize = maxSize !== null && maxSize !== void 0 ? maxSize : this.maxSize;\n this.beginColor = beginColor !== null && beginColor !== void 0 ? beginColor : this.beginColor;\n this.endColor = endColor !== null && endColor !== void 0 ? endColor : this.endColor;\n this.particleSprite = particleSprite !== null && particleSprite !== void 0 ? particleSprite : this.particleSprite;\n this.emitterType = emitterType !== null && emitterType !== void 0 ? emitterType : this.emitterType;\n this.radius = radius !== null && radius !== void 0 ? radius : this.radius;\n this.particleRotationalVelocity = particleRotationalVelocity !== null && particleRotationalVelocity !== void 0 ? particleRotationalVelocity : this.particleRotationalVelocity;\n this.randomRotation = randomRotation !== null && randomRotation !== void 0 ? randomRotation : this.randomRotation;\n this.particleTransform = particleTransform !== null && particleTransform !== void 0 ? particleTransform : this.particleTransform;\n this.body.collisionType = CollisionType.PreventCollision;\n this.random = random !== null && random !== void 0 ? random : new Random();\n }\n removeParticle(particle) {\n this.deadParticles.push(particle);\n }\n /**\n * Causes the emitter to emit particles\n * @param particleCount Number of particles to emit right now\n */\n emitParticles(particleCount) {\n var _a;\n for (let i = 0; i < particleCount; i++) {\n const p = this._createParticle();\n this.particles.push(p);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\n if (this.particleTransform === ParticleTransform.Global) {\n this.scene.world.add(p);\n }\n else {\n this.addChild(p);\n }\n }\n }\n }\n clearParticles() {\n this.particles.length = 0;\n }\n // Creates a new particle given the constraints of the emitter\n _createParticle() {\n // todo implement emitter constraints;\n let ranX = 0;\n let ranY = 0;\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\n const dx = vel * Math.cos(angle);\n const dy = vel * Math.sin(angle);\n if (this.emitterType === EmitterType.Rectangle) {\n ranX = randomInRange(0, this.width, this.random);\n ranY = randomInRange(0, this.height, this.random);\n }\n else if (this.emitterType === EmitterType.Circle) {\n const radius = randomInRange(0, this.radius, this.random);\n ranX = radius * Math.cos(angle);\n ranY = radius * Math.sin(angle);\n }\n const p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new Vector(ranX, ranY), new Vector(dx, dy), this.acceleration, this.startSize, this.endSize, this.particleSprite);\n p.fadeFlag = this.fadeFlag;\n p.particleSize = size;\n p.particleRotationalVelocity = this.particleRotationalVelocity;\n if (this.randomRotation) {\n p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\n }\n if (this.focus) {\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\n p.focusAccel = this.focusAccel;\n }\n return p;\n }\n update(engine, delta) {\n var _a;\n super.update(engine, delta);\n if (this.isEmitting) {\n this._particlesToEmit += this.emitRate * (delta / 1000);\n if (this._particlesToEmit > 1.0) {\n this.emitParticles(Math.floor(this._particlesToEmit));\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\n }\n }\n // deferred removal\n for (let i = 0; i < this.deadParticles.length; i++) {\n removeItemFromArray(this.deadParticles[i], this.particles);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\n this.scene.world.remove(this.deadParticles[i], false);\n }\n }\n this.deadParticles.length = 0;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/TransformInterpolation.ts\n\n/**\n * Blend 2 transforms for interpolation, will interpolate from the context of newTx's parent if it exists\n */\nfunction blendTransform(oldTx, newTx, blend, target) {\n if (oldTx.parent !== newTx.parent) {\n // Caller expects a local transform\n // Adjust old tx to be local to the new parent whatever that is\n const oldTxWithNewParent = oldTx.clone();\n const oldGlobalPos = oldTx.globalPos.clone();\n const oldGlobalScale = oldTx.globalScale.clone();\n const oldGlobalRotation = oldTx.globalRotation;\n oldTxWithNewParent.parent = newTx.parent;\n oldTxWithNewParent.globalPos = oldGlobalPos;\n oldTxWithNewParent.globalScale = oldGlobalScale;\n oldTxWithNewParent.globalRotation = oldGlobalRotation;\n oldTx = oldTxWithNewParent;\n }\n let interpolatedPos = newTx.pos;\n let interpolatedScale = newTx.scale;\n let interpolatedRotation = newTx.rotation;\n interpolatedPos = newTx.pos.scale(blend).add(oldTx.pos.scale(1.0 - blend));\n interpolatedScale = newTx.scale.scale(blend).add(oldTx.scale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(oldTx.rotation) + blend * Math.cos(newTx.rotation);\n const sine = (1.0 - blend) * Math.sin(oldTx.rotation) + blend * Math.sin(newTx.rotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n const tx = target !== null && target !== void 0 ? target : new transform_Transform();\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\n return tx;\n}\n/**\n *\n */\nfunction blendGlobalTransform(oldTx, newTx, blend, target) {\n let interpolatedPos = newTx.globalPos;\n let interpolatedScale = newTx.globalScale;\n let interpolatedRotation = newTx.globalRotation;\n interpolatedPos = newTx.globalPos.scale(blend).add(oldTx.globalPos.scale(1.0 - blend));\n interpolatedScale = newTx.globalScale.scale(blend).add(oldTx.globalScale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(oldTx.globalRotation) + blend * Math.cos(newTx.globalRotation);\n const sine = (1.0 - blend) * Math.sin(oldTx.globalRotation) + blend * Math.sin(newTx.globalRotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n const tx = target !== null && target !== void 0 ? target : new Transform();\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\n return tx;\n}\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsSystem.ts\n\n\n\n\n\n // this import seems to bomb wallaby\n\n\n\n\n\n\n\n\nclass GraphicsSystem extends System {\n get sortedTransforms() {\n return this._sortedTransforms;\n }\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Average;\n this._token = 0;\n this._sortedTransforms = [];\n this._zHasChanged = false;\n this._zIndexUpdate = () => {\n this._zHasChanged = true;\n };\n this._targetInterpolationTransform = new transform_Transform();\n this.query = this.world.query([TransformComponent, GraphicsComponent]);\n this.query.entityAdded$.subscribe(e => {\n const tx = e.get(TransformComponent);\n this._sortedTransforms.push(tx);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n });\n this.query.entityRemoved$.subscribe(e => {\n const tx = e.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) {\n this._sortedTransforms.splice(index, 1);\n }\n });\n }\n initialize(world, scene) {\n this._camera = scene.camera;\n this._engine = scene.engine;\n }\n preupdate() {\n // Graphics context could be switched to fallback in a new frame\n this._graphicsContext = this._engine.graphicsContext;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b) => {\n return a.z - b.z;\n });\n this._zHasChanged = false;\n }\n }\n update(delta) {\n this._token++;\n let graphics;\n FontCache.checkAndClearCache();\n // This is a performance enhancement, most things are in world space\n // so if we can only do this once saves a ton of transform updates\n this._graphicsContext.save();\n if (this._camera) {\n this._camera.draw(this._graphicsContext);\n }\n for (const transform of this._sortedTransforms) {\n const entity = transform.owner;\n // If the entity is offscreen skip\n if (entity.hasTag('ex.offscreen')) {\n continue;\n }\n graphics = entity.get(GraphicsComponent);\n // Exit if graphics set to not visible\n if (!graphics.visible) {\n continue;\n }\n // Optionally run the onPreTransformDraw graphics lifecycle draw\n if (graphics.onPreTransformDraw) {\n graphics.onPreTransformDraw(this._graphicsContext, delta);\n }\n entity.events.emit('pretransformdraw', new PreTransformDrawEvent(this._graphicsContext, delta, entity));\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.restore();\n }\n this._graphicsContext.save();\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n }\n // Tick any graphics state (but only once) for animations and graphics groups\n graphics.update(delta, this._token);\n // Apply parallax\n const parallax = entity.get(ParallaxComponent);\n if (parallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\n const parallaxOffset = this._camera.drawPos.scale(oneMinusFactor);\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\n }\n // Position the entity + estimate lag\n this._applyTransform(entity);\n // If there is a material enable it on the context\n if (graphics.material) {\n this._graphicsContext.material = graphics.material;\n }\n // Optionally run the onPreDraw graphics lifecycle draw\n if (graphics.onPreDraw) {\n graphics.onPreDraw(this._graphicsContext, delta);\n }\n entity.events.emit('predraw', new PreDrawEvent(this._graphicsContext, delta, entity));\n // TODO remove this hack on the particle redo\n // Remove this line after removing the wallaby import\n const particleOpacity = (entity instanceof Particle) ? entity.opacity : 1;\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\n // Draw the graphics component\n this._drawGraphicsComponent(graphics, transform);\n // Optionally run the onPostDraw graphics lifecycle draw\n if (graphics.onPostDraw) {\n graphics.onPostDraw(this._graphicsContext, delta);\n }\n entity.events.emit('postdraw', new PostDrawEvent(this._graphicsContext, delta, entity));\n this._graphicsContext.restore();\n // Reset the transform back to the original world space\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.save();\n if (this._camera) {\n this._camera.draw(this._graphicsContext);\n }\n }\n // Optionally run the onPreTransformDraw graphics lifecycle draw\n if (graphics.onPostTransformDraw) {\n graphics.onPostTransformDraw(this._graphicsContext, delta);\n }\n entity.events.emit('posttransformdraw', new PostTransformDrawEvent(this._graphicsContext, delta, entity));\n }\n this._graphicsContext.restore();\n }\n _drawGraphicsComponent(graphicsComponent, transformComponent) {\n var _a, _b;\n if (graphicsComponent.visible) {\n const flipHorizontal = graphicsComponent.flipHorizontal;\n const flipVertical = graphicsComponent.flipVertical;\n const graphic = graphicsComponent.current;\n const options = (_a = graphicsComponent.currentOptions) !== null && _a !== void 0 ? _a : {};\n if (graphic) {\n let anchor = graphicsComponent.anchor;\n let offset = graphicsComponent.offset;\n let scaleX = 1;\n let scaleY = 1;\n // handle specific overrides\n if (options === null || options === void 0 ? void 0 : options.anchor) {\n anchor = options.anchor;\n }\n if (options === null || options === void 0 ? void 0 : options.offset) {\n offset = options.offset;\n }\n const globalScale = transformComponent.globalScale;\n scaleX *= graphic.scale.x * globalScale.x;\n scaleY *= graphic.scale.y * globalScale.y;\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\n const offsetX = -graphic.width * anchor.x + offset.x * scaleX;\n const offsetY = -graphic.height * anchor.y + offset.y * scaleY;\n const oldFlipHorizontal = graphic.flipHorizontal;\n const oldFlipVertical = graphic.flipVertical;\n if (flipHorizontal || flipVertical) {\n // flip any currently flipped graphics\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\n }\n graphic === null || graphic === void 0 ? void 0 : graphic.draw(this._graphicsContext, offsetX, offsetY);\n if (flipHorizontal || flipVertical) {\n graphic.flipHorizontal = oldFlipHorizontal;\n graphic.flipVertical = oldFlipVertical;\n }\n // TODO move debug code out?\n if (((_b = this._engine) === null || _b === void 0 ? void 0 : _b.isDebug) && this._engine.debug.graphics.showBounds) {\n const offset = vec(offsetX, offsetY);\n if (graphic instanceof GraphicsGroup) {\n for (const member of graphic.members) {\n let g;\n let pos = Vector.Zero;\n if (member instanceof Graphic) {\n g = member;\n }\n else {\n g = member.graphic;\n pos = member.offset;\n }\n g === null || g === void 0 ? void 0 : g.localBounds.translate(offset.add(pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n }\n else {\n /* istanbul ignore next */\n graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n }\n }\n }\n }\n /**\n * This applies the current entity transform to the graphics context\n * @param entity\n */\n _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors) {\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n const optionalBody = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(BodyComponent);\n let tx = transform.get();\n if (optionalBody) {\n if (this._engine.fixedUpdateFps &&\n optionalBody.__oldTransformCaptured &&\n optionalBody.enableFixedUpdateInterpolate) {\n // Interpolate graphics if needed\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n tx = blendTransform(optionalBody.oldTransform, transform.get(), blend, this._targetInterpolationTransform);\n }\n }\n if (transform) {\n this._graphicsContext.z = transform.z;\n this._graphicsContext.translate(tx.pos.x, tx.pos.y);\n this._graphicsContext.scale(tx.scale.x, tx.scale.y);\n this._graphicsContext.rotate(tx.rotation);\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Debug/DebugSystem.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nclass DebugSystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Lowest;\n this.query = this.world.query([TransformComponent]);\n }\n initialize(world, scene) {\n this._graphicsContext = scene.engine.graphicsContext;\n this._camera = scene.camera;\n this._engine = scene.engine;\n this._collisionSystem = world.systemManager.get(CollisionSystem);\n }\n update() {\n var _a;\n if (!this._engine.isDebug) {\n return;\n }\n const filterSettings = this._engine.debug.filter;\n let id;\n let name;\n const entitySettings = this._engine.debug.entity;\n let tx;\n const txSettings = this._engine.debug.transform;\n let motion;\n const motionSettings = this._engine.debug.motion;\n let colliderComp;\n const colliderSettings = this._engine.debug.collider;\n const physicsSettings = this._engine.debug.physics;\n let graphics;\n const graphicsSettings = this._engine.debug.graphics;\n let debugDraw;\n let body;\n const bodySettings = this._engine.debug.body;\n const cameraSettings = this._engine.debug.camera;\n for (const entity of this.query.entities) {\n if (entity.hasTag('offscreen')) {\n // skip offscreen entities\n continue;\n }\n if (entity instanceof Particle) {\n // Particles crush the renderer :(\n continue;\n }\n if (filterSettings.useFilter) {\n const allIds = filterSettings.ids.length === 0;\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\n if (!idMatch) {\n continue;\n }\n const allNames = filterSettings.nameQuery === '';\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\n if (!nameMatch) {\n continue;\n }\n }\n let cursor = Vector.Zero;\n const lineHeight = vec(0, 16);\n id = entity.id;\n name = entity.name;\n tx = entity.get(TransformComponent);\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n this._pushCameraTransform(tx);\n this._graphicsContext.save();\n if (tx.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n }\n this._graphicsContext.z = txSettings.debugZIndex;\n this._applyTransform(entity);\n if (tx) {\n if (txSettings.showAll || txSettings.showPosition) {\n this._graphicsContext.debug.drawPoint(Vector.Zero, { size: 4, color: txSettings.positionColor });\n }\n if (txSettings.showAll || txSettings.showPositionLabel) {\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showZIndex) {\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showId) {\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? 'child of id(' + ((_a = entity.parent) === null || _a === void 0 ? void 0 : _a.id) + ')' : ''}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showName) {\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showRotation) {\n this._graphicsContext.drawLine(Vector.Zero, Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero), txSettings.rotationColor, 2);\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showScale) {\n this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\n }\n }\n graphics = entity.get(GraphicsComponent);\n if (graphics) {\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\n const bounds = graphics.localBounds;\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\n }\n }\n debugDraw = entity.get(DebugGraphicsComponent);\n if (debugDraw) {\n if (!debugDraw.useTransform) {\n this._graphicsContext.restore();\n }\n debugDraw.draw(this._graphicsContext, this._engine.debug);\n if (!debugDraw.useTransform) {\n this._graphicsContext.save();\n this._applyTransform(entity);\n }\n }\n body = entity.get(BodyComponent);\n if (body) {\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showCollisionType) {\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMass) {\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMotion) {\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showSleeping) {\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping : 'cant sleep'})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n }\n this._graphicsContext.restore();\n // World space\n this._graphicsContext.save();\n if (tx.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n }\n this._graphicsContext.z = txSettings.debugZIndex;\n motion = entity.get(MotionComponent);\n if (motion) {\n if (motionSettings.showAll || motionSettings.showVelocity) {\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\n cursor = cursor.add(lineHeight);\n }\n if (motionSettings.showAll || motionSettings.showAcceleration) {\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\n }\n }\n // Colliders live in world space already so after the restore()\n colliderComp = entity.get(ColliderComponent);\n if (colliderComp) {\n const collider = colliderComp.get();\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) {\n collider.debug(this._graphicsContext, colliderSettings.geometryColor, {\n lineWidth: colliderSettings.geometryLineWidth,\n pointSize: colliderSettings.geometryPointSize\n });\n }\n if (colliderSettings.showAll || colliderSettings.showBounds) {\n if (collider instanceof CompositeCollider) {\n const colliders = collider.getColliders();\n for (const collider of colliders) {\n const bounds = collider.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\n if (colliderSettings.showAll || colliderSettings.showOwner) {\n this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\n }\n }\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\n }\n else if (collider) {\n const bounds = colliderComp.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\n if (colliderSettings.showAll || colliderSettings.showOwner) {\n this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\n }\n }\n }\n }\n this._graphicsContext.restore();\n this._popCameraTransform(tx);\n }\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) {\n this._collisionSystem.debug(this._graphicsContext);\n }\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) {\n for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts) {\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) {\n for (const point of contact.points) {\n this._graphicsContext.debug.drawPoint(point, {\n size: physicsSettings.contactSize,\n color: physicsSettings.collisionContactColor\n });\n }\n }\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) {\n for (const point of contact.points) {\n this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\n color: physicsSettings.collisionNormalColor\n });\n }\n }\n }\n }\n this._graphicsContext.restore();\n if (cameraSettings) {\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (cameraSettings.showAll || cameraSettings.showFocus) {\n this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\n }\n if (cameraSettings.showAll || cameraSettings.showZoom) {\n this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\n }\n this._graphicsContext.restore();\n }\n this._graphicsContext.flush();\n }\n postupdate(engine, elapsedMs) {\n if (this._engine.isDebug) {\n this._graphicsContext.save();\n if (this._camera) {\n this._camera.draw(this._graphicsContext);\n }\n Debug.flush(this._graphicsContext);\n this._graphicsContext.restore();\n }\n }\n /**\n * This applies the current entity transform to the graphics context\n * @param entity\n */\n _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors) {\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n if (transform) {\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\n this._graphicsContext.rotate(transform.rotation);\n }\n }\n }\n /**\n * Applies the current camera transform if in world coordinates\n * @param transform\n */\n _pushCameraTransform(transform) {\n // Establish camera offset per entity\n if (transform.coordPlane === CoordPlane.World) {\n this._graphicsContext.save();\n if (this._camera) {\n this._camera.draw(this._graphicsContext);\n }\n }\n }\n /**\n * Resets the current camera transform if in world coordinates\n * @param transform\n */\n _popCameraTransform(transform) {\n if (transform.coordPlane === CoordPlane.World) {\n // Apply camera world offset\n this._graphicsContext.restore();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerSystem.ts\n\n\n\n\n\n/**\n * The PointerSystem is responsible for dispatching pointer events to entities\n * that need them.\n *\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\n * the [[Collider]]'s shape for pointer events.\n */\nclass PointerSystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n /**\n * Optionally override component configuration for all entities\n */\n this.overrideUseColliderShape = false;\n /**\n * Optionally override component configuration for all entities\n */\n this.overrideUseGraphicsBounds = false;\n this.lastFrameEntityToPointers = new Map();\n this.currentFrameEntityToPointers = new Map();\n this._sortedTransforms = [];\n this._sortedEntities = [];\n this._zHasChanged = false;\n this._zIndexUpdate = () => {\n this._zHasChanged = true;\n };\n this.query = this.world.query([TransformComponent, PointerComponent]);\n this.query.entityAdded$.subscribe(e => {\n const tx = e.get(TransformComponent);\n this._sortedTransforms.push(tx);\n this._sortedEntities.push(tx.owner);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n });\n this.query.entityRemoved$.subscribe(e => {\n const tx = e.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) {\n this._sortedTransforms.splice(index, 1);\n this._sortedEntities.splice(index, 1);\n }\n });\n }\n initialize(world, scene) {\n this._engine = scene.engine;\n this._scene = scene;\n }\n preupdate() {\n // event receiver might change per frame\n this._receivers = [this._engine.input.pointers, this._scene.input.pointers];\n this._engineReceiver = this._engine.input.pointers;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b) => {\n return b.z - a.z;\n });\n this._sortedEntities = this._sortedTransforms.map(t => t.owner);\n this._zHasChanged = false;\n }\n }\n entityCurrentlyUnderPointer(entity, pointerId) {\n return this.currentFrameEntityToPointers.has(entity.id) &&\n this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entityWasUnderPointer(entity, pointerId) {\n return this.lastFrameEntityToPointers.has(entity.id) &&\n this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entered(entity, pointerId) {\n return this.entityCurrentlyUnderPointer(entity, pointerId) &&\n !this.lastFrameEntityToPointers.has(entity.id);\n }\n left(entity, pointerId) {\n return !this.currentFrameEntityToPointers.has(entity.id) &&\n this.entityWasUnderPointer(entity, pointerId);\n }\n addPointerToEntity(entity, pointerId) {\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\n this.currentFrameEntityToPointers.set(entity.id, [pointerId]);\n return;\n }\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\n }\n update() {\n // Locate all the pointer/entity mappings\n this._processPointerToEntity(this._sortedEntities);\n // Dispatch pointer events on entities\n this._dispatchEvents(this._sortedEntities);\n // Clear last frame's events\n this._receivers.forEach(r => r.update());\n this.lastFrameEntityToPointers.clear();\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\n this.currentFrameEntityToPointers.clear();\n this._receivers.forEach(r => r.clear());\n }\n _processPointerToEntity(entities) {\n var _a;\n let transform;\n let collider;\n let graphics;\n let pointer;\n const receiver = this._engineReceiver;\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\n // doesn't seem to cause issues tho for perf\n // Pre-process find entities under pointers\n for (const entity of entities) {\n transform = entity.get(TransformComponent);\n pointer = (_a = entity.get(PointerComponent)) !== null && _a !== void 0 ? _a : new PointerComponent;\n // Check collider contains pointer\n collider = entity.get(ColliderComponent);\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\n collider.update();\n const geom = collider.get();\n if (geom) {\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries()) {\n if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\n this.addPointerToEntity(entity, pointerId);\n }\n }\n }\n }\n // Check graphics contains pointer\n graphics = entity.get(GraphicsComponent);\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries()) {\n if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\n this.addPointerToEntity(entity, pointerId);\n }\n }\n }\n }\n }\n _processDownAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastDownPerPointer = new Map(); // TODO will this get confused between receivers?\n // Loop through down and dispatch to entities\n for (const event of receiver.currentFrameDown) {\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit('pointerdown', event);\n if (receiver.isDragStart(event.pointerId)) {\n entity.events.emit('pointerdragstart', event);\n }\n }\n lastDownPerPointer.set(event.pointerId, event);\n }\n return lastDownPerPointer;\n }\n _processUpAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastUpPerPointer = new Map();\n // Loop through up and dispatch to entities\n for (const event of receiver.currentFrameUp) {\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit('pointerup', event);\n if (receiver.isDragEnd(event.pointerId)) {\n entity.events.emit('pointerdragend', event);\n }\n }\n lastUpPerPointer.set(event.pointerId, event);\n }\n return lastUpPerPointer;\n }\n _processMoveAndEmit(entity) {\n const receiver = this._engineReceiver;\n const lastMovePerPointer = new Map();\n // Loop through move and dispatch to entities\n for (const event of receiver.currentFrameMove) {\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n // move\n entity.events.emit('pointermove', event);\n if (receiver.isDragging(event.pointerId)) {\n entity.events.emit('pointerdragmove', event);\n }\n }\n lastMovePerPointer.set(event.pointerId, event);\n }\n return lastMovePerPointer;\n }\n _processEnterLeaveAndEmit(entity, lastUpDownMoveEvents) {\n const receiver = this._engineReceiver;\n // up, down, and move are considered for enter and leave\n for (const event of lastUpDownMoveEvents) {\n // enter\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\n entity.events.emit('pointerenter', event);\n if (receiver.isDragging(event.pointerId)) {\n entity.events.emit('pointerdragenter', event);\n }\n break;\n }\n if (event.active && entity.active &&\n // leave can happen on move\n (this.left(entity, event.pointerId) ||\n // or leave can happen on pointer up\n (this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === 'up'))) {\n entity.events.emit('pointerleave', event);\n if (receiver.isDragging(event.pointerId)) {\n entity.events.emit('pointerdragleave', event);\n }\n break;\n }\n }\n }\n _processCancelAndEmit(entity) {\n const receiver = this._engineReceiver;\n // cancel\n for (const event of receiver.currentFrameCancel) {\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit('pointercancel', event);\n }\n }\n }\n _processWheelAndEmit(entity) {\n const receiver = this._engineReceiver;\n // wheel\n for (const event of receiver.currentFrameWheel) {\n // Currently the wheel only fires under the primary pointer '0'\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) {\n entity.events.emit('pointerwheel', event);\n }\n }\n }\n _dispatchEvents(entities) {\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\n // Filter preserves z order\n const entitiesWithEvents = entities.filter(e => lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\n let lastMovePerPointer;\n let lastUpPerPointer;\n let lastDownPerPointer;\n // Dispatch events in entity z order\n for (const entity of entitiesWithEvents) {\n lastDownPerPointer = this._processDownAndEmit(entity);\n lastUpPerPointer = this._processUpAndEmit(entity);\n lastMovePerPointer = this._processMoveAndEmit(entity);\n const lastUpDownMoveEvents = [\n ...lastMovePerPointer.values(),\n ...lastDownPerPointer.values(),\n ...lastUpPerPointer.values()\n ];\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\n this._processCancelAndEmit(entity);\n this._processWheelAndEmit(entity);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/ActionsSystem.ts\n\n\n\nclass ActionsSystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Higher;\n this._actions = [];\n this.query = this.world.query([ActionsComponent]);\n this.query.entityAdded$.subscribe(e => this._actions.push(e.get(ActionsComponent)));\n this.query.entityRemoved$.subscribe(e => {\n const action = e.get(ActionsComponent);\n const index = this._actions.indexOf(action);\n if (index > -1) {\n this._actions.splice(index, 1);\n }\n });\n }\n update(delta) {\n for (const actions of this._actions) {\n actions.update(delta);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/IsometricEntityComponent.ts\n\nclass IsometricEntityComponent extends Component {\n /**\n * Specify the isometric map to use to position this entity's z-index\n * @param mapOrOptions\n */\n constructor(mapOrOptions) {\n super();\n /**\n * Vertical \"height\" in the isometric world\n */\n this.elevation = 0;\n this.columns = mapOrOptions.columns;\n this.rows = mapOrOptions.rows;\n this.tileWidth = mapOrOptions.tileWidth;\n this.tileHeight = mapOrOptions.tileHeight;\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/IsometricEntitySystem.ts\n\n\n\n\nclass IsometricEntitySystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Update;\n this.priority = SystemPriority.Lower;\n this.query = this.world.query([TransformComponent, IsometricEntityComponent]);\n }\n update() {\n let transform;\n let iso;\n for (const entity of this.query.entities) {\n transform = entity.get(TransformComponent);\n iso = entity.get(IsometricEntityComponent);\n const maxZindexPerElevation = Math.max(iso.columns * iso.tileWidth, iso.rows * iso.tileHeight);\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\n transform.z = newZ;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/OffscreenSystem.ts\n\n\n\n\n\n\n\n\nclass OffscreenSystem extends System {\n constructor(world) {\n super();\n this.world = world;\n this.systemType = SystemType.Draw;\n this.priority = SystemPriority.Higher;\n this.query = this.world.query([TransformComponent, GraphicsComponent]);\n }\n initialize(world, scene) {\n this._camera = scene.camera;\n this._screen = scene.engine.screen;\n }\n update() {\n this._worldBounds = this._screen.getWorldBounds();\n let transform;\n let graphics;\n let maybeParallax;\n for (const entity of this.query.entities) {\n graphics = entity.get(GraphicsComponent);\n transform = entity.get(TransformComponent);\n maybeParallax = entity.get(ParallaxComponent);\n let parallaxOffset;\n if (maybeParallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\n }\n // Figure out if entities are offscreen\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\n if (entityOffscreen && !entity.hasTag('ex.offscreen')) {\n entity.events.emit('exitviewport', new ExitViewPortEvent(entity));\n entity.addTag('ex.offscreen');\n }\n if (!entityOffscreen && entity.hasTag('ex.offscreen')) {\n entity.events.emit('enterviewport', new EnterViewPortEvent(entity));\n entity.removeTag('ex.offscreen');\n }\n }\n }\n _isOffscreen(transform, graphics, parallaxOffset) {\n if (transform.coordPlane === CoordPlane.World) {\n let bounds = graphics.localBounds;\n if (parallaxOffset) {\n bounds = bounds.translate(parallaxOffset);\n }\n const transformedBounds = bounds.transform(transform.get().matrix);\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\n return graphicsOffscreen;\n }\n else {\n // TODO screen coordinates\n return false;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/PhysicsWorld.ts\n\n\n\n\nclass PhysicsWorld {\n get config() {\n return watchDeep(this._config, change => {\n this.$configUpdate.notifyAll(change);\n });\n }\n set config(newConfig) {\n this._config = newConfig;\n this.$configUpdate.notifyAll(newConfig);\n }\n /**\n * Spatial data structure for locating potential collision pairs and ray casts\n */\n get collisionProcessor() {\n if (this._configDirty) {\n this._configDirty = false;\n // preserve tracked colliders if config updates\n const colliders = this._collisionProcessor.getColliders();\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this._config);\n for (const collider of colliders) {\n this._collisionProcessor.track(collider);\n }\n }\n return this._collisionProcessor;\n }\n constructor(config) {\n this.$configUpdate = new Observable;\n this._configDirty = false;\n this.config = config;\n this.$configUpdate.subscribe((config) => {\n this._configDirty = true;\n BodyComponent.updateDefaultPhysicsConfig(config.bodies);\n });\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this.config);\n }\n /**\n * Raycast into the scene's physics world\n * @param ray\n * @param options\n */\n rayCast(ray, options) {\n return this.collisionProcessor.rayCast(ray, options);\n }\n}\n\n;// CONCATENATED MODULE: ./Input/Gamepad.ts\n\n\nconst GamepadEvents = {\n GamepadConnect: 'connect',\n GamepadDisconnect: 'disconnect',\n GamepadButton: 'button',\n GamepadAxis: 'axis'\n};\n/**\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\n * to provide controller support for your games.\n */\nclass Gamepads {\n constructor() {\n this.events = new EventEmitter();\n /**\n * Whether or not to poll for Gamepad input (default: `false`)\n */\n this.enabled = false;\n /**\n * Whether or not Gamepad API is supported\n */\n this.supported = !!navigator.getGamepads;\n this._gamePadTimeStamps = [0, 0, 0, 0];\n this._oldPads = [];\n this._pads = [];\n this._initSuccess = false;\n this._navigator = navigator;\n this._minimumConfiguration = null;\n this._enabled = true;\n }\n init() {\n if (!this.supported) {\n return;\n }\n if (this._initSuccess) {\n return;\n }\n // In Chrome, this will return 4 undefined items until a button is pressed\n // In FF, this will not return any items until a button is pressed\n this._oldPads = this._clonePads(this._navigator.getGamepads());\n if (this._oldPads.length && this._oldPads[0]) {\n this._initSuccess = true;\n }\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n /**\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\n * all other controllers with more axis or buttons are valid as well. If no minimum\n * configuration is set all pads are valid.\n */\n setMinimumGamepadConfiguration(config) {\n this._enableAndUpdate(); // if config is used, implicitly enable\n this._minimumConfiguration = config;\n }\n /**\n * When implicitly enabled, set the enabled flag and run an update so information is updated\n */\n _enableAndUpdate() {\n if (!this.enabled) {\n this.enabled = true;\n this.update();\n }\n }\n /**\n * Checks a navigator gamepad against the minimum configuration if present.\n */\n _isGamepadValid(pad) {\n if (!this._minimumConfiguration) {\n return true;\n }\n if (!pad) {\n return false;\n }\n const axesLength = pad.axes.filter((value) => {\n return typeof value !== undefined;\n }).length;\n const buttonLength = pad.buttons.filter((value) => {\n return typeof value !== undefined;\n }).length;\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n this.events.off(eventName, handler);\n }\n /**\n * Updates Gamepad state and publishes Gamepad events\n */\n update() {\n if (!this.enabled || !this.supported) {\n return;\n }\n if (!this._enabled) {\n return;\n }\n this.init();\n const gamepads = this._navigator.getGamepads();\n for (let i = 0; i < gamepads.length; i++) {\n if (!gamepads[i]) {\n const gamepad = this.at(i);\n // If was connected, but now isn't emit the disconnect event\n if (gamepad.connected) {\n this.events.emit('disconnect', new GamepadDisconnectEvent(i, gamepad));\n }\n // Reset connection status\n gamepad.connected = false;\n continue;\n }\n else {\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) {\n this.events.emit('connect', new GamepadConnectEvent(i, this.at(i)));\n }\n // Set connection status\n this.at(i).connected = true;\n }\n this.at(i).update();\n // Only supported in Chrome\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) {\n continue;\n }\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\n // Add reference to navigator gamepad\n this.at(i).navigatorGamepad = gamepads[i];\n // Buttons\n let b, bi, a, ai, value;\n for (b in Buttons) {\n bi = Buttons[b];\n if (typeof bi === 'number') {\n if (gamepads[i].buttons[bi]) {\n value = gamepads[i].buttons[bi].value;\n if (value !== this._oldPads[i].getButton(bi)) {\n if (gamepads[i].buttons[bi].pressed) {\n this.at(i).updateButton(bi, value);\n this.at(i).events.emit('button', new GamepadButtonEvent(bi, value, this.at(i)));\n }\n else {\n this.at(i).updateButton(bi, 0);\n }\n }\n }\n }\n }\n // Axes\n for (a in Axes) {\n ai = Axes[a];\n if (typeof ai === 'number') {\n value = gamepads[i].axes[ai];\n if (value !== this._oldPads[i].getAxes(ai)) {\n this.at(i).updateAxes(ai, value);\n this.at(i).events.emit('axis', new GamepadAxisEvent(ai, value, this.at(i)));\n }\n }\n }\n this._oldPads[i] = this._clonePad(gamepads[i]);\n }\n }\n /**\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\n */\n at(index) {\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\n if (index >= this._pads.length) {\n // Ensure there is a pad to retrieve\n for (let i = this._pads.length - 1, max = index; i < max; i++) {\n this._pads.push(new Gamepad());\n this._oldPads.push(new Gamepad());\n }\n }\n return this._pads[index];\n }\n /**\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\n */\n getValidGamepads() {\n this._enableAndUpdate();\n const result = [];\n for (let i = 0; i < this._pads.length; i++) {\n if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) {\n result.push(this.at(i));\n }\n }\n return result;\n }\n /**\n * Gets the number of connected gamepads\n */\n count() {\n return this._pads.filter((p) => p.connected).length;\n }\n _clonePads(pads) {\n const arr = [];\n for (let i = 0, len = pads.length; i < len; i++) {\n arr.push(this._clonePad(pads[i]));\n }\n return arr;\n }\n /**\n * Fastest way to clone a known object is to do it yourself\n */\n _clonePad(pad) {\n let i, len;\n const clonedPad = new Gamepad();\n if (!pad) {\n return clonedPad;\n }\n for (i = 0, len = pad.buttons.length; i < len; i++) {\n if (pad.buttons[i]) {\n clonedPad.updateButton(i, pad.buttons[i].value);\n }\n }\n for (i = 0, len = pad.axes.length; i < len; i++) {\n clonedPad.updateAxes(i, pad.axes[i]);\n }\n return clonedPad;\n }\n}\n/**\n * The minimum value an axis has to move before considering it a change\n */\nGamepads.MinAxisMoveThreshold = 0.05;\n/**\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\n * for more information on handling controller input.\n */\nclass Gamepad {\n constructor() {\n this.events = new EventEmitter();\n this.connected = false;\n this._axes = new Array(4);\n this._buttons = new Array(16);\n this._buttonsUp = new Array(16);\n this._buttonsDown = new Array(16);\n for (let i = 0; i < this._buttons.length; i++) {\n this._buttons[i] = 0;\n }\n for (let i = 0; i < this._axes.length; i++) {\n this._axes[i] = 0;\n }\n }\n update() {\n // Reset buttonsDown and buttonsUp after update is complete\n this._buttonsDown = new Array(16);\n this._buttonsUp = new Array(16);\n }\n /**\n * Whether or not the given button is pressed\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\n * @param button The button to query\n * @param threshold The threshold over which the button is considered to be pressed\n */\n isButtonPressed(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\n * Tests if a certain button is held down. This is persisted between frames.\n * @param button The button to query\n * @param threshold The threshold over which the button is considered to be pressed\n */\n isButtonHeld(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\n * @param button Test whether a button was just pressed\n * @param threshold The threshold over which the button is considered to be pressed\n */\n wasButtonPressed(button, threshold = 1) {\n return this._buttonsDown[button] >= threshold;\n }\n /**\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\n * @param button Test whether a button was just released\n */\n wasButtonReleased(button) {\n return Boolean(this._buttonsUp[button]);\n }\n /**\n * Gets the given button value between 0 and 1\n */\n getButton(button) {\n return this._buttons[button];\n }\n /**\n * Gets the given axis value between -1 and 1. Values below\n * [[MinAxisMoveThreshold]] are considered 0.\n */\n getAxes(axes) {\n const value = this._axes[axes];\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) {\n return 0;\n }\n else {\n return value;\n }\n }\n updateButton(buttonIndex, value) {\n // button was just released\n if (value === 0 && this._buttons[buttonIndex]) {\n this._buttonsUp[buttonIndex] = 1;\n // button was just pressed\n }\n else {\n this._buttonsDown[buttonIndex] = value;\n }\n this._buttons[buttonIndex] = value;\n }\n updateAxes(axesIndex, value) {\n this._axes[axesIndex] = value;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n}\n/**\n * Gamepad Buttons enumeration\n */\nvar Buttons;\n(function (Buttons) {\n /**\n * Face 1 button (e.g. A)\n */\n Buttons[Buttons[\"Face1\"] = 0] = \"Face1\";\n /**\n * Face 2 button (e.g. B)\n */\n Buttons[Buttons[\"Face2\"] = 1] = \"Face2\";\n /**\n * Face 3 button (e.g. X)\n */\n Buttons[Buttons[\"Face3\"] = 2] = \"Face3\";\n /**\n * Face 4 button (e.g. Y)\n */\n Buttons[Buttons[\"Face4\"] = 3] = \"Face4\";\n /**\n * Left bumper button\n */\n Buttons[Buttons[\"LeftBumper\"] = 4] = \"LeftBumper\";\n /**\n * Right bumper button\n */\n Buttons[Buttons[\"RightBumper\"] = 5] = \"RightBumper\";\n /**\n * Left trigger button\n */\n Buttons[Buttons[\"LeftTrigger\"] = 6] = \"LeftTrigger\";\n /**\n * Right trigger button\n */\n Buttons[Buttons[\"RightTrigger\"] = 7] = \"RightTrigger\";\n /**\n * Select button\n */\n Buttons[Buttons[\"Select\"] = 8] = \"Select\";\n /**\n * Start button\n */\n Buttons[Buttons[\"Start\"] = 9] = \"Start\";\n /**\n * Left analog stick press (e.g. L3)\n */\n Buttons[Buttons[\"LeftStick\"] = 10] = \"LeftStick\";\n /**\n * Right analog stick press (e.g. R3)\n */\n Buttons[Buttons[\"RightStick\"] = 11] = \"RightStick\";\n /**\n * D-pad up\n */\n Buttons[Buttons[\"DpadUp\"] = 12] = \"DpadUp\";\n /**\n * D-pad down\n */\n Buttons[Buttons[\"DpadDown\"] = 13] = \"DpadDown\";\n /**\n * D-pad left\n */\n Buttons[Buttons[\"DpadLeft\"] = 14] = \"DpadLeft\";\n /**\n * D-pad right\n */\n Buttons[Buttons[\"DpadRight\"] = 15] = \"DpadRight\";\n})(Buttons || (Buttons = {}));\n/**\n * Gamepad Axes enumeration\n */\nvar Axes;\n(function (Axes) {\n /**\n * Left analogue stick X direction\n */\n Axes[Axes[\"LeftStickX\"] = 0] = \"LeftStickX\";\n /**\n * Left analogue stick Y direction\n */\n Axes[Axes[\"LeftStickY\"] = 1] = \"LeftStickY\";\n /**\n * Right analogue stick X direction\n */\n Axes[Axes[\"RightStickX\"] = 2] = \"RightStickX\";\n /**\n * Right analogue stick Y direction\n */\n Axes[Axes[\"RightStickY\"] = 3] = \"RightStickY\";\n})(Axes || (Axes = {}));\n\n;// CONCATENATED MODULE: ./Input/InputMapper.ts\n/**\n * This allows you to map multiple inputs to specific commands! This is especially useful when\n * you need to allow multiple input sources to control a specific action.\n */\nclass InputMapper {\n constructor(inputs) {\n this.inputs = inputs;\n this._handlers = new Map();\n }\n /**\n * Executes the input map, called internally by Excalibur\n */\n execute() {\n for (const [input, command] of this._handlers.entries()) {\n const results = input(this.inputs);\n if (results) {\n command(results);\n }\n }\n }\n /**\n * This allows you to map multiple inputs to specific commands! This is useful\n *\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\n *\n * Example:\n * ```typescript\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\n *\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\n * ```\n * @param inputHandler\n * @param commandHandler\n */\n on(inputHandler, commandHandler) {\n this._handlers.set(inputHandler, commandHandler);\n }\n}\n\n;// CONCATENATED MODULE: ./Util/IFrame.ts\n/**\n * Checks if excalibur is in a x-origin iframe\n */\nfunction isCrossOriginIframe() {\n try {\n // Try and listen to events on top window frame if within an iframe.\n //\n // See https://github.com/excaliburjs/Excalibur/issues/1294\n //\n // Attempt to add an event listener, which triggers a DOMException on\n // cross-origin iframes\n const noop = () => {\n return;\n };\n window.top.addEventListener('blur', noop);\n window.top.removeEventListener('blur', noop);\n }\n catch (_a) {\n return true;\n }\n return false;\n}\n\n;// CONCATENATED MODULE: ./Input/Keyboard.ts\n\n\n\n\n/**\n * Enum representing physical input key codes\n */\nvar Keys;\n(function (Keys) {\n // NUMPAD\n Keys[\"Num0\"] = \"Numpad0\";\n Keys[\"Num1\"] = \"Numpad1\";\n Keys[\"Num2\"] = \"Numpad2\";\n Keys[\"Num3\"] = \"Numpad3\";\n Keys[\"Num4\"] = \"Numpad4\";\n Keys[\"Num5\"] = \"Numpad5\";\n Keys[\"Num6\"] = \"Numpad6\";\n Keys[\"Num7\"] = \"Numpad7\";\n Keys[\"Num8\"] = \"Numpad8\";\n Keys[\"Num9\"] = \"Numpad9\";\n Keys[\"NumAdd\"] = \"NumpadAdd\";\n Keys[\"NumSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumDivide\"] = \"NumpadDivide\";\n // NumComma = 'NumpadComma', // not x-browser\n Keys[\"NumDecimal\"] = \"NumpadDecimal\";\n Keys[\"Numpad0\"] = \"Numpad0\";\n Keys[\"Numpad1\"] = \"Numpad1\";\n Keys[\"Numpad2\"] = \"Numpad2\";\n Keys[\"Numpad3\"] = \"Numpad3\";\n Keys[\"Numpad4\"] = \"Numpad4\";\n Keys[\"Numpad5\"] = \"Numpad5\";\n Keys[\"Numpad6\"] = \"Numpad6\";\n Keys[\"Numpad7\"] = \"Numpad7\";\n Keys[\"Numpad8\"] = \"Numpad8\";\n Keys[\"Numpad9\"] = \"Numpad9\";\n Keys[\"NumpadAdd\"] = \"NumpadAdd\";\n Keys[\"NumpadSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumpadMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumpadDivide\"] = \"NumpadDivide\";\n // NumpadComma = 'NumpadComma', // not x-browser\n Keys[\"NumpadDecimal\"] = \"NumpadDecimal\";\n // MODIFIERS\n Keys[\"NumLock\"] = \"NumLock\";\n Keys[\"ShiftLeft\"] = \"ShiftLeft\";\n Keys[\"ShiftRight\"] = \"ShiftRight\";\n Keys[\"AltLeft\"] = \"AltLeft\";\n Keys[\"AltRight\"] = \"AltRight\";\n Keys[\"ControlLeft\"] = \"ControlLeft\";\n Keys[\"ControlRight\"] = \"ControlRight\";\n Keys[\"MetaLeft\"] = \"MetaLeft\";\n Keys[\"MetaRight\"] = \"MetaRight\";\n // NUMBERS\n Keys[\"Key0\"] = \"Digit0\";\n Keys[\"Key1\"] = \"Digit1\";\n Keys[\"Key2\"] = \"Digit2\";\n Keys[\"Key3\"] = \"Digit3\";\n Keys[\"Key4\"] = \"Digit4\";\n Keys[\"Key5\"] = \"Digit5\";\n Keys[\"Key6\"] = \"Digit6\";\n Keys[\"Key7\"] = \"Digit7\";\n Keys[\"Key8\"] = \"Digit8\";\n Keys[\"Key9\"] = \"Digit9\";\n Keys[\"Digit0\"] = \"Digit0\";\n Keys[\"Digit1\"] = \"Digit1\";\n Keys[\"Digit2\"] = \"Digit2\";\n Keys[\"Digit3\"] = \"Digit3\";\n Keys[\"Digit4\"] = \"Digit4\";\n Keys[\"Digit5\"] = \"Digit5\";\n Keys[\"Digit6\"] = \"Digit6\";\n Keys[\"Digit7\"] = \"Digit7\";\n Keys[\"Digit8\"] = \"Digit8\";\n Keys[\"Digit9\"] = \"Digit9\";\n // FUNCTION KEYS\n Keys[\"F1\"] = \"F1\";\n Keys[\"F2\"] = \"F2\";\n Keys[\"F3\"] = \"F3\";\n Keys[\"F4\"] = \"F4\";\n Keys[\"F5\"] = \"F5\";\n Keys[\"F6\"] = \"F6\";\n Keys[\"F7\"] = \"F7\";\n Keys[\"F8\"] = \"F8\";\n Keys[\"F9\"] = \"F9\";\n Keys[\"F10\"] = \"F10\";\n Keys[\"F11\"] = \"F11\";\n Keys[\"F12\"] = \"F12\";\n // LETTERS\n Keys[\"A\"] = \"KeyA\";\n Keys[\"B\"] = \"KeyB\";\n Keys[\"C\"] = \"KeyC\";\n Keys[\"D\"] = \"KeyD\";\n Keys[\"E\"] = \"KeyE\";\n Keys[\"F\"] = \"KeyF\";\n Keys[\"G\"] = \"KeyG\";\n Keys[\"H\"] = \"KeyH\";\n Keys[\"I\"] = \"KeyI\";\n Keys[\"J\"] = \"KeyJ\";\n Keys[\"K\"] = \"KeyK\";\n Keys[\"L\"] = \"KeyL\";\n Keys[\"M\"] = \"KeyM\";\n Keys[\"N\"] = \"KeyN\";\n Keys[\"O\"] = \"KeyO\";\n Keys[\"P\"] = \"KeyP\";\n Keys[\"Q\"] = \"KeyQ\";\n Keys[\"R\"] = \"KeyR\";\n Keys[\"S\"] = \"KeyS\";\n Keys[\"T\"] = \"KeyT\";\n Keys[\"U\"] = \"KeyU\";\n Keys[\"V\"] = \"KeyV\";\n Keys[\"W\"] = \"KeyW\";\n Keys[\"X\"] = \"KeyX\";\n Keys[\"Y\"] = \"KeyY\";\n Keys[\"Z\"] = \"KeyZ\";\n Keys[\"KeyA\"] = \"KeyA\";\n Keys[\"KeyB\"] = \"KeyB\";\n Keys[\"KeyC\"] = \"KeyC\";\n Keys[\"KeyD\"] = \"KeyD\";\n Keys[\"KeyE\"] = \"KeyE\";\n Keys[\"KeyF\"] = \"KeyF\";\n Keys[\"KeyG\"] = \"KeyG\";\n Keys[\"KeyH\"] = \"KeyH\";\n Keys[\"KeyI\"] = \"KeyI\";\n Keys[\"KeyJ\"] = \"KeyJ\";\n Keys[\"KeyK\"] = \"KeyK\";\n Keys[\"KeyL\"] = \"KeyL\";\n Keys[\"KeyM\"] = \"KeyM\";\n Keys[\"KeyN\"] = \"KeyN\";\n Keys[\"KeyO\"] = \"KeyO\";\n Keys[\"KeyP\"] = \"KeyP\";\n Keys[\"KeyQ\"] = \"KeyQ\";\n Keys[\"KeyR\"] = \"KeyR\";\n Keys[\"KeyS\"] = \"KeyS\";\n Keys[\"KeyT\"] = \"KeyT\";\n Keys[\"KeyU\"] = \"KeyU\";\n Keys[\"KeyV\"] = \"KeyV\";\n Keys[\"KeyW\"] = \"KeyW\";\n Keys[\"KeyX\"] = \"KeyX\";\n Keys[\"KeyY\"] = \"KeyY\";\n Keys[\"KeyZ\"] = \"KeyZ\";\n // SYMBOLS\n Keys[\"Semicolon\"] = \"Semicolon\";\n Keys[\"Quote\"] = \"Quote\";\n Keys[\"Comma\"] = \"Comma\";\n Keys[\"Minus\"] = \"Minus\";\n Keys[\"Period\"] = \"Period\";\n Keys[\"Slash\"] = \"Slash\";\n Keys[\"Equal\"] = \"Equal\";\n Keys[\"BracketLeft\"] = \"BracketLeft\";\n Keys[\"Backslash\"] = \"Backslash\";\n Keys[\"BracketRight\"] = \"BracketRight\";\n Keys[\"Backquote\"] = \"Backquote\";\n // DIRECTIONS\n Keys[\"Up\"] = \"ArrowUp\";\n Keys[\"Down\"] = \"ArrowDown\";\n Keys[\"Left\"] = \"ArrowLeft\";\n Keys[\"Right\"] = \"ArrowRight\";\n Keys[\"ArrowUp\"] = \"ArrowUp\";\n Keys[\"ArrowDown\"] = \"ArrowDown\";\n Keys[\"ArrowLeft\"] = \"ArrowLeft\";\n Keys[\"ArrowRight\"] = \"ArrowRight\";\n // OTHER\n Keys[\"Space\"] = \"Space\";\n Keys[\"Backspace\"] = \"Backspace\";\n Keys[\"Delete\"] = \"Delete\";\n Keys[\"Esc\"] = \"Escape\";\n Keys[\"Escape\"] = \"Escape\";\n Keys[\"Enter\"] = \"Enter\";\n Keys[\"NumpadEnter\"] = \"NumpadEnter\";\n Keys[\"ContextMenu\"] = \"ContextMenu\";\n})(Keys || (Keys = {}));\n/**\n * Event thrown on a game object for a key event\n */\nclass KeyEvent extends GameEvent {\n /**\n * @param key The key responsible for throwing the event\n * @param value The key's typed value the browser detected\n * @param originalEvent The original keyboard event that Excalibur handled\n */\n constructor(key, value, originalEvent) {\n super();\n this.key = key;\n this.value = value;\n this.originalEvent = originalEvent;\n }\n}\nconst KeyEvents = {\n Press: 'press',\n Hold: 'hold',\n Release: 'release'\n};\n/**\n * Provides keyboard support for Excalibur.\n */\nclass Keyboard {\n constructor() {\n this.events = new EventEmitter();\n this._enabled = true;\n /**\n * Keys that are currently held down\n */\n this._keys = [];\n /**\n * Keys up in the current frame\n */\n this._keysUp = [];\n /**\n * Keys down in the current frame\n */\n this._keysDown = [];\n this._releaseAllKeys = (ev) => {\n for (const code of this._keys) {\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit('up', keyEvent);\n this.events.emit('release', keyEvent);\n }\n this._keysUp = Array.from((new Set(this._keys.concat(this._keysUp))));\n this._keys.length = 0;\n };\n this._handleKeyDown = (ev) => {\n if (!this._enabled) {\n return;\n }\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) {\n this._releaseAllKeys(ev);\n }\n const code = ev.code;\n if (this._keys.indexOf(code) === -1) {\n this._keys.push(code);\n this._keysDown.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit('down', keyEvent);\n this.events.emit('press', keyEvent);\n }\n };\n this._handleKeyUp = (ev) => {\n if (!this._enabled) {\n return;\n }\n const code = ev.code;\n const key = this._keys.indexOf(code);\n this._keys.splice(key, 1);\n this._keysUp.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n // alias the old api, we may want to deprecate this in the future\n this.events.emit('up', keyEvent);\n this.events.emit('release', keyEvent);\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (ev.key === 'Meta') {\n this._releaseAllKeys(ev);\n }\n };\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Initialize Keyboard event listeners\n */\n init(keyboardOptions) {\n let { global } = keyboardOptions;\n const { grabWindowFocus } = keyboardOptions;\n if (!global) {\n if (isCrossOriginIframe()) {\n global = window;\n // Workaround for iframes like for itch.io or codesandbox\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\n if (grabWindowFocus) {\n window.focus();\n }\n Logger.getInstance().warn('Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus');\n }\n else {\n global = window.top;\n }\n }\n global.addEventListener('blur', () => {\n this._keys.length = 0; // empties array efficiently\n });\n // key up is on window because canvas cannot have focus\n global.addEventListener('keyup', this._handleKeyUp);\n // key down is on window because canvas cannot have focus\n global.addEventListener('keydown', this._handleKeyDown);\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n update() {\n // Reset keysDown and keysUp after update is complete\n this._keysDown.length = 0;\n this._keysUp.length = 0;\n // Emit synthetic \"hold\" event\n for (let i = 0; i < this._keys.length; i++) {\n this.events.emit('hold', new KeyEvent(this._keys[i]));\n }\n }\n /**\n * Gets list of keys being pressed down\n */\n getKeys() {\n return this._keys;\n }\n /**\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\n * @param key Test whether a key was just pressed\n */\n wasPressed(key) {\n return this._keysDown.indexOf(key) > -1;\n }\n /**\n * Tests if a certain key is held down. This is persisted between frames.\n * @param key Test whether a key is held down\n */\n isHeld(key) {\n return this._keys.indexOf(key) > -1;\n }\n /**\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\n * @param key Test whether a key was just released\n */\n wasReleased(key) {\n return this._keysUp.indexOf(key) > -1;\n }\n /**\n * Trigger a manual key event\n * @param type\n * @param key\n * @param character\n */\n triggerEvent(type, key, character) {\n if (type === 'down') {\n this._handleKeyDown(new KeyboardEvent('keydown', {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n }\n if (type === 'up') {\n this._handleKeyUp(new KeyboardEvent('keyup', {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Math/global-coordinates.ts\n\nclass GlobalCoordinates {\n static fromPagePosition(xOrPos, yOrEngine, engineOrUndefined) {\n let pageX;\n let pageY;\n let pagePos;\n let engine;\n if (arguments.length === 3) {\n pageX = xOrPos;\n pageY = yOrEngine;\n pagePos = new Vector(pageX, pageY);\n engine = engineOrUndefined;\n }\n else {\n pagePos = xOrPos;\n pageX = pagePos.x;\n pageY = pagePos.y;\n engine = yOrEngine;\n }\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\n }\n constructor(worldPos, pagePos, screenPos) {\n this.worldPos = worldPos;\n this.pagePos = pagePos;\n this.screenPos = screenPos;\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerEvent.ts\nclass PointerEvent {\n cancel() {\n this.active = false;\n }\n get pagePos() {\n return this.coordinates.pagePos;\n }\n get screenPos() {\n return this.coordinates.screenPos;\n }\n get worldPos() {\n return this.coordinates.worldPos;\n }\n constructor(type, pointerId, button, pointerType, coordinates, nativeEvent) {\n this.type = type;\n this.pointerId = pointerId;\n this.button = button;\n this.pointerType = pointerType;\n this.coordinates = coordinates;\n this.nativeEvent = nativeEvent;\n this.active = true;\n }\n ;\n}\n\n;// CONCATENATED MODULE: ./Input/WheelEvent.ts\nclass WheelEvent {\n cancel() {\n this.active = false;\n }\n constructor(x, y, pageX, pageY, screenX, screenY, index, deltaX, deltaY, deltaZ, deltaMode, ev) {\n this.x = x;\n this.y = y;\n this.pageX = pageX;\n this.pageY = pageY;\n this.screenX = screenX;\n this.screenY = screenY;\n this.index = index;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.deltaZ = deltaZ;\n this.deltaMode = deltaMode;\n this.ev = ev;\n this.active = true;\n }\n}\n\n;// CONCATENATED MODULE: ./Input/PointerAbstraction.ts\n\n\nclass PointerAbstraction {\n constructor() {\n this.events = new EventEmitter();\n /**\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\n */\n this.lastPagePos = Vector.Zero;\n /**\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\n */\n this.lastScreenPos = Vector.Zero;\n /**\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\n */\n this.lastWorldPos = Vector.Zero;\n this._onPointerMove = (ev) => {\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this._onPointerDown = (ev) => {\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this.on('move', this._onPointerMove);\n this.on('down', this._onPointerDown);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n}\n\n;// CONCATENATED MODULE: ./Input/WheelDeltaMode.ts\nvar WheelDeltaMode;\n(function (WheelDeltaMode) {\n WheelDeltaMode[\"Pixel\"] = \"Pixel\";\n WheelDeltaMode[\"Line\"] = \"Line\";\n WheelDeltaMode[\"Page\"] = \"Page\";\n})(WheelDeltaMode || (WheelDeltaMode = {}));\n\n;// CONCATENATED MODULE: ./Input/NativePointerButton.ts\n/**\n * Native browser button enumeration\n */\nvar NativePointerButton;\n(function (NativePointerButton) {\n NativePointerButton[NativePointerButton[\"NoButton\"] = -1] = \"NoButton\";\n NativePointerButton[NativePointerButton[\"Left\"] = 0] = \"Left\";\n NativePointerButton[NativePointerButton[\"Middle\"] = 1] = \"Middle\";\n NativePointerButton[NativePointerButton[\"Right\"] = 2] = \"Right\";\n NativePointerButton[NativePointerButton[\"Unknown\"] = 3] = \"Unknown\";\n})(NativePointerButton || (NativePointerButton = {}));\n\n;// CONCATENATED MODULE: ./Input/PointerButton.ts\n/**\n * The mouse button being pressed.\n */\nvar PointerButton;\n(function (PointerButton) {\n PointerButton[\"Left\"] = \"Left\";\n PointerButton[\"Middle\"] = \"Middle\";\n PointerButton[\"Right\"] = \"Right\";\n PointerButton[\"Unknown\"] = \"Unknown\";\n PointerButton[\"NoButton\"] = \"NoButton\";\n})(PointerButton || (PointerButton = {}));\n\n;// CONCATENATED MODULE: ./Input/PointerType.ts\n/**\n * The type of pointer for a [[PointerEvent]].\n */\nvar PointerType;\n(function (PointerType) {\n PointerType[\"Touch\"] = \"Touch\";\n PointerType[\"Mouse\"] = \"Mouse\";\n PointerType[\"Pen\"] = \"Pen\";\n PointerType[\"Unknown\"] = \"Unknown\";\n})(PointerType || (PointerType = {}));\n\n;// CONCATENATED MODULE: ./Input/PointerEventReceiver.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst PointerEvents = {\n Move: 'move',\n Down: 'down',\n Up: 'up',\n Wheel: 'wheel'\n};\n/**\n * Is this event a native touch event?\n */\nfunction isTouchEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\n}\n/**\n * Is this event a native pointer event\n */\nfunction isPointerEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\n}\n/**\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\n */\nclass PointerEventReceiver {\n constructor(target, engine) {\n this.target = target;\n this.engine = engine;\n this.events = new EventEmitter();\n this.primary = new PointerAbstraction();\n this._activeNativePointerIdsToNormalized = new Map();\n this.lastFramePointerCoords = new Map();\n this.currentFramePointerCoords = new Map();\n this.currentFramePointerDown = new Map();\n this.lastFramePointerDown = new Map();\n this.currentFrameDown = [];\n this.currentFrameUp = [];\n this.currentFrameMove = [];\n this.currentFrameCancel = [];\n this.currentFrameWheel = [];\n this._enabled = true;\n this._pointers = [this.primary];\n this._boundHandle = this._handle.bind(this);\n this._boundWheel = this._handleWheel.bind(this);\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n }\n /**\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\n * handlers.\n * @param target\n * @param engine\n */\n recreate(target, engine) {\n const eventReceiver = new PointerEventReceiver(target, engine);\n eventReceiver.primary = this.primary;\n eventReceiver._pointers = this._pointers;\n return eventReceiver;\n }\n /**\n * Locates a specific pointer by id, creates it if it doesn't exist\n * @param index\n */\n at(index) {\n if (index >= this._pointers.length) {\n // Ensure there is a pointer to retrieve\n for (let i = this._pointers.length - 1, max = index; i < max; i++) {\n this._pointers.push(new PointerAbstraction());\n }\n }\n return this._pointers[index];\n }\n /**\n * The number of pointers currently being tracked by excalibur\n */\n count() {\n return this._pointers.length;\n }\n /**\n * Is the specified pointer id down this frame\n * @param pointerId\n */\n isDown(pointerId) {\n var _a;\n return (_a = this.currentFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\n * Was the specified pointer id down last frame\n * @param pointerId\n */\n wasDown(pointerId) {\n var _a;\n return (_a = this.lastFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\n * Whether the Pointer is currently dragging.\n */\n isDragging(pointerId) {\n return this.isDown(pointerId);\n }\n /**\n * Whether the Pointer just started dragging.\n */\n isDragStart(pointerId) {\n return this.isDown(pointerId) && !this.wasDown(pointerId);\n }\n /**\n * Whether the Pointer just ended dragging.\n */\n isDragEnd(pointerId) {\n return !this.isDown(pointerId) && this.wasDown(pointerId);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Called internally by excalibur\n *\n * Updates the current frame pointer info and emits raw pointer events\n *\n * This does not emit events to entities, see PointerSystem\n */\n update() {\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\n for (const event of this.currentFrameDown) {\n this.emit('down', event);\n const pointer = this.at(event.pointerId);\n pointer.emit('down', event);\n this.primary.emit('pointerdown', event);\n }\n for (const event of this.currentFrameUp) {\n this.emit('up', event);\n const pointer = this.at(event.pointerId);\n pointer.emit('up', event);\n }\n for (const event of this.currentFrameMove) {\n this.emit('move', event);\n const pointer = this.at(event.pointerId);\n pointer.emit('move', event);\n }\n for (const event of this.currentFrameCancel) {\n this.emit('cancel', event);\n const pointer = this.at(event.pointerId);\n pointer.emit('cancel', event);\n }\n for (const event of this.currentFrameWheel) {\n this.emit('wheel', event);\n this.primary.emit('pointerwheel', event);\n this.primary.emit('wheel', event);\n }\n }\n /**\n * Clears the current frame event and pointer data\n */\n clear() {\n for (const event of this.currentFrameUp) {\n this.currentFramePointerCoords.delete(event.pointerId);\n const ids = this._activeNativePointerIdsToNormalized.entries();\n for (const [native, normalized] of ids) {\n if (normalized === event.pointerId) {\n this._activeNativePointerIdsToNormalized.delete(native);\n }\n }\n }\n this.currentFrameDown.length = 0;\n this.currentFrameUp.length = 0;\n this.currentFrameMove.length = 0;\n this.currentFrameCancel.length = 0;\n this.currentFrameWheel.length = 0;\n }\n /**\n * Initializes the pointer event receiver so that it can start listening to native\n * browser events.\n */\n init(options) {\n var _a;\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\n // It is important on mobile to have touch action 'none'\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\n if (this.target === this.engine.canvas) {\n this.engine.canvas.style.touchAction = 'none';\n }\n else {\n document.body.style.touchAction = 'none';\n }\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.addEventListener('pointerdown', this._boundHandle);\n this.target.addEventListener('pointerup', this._boundHandle);\n this.target.addEventListener('pointermove', this._boundHandle);\n this.target.addEventListener('pointercancel', this._boundHandle);\n }\n else {\n // Touch Events\n this.target.addEventListener('touchstart', this._boundHandle);\n this.target.addEventListener('touchend', this._boundHandle);\n this.target.addEventListener('touchmove', this._boundHandle);\n this.target.addEventListener('touchcancel', this._boundHandle);\n // Mouse Events\n this.target.addEventListener('mousedown', this._boundHandle);\n this.target.addEventListener('mouseup', this._boundHandle);\n this.target.addEventListener('mousemove', this._boundHandle);\n }\n // MDN MouseWheelEvent\n const wheelOptions = {\n passive: !(this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas)\n };\n if ('onwheel' in document.createElement('div')) {\n // Modern Browsers\n this.target.addEventListener('wheel', this._boundWheel, wheelOptions);\n }\n else if (document.onmousewheel !== undefined) {\n // Webkit and IE\n this.target.addEventListener('mousewheel', this._boundWheel, wheelOptions);\n }\n else {\n // Remaining browser and older Firefox\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel, wheelOptions);\n }\n const grabWindowFocus = (_a = options === null || options === void 0 ? void 0 : options.grabWindowFocus) !== null && _a !== void 0 ? _a : true;\n // Handle cross origin iframe\n if (grabWindowFocus && isCrossOriginIframe()) {\n const grabFocus = () => {\n window.focus();\n };\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.addEventListener('pointerdown', grabFocus);\n }\n else {\n // Touch Events\n this.target.addEventListener('touchstart', grabFocus);\n // Mouse Events\n this.target.addEventListener('mousedown', grabFocus);\n }\n }\n }\n detach() {\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.removeEventListener('pointerdown', this._boundHandle);\n this.target.removeEventListener('pointerup', this._boundHandle);\n this.target.removeEventListener('pointermove', this._boundHandle);\n this.target.removeEventListener('pointercancel', this._boundHandle);\n }\n else {\n // Touch Events\n this.target.removeEventListener('touchstart', this._boundHandle);\n this.target.removeEventListener('touchend', this._boundHandle);\n this.target.removeEventListener('touchmove', this._boundHandle);\n this.target.removeEventListener('touchcancel', this._boundHandle);\n // Mouse Events\n this.target.removeEventListener('mousedown', this._boundHandle);\n this.target.removeEventListener('mouseup', this._boundHandle);\n this.target.removeEventListener('mousemove', this._boundHandle);\n }\n if ('onwheel' in document.createElement('div')) {\n // Modern Browsers\n this.target.removeEventListener('wheel', this._boundWheel);\n }\n else if (document.onmousewheel !== undefined) {\n // Webkit and IE\n this.target.addEventListener('mousewheel', this._boundWheel);\n }\n else {\n // Remaining browser and older Firefox\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel);\n }\n }\n /**\n * Take native pointer id and map it to index in active pointers\n * @param nativePointerId\n */\n _normalizePointerId(nativePointerId) {\n // Add to the the native pointer set id\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\n // Native pointer ids in ascending order\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b) => a - b);\n // The index into sorted ids will be the new id, will always have an id\n const id = currentPointerIds.findIndex(p => p === nativePointerId);\n // Save the mapping so we can reverse it later\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\n // ignore pointer because game isn't watching\n return id;\n }\n /**\n * Responsible for handling and parsing pointer events\n */\n _handle(ev) {\n if (!this._enabled) {\n return;\n }\n ev.preventDefault();\n const eventCoords = new Map();\n let button;\n let pointerType;\n if (isTouchEvent(ev)) {\n button = PointerButton.Unknown;\n pointerType = PointerType.Touch;\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\n for (let i = 0; i < ev.changedTouches.length; i++) {\n const touch = ev.changedTouches[i];\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\n const nativePointerId = i + 1;\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n }\n else {\n button = this._nativeButtonToPointerButton(ev.button);\n pointerType = PointerType.Mouse;\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\n let nativePointerId = 1;\n if (isPointerEvent(ev)) {\n nativePointerId = ev.pointerId;\n pointerType = this._stringToPointerType(ev.pointerType);\n }\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n for (const [pointerId, coord] of eventCoords.entries()) {\n switch (ev.type) {\n case 'mousedown':\n case 'pointerdown':\n case 'touchstart':\n this.currentFrameDown.push(new PointerEvent('down', pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, true);\n break;\n case 'mouseup':\n case 'pointerup':\n case 'touchend':\n this.currentFrameUp.push(new PointerEvent('up', pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, false);\n break;\n case 'mousemove':\n case 'pointermove':\n case 'touchmove':\n this.currentFrameMove.push(new PointerEvent('move', pointerId, button, pointerType, coord, ev));\n break;\n case 'touchcancel':\n case 'pointercancel':\n this.currentFrameCancel.push(new PointerEvent('cancel', pointerId, button, pointerType, coord, ev));\n break;\n }\n }\n }\n _handleWheel(ev) {\n if (!this._enabled) {\n return;\n }\n // Should we prevent page scroll because of this event\n if (this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\n (this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas)) {\n ev.preventDefault();\n }\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\n const world = this.engine.screen.screenToWorldCoordinates(screen);\n /**\n * A constant used to normalize wheel events across different browsers\n *\n * This normalization factor is pulled from\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\n */\n const ScrollWheelNormalizationFactor = -1 / 40;\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\n const deltaY = ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\n const deltaZ = ev.deltaZ || 0;\n let deltaMode = WheelDeltaMode.Pixel;\n if (ev.deltaMode) {\n if (ev.deltaMode === 1) {\n deltaMode = WheelDeltaMode.Line;\n }\n else if (ev.deltaMode === 2) {\n deltaMode = WheelDeltaMode.Page;\n }\n }\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\n this.currentFrameWheel.push(we);\n }\n /**\n * Triggers an excalibur pointer event in a world space pos\n *\n * Useful for testing pointers in excalibur\n * @param type\n * @param pos\n */\n triggerEvent(type, pos) {\n const page = this.engine.screen.worldToPageCoordinates(pos);\n // Send an event to the event receiver\n if (window.PointerEvent) {\n this._handle(new window.PointerEvent('pointer' + type, {\n pointerId: 0,\n clientX: page.x,\n clientY: page.y\n }));\n }\n else {\n // Safari hack\n this._handle(new window.MouseEvent('mouse' + type, {\n clientX: page.x,\n clientY: page.y\n }));\n }\n // Force update pointer system\n const pointerSystem = this.engine.currentScene.world.get(PointerSystem);\n pointerSystem.preupdate(this.engine.currentScene, 1);\n pointerSystem.update(1);\n }\n _nativeButtonToPointerButton(s) {\n switch (s) {\n case NativePointerButton.NoButton:\n return PointerButton.NoButton;\n case NativePointerButton.Left:\n return PointerButton.Left;\n case NativePointerButton.Middle:\n return PointerButton.Middle;\n case NativePointerButton.Right:\n return PointerButton.Right;\n case NativePointerButton.Unknown:\n return PointerButton.Unknown;\n default:\n return fail(s);\n }\n }\n _stringToPointerType(s) {\n switch (s) {\n case 'touch':\n return PointerType.Touch;\n case 'mouse':\n return PointerType.Mouse;\n case 'pen':\n return PointerType.Pen;\n default:\n return PointerType.Unknown;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Input/InputHost.ts\n\n\n\n\nclass InputHost {\n constructor(options) {\n this._enabled = true;\n const { pointerTarget, grabWindowFocus, engine } = options;\n this.keyboard = new Keyboard();\n this.pointers = new PointerEventReceiver(pointerTarget, engine);\n this.gamepads = new Gamepads();\n this.keyboard.init({ grabWindowFocus });\n this.pointers.init({ grabWindowFocus });\n this.gamepads.init();\n this.inputMapper = new InputMapper({\n keyboard: this.keyboard,\n pointers: this.pointers,\n gamepads: this.gamepads\n });\n }\n get enabled() {\n return this._enabled;\n }\n toggleEnabled(enabled) {\n this._enabled = enabled;\n this.keyboard.toggleEnabled(this._enabled);\n this.pointers.toggleEnabled(this._enabled);\n this.gamepads.toggleEnabled(this._enabled);\n }\n update() {\n if (this._enabled) {\n this.inputMapper.execute();\n this.keyboard.update();\n this.gamepads.update();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Scene.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nclass PreLoadEvent {\n}\nconst SceneEvents = {\n Initialize: 'initialize',\n Activate: 'activate',\n Deactivate: 'deactivate',\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate',\n PreDraw: 'predraw',\n PostDraw: 'postdraw',\n PreDebugDraw: 'predebugdraw',\n PostDebugDraw: 'postdebugdraw',\n PreLoad: 'preload'\n};\n/**\n *\n */\nfunction isSceneConstructor(x) {\n var _a, _b;\n return !!(x === null || x === void 0 ? void 0 : x.prototype) && !!((_b = (_a = x === null || x === void 0 ? void 0 : x.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);\n}\n/**\n * [[Actor|Actors]] are composed together into groupings called Scenes in\n * Excalibur. The metaphor models the same idea behind real world\n * actors in a scene. Only actors in scenes will be updated and drawn.\n *\n * Typical usages of a scene include: levels, menus, loading screens, etc.\n */\nclass Scene {\n /**\n * The actors in the current scene\n */\n get actors() {\n return this.world.entityManager.entities.filter((e) => {\n return e instanceof Actor;\n });\n }\n /**\n * The entities in the current scene\n */\n get entities() {\n return this.world.entityManager.entities;\n }\n /**\n * The triggers in the current scene\n */\n get triggers() {\n return this.world.entityManager.entities.filter((e) => {\n return e instanceof Trigger;\n });\n }\n /**\n * The [[TileMap]]s in the scene, if any\n */\n get tileMaps() {\n return this.world.entityManager.entities.filter((e) => {\n return e instanceof TileMap;\n });\n }\n get timers() {\n return this._timers;\n }\n constructor() {\n // Initialize systems\n this._logger = Logger.getInstance();\n this.events = new EventEmitter();\n /**\n * Gets or sets the current camera for the scene\n */\n this.camera = new Camera();\n /**\n * The ECS world for the scene\n */\n this.world = new World(this);\n /**\n * The Excalibur physics world for the scene. Used to interact\n * with colliders included in the scene.\n *\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\n */\n this.physics = new PhysicsWorld(DefaultPhysicsConfig);\n this._isInitialized = false;\n this._timers = [];\n this._cancelQueue = [];\n // Update\n this.world.add(ActionsSystem);\n this.world.add(new MotionSystem(this.world, this.physics));\n this.world.add(new CollisionSystem(this.world, this.physics));\n this.world.add(PointerSystem);\n this.world.add(IsometricEntitySystem);\n // Draw\n this.world.add(OffscreenSystem);\n this.world.add(GraphicsSystem);\n this.world.add(DebugSystem);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Event hook to provide Scenes a way of loading scene specific resources.\n *\n * This is called before the Scene.onInitialize during scene transition. It will only ever fire once for a scene.\n * @param loader\n */\n onPreLoad(loader) {\n // will be overridden\n }\n /**\n * Event hook fired directly before transition, either \"in\" or \"out\" of the scene\n *\n * This overrides the Engine scene definition. However transitions specified in goToScene take highest precedence\n *\n * ```typescript\n * // Overrides all\n * Engine.goToScene('scene', { destinationIn: ..., sourceOut: ... });\n * ```\n *\n * This can be used to configure custom transitions for a scene dynamically\n */\n onTransition(direction) {\n // will be overridden\n return undefined;\n }\n /**\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\n * overridden. This is where initialization of child actors should take place.\n */\n onInitialize(engine) {\n // will be overridden\n }\n /**\n * This is called when the scene is made active and started. It is meant to be overridden,\n * this is where you should setup any DOM UI or event handlers needed for the scene.\n */\n onActivate(context) {\n // will be overridden\n }\n /**\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\n */\n onDeactivate(context) {\n // will be overridden\n }\n /**\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreUpdate` is called directly before a scene is updated.\n */\n onPreUpdate(engine, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostUpdate` is called directly after a scene is updated.\n */\n onPostUpdate(engine, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPreDraw` is called directly before a scene is drawn.\n *\n */\n onPreDraw(ctx, delta) {\n // will be overridden\n }\n /**\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\n *\n * `onPostDraw` is called directly after a scene is drawn.\n *\n */\n onPostDraw(ctx, delta) {\n // will be overridden\n }\n /**\n * Initializes actors in the scene\n */\n _initializeChildren() {\n for (const child of this.entities) {\n child._initialize(this.engine);\n }\n }\n /**\n * Gets whether or not the [[Scene]] has been initialized\n */\n get isInitialized() {\n return this._isInitialized;\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Initializes the scene before the first update, meant to be called by engine not by users of\n * Excalibur\n * @internal\n */\n async _initialize(engine) {\n var _a;\n if (!this.isInitialized) {\n try {\n this.engine = engine;\n // PhysicsWorld config is watched so things will automagically update\n this.physics.config = this.engine.physics;\n this.input = new InputHost({\n pointerTarget: engine.pointerScope === PointerScope.Canvas ? engine.canvas : document,\n grabWindowFocus: engine.grabWindowFocus,\n engine\n });\n // Initialize camera first\n this.camera._initialize(engine);\n this.world.systemManager.initialize();\n // This order is important! we want to be sure any custom init that add actors\n // fire before the actor init\n await this.onInitialize(engine);\n this._initializeChildren();\n this._logger.debug('Scene.onInitialize', this, engine);\n this.events.emit('initialize', new InitializeEvent(engine, this));\n }\n catch (e) {\n this._logger.error(`Error during scene initialization for scene ${(_a = engine.director) === null || _a === void 0 ? void 0 : _a.getSceneName(this)}!`);\n throw e;\n }\n this._isInitialized = true;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\n * @internal\n */\n async _activate(context) {\n var _a, _b;\n try {\n this._logger.debug('Scene.onActivate', this);\n this.input.toggleEnabled(true);\n await this.onActivate(context);\n }\n catch (e) {\n this._logger.error(`Error during scene activation for scene ${(_b = (_a = this.engine) === null || _a === void 0 ? void 0 : _a.director) === null || _b === void 0 ? void 0 : _b.getSceneName(this)}!`);\n throw e;\n }\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\n * @internal\n */\n async _deactivate(context) {\n this._logger.debug('Scene.onDeactivate', this);\n this.input.toggleEnabled(false);\n await this.onDeactivate(context);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\n * @internal\n */\n _preupdate(engine, delta) {\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\n * @internal\n */\n _postupdate(engine, delta) {\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\n * @internal\n */\n _predraw(ctx, delta) {\n this.emit('predraw', new PreDrawEvent(ctx, delta, this));\n this.onPreDraw(ctx, delta);\n }\n /**\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\n *\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\n * @internal\n */\n _postdraw(ctx, delta) {\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\n this.onPostDraw(ctx, delta);\n }\n /**\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\n * @param engine Reference to the current Engine\n * @param delta The number of milliseconds since the last update\n */\n update(engine, delta) {\n var _a;\n if (!this.isInitialized) {\n this._logger.warnOnce(`Scene update called before initialize for scene ${(_a = engine.director) === null || _a === void 0 ? void 0 : _a.getSceneName(this)}!`);\n return;\n }\n this._preupdate(engine, delta);\n // TODO differed entity removal for timers\n let i, len;\n // Remove timers in the cancel queue before updating them\n for (i = 0, len = this._cancelQueue.length; i < len; i++) {\n this.removeTimer(this._cancelQueue[i]);\n }\n this._cancelQueue.length = 0;\n // Cycle through timers updating timers\n for (const timer of this._timers) {\n timer.update(delta);\n }\n this.world.update(SystemType.Update, delta);\n // Camera last keeps renders smooth that are based on entity/actor\n if (this.camera) {\n this.camera.update(engine, delta);\n }\n this._collectActorStats(engine);\n this._postupdate(engine, delta);\n this.input.update();\n }\n /**\n * Draws all the actors in the Scene. Called by the [[Engine]].\n * @param ctx The current rendering context\n * @param delta The number of milliseconds since the last draw\n */\n draw(ctx, delta) {\n var _a;\n if (!this.isInitialized) {\n this._logger.warnOnce(`Scene draw called before initialize!`);\n return;\n }\n this._predraw(ctx, delta);\n this.world.update(SystemType.Draw, delta);\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.isDebug) {\n this.debugDraw(ctx);\n }\n this._postdraw(ctx, delta);\n }\n /**\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\n * @param ctx The current rendering context\n */\n /* istanbul ignore next */\n debugDraw(ctx) {\n this.emit('predebugdraw', new PreDebugDrawEvent(ctx, this));\n // pass\n this.emit('postdebugdraw', new PostDebugDrawEvent(ctx, this));\n }\n /**\n * Checks whether an actor is contained in this scene or not\n */\n contains(actor) {\n return this.actors.indexOf(actor) > -1;\n }\n add(entity) {\n this.emit('entityadded', { target: entity });\n this.world.add(entity);\n entity.scene = this;\n if (entity instanceof Timer) {\n if (!contains(this._timers, entity)) {\n this.addTimer(entity);\n }\n return;\n }\n }\n /**\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\n * and adds it to this scene.\n *\n * Useful if you want to have an object be present in only 1 scene at a time.\n * @param entity\n */\n transfer(entity) {\n let scene;\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\n scene = entity.scene;\n entity.scene.world.remove(entity, false);\n }\n if (entity instanceof Timer && entity.scene) {\n scene = entity.scene;\n entity.scene.removeTimer(entity);\n }\n scene === null || scene === void 0 ? void 0 : scene.emit('entityremoved', { target: entity });\n this.add(entity);\n }\n remove(entity) {\n if (entity instanceof Entity) {\n this.emit('entityremoved', { target: entity });\n if (entity.active) {\n entity.kill();\n }\n this.world.remove(entity);\n }\n if (entity instanceof Timer) {\n this.removeTimer(entity);\n }\n }\n /**\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\n *\n * By default entities use deferred removal\n * @param deferred\n */\n clear(deferred = true) {\n for (let i = this.entities.length - 1; i >= 0; i--) {\n this.world.remove(this.entities[i], deferred);\n }\n for (let i = this.timers.length - 1; i >= 0; i--) {\n this.removeTimer(this.timers[i]);\n }\n }\n /**\n * Adds a [[Timer]] to the scene\n * @param timer The timer to add\n */\n addTimer(timer) {\n this._timers.push(timer);\n timer.scene = this;\n return timer;\n }\n /**\n * Removes a [[Timer]] from the scene.\n * @warning Can be dangerous, use [[cancelTimer]] instead\n * @param timer The timer to remove\n */\n removeTimer(timer) {\n const i = this._timers.indexOf(timer);\n if (i !== -1) {\n this._timers.splice(i, 1);\n }\n return timer;\n }\n /**\n * Cancels a [[Timer]], removing it from the scene nicely\n * @param timer The timer to cancel\n */\n cancelTimer(timer) {\n this._cancelQueue.push(timer);\n return timer;\n }\n /**\n * Tests whether a [[Timer]] is active in the scene\n */\n isTimerActive(timer) {\n return this._timers.indexOf(timer) > -1 && !timer.complete;\n }\n isCurrentScene() {\n if (this.engine) {\n return this.engine.currentScene === this;\n }\n return false;\n }\n _collectActorStats(engine) {\n const screenElements = this.actors.filter((a) => a instanceof ScreenElement);\n for (const _ui of screenElements) {\n engine.stats.currFrame.actors.ui++;\n }\n for (const actor of this.actors) {\n engine.stats.currFrame.actors.alive++;\n for (const child of actor.children) {\n if (isScreenElement(child)) {\n // TODO not true\n engine.stats.currFrame.actors.ui++;\n }\n else {\n engine.stats.currFrame.actors.alive++;\n }\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ColorBlindnessMode.ts\nvar ColorBlindnessMode;\n(function (ColorBlindnessMode) {\n ColorBlindnessMode[\"Protanope\"] = \"Protanope\";\n ColorBlindnessMode[\"Deuteranope\"] = \"Deuteranope\";\n ColorBlindnessMode[\"Tritanope\"] = \"Tritanope\";\n})(ColorBlindnessMode || (ColorBlindnessMode = {}));\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/color-blind-fragment.glsl\n/* harmony default export */ const color_blind_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ScreenShader.ts\n\n\n\n/**\n * Helper that defines a whole screen renderer, just provide a fragment source!\n *\n * Currently supports 1 varying\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\n */\nclass ScreenShader {\n constructor(gl, fragmentSource) {\n this._shader = new Shader({\n gl,\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\n fragmentSource: fragmentSource\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl,\n type: 'static',\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1, -1, 0, 0,\n -1, 1, 0, 1,\n 1, -1, 1, 0,\n 1, -1, 1, 0,\n -1, 1, 0, 1,\n 1, 1, 1, 1\n ])\n });\n this._layout = new VertexLayout({\n gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n ['a_position', 2],\n ['a_texcoord', 2]\n ]\n });\n this._buffer.upload();\n }\n getShader() {\n return this._shader;\n }\n getLayout() {\n return this._layout;\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ColorBlindnessPostProcessor.ts\n\n\n\nclass ColorBlindnessPostProcessor {\n constructor(_colorBlindnessMode, simulate = false) {\n this._colorBlindnessMode = _colorBlindnessMode;\n this._simulate = false;\n this._simulate = simulate;\n }\n initialize(gl) {\n this._shader = new ScreenShader(gl, color_blind_fragment);\n this.simulate = this._simulate;\n this.colorBlindnessMode = this._colorBlindnessMode;\n }\n getShader() {\n return this._shader.getShader();\n }\n getLayout() {\n return this._shader.getLayout();\n }\n set colorBlindnessMode(colorBlindMode) {\n this._colorBlindnessMode = colorBlindMode;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) {\n shader.setUniformInt('u_type', 0);\n }\n else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) {\n shader.setUniformInt('u_type', 1);\n }\n else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) {\n shader.setUniformInt('u_type', 2);\n }\n }\n }\n get colorBlindnessMode() {\n return this._colorBlindnessMode;\n }\n set simulate(value) {\n this._simulate = value;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n shader.setUniformBoolean('u_simulate', value);\n }\n }\n get simulate() {\n return this._simulate;\n }\n}\n\n;// CONCATENATED MODULE: ./Debug/DebugFlags.ts\n\n\n\nclass ColorBlindFlags {\n constructor(engine) {\n this._engine = engine;\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\n }\n /**\n * Correct colors for a specified color blindness\n * @param colorBlindness\n */\n correct(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = false;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Simulate colors for a specified color blindness\n * @param colorBlindness\n */\n simulate(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = true;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\n * Remove color blindness post processor\n */\n clear() {\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\n }\n}\n\n;// CONCATENATED MODULE: ./Debug/DebugConfig.ts\n\n\n/**\n * Debug statistics and flags for Excalibur. If polling these values, it would be\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\n * updated during a frame.\n */\nclass DebugConfig {\n constructor(engine) {\n /**\n * Performance statistics\n */\n this.stats = {\n /**\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\n * Best accessed on [[postframe]] event. See [[FrameStats]]\n */\n currFrame: new FrameStats(),\n /**\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\n */\n prevFrame: new FrameStats()\n };\n /**\n * Filter debug context to named entities or entity ids\n */\n this.filter = {\n /**\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\n */\n useFilter: false,\n /**\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\n */\n nameQuery: '',\n /**\n * Query for Entity ids, if the id matches it will be included\n */\n ids: []\n };\n /**\n * Entity debug settings\n */\n this.entity = {\n showAll: false,\n showId: false,\n showName: false\n };\n /**\n * Transform component debug settings\n */\n this.transform = {\n showAll: false,\n debugZIndex: 10000000,\n showPosition: false,\n showPositionLabel: false,\n positionColor: Color.Yellow,\n showZIndex: false,\n showScale: false,\n scaleColor: Color.Green,\n showRotation: false,\n rotationColor: Color.Blue\n };\n /**\n * Graphics component debug settings\n */\n this.graphics = {\n showAll: false,\n showBounds: false,\n boundsColor: Color.Yellow\n };\n /**\n * Collider component debug settings\n */\n this.collider = {\n showAll: false,\n showBounds: false,\n boundsColor: Color.Blue,\n showOwner: false,\n showGeometry: true,\n geometryColor: Color.Green,\n geometryLineWidth: 1,\n geometryPointSize: .5\n };\n /**\n * Physics simulation debug settings\n */\n this.physics = {\n showAll: false,\n showBroadphaseSpacePartitionDebug: false,\n showCollisionNormals: false,\n collisionNormalColor: Color.Cyan,\n showCollisionContacts: true,\n contactSize: 2,\n collisionContactColor: Color.Red\n };\n /**\n * Motion component debug settings\n */\n this.motion = {\n showAll: false,\n showVelocity: false,\n velocityColor: Color.Yellow,\n showAcceleration: false,\n accelerationColor: Color.Red\n };\n /**\n * Body component debug settings\n */\n this.body = {\n showAll: false,\n showCollisionGroup: false,\n showCollisionType: false,\n showSleeping: false,\n showMotion: false,\n showMass: false\n };\n /**\n * Camera debug settings\n */\n this.camera = {\n showAll: false,\n showFocus: false,\n focusColor: Color.Red,\n showZoom: false\n };\n this.tilemap = {\n showAll: false,\n showGrid: false,\n gridColor: Color.Red,\n gridWidth: .5,\n showSolidBounds: false,\n solidBoundsColor: Color.fromHex('#8080807F'), // grayish\n showColliderGeometry: true\n };\n this.isometric = {\n showAll: false,\n showPosition: false,\n positionColor: Color.Yellow,\n positionSize: 1,\n showGrid: false,\n gridColor: Color.Red,\n gridWidth: 1,\n showColliderGeometry: true\n };\n this._engine = engine;\n this.colorBlindMode = new ColorBlindFlags(this._engine);\n }\n /**\n * Switch the current excalibur clock with the [[TestClock]] and return\n * it in the same running state.\n *\n * This is useful when you need to debug frame by frame.\n */\n useTestClock() {\n const clock = this._engine.clock;\n const wasRunning = clock.isRunning();\n clock.stop();\n const testClock = clock.toTestClock();\n if (wasRunning) {\n testClock.start();\n }\n this._engine.clock = testClock;\n return testClock;\n }\n /**\n * Switch the current excalibur clock with the [[StandardClock]] and\n * return it in the same running state.\n *\n * This is useful when you need to switch back to normal mode after\n * debugging.\n */\n useStandardClock() {\n const currentClock = this._engine.clock;\n const wasRunning = currentClock.isRunning();\n currentClock.stop();\n const standardClock = currentClock.toStandardClock();\n if (wasRunning) {\n standardClock.start();\n }\n this._engine.clock = standardClock;\n return standardClock;\n }\n}\n/**\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\n * creating instances of this every frame.\n */\nclass FrameStats {\n constructor() {\n this._id = 0;\n this._delta = 0;\n this._fps = 0;\n this._actorStats = {\n alive: 0,\n killed: 0,\n ui: 0,\n get remaining() {\n return this.alive - this.killed;\n },\n get total() {\n return this.remaining + this.ui;\n }\n };\n this._durationStats = {\n update: 0,\n draw: 0,\n get total() {\n return this.update + this.draw;\n }\n };\n this._physicsStats = new PhysicsStats();\n this._graphicsStats = {\n drawCalls: 0,\n drawnImages: 0\n };\n }\n /**\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\n * @param [otherStats] Optional stats to clone\n */\n reset(otherStats) {\n if (otherStats) {\n this.id = otherStats.id;\n this.delta = otherStats.delta;\n this.fps = otherStats.fps;\n this.actors.alive = otherStats.actors.alive;\n this.actors.killed = otherStats.actors.killed;\n this.actors.ui = otherStats.actors.ui;\n this.duration.update = otherStats.duration.update;\n this.duration.draw = otherStats.duration.draw;\n this._physicsStats.reset(otherStats.physics);\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\n }\n else {\n this.id = this.delta = this.fps = 0;\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\n this.duration.update = this.duration.draw = 0;\n this._physicsStats.reset();\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\n }\n }\n /**\n * Provides a clone of this instance.\n */\n clone() {\n const fs = new FrameStats();\n fs.reset(this);\n return fs;\n }\n /**\n * Gets the frame's id\n */\n get id() {\n return this._id;\n }\n /**\n * Sets the frame's id\n */\n set id(value) {\n this._id = value;\n }\n /**\n * Gets the frame's delta (time since last frame)\n */\n get delta() {\n return this._delta;\n }\n /**\n * Sets the frame's delta (time since last frame). Internal use only.\n * @internal\n */\n set delta(value) {\n this._delta = value;\n }\n /**\n * Gets the frame's frames-per-second (FPS)\n */\n get fps() {\n return this._fps;\n }\n /**\n * Sets the frame's frames-per-second (FPS). Internal use only.\n * @internal\n */\n set fps(value) {\n this._fps = value;\n }\n /**\n * Gets the frame's actor statistics\n */\n get actors() {\n return this._actorStats;\n }\n /**\n * Gets the frame's duration statistics\n */\n get duration() {\n return this._durationStats;\n }\n /**\n * Gets the frame's physics statistics\n */\n get physics() {\n return this._physicsStats;\n }\n /**\n * Gets the frame's graphics statistics\n */\n get graphics() {\n return this._graphicsStats;\n }\n}\nclass PhysicsStats {\n constructor() {\n this._pairs = 0;\n this._collisions = 0;\n this._contacts = new Map();\n this._fastBodies = 0;\n this._fastBodyCollisions = 0;\n this._broadphase = 0;\n this._narrowphase = 0;\n }\n /**\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\n * @param [otherStats] Optional stats to clone\n */\n reset(otherStats) {\n if (otherStats) {\n this.pairs = otherStats.pairs;\n this.collisions = otherStats.collisions;\n this.contacts = otherStats.contacts;\n this.fastBodies = otherStats.fastBodies;\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\n this.broadphase = otherStats.broadphase;\n this.narrowphase = otherStats.narrowphase;\n }\n else {\n this.pairs = this.collisions = this.fastBodies = 0;\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\n this.contacts.clear();\n }\n }\n /**\n * Provides a clone of this instance.\n */\n clone() {\n const ps = new PhysicsStats();\n ps.reset(this);\n return ps;\n }\n get pairs() {\n return this._pairs;\n }\n set pairs(value) {\n this._pairs = value;\n }\n get collisions() {\n return this._collisions;\n }\n set collisions(value) {\n this._collisions = value;\n }\n get contacts() {\n return this._contacts;\n }\n set contacts(contacts) {\n this._contacts = contacts;\n }\n get fastBodies() {\n return this._fastBodies;\n }\n set fastBodies(value) {\n this._fastBodies = value;\n }\n get fastBodyCollisions() {\n return this._fastBodyCollisions;\n }\n set fastBodyCollisions(value) {\n this._fastBodyCollisions = value;\n }\n get broadphase() {\n return this._broadphase;\n }\n set broadphase(value) {\n this._broadphase = value;\n }\n get narrowphase() {\n return this._narrowphase;\n }\n set narrowphase(value) {\n this._narrowphase = value;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Browser.ts\nclass BrowserComponent {\n on(eventName, handler) {\n if (this._nativeHandlers[eventName]) {\n this.off(eventName, this._nativeHandlers[eventName]);\n }\n this._nativeHandlers[eventName] = this._decorate(handler);\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\n }\n off(eventName, handler) {\n if (!handler) {\n handler = this._nativeHandlers[eventName];\n }\n this.nativeComponent.removeEventListener(eventName, handler);\n this._nativeHandlers[eventName] = null;\n }\n _decorate(handler) {\n return (evt) => {\n if (!this._paused) {\n handler(evt);\n }\n };\n }\n pause() {\n this._paused = true;\n }\n resume() {\n this._paused = false;\n }\n clear() {\n for (const event in this._nativeHandlers) {\n this.off(event);\n }\n }\n constructor(nativeComponent) {\n this.nativeComponent = nativeComponent;\n this._paused = false;\n this._nativeHandlers = {};\n }\n}\nclass BrowserEvents {\n constructor(_windowGlobal, _documentGlobal) {\n this._windowGlobal = _windowGlobal;\n this._documentGlobal = _documentGlobal;\n this._windowComponent = new BrowserComponent(this._windowGlobal);\n this._documentComponent = new BrowserComponent(this._documentGlobal);\n }\n get window() {\n return this._windowComponent;\n }\n get document() {\n return this._documentComponent;\n }\n pause() {\n this.window.pause();\n this.document.pause();\n }\n resume() {\n this.window.resume();\n this.document.resume();\n }\n clear() {\n this.window.clear();\n this.document.clear();\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Context/ExcaliburGraphicsContext.ts\n\nconst DefaultAntialiasOptions = {\n pixelArtSampler: false,\n nativeContextAntialiasing: false,\n multiSampleAntialiasing: true,\n filtering: ImageFiltering.Blended,\n canvasImageRendering: 'auto'\n};\nconst DefaultPixelArtOptions = {\n pixelArtSampler: true,\n nativeContextAntialiasing: false,\n multiSampleAntialiasing: true,\n filtering: ImageFiltering.Blended,\n canvasImageRendering: 'auto'\n};\n\n;// CONCATENATED MODULE: ./Util/Fps.ts\nclass FpsSampler {\n constructor(options) {\n var _a;\n this._samplePeriod = 100;\n this._currentFrameTime = 0;\n this._frames = 0;\n this._previousSampleTime = 0;\n this._beginFrameTime = 0;\n this._fps = options.initialFps;\n this._samplePeriod = (_a = options.samplePeriod) !== null && _a !== void 0 ? _a : this._samplePeriod;\n this._currentFrameTime = 1000 / options.initialFps;\n this._nowFn = options.nowFn;\n this._previousSampleTime = this._nowFn();\n }\n /**\n * Start of code block to sample FPS for\n */\n start() {\n this._beginFrameTime = this._nowFn();\n }\n /**\n * End of code block to sample FPS for\n */\n end() {\n this._frames++;\n const time = this._nowFn();\n this._currentFrameTime = time - this._beginFrameTime;\n if (time >= this._previousSampleTime + this._samplePeriod) {\n this._fps = (this._frames * 1000) / (time - this._previousSampleTime);\n this._previousSampleTime = time;\n this._frames = 0;\n }\n }\n /**\n * Return the currently sampled fps over the last sample period, by default every 100ms\n */\n get fps() {\n return this._fps;\n }\n /**\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\n */\n get instant() {\n return 1000 / this._currentFrameTime;\n }\n}\n\n;// CONCATENATED MODULE: ./Util/Clock.ts\n\n\n/**\n * Abstract Clock is the base type of all Clocks\n *\n * It has a few opinions\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\n * 2. The default timing api is implemented in now()\n *\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\n * method is unique to your clock implementation.\n */\nclass Clock {\n constructor(options) {\n var _a, _b, _c;\n this._onFatalException = () => { };\n this._maxFps = Infinity;\n this._lastTime = 0;\n this._elapsed = 1;\n this._scheduledCbs = [];\n this._totalElapsed = 0;\n this._options = options;\n this.tick = options.tick;\n this._lastTime = (_a = this.now()) !== null && _a !== void 0 ? _a : 0;\n this._maxFps = (_b = options.maxFps) !== null && _b !== void 0 ? _b : this._maxFps;\n this._onFatalException = (_c = options.onFatalException) !== null && _c !== void 0 ? _c : this._onFatalException;\n this.fpsSampler = new FpsSampler({\n initialFps: 60,\n nowFn: () => this.now()\n });\n }\n /**\n * Get the elapsed time for the last completed frame\n */\n elapsed() {\n return this._elapsed;\n }\n /**\n * Get the current time in milliseconds\n */\n now() {\n return performance.now();\n }\n toTestClock() {\n const testClock = new TestClock({\n ...this._options,\n defaultUpdateMs: 16.6\n });\n return testClock;\n }\n toStandardClock() {\n const clock = new StandardClock({\n ...this._options\n });\n return clock;\n }\n setFatalExceptionHandler(handler) {\n this._onFatalException = handler;\n }\n /**\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\n *\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\n * stopped or paused.\n * @param cb callback to fire\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\n */\n schedule(cb, timeoutMs = 0) {\n // Scheduled based on internal elapsed time\n const scheduledTime = this._totalElapsed + timeoutMs;\n this._scheduledCbs.push([cb, scheduledTime]);\n }\n _runScheduledCbs() {\n // walk backwards to delete items as we loop\n for (let i = this._scheduledCbs.length - 1; i > -1; i--) {\n if (this._scheduledCbs[i][1] <= this._totalElapsed) {\n this._scheduledCbs[i][0](this._elapsed);\n this._scheduledCbs.splice(i, 1);\n }\n }\n }\n update(overrideUpdateMs) {\n try {\n this.fpsSampler.start();\n // Get the time to calculate time-elapsed\n const now = this.now();\n let elapsed = now - this._lastTime || 1; // first frame\n // Constrain fps\n const fpsInterval = (1000 / this._maxFps);\n // only run frame if enough time has elapsed\n if (elapsed >= fpsInterval) {\n let leftover = 0;\n if (fpsInterval !== 0) {\n leftover = (elapsed % fpsInterval);\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\n }\n // Resolves issue #138 if the game has been paused, or blurred for\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\n // and provides more expected behavior when the engine comes back\n // into focus\n if (elapsed > 200) {\n elapsed = 1;\n }\n // tick the mainloop and run scheduled callbacks\n this._elapsed = overrideUpdateMs || elapsed;\n this._totalElapsed += this._elapsed;\n this._runScheduledCbs();\n this.tick(overrideUpdateMs || elapsed);\n if (fpsInterval !== 0) {\n this._lastTime = now - leftover;\n }\n else {\n this._lastTime = now;\n }\n this.fpsSampler.end();\n }\n }\n catch (e) {\n this._onFatalException(e);\n this.stop();\n }\n }\n}\n/**\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\n */\nclass StandardClock extends Clock {\n constructor(options) {\n super(options);\n this._running = false;\n }\n isRunning() {\n return this._running;\n }\n start() {\n if (this._running) {\n return;\n }\n this._running = true;\n const mainloop = () => {\n // stop the loop\n if (!this._running) {\n return;\n }\n try {\n // request next loop\n this._requestId = window.requestAnimationFrame(mainloop);\n this.update();\n }\n catch (e) {\n window.cancelAnimationFrame(this._requestId);\n throw e;\n }\n };\n // begin the first frame\n mainloop();\n }\n stop() {\n window.cancelAnimationFrame(this._requestId);\n this._running = false;\n }\n}\n/**\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\n */\nclass TestClock extends Clock {\n constructor(options) {\n super({\n ...options\n });\n this._logger = Logger.getInstance();\n this._running = false;\n this._currentTime = 0;\n this._updateMs = options.defaultUpdateMs;\n }\n /**\n * Get the current time in milliseconds\n */\n now() {\n var _a;\n return (_a = this._currentTime) !== null && _a !== void 0 ? _a : 0;\n }\n isRunning() {\n return this._running;\n }\n start() {\n this._running = true;\n }\n stop() {\n this._running = false;\n }\n /**\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\n * @param overrideUpdateMs\n */\n step(overrideUpdateMs) {\n const time = overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs;\n if (this._running) {\n // to be comparable to RAF this needs to be a full blown Task\n // For example, images cannot decode synchronously in a single step\n this.update(time);\n this._currentTime += time;\n }\n else {\n this._logger.warn('The clock is not running, no step will be performed');\n }\n }\n /**\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\n * @param numberOfSteps\n * @param overrideUpdateMs\n */\n run(numberOfSteps, overrideUpdateMs) {\n for (let i = 0; i < numberOfSteps; i++) {\n this.step(overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs);\n }\n }\n}\n\n// EXTERNAL MODULE: ./Util/Toaster.css\nvar Util_Toaster = __webpack_require__(7379);\n;// CONCATENATED MODULE: ./Util/Toaster.ts\n\n/**\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\n */\nclass Toaster {\n constructor() {\n this._toasterCss = Util_Toaster/* default */.Z.toString();\n this._isInitialized = false;\n }\n _initialize() {\n if (!this._isInitialized) {\n this._container = document.createElement('div');\n this._container.id = 'ex-toast-container';\n document.body.appendChild(this._container);\n this._isInitialized = true;\n this._styleBlock = document.createElement('style');\n this._styleBlock.textContent = this._toasterCss;\n document.head.appendChild(this._styleBlock);\n }\n }\n dispose() {\n this._container.parentElement.removeChild(this._container);\n this._styleBlock.parentElement.removeChild(this._styleBlock);\n this._isInitialized = false;\n }\n _createFragment(message) {\n const toastMessage = document.createElement('span');\n toastMessage.innerText = message;\n return toastMessage;\n }\n /**\n * Display a toast message to a player\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\n * @param linkTarget Optionally specify a link location\n * @param linkName Optionally specify a name for that link location\n */\n toast(message, linkTarget, linkName) {\n this._initialize();\n const toast = document.createElement('div');\n toast.className = 'ex-toast-message';\n const messageFragments = message.split('[LINK]').map(message => this._createFragment(message));\n if (linkTarget) {\n const link = document.createElement('a');\n link.href = linkTarget;\n if (linkName) {\n link.innerText = linkName;\n }\n else {\n link.innerText = linkTarget;\n }\n messageFragments.splice(1, 0, link);\n }\n // Assembly message\n const finalMessage = document.createElement('div');\n messageFragments.forEach(message => {\n finalMessage.appendChild(message);\n });\n toast.appendChild(finalMessage);\n // Dismiss button\n const dismissBtn = document.createElement('button');\n dismissBtn.innerText = 'x';\n dismissBtn.addEventListener('click', () => {\n this._container.removeChild(toast);\n });\n toast.appendChild(dismissBtn);\n // Escape to dismiss\n const keydownHandler = (evt) => {\n if (evt.key === 'Escape') {\n try {\n this._container.removeChild(toast);\n }\n catch (_a) {\n // pass\n }\n }\n document.removeEventListener('keydown', keydownHandler);\n };\n document.addEventListener('keydown', keydownHandler);\n // Insert into container\n const first = this._container.firstChild;\n this._container.insertBefore(toast, first);\n }\n}\n\n;// CONCATENATED MODULE: ./Director/Director.ts\n\n\n\n\n\n\nconst DirectorEvents = {\n NavigationStart: 'navigationstart',\n Navigation: 'navigation',\n NavigationEnd: 'navigationend'\n};\n/**\n * The Director is responsible for managing scenes and changing scenes in Excalibur.\n *\n * It deals with transitions, scene loaders, switching scenes\n *\n * This is used internally by Excalibur, generally not mean to\n * be instantiated end users directly.\n */\nclass Director {\n /**\n * Gets whether the director currently transitioning between scenes\n *\n * Useful if you need to block behavior during transition\n */\n get isTransitioning() {\n return this._isTransitioning;\n }\n constructor(_engine, scenes) {\n this._engine = _engine;\n this.events = new EventEmitter();\n this._logger = Logger.getInstance();\n this._initialized = false;\n /**\n * All registered scenes in Excalibur\n */\n this.scenes = {};\n /**\n * Holds all instantiated scenes\n */\n this._sceneToInstance = new Map();\n this._sceneToLoader = new Map();\n this._sceneToTransition = new Map();\n /**\n * Used to keep track of scenes that have already been loaded so we don't load multiple times\n */\n this._loadedScenes = new Set();\n this._isTransitioning = false;\n this.rootScene = this.currentScene = new Scene();\n this.add('root', this.rootScene);\n this.currentScene = this.rootScene;\n this.currentSceneName = 'root';\n for (const sceneKey in scenes) {\n const sceneOrOptions = scenes[sceneKey];\n this.add(sceneKey, sceneOrOptions);\n if (sceneKey === 'root') {\n this.rootScene = this.getSceneInstance('root');\n this.currentScene = this.rootScene;\n }\n }\n }\n /**\n * Initialize the director's internal state\n */\n async onInitialize() {\n if (!this._initialized) {\n this._initialized = true;\n if (this._deferredGoto) {\n const deferredScene = this._deferredGoto;\n this._deferredGoto = null;\n await this.swapScene(deferredScene);\n }\n else {\n await this.swapScene('root');\n }\n }\n }\n get isInitialized() {\n return this._initialized;\n }\n /**\n * Configures the start scene, and optionally the transition & loader for the director\n *\n * Typically this is called at the beginning of the game to the start scene and transition and never again.\n * @param startScene\n * @param options\n */\n configureStart(startScene, options) {\n const maybeLoaderOrCtor = options === null || options === void 0 ? void 0 : options.loader;\n if (maybeLoaderOrCtor instanceof DefaultLoader) {\n this.mainLoader = maybeLoaderOrCtor;\n }\n else if (isLoaderConstructor(maybeLoaderOrCtor)) {\n this.mainLoader = new maybeLoaderOrCtor();\n }\n else {\n this.mainLoader = new Loader();\n }\n let maybeStartTransition;\n if (options) {\n const { inTransition } = options;\n maybeStartTransition = inTransition;\n }\n this.startScene = startScene;\n // Fire and forget promise for the initial scene\n if (maybeStartTransition) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.swapScene(this.startScene);\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.playTransition(maybeStartTransition);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.swapScene(this.startScene);\n }\n this.currentSceneName = this.startScene;\n }\n _getLoader(sceneName) {\n return this._sceneToLoader.get(sceneName);\n }\n _getInTransition(sceneName) {\n var _a;\n const sceneOrRoute = this.scenes[sceneName];\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) {\n return null;\n }\n return (_a = sceneOrRoute === null || sceneOrRoute === void 0 ? void 0 : sceneOrRoute.transitions) === null || _a === void 0 ? void 0 : _a.in;\n }\n _getOutTransition(sceneName) {\n var _a;\n const sceneOrRoute = this.scenes[sceneName];\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) {\n return null;\n }\n return (_a = sceneOrRoute === null || sceneOrRoute === void 0 ? void 0 : sceneOrRoute.transitions) === null || _a === void 0 ? void 0 : _a.out;\n }\n getDeferredScene() {\n const maybeDeferred = this.getSceneDefinition(this._deferredGoto);\n if (this._deferredGoto && maybeDeferred) {\n return maybeDeferred;\n }\n return null;\n }\n /**\n * Returns a scene by name if it exists, might be the constructor and not the instance of a scene\n * @param name\n */\n getSceneDefinition(name) {\n const maybeScene = this.scenes[name];\n if (maybeScene instanceof Scene || isSceneConstructor(maybeScene)) {\n return maybeScene;\n }\n else if (maybeScene) {\n return maybeScene.scene;\n }\n return undefined;\n }\n getSceneName(scene) {\n for (const [name, sceneInstance] of this._sceneToInstance) {\n if (scene === sceneInstance) {\n return name;\n }\n }\n return 'unknown scene name';\n }\n /**\n * Returns the same Director, but asserts a scene DOES exist to the type system\n * @param name\n */\n assertAdded(name) {\n return this;\n }\n /**\n * Returns the same Director, but asserts a scene DOES NOT exist to the type system\n * @param name\n */\n assertRemoved(name) {\n return this;\n }\n /**\n * Adds additional Scenes to the game!\n * @param name\n * @param sceneOrRoute\n */\n add(name, sceneOrRoute) {\n if (!(sceneOrRoute instanceof Scene) && !(isSceneConstructor(sceneOrRoute))) {\n const { loader, transitions } = sceneOrRoute;\n const { in: inTransition, out: outTransition } = transitions !== null && transitions !== void 0 ? transitions : {};\n this._sceneToTransition.set(name, { in: inTransition, out: outTransition });\n if (isLoaderConstructor(loader)) {\n this._sceneToLoader.set(name, new loader());\n }\n else {\n this._sceneToLoader.set(name, loader);\n }\n }\n if (this.scenes[name]) {\n this._logger.warn('Scene', name, 'already exists overwriting');\n }\n this.scenes[name] = sceneOrRoute;\n return this.assertAdded(name);\n }\n remove(nameOrScene) {\n if (nameOrScene instanceof Scene || isSceneConstructor(nameOrScene)) {\n const sceneOrCtor = nameOrScene;\n // remove scene\n for (const key in this.scenes) {\n if (this.scenes.hasOwnProperty(key)) {\n const potentialSceneOrOptions = this.scenes[key];\n let scene;\n if (potentialSceneOrOptions instanceof Scene || isSceneConstructor(potentialSceneOrOptions)) {\n scene = potentialSceneOrOptions;\n }\n else {\n scene = potentialSceneOrOptions.scene;\n }\n if (scene === sceneOrCtor) {\n if (key === this.currentSceneName) {\n throw new Error(`Cannot remove a currently active scene: ${key}`);\n }\n this._sceneToTransition.delete(key);\n this._sceneToLoader.delete(key);\n delete this.scenes[key];\n }\n }\n }\n }\n if (typeof nameOrScene === 'string') {\n if (nameOrScene === this.currentSceneName) {\n throw new Error(`Cannot remove a currently active scene: ${nameOrScene}`);\n }\n // remove scene\n this._sceneToTransition.delete(nameOrScene);\n this._sceneToLoader.delete(nameOrScene);\n delete this.scenes[nameOrScene];\n }\n }\n /**\n * Go to a specific scene, and optionally override loaders and transitions\n * @param destinationScene\n * @param options\n */\n async goto(destinationScene, options) {\n var _a, _b, _c, _d, _e, _f;\n const maybeDest = this.getSceneInstance(destinationScene);\n if (!maybeDest) {\n this._logger.warn(`Scene ${destinationScene} does not exist! Check the name, are you sure you added it?`);\n return;\n }\n const sourceScene = this.currentSceneName;\n const engineInputEnabled = (_b = (_a = this._engine.input) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;\n this._isTransitioning = true;\n const maybeSourceOut = (_c = this.getSceneInstance(sourceScene)) === null || _c === void 0 ? void 0 : _c.onTransition('out');\n const maybeDestinationIn = maybeDest === null || maybeDest === void 0 ? void 0 : maybeDest.onTransition('in');\n options = {\n // Engine configuration then dynamic scene transitions\n ...{ sourceOut: (_d = this._getOutTransition(this.currentSceneName)) !== null && _d !== void 0 ? _d : maybeSourceOut },\n ...{ destinationIn: (_e = this._getInTransition(destinationScene)) !== null && _e !== void 0 ? _e : maybeDestinationIn },\n // Goto options\n ...options\n };\n const { sourceOut, destinationIn, sceneActivationData } = options;\n const outTransition = sourceOut !== null && sourceOut !== void 0 ? sourceOut : this._getOutTransition(this.currentSceneName);\n const inTransition = destinationIn !== null && destinationIn !== void 0 ? destinationIn : this._getInTransition(destinationScene);\n const hideLoader = (outTransition === null || outTransition === void 0 ? void 0 : outTransition.hideLoader) || (inTransition === null || inTransition === void 0 ? void 0 : inTransition.hideLoader);\n if (hideLoader) {\n // Start hidden loader early and take advantage of the transition\n // Don't await and block on a hidden loader\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.maybeLoadScene(destinationScene, hideLoader);\n }\n this._emitEvent('navigationstart', sourceScene, destinationScene);\n // Run the out transition on the current scene if present\n await this.playTransition(outTransition);\n // Run the loader if present\n await this.maybeLoadScene(destinationScene, hideLoader);\n // Give incoming transition a chance to grab info from previous\n await (inTransition === null || inTransition === void 0 ? void 0 : inTransition.onPreviousSceneDeactivate(this.currentScene));\n // Swap to the new scene\n await this.swapScene(destinationScene, sceneActivationData);\n this._emitEvent('navigation', sourceScene, destinationScene);\n // Run the in transition on the new scene if present\n await this.playTransition(inTransition);\n this._emitEvent('navigationend', sourceScene, destinationScene);\n (_f = this._engine.input) === null || _f === void 0 ? void 0 : _f.toggleEnabled(engineInputEnabled);\n this._isTransitioning = false;\n }\n /**\n * Retrieves a scene instance by key if it's registered.\n *\n * This will call any constructors that were given as a definition\n * @param scene\n */\n getSceneInstance(scene) {\n const sceneDefinition = this.getSceneDefinition(scene);\n if (!sceneDefinition) {\n return undefined;\n }\n if (this._sceneToInstance.has(scene)) {\n return this._sceneToInstance.get(scene);\n }\n if (sceneDefinition instanceof Scene) {\n this._sceneToInstance.set(scene, sceneDefinition);\n return sceneDefinition;\n }\n const newScene = new sceneDefinition();\n this._sceneToInstance.set(scene, newScene);\n return newScene;\n }\n /**\n * Triggers scene loading if has not already been loaded\n * @param scene\n * @param hideLoader\n */\n async maybeLoadScene(scene, hideLoader = false) {\n var _a;\n const loader = (_a = this._getLoader(scene)) !== null && _a !== void 0 ? _a : new DefaultLoader();\n const sceneToLoad = this.getSceneDefinition(scene);\n const sceneToLoadInstance = this.getSceneInstance(scene);\n if (sceneToLoad && sceneToLoadInstance && !this._loadedScenes.has(sceneToLoadInstance)) {\n sceneToLoadInstance.onPreLoad(loader);\n sceneToLoadInstance.events.emit('preload', { loader });\n if (hideLoader) {\n // Don't await a hidden loader\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this._engine.load(loader, hideLoader);\n }\n else {\n await this._engine.load(loader);\n }\n this._loadedScenes.add(sceneToLoadInstance);\n }\n }\n /**\n * Plays a transition in the current scene\n * @param transition\n */\n async playTransition(transition) {\n var _a, _b, _c, _d, _e, _f, _g;\n if (transition) {\n this.currentTransition = transition;\n const currentScene = this._engine.currentScene;\n const sceneInputEnabled = (_b = (_a = currentScene.input) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;\n (_c = currentScene.input) === null || _c === void 0 ? void 0 : _c.toggleEnabled(!transition.blockInput);\n (_d = this._engine.input) === null || _d === void 0 ? void 0 : _d.toggleEnabled(!transition.blockInput);\n await this.currentTransition.play(this._engine);\n (_e = currentScene.input) === null || _e === void 0 ? void 0 : _e.toggleEnabled(sceneInputEnabled);\n }\n (_f = this.currentTransition) === null || _f === void 0 ? void 0 : _f.kill();\n (_g = this.currentTransition) === null || _g === void 0 ? void 0 : _g.reset();\n this.currentTransition = null;\n }\n /**\n * Swaps the current and destination scene after performing required lifecycle events\n * @param destinationScene\n * @param data\n */\n async swapScene(destinationScene, data) {\n const engine = this._engine;\n // if not yet initialized defer goToScene\n if (!this.isInitialized) {\n this._deferredGoto = destinationScene;\n return;\n }\n const maybeDest = this.getSceneInstance(destinationScene);\n if (maybeDest) {\n const previousScene = this.currentScene;\n const nextScene = maybeDest;\n this._logger.debug('Going to scene:', destinationScene);\n // only deactivate when initialized\n if (this.currentScene.isInitialized) {\n const context = { engine, previousScene, nextScene };\n await this.currentScene._deactivate(context);\n this.currentScene.events.emit('deactivate', new DeactivateEvent(context, this.currentScene));\n }\n // wait for the scene to be loaded if needed\n const destLoader = this._sceneToLoader.get(destinationScene);\n await (destLoader === null || destLoader === void 0 ? void 0 : destLoader.areResourcesLoaded());\n // set current scene to new one\n this.currentScene = nextScene;\n this.currentSceneName = destinationScene;\n engine.screen.setCurrentCamera(nextScene.camera);\n // initialize the current scene if has not been already\n await this.currentScene._initialize(engine);\n const context = { engine, previousScene, nextScene, data };\n await this.currentScene._activate(context);\n this.currentScene.events.emit('activate', new ActivateEvent(context, this.currentScene));\n }\n else {\n this._logger.error('Scene', destinationScene, 'does not exist!');\n }\n }\n _emitEvent(eventName, sourceScene, destinationScene) {\n const source = this.getSceneDefinition(sourceScene);\n const dest = this.getSceneDefinition(destinationScene);\n this.events.emit(eventName, {\n sourceScene: source,\n sourceName: sourceScene,\n destinationScene: dest,\n destinationName: destinationScene\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Engine.ts\n\n\n\n\n\n\npolyfill();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst EngineEvents = {\n FallbackGraphicsContext: 'fallbackgraphicscontext',\n Initialize: 'initialize',\n Visible: 'visible',\n Hidden: 'hidden',\n Start: 'start',\n Stop: 'stop',\n PreUpdate: 'preupdate',\n PostUpdate: 'postupdate',\n PreFrame: 'preframe',\n PostFrame: 'postframe',\n PreDraw: 'predraw',\n PostDraw: 'postdraw'\n};\n/**\n * Enum representing the different mousewheel event bubble prevention\n */\nvar ScrollPreventionMode;\n(function (ScrollPreventionMode) {\n /**\n * Do not prevent any page scrolling\n */\n ScrollPreventionMode[ScrollPreventionMode[\"None\"] = 0] = \"None\";\n /**\n * Prevent page scroll if mouse is over the game canvas\n */\n ScrollPreventionMode[ScrollPreventionMode[\"Canvas\"] = 1] = \"Canvas\";\n /**\n * Prevent all page scrolling via mouse wheel\n */\n ScrollPreventionMode[ScrollPreventionMode[\"All\"] = 2] = \"All\";\n})(ScrollPreventionMode || (ScrollPreventionMode = {}));\n/**\n * The Excalibur Engine\n *\n * The [[Engine]] is the main driver for a game. It is responsible for\n * starting/stopping the game, maintaining state, transmitting events,\n * loading resources, and managing the scene.\n */\nclass Engine {\n /**\n * The width of the game canvas in pixels (physical width component of the\n * resolution of the canvas element)\n */\n get canvasWidth() {\n return this.screen.canvasWidth;\n }\n /**\n * Returns half width of the game canvas in pixels (half physical width component)\n */\n get halfCanvasWidth() {\n return this.screen.halfCanvasWidth;\n }\n /**\n * The height of the game canvas in pixels, (physical height component of\n * the resolution of the canvas element)\n */\n get canvasHeight() {\n return this.screen.canvasHeight;\n }\n /**\n * Returns half height of the game canvas in pixels (half physical height component)\n */\n get halfCanvasHeight() {\n return this.screen.halfCanvasHeight;\n }\n /**\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get drawWidth() {\n return this.screen.drawWidth;\n }\n /**\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get halfDrawWidth() {\n return this.screen.halfDrawWidth;\n }\n /**\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get drawHeight() {\n return this.screen.drawHeight;\n }\n /**\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\n */\n get halfDrawHeight() {\n return this.screen.halfDrawHeight;\n }\n /**\n * Returns whether excalibur detects the current screen to be HiDPI\n */\n get isHiDpi() {\n return this.screen.isHiDpi;\n }\n /**\n * Access [[stats]] that holds frame statistics.\n */\n get stats() {\n return this.debug.stats;\n }\n /**\n * The current [[Scene]] being drawn and updated on screen\n */\n get currentScene() {\n return this.director.currentScene;\n }\n /**\n * The current [[Scene]] being drawn and updated on screen\n */\n get currentSceneName() {\n return this.director.currentSceneName;\n }\n /**\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\n */\n get rootScene() {\n return this.director.rootScene;\n }\n /**\n * Contains all the scenes currently registered with Excalibur\n */\n get scenes() {\n return this.director.scenes;\n }\n ;\n /**\n * Indicates whether the engine is set to fullscreen or not\n */\n get isFullscreen() {\n return this.screen.isFullScreen;\n }\n /**\n * Indicates the current [[DisplayMode]] of the engine.\n */\n get displayMode() {\n return this.screen.displayMode;\n }\n /**\n * Returns the calculated pixel ration for use in rendering\n */\n get pixelRatio() {\n return this.screen.pixelRatio;\n }\n get isDebug() {\n return this._isDebug;\n }\n /**\n * Hints the graphics context to truncate fractional world space coordinates\n */\n get snapToPixel() {\n return this.graphicsContext.snapToPixel;\n }\n ;\n set snapToPixel(shouldSnapToPixel) {\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\n }\n ;\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\n * the game will be rendered full screen (taking up all available browser window space).\n * You can customize the game rendering through [[EngineOptions]].\n *\n * Example:\n *\n * ```js\n * var game = new ex.Engine({\n * width: 0, // the width of the canvas\n * height: 0, // the height of the canvas\n * enableCanvasTransparency: true, // the transparencySection of the canvas\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\n * });\n *\n * // call game.start, which is a Promise\n * game.start().then(function () {\n * // ready, set, go!\n * });\n * ```\n */\n constructor(options) {\n var _a, _b, _c, _d, _e, _f, _g;\n /**\n * Current Excalibur version string\n *\n * Useful for plugins or other tools that need to know what features are available\n */\n this.version = EX_VERSION;\n /**\n * Listen to and emit events on the Engine\n */\n this.events = new EventEmitter();\n /**\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\n *\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\n * one that bounces between 30fps and 60fps\n */\n this.maxFps = Number.POSITIVE_INFINITY;\n this._inputEnabled = true;\n this._suppressPlayButton = false;\n /**\n * Indicates whether audio should be paused when the game is no longer visible.\n */\n this.pauseAudioWhenHidden = true;\n /**\n * Indicates whether the engine should draw with debug information\n */\n this._isDebug = false;\n /**\n * Sets the Transparency for the engine.\n */\n this.enableCanvasTransparency = true;\n /**\n * The action to take when a fatal exception is thrown\n */\n this.onFatalException = (e) => {\n Logger.getInstance().fatal(e, e.stack);\n };\n this._toaster = new Toaster();\n this._timescale = 1.0;\n this._isInitialized = false;\n this._originalOptions = {};\n this._performanceThresholdTriggered = false;\n this._fpsSamples = [];\n this._disposed = false;\n this._isLoading = false;\n this._hideLoader = false;\n this._isReadyFuture = new Future();\n /**\n * Returns the current frames elapsed milliseconds\n */\n this.currentFrameElapsedMs = 0;\n /**\n * Returns the current frame lag when in fixed update mode\n */\n this.currentFrameLagMs = 0;\n this._lagMs = 0;\n this._screenShotRequests = [];\n options = { ...Engine._DEFAULT_ENGINE_OPTIONS, ...options };\n this._originalOptions = options;\n Flags.freeze();\n // Initialize browser events facade\n this.browser = new BrowserEvents(window, document);\n // Check compatibility\n const detector = new Detector();\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\n const message = document.createElement('div');\n message.innerText = 'Sorry, your browser does not support all the features needed for Excalibur';\n document.body.appendChild(message);\n detector.failedTests.forEach(function (test) {\n const testMessage = document.createElement('div');\n testMessage.innerText = 'Browser feature missing ' + test;\n document.body.appendChild(testMessage);\n });\n if (options.canvasElementId) {\n const canvas = document.getElementById(options.canvasElementId);\n if (canvas) {\n canvas.parentElement.removeChild(canvas);\n }\n }\n return;\n }\n else {\n this._compatible = true;\n }\n // Use native console API for color fun\n // eslint-disable-next-line no-console\n if (console.log && !options.suppressConsoleBootMessage) {\n // eslint-disable-next-line no-console\n console.log(`%cPowered by Excalibur.js (v${EX_VERSION})`, 'background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;');\n // eslint-disable-next-line no-console\n console.log('\\n\\\r\n /| ________________\\n\\\r\nO|===|* >________________>\\n\\\r\n \\\\|');\n // eslint-disable-next-line no-console\n console.log('Visit', 'http://excaliburjs.com', 'for more information');\n }\n // Suppress play button\n if (options.suppressPlayButton) {\n this._suppressPlayButton = true;\n }\n this._logger = Logger.getInstance();\n // If debug is enabled, let's log browser features to the console.\n if (this._logger.defaultLevel === LogLevel.Debug) {\n detector.logBrowserFeatures();\n }\n this._logger.debug('Building engine...');\n this.canvasElementId = options.canvasElementId;\n if (options.canvasElementId) {\n this._logger.debug('Using Canvas element specified: ' + options.canvasElementId);\n //test for existence of element\n if (document.getElementById(options.canvasElementId) === null) {\n throw new Error('Cannot find existing element in the DOM, please ensure element is created prior to engine creation.');\n }\n this.canvas = document.getElementById(options.canvasElementId);\n }\n else if (options.canvasElement) {\n this._logger.debug('Using Canvas element specified:', options.canvasElement);\n this.canvas = options.canvasElement;\n }\n else {\n this._logger.debug('Using generated canvas element');\n this.canvas = document.createElement('canvas');\n }\n let displayMode = (_a = options.displayMode) !== null && _a !== void 0 ? _a : DisplayMode.Fixed;\n if ((options.width && options.height) || options.viewport) {\n if (options.displayMode === undefined) {\n displayMode = DisplayMode.Fixed;\n }\n this._logger.debug('Engine viewport is size ' + options.width + ' x ' + options.height);\n }\n else if (!options.displayMode) {\n this._logger.debug('Engine viewport is fit');\n displayMode = DisplayMode.FitScreen;\n }\n this._originalDisplayMode = displayMode;\n let pixelArtSampler;\n let uvPadding;\n let nativeContextAntialiasing;\n let canvasImageRendering;\n let filtering;\n let multiSampleAntialiasing;\n if (typeof options.antialiasing === 'object') {\n ({\n pixelArtSampler,\n nativeContextAntialiasing,\n multiSampleAntialiasing,\n filtering,\n canvasImageRendering\n } = {\n ...(options.pixelArt ? DefaultPixelArtOptions : DefaultAntialiasOptions),\n ...options.antialiasing\n });\n }\n else {\n pixelArtSampler = !!options.pixelArt;\n nativeContextAntialiasing = false;\n multiSampleAntialiasing = options.antialiasing;\n canvasImageRendering = options.antialiasing ? 'auto' : 'pixelated';\n filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\n }\n if (nativeContextAntialiasing && multiSampleAntialiasing) {\n this._logger.warnOnce(`Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing` +\n ` at the same time, they are incompatible settings. If you aren\\'t sure use multiSampleAntialiasing`);\n }\n if (options.pixelArt) {\n uvPadding = .25;\n }\n if (!options.antialiasing || filtering === ImageFiltering.Pixel) {\n uvPadding = 0;\n }\n // Override with any user option, if non default to .25 for pixel art, 0.01 for everything else\n uvPadding = (_c = (_b = options.uvPadding) !== null && _b !== void 0 ? _b : uvPadding) !== null && _c !== void 0 ? _c : 0.01;\n // Canvas 2D fallback can be flagged on\n let useCanvasGraphicsContext = Flags.isEnabled('use-canvas-context');\n if (!useCanvasGraphicsContext) {\n // Attempt webgl first\n try {\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n pixelArtSampler: pixelArtSampler,\n antialiasing: nativeContextAntialiasing,\n multiSampleAntialiasing: multiSampleAntialiasing,\n uvPadding: uvPadding,\n powerPreference: options.powerPreference,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n }\n catch (e) {\n this._logger.warn(`Excalibur could not load webgl for some reason (${e.message}) and loaded a Canvas 2D fallback. ` +\n `Some features of Excalibur will not work in this mode. \\n\\n` +\n 'Read more about this issue at https://excaliburjs.com/docs/webgl');\n // fallback to canvas in case of failure\n useCanvasGraphicsContext = true;\n }\n }\n if (useCanvasGraphicsContext) {\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n antialiasing: nativeContextAntialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n }\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: nativeContextAntialiasing,\n canvasImageRendering: canvasImageRendering,\n browser: this.browser,\n viewport: (_d = options.viewport) !== null && _d !== void 0 ? _d : (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\n resolution: options.resolution,\n displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : ((_e = options.pixelRatio) !== null && _e !== void 0 ? _e : null)\n });\n // TODO REMOVE STATIC!!!\n // Set default filtering based on antialiasing\n TextureLoader.filtering = filtering;\n if (options.backgroundColor) {\n this.backgroundColor = options.backgroundColor.clone();\n }\n this.grabWindowFocus = options.grabWindowFocus;\n this.pointerScope = options.pointerScope;\n this.maxFps = (_f = options.maxFps) !== null && _f !== void 0 ? _f : this.maxFps;\n this.fixedUpdateFps = (_g = options.fixedUpdateFps) !== null && _g !== void 0 ? _g : this.fixedUpdateFps;\n this.clock = new StandardClock({\n maxFps: this.maxFps,\n tick: this._mainloop.bind(this),\n onFatalException: (e) => this.onFatalException(e)\n });\n this.enableCanvasTransparency = options.enableCanvasTransparency;\n if (typeof options.physics === 'boolean') {\n this.physics = {\n ...DefaultPhysicsConfig,\n ...DeprecatedStaticToConfig(),\n enabled: options.physics\n };\n }\n else {\n this.physics = {\n ...DefaultPhysicsConfig,\n ...DeprecatedStaticToConfig(),\n ...options.physics\n };\n }\n this.debug = new DebugConfig(this);\n this.director = new Director(this, options.scenes);\n this._initialize(options);\n window.___EXCALIBUR_DEVTOOL = this;\n }\n _monitorPerformanceThresholdAndTriggerFallback() {\n const { allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\n let { threshold, showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\n if (threshold === undefined) {\n threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\n }\n if (showPlayerMessage === undefined) {\n showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\n }\n if (!Flags.isEnabled('use-canvas-context') && allow && this.ready && !this._performanceThresholdTriggered) {\n // Calculate Average fps for last X number of frames after start\n if (this._fpsSamples.length === threshold.numberOfFrames) {\n this._fpsSamples.splice(0, 1);\n }\n this._fpsSamples.push(this.clock.fpsSampler.fps);\n let total = 0;\n for (let i = 0; i < this._fpsSamples.length; i++) {\n total += this._fpsSamples[i];\n }\n const average = total / this._fpsSamples.length;\n if (this._fpsSamples.length === threshold.numberOfFrames) {\n if (average <= threshold.fps) {\n this._performanceThresholdTriggered = true;\n this._logger.warn(`Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` +\n 'this might mean your browser doesn\\'t have webgl enabled or hardware acceleration is unavailable.\\n\\n' +\n 'If in Chrome:\\n' +\n ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n' +\n ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' +\n 'If in Firefox, visit about:config\\n' +\n ' * Ensure webgl.disabled = false\\n' +\n ' * Ensure webgl.force-enabled = true\\n' +\n ' * Ensure layers.acceleration.force-enabled = true\\n\\n' +\n 'Read more about this issue at https://excaliburjs.com/docs/performance');\n if (showPlayerMessage) {\n this._toaster.toast('Excalibur is encountering performance issues. ' +\n 'It\\'s possible that your browser doesn\\'t have hardware acceleration enabled. ' +\n 'Visit [LINK] for more information and potential solutions.', 'https://excaliburjs.com/docs/performance');\n }\n this.useCanvas2DFallback();\n this.emit('fallbackgraphicscontext', this.graphicsContext);\n }\n }\n }\n }\n /**\n * Switches the engine's graphics context to the 2D Canvas.\n * @warning Some features of Excalibur will not work in this mode.\n */\n useCanvas2DFallback() {\n var _a, _b, _c;\n // Swap out the canvas\n const newCanvas = this.canvas.cloneNode(false);\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\n this.canvas = newCanvas;\n const options = { ...this._originalOptions, antialiasing: this.getAntialiasing() };\n const displayMode = this._originalDisplayMode;\n // New graphics context\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n antialiasing: options.antialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n // Reset screen\n if (this.screen) {\n this.screen.dispose();\n }\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: (_a = options.antialiasing) !== null && _a !== void 0 ? _a : true,\n browser: this.browser,\n viewport: (_b = options.viewport) !== null && _b !== void 0 ? _b : (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\n resolution: options.resolution,\n displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : ((_c = options.pixelRatio) !== null && _c !== void 0 ? _c : null)\n });\n this.screen.setCurrentCamera(this.currentScene.camera);\n // Reset pointers\n this.input.pointers.detach();\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\n this.input.pointers.init();\n }\n /**\n * Attempts to completely clean up excalibur resources, including removing the canvas from the dom.\n *\n * To start again you will need to new up an Engine.\n */\n dispose() {\n if (!this._disposed) {\n this._disposed = true;\n this.stop();\n this.input.toggleEnabled(false);\n this.canvas.parentNode.removeChild(this.canvas);\n this.canvas = null;\n this.screen.dispose();\n this.graphicsContext.dispose();\n this.graphicsContext = null;\n }\n }\n /**\n * Returns a BoundingBox of the top left corner of the screen\n * and the bottom right corner of the screen.\n */\n getWorldBounds() {\n return this.screen.getWorldBounds();\n }\n /**\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\n */\n get timescale() {\n return this._timescale;\n }\n /**\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\n * when using time-based movement.\n */\n set timescale(value) {\n if (value <= 0) {\n Logger.getInstance().error('Cannot set engine.timescale to a value of 0 or less than 0.');\n return;\n }\n this._timescale = value;\n }\n /**\n * Adds a [[Timer]] to the [[currentScene]].\n * @param timer The timer to add to the [[currentScene]].\n */\n addTimer(timer) {\n return this.currentScene.addTimer(timer);\n }\n /**\n * Removes a [[Timer]] from the [[currentScene]].\n * @param timer The timer to remove to the [[currentScene]].\n */\n removeTimer(timer) {\n return this.currentScene.removeTimer(timer);\n }\n /**\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\n * would levels or menus.\n * @param key The name of the scene, must be unique\n * @param scene The scene to add to the engine\n */\n addScene(key, scene) {\n this.director.add(key, scene);\n return this;\n }\n /**\n * @internal\n */\n removeScene(entity) {\n this.director.remove(entity);\n }\n add(entity) {\n if (arguments.length === 2) {\n this.director.add(arguments[0], arguments[1]);\n return;\n }\n const maybeDeferred = this.director.getDeferredScene();\n if (maybeDeferred instanceof Scene) {\n maybeDeferred.add(entity);\n }\n else {\n this.currentScene.add(entity);\n }\n }\n remove(entity) {\n if (entity instanceof Entity) {\n this.currentScene.remove(entity);\n }\n if (entity instanceof Scene || isSceneConstructor(entity)) {\n this.removeScene(entity);\n }\n if (typeof entity === 'string') {\n this.removeScene(entity);\n }\n }\n /**\n * Changes the current scene with optionally supplied:\n * * Activation data\n * * Transitions\n * * Loaders\n *\n * Example:\n * ```typescript\n * game.goToScene('myScene', {\n * sceneActivationData: {any: 'thing at all'},\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\n * loader: MyLoader\n * });\n * ```\n *\n * Scenes are defined in the Engine constructor\n * ```typescript\n * const engine = new ex.Engine({\n scenes: {...}\n });\n * ```\n * Or by adding dynamically\n *\n * ```typescript\n * engine.addScene('myScene', new ex.Scene());\n * ```\n * @param destinationScene\n * @param options\n * @deprecated use goToScene, it now behaves the same as goto\n */\n async goto(destinationScene, options) {\n await this.director.goto(destinationScene, options);\n }\n /**\n * Changes the current scene with optionally supplied:\n * * Activation data\n * * Transitions\n * * Loaders\n *\n * Example:\n * ```typescript\n * game.goToScene('myScene', {\n * sceneActivationData: {any: 'thing at all'},\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\n * loader: MyLoader\n * });\n * ```\n *\n * Scenes are defined in the Engine constructor\n * ```typescript\n * const engine = new ex.Engine({\n scenes: {...}\n });\n * ```\n * Or by adding dynamically\n *\n * ```typescript\n * engine.addScene('myScene', new ex.Scene());\n * ```\n * @param destinationScene\n * @param options\n */\n async goToScene(destinationScene, options) {\n await this.director.goto(destinationScene, options);\n }\n /**\n * Transforms the current x, y from screen coordinates to world coordinates\n * @param point Screen coordinate to convert\n */\n screenToWorldCoordinates(point) {\n return this.screen.screenToWorldCoordinates(point);\n }\n /**\n * Transforms a world coordinate, to a screen coordinate\n * @param point World coordinate to convert\n */\n worldToScreenCoordinates(point) {\n return this.screen.worldToScreenCoordinates(point);\n }\n /**\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\n */\n _initialize(options) {\n var _a, _b;\n this.pageScrollPreventionMode = options.scrollPreventionMode;\n // initialize inputs\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n const grabWindowFocus = (_b = (_a = this._originalOptions) === null || _a === void 0 ? void 0 : _a.grabWindowFocus) !== null && _b !== void 0 ? _b : true;\n this.input = new InputHost({\n pointerTarget,\n grabWindowFocus,\n engine: this\n });\n this.inputMapper = this.input.inputMapper;\n // Issue #385 make use of the visibility api\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\n this.browser.document.on('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n this.events.emit('hidden', new HiddenEvent(this));\n this._logger.debug('Window hidden');\n }\n else if (document.visibilityState === 'visible') {\n this.events.emit('visible', new VisibleEvent(this));\n this._logger.debug('Window visible');\n }\n });\n if (!this.canvasElementId && !options.canvasElement) {\n document.body.appendChild(this.canvas);\n }\n }\n toggleInputEnabled(enabled) {\n this._inputEnabled = enabled;\n this.input.toggleEnabled(this._inputEnabled);\n }\n onInitialize(engine) {\n // Override me\n }\n /**\n * If supported by the browser, this will set the antialiasing flag on the\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\n * image resources.\n * @param isSmooth Set smoothing to true or false\n * @deprecated Set in engine constructor, will be removed in v0.30\n */\n setAntialiasing(isSmooth) {\n this.screen.antialiasing = isSmooth;\n }\n /**\n * Return the current smoothing status of the canvas\n * @deprecated Set in engine constructor, will be removed in v0.30\n */\n getAntialiasing() {\n return this.screen.antialiasing;\n }\n /**\n * Gets whether the actor is Initialized\n */\n get isInitialized() {\n return this._isInitialized;\n }\n async _overrideInitialize(engine) {\n if (!this.isInitialized) {\n await this.director.onInitialize();\n await this.onInitialize(engine);\n this.events.emit('initialize', new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\n * Updates the entire state of the game\n * @param delta Number of milliseconds elapsed since the last update.\n */\n _update(delta) {\n var _a;\n if (this._isLoading) {\n // suspend updates until loading is finished\n (_a = this._loader) === null || _a === void 0 ? void 0 : _a.onUpdate(this, delta);\n // Update input listeners\n this.input.update();\n return;\n }\n // Publish preupdate events\n this._preupdate(delta);\n // process engine level events\n this.currentScene.update(this, delta);\n // Update graphics postprocessors\n this.graphicsContext.updatePostProcessors(delta);\n // Publish update event\n this._postupdate(delta);\n // Update input listeners\n this.input.update();\n }\n /**\n * @internal\n */\n _preupdate(delta) {\n this.emit('preupdate', new PreUpdateEvent(this, delta, this));\n this.onPreUpdate(this, delta);\n }\n onPreUpdate(engine, delta) {\n // Override me\n }\n /**\n * @internal\n */\n _postupdate(delta) {\n this.emit('postupdate', new PostUpdateEvent(this, delta, this));\n this.onPostUpdate(this, delta);\n }\n onPostUpdate(engine, delta) {\n // Override me\n }\n /**\n * Draws the entire game\n * @param delta Number of milliseconds elapsed since the last draw.\n */\n _draw(delta) {\n var _a, _b;\n this.graphicsContext.beginDrawLifecycle();\n this.graphicsContext.clear();\n this._predraw(this.graphicsContext, delta);\n // Drawing nothing else while loading\n if (this._isLoading) {\n if (!this._hideLoader) {\n (_a = this._loader) === null || _a === void 0 ? void 0 : _a.canvas.draw(this.graphicsContext, 0, 0);\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n }\n return;\n }\n // Use scene background color if present, fallback to engine\n this.graphicsContext.backgroundColor = (_b = this.currentScene.backgroundColor) !== null && _b !== void 0 ? _b : this.backgroundColor;\n this.currentScene.draw(this.graphicsContext, delta);\n this._postdraw(this.graphicsContext, delta);\n // Flush any pending drawings\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n this._checkForScreenShots();\n }\n /**\n * @internal\n */\n _predraw(ctx, delta) {\n this.emit('predraw', new PreDrawEvent(ctx, delta, this));\n this.onPreDraw(ctx, delta);\n }\n onPreDraw(ctx, delta) {\n // Override me\n }\n /**\n * @internal\n */\n _postdraw(ctx, delta) {\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\n this.onPostDraw(ctx, delta);\n }\n onPostDraw(ctx, delta) {\n // Override me\n }\n /**\n * Enable or disable Excalibur debugging functionality.\n * @param toggle a value that debug drawing will be changed to\n */\n showDebug(toggle) {\n this._isDebug = toggle;\n }\n /**\n * Toggle Excalibur debugging functionality.\n */\n toggleDebug() {\n this._isDebug = !this._isDebug;\n return this._isDebug;\n }\n /**\n * Returns true when loading is totally complete and the player has clicked start\n */\n get loadingComplete() {\n return !this._isLoading;\n }\n get ready() {\n return this._isReadyFuture.isCompleted;\n }\n isReady() {\n return this._isReadyFuture.promise;\n }\n async start(sceneNameOrLoader, options) {\n if (!this._compatible) {\n throw new Error('Excalibur is incompatible with your browser');\n }\n this._isLoading = true;\n let loader;\n if (sceneNameOrLoader instanceof DefaultLoader) {\n loader = sceneNameOrLoader;\n }\n else if (typeof sceneNameOrLoader === 'string') {\n this.director.configureStart(sceneNameOrLoader, options);\n loader = this.director.mainLoader;\n }\n // Start the excalibur clock which drives the mainloop\n this._logger.debug('Starting game clock...');\n this.browser.resume();\n this.clock.start();\n this._logger.debug('Game clock started');\n await this.load(loader !== null && loader !== void 0 ? loader : new Loader());\n // Initialize before ready\n await this._overrideInitialize(this);\n this._isReadyFuture.resolve();\n this.emit('start', new GameStartEvent(this));\n return this._isReadyFuture.promise;\n }\n _mainloop(elapsed) {\n this.emit('preframe', new PreFrameEvent(this, this.stats.prevFrame));\n const delta = elapsed * this.timescale;\n this.currentFrameElapsedMs = delta;\n // reset frame stats (reuse existing instances)\n const frameId = this.stats.prevFrame.id + 1;\n this.stats.currFrame.reset();\n this.stats.currFrame.id = frameId;\n this.stats.currFrame.delta = delta;\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\n GraphicsDiagnostics.clear();\n const beforeUpdate = this.clock.now();\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\n if (this.fixedUpdateFps) {\n this._lagMs += delta;\n while (this._lagMs >= fixedTimestepMs) {\n this._update(fixedTimestepMs);\n this._lagMs -= fixedTimestepMs;\n }\n }\n else {\n this._update(delta);\n }\n const afterUpdate = this.clock.now();\n this.currentFrameLagMs = this._lagMs;\n this._draw(delta);\n const afterDraw = this.clock.now();\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\n this.emit('postframe', new PostFrameEvent(this, this.stats.currFrame));\n this.stats.prevFrame.reset(this.stats.currFrame);\n this._monitorPerformanceThresholdAndTriggerFallback();\n }\n /**\n * Stops Excalibur's main loop, useful for pausing the game.\n */\n stop() {\n if (this.clock.isRunning()) {\n this.emit('stop', new GameStopEvent(this));\n this.browser.pause();\n this.clock.stop();\n this._logger.debug('Game stopped');\n }\n }\n /**\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\n */\n isRunning() {\n return this.clock.isRunning();\n }\n /**\n * Takes a screen shot of the current viewport and returns it as an\n * HTML Image Element.\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\n */\n screenshot(preserveHiDPIResolution = false) {\n const screenShotPromise = new Promise((resolve) => {\n this._screenShotRequests.push({ preserveHiDPIResolution, resolve });\n });\n return screenShotPromise;\n }\n _checkForScreenShots() {\n // We must grab the draw buffer before we yield to the browser\n // the draw buffer is cleared after compositing\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\n // forces the browser to copy buffers which can have a mass perf impact on mobile\n for (const request of this._screenShotRequests) {\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\n const screenshot = document.createElement('canvas');\n screenshot.width = finalWidth;\n screenshot.height = finalHeight;\n const ctx = screenshot.getContext('2d');\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\n const result = new Image();\n const raw = screenshot.toDataURL('image/png');\n result.src = raw;\n request.resolve(result);\n }\n // Reset state\n this._screenShotRequests.length = 0;\n }\n /**\n * Another option available to you to load resources into the game.\n * Immediately after calling this the game will pause and the loading screen\n * will appear.\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\n */\n async load(loader, hideLoader = false) {\n try {\n // early exit if loaded\n if (loader.isLoaded()) {\n return;\n }\n this._loader = loader;\n this._isLoading = true;\n this._hideLoader = hideLoader;\n if (loader instanceof Loader) {\n loader.suppressPlayButton = this._suppressPlayButton;\n }\n this._loader.onInitialize(this);\n await loader.load();\n }\n catch (e) {\n this._logger.error('Error loading resources, things may not behave properly', e);\n await Promise.resolve();\n }\n finally {\n this._isLoading = false;\n this._hideLoader = false;\n this._loader = null;\n }\n }\n}\n/**\n * Default [[EngineOptions]]\n */\nEngine._DEFAULT_ENGINE_OPTIONS = {\n width: 0,\n height: 0,\n enableCanvasTransparency: true,\n useDrawSorting: true,\n configurePerformanceCanvas2DFallback: {\n allow: false,\n showPlayerMessage: false,\n threshold: { fps: 20, numberOfFrames: 100 }\n },\n canvasElementId: '',\n canvasElement: undefined,\n snapToPixel: false,\n antialiasing: true,\n pixelArt: false,\n powerPreference: 'high-performance',\n pointerScope: PointerScope.Canvas,\n suppressConsoleBootMessage: null,\n suppressMinimumBrowserFeatureDetection: null,\n suppressHiDPIScaling: null,\n suppressPlayButton: null,\n grabWindowFocus: true,\n scrollPreventionMode: ScrollPreventionMode.Canvas,\n backgroundColor: Color.fromHex('#2185d0') // Excalibur blue\n};\n\n;// CONCATENATED MODULE: ./Math/Index.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Debug/index.ts\n\n\n\n\n;// CONCATENATED MODULE: ./EventDispatcher.ts\n\n/**\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\n */\nclass EventDispatcher {\n constructor() {\n this._handlers = {};\n this._wiredEventDispatchers = [];\n this._deferedHandlerRemovals = [];\n }\n /**\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\n */\n clear() {\n this._handlers = {};\n this._wiredEventDispatchers = [];\n }\n _processDeferredHandlerRemovals() {\n for (const eventHandler of this._deferedHandlerRemovals) {\n this._removeHandler(eventHandler.name, eventHandler.handler);\n }\n this._deferedHandlerRemovals.length = 0;\n }\n /**\n * Emits an event for target\n * @param eventName The name of the event to publish\n * @param event Optionally pass an event data object to the handler\n */\n emit(eventName, event) {\n this._processDeferredHandlerRemovals();\n if (!eventName) {\n // key not mapped\n return;\n }\n eventName = eventName.toLowerCase();\n if (typeof event === 'undefined' || event === null) {\n event = new GameEvent();\n }\n let i, len;\n if (this._handlers[eventName]) {\n i = 0;\n len = this._handlers[eventName].length;\n for (i; i < len; i++) {\n this._handlers[eventName][i](event);\n }\n }\n i = 0;\n len = this._wiredEventDispatchers.length;\n for (i; i < len; i++) {\n this._wiredEventDispatchers[i].emit(eventName, event);\n }\n }\n /**\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\n * @param eventName The name of the event to subscribe to\n * @param handler The handler callback to fire on this event\n */\n on(eventName, handler) {\n this._processDeferredHandlerRemovals();\n eventName = eventName.toLowerCase();\n if (!this._handlers[eventName]) {\n this._handlers[eventName] = [];\n }\n this._handlers[eventName].push(handler);\n }\n /**\n * Unsubscribe an event handler(s) from an event. If a specific handler\n * is specified for an event, only that handler will be unsubscribed.\n * Otherwise all handlers will be unsubscribed for that event.\n * @param eventName The name of the event to unsubscribe\n * @param handler Optionally the specific handler to unsubscribe\n */\n off(eventName, handler) {\n this._deferedHandlerRemovals.push({ name: eventName, handler });\n }\n _removeHandler(eventName, handler) {\n eventName = eventName.toLowerCase();\n const eventHandlers = this._handlers[eventName];\n if (eventHandlers) {\n // if no explicit handler is give with the event name clear all handlers\n if (!handler) {\n this._handlers[eventName].length = 0;\n }\n else {\n const index = eventHandlers.indexOf(handler);\n if (index > -1) {\n this._handlers[eventName].splice(index, 1);\n }\n }\n }\n }\n /**\n * Once listens to an event one time, then unsubscribes from that event\n * @param eventName The name of the event to subscribe to once\n * @param handler The handler of the event that will be auto unsubscribed\n */\n once(eventName, handler) {\n this._processDeferredHandlerRemovals();\n const metaHandler = (event) => {\n const ev = event || new GameEvent();\n this.off(eventName, metaHandler);\n handler(ev);\n };\n this.on(eventName, metaHandler);\n }\n /**\n * Wires this event dispatcher to also receive events from another\n */\n wire(eventDispatcher) {\n eventDispatcher._wiredEventDispatchers.push(this);\n }\n /**\n * Unwires this event dispatcher from another\n */\n unwire(eventDispatcher) {\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\n if (index > -1) {\n eventDispatcher._wiredEventDispatchers.splice(index, 1);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Label.ts\n\n\n\n\n\n/**\n * Labels are the way to draw small amounts of text to the screen. They are\n * actors and inherit all of the benefits and capabilities.\n */\nclass Label extends Actor {\n get font() {\n return this._font;\n }\n set font(newFont) {\n this._font = newFont;\n this._text.font = newFont;\n }\n /**\n * The text to draw.\n */\n get text() {\n return this._text.text;\n }\n set text(text) {\n this._text.text = text;\n }\n get color() {\n return this._text.color;\n }\n set color(color) {\n if (this._text) {\n this._text.color = color;\n }\n }\n get opacity() {\n return this._text.opacity;\n }\n set opacity(opacity) {\n this._text.opacity = opacity;\n }\n /**\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\n */\n get spriteFont() {\n return this._spriteFont;\n }\n set spriteFont(sf) {\n if (sf) {\n this._spriteFont = sf;\n this._text.font = this._spriteFont;\n }\n }\n /**\n * Build a new label\n * @param options\n */\n constructor(options) {\n super(options);\n this._font = new Font();\n this._text = new Text({ text: '', font: this._font });\n const { text, pos, x, y, spriteFont, font, color } = { text: '', ...options };\n this.pos = pos !== null && pos !== void 0 ? pos : (x && y ? vec(x, y) : this.pos);\n this.text = text !== null && text !== void 0 ? text : this.text;\n this.font = font !== null && font !== void 0 ? font : this.font;\n this.spriteFont = spriteFont !== null && spriteFont !== void 0 ? spriteFont : this.spriteFont;\n this._text.color = color !== null && color !== void 0 ? color : this.color;\n const gfx = this.get(GraphicsComponent);\n gfx.anchor = Vector.Zero;\n gfx.use(this._text);\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n /**\n * Returns the width of the text in the label (in pixels);\n */\n getTextWidth() {\n return this._text.width;\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/IsometricMap.ts\n\n\n\n\n\n\n\n\n\n\nclass IsometricTile extends Entity {\n getGraphics() {\n return this._graphics;\n }\n /**\n * Tile graphics\n */\n addGraphic(graphic, options) {\n this._graphics.push(graphic);\n this._gfx.visible = this.map.visible;\n this._gfx.opacity = this.map.opacity;\n if (options === null || options === void 0 ? void 0 : options.offset) {\n this._gfx.offset = options.offset;\n }\n // TODO detect when this changes on the map and apply to all tiles\n this._gfx.localBounds = this._recalculateBounds();\n }\n _recalculateBounds() {\n let bounds = this._tileBounds.clone();\n for (const graphic of this._graphics) {\n const offset = vec(this.map.graphicsOffset.x - this.map.tileWidth / 2, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\n bounds = bounds.combine(graphic.localBounds.translate(offset));\n }\n return bounds;\n }\n removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) {\n this._graphics.splice(index, 1);\n }\n this._gfx.localBounds = this._recalculateBounds();\n }\n clearGraphics() {\n this._graphics.length = 0;\n this._gfx.visible = false;\n this._gfx.localBounds = this._recalculateBounds();\n }\n getColliders() {\n return this._colliders;\n }\n /**\n * Adds a collider to the IsometricTile\n *\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\n * @param collider\n */\n addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\n * Removes a collider from the IsometricTile\n * @param collider\n */\n removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) {\n this._colliders.splice(index, 1);\n }\n this.map.flagCollidersDirty();\n }\n /**\n * Clears all colliders from the IsometricTile\n */\n clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n /**\n * Returns the top left corner of the [[IsometricTile]] in world space\n */\n get pos() {\n return this.map.tileToWorld(vec(this.x, this.y));\n }\n /**\n * Returns the center of the [[IsometricTile]]\n */\n get center() {\n return this.pos.add(vec(0, this.map.tileHeight / 2));\n }\n /**\n * Construct a new IsometricTile\n * @param x tile coordinate in x (not world position)\n * @param y tile coordinate in y (not world position)\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\n * @param map reference to owning IsometricMap\n */\n constructor(x, y, graphicsOffset, map) {\n super([\n new TransformComponent(),\n new GraphicsComponent({\n offset: graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : Vector.Zero,\n onPostDraw: (gfx, elapsed) => this.draw(gfx, elapsed)\n }),\n new IsometricEntityComponent(map)\n ]);\n /**\n * Indicates whether this tile is solid\n */\n this.solid = false;\n this._tileBounds = new BoundingBox();\n this._graphics = [];\n /**\n * Tile colliders\n */\n this._colliders = [];\n /**\n * Arbitrary data storage per tile, useful for any game specific data\n */\n this.data = new Map();\n this.x = x;\n this.y = y;\n this.map = map;\n this._transform = this.get(TransformComponent);\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\n const halfTileWidth = this.map.tileWidth / 2;\n const halfTileHeight = this.map.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n // The x position shifts left with every y step\n const xPos = (this.x - this.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (this.x + this.y) * halfTileHeight;\n this._transform.pos = vec(xPos, yPos);\n this._isometricEntityComponent.elevation = map.elevation;\n this._gfx = this.get(GraphicsComponent);\n this._gfx.visible = false; // start not visible\n const totalWidth = this.map.tileWidth;\n const totalHeight = this.map.tileHeight;\n // initial guess at gfx bounds based on the tile\n const offset = vec(0, (this.map.renderFromTopOfGraphic ? totalHeight : 0));\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\n left: -totalWidth / 2,\n top: -totalHeight,\n right: totalWidth / 2,\n bottom: totalHeight\n }).translate(offset);\n }\n draw(gfx, _elapsed) {\n const halfTileWidth = this.map.tileWidth / 2;\n gfx.save();\n // shift left origin to corner of map, not the left corner of the first sprite\n gfx.translate(-halfTileWidth, 0);\n for (const graphic of this._graphics) {\n graphic.draw(gfx, this.map.graphicsOffset.x, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\n }\n gfx.restore();\n }\n}\n/**\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\n *\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\n *\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\n * your art assets.\n */\nclass IsometricMap extends Entity {\n constructor(options) {\n super([\n new TransformComponent(),\n new BodyComponent({\n type: CollisionType.Fixed\n }),\n new ColliderComponent(),\n new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false)\n ], options.name);\n this.elevation = 0;\n /**\n * Whether tiles should be visible\n */\n this.visible = true;\n /**\n * Opacity of tiles\n */\n this.opacity = 1.0;\n /**\n * Render the tile graphic from the top instead of the bottom\n *\n * default is `false` meaning rendering from the bottom\n */\n this.renderFromTopOfGraphic = false;\n this.graphicsOffset = vec(0, 0);\n this._collidersDirty = false;\n this._originalOffsets = new WeakMap();\n const { pos, tileWidth, tileHeight, columns: width, rows: height, renderFromTopOfGraphic, graphicsOffset, elevation } = options;\n this.transform = this.get(TransformComponent);\n if (pos) {\n this.transform.pos = pos;\n }\n this.collider = this.get(ColliderComponent);\n if (this.collider) {\n this.collider.set(this._composite = new CompositeCollider([]));\n }\n this.renderFromTopOfGraphic = renderFromTopOfGraphic !== null && renderFromTopOfGraphic !== void 0 ? renderFromTopOfGraphic : this.renderFromTopOfGraphic;\n this.graphicsOffset = graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : this.graphicsOffset;\n this.elevation = elevation !== null && elevation !== void 0 ? elevation : this.elevation;\n this.tileWidth = tileWidth;\n this.tileHeight = tileHeight;\n this.columns = width;\n this.rows = height;\n this.tiles = new Array(width * height);\n // build up tile representation\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\n this.tiles[x + y * width] = tile;\n this.addChild(tile);\n }\n }\n }\n update() {\n if (this._collidersDirty) {\n this.updateColliders();\n this._collidersDirty = false;\n }\n }\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n }\n else {\n return this._originalOffsets.get(collider);\n }\n }\n updateColliders() {\n this._composite.clearColliders();\n const pos = this.get(TransformComponent).pos;\n for (const tile of this.tiles) {\n if (tile.solid) {\n for (const collider of tile.getColliders()) {\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = this.tileToWorld(vec(tile.x, tile.y))\n .sub(pos)\n .add(originalOffset)\n .sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n }\n }\n this.collider.update();\n }\n /**\n * Convert world space coordinates to the tile x, y coordinate\n * @param worldCoordinate\n */\n worldToTile(worldCoordinate) {\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n return vec(~~((worldCoordinate.x / halfTileWidth + (worldCoordinate.y / halfTileHeight)) / 2), ~~((worldCoordinate.y / halfTileHeight - (worldCoordinate.x / halfTileWidth)) / 2));\n }\n /**\n * Given a tile coordinate, return the top left corner in world space\n * @param tileCoordinate\n */\n tileToWorld(tileCoordinate) {\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // The x position shifts left with every y step\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\n return vec(xPos, yPos).add(this.transform.pos);\n }\n /**\n * Returns the [[IsometricTile]] by its x and y coordinates\n */\n getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\n return null;\n }\n return this.tiles[x + y * this.columns];\n }\n /**\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\n * returns `null` if no Tile was found.\n */\n getTileByPoint(point) {\n const tileCoord = this.worldToTile(point);\n const tile = this.getTile(tileCoord.x, tileCoord.y);\n return tile;\n }\n _getMaxZIndex() {\n let maxZ = Number.NEGATIVE_INFINITY;\n for (const tile of this.tiles) {\n const currentZ = tile.get(TransformComponent).z;\n if (currentZ > maxZ) {\n maxZ = currentZ;\n }\n }\n return maxZ;\n }\n /**\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\n * @param gfx\n */\n debug(gfx, debugFlags) {\n const { showAll, showPosition, positionColor, positionSize, showGrid, gridColor, gridWidth, showColliderGeometry } = debugFlags.isometric;\n const { geometryColor, geometryLineWidth, geometryPointSize } = debugFlags.collider;\n gfx.save();\n gfx.z = this._getMaxZIndex() + 0.5;\n if (showAll || showGrid) {\n for (let y = 0; y < this.rows + 1; y++) {\n const left = this.tileToWorld(vec(0, y));\n const right = this.tileToWorld(vec(this.columns, y));\n gfx.drawLine(left, right, gridColor, gridWidth);\n }\n for (let x = 0; x < this.columns + 1; x++) {\n const top = this.tileToWorld(vec(x, 0));\n const bottom = this.tileToWorld(vec(x, this.rows));\n gfx.drawLine(top, bottom, gridColor, gridWidth);\n }\n }\n if (showAll || showPosition) {\n for (const tile of this.tiles) {\n gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), positionSize, positionColor);\n }\n }\n if (showAll || showColliderGeometry) {\n for (const tile of this.tiles) {\n if (tile.solid) { // only draw solid tiles\n for (const collider of tile.getColliders()) {\n collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize });\n }\n }\n }\n }\n gfx.restore();\n }\n}\n\n;// CONCATENATED MODULE: ./TileMap/index.ts\n\n\n\n\n\n;// CONCATENATED MODULE: ./Actions/Action/ActionSequence.ts\n\n/**\n * Action that can represent a sequence of actions, this can be useful in conjunction with\n * [[ParallelActions]] to run multiple sequences in parallel.\n */\nclass ActionSequence {\n constructor(entity, actionBuilder) {\n this._stopped = false;\n this._sequenceBuilder = actionBuilder;\n this._sequenceContext = new ActionContext(entity);\n this._actionQueue = this._sequenceContext.getQueue();\n this._sequenceBuilder(this._sequenceContext);\n }\n update(delta) {\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || this._actionQueue.isComplete();\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._stopped = false;\n this._actionQueue.reset();\n }\n clone(entity) {\n return new ActionSequence(entity, this._sequenceBuilder);\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Action/ParallelActions.ts\n/**\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\n */\nclass ParallelActions {\n constructor(parallelActions) {\n this._actions = parallelActions;\n }\n update(delta) {\n for (let i = 0; i < this._actions.length; i++) {\n this._actions[i].update(delta);\n }\n }\n isComplete(entity) {\n return this._actions.every(a => a.isComplete(entity));\n }\n reset() {\n this._actions.forEach(a => a.reset());\n }\n stop() {\n this._actions.forEach(a => a.stop());\n }\n}\n\n;// CONCATENATED MODULE: ./Actions/Index.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Collision/Detection/QuadTree.ts\n\n\n/**\n * QuadTree spatial data structure. Useful for quickly retrieving all objects that might\n * be in a specific location.\n */\nclass QuadTree {\n constructor(bounds, options) {\n this.bounds = bounds;\n this.options = options;\n this._defaultOptions = {\n maxDepth: 10,\n capacity: 10,\n level: 0\n };\n this.items = [];\n this._isDivided = false;\n this.topLeft = null;\n this.topRight = null;\n this.bottomLeft = null;\n this.bottomRight = null;\n this.options = { ...this._defaultOptions, ...options };\n this.halfWidth = bounds.width / 2;\n this.halfHeight = bounds.height / 2;\n }\n /**\n * Splits the quad tree one level deeper\n */\n _split() {\n this._isDivided = true;\n const newLevelOptions = {\n maxDepth: this.options.maxDepth,\n capacity: this.options.capacity,\n level: this.options.level + 1\n };\n this.topLeft = new QuadTree(new BoundingBox({\n left: this.bounds.left,\n top: this.bounds.top,\n right: this.bounds.left + this.halfWidth,\n bottom: this.bounds.top + this.halfHeight\n }), newLevelOptions);\n this.topRight = new QuadTree(new BoundingBox({\n left: this.bounds.left + this.halfWidth,\n top: this.bounds.top,\n right: this.bounds.right,\n bottom: this.bounds.top + this.halfHeight\n }), newLevelOptions);\n this.bottomLeft = new QuadTree(new BoundingBox({\n left: this.bounds.left,\n top: this.bounds.top + this.halfHeight,\n right: this.bounds.left + this.halfWidth,\n bottom: this.bounds.bottom\n }), newLevelOptions);\n this.bottomRight = new QuadTree(new BoundingBox({\n left: this.bounds.left + this.halfWidth,\n top: this.bounds.top + this.halfHeight,\n right: this.bounds.right,\n bottom: this.bounds.bottom\n }), newLevelOptions);\n }\n _insertIntoSubNodes(item) {\n var _a, _b, _c, _d;\n if ((_a = this.topLeft) === null || _a === void 0 ? void 0 : _a.bounds.overlaps(item.bounds)) {\n this.topLeft.insert(item);\n }\n if ((_b = this.topRight) === null || _b === void 0 ? void 0 : _b.bounds.overlaps(item.bounds)) {\n this.topRight.insert(item);\n }\n if ((_c = this.bottomLeft) === null || _c === void 0 ? void 0 : _c.bounds.overlaps(item.bounds)) {\n this.bottomLeft.insert(item);\n }\n if ((_d = this.bottomRight) === null || _d === void 0 ? void 0 : _d.bounds.overlaps(item.bounds)) {\n this.bottomRight.insert(item);\n }\n }\n /**\n * Insert an item to be tracked in the QuadTree\n * @param item\n */\n insert(item) {\n // add to subnodes if it matches\n if (this._isDivided) {\n this._insertIntoSubNodes(item);\n return;\n }\n // leaf case\n this.items.push(item);\n // capacity\n if (this.items.length > this.options.capacity && this.options.level < this.options.maxDepth) {\n if (!this._isDivided) {\n this._split();\n }\n // divide this level's items into it's subnodes\n for (const item of this.items) {\n this._insertIntoSubNodes(item);\n }\n // clear this level\n this.items.length = 0;\n }\n }\n /**\n * Remove a tracked item in the QuadTree\n * @param item\n */\n remove(item) {\n var _a, _b, _c, _d;\n if (!this.bounds.overlaps(item.bounds)) {\n return;\n }\n if (!this._isDivided) {\n const index = this.items.indexOf(item);\n if (index > -1) {\n this.items.splice(index, 1);\n }\n return;\n }\n if ((_a = this.topLeft) === null || _a === void 0 ? void 0 : _a.bounds.overlaps(item.bounds)) {\n this.topLeft.remove(item);\n }\n if ((_b = this.topRight) === null || _b === void 0 ? void 0 : _b.bounds.overlaps(item.bounds)) {\n this.topRight.remove(item);\n }\n if ((_c = this.bottomLeft) === null || _c === void 0 ? void 0 : _c.bounds.overlaps(item.bounds)) {\n this.bottomLeft.remove(item);\n }\n if ((_d = this.bottomRight) === null || _d === void 0 ? void 0 : _d.bounds.overlaps(item.bounds)) {\n this.bottomRight.remove(item);\n }\n }\n /**\n * Query the structure for all objects that intersect the bounding box\n * @param boundingBox\n * @returns items\n */\n query(boundingBox) {\n let results = this.items;\n if (this._isDivided) {\n if (this.topLeft.bounds.overlaps(boundingBox)) {\n results = results.concat(this.topLeft.query(boundingBox));\n }\n if (this.topRight.bounds.overlaps(boundingBox)) {\n results = results.concat(this.topRight.query(boundingBox));\n }\n if (this.bottomLeft.bounds.overlaps(boundingBox)) {\n results = results.concat(this.bottomLeft.query(boundingBox));\n }\n if (this.bottomRight.bounds.overlaps(boundingBox)) {\n results = results.concat(this.bottomRight.query(boundingBox));\n }\n }\n results = results.filter((item, index) => {\n return results.indexOf(item) >= index;\n });\n return results;\n }\n clear() {\n this.items = [];\n this._isDivided = false;\n this.topLeft = null;\n this.topRight = null;\n this.bottomLeft = null;\n this.bottomRight = null;\n }\n getAllItems() {\n let results = this.items;\n if (this._isDivided) {\n results = results.concat(this.topLeft.getAllItems());\n results = results.concat(this.topRight.getAllItems());\n results = results.concat(this.bottomLeft.getAllItems());\n results = results.concat(this.bottomRight.getAllItems());\n }\n results = results.filter((item, index) => {\n return results.indexOf(item) >= index;\n });\n return results;\n }\n getTreeDepth() {\n if (!this._isDivided) {\n return 0;\n }\n return 1 + Math.max(this.topLeft.getTreeDepth(), this.topRight.getTreeDepth(), this.bottomLeft.getTreeDepth(), this.bottomRight.getTreeDepth());\n }\n debug(ctx) {\n this.bounds.draw(ctx, Color.Yellow);\n if (this._isDivided) {\n this.topLeft.bounds.draw(ctx, Color.Yellow);\n this.topRight.bounds.draw(ctx, Color.Yellow);\n this.bottomLeft.bounds.draw(ctx, Color.Yellow);\n this.bottomRight.bounds.draw(ctx, Color.Yellow);\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Collision/Index.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Interfaces/LifecycleEvents.ts\n/**\n * Type guard checking for internal initialize method\n * @internal\n * @param a\n */\nfunction has_initialize(a) {\n return !!a._initialize;\n}\n/**\n *\n */\nfunction hasOnInitialize(a) {\n return !!a.onInitialize;\n}\n/**\n *\n */\nfunction has_preupdate(a) {\n return !!a._preupdate;\n}\n/**\n *\n */\nfunction hasOnPreUpdate(a) {\n return !!a.onPreUpdate;\n}\n/**\n *\n */\nfunction has_postupdate(a) {\n return !!a.onPostUpdate;\n}\n/**\n *\n */\nfunction hasOnPostUpdate(a) {\n return !!a.onPostUpdate;\n}\n/**\n *\n */\nfunction hasPreDraw(a) {\n return !!a.onPreDraw;\n}\n/**\n *\n */\nfunction hasPostDraw(a) {\n return !!a.onPostDraw;\n}\n\n;// CONCATENATED MODULE: ./Interfaces/Index.ts\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Resources/Sound/Index.ts\n\n\n\n\n;// CONCATENATED MODULE: ./Resources/Gif.ts\n\n\n\n\n\n\n/**\n * The [[Texture]] object allows games built in Excalibur to load image resources.\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\n * to pre-load before starting a level or game.\n */\nclass Gif {\n /**\n * @param path Path to the image resource\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\n * @param bustCache Optionally load texture with cache busting\n */\n constructor(path, color = Color.Magenta, bustCache = false) {\n this.path = path;\n this.color = color;\n this._stream = null;\n this._gif = null;\n this._textures = [];\n this._animation = null;\n this._transparentColor = null;\n this._resource = new Resource(path, 'arraybuffer', bustCache);\n this._transparentColor = color;\n }\n /**\n * Should excalibur add a cache busting querystring? By default false.\n * Must be set before loading\n */\n get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\n * Begins loading the texture and returns a promise to be resolved on completion\n */\n async load() {\n const arraybuffer = await this._resource.load();\n this._stream = new Stream(arraybuffer);\n this._gif = new ParseGif(this._stream, this._transparentColor);\n const images = this._gif.images.map(i => new ImageSource(i.src, false));\n // Load all textures\n await Promise.all(images.map(t => t.load()));\n return this.data = this._textures = images;\n }\n isLoaded() {\n return !!this.data;\n }\n /**\n * Return a frame of the gif as a sprite by id\n * @param id\n */\n toSprite(id = 0) {\n const sprite = this._textures[id].toSprite();\n return sprite;\n }\n /**\n * Return the gif as a spritesheet\n */\n toSpriteSheet() {\n const sprites = this._textures.map((image) => {\n return image.toSprite();\n });\n return new SpriteSheet({ sprites });\n }\n /**\n * Transform the GIF into an animation with duration per frame\n */\n toAnimation(durationPerFrameMs) {\n const spriteSheet = this.toSpriteSheet();\n const length = spriteSheet.sprites.length;\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\n return this._animation;\n }\n get readCheckBytes() {\n return this._gif.checkBytes;\n }\n}\nconst bitsToNum = (ba) => {\n return ba.reduce(function (s, n) {\n return s * 2 + n;\n }, 0);\n};\nconst byteToBitArr = (bite) => {\n const a = [];\n for (let i = 7; i >= 0; i--) {\n a.push(!!(bite & (1 << i)));\n }\n return a;\n};\nclass Stream {\n constructor(dataArray) {\n this.data = null;\n this.len = 0;\n this.position = 0;\n this.readByte = () => {\n if (this.position >= this.data.byteLength) {\n throw new Error('Attempted to read past end of stream.');\n }\n return this.data[this.position++];\n };\n this.readBytes = (n) => {\n const bytes = [];\n for (let i = 0; i < n; i++) {\n bytes.push(this.readByte());\n }\n return bytes;\n };\n this.read = (n) => {\n let s = '';\n for (let i = 0; i < n; i++) {\n s += String.fromCharCode(this.readByte());\n }\n return s;\n };\n this.readUnsigned = () => {\n // Little-endian.\n const a = this.readBytes(2);\n return (a[1] << 8) + a[0];\n };\n this.data = new Uint8Array(dataArray);\n this.len = this.data.byteLength;\n if (this.len === 0) {\n throw new Error('No data loaded from file');\n }\n }\n}\nconst lzwDecode = function (minCodeSize, data) {\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\n const readCode = function (size) {\n let code = 0;\n for (let i = 0; i < size; i++) {\n if (data.charCodeAt(pos >> 3) & (1 << (pos & 7))) {\n code |= 1 << i;\n }\n pos++;\n }\n return code;\n };\n const output = [];\n const clearCode = 1 << minCodeSize;\n const eoiCode = clearCode + 1;\n let codeSize = minCodeSize + 1;\n let dict = [];\n const clear = function () {\n dict = [];\n codeSize = minCodeSize + 1;\n for (let i = 0; i < clearCode; i++) {\n dict[i] = [i];\n }\n dict[clearCode] = [];\n dict[eoiCode] = null;\n };\n let code;\n let last;\n while (true) {\n last = code;\n code = readCode(codeSize);\n if (code === clearCode) {\n clear();\n continue;\n }\n if (code === eoiCode) {\n break;\n }\n if (code < dict.length) {\n if (last !== clearCode) {\n dict.push(dict[last].concat(dict[code][0]));\n }\n }\n else {\n if (code !== dict.length) {\n throw new Error('Invalid LZW code.');\n }\n dict.push(dict[last].concat(dict[last][0]));\n }\n output.push.apply(output, dict[code]);\n if (dict.length === 1 << codeSize && codeSize < 12) {\n // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\n codeSize++;\n }\n }\n // I don't know if this is technically an error, but some GIFs do it.\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\n return output;\n};\n// The actual parsing; returns an object with properties.\nclass ParseGif {\n constructor(stream, color = Color.Magenta) {\n this._st = null;\n this._handler = {};\n this._transparentColor = null;\n this.frames = [];\n this.images = [];\n this.globalColorTable = [];\n this.checkBytes = [];\n // LZW (GIF-specific)\n this.parseColorTable = (entries) => {\n // Each entry is 3 bytes, for RGB.\n const ct = [];\n for (let i = 0; i < entries; i++) {\n const rgb = this._st.readBytes(3);\n const rgba = '#' +\n rgb\n .map((x) => {\n const hex = x.toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n })\n .join('');\n ct.push(rgba);\n }\n return ct;\n };\n this.readSubBlocks = () => {\n let size, data;\n data = '';\n do {\n size = this._st.readByte();\n data += this._st.read(size);\n } while (size !== 0);\n return data;\n };\n this.parseHeader = () => {\n const hdr = {\n sig: null,\n ver: null,\n width: null,\n height: null,\n colorRes: null,\n globalColorTableSize: null,\n gctFlag: null,\n sorted: null,\n globalColorTable: [],\n bgColor: null,\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n };\n hdr.sig = this._st.read(3);\n hdr.ver = this._st.read(3);\n if (hdr.sig !== 'GIF') {\n throw new Error('Not a GIF file.'); // XXX: This should probably be handled more nicely.\n }\n hdr.width = this._st.readUnsigned();\n hdr.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n hdr.gctFlag = bits.shift();\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\n hdr.sorted = bits.shift();\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\n hdr.bgColor = this._st.readByte();\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n if (hdr.gctFlag) {\n hdr.globalColorTable = this.parseColorTable(1 << (hdr.globalColorTableSize + 1));\n this.globalColorTable = hdr.globalColorTable;\n }\n if (this._handler.hdr && this._handler.hdr(hdr)) {\n this.checkBytes.push(this._handler.hdr);\n }\n };\n this.parseExt = (block) => {\n const parseGCExt = (block) => {\n this.checkBytes.push(this._st.readByte()); // Always 4\n const bits = byteToBitArr(this._st.readByte());\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\n block.userInput = bits.shift();\n block.transparencyGiven = bits.shift();\n block.delayTime = this._st.readUnsigned();\n block.transparencyIndex = this._st.readByte();\n block.terminator = this._st.readByte();\n if (this._handler.gce && this._handler.gce(block)) {\n this.checkBytes.push(this._handler.gce);\n }\n };\n const parseComExt = (block) => {\n block.comment = this.readSubBlocks();\n if (this._handler.com && this._handler.com(block)) {\n this.checkBytes.push(this._handler.com);\n }\n };\n const parsePTExt = (block) => {\n this.checkBytes.push(this._st.readByte()); // Always 12\n block.ptHeader = this._st.readBytes(12);\n block.ptData = this.readSubBlocks();\n if (this._handler.pte && this._handler.pte(block)) {\n this.checkBytes.push(this._handler.pte);\n }\n };\n const parseAppExt = (block) => {\n const parseNetscapeExt = (block) => {\n this.checkBytes.push(this._st.readByte()); // Always 3\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\n block.iterations = this._st.readUnsigned();\n block.terminator = this._st.readByte();\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) {\n this.checkBytes.push(this._handler.app);\n }\n };\n const parseUnknownAppExt = (block) => {\n block.appData = this.readSubBlocks();\n // FIXME: This won't work if a handler wants to match on any identifier.\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) {\n this.checkBytes.push(this._handler.app[block.identifier]);\n }\n };\n this.checkBytes.push(this._st.readByte()); // Always 11\n block.identifier = this._st.read(8);\n block.authCode = this._st.read(3);\n switch (block.identifier) {\n case 'NETSCAPE':\n parseNetscapeExt(block);\n break;\n default:\n parseUnknownAppExt(block);\n break;\n }\n };\n const parseUnknownExt = (block) => {\n block.data = this.readSubBlocks();\n if (this._handler.unknown && this._handler.unknown(block)) {\n this.checkBytes.push(this._handler.unknown);\n }\n };\n block.label = this._st.readByte();\n switch (block.label) {\n case 0xf9:\n block.extType = 'gce';\n parseGCExt(block);\n break;\n case 0xfe:\n block.extType = 'com';\n parseComExt(block);\n break;\n case 0x01:\n block.extType = 'pte';\n parsePTExt(block);\n break;\n case 0xff:\n block.extType = 'app';\n parseAppExt(block);\n break;\n default:\n block.extType = 'unknown';\n parseUnknownExt(block);\n break;\n }\n };\n this.parseImg = (img) => {\n const deinterlace = (pixels, width) => {\n // Of course this defeats the purpose of interlacing. And it's *probably*\n // the least efficient way it's ever been implemented. But nevertheless...\n const newPixels = new Array(pixels.length);\n const rows = pixels.length / width;\n const cpRow = (toRow, fromRow) => {\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\n newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels));\n };\n const offsets = [0, 4, 2, 1];\n const steps = [8, 8, 4, 2];\n let fromRow = 0;\n for (let pass = 0; pass < 4; pass++) {\n for (let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) {\n cpRow(toRow, fromRow);\n fromRow++;\n }\n }\n return newPixels;\n };\n img.leftPos = this._st.readUnsigned();\n img.topPos = this._st.readUnsigned();\n img.width = this._st.readUnsigned();\n img.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n img.lctFlag = bits.shift();\n img.interlaced = bits.shift();\n img.sorted = bits.shift();\n img.reserved = bits.splice(0, 2);\n img.lctSize = bitsToNum(bits.splice(0, 3));\n if (img.lctFlag) {\n img.lct = this.parseColorTable(1 << (img.lctSize + 1));\n }\n img.lzwMinCodeSize = this._st.readByte();\n const lzwData = this.readSubBlocks();\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\n if (img.interlaced) {\n // Move\n img.pixels = deinterlace(img.pixels, img.width);\n }\n this.frames.push(img);\n this.arrayToImage(img);\n if (this._handler.img && this._handler.img(img)) {\n this.checkBytes.push(this._handler);\n }\n };\n this.parseBlock = () => {\n const block = {\n sentinel: this._st.readByte(),\n type: ''\n };\n const blockChar = String.fromCharCode(block.sentinel);\n switch (blockChar) {\n case '!':\n block.type = 'ext';\n this.parseExt(block);\n break;\n case ',':\n block.type = 'img';\n this.parseImg(block);\n break;\n case ';':\n block.type = 'eof';\n if (this._handler.eof && this._handler.eof(block)) {\n this.checkBytes.push(this._handler.eof);\n }\n break;\n default:\n throw new Error('Unknown block: 0x' + block.sentinel.toString(16));\n }\n if (block.type !== 'eof') {\n this.parseBlock();\n }\n };\n this.arrayToImage = (frame) => {\n let count = 0;\n const c = document.createElement('canvas');\n c.id = count.toString();\n c.width = frame.width;\n c.height = frame.height;\n count++;\n const context = c.getContext('2d');\n const pixSize = 1;\n let y = 0;\n let x = 0;\n for (let i = 0; i < frame.pixels.length; i++) {\n if (x % frame.width === 0) {\n y++;\n x = 0;\n }\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) {\n context.fillStyle = `rgba(0, 0, 0, 0)`;\n }\n else {\n context.fillStyle = this.globalColorTable[frame.pixels[i]];\n }\n context.fillRect(x, y, pixSize, pixSize);\n x++;\n }\n const img = new Image();\n img.src = c.toDataURL();\n this.images.push(img);\n };\n this._st = stream;\n this._handler = {};\n this._transparentColor = color;\n this.parseHeader();\n this.parseBlock();\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Font.ts\n\n\nclass FontSource {\n constructor(\n /**\n * Path to the font resource relative from the HTML document hosting the game, or absolute\n */\n path, \n /**\n * The font family name\n */\n family, { bustCache, ...options } = {}) {\n this.path = path;\n this.family = family;\n this._isLoaded = false;\n this._resource = new Resource(path, 'blob', bustCache);\n this._options = options;\n }\n async load() {\n if (this.isLoaded()) {\n return this.data;\n }\n try {\n const blob = await this._resource.load();\n const url = URL.createObjectURL(blob);\n if (!this.data) {\n this.data = new FontFace(this.family, `url(${url})`);\n document.fonts.add(this.data);\n }\n await this.data.load();\n this._isLoaded = true;\n }\n catch (error) {\n throw `Error loading FontSource from path '${this.path}' with error [${error.message}]`;\n }\n return this.data;\n }\n isLoaded() {\n return this._isLoaded;\n }\n /**\n * Build a font from this FontSource.\n * @param options {FontOptions} Override the font options\n */\n toFont(options) {\n return new Font({ family: this.family, ...this._options, ...options });\n }\n}\n\n;// CONCATENATED MODULE: ./Resources/Index.ts\n\n\n\n\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/index.ts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Util/Coroutine.ts\n/**\n * Excalibur coroutine helper, returns a promise when complete. Coroutines run before frame update.\n *\n * Each coroutine yield is 1 excalibur frame. Coroutines get passed the elapsed time our of yield. Coroutines\n * run internally on the excalibur clock.\n *\n * If you yield a promise it will be awaited before resumed\n * If you yield a number it will wait that many ms before resumed\n * @param engine\n * @param coroutineGenerator\n */\nfunction coroutine(engine, coroutineGenerator) {\n return new Promise((resolve, reject) => {\n const generator = coroutineGenerator();\n const loop = (elapsedMs) => {\n try {\n const { done, value } = generator.next(elapsedMs);\n if (done) {\n resolve();\n }\n if (value instanceof Promise) {\n value.then(() => {\n // schedule next loop\n engine.clock.schedule(loop);\n });\n }\n else if (value === undefined || value === (void 0)) {\n // schedule next frame\n engine.clock.schedule(loop);\n }\n else {\n // schedule value milliseconds from now\n engine.clock.schedule(loop, value || 0);\n }\n }\n catch (e) {\n reject(e);\n }\n };\n loop(engine.clock.elapsed()); // run first frame immediately\n });\n}\n\n;// CONCATENATED MODULE: ./Director/Transition.ts\n\n\n\n\n\n\n\n\n\n/**\n * Base Transition that can be extended to provide custom scene transitions in Excalibur.\n */\nclass Transition extends Entity {\n /**\n * Returns a number between [0, 1] indicating what state the transition is in.\n *\n * * For 'out' direction transitions start at 0 and end at 1\n * * For 'in' direction transitions start at 1 and end at 0\n */\n get progress() {\n return this._currentProgress;\n }\n get complete() {\n if (this.direction === 'out') {\n return this.progress >= 1;\n }\n else {\n return this.progress <= 0;\n }\n }\n constructor(options) {\n var _a, _b, _c, _d;\n super();\n this._logger = Logger.getInstance();\n this.transform = new TransformComponent();\n this.graphics = new GraphicsComponent();\n this._completeFuture = new Future();\n // State needs to be reset between uses\n this.started = false;\n this._currentDistance = 0;\n this._currentProgress = 0;\n this.done = this._completeFuture.promise;\n this.name = `Transition#${this.id}`;\n this.duration = options.duration;\n this.easing = (_a = options.easing) !== null && _a !== void 0 ? _a : EasingFunctions.Linear;\n this.direction = (_b = options.direction) !== null && _b !== void 0 ? _b : 'out';\n this.hideLoader = (_c = options.hideLoader) !== null && _c !== void 0 ? _c : false;\n this.blockInput = (_d = options.blockInput) !== null && _d !== void 0 ? _d : false;\n this.transform.coordPlane = CoordPlane.Screen;\n this.transform.pos = Vector.Zero;\n this.transform.z = Infinity; // Transitions sit on top of everything\n this.graphics.anchor = Vector.Zero;\n this.addComponent(this.transform);\n this.addComponent(this.graphics);\n if (this.direction === 'out') {\n this._currentProgress = 0;\n }\n else {\n this._currentProgress = 1;\n }\n }\n /**\n * Overridable lifecycle method, called before each update.\n *\n * **WARNING BE SURE** to call `super.updateTransition()` if overriding in your own custom implementation\n * @param engine\n * @param delta\n */\n updateTransition(engine, delta) {\n if (this.complete) {\n return;\n }\n this._currentDistance += clamp(delta / this.duration, 0, 1);\n if (this._currentDistance >= 1) {\n this._currentDistance = 1;\n }\n if (this.direction === 'out') {\n this._currentProgress = clamp(this.easing(this._currentDistance, 0, 1, 1), 0, 1);\n }\n else {\n this._currentProgress = clamp(this.easing(this._currentDistance, 1, 0, 1), 0, 1);\n }\n }\n /**\n * Overridable lifecycle method, called right before the previous scene has deactivated.\n *\n * This gives incoming transition a chance to grab info from previous scene if desired\n * @param scene\n */\n async onPreviousSceneDeactivate(scene) {\n // override me\n }\n /**\n * Overridable lifecycle method, called once at the beginning of the transition\n *\n * `progress` is given between 0 and 1\n * @param progress\n */\n onStart(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called every frame of the transition\n *\n * `progress` is given between 0 and 1\n * @param progress\n */\n onUpdate(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called at the end of the transition,\n *\n * `progress` is given between 0 and 1\n * @param progress\n */\n onEnd(progress) {\n // override me\n }\n /**\n * Overridable lifecycle method, called when the transition is reset\n *\n * Use this to override and provide your own reset logic for internal state in custom transition implementations\n */\n onReset() {\n // override me\n }\n /**\n * reset() is called by the engine to reset transitions\n */\n reset() {\n this.started = false;\n this._completeFuture = new Future();\n this.done = this._completeFuture.promise;\n this._currentDistance = 0;\n if (this.direction === 'out') {\n this._currentProgress = 0;\n }\n else {\n this._currentProgress = 1;\n }\n this.onReset();\n }\n play(engine) {\n if (this.started) {\n this._logger.warn(`Attempted to play a transition ${this.name} that is already playing`);\n return Promise.resolve();\n }\n engine.add(this);\n const self = this;\n return coroutine(engine, function* () {\n while (!self.complete) {\n const elapsed = yield; // per frame\n self.updateTransition(engine, elapsed);\n self.execute();\n }\n });\n }\n /**\n * execute() is called by the engine every frame to update the Transition lifecycle onStart/onUpdate/onEnd\n */\n execute() {\n if (!this.isInitialized) {\n return;\n }\n if (!this.started) {\n this.started = true;\n this.onStart(this.progress);\n }\n this.onUpdate(this.progress);\n if (this.complete && !this._completeFuture.isCompleted) {\n this.onEnd(this.progress);\n this._completeFuture.resolve();\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Director/FadeInOut.ts\n\n\n\n\nclass FadeInOut extends Transition {\n constructor(options) {\n var _a, _b;\n super({\n ...options,\n duration: (_a = options.duration) !== null && _a !== void 0 ? _a : 2000\n });\n this.name = `FadeInOut#${this.id}`;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n }\n onInitialize(engine) {\n const bounds = engine.screen.getWorldBounds();\n this.transform.pos = vec(bounds.left, bounds.top);\n this.screenCover = new Rectangle({\n width: bounds.width,\n height: bounds.height,\n color: this.color\n });\n this.graphics.add(this.screenCover);\n this.graphics.opacity = this.progress;\n }\n onReset() {\n this.graphics.opacity = this.progress;\n }\n onStart(progress) {\n this.graphics.opacity = progress;\n }\n onEnd(progress) {\n this.graphics.opacity = progress;\n }\n onUpdate(progress) {\n this.graphics.opacity = progress;\n }\n}\n\n;// CONCATENATED MODULE: ./Director/CrossFade.ts\n\n\n\n/**\n * CrossFades between the previous scene and the destination scene\n *\n * Note: CrossFade only works as an \"in\" transition\n */\nclass CrossFade extends Transition {\n constructor(options) {\n super({ direction: 'in', ...options }); // default the correct direction\n this.name = `CrossFade#${this.id}`;\n }\n async onPreviousSceneDeactivate(scene) {\n this.image = await scene.engine.screenshot(true);\n // Firefox is particularly slow\n // needed in case the image isn't ready yet\n await this.image.decode();\n }\n onInitialize(engine) {\n this.engine = engine;\n const bounds = engine.screen.getWorldBounds();\n this.transform.pos = vec(bounds.left, bounds.top);\n this.screenCover = ImageSource.fromHtmlImageElement(this.image).toSprite();\n this.graphics.add(this.screenCover);\n this.transform.scale = vec(1 / engine.screen.pixelRatio, 1 / engine.screen.pixelRatio);\n this.graphics.opacity = this.progress;\n }\n onStart(_progress) {\n this.graphics.opacity = this.progress;\n }\n onReset() {\n this.graphics.opacity = this.progress;\n }\n onEnd(progress) {\n this.graphics.opacity = progress;\n }\n onUpdate(progress) {\n this.graphics.opacity = progress;\n }\n}\n\n;// CONCATENATED MODULE: ./Director/index.ts\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Graphics/Line.ts\n\n\n\nclass Line extends Graphic {\n constructor(options) {\n super();\n this.color = Color.Black;\n this.thickness = 1;\n const { start, end, color, thickness } = options;\n this.start = start;\n this.end = end;\n this.color = color !== null && color !== void 0 ? color : this.color;\n this.thickness = thickness !== null && thickness !== void 0 ? thickness : this.thickness;\n this._localBounds = this._calculateBounds();\n const { width, height } = this._localBounds;\n this.width = width;\n this.height = height;\n }\n get localBounds() {\n return this._localBounds;\n }\n _calculateBounds() {\n const lineNormal = this.end.sub(this.start).normal();\n const halfThickness = this.thickness / 2;\n const points = [\n this.start.add(lineNormal.scale(halfThickness)),\n this.end.add(lineNormal.scale(halfThickness)),\n this.end.add(lineNormal.scale(-halfThickness)),\n this.start.add(lineNormal.scale(-halfThickness))\n ];\n return BoundingBox.fromPoints(points);\n }\n _drawImage(ctx, _x, _y) {\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\n }\n clone() {\n return new Line({\n start: this.start,\n end: this.end,\n color: this.color,\n thickness: this.thickness\n });\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/Polygon.ts\n\n\n\n/**\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\n *\n * Polygons default to [[ImageFiltering.Blended]]\n */\nclass Polygon extends Raster {\n get points() {\n return this._points;\n }\n set points(points) {\n this._points = points;\n const min = this.minPoint;\n this.width = this._points.reduce((max, p) => Math.max(p.x, max), 0) - min.x;\n this.height = this._points.reduce((max, p) => Math.max(p.y, max), 0) - min.y;\n this.flagDirty();\n }\n get minPoint() {\n const minX = this._points.reduce((min, p) => Math.min(p.x, min), Infinity);\n const minY = this._points.reduce((min, p) => Math.min(p.y, min), Infinity);\n return vec(minX, minY);\n }\n constructor(options) {\n super(options);\n this.points = options.points;\n this.filtering = ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Polygon({\n points: this.points.map((p) => p.clone()),\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.points && this.points.length) {\n ctx.beginPath();\n // Iterate through the supplied points and construct a 'polygon'\n const min = this.minPoint.negate();\n const firstPoint = this.points[0].add(min);\n ctx.moveTo(firstPoint.x, firstPoint.y);\n this.points.forEach((point) => {\n ctx.lineTo(point.x + min.x, point.y + min.y);\n });\n ctx.lineTo(firstPoint.x, firstPoint.y);\n ctx.closePath();\n if (this.color) {\n ctx.fill();\n }\n if (this.strokeColor) {\n ctx.stroke();\n }\n }\n }\n}\n\n;// CONCATENATED MODULE: ./Graphics/index.ts\n// Graphics\n\n\n\n\n\n\n\n// Graphics ECS\n\n\n\n\n\n// Raster graphics\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// Post Processor\n\n\n\n\n\n\n// Rendering\n\n\n\n\n\n// Debug\n\n// Util\n\n\n\n;// CONCATENATED MODULE: ./Input/Index.ts\n// This import site is deprecated\n// TODO remove deprecated exports in v0.29.0\n\n\n\n\n\n\n\n\n\n\n\n// Re-export hack to deprecate import site gently\n\n\n;// CONCATENATED MODULE: ./Util/Index.ts\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./Util/Decorators.ts\n\n\nconst maxMessages = 5;\nconst obsoleteMessage = {};\nconst resetObsoleteCounter = () => {\n for (const message in obsoleteMessage) {\n obsoleteMessage[message] = 0;\n }\n};\nconst logMessage = (message, options) => {\n const suppressObsoleteMessages = Flags.isEnabled('suppress-obsolete-message');\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\n Logger.getInstance().warn(message);\n // tslint:disable-next-line: no-console\n if (console.trace && options.showStackTrace) {\n // tslint:disable-next-line: no-console\n console.trace();\n }\n }\n obsoleteMessage[message]++;\n};\n/**\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\n */\nfunction obsolete(options) {\n options = {\n message: 'This feature will be removed in future versions of Excalibur.',\n alternateMethod: null,\n showStackTrace: false,\n ...options\n };\n return function (target, property, descriptor) {\n if (descriptor &&\n !(typeof descriptor.value === 'function' || typeof descriptor.get === 'function' || typeof descriptor.set === 'function')) {\n throw new SyntaxError('Only classes/functions/getters/setters can be marked as obsolete');\n }\n const methodSignature = `${target.name || ''}${target.name && property ? '.' : ''}${property ? property : ''}`;\n const message = `${methodSignature} is marked obsolete: ${options.message}` +\n (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : '');\n if (!obsoleteMessage[message]) {\n obsoleteMessage[message] = 0;\n }\n // If descriptor is null it is a class\n const method = descriptor ? { ...descriptor } : target;\n if (!descriptor) {\n // with es2015 classes we need to change our decoration tactic\n class DecoratedClass extends method {\n constructor(...args) {\n logMessage(message, options);\n super(...args);\n }\n }\n return DecoratedClass;\n }\n if (descriptor && descriptor.value) {\n method.value = function () {\n logMessage(message, options);\n return descriptor.value.apply(this, arguments);\n };\n return method;\n }\n if (descriptor && descriptor.get) {\n method.get = function () {\n logMessage(message, options);\n return descriptor.get.apply(this, arguments);\n };\n }\n if (descriptor && descriptor.set) {\n method.set = function () {\n logMessage(message, options);\n return descriptor.set.apply(this, arguments);\n };\n }\n return method;\n };\n}\n\n;// CONCATENATED MODULE: ./Util/Semaphore.ts\n\nclass AsyncWaitQueue {\n constructor() {\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\n this._queue = [];\n }\n get length() {\n return this._queue.length;\n }\n enqueue() {\n const future = new Future();\n this._queue.push(future);\n return future.promise;\n }\n dequeue(value) {\n const future = this._queue.shift();\n future.resolve(value);\n }\n}\n/**\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\n *\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\n * around browser limitations like max Image.decode() calls in chromium being 256.\n */\nclass Semaphore {\n constructor(_count) {\n this._count = _count;\n this._waitQueue = new AsyncWaitQueue();\n }\n get count() {\n return this._count;\n }\n get waiting() {\n return this._waitQueue.length;\n }\n // eslint-disable-next-line require-await\n async enter() {\n if (this._count !== 0) {\n this._count--;\n return Promise.resolve();\n }\n return this._waitQueue.enqueue();\n }\n exit(count = 1) {\n if (count === 0) {\n return;\n }\n while (count !== 0 && this._waitQueue.length !== 0) {\n this._waitQueue.dequeue(null);\n count--;\n }\n this._count += count;\n }\n}\n\n;// CONCATENATED MODULE: ./index.ts\n/**\n * The current Excalibur version string\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\n */\nconst EX_VERSION = \"0.29.0\";\n\npolyfill();\n// This file is used as the bundle entry point and exports everything\n// that will be exposed as the `ex` global variable.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// ex.Events namespace\n\n\n// ex.Input namespace\n// TODO deprecated import site remove in v0.29.0\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// ex.Util namespaces\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// ex.Deprecated\n// import * as deprecated from './Deprecated';\n// export { deprecated as Deprecated };\n// export * from './Deprecated';\n\n})();\n\nvar __webpack_exports__ActionCompleteEvent = __webpack_exports__.y1j;\nvar __webpack_exports__ActionContext = __webpack_exports__.fWn;\nvar __webpack_exports__ActionQueue = __webpack_exports__.Ia8;\nvar __webpack_exports__ActionSequence = __webpack_exports__.rqv;\nvar __webpack_exports__ActionStartEvent = __webpack_exports__.zH6;\nvar __webpack_exports__ActionsComponent = __webpack_exports__.hLI;\nvar __webpack_exports__ActionsSystem = __webpack_exports__.yyv;\nvar __webpack_exports__ActivateEvent = __webpack_exports__.tX5;\nvar __webpack_exports__Actor = __webpack_exports__.vtX;\nvar __webpack_exports__AddedComponent = __webpack_exports__.r7K;\nvar __webpack_exports__AffineMatrix = __webpack_exports__.cE4;\nvar __webpack_exports__Animation = __webpack_exports__.fwF;\nvar __webpack_exports__AnimationDirection = __webpack_exports__.sce;\nvar __webpack_exports__AnimationEvents = __webpack_exports__.AQ6;\nvar __webpack_exports__AnimationStrategy = __webpack_exports__._c7;\nvar __webpack_exports__ArcadeSolver = __webpack_exports__.KUs;\nvar __webpack_exports__AudioContextFactory = __webpack_exports__.Ajp;\nvar __webpack_exports__Axes = __webpack_exports__.dkO;\nvar __webpack_exports__Axis = __webpack_exports__.RDh;\nvar __webpack_exports__BaseAlign = __webpack_exports__._H9;\nvar __webpack_exports__Blink = __webpack_exports__.mxs;\nvar __webpack_exports__BodyComponent = __webpack_exports__.OmD;\nvar __webpack_exports__BoundingBox = __webpack_exports__.kBf;\nvar __webpack_exports__BroadphaseStrategy = __webpack_exports__.C4F;\nvar __webpack_exports__BrowserComponent = __webpack_exports__.NQt;\nvar __webpack_exports__BrowserEvents = __webpack_exports__.JjN;\nvar __webpack_exports__Buttons = __webpack_exports__.EK_;\nvar __webpack_exports__Camera = __webpack_exports__.V1s;\nvar __webpack_exports__CameraEvents = __webpack_exports__.xHm;\nvar __webpack_exports__Canvas = __webpack_exports__.Xz7;\nvar __webpack_exports__Circle = __webpack_exports__.Cdc;\nvar __webpack_exports__CircleCollider = __webpack_exports__.FKn;\nvar __webpack_exports__Clock = __webpack_exports__.SUY;\nvar __webpack_exports__ClosestLine = __webpack_exports__.ab2;\nvar __webpack_exports__ClosestLineJumpTable = __webpack_exports__.GfZ;\nvar __webpack_exports__Collider = __webpack_exports__.YMS;\nvar __webpack_exports__ColliderComponent = __webpack_exports__.oyv;\nvar __webpack_exports__CollisionContact = __webpack_exports__.aUb;\nvar __webpack_exports__CollisionEndEvent = __webpack_exports__.SdD;\nvar __webpack_exports__CollisionGroup = __webpack_exports__.JUv;\nvar __webpack_exports__CollisionGroupManager = __webpack_exports__.jEj;\nvar __webpack_exports__CollisionJumpTable = __webpack_exports__.TFq;\nvar __webpack_exports__CollisionPostSolveEvent = __webpack_exports__.HDU;\nvar __webpack_exports__CollisionPreSolveEvent = __webpack_exports__.R_y;\nvar __webpack_exports__CollisionStartEvent = __webpack_exports__.t50;\nvar __webpack_exports__CollisionSystem = __webpack_exports__.s$$;\nvar __webpack_exports__CollisionType = __webpack_exports__.v2G;\nvar __webpack_exports__Color = __webpack_exports__.Ilk;\nvar __webpack_exports__ColorBlindFlags = __webpack_exports__.s9i;\nvar __webpack_exports__ColorBlindnessMode = __webpack_exports__.dxL;\nvar __webpack_exports__ColorBlindnessPostProcessor = __webpack_exports__.LLX;\nvar __webpack_exports__Component = __webpack_exports__.wA2;\nvar __webpack_exports__CompositeCollider = __webpack_exports__.R_p;\nvar __webpack_exports__Configurable = __webpack_exports__.IQ$;\nvar __webpack_exports__ConsoleAppender = __webpack_exports__.I5F;\nvar __webpack_exports__ContactConstraintPoint = __webpack_exports__.X8$;\nvar __webpack_exports__ContactEndEvent = __webpack_exports__.FR6;\nvar __webpack_exports__ContactSolveBias = __webpack_exports__.pTZ;\nvar __webpack_exports__ContactStartEvent = __webpack_exports__.U8o;\nvar __webpack_exports__CoordPlane = __webpack_exports__.kbG;\nvar __webpack_exports__CrossFade = __webpack_exports__.FEv;\nvar __webpack_exports__DeactivateEvent = __webpack_exports__.iS_;\nvar __webpack_exports__Debug = __webpack_exports__.cGG;\nvar __webpack_exports__DebugConfig = __webpack_exports__.ETM;\nvar __webpack_exports__DebugGraphicsComponent = __webpack_exports__.RPN;\nvar __webpack_exports__DebugSystem = __webpack_exports__.skb;\nvar __webpack_exports__DebugText = __webpack_exports__.SLU;\nvar __webpack_exports__DefaultAntialiasOptions = __webpack_exports__.Q3w;\nvar __webpack_exports__DefaultLoader = __webpack_exports__.xK2;\nvar __webpack_exports__DefaultPhysicsConfig = __webpack_exports__.vrO;\nvar __webpack_exports__DefaultPixelArtOptions = __webpack_exports__.EA2;\nvar __webpack_exports__DegreeOfFreedom = __webpack_exports__.RdJ;\nvar __webpack_exports__Delay = __webpack_exports__.cNu;\nvar __webpack_exports__DeprecatedStaticToConfig = __webpack_exports__.wtG;\nvar __webpack_exports__Detector = __webpack_exports__.gU7;\nvar __webpack_exports__Die = __webpack_exports__.LSk;\nvar __webpack_exports__Direction = __webpack_exports__.Nmp;\nvar __webpack_exports__Director = __webpack_exports__.twX;\nvar __webpack_exports__DirectorEvents = __webpack_exports__.UND;\nvar __webpack_exports__DisplayMode = __webpack_exports__.d1Y;\nvar __webpack_exports__DynamicTree = __webpack_exports__.xrL;\nvar __webpack_exports__DynamicTreeCollisionProcessor = __webpack_exports__.sRW;\nvar __webpack_exports__EX_VERSION = __webpack_exports__.cmV;\nvar __webpack_exports__EaseBy = __webpack_exports__.qWz;\nvar __webpack_exports__EaseTo = __webpack_exports__.N0Q;\nvar __webpack_exports__EasingFunctions = __webpack_exports__.q8b;\nvar __webpack_exports__EdgeCollider = __webpack_exports__.ynB;\nvar __webpack_exports__ElasticToActorStrategy = __webpack_exports__.jT9;\nvar __webpack_exports__EmitterType = __webpack_exports__.wAz;\nvar __webpack_exports__Engine = __webpack_exports__.D4V;\nvar __webpack_exports__EngineEvents = __webpack_exports__.NLr;\nvar __webpack_exports__EnterTriggerEvent = __webpack_exports__.N6H;\nvar __webpack_exports__EnterViewPortEvent = __webpack_exports__.W1A;\nvar __webpack_exports__Entity = __webpack_exports__.JHW;\nvar __webpack_exports__EntityEvents = __webpack_exports__.ZZ$;\nvar __webpack_exports__EntityManager = __webpack_exports__.v2K;\nvar __webpack_exports__EventDispatcher = __webpack_exports__.pBf;\nvar __webpack_exports__EventEmitter = __webpack_exports__.vpe;\nvar __webpack_exports__EventTypes = __webpack_exports__.GMl;\nvar __webpack_exports__Events = __webpack_exports__.zW2;\nvar __webpack_exports__ExResponse = __webpack_exports__.B0K;\nvar __webpack_exports__ExcaliburGraphicsContext2DCanvas = __webpack_exports__.Nv7;\nvar __webpack_exports__ExcaliburGraphicsContextWebGL = __webpack_exports__.C_p;\nvar __webpack_exports__ExitTriggerEvent = __webpack_exports__.MUA;\nvar __webpack_exports__ExitViewPortEvent = __webpack_exports__.xqU;\nvar __webpack_exports__Fade = __webpack_exports__.pTp;\nvar __webpack_exports__FadeInOut = __webpack_exports__.trb;\nvar __webpack_exports__Flags = __webpack_exports__.vUK;\nvar __webpack_exports__Follow = __webpack_exports__.j9l;\nvar __webpack_exports__Font = __webpack_exports__.Zxw;\nvar __webpack_exports__FontCache = __webpack_exports__.v51;\nvar __webpack_exports__FontSource = __webpack_exports__.gYv;\nvar __webpack_exports__FontStyle = __webpack_exports__.Hdx;\nvar __webpack_exports__FontUnit = __webpack_exports__.Z$d;\nvar __webpack_exports__FpsSampler = __webpack_exports__.iqV;\nvar __webpack_exports__FrameStats = __webpack_exports__.o$7;\nvar __webpack_exports__Future = __webpack_exports__.olM;\nvar __webpack_exports__GameEvent = __webpack_exports__.Zm$;\nvar __webpack_exports__GameStartEvent = __webpack_exports__.$QH;\nvar __webpack_exports__GameStopEvent = __webpack_exports__.i78;\nvar __webpack_exports__Gamepad = __webpack_exports__.nJg;\nvar __webpack_exports__GamepadAxisEvent = __webpack_exports__.h6u;\nvar __webpack_exports__GamepadButtonEvent = __webpack_exports__.hts;\nvar __webpack_exports__GamepadConnectEvent = __webpack_exports__.j88;\nvar __webpack_exports__GamepadDisconnectEvent = __webpack_exports__.VME;\nvar __webpack_exports__Gamepads = __webpack_exports__.fy2;\nvar __webpack_exports__Gif = __webpack_exports__.nt;\nvar __webpack_exports__GlobalCoordinates = __webpack_exports__.Ukr;\nvar __webpack_exports__Graphic = __webpack_exports__.zsu;\nvar __webpack_exports__GraphicsComponent = __webpack_exports__.oA6;\nvar __webpack_exports__GraphicsGroup = __webpack_exports__.TVh;\nvar __webpack_exports__GraphicsSystem = __webpack_exports__.xxj;\nvar __webpack_exports__HiddenEvent = __webpack_exports__.XdK;\nvar __webpack_exports__HorizontalFirst = __webpack_exports__.fBD;\nvar __webpack_exports__ImageFiltering = __webpack_exports__.Jmb;\nvar __webpack_exports__ImageSource = __webpack_exports__.cXo;\nvar __webpack_exports__InitializeEvent = __webpack_exports__.Dm5;\nvar __webpack_exports__Input = __webpack_exports__.IIB;\nvar __webpack_exports__InputHost = __webpack_exports__.IX$;\nvar __webpack_exports__InputMapper = __webpack_exports__.ebW;\nvar __webpack_exports__Integrator = __webpack_exports__.zI0;\nvar __webpack_exports__IsometricEntityComponent = __webpack_exports__.LYD;\nvar __webpack_exports__IsometricEntitySystem = __webpack_exports__.cEG;\nvar __webpack_exports__IsometricMap = __webpack_exports__.SEl;\nvar __webpack_exports__IsometricTile = __webpack_exports__.t9V;\nvar __webpack_exports__KeyEvent = __webpack_exports__.ez5;\nvar __webpack_exports__Keyboard = __webpack_exports__.N1d;\nvar __webpack_exports__Keys = __webpack_exports__.R8U;\nvar __webpack_exports__KillEvent = __webpack_exports__.SKZ;\nvar __webpack_exports__Label = __webpack_exports__.__J;\nvar __webpack_exports__LimitCameraBoundsStrategy = __webpack_exports__.RI$;\nvar __webpack_exports__Line = __webpack_exports__.x12;\nvar __webpack_exports__LineSegment = __webpack_exports__.ccz;\nvar __webpack_exports__Loader = __webpack_exports__.aNw;\nvar __webpack_exports__LoaderEvents = __webpack_exports__.XrL;\nvar __webpack_exports__LockCameraToActorAxisStrategy = __webpack_exports__.xwn;\nvar __webpack_exports__LockCameraToActorStrategy = __webpack_exports__.dNK;\nvar __webpack_exports__LogLevel = __webpack_exports__.ini;\nvar __webpack_exports__Logger = __webpack_exports__.YdH;\nvar __webpack_exports__Material = __webpack_exports__.F5T;\nvar __webpack_exports__Matrix = __webpack_exports__.y3G;\nvar __webpack_exports__MatrixLocations = __webpack_exports__.l57;\nvar __webpack_exports__MediaEvent = __webpack_exports__.xn0;\nvar __webpack_exports__Meet = __webpack_exports__.t2V;\nvar __webpack_exports__MotionComponent = __webpack_exports__.uxB;\nvar __webpack_exports__MotionSystem = __webpack_exports__.cpd;\nvar __webpack_exports__MoveBy = __webpack_exports__.fiy;\nvar __webpack_exports__MoveTo = __webpack_exports__.$XZ;\nvar __webpack_exports__NativePointerButton = __webpack_exports__.UG6;\nvar __webpack_exports__NativeSoundEvent = __webpack_exports__.uqK;\nvar __webpack_exports__NativeSoundProcessedEvent = __webpack_exports__.STE;\nvar __webpack_exports__None = __webpack_exports__.Hq9;\nvar __webpack_exports__Observable = __webpack_exports__.y$z;\nvar __webpack_exports__OffscreenSystem = __webpack_exports__.mAD;\nvar __webpack_exports__Pair = __webpack_exports__.sOq;\nvar __webpack_exports__ParallaxComponent = __webpack_exports__.hUw;\nvar __webpack_exports__ParallelActions = __webpack_exports__._0G;\nvar __webpack_exports__ParseGif = __webpack_exports__.Sqs;\nvar __webpack_exports__Particle = __webpack_exports__.hpZ;\nvar __webpack_exports__ParticleEmitter = __webpack_exports__.Vol;\nvar __webpack_exports__ParticleTransform = __webpack_exports__.vYX;\nvar __webpack_exports__Physics = __webpack_exports__.wIZ;\nvar __webpack_exports__PhysicsStats = __webpack_exports__.cBi;\nvar __webpack_exports__PhysicsWorld = __webpack_exports__.c30;\nvar __webpack_exports__PointerAbstraction = __webpack_exports__.PGK;\nvar __webpack_exports__PointerButton = __webpack_exports__.MPV;\nvar __webpack_exports__PointerComponent = __webpack_exports__.RFv;\nvar __webpack_exports__PointerEvent = __webpack_exports__.Ux6;\nvar __webpack_exports__PointerEventReceiver = __webpack_exports__.rxy;\nvar __webpack_exports__PointerScope = __webpack_exports__.I$c;\nvar __webpack_exports__PointerSystem = __webpack_exports__.kfC;\nvar __webpack_exports__PointerType = __webpack_exports__.VjY;\nvar __webpack_exports__Polygon = __webpack_exports__.mgq;\nvar __webpack_exports__PolygonCollider = __webpack_exports__.YVA;\nvar __webpack_exports__Pool = __webpack_exports__.Kgp;\nvar __webpack_exports__PostCollisionEvent = __webpack_exports__.HH$;\nvar __webpack_exports__PostDebugDrawEvent = __webpack_exports__.M_d;\nvar __webpack_exports__PostDrawEvent = __webpack_exports__.rgh;\nvar __webpack_exports__PostFrameEvent = __webpack_exports__.Ra6;\nvar __webpack_exports__PostKillEvent = __webpack_exports__.KhR;\nvar __webpack_exports__PostTransformDrawEvent = __webpack_exports__.gvQ;\nvar __webpack_exports__PostUpdateEvent = __webpack_exports__.BS5;\nvar __webpack_exports__PreCollisionEvent = __webpack_exports__.xhz;\nvar __webpack_exports__PreDebugDrawEvent = __webpack_exports__.xOq;\nvar __webpack_exports__PreDrawEvent = __webpack_exports__.a9j;\nvar __webpack_exports__PreFrameEvent = __webpack_exports__.bHk;\nvar __webpack_exports__PreKillEvent = __webpack_exports__.CgK;\nvar __webpack_exports__PreLoadEvent = __webpack_exports__.A0M;\nvar __webpack_exports__PreTransformDrawEvent = __webpack_exports__.cEd;\nvar __webpack_exports__PreUpdateEvent = __webpack_exports__.cuY;\nvar __webpack_exports__Projection = __webpack_exports__.kvE;\nvar __webpack_exports__QuadIndexBuffer = __webpack_exports__.SBu;\nvar __webpack_exports__QuadTree = __webpack_exports__.PsT;\nvar __webpack_exports__Query = __webpack_exports__.AE_;\nvar __webpack_exports__QueryManager = __webpack_exports__.ctO;\nvar __webpack_exports__RadiusAroundActorStrategy = __webpack_exports__.OLH;\nvar __webpack_exports__Random = __webpack_exports__.kky;\nvar __webpack_exports__Raster = __webpack_exports__.nSF;\nvar __webpack_exports__Ray = __webpack_exports__.zHn;\nvar __webpack_exports__RealisticSolver = __webpack_exports__.zwx;\nvar __webpack_exports__Rectangle = __webpack_exports__.AeJ;\nvar __webpack_exports__RemovedComponent = __webpack_exports__.hLz;\nvar __webpack_exports__Repeat = __webpack_exports__.wA;\nvar __webpack_exports__RepeatForever = __webpack_exports__.jhr;\nvar __webpack_exports__Resolution = __webpack_exports__.GVs;\nvar __webpack_exports__Resource = __webpack_exports__._zO;\nvar __webpack_exports__ResourceEvents = __webpack_exports__.LXZ;\nvar __webpack_exports__RotateBy = __webpack_exports__.w6$;\nvar __webpack_exports__RotateTo = __webpack_exports__.mhV;\nvar __webpack_exports__RotationType = __webpack_exports__.MOD;\nvar __webpack_exports__ScaleBy = __webpack_exports__.kwd;\nvar __webpack_exports__ScaleTo = __webpack_exports__.Lmr;\nvar __webpack_exports__Scene = __webpack_exports__.xsS;\nvar __webpack_exports__SceneEvents = __webpack_exports__.K5l;\nvar __webpack_exports__Screen = __webpack_exports__.lLr;\nvar __webpack_exports__ScreenAppender = __webpack_exports__.Z$r;\nvar __webpack_exports__ScreenElement = __webpack_exports__.IXb;\nvar __webpack_exports__ScreenEvents = __webpack_exports__.Xsu;\nvar __webpack_exports__ScreenShader = __webpack_exports__.SGH;\nvar __webpack_exports__ScrollPreventionMode = __webpack_exports__.SMj;\nvar __webpack_exports__Semaphore = __webpack_exports__.L34;\nvar __webpack_exports__Shader = __webpack_exports__.exe;\nvar __webpack_exports__Shape = __webpack_exports__.bnF;\nvar __webpack_exports__Side = __webpack_exports__.MFA;\nvar __webpack_exports__SolverStrategy = __webpack_exports__.kPj;\nvar __webpack_exports__Sound = __webpack_exports__.$uU;\nvar __webpack_exports__SoundEvents = __webpack_exports__.Sap;\nvar __webpack_exports__Sprite = __webpack_exports__.jyi;\nvar __webpack_exports__SpriteFont = __webpack_exports__.E03;\nvar __webpack_exports__SpriteSheet = __webpack_exports__.V6q;\nvar __webpack_exports__StandardClock = __webpack_exports__.rg2;\nvar __webpack_exports__StateMachine = __webpack_exports__.DVW;\nvar __webpack_exports__StrategyContainer = __webpack_exports__.nVo;\nvar __webpack_exports__Stream = __webpack_exports__.F6N;\nvar __webpack_exports__System = __webpack_exports__.xP7;\nvar __webpack_exports__SystemManager = __webpack_exports__.Odq;\nvar __webpack_exports__SystemPriority = __webpack_exports__.uY9;\nvar __webpack_exports__SystemType = __webpack_exports__.Zif;\nvar __webpack_exports__TagQuery = __webpack_exports__.c_d;\nvar __webpack_exports__TestClock = __webpack_exports__.MJk;\nvar __webpack_exports__Text = __webpack_exports__.xvT;\nvar __webpack_exports__TextAlign = __webpack_exports__.PHM;\nvar __webpack_exports__TextureLoader = __webpack_exports__.dpR;\nvar __webpack_exports__Tile = __webpack_exports__.n9L;\nvar __webpack_exports__TileMap = __webpack_exports__.KwO;\nvar __webpack_exports__TileMapEvents = __webpack_exports__.SxM;\nvar __webpack_exports__Timer = __webpack_exports__.B7y;\nvar __webpack_exports__Toaster = __webpack_exports__.x7r;\nvar __webpack_exports__Transform = __webpack_exports__.wx7;\nvar __webpack_exports__TransformComponent = __webpack_exports__.Uvn;\nvar __webpack_exports__Transition = __webpack_exports__.uTP;\nvar __webpack_exports__TreeNode = __webpack_exports__.OFT;\nvar __webpack_exports__Trigger = __webpack_exports__.xzN;\nvar __webpack_exports__TriggerEvents = __webpack_exports__.CcZ;\nvar __webpack_exports__TwoPI = __webpack_exports__.M5Z;\nvar __webpack_exports__Util = __webpack_exports__.ZrN;\nvar __webpack_exports__Vector = __webpack_exports__.OWs;\nvar __webpack_exports__VectorView = __webpack_exports__.dF9;\nvar __webpack_exports__VertexBuffer = __webpack_exports__.oZy;\nvar __webpack_exports__VertexLayout = __webpack_exports__.rD2;\nvar __webpack_exports__VerticalFirst = __webpack_exports__.KmN;\nvar __webpack_exports__VisibleEvent = __webpack_exports__.VHo;\nvar __webpack_exports__WebAudio = __webpack_exports__.ohE;\nvar __webpack_exports__WebAudioInstance = __webpack_exports__.R$E;\nvar __webpack_exports__WheelDeltaMode = __webpack_exports__.xQN;\nvar __webpack_exports__WheelEvent = __webpack_exports__.AdJ;\nvar __webpack_exports__World = __webpack_exports__.q3I;\nvar __webpack_exports__canonicalizeAngle = __webpack_exports__.Pab;\nvar __webpack_exports__clamp = __webpack_exports__.uZ5;\nvar __webpack_exports__coroutine = __webpack_exports__.TAE;\nvar __webpack_exports__createId = __webpack_exports__.McK;\nvar __webpack_exports__frac = __webpack_exports__.F9c;\nvar __webpack_exports__hasGraphicsTick = __webpack_exports__.k0b;\nvar __webpack_exports__hasOnInitialize = __webpack_exports__.hnT;\nvar __webpack_exports__hasOnPostUpdate = __webpack_exports__.RSJ;\nvar __webpack_exports__hasOnPreUpdate = __webpack_exports__.Mku;\nvar __webpack_exports__hasPostDraw = __webpack_exports__.h90;\nvar __webpack_exports__hasPreDraw = __webpack_exports__.rms;\nvar __webpack_exports__has_initialize = __webpack_exports__.ErP;\nvar __webpack_exports__has_postupdate = __webpack_exports__.aVg;\nvar __webpack_exports__has_preupdate = __webpack_exports__.lPc;\nvar __webpack_exports__isAddedComponent = __webpack_exports__.Z8E;\nvar __webpack_exports__isComponentCtor = __webpack_exports__.k15;\nvar __webpack_exports__isLoaderConstructor = __webpack_exports__.YsU;\nvar __webpack_exports__isRemovedComponent = __webpack_exports__.lNv;\nvar __webpack_exports__isSceneConstructor = __webpack_exports__.Xyg;\nvar __webpack_exports__isScreenElement = __webpack_exports__.cu9;\nvar __webpack_exports__isSystemConstructor = __webpack_exports__.p88;\nvar __webpack_exports__maxMessages = __webpack_exports__.MZQ;\nvar __webpack_exports__obsolete = __webpack_exports__.FUM;\nvar __webpack_exports__pixelSnapEpsilon = __webpack_exports__.BxR;\nvar __webpack_exports__randomInRange = __webpack_exports__.vdf;\nvar __webpack_exports__randomIntInRange = __webpack_exports__.iaL;\nvar __webpack_exports__range = __webpack_exports__.w6H;\nvar __webpack_exports__resetObsoleteCounter = __webpack_exports__.Q4c;\nvar __webpack_exports__sign = __webpack_exports__.Xxe;\nvar __webpack_exports__toDegrees = __webpack_exports__.Uxb;\nvar __webpack_exports__toRadians = __webpack_exports__.Yr5;\nvar __webpack_exports__vec = __webpack_exports__.Bhw;\nvar __webpack_exports__webgl = __webpack_exports__.yOA;\nexport { __webpack_exports__ActionCompleteEvent as ActionCompleteEvent, __webpack_exports__ActionContext as ActionContext, __webpack_exports__ActionQueue as ActionQueue, __webpack_exports__ActionSequence as ActionSequence, __webpack_exports__ActionStartEvent as ActionStartEvent, __webpack_exports__ActionsComponent as ActionsComponent, __webpack_exports__ActionsSystem as ActionsSystem, __webpack_exports__ActivateEvent as ActivateEvent, __webpack_exports__Actor as Actor, __webpack_exports__AddedComponent as AddedComponent, __webpack_exports__AffineMatrix as AffineMatrix, __webpack_exports__Animation as Animation, __webpack_exports__AnimationDirection as AnimationDirection, __webpack_exports__AnimationEvents as AnimationEvents, __webpack_exports__AnimationStrategy as AnimationStrategy, __webpack_exports__ArcadeSolver as ArcadeSolver, __webpack_exports__AudioContextFactory as AudioContextFactory, __webpack_exports__Axes as Axes, __webpack_exports__Axis as Axis, __webpack_exports__BaseAlign as BaseAlign, __webpack_exports__Blink as Blink, __webpack_exports__BodyComponent as BodyComponent, __webpack_exports__BoundingBox as BoundingBox, __webpack_exports__BroadphaseStrategy as BroadphaseStrategy, __webpack_exports__BrowserComponent as BrowserComponent, __webpack_exports__BrowserEvents as BrowserEvents, __webpack_exports__Buttons as Buttons, __webpack_exports__Camera as Camera, __webpack_exports__CameraEvents as CameraEvents, __webpack_exports__Canvas as Canvas, __webpack_exports__Circle as Circle, __webpack_exports__CircleCollider as CircleCollider, __webpack_exports__Clock as Clock, __webpack_exports__ClosestLine as ClosestLine, __webpack_exports__ClosestLineJumpTable as ClosestLineJumpTable, __webpack_exports__Collider as Collider, __webpack_exports__ColliderComponent as ColliderComponent, __webpack_exports__CollisionContact as CollisionContact, __webpack_exports__CollisionEndEvent as CollisionEndEvent, __webpack_exports__CollisionGroup as CollisionGroup, __webpack_exports__CollisionGroupManager as CollisionGroupManager, __webpack_exports__CollisionJumpTable as CollisionJumpTable, __webpack_exports__CollisionPostSolveEvent as CollisionPostSolveEvent, __webpack_exports__CollisionPreSolveEvent as CollisionPreSolveEvent, __webpack_exports__CollisionStartEvent as CollisionStartEvent, __webpack_exports__CollisionSystem as CollisionSystem, __webpack_exports__CollisionType as CollisionType, __webpack_exports__Color as Color, __webpack_exports__ColorBlindFlags as ColorBlindFlags, __webpack_exports__ColorBlindnessMode as ColorBlindnessMode, __webpack_exports__ColorBlindnessPostProcessor as ColorBlindnessPostProcessor, __webpack_exports__Component as Component, __webpack_exports__CompositeCollider as CompositeCollider, __webpack_exports__Configurable as Configurable, __webpack_exports__ConsoleAppender as ConsoleAppender, __webpack_exports__ContactConstraintPoint as ContactConstraintPoint, __webpack_exports__ContactEndEvent as ContactEndEvent, __webpack_exports__ContactSolveBias as ContactSolveBias, __webpack_exports__ContactStartEvent as ContactStartEvent, __webpack_exports__CoordPlane as CoordPlane, __webpack_exports__CrossFade as CrossFade, __webpack_exports__DeactivateEvent as DeactivateEvent, __webpack_exports__Debug as Debug, __webpack_exports__DebugConfig as DebugConfig, __webpack_exports__DebugGraphicsComponent as DebugGraphicsComponent, __webpack_exports__DebugSystem as DebugSystem, __webpack_exports__DebugText as DebugText, __webpack_exports__DefaultAntialiasOptions as DefaultAntialiasOptions, __webpack_exports__DefaultLoader as DefaultLoader, __webpack_exports__DefaultPhysicsConfig as DefaultPhysicsConfig, __webpack_exports__DefaultPixelArtOptions as DefaultPixelArtOptions, __webpack_exports__DegreeOfFreedom as DegreeOfFreedom, __webpack_exports__Delay as Delay, __webpack_exports__DeprecatedStaticToConfig as DeprecatedStaticToConfig, __webpack_exports__Detector as Detector, __webpack_exports__Die as Die, __webpack_exports__Direction as Direction, __webpack_exports__Director as Director, __webpack_exports__DirectorEvents as DirectorEvents, __webpack_exports__DisplayMode as DisplayMode, __webpack_exports__DynamicTree as DynamicTree, __webpack_exports__DynamicTreeCollisionProcessor as DynamicTreeCollisionProcessor, __webpack_exports__EX_VERSION as EX_VERSION, __webpack_exports__EaseBy as EaseBy, __webpack_exports__EaseTo as EaseTo, __webpack_exports__EasingFunctions as EasingFunctions, __webpack_exports__EdgeCollider as EdgeCollider, __webpack_exports__ElasticToActorStrategy as ElasticToActorStrategy, __webpack_exports__EmitterType as EmitterType, __webpack_exports__Engine as Engine, __webpack_exports__EngineEvents as EngineEvents, __webpack_exports__EnterTriggerEvent as EnterTriggerEvent, __webpack_exports__EnterViewPortEvent as EnterViewPortEvent, __webpack_exports__Entity as Entity, __webpack_exports__EntityEvents as EntityEvents, __webpack_exports__EntityManager as EntityManager, __webpack_exports__EventDispatcher as EventDispatcher, __webpack_exports__EventEmitter as EventEmitter, __webpack_exports__EventTypes as EventTypes, __webpack_exports__Events as Events, __webpack_exports__ExResponse as ExResponse, __webpack_exports__ExcaliburGraphicsContext2DCanvas as ExcaliburGraphicsContext2DCanvas, __webpack_exports__ExcaliburGraphicsContextWebGL as ExcaliburGraphicsContextWebGL, __webpack_exports__ExitTriggerEvent as ExitTriggerEvent, __webpack_exports__ExitViewPortEvent as ExitViewPortEvent, __webpack_exports__Fade as Fade, __webpack_exports__FadeInOut as FadeInOut, __webpack_exports__Flags as Flags, __webpack_exports__Follow as Follow, __webpack_exports__Font as Font, __webpack_exports__FontCache as FontCache, __webpack_exports__FontSource as FontSource, __webpack_exports__FontStyle as FontStyle, __webpack_exports__FontUnit as FontUnit, __webpack_exports__FpsSampler as FpsSampler, __webpack_exports__FrameStats as FrameStats, __webpack_exports__Future as Future, __webpack_exports__GameEvent as GameEvent, __webpack_exports__GameStartEvent as GameStartEvent, __webpack_exports__GameStopEvent as GameStopEvent, __webpack_exports__Gamepad as Gamepad, __webpack_exports__GamepadAxisEvent as GamepadAxisEvent, __webpack_exports__GamepadButtonEvent as GamepadButtonEvent, __webpack_exports__GamepadConnectEvent as GamepadConnectEvent, __webpack_exports__GamepadDisconnectEvent as GamepadDisconnectEvent, __webpack_exports__Gamepads as Gamepads, __webpack_exports__Gif as Gif, __webpack_exports__GlobalCoordinates as GlobalCoordinates, __webpack_exports__Graphic as Graphic, __webpack_exports__GraphicsComponent as GraphicsComponent, __webpack_exports__GraphicsGroup as GraphicsGroup, __webpack_exports__GraphicsSystem as GraphicsSystem, __webpack_exports__HiddenEvent as HiddenEvent, __webpack_exports__HorizontalFirst as HorizontalFirst, __webpack_exports__ImageFiltering as ImageFiltering, __webpack_exports__ImageSource as ImageSource, __webpack_exports__InitializeEvent as InitializeEvent, __webpack_exports__Input as Input, __webpack_exports__InputHost as InputHost, __webpack_exports__InputMapper as InputMapper, __webpack_exports__Integrator as Integrator, __webpack_exports__IsometricEntityComponent as IsometricEntityComponent, __webpack_exports__IsometricEntitySystem as IsometricEntitySystem, __webpack_exports__IsometricMap as IsometricMap, __webpack_exports__IsometricTile as IsometricTile, __webpack_exports__KeyEvent as KeyEvent, __webpack_exports__Keyboard as Keyboard, __webpack_exports__Keys as Keys, __webpack_exports__KillEvent as KillEvent, __webpack_exports__Label as Label, __webpack_exports__LimitCameraBoundsStrategy as LimitCameraBoundsStrategy, __webpack_exports__Line as Line, __webpack_exports__LineSegment as LineSegment, __webpack_exports__Loader as Loader, __webpack_exports__LoaderEvents as LoaderEvents, __webpack_exports__LockCameraToActorAxisStrategy as LockCameraToActorAxisStrategy, __webpack_exports__LockCameraToActorStrategy as LockCameraToActorStrategy, __webpack_exports__LogLevel as LogLevel, __webpack_exports__Logger as Logger, __webpack_exports__Material as Material, __webpack_exports__Matrix as Matrix, __webpack_exports__MatrixLocations as MatrixLocations, __webpack_exports__MediaEvent as MediaEvent, __webpack_exports__Meet as Meet, __webpack_exports__MotionComponent as MotionComponent, __webpack_exports__MotionSystem as MotionSystem, __webpack_exports__MoveBy as MoveBy, __webpack_exports__MoveTo as MoveTo, __webpack_exports__NativePointerButton as NativePointerButton, __webpack_exports__NativeSoundEvent as NativeSoundEvent, __webpack_exports__NativeSoundProcessedEvent as NativeSoundProcessedEvent, __webpack_exports__None as None, __webpack_exports__Observable as Observable, __webpack_exports__OffscreenSystem as OffscreenSystem, __webpack_exports__Pair as Pair, __webpack_exports__ParallaxComponent as ParallaxComponent, __webpack_exports__ParallelActions as ParallelActions, __webpack_exports__ParseGif as ParseGif, __webpack_exports__Particle as Particle, __webpack_exports__ParticleEmitter as ParticleEmitter, __webpack_exports__ParticleTransform as ParticleTransform, __webpack_exports__Physics as Physics, __webpack_exports__PhysicsStats as PhysicsStats, __webpack_exports__PhysicsWorld as PhysicsWorld, __webpack_exports__PointerAbstraction as PointerAbstraction, __webpack_exports__PointerButton as PointerButton, __webpack_exports__PointerComponent as PointerComponent, __webpack_exports__PointerEvent as PointerEvent, __webpack_exports__PointerEventReceiver as PointerEventReceiver, __webpack_exports__PointerScope as PointerScope, __webpack_exports__PointerSystem as PointerSystem, __webpack_exports__PointerType as PointerType, __webpack_exports__Polygon as Polygon, __webpack_exports__PolygonCollider as PolygonCollider, __webpack_exports__Pool as Pool, __webpack_exports__PostCollisionEvent as PostCollisionEvent, __webpack_exports__PostDebugDrawEvent as PostDebugDrawEvent, __webpack_exports__PostDrawEvent as PostDrawEvent, __webpack_exports__PostFrameEvent as PostFrameEvent, __webpack_exports__PostKillEvent as PostKillEvent, __webpack_exports__PostTransformDrawEvent as PostTransformDrawEvent, __webpack_exports__PostUpdateEvent as PostUpdateEvent, __webpack_exports__PreCollisionEvent as PreCollisionEvent, __webpack_exports__PreDebugDrawEvent as PreDebugDrawEvent, __webpack_exports__PreDrawEvent as PreDrawEvent, __webpack_exports__PreFrameEvent as PreFrameEvent, __webpack_exports__PreKillEvent as PreKillEvent, __webpack_exports__PreLoadEvent as PreLoadEvent, __webpack_exports__PreTransformDrawEvent as PreTransformDrawEvent, __webpack_exports__PreUpdateEvent as PreUpdateEvent, __webpack_exports__Projection as Projection, __webpack_exports__QuadIndexBuffer as QuadIndexBuffer, __webpack_exports__QuadTree as QuadTree, __webpack_exports__Query as Query, __webpack_exports__QueryManager as QueryManager, __webpack_exports__RadiusAroundActorStrategy as RadiusAroundActorStrategy, __webpack_exports__Random as Random, __webpack_exports__Raster as Raster, __webpack_exports__Ray as Ray, __webpack_exports__RealisticSolver as RealisticSolver, __webpack_exports__Rectangle as Rectangle, __webpack_exports__RemovedComponent as RemovedComponent, __webpack_exports__Repeat as Repeat, __webpack_exports__RepeatForever as RepeatForever, __webpack_exports__Resolution as Resolution, __webpack_exports__Resource as Resource, __webpack_exports__ResourceEvents as ResourceEvents, __webpack_exports__RotateBy as RotateBy, __webpack_exports__RotateTo as RotateTo, __webpack_exports__RotationType as RotationType, __webpack_exports__ScaleBy as ScaleBy, __webpack_exports__ScaleTo as ScaleTo, __webpack_exports__Scene as Scene, __webpack_exports__SceneEvents as SceneEvents, __webpack_exports__Screen as Screen, __webpack_exports__ScreenAppender as ScreenAppender, __webpack_exports__ScreenElement as ScreenElement, __webpack_exports__ScreenEvents as ScreenEvents, __webpack_exports__ScreenShader as ScreenShader, __webpack_exports__ScrollPreventionMode as ScrollPreventionMode, __webpack_exports__Semaphore as Semaphore, __webpack_exports__Shader as Shader, __webpack_exports__Shape as Shape, __webpack_exports__Side as Side, __webpack_exports__SolverStrategy as SolverStrategy, __webpack_exports__Sound as Sound, __webpack_exports__SoundEvents as SoundEvents, __webpack_exports__Sprite as Sprite, __webpack_exports__SpriteFont as SpriteFont, __webpack_exports__SpriteSheet as SpriteSheet, __webpack_exports__StandardClock as StandardClock, __webpack_exports__StateMachine as StateMachine, __webpack_exports__StrategyContainer as StrategyContainer, __webpack_exports__Stream as Stream, __webpack_exports__System as System, __webpack_exports__SystemManager as SystemManager, __webpack_exports__SystemPriority as SystemPriority, __webpack_exports__SystemType as SystemType, __webpack_exports__TagQuery as TagQuery, __webpack_exports__TestClock as TestClock, __webpack_exports__Text as Text, __webpack_exports__TextAlign as TextAlign, __webpack_exports__TextureLoader as TextureLoader, __webpack_exports__Tile as Tile, __webpack_exports__TileMap as TileMap, __webpack_exports__TileMapEvents as TileMapEvents, __webpack_exports__Timer as Timer, __webpack_exports__Toaster as Toaster, __webpack_exports__Transform as Transform, __webpack_exports__TransformComponent as TransformComponent, __webpack_exports__Transition as Transition, __webpack_exports__TreeNode as TreeNode, __webpack_exports__Trigger as Trigger, __webpack_exports__TriggerEvents as TriggerEvents, __webpack_exports__TwoPI as TwoPI, __webpack_exports__Util as Util, __webpack_exports__Vector as Vector, __webpack_exports__VectorView as VectorView, __webpack_exports__VertexBuffer as VertexBuffer, __webpack_exports__VertexLayout as VertexLayout, __webpack_exports__VerticalFirst as VerticalFirst, __webpack_exports__VisibleEvent as VisibleEvent, __webpack_exports__WebAudio as WebAudio, __webpack_exports__WebAudioInstance as WebAudioInstance, __webpack_exports__WheelDeltaMode as WheelDeltaMode, __webpack_exports__WheelEvent as WheelEvent, __webpack_exports__World as World, __webpack_exports__canonicalizeAngle as canonicalizeAngle, __webpack_exports__clamp as clamp, __webpack_exports__coroutine as coroutine, __webpack_exports__createId as createId, __webpack_exports__frac as frac, __webpack_exports__hasGraphicsTick as hasGraphicsTick, __webpack_exports__hasOnInitialize as hasOnInitialize, __webpack_exports__hasOnPostUpdate as hasOnPostUpdate, __webpack_exports__hasOnPreUpdate as hasOnPreUpdate, __webpack_exports__hasPostDraw as hasPostDraw, __webpack_exports__hasPreDraw as hasPreDraw, __webpack_exports__has_initialize as has_initialize, __webpack_exports__has_postupdate as has_postupdate, __webpack_exports__has_preupdate as has_preupdate, __webpack_exports__isAddedComponent as isAddedComponent, __webpack_exports__isComponentCtor as isComponentCtor, __webpack_exports__isLoaderConstructor as isLoaderConstructor, __webpack_exports__isRemovedComponent as isRemovedComponent, __webpack_exports__isSceneConstructor as isSceneConstructor, __webpack_exports__isScreenElement as isScreenElement, __webpack_exports__isSystemConstructor as isSystemConstructor, __webpack_exports__maxMessages as maxMessages, __webpack_exports__obsolete as obsolete, __webpack_exports__pixelSnapEpsilon as pixelSnapEpsilon, __webpack_exports__randomInRange as randomInRange, __webpack_exports__randomIntInRange as randomIntInRange, __webpack_exports__range as range, __webpack_exports__resetObsoleteCounter as resetObsoleteCounter, __webpack_exports__sign as sign, __webpack_exports__toDegrees as toDegrees, __webpack_exports__toRadians as toRadians, __webpack_exports__vec as vec, __webpack_exports__webgl as webgl };\n\n//# sourceMappingURL=excalibur.js.map","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./Director/Loader.css\"],\"names\":[],\"mappings\":\"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\"sourcesContent\":[\"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./Util/Toaster.css\"],\"names\":[],\"mappings\":\";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\"sourcesContent\":[\"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};","\"use strict\";\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};","'use strict';\nrequire('../../modules/es.array.sort');\nvar entryUnbind = require('../../internals/entry-unbind');\n\nmodule.exports = entryUnbind('Array', 'sort');\n","'use strict';\nrequire('../../modules/es.object.keys');\nvar path = require('../../internals/path');\n\nmodule.exports = path.Object.keys;\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar tryToString = require('../internals/try-to-string');\n\nvar $TypeError = TypeError;\n\n// `Assert: IsCallable(argument) is true`\nmodule.exports = function (argument) {\n if (isCallable(argument)) return argument;\n throw new $TypeError(tryToString(argument) + ' is not a function');\n};\n","'use strict';\nvar isObject = require('../internals/is-object');\n\nvar $String = String;\nvar $TypeError = TypeError;\n\n// `Assert: Type(argument) is Object`\nmodule.exports = function (argument) {\n if (isObject(argument)) return argument;\n throw new $TypeError($String(argument) + ' is not an object');\n};\n","'use strict';\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\nvar createMethod = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el !== el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value !== value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) {\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = function (METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function () { return 1; }, 1);\n });\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = uncurryThis([].slice);\n","'use strict';\nvar arraySlice = require('../internals/array-slice');\n\nvar floor = Math.floor;\n\nvar sort = function (array, comparefn) {\n var length = array.length;\n\n if (length < 8) {\n // insertion sort\n var i = 1;\n var element, j;\n\n while (i < length) {\n j = i;\n element = array[i];\n while (j && comparefn(array[j - 1], element) > 0) {\n array[j] = array[--j];\n }\n if (j !== i++) array[j] = element;\n }\n } else {\n // merge sort\n var middle = floor(length / 2);\n var left = sort(arraySlice(array, 0, middle), comparefn);\n var right = sort(arraySlice(array, middle), comparefn);\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n\n while (lindex < llength || rindex < rlength) {\n array[lindex + rindex] = (lindex < llength && rindex < rlength)\n ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]\n : lindex < llength ? left[lindex++] : right[rindex++];\n }\n }\n\n return array;\n};\n\nmodule.exports = sort;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nvar toString = uncurryThis({}.toString);\nvar stringSlice = uncurryThis(''.slice);\n\nmodule.exports = function (it) {\n return stringSlice(toString(it), 8, -1);\n};\n","'use strict';\nvar TO_STRING_TAG_SUPPORT = require('../internals/to-string-tag-support');\nvar isCallable = require('../internals/is-callable');\nvar classofRaw = require('../internals/classof-raw');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar $Object = Object;\n\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result;\n};\n","'use strict';\nvar hasOwn = require('../internals/has-own-property');\nvar ownKeys = require('../internals/own-keys');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar definePropertyModule = require('../internals/object-define-property');\n\nmodule.exports = function (target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {\n defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n }\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar definePropertyModule = require('../internals/object-define-property');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","'use strict';\nmodule.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar definePropertyModule = require('../internals/object-define-property');\nvar makeBuiltIn = require('../internals/make-built-in');\nvar defineGlobalProperty = require('../internals/define-global-property');\n\nmodule.exports = function (O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) { /* empty */ }\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n } return O;\n};\n","'use strict';\nvar global = require('../internals/global');\n\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\n\nmodule.exports = function (key, value) {\n try {\n defineProperty(global, key, { value: value, configurable: true, writable: true });\n } catch (error) {\n global[key] = value;\n } return value;\n};\n","'use strict';\nvar tryToString = require('../internals/try-to-string');\n\nvar $TypeError = TypeError;\n\nmodule.exports = function (O, P) {\n if (!delete O[P]) throw new $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\n// Detect IE8's incomplete defineProperty implementation\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7;\n});\n","'use strict';\nvar global = require('../internals/global');\nvar isObject = require('../internals/is-object');\n\nvar document = global.document;\n// typeof document.createElement is 'object' in old IE\nvar EXISTS = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return EXISTS ? document.createElement(it) : {};\n};\n","'use strict';\nvar userAgent = require('../internals/engine-user-agent');\n\nvar firefox = userAgent.match(/firefox\\/(\\d+)/i);\n\nmodule.exports = !!firefox && +firefox[1];\n","'use strict';\nvar UA = require('../internals/engine-user-agent');\n\nmodule.exports = /MSIE|Trident/.test(UA);\n","'use strict';\nmodule.exports = typeof navigator != 'undefined' && String(navigator.userAgent) || '';\n","'use strict';\nvar global = require('../internals/global');\nvar userAgent = require('../internals/engine-user-agent');\n\nvar process = global.process;\nvar Deno = global.Deno;\nvar versions = process && process.versions || Deno && Deno.version;\nvar v8 = versions && versions.v8;\nvar match, version;\n\nif (v8) {\n match = v8.split('.');\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n}\n\n// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n// so check `userAgent` even if `.v8` exists, but 0\nif (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n}\n\nmodule.exports = version;\n","'use strict';\nvar userAgent = require('../internals/engine-user-agent');\n\nvar webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n\nmodule.exports = !!webkit && +webkit[1];\n","'use strict';\nvar global = require('../internals/global');\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = function (CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n};\n","'use strict';\n// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n","'use strict';\nvar global = require('../internals/global');\nvar getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar defineBuiltIn = require('../internals/define-built-in');\nvar defineGlobalProperty = require('../internals/define-global-property');\nvar copyConstructorProperties = require('../internals/copy-constructor-properties');\nvar isForced = require('../internals/is-forced');\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = global;\n } else if (STATIC) {\n target = global[TARGET] || defineGlobalProperty(TARGET, {});\n } else {\n target = global[TARGET] && global[TARGET].prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n createNonEnumerableProperty(sourceProperty, 'sham', true);\n }\n defineBuiltIn(target, key, sourceProperty, options);\n }\n};\n","'use strict';\nmodule.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function () { /* empty */ }).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != 'function' || test.hasOwnProperty('prototype');\n});\n","'use strict';\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar call = Function.prototype.call;\n\nmodule.exports = NATIVE_BIND ? call.bind(call) : function () {\n return call.apply(call, arguments);\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar hasOwn = require('../internals/has-own-property');\n\nvar FunctionPrototype = Function.prototype;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n\nvar EXISTS = hasOwn(FunctionPrototype, 'name');\n// additional protection from minified / mangled / dropped function names\nvar PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';\nvar CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable));\n\nmodule.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n};\n","'use strict';\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar FunctionPrototype = Function.prototype;\nvar call = FunctionPrototype.call;\nvar uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n\nmodule.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {\n return function () {\n return call.apply(fn, arguments);\n };\n};\n","'use strict';\nvar global = require('../internals/global');\nvar isCallable = require('../internals/is-callable');\n\nvar aFunction = function (argument) {\n return isCallable(argument) ? argument : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n};\n","'use strict';\nvar aCallable = require('../internals/a-callable');\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\n\n// `GetMethod` abstract operation\n// https://tc39.es/ecma262/#sec-getmethod\nmodule.exports = function (V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n};\n","'use strict';\nvar check = function (it) {\n return it && it.Math === Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == 'object' && globalThis) ||\n check(typeof window == 'object' && window) ||\n // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == 'object' && self) ||\n check(typeof global == 'object' && global) ||\n check(typeof this == 'object' && this) ||\n // eslint-disable-next-line no-new-func -- fallback\n (function () { return this; })() || Function('return this')();\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar toObject = require('../internals/to-object');\n\nvar hasOwnProperty = uncurryThis({}.hasOwnProperty);\n\n// `HasOwnProperty` abstract operation\n// https://tc39.es/ecma262/#sec-hasownproperty\n// eslint-disable-next-line es/no-object-hasown -- safe\nmodule.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n};\n","'use strict';\nmodule.exports = {};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\nvar createElement = require('../internals/document-create-element');\n\n// Thanks to IE8 for its funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a !== 7;\n});\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar fails = require('../internals/fails');\nvar classof = require('../internals/classof-raw');\n\nvar $Object = Object;\nvar split = uncurryThis(''.split);\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) === 'String' ? split(it, '') : $Object(it);\n} : $Object;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar isCallable = require('../internals/is-callable');\nvar store = require('../internals/shared-store');\n\nvar functionToString = uncurryThis(Function.toString);\n\n// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\nif (!isCallable(store.inspectSource)) {\n store.inspectSource = function (it) {\n return functionToString(it);\n };\n}\n\nmodule.exports = store.inspectSource;\n","'use strict';\nvar NATIVE_WEAK_MAP = require('../internals/weak-map-basic-detection');\nvar global = require('../internals/global');\nvar isObject = require('../internals/is-object');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar hasOwn = require('../internals/has-own-property');\nvar shared = require('../internals/shared-store');\nvar sharedKey = require('../internals/shared-key');\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar OBJECT_ALREADY_INITIALIZED = 'Object already initialized';\nvar TypeError = global.TypeError;\nvar WeakMap = global.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw new TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap());\n /* eslint-disable no-self-assign -- prototype methods protection */\n store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */\n set = function (it, metadata) {\n if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function (it) {\n return store.get(it) || {};\n };\n has = function (it) {\n return store.has(it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return hasOwn(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n","'use strict';\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\nvar documentAll = typeof document == 'object' && document.all;\n\n// `IsCallable` abstract operation\n// https://tc39.es/ecma262/#sec-iscallable\n// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\nmodule.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) {\n return typeof argument == 'function' || argument === documentAll;\n} : function (argument) {\n return typeof argument == 'function';\n};\n","'use strict';\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value === POLYFILL ? true\n : value === NATIVE ? false\n : isCallable(detection) ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n","'use strict';\n// we can't use just `it == null` since of `document.all` special case\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\nmodule.exports = function (it) {\n return it === null || it === undefined;\n};\n","'use strict';\nvar isCallable = require('../internals/is-callable');\n\nmodule.exports = function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it);\n};\n","'use strict';\nmodule.exports = false;\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar isCallable = require('../internals/is-callable');\nvar isPrototypeOf = require('../internals/object-is-prototype-of');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar $Object = Object;\n\nmodule.exports = USE_SYMBOL_AS_UID ? function (it) {\n return typeof it == 'symbol';\n} : function (it) {\n var $Symbol = getBuiltIn('Symbol');\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n};\n","'use strict';\nvar toLength = require('../internals/to-length');\n\n// `LengthOfArrayLike` abstract operation\n// https://tc39.es/ecma262/#sec-lengthofarraylike\nmodule.exports = function (obj) {\n return toLength(obj.length);\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\nvar hasOwn = require('../internals/has-own-property');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar CONFIGURABLE_FUNCTION_NAME = require('../internals/function-name').CONFIGURABLE;\nvar inspectSource = require('../internals/inspect-source');\nvar InternalStateModule = require('../internals/internal-state');\n\nvar enforceInternalState = InternalStateModule.enforce;\nvar getInternalState = InternalStateModule.get;\nvar $String = String;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\nvar stringSlice = uncurryThis(''.slice);\nvar replace = uncurryThis(''.replace);\nvar join = uncurryThis([].join);\n\nvar CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () {\n return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;\n});\n\nvar TEMPLATE = String(String).split('String');\n\nvar makeBuiltIn = module.exports = function (value, name, options) {\n if (stringSlice($String(name), 0, 7) === 'Symbol(') {\n name = '[' + replace($String(name), /^Symbol\\(([^)]*)\\).*$/, '$1') + ']';\n }\n if (options && options.getter) name = 'get ' + name;\n if (options && options.setter) name = 'set ' + name;\n if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {\n if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) {\n defineProperty(value, 'length', { value: options.arity });\n }\n try {\n if (options && hasOwn(options, 'constructor') && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false });\n // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) { /* empty */ }\n var state = enforceInternalState(value);\n if (!hasOwn(state, 'source')) {\n state.source = join(TEMPLATE, typeof name == 'string' ? name : '');\n } return value;\n};\n\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n// eslint-disable-next-line no-extend-native -- required\nFunction.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n}, 'toString');\n","'use strict';\nvar ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `Math.trunc` method\n// https://tc39.es/ecma262/#sec-math.trunc\n// eslint-disable-next-line es/no-math-trunc -- safe\nmodule.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\nvar V8_PROTOTYPE_DEFINE_BUG = require('../internals/v8-prototype-define-bug');\nvar anObject = require('../internals/an-object');\nvar toPropertyKey = require('../internals/to-property-key');\n\nvar $TypeError = TypeError;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar $defineProperty = Object.defineProperty;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar ENUMERABLE = 'enumerable';\nvar CONFIGURABLE = 'configurable';\nvar WRITABLE = 'writable';\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\nexports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n } return $defineProperty(O, P, Attributes);\n} : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar call = require('../internals/function-call');\nvar propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toPropertyKey = require('../internals/to-property-key');\nvar hasOwn = require('../internals/has-own-property');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\n\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\nexports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n};\n","'use strict';\nvar internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.es/ecma262/#sec-object.getownpropertynames\n// eslint-disable-next-line es/no-object-getownpropertynames -- safe\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n","'use strict';\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\nexports.f = Object.getOwnPropertySymbols;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = uncurryThis({}.isPrototypeOf);\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar hasOwn = require('../internals/has-own-property');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar indexOf = require('../internals/array-includes').indexOf;\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar push = uncurryThis([].push);\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (hasOwn(O, key = names[i++])) {\n ~indexOf(result, key) || push(result, key);\n }\n return result;\n};\n","'use strict';\nvar internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n// eslint-disable-next-line es/no-object-keys -- safe\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n","'use strict';\nvar $propertyIsEnumerable = {}.propertyIsEnumerable;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);\n\n// `Object.prototype.propertyIsEnumerable` method implementation\n// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : $propertyIsEnumerable;\n","'use strict';\nvar call = require('../internals/function-call');\nvar isCallable = require('../internals/is-callable');\nvar isObject = require('../internals/is-object');\n\nvar $TypeError = TypeError;\n\n// `OrdinaryToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-ordinarytoprimitive\nmodule.exports = function (input, pref) {\n var fn, val;\n if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw new $TypeError(\"Can't convert object to primitive value\");\n};\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar anObject = require('../internals/an-object');\n\nvar concat = uncurryThis([].concat);\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n};\n","'use strict';\nvar global = require('../internals/global');\n\nmodule.exports = global;\n","'use strict';\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\n\nvar $TypeError = TypeError;\n\n// `RequireObjectCoercible` abstract operation\n// https://tc39.es/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (isNullOrUndefined(it)) throw new $TypeError(\"Can't call method on \" + it);\n return it;\n};\n","'use strict';\nvar shared = require('../internals/shared');\nvar uid = require('../internals/uid');\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n","'use strict';\nvar global = require('../internals/global');\nvar defineGlobalProperty = require('../internals/define-global-property');\n\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || defineGlobalProperty(SHARED, {});\n\nmodule.exports = store;\n","'use strict';\nvar IS_PURE = require('../internals/is-pure');\nvar store = require('../internals/shared-store');\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: '3.35.1',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)',\n license: 'https://github.com/zloirock/core-js/blob/v3.35.1/LICENSE',\n source: 'https://github.com/zloirock/core-js'\n});\n","'use strict';\n/* eslint-disable es/no-symbol -- required for testing */\nvar V8_VERSION = require('../internals/engine-v8-version');\nvar fails = require('../internals/fails');\nvar global = require('../internals/global');\n\nvar $String = global.String;\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n var symbol = Symbol('symbol detection');\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) ||\n // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n});\n","'use strict';\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\nmodule.exports = function (index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n","'use strict';\n// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = require('../internals/indexed-object');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n","'use strict';\nvar trunc = require('../internals/math-trunc');\n\n// `ToIntegerOrInfinity` abstract operation\n// https://tc39.es/ecma262/#sec-tointegerorinfinity\nmodule.exports = function (argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n};\n","'use strict';\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.es/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n var len = toIntegerOrInfinity(argument);\n return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n","'use strict';\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nvar $Object = Object;\n\n// `ToObject` abstract operation\n// https://tc39.es/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return $Object(requireObjectCoercible(argument));\n};\n","'use strict';\nvar call = require('../internals/function-call');\nvar isObject = require('../internals/is-object');\nvar isSymbol = require('../internals/is-symbol');\nvar getMethod = require('../internals/get-method');\nvar ordinaryToPrimitive = require('../internals/ordinary-to-primitive');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar $TypeError = TypeError;\nvar TO_PRIMITIVE = wellKnownSymbol('toPrimitive');\n\n// `ToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-toprimitive\nmodule.exports = function (input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = 'default';\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw new $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = 'number';\n return ordinaryToPrimitive(input, pref);\n};\n","'use strict';\nvar toPrimitive = require('../internals/to-primitive');\nvar isSymbol = require('../internals/is-symbol');\n\n// `ToPropertyKey` abstract operation\n// https://tc39.es/ecma262/#sec-topropertykey\nmodule.exports = function (argument) {\n var key = toPrimitive(argument, 'string');\n return isSymbol(key) ? key : key + '';\n};\n","'use strict';\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n\ntest[TO_STRING_TAG] = 'z';\n\nmodule.exports = String(test) === '[object z]';\n","'use strict';\nvar classof = require('../internals/classof');\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n return $String(argument);\n};\n","'use strict';\nvar $String = String;\n\nmodule.exports = function (argument) {\n try {\n return $String(argument);\n } catch (error) {\n return 'Object';\n }\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nvar id = 0;\nvar postfix = Math.random();\nvar toString = uncurryThis(1.0.toString);\n\nmodule.exports = function (key) {\n return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);\n};\n","'use strict';\n/* eslint-disable es/no-symbol -- required for testing */\nvar NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');\n\nmodule.exports = NATIVE_SYMBOL\n && !Symbol.sham\n && typeof Symbol.iterator == 'symbol';\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\n\n// V8 ~ Chrome 36-\n// https://bugs.chromium.org/p/v8/issues/detail?id=3334\nmodule.exports = DESCRIPTORS && fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function () { /* empty */ }, 'prototype', {\n value: 42,\n writable: false\n }).prototype !== 42;\n});\n","'use strict';\nvar global = require('../internals/global');\nvar isCallable = require('../internals/is-callable');\n\nvar WeakMap = global.WeakMap;\n\nmodule.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));\n","'use strict';\nvar global = require('../internals/global');\nvar shared = require('../internals/shared');\nvar hasOwn = require('../internals/has-own-property');\nvar uid = require('../internals/uid');\nvar NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar Symbol = global.Symbol;\nvar WellKnownSymbolsStore = shared('wks');\nvar createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;\n\nmodule.exports = function (name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) {\n WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name)\n ? Symbol[name]\n : createWellKnownSymbol('Symbol.' + name);\n } return WellKnownSymbolsStore[name];\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar aCallable = require('../internals/a-callable');\nvar toObject = require('../internals/to-object');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar deletePropertyOrThrow = require('../internals/delete-property-or-throw');\nvar toString = require('../internals/to-string');\nvar fails = require('../internals/fails');\nvar internalSort = require('../internals/array-sort');\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\nvar FF = require('../internals/engine-ff-version');\nvar IE_OR_EDGE = require('../internals/engine-is-ie-or-edge');\nvar V8 = require('../internals/engine-v8-version');\nvar WEBKIT = require('../internals/engine-webkit-version');\n\nvar test = [];\nvar nativeSort = uncurryThis(test.sort);\nvar push = uncurryThis(test.push);\n\n// IE8-\nvar FAILS_ON_UNDEFINED = fails(function () {\n test.sort(undefined);\n});\n// V8 bug\nvar FAILS_ON_NULL = fails(function () {\n test.sort(null);\n});\n// Old WebKit\nvar STRICT_METHOD = arrayMethodIsStrict('sort');\n\nvar STABLE_SORT = !fails(function () {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n\n var result = '';\n var code, chr, value, index;\n\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for (code = 65; code < 76; code++) {\n chr = String.fromCharCode(code);\n\n switch (code) {\n case 66: case 69: case 70: case 72: value = 3; break;\n case 68: case 71: value = 4; break;\n default: value = 2;\n }\n\n for (index = 0; index < 47; index++) {\n test.push({ k: chr + index, v: value });\n }\n }\n\n test.sort(function (a, b) { return b.v - a.v; });\n\n for (index = 0; index < test.length; index++) {\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n\n return result !== 'DGBEFHACIJK';\n});\n\nvar FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n\nvar getSortCompare = function (comparefn) {\n return function (x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n};\n\n// `Array.prototype.sort` method\n// https://tc39.es/ecma262/#sec-array.prototype.sort\n$({ target: 'Array', proto: true, forced: FORCED }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n\n var array = toObject(this);\n\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n\n for (index = 0; index < arrayLength; index++) {\n if (index in array) push(items, array[index]);\n }\n\n internalSort(items, getSortCompare(comparefn));\n\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n\n while (index < itemsLength) array[index] = items[index++];\n while (index < arrayLength) deletePropertyOrThrow(array, index++);\n\n return array;\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar toObject = require('../internals/to-object');\nvar nativeKeys = require('../internals/object-keys');\nvar fails = require('../internals/fails');\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeKeys(1); });\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n});\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import 'core-js/es/array/sort';\r\nimport 'core-js/es/object/keys';\r\n\r\n/**\r\n * Polyfill adding function\r\n */\r\nexport function polyfill() {\r\n /* istanbul ignore next */\r\n if (typeof window === 'undefined') {\r\n window = {\r\n audioContext: function () {\r\n return;\r\n }\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.requestAnimationFrame) {\r\n (window).requestAnimationFrame =\r\n (window).webkitRequestAnimationFrame ||\r\n (window).mozRequestAnimationFrame ||\r\n function (callback: Function) {\r\n window.setInterval(callback, 1000 / 60);\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.cancelAnimationFrame) {\r\n (window).cancelAnimationFrame =\r\n (window).webkitCancelAnimationFrame ||\r\n (window).mozCancelAnimationFrame ||\r\n function () {\r\n return;\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !(window).AudioContext) {\r\n if ((window).webkitAudioContext) {\r\n const ctx = (window).webkitAudioContext;\r\n const replaceMe = ctx.prototype.decodeAudioData;\r\n (window).webkitAudioContext.prototype.decodeAudioData = function (arrayBuffer: ArrayBuffer) {\r\n return new Promise((resolve, reject) => {\r\n replaceMe.call(this, arrayBuffer, resolve, reject);\r\n });\r\n };\r\n }\r\n\r\n (window).AudioContext =\r\n (window).AudioContext ||\r\n (window).webkitAudioContext ||\r\n (window).mozAudioContext ||\r\n (window).msAudioContext ||\r\n (window).oAudioContext;\r\n }\r\n\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !(window).devicePixelRatio) {\r\n (window).devicePixelRatio = window.devicePixelRatio || 1;\r\n }\r\n}\r\n","\r\n/**\r\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\r\n * after which they are frozen and are read-only.\r\n *\r\n * Flags are used to enable experimental or preview features in Excalibur.\r\n */\r\nexport class Flags {\r\n private static _FROZEN = false;\r\n private static _FLAGS: Record = {};\r\n\r\n\r\n /**\r\n * Force excalibur to load the Canvas 2D graphics context fallback\r\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\r\n */\r\n public static useCanvasGraphicsContext() {\r\n Flags.enable('use-canvas-context');\r\n }\r\n\r\n /**\r\n * Freeze all flag modifications making them readonly\r\n */\r\n public static freeze() {\r\n Flags._FROZEN = true;\r\n }\r\n\r\n /**\r\n * Resets internal flag state, not meant to be called by users. Only used for testing.\r\n *\r\n * Calling this in your game is UNSUPPORTED\r\n * @internal\r\n */\r\n public static _reset() {\r\n Flags._FROZEN = false;\r\n Flags._FLAGS = {};\r\n }\r\n /**\r\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */\r\n public static enable(flagName: string): void {\r\n if (this._FROZEN) {\r\n throw Error('Feature flags can only be enabled before Engine constructor time');\r\n }\r\n Flags._FLAGS[flagName] = true;\r\n }\r\n\r\n /**\r\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */\r\n public static disable(flagName: string): void {\r\n if (this._FROZEN) {\r\n throw Error('Feature flags can only be disabled before Engine constructor time');\r\n }\r\n Flags._FLAGS[flagName] = false;\r\n }\r\n\r\n /**\r\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\r\n * @param flagName\r\n */\r\n public static isEnabled(flagName: string): boolean {\r\n return !!Flags._FLAGS[flagName];\r\n }\r\n\r\n /**\r\n * Show a list of currently known flags\r\n */\r\n public static show(): string[] {\r\n return Object.keys(Flags._FLAGS);\r\n }\r\n}\r\n","export type Id = {\r\n type: T,\r\n value: number\r\n};\r\n\r\n/**\r\n * Create a branded ID type from a number\r\n */\r\nexport function createId(type: T, value: number): Id {\r\n return { type, value };\r\n};\r\n","\r\n/**\r\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\r\n */\r\nexport class Future {\r\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\r\n private _resolver: (value: T) => void;\r\n private _rejecter: (error: Error) => void;\r\n private _isCompleted: boolean = false;\r\n\r\n constructor() {\r\n this.promise = new Promise((resolve, reject) => {\r\n this._resolver = resolve;\r\n this._rejecter = reject;\r\n });\r\n }\r\n\r\n public readonly promise: Promise;\r\n\r\n public get isCompleted(): boolean {\r\n return this._isCompleted;\r\n }\r\n\r\n public resolve(value: T): void {\r\n if (this._isCompleted) {\r\n return;\r\n }\r\n this._isCompleted = true;\r\n this._resolver(value);\r\n }\r\n\r\n public reject(error: Error): void {\r\n if (this._isCompleted) {\r\n return;\r\n }\r\n this._isCompleted = true;\r\n this._rejecter(error);\r\n }\r\n}","export type EventMap = Record;\r\nexport type EventKey = string & keyof T;\r\nexport type Handler = (event: EventType) => void;\r\n\r\n/**\r\n * Interface that represents a handle to a subscription that can be closed\r\n */\r\nexport interface Subscription {\r\n close(): void;\r\n}\r\n\r\n/**\r\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\r\n */\r\nexport class EventEmitter {\r\n private _paused = false;\r\n private _listeners: Record[]> = {};\r\n private _listenersOnce: Record[]> = {};\r\n private _pipes: EventEmitter[] = [];\r\n\r\n clear() {\r\n this._listeners = {};\r\n this._listenersOnce = {};\r\n this._pipes.length = 0;\r\n }\r\n\r\n on>(eventName: TEventName, handler: Handler): Subscription;\r\n on(eventName: string, handler: Handler): Subscription;\r\n on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._listeners[eventName] = this._listeners[eventName] ?? [];\r\n this._listeners[eventName].push(handler);\r\n return {\r\n close: () => this.off(eventName, handler)\r\n };\r\n }\r\n\r\n once>(eventName: TEventName, handler: Handler): Subscription;\r\n once(eventName: string, handler: Handler): Subscription;\r\n once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._listenersOnce[eventName] = this._listenersOnce[eventName] ?? [];\r\n this._listenersOnce[eventName].push(handler);\r\n return {\r\n close: () => this.off(eventName, handler)\r\n };\r\n }\r\n\r\n off>(eventName: TEventName, handler: Handler): void;\r\n off(eventName: string, handler: Handler): void;\r\n off(eventName: string): void;\r\n off | string>(eventName: TEventName, handler?: Handler): void {\r\n if (handler) {\r\n const newListeners = this._listeners[eventName]?.filter(h => h !== handler);\r\n this._listeners[eventName] = newListeners;\r\n\r\n const newOnceListeners = this._listenersOnce[eventName]?.filter(h => h !== handler);\r\n this._listenersOnce[eventName] = newOnceListeners;\r\n } else {\r\n delete this._listeners[eventName];\r\n }\r\n }\r\n\r\n emit>(eventName: TEventName, event: TEventMap[TEventName]): void;\r\n emit(eventName: string, event?: any): void;\r\n emit | string>(eventName: TEventName, event?: TEventMap[TEventName]): void {\r\n if (this._paused) {\r\n return;\r\n }\r\n this._listeners[eventName]?.forEach((fn) => fn(event));\r\n const onces = this._listenersOnce[eventName];\r\n this._listenersOnce[eventName] = [];\r\n if (onces) {\r\n onces.forEach((fn) => fn(event));\r\n }\r\n this._pipes.forEach((pipe) => {\r\n pipe.emit(eventName, event);\r\n });\r\n }\r\n\r\n pipe(emitter: EventEmitter): Subscription {\r\n if (this === emitter) {\r\n throw Error('Cannot pipe to self');\r\n }\r\n this._pipes.push(emitter);\r\n return {\r\n close: () => {\r\n const i = this._pipes.indexOf(emitter);\r\n if (i > -1) {\r\n this._pipes.splice(i, 1);\r\n }\r\n }\r\n };\r\n }\r\n\r\n unpipe(emitter: EventEmitter): void {\r\n const i = this._pipes.indexOf(emitter);\r\n if (i > -1) {\r\n this._pipes.splice(i, 1);\r\n }\r\n }\r\n\r\n pause(): void {\r\n this._paused = true;\r\n }\r\n\r\n unpause(): void {\r\n this._paused = false;\r\n }\r\n}","/**\r\n * Determines the scope of handling mouse/touch events.\r\n */\r\n\r\nexport enum PointerScope {\r\n /**\r\n * Handle events on the `canvas` element only. Events originating outside the\r\n * `canvas` will not be handled.\r\n */\r\n Canvas = 'Canvas',\r\n\r\n /**\r\n * Handles events on the entire document. All events will be handled by Excalibur.\r\n */\r\n Document = 'Document'\r\n}\r\n","/**\r\n * @module\r\n * Pseudo-Random Utility\r\n *\r\n * A pseudo-random utility to add seeded random support for help in\r\n * generating things like terrain or reproducible randomness. Uses the\r\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\r\n */\r\n\r\n/**\r\n * 32-bit mask\r\n */\r\nconst BITMASK32: number = 0xffffffff;\r\n\r\n/**\r\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\r\n * of numbers each time it is called.\r\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\r\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\r\n *\r\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\r\n */\r\nexport class Random {\r\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\r\n private _lowerMask: number = 0x7fffffff; // 31 bits same as _r\r\n private _upperMask: number = 0x80000000; // 34 high bits\r\n\r\n // Word size, 64 bits\r\n private _w: number = 32;\r\n\r\n // Degree of recurrence\r\n private _n: number = 624;\r\n\r\n // Middle word, an offset used in the recurrence defining the series x, 1<=m(this._n);\r\n // need to mask to support higher bit machines\r\n this._mt[0] = (seed || Date.now()) >>> 0;\r\n\r\n for (let i = 1; i < this._n; i++) {\r\n const s = this._mt[i - 1] ^ (this._mt[i - 1] >>> (this._w - 2));\r\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\r\n this._mt[i] = (((this._f * ((s & 0xffff0000) >>> 16)) << 16) + this._f * (s & 0xffff) + i) >>> 0;\r\n }\r\n this._index = this._n;\r\n }\r\n\r\n /**\r\n * Apply the twist\r\n */\r\n private _twist(): void {\r\n const mag01 = [0x0, this._a];\r\n let y = 0,\r\n i = 0;\r\n for (; i < this._n - this._m; i++) {\r\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\r\n this._mt[i] = this._mt[i + this._m] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n }\r\n for (; i < this._n - 1; i++) {\r\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\r\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n }\r\n y = (this._mt[this._n - 1] & this._upperMask) | (this._mt[0] & this._lowerMask);\r\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n\r\n this._index = 0;\r\n }\r\n\r\n /**\r\n * Return next 32 bit integer number in sequence\r\n */\r\n public nextInt(): number {\r\n if (this._index >= this._n) {\r\n this._twist();\r\n }\r\n\r\n let y = this._mt[this._index++];\r\n\r\n y ^= y >>> this._u;\r\n y ^= (y << this._s) & this._b;\r\n y ^= (y << this._t) & this._c;\r\n y ^= y >>> this._l;\r\n\r\n return y >>> 0;\r\n }\r\n\r\n /**\r\n * Return a random floating point number between [0, 1)\r\n */\r\n public next(): number {\r\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\r\n }\r\n\r\n /**\r\n * Return a random floating point in range [min, max) min is included, max is not included\r\n */\r\n public floating(min: number, max: number): number {\r\n return (max - min) * this.next() + min;\r\n }\r\n\r\n /**\r\n * Return a random integer in range [min, max] min is included, max is included.\r\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\r\n */\r\n public integer(min: number, max: number): number {\r\n return Math.floor((max - min + 1) * this.next() + min);\r\n }\r\n\r\n /**\r\n * Returns true or false randomly with 50/50 odds by default.\r\n * By default the likelihood of returning a true is .5 (50%).\r\n * @param likelihood takes values between [0, 1]\r\n */\r\n public bool(likelihood: number = 0.5): boolean {\r\n return this.next() <= likelihood;\r\n }\r\n\r\n /**\r\n * Returns one element from an array at random\r\n */\r\n public pickOne(array: Array): T {\r\n return array[this.integer(0, array.length - 1)];\r\n }\r\n\r\n /**\r\n * Returns a new array random picking elements from the original\r\n * @param array Original array to pick from\r\n * @param numPicks can be any positive number\r\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\r\n * just that it is possible)\r\n */\r\n public pickSet(array: Array, numPicks: number, allowDuplicates: boolean = false): Array {\r\n if (allowDuplicates) {\r\n return this._pickSetWithDuplicates(array, numPicks);\r\n } else {\r\n return this._pickSetWithoutDuplicates(array, numPicks);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a new array randomly picking elements in the original (not reused)\r\n * @param array Array to pick elements out of\r\n * @param numPicks must be less than or equal to the number of elements in the array.\r\n */\r\n private _pickSetWithoutDuplicates(array: Array, numPicks: number): Array {\r\n if (numPicks > array.length || numPicks < 0) {\r\n throw new Error('Invalid number of elements to pick, must pick a value 0 < n <= length');\r\n }\r\n if (numPicks === array.length) {\r\n return array;\r\n }\r\n\r\n const result: Array = new Array(numPicks);\r\n let currentPick = 0;\r\n const tempArray = array.slice(0);\r\n while (currentPick < numPicks) {\r\n const index = this.integer(0, tempArray.length - 1);\r\n result[currentPick++] = tempArray[index];\r\n tempArray.splice(index, 1);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new array random picking elements from the original allowing duplicates\r\n * @param array Array to pick elements out of\r\n * @param numPicks can be any positive number\r\n */\r\n private _pickSetWithDuplicates(array: Array, numPicks: number): Array {\r\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\r\n if (numPicks < 0) {\r\n throw new Error('Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT');\r\n }\r\n const result = new Array(numPicks);\r\n for (let i = 0; i < numPicks; i++) {\r\n result[i] = this.pickOne(array);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\r\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\r\n */\r\n public shuffle(array: Array): Array {\r\n const tempArray = array.slice(0);\r\n let swap: T = null;\r\n for (let i = 0; i < tempArray.length - 2; i++) {\r\n const randomIndex = this.integer(i, tempArray.length - 1);\r\n swap = tempArray[i];\r\n tempArray[i] = tempArray[randomIndex];\r\n tempArray[randomIndex] = swap;\r\n }\r\n\r\n return tempArray;\r\n }\r\n\r\n /**\r\n * Generate a list of random integer numbers\r\n * @param length the length of the final array\r\n * @param min the minimum integer number to generate inclusive\r\n * @param max the maximum integer number to generate inclusive\r\n */\r\n public range(length: number, min: number, max: number): Array {\r\n const result: Array = new Array(length);\r\n for (let i = 0; i < length; i++) {\r\n result[i] = this.integer(min, max);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns the result of a d4 dice roll\r\n */\r\n public d4() {\r\n return this.integer(1, 4);\r\n }\r\n\r\n /**\r\n * Returns the result of a d6 dice roll\r\n */\r\n public d6() {\r\n return this.integer(1, 6);\r\n }\r\n\r\n /**\r\n * Returns the result of a d8 dice roll\r\n */\r\n public d8() {\r\n return this.integer(1, 8);\r\n }\r\n\r\n /**\r\n * Returns the result of a d10 dice roll\r\n */\r\n public d10() {\r\n return this.integer(1, 10);\r\n }\r\n\r\n /**\r\n * Returns the result of a d12 dice roll\r\n */\r\n public d12() {\r\n return this.integer(1, 12);\r\n }\r\n\r\n /**\r\n * Returns the result of a d20 dice roll\r\n */\r\n public d20() {\r\n return this.integer(1, 20);\r\n }\r\n}\r\n","import { Random } from './Random';\r\n\r\n/**\r\n * Two PI constant\r\n */\r\nexport const TwoPI: number = Math.PI * 2;\r\n\r\n/**\r\n * Returns the fractional part of a number\r\n * @param x\r\n */\r\nexport function frac(x: number): number {\r\n if (x >= 0) {\r\n return x - Math.floor(x);\r\n } else {\r\n return x - Math.ceil(x);\r\n }\r\n}\r\n\r\n/**\r\n * Returns the sign of a number, if 0 returns 0\r\n */\r\nexport function sign(val: number): number {\r\n if (val === 0) {\r\n return 0;\r\n }\r\n return val < 0 ? -1 : 1;\r\n};\r\n\r\n/**\r\n * Clamps a value between a min and max inclusive\r\n */\r\nexport function clamp(val: number, min: number, max: number) {\r\n return Math.min(Math.max(min, val), max);\r\n}\r\n\r\n\r\n/**\r\n * Convert an angle to be the equivalent in the range [0, 2PI]\r\n */\r\nexport function canonicalizeAngle(angle: number): number {\r\n let tmpAngle = angle;\r\n if (angle > TwoPI) {\r\n while (tmpAngle > TwoPI) {\r\n tmpAngle -= TwoPI;\r\n }\r\n }\r\n\r\n if (angle < 0) {\r\n while (tmpAngle < 0) {\r\n tmpAngle += TwoPI;\r\n }\r\n }\r\n return tmpAngle;\r\n}\r\n\r\n/**\r\n * Convert radians to degrees\r\n */\r\nexport function toDegrees(radians: number): number {\r\n return (180 / Math.PI) * radians;\r\n}\r\n\r\n/**\r\n * Convert degrees to radians\r\n */\r\nexport function toRadians(degrees: number): number {\r\n return (degrees / 180) * Math.PI;\r\n}\r\n\r\n/**\r\n * Generate a range of numbers\r\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\r\n * @param from inclusive\r\n * @param to inclusive\r\n */\r\nexport const range = (from: number, to: number) => Array.from(new Array(to - from + 1), (_x, i) => i + from);\r\n\r\n/**\r\n * Find a random floating point number in range\r\n */\r\nexport function randomInRange(min: number, max: number, random: Random = new Random()): number {\r\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\r\n}\r\n\r\n/**\r\n * Find a random integer in a range\r\n */\r\nexport function randomIntInRange(min: number, max: number, random: Random = new Random()): number {\r\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\r\n}","import { Clonable } from '../Interfaces/Clonable';\r\nimport { clamp } from './util';\r\n\r\n/**\r\n * A 2D vector on a plane.\r\n */\r\n\r\nexport class Vector implements Clonable {\r\n /**\r\n * A (0, 0) vector\r\n */\r\n public static get Zero() {\r\n return new Vector(0, 0);\r\n }\r\n\r\n /**\r\n * A (1, 1) vector\r\n */\r\n public static get One() {\r\n return new Vector(1, 1);\r\n }\r\n\r\n /**\r\n * A (0.5, 0.5) vector\r\n */\r\n public static get Half() {\r\n return new Vector(0.5, 0.5);\r\n }\r\n\r\n /**\r\n * A unit vector pointing up (0, -1)\r\n */\r\n public static get Up() {\r\n return new Vector(0, -1);\r\n }\r\n\r\n /**\r\n * A unit vector pointing down (0, 1)\r\n */\r\n public static get Down() {\r\n return new Vector(0, 1);\r\n }\r\n\r\n /**\r\n * A unit vector pointing left (-1, 0)\r\n */\r\n public static get Left() {\r\n return new Vector(-1, 0);\r\n }\r\n /**\r\n * A unit vector pointing right (1, 0)\r\n */\r\n public static get Right() {\r\n return new Vector(1, 0);\r\n }\r\n\r\n /**\r\n * Returns a vector of unit length in the direction of the specified angle in Radians.\r\n * @param angle The angle to generate the vector\r\n */\r\n public static fromAngle(angle: number) {\r\n return new Vector(Math.cos(angle), Math.sin(angle));\r\n }\r\n\r\n /**\r\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\r\n */\r\n public static isValid(vec: Vector) {\r\n if (vec === null || vec === undefined) {\r\n return false;\r\n }\r\n if (isNaN(vec.x) || isNaN(vec.y)) {\r\n return false;\r\n }\r\n\r\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Calculates distance between two Vectors\r\n * @param vec1\r\n * @param vec2\r\n */\r\n public static distance(vec1: Vector, vec2: Vector) {\r\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\r\n }\r\n\r\n public static min(vec1: Vector, vec2: Vector) {\r\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\r\n }\r\n\r\n public static max(vec1: Vector, vec2: Vector) {\r\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\r\n }\r\n\r\n /**\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */\r\n constructor(x: number, y: number) {\r\n this._x = x;\r\n this._y = y;\r\n }\r\n\r\n protected _x = 0;\r\n /**\r\n * Get the x component of the vector\r\n */\r\n public get x(): number {\r\n return this._x;\r\n }\r\n\r\n /**\r\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */\r\n public set x(val: number) {\r\n this._x = val;\r\n }\r\n\r\n protected _y = 0;\r\n /**\r\n * Get the y component of the vector\r\n */\r\n public get y(): number {\r\n return this._y;\r\n }\r\n\r\n /**\r\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */\r\n public set y(val: number) {\r\n this._y = val;\r\n }\r\n\r\n /**\r\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\r\n */\r\n setTo(x: number, y: number) {\r\n (this.x as number) = x;\r\n (this.y as number) = y;\r\n }\r\n\r\n /**\r\n * Compares this point against another and tests for equality\r\n * @param vector The other point to compare to\r\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\r\n */\r\n public equals(vector: Vector, tolerance: number = 0.001): boolean {\r\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\r\n }\r\n\r\n /**\r\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\r\n * @param v The other vector. Leave blank to use origin vector.\r\n */\r\n public distance(v?: Vector): number {\r\n if (!v) {\r\n return Math.sqrt(this.x * this.x + this.y * this.y);\r\n }\r\n const deltaX = this.x - v.x;\r\n const deltaY = this.y - v.y;\r\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\r\n }\r\n\r\n public squareDistance(v?: Vector): number {\r\n if (!v) {\r\n v = Vector.Zero;\r\n }\r\n const deltaX = this.x - v.x;\r\n const deltaY = this.y - v.y;\r\n return deltaX * deltaX + deltaY * deltaY;\r\n }\r\n\r\n /**\r\n * Clamps the current vector's magnitude mutating it\r\n * @param magnitude\r\n */\r\n public clampMagnitude(magnitude: number): Vector {\r\n const size = this.size;\r\n const newSize = clamp(size, 0, magnitude);\r\n this.size = newSize;\r\n return this;\r\n }\r\n\r\n /**\r\n * The size (magnitude) of the Vector\r\n */\r\n public get size(): number {\r\n return this.distance();\r\n }\r\n\r\n /**\r\n * Setting the size mutates the current vector\r\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\r\n */\r\n public set size(newLength: number) {\r\n const v = this.normalize().scale(newLength);\r\n this.setTo(v.x, v.y);\r\n }\r\n\r\n /**\r\n * Normalizes a vector to have a magnitude of 1.\r\n */\r\n public normalize(): Vector {\r\n const d = this.distance();\r\n if (d > 0) {\r\n return new Vector(this.x / d, this.y / d);\r\n } else {\r\n return new Vector(0, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Returns the average (midpoint) between the current point and the specified\r\n */\r\n public average(vec: Vector): Vector {\r\n return this.add(vec).scale(0.5);\r\n }\r\n\r\n /**\r\n * Scales a vector's by a factor of size\r\n * @param size The factor to scale the magnitude by\r\n * @param dest Optionally provide a destination vector for the result\r\n */\r\n public scale(scale: Vector, dest?: Vector): Vector;\r\n public scale(size: number, dest?: Vector): Vector;\r\n public scale(sizeOrScale: number | Vector, dest?: Vector): Vector {\r\n const result = dest || new Vector(0, 0);\r\n if (sizeOrScale instanceof Vector) {\r\n result.x = this.x * sizeOrScale.x;\r\n result.y = this.y * sizeOrScale.y;\r\n } else {\r\n result.x = this.x * sizeOrScale;\r\n result.y = this.y * sizeOrScale;\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Adds one vector to another\r\n * @param v The vector to add\r\n * @param dest Optionally copy the result into a provided vector\r\n */\r\n public add(v: Vector, dest?: Vector): Vector {\r\n if (dest) {\r\n dest.x = this.x + v.x;\r\n dest.y = this.y + v.y;\r\n return dest;\r\n }\r\n return new Vector(this.x + v.x, this.y + v.y);\r\n }\r\n\r\n /**\r\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\r\n * @param v The vector to subtract\r\n */\r\n public sub(v: Vector): Vector {\r\n return new Vector(this.x - v.x, this.y - v.y);\r\n }\r\n\r\n /**\r\n * Adds one vector to this one modifying the original\r\n * @param v The vector to add\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public addEqual(v: Vector): Vector {\r\n this.setTo(this.x + v.x, this.y + v.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * Subtracts a vector from this one modifying the original\r\n * @param v The vector to subtract\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public subEqual(v: Vector): Vector {\r\n this.setTo(this.x - v.x, this.y - v.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * Scales this vector by a factor of size and modifies the original\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public scaleEqual(size: number): Vector {\r\n this.setTo(this.x * size, this.y * size);\r\n return this;\r\n }\r\n\r\n /**\r\n * Performs a dot product with another vector\r\n * @param v The vector to dot\r\n */\r\n public dot(v: Vector): number {\r\n return this.x * v.x + this.y * v.y;\r\n }\r\n\r\n /**\r\n * Performs a 2D cross product with scalar. 2D cross products with a scalar return a vector.\r\n * @param v The scalar to cross\r\n */\r\n public cross(v: number): Vector;\r\n /**\r\n * Performs a 2D cross product with another vector. 2D cross products return a scalar value not a vector.\r\n * @param v The vector to cross\r\n */\r\n public cross(v: Vector): number;\r\n public cross(v: any): any {\r\n if (v instanceof Vector) {\r\n return this.x * v.y - this.y * v.x;\r\n } else if (typeof v === 'number') {\r\n return new Vector(v * this.y, -v * this.x);\r\n }\r\n }\r\n\r\n static cross(num: number, vec: Vector): Vector {\r\n return new Vector(-num * vec.y, num * vec.x);\r\n }\r\n\r\n /**\r\n * Returns the perpendicular vector to this one\r\n */\r\n public perpendicular(): Vector {\r\n return new Vector(this.y, -this.x);\r\n }\r\n\r\n /**\r\n * Returns the normal vector to this one, same as the perpendicular of length 1\r\n */\r\n public normal(): Vector {\r\n return this.perpendicular().normalize();\r\n }\r\n\r\n /**\r\n * Negate the current vector\r\n */\r\n public negate(): Vector {\r\n return this.scale(-1);\r\n }\r\n\r\n /**\r\n * Returns the angle of this vector.\r\n */\r\n public toAngle(): number {\r\n return Math.atan2(this.y, this.x);\r\n }\r\n\r\n /**\r\n * Rotates the current vector around a point by a certain number of\r\n * degrees in radians\r\n */\r\n public rotate(angle: number, anchor?: Vector): Vector {\r\n if (!anchor) {\r\n anchor = new Vector(0, 0);\r\n }\r\n const sinAngle = Math.sin(angle);\r\n const cosAngle = Math.cos(angle);\r\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\r\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\r\n return new Vector(x, y);\r\n }\r\n\r\n /**\r\n * Creates new vector that has the same values as the previous.\r\n */\r\n public clone(dest?: Vector): Vector {\r\n const v = dest ?? new Vector(0, 0);\r\n v.x = this.x;\r\n v.y = this.y;\r\n return v;\r\n }\r\n\r\n /**\r\n * Returns a string representation of the vector.\r\n */\r\n public toString(fixed?: number): string {\r\n if (fixed) {\r\n return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\r\n }\r\n return `(${this.x}, ${this.y})`;\r\n }\r\n}\r\n\r\n/**\r\n * Shorthand for creating new Vectors - returns a new Vector instance with the\r\n * provided X and Y components.\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */\r\nexport function vec(x: number, y: number): Vector {\r\n return new Vector(x, y);\r\n}\r\n","\r\n/**\r\n * Provides standard colors (e.g. [[Color.Black]])\r\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\r\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\r\n */\r\nexport class Color {\r\n /**\r\n * Red channel\r\n */\r\n public r: number;\r\n /**\r\n * Green channel\r\n */\r\n public g: number;\r\n /**\r\n * Blue channel\r\n */\r\n public b: number;\r\n /**\r\n * Alpha channel (between 0 and 1)\r\n */\r\n public a: number;\r\n\r\n /**\r\n * Hue\r\n */\r\n public h: number;\r\n /**\r\n * Saturation\r\n */\r\n public s: number;\r\n /**\r\n * Lightness\r\n */\r\n public l: number;\r\n\r\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */\r\n constructor(r: number, g: number, b: number, a?: number) {\r\n this.r = r;\r\n this.g = g;\r\n this.b = b;\r\n this.a = a != null ? a : 1;\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */\r\n public static fromRGB(r: number, g: number, b: number, a?: number): Color {\r\n return new Color(r, g, b, a);\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from a rgb string\r\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\r\n */\r\n public static fromRGBString(string: string): Color {\r\n const rgbaRegEx: RegExp = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\r\n let match = null;\r\n if ((match = string.match(rgbaRegEx))) {\r\n const r = parseInt(match[1], 10);\r\n const g = parseInt(match[2], 10);\r\n const b = parseInt(match[3], 10);\r\n let a = 1;\r\n if (match[4]) {\r\n a = parseFloat(match[4]);\r\n }\r\n return new Color(r, g, b, a);\r\n } else {\r\n throw new Error('Invalid rgb/a string: ' + string);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from a hex string\r\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\r\n */\r\n public static fromHex(hex: string): Color {\r\n const hexRegEx: RegExp = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\r\n let match = null;\r\n if ((match = hex.match(hexRegEx))) {\r\n const r = parseInt(match[1], 16);\r\n const g = parseInt(match[2], 16);\r\n const b = parseInt(match[3], 16);\r\n let a = 1;\r\n if (match[4]) {\r\n a = parseInt(match[4], 16) / 255;\r\n }\r\n return new Color(r, g, b, a);\r\n } else {\r\n throw new Error('Invalid hex string: ' + hex);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from hsla values\r\n * @param h Hue is represented [0-1]\r\n * @param s Saturation is represented [0-1]\r\n * @param l Luminance is represented [0-1]\r\n * @param a Alpha is represented [0-1]\r\n */\r\n public static fromHSL(h: number, s: number, l: number, a: number = 1.0): Color {\r\n const temp = new HSLColor(h, s, l, a);\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Lightens the current color by a specified amount\r\n * @param factor The amount to lighten by [0-1]\r\n */\r\n public lighten(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.l += (1 - temp.l) * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Darkens the current color by a specified amount\r\n * @param factor The amount to darken by [0-1]\r\n */\r\n public darken(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.l -= temp.l * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Saturates the current color by a specified amount\r\n * @param factor The amount to saturate by [0-1]\r\n */\r\n public saturate(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.s += temp.s * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Desaturates the current color by a specified amount\r\n * @param factor The amount to desaturate by [0-1]\r\n */\r\n public desaturate(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.s -= temp.s * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Multiplies a color by another, results in a darker color\r\n * @param color The other color\r\n */\r\n public multiply(color: Color): Color {\r\n const newR = (((color.r / 255) * this.r) / 255) * 255;\r\n const newG = (((color.g / 255) * this.g) / 255) * 255;\r\n const newB = (((color.b / 255) * this.b) / 255) * 255;\r\n const newA = color.a * this.a;\r\n return new Color(newR, newG, newB, newA);\r\n }\r\n\r\n /**\r\n * Screens a color by another, results in a lighter color\r\n * @param color The other color\r\n */\r\n public screen(color: Color): Color {\r\n const color1 = color.invert();\r\n const color2 = color.invert();\r\n return color1.multiply(color2).invert();\r\n }\r\n\r\n /**\r\n * Inverts the current color\r\n */\r\n public invert(): Color {\r\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\r\n }\r\n\r\n /**\r\n * Averages the current color with another\r\n * @param color The other color\r\n */\r\n public average(color: Color): Color {\r\n const newR = (color.r + this.r) / 2;\r\n const newG = (color.g + this.g) / 2;\r\n const newB = (color.b + this.b) / 2;\r\n const newA = (color.a + this.a) / 2;\r\n return new Color(newR, newG, newB, newA);\r\n }\r\n\r\n public equal(color: Color): boolean {\r\n return this.toString() === color.toString();\r\n }\r\n\r\n /**\r\n * Returns a CSS string representation of a color.\r\n * @param format Color representation, accepts: rgb, hsl, or hex\r\n */\r\n public toString(format: 'rgb' | 'hsl' | 'hex' = 'rgb') {\r\n switch (format) {\r\n case 'rgb':\r\n return this.toRGBA();\r\n case 'hsl':\r\n return this.toHSLA();\r\n case 'hex':\r\n return this.toHex();\r\n default:\r\n throw new Error('Invalid Color format');\r\n }\r\n }\r\n\r\n /**\r\n * Returns Hex Value of a color component\r\n * @param c color component\r\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\r\n */\r\n private _componentToHex(c: number) {\r\n const hex = c.toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n }\r\n\r\n /**\r\n * Return Hex representation of a color.\r\n */\r\n public toHex() {\r\n return '#' + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\r\n }\r\n\r\n /**\r\n * Return RGBA representation of a color.\r\n */\r\n public toRGBA() {\r\n const result = String(this.r.toFixed(0)) + ', ' + String(this.g.toFixed(0)) + ', ' + String(this.b.toFixed(0));\r\n if (this.a !== undefined || this.a !== null) {\r\n return 'rgba(' + result + ', ' + String(this.a) + ')';\r\n }\r\n return 'rgb(' + result + ')';\r\n }\r\n\r\n /**\r\n * Return HSLA representation of a color.\r\n */\r\n public toHSLA() {\r\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\r\n }\r\n\r\n /**\r\n * Returns a CSS string representation of a color.\r\n */\r\n public fillStyle() {\r\n return this.toString();\r\n }\r\n\r\n /**\r\n * Returns a clone of the current color.\r\n */\r\n public clone(): Color {\r\n return new Color(this.r, this.g, this.b, this.a);\r\n }\r\n\r\n /**\r\n * Black (#000000)\r\n */\r\n public static get Black(): Color {\r\n return Color.fromHex('#000000');\r\n }\r\n\r\n /**\r\n * White (#FFFFFF)\r\n */\r\n public static get White(): Color {\r\n return Color.fromHex('#FFFFFF');\r\n }\r\n\r\n /**\r\n * Gray (#808080)\r\n */\r\n public static get Gray(): Color {\r\n return Color.fromHex('#808080');\r\n }\r\n\r\n /**\r\n * Light gray (#D3D3D3)\r\n */\r\n public static get LightGray(): Color {\r\n return Color.fromHex('#D3D3D3');\r\n }\r\n\r\n /**\r\n * Dark gray (#A9A9A9)\r\n */\r\n public static get DarkGray(): Color {\r\n return Color.fromHex('#A9A9A9');\r\n }\r\n\r\n /**\r\n * Yellow (#FFFF00)\r\n */\r\n public static get Yellow(): Color {\r\n return Color.fromHex('#FFFF00');\r\n }\r\n\r\n /**\r\n * Orange (#FFA500)\r\n */\r\n public static get Orange(): Color {\r\n return Color.fromHex('#FFA500');\r\n }\r\n\r\n /**\r\n * Red (#FF0000)\r\n */\r\n public static get Red(): Color {\r\n return Color.fromHex('#FF0000');\r\n }\r\n\r\n /**\r\n * Vermilion (#FF5B31)\r\n */\r\n public static get Vermilion(): Color {\r\n return Color.fromHex('#FF5B31');\r\n }\r\n\r\n /**\r\n * Rose (#FF007F)\r\n */\r\n public static get Rose(): Color {\r\n return Color.fromHex('#FF007F');\r\n }\r\n\r\n /**\r\n * Magenta (#FF00FF)\r\n */\r\n public static get Magenta(): Color {\r\n return Color.fromHex('#FF00FF');\r\n }\r\n\r\n /**\r\n * Violet (#7F00FF)\r\n */\r\n public static get Violet(): Color {\r\n return Color.fromHex('#7F00FF');\r\n }\r\n\r\n /**\r\n * Blue (#0000FF)\r\n */\r\n public static get Blue(): Color {\r\n return Color.fromHex('#0000FF');\r\n }\r\n\r\n /**\r\n * Azure (#007FFF)\r\n */\r\n public static get Azure(): Color {\r\n return Color.fromHex('#007FFF');\r\n }\r\n\r\n /**\r\n * Cyan (#00FFFF)\r\n */\r\n public static get Cyan(): Color {\r\n return Color.fromHex('#00FFFF');\r\n }\r\n\r\n /**\r\n * Viridian (#59978F)\r\n */\r\n public static get Viridian(): Color {\r\n return Color.fromHex('#59978F');\r\n }\r\n\r\n /**\r\n * Green (#00FF00)\r\n */\r\n public static get Green(): Color {\r\n return Color.fromHex('#00FF00');\r\n }\r\n\r\n /**\r\n * Chartreuse (#7FFF00)\r\n */\r\n public static get Chartreuse(): Color {\r\n return Color.fromHex('#7FFF00');\r\n }\r\n\r\n /**\r\n * Transparent (#FFFFFF00)\r\n */\r\n public static get Transparent(): Color {\r\n return Color.fromHex('#FFFFFF00');\r\n }\r\n\r\n /**\r\n * ExcaliburBlue (#176BAA)\r\n */\r\n public static get ExcaliburBlue(): Color {\r\n return Color.fromHex('#176BAA');\r\n }\r\n}\r\n\r\n/**\r\n * Internal HSL Color representation\r\n *\r\n * http://en.wikipedia.org/wiki/HSL_and_HSV\r\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\r\n */\r\nclass HSLColor {\r\n constructor(public h: number, public s: number, public l: number, public a: number) {}\r\n\r\n public static hue2rgb(p: number, q: number, t: number): number {\r\n if (t < 0) {\r\n t += 1;\r\n }\r\n if (t > 1) {\r\n t -= 1;\r\n }\r\n if (t < 1 / 6) {\r\n return p + (q - p) * 6 * t;\r\n }\r\n if (t < 1 / 2) {\r\n return q;\r\n }\r\n if (t < 2 / 3) {\r\n return p + (q - p) * (2 / 3 - t) * 6;\r\n }\r\n return p;\r\n }\r\n\r\n public static fromRGBA(r: number, g: number, b: number, a: number): HSLColor {\r\n r /= 255;\r\n g /= 255;\r\n b /= 255;\r\n const max = Math.max(r, g, b),\r\n min = Math.min(r, g, b);\r\n let h, s;\r\n const l = (max + min) / 2;\r\n\r\n if (max === min) {\r\n h = s = 0; // achromatic\r\n } else {\r\n const d = max - min;\r\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\r\n switch (max) {\r\n case r:\r\n h = (g - b) / d + (g < b ? 6 : 0);\r\n break;\r\n case g:\r\n h = (b - r) / d + 2;\r\n break;\r\n case b:\r\n h = (r - g) / d + 4;\r\n break;\r\n }\r\n h /= 6;\r\n }\r\n\r\n return new HSLColor(h, s, l, a);\r\n }\r\n\r\n public toRGBA(): Color {\r\n let r: number, g: number, b: number;\r\n\r\n if (this.s === 0) {\r\n r = g = b = this.l; // achromatic\r\n } else {\r\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\r\n const p = 2 * this.l - q;\r\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\r\n g = HSLColor.hue2rgb(p, q, this.h);\r\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\r\n }\r\n\r\n return new Color(r * 255, g * 255, b * 255, this.a);\r\n }\r\n\r\n public toString(): string {\r\n const h = this.h.toFixed(0),\r\n s = this.s.toFixed(0),\r\n l = this.l.toFixed(0),\r\n a = this.a.toFixed(0);\r\n return `hsla(${h}, ${s}, ${l}, ${a})`;\r\n }\r\n}\r\n","/* eslint-disable no-console */\r\n\r\nimport { Engine } from '../Engine';\r\nimport { vec } from '../Math/vector';\r\nimport { Color } from '../Color';\r\n\r\n/**\r\n * Logging level that Excalibur will tag\r\n */\r\nexport enum LogLevel {\r\n Debug,\r\n Info,\r\n Warn,\r\n Error,\r\n Fatal\r\n}\r\n\r\n/**\r\n * Static singleton that represents the logging facility for Excalibur.\r\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\r\n * Derive from [[Appender]] to create your own logging appenders.\r\n */\r\nexport class Logger {\r\n private static _INSTANCE: Logger = null;\r\n private _appenders: Appender[] = [];\r\n\r\n constructor() {\r\n if (Logger._INSTANCE) {\r\n throw new Error('Logger is a singleton');\r\n }\r\n Logger._INSTANCE = this;\r\n // Default console appender\r\n Logger._INSTANCE.addAppender(new ConsoleAppender());\r\n return Logger._INSTANCE;\r\n }\r\n\r\n /**\r\n * Gets or sets the default logging level. Excalibur will only log\r\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\r\n */\r\n public defaultLevel: LogLevel = LogLevel.Info;\r\n\r\n /**\r\n * Gets the current static instance of Logger\r\n */\r\n public static getInstance(): Logger {\r\n if (Logger._INSTANCE == null) {\r\n Logger._INSTANCE = new Logger();\r\n }\r\n return Logger._INSTANCE;\r\n }\r\n\r\n /**\r\n * Adds a new [[Appender]] to the list of appenders to write to\r\n */\r\n public addAppender(appender: Appender): void {\r\n this._appenders.push(appender);\r\n }\r\n\r\n /**\r\n * Clears all appenders from the logger\r\n */\r\n public clearAppenders(): void {\r\n this._appenders.length = 0;\r\n }\r\n\r\n /**\r\n * Logs a message at a given LogLevel\r\n * @param level The LogLevel`to log the message at\r\n * @param args An array of arguments to write to an appender\r\n */\r\n private _log(level: LogLevel, args: any[]): void {\r\n if (level == null) {\r\n level = this.defaultLevel;\r\n }\r\n\r\n const len = this._appenders.length;\r\n\r\n for (let i = 0; i < len; i++) {\r\n if (level >= this.defaultLevel) {\r\n this._appenders[i].log(level, args);\r\n }\r\n }\r\n }\r\n\r\n\r\n private _logOnceSet = new Set();\r\n private _logOnce(level: LogLevel, args: any[]): void {\r\n const serialized = level + args.join('+');\r\n if (this._logOnceSet.has(serialized)) {\r\n return;\r\n } else {\r\n this._logOnceSet.add(serialized);\r\n this._log(level, args);\r\n }\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Debug]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public debug(...args: any[]): void {\r\n this._log(LogLevel.Debug, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it wont log\r\n * @param args Accepts any number of arguments\r\n */\r\n public debugOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Debug, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Info]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public info(...args: any[]): void {\r\n this._log(LogLevel.Info, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Info]] level, if it sees the same args again it wont log\r\n * @param args Accepts any number of arguments\r\n */\r\n public infoOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Info, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Warn]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public warn(...args: any[]): void {\r\n this._log(LogLevel.Warn, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Warn]] level, if it sees the same args again it won't log\r\n * @param args Accepts any number of arguments\r\n */\r\n public warnOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Warn, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Error]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public error(...args: any[]): void {\r\n this._log(LogLevel.Error, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Error]] level, if it sees the same args again it won't log\r\n * @param args Accepts any number of arguments\r\n */\r\n public errorOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Error, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Fatal]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public fatal(...args: any[]): void {\r\n this._log(LogLevel.Fatal, args);\r\n }\r\n\r\n /**\r\n * Writes a log message once at the [[LogLevel.Fatal]] level, if it sees the same args again it won't log\r\n * @param args Accepts any number of arguments\r\n */\r\n public fatalOnce(...args: any[]): void {\r\n this._logOnce(LogLevel.Fatal, args);\r\n }\r\n}\r\n\r\n/**\r\n * Contract for any log appender (such as console/screen)\r\n */\r\nexport interface Appender {\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n log(level: LogLevel, args: any[]): void;\r\n}\r\n\r\n/**\r\n * Console appender for browsers (i.e. `console.log`)\r\n */\r\nexport class ConsoleAppender implements Appender {\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n public log(level: LogLevel, args: any[]): void {\r\n // Check for console support\r\n if (!console && !console.log && console.warn && console.error) {\r\n // todo maybe do something better than nothing\r\n return;\r\n }\r\n\r\n // Create a new console args array\r\n const consoleArgs: any[] = [];\r\n consoleArgs.unshift.apply(consoleArgs, args);\r\n consoleArgs.unshift('[' + LogLevel[level] + '] : ');\r\n\r\n if (level < LogLevel.Warn) {\r\n // Call .log for Debug/Info\r\n if (console.log.apply) {\r\n // this is required on some older browsers that don't support apply on console.log :(\r\n console.log.apply(console, consoleArgs);\r\n } else {\r\n console.log(consoleArgs.join(' '));\r\n }\r\n } else if (level < LogLevel.Error) {\r\n // Call .warn for Warn\r\n if (console.warn.apply) {\r\n console.warn.apply(console, consoleArgs);\r\n } else {\r\n console.warn(consoleArgs.join(' '));\r\n }\r\n } else {\r\n // Call .error for Error/Fatal\r\n if (console.error.apply) {\r\n console.error.apply(console, consoleArgs);\r\n } else {\r\n console.error(consoleArgs.join(' '));\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport interface ScreenAppenderOptions {\r\n engine: Engine;\r\n /**\r\n * Optionally set the width of the overlay canvas\r\n */\r\n width?: number;\r\n /**\r\n * Optionally set the height of the overlay canvas\r\n */\r\n height?: number;\r\n /**\r\n * Adjust the text offset from the left side of the screen\r\n */\r\n xPos?: number;\r\n /**\r\n * Provide a text color\r\n */\r\n color?: Color;\r\n /**\r\n * Optionally set the CSS zindex of the overlay canvas\r\n */\r\n zIndex?: number;\r\n}\r\n\r\n/**\r\n * On-screen (canvas) appender\r\n */\r\nexport class ScreenAppender implements Appender {\r\n\r\n private _messages: string[] = [];\r\n public canvas: HTMLCanvasElement;\r\n private _ctx: CanvasRenderingContext2D;\r\n private _pos = 10;\r\n private _color = Color.Black;\r\n private _options: ScreenAppenderOptions;\r\n constructor(options: ScreenAppenderOptions) {\r\n this._options = options;\r\n this.canvas = document.createElement('canvas');\r\n this._ctx = this.canvas.getContext('2d')!;\r\n this.canvas.style.position = 'absolute';\r\n this.canvas.style.zIndex = options.zIndex?.toString() ?? '99';\r\n document.body.appendChild(this.canvas);\r\n this._positionScreenAppenderCanvas();\r\n options.engine.screen.events.on('resize', () => {\r\n this._positionScreenAppenderCanvas();\r\n });\r\n }\r\n\r\n private _positionScreenAppenderCanvas() {\r\n const options = this._options;\r\n this.canvas.width = options.width ?? options.engine.screen.resolution.width;\r\n this.canvas.height = options.height ?? options.engine.screen.resolution.height;\r\n this.canvas.style.position = 'absolute';\r\n const pagePos = options.engine.screen.screenToPageCoordinates(vec(0, 0));\r\n this.canvas.style.left = pagePos.x + 'px';\r\n this.canvas.style.top = pagePos.y + 'px';\r\n this._pos = options.xPos ?? this._pos;\r\n this._color = options.color ?? this._color;\r\n }\r\n\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n public log(level: LogLevel, args: any[]): void {\r\n const message = args.join(',');\r\n\r\n this._ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\r\n\r\n this._messages.unshift('[' + LogLevel[level] + '] : ' + message);\r\n\r\n let pos = 10;\r\n\r\n this._messages = this._messages.slice(0, 1000);\r\n for (let i = 0; i < this._messages.length; i++) {\r\n this._ctx.fillStyle = this._color.toRGBA();\r\n this._ctx.fillText(this._messages[i], this._pos, pos);\r\n pos += 10;\r\n }\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\n\r\n/**\r\n * An enum that describes the sides of an axis aligned box for collision\r\n */\r\nexport enum Side {\r\n None = 'None',\r\n Top = 'Top',\r\n Bottom = 'Bottom',\r\n Left = 'Left',\r\n Right = 'Right'\r\n}\r\n\r\nexport module Side {\r\n /**\r\n * Returns the opposite side from the current\r\n */\r\n export function getOpposite(side: Side): Side {\r\n if (side === Side.Top) {\r\n return Side.Bottom;\r\n }\r\n if (side === Side.Bottom) {\r\n return Side.Top;\r\n }\r\n if (side === Side.Left) {\r\n return Side.Right;\r\n }\r\n if (side === Side.Right) {\r\n return Side.Left;\r\n }\r\n\r\n return Side.None;\r\n }\r\n\r\n /**\r\n * Given a vector, return the Side most in that direction (via dot product)\r\n */\r\n export function fromDirection(direction: Vector): Side {\r\n const directions = [Vector.Left, Vector.Right, Vector.Up, Vector.Down];\r\n const directionEnum = [Side.Left, Side.Right, Side.Top, Side.Bottom];\r\n\r\n let max = -Number.MAX_VALUE;\r\n let maxIndex = -1;\r\n for (let i = 0; i < directions.length; i++) {\r\n if (directions[i].dot(direction) > max) {\r\n max = directions[i].dot(direction);\r\n maxIndex = i;\r\n }\r\n }\r\n return directionEnum[maxIndex];\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Ray } from '../Math/ray';\r\nimport { Color } from '../Color';\r\nimport { Side } from './Side';\r\nimport { ExcaliburGraphicsContext } from '../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { AffineMatrix } from '../Math/affine-matrix';\r\n\r\nexport interface BoundingBoxOptions {\r\n left: number;\r\n right: number;\r\n top: number;\r\n bottom: number;\r\n}\r\n\r\n/**\r\n * Axis Aligned collision primitive for Excalibur.\r\n */\r\nexport class BoundingBox {\r\n public top: number;\r\n public right: number;\r\n public bottom: number;\r\n public left: number;\r\n\r\n /**\r\n * Constructor allows passing of either an object with all coordinate components,\r\n * or the coordinate components passed separately.\r\n * @param leftOrOptions Either x coordinate of the left edge or an options object\r\n * containing the four coordinate components.\r\n * @param top y coordinate of the top edge\r\n * @param right x coordinate of the right edge\r\n * @param bottom y coordinate of the bottom edge\r\n */\r\n constructor(leftOrOptions: number | BoundingBoxOptions = 0, top: number = 0, right: number = 0, bottom: number = 0) {\r\n if (typeof leftOrOptions === 'object') {\r\n this.left = leftOrOptions.left;\r\n this.top = leftOrOptions.top;\r\n this.right = leftOrOptions.right;\r\n this.bottom = leftOrOptions.bottom;\r\n } else if (typeof leftOrOptions === 'number') {\r\n this.left = leftOrOptions;\r\n this.top = top;\r\n this.right = right;\r\n this.bottom = bottom;\r\n }\r\n }\r\n\r\n /**\r\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\r\n */\r\n public clone(): BoundingBox {\r\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\r\n }\r\n\r\n /**\r\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\r\n * @param intersection Intersection vector between 2 bounding boxes\r\n */\r\n public static getSideFromIntersection(intersection: Vector): Side {\r\n if (!intersection) {\r\n return Side.None;\r\n }\r\n if (intersection) {\r\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\r\n if (intersection.x < 0) {\r\n return Side.Right;\r\n }\r\n return Side.Left;\r\n } else {\r\n if (intersection.y < 0) {\r\n return Side.Bottom;\r\n }\r\n return Side.Top;\r\n }\r\n }\r\n return Side.None;\r\n }\r\n\r\n public static fromPoints(points: Vector[]): BoundingBox {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n for (let i = 0; i < points.length; i++) {\r\n if (points[i].x < minX) {\r\n minX = points[i].x;\r\n }\r\n if (points[i].x > maxX) {\r\n maxX = points[i].x;\r\n }\r\n if (points[i].y < minY) {\r\n minY = points[i].y;\r\n }\r\n if (points[i].y > maxY) {\r\n maxY = points[i].y;\r\n }\r\n }\r\n return new BoundingBox(minX, minY, maxX, maxY);\r\n }\r\n\r\n /**\r\n * Creates a bounding box from a width and height\r\n * @param width\r\n * @param height\r\n * @param anchor Default Vector.Half\r\n * @param pos Default Vector.Zero\r\n */\r\n public static fromDimension(width: number, height: number, anchor: Vector = Vector.Half, pos: Vector = Vector.Zero) {\r\n return new BoundingBox(\r\n -width * anchor.x + pos.x,\r\n -height * anchor.y + pos.y,\r\n width - width * anchor.x + pos.x,\r\n height - height * anchor.y + pos.y\r\n );\r\n }\r\n\r\n /**\r\n * Returns the calculated width of the bounding box\r\n */\r\n public get width() {\r\n return this.right - this.left;\r\n }\r\n\r\n /**\r\n * Returns the calculated height of the bounding box\r\n */\r\n public get height() {\r\n return this.bottom - this.top;\r\n }\r\n\r\n /**\r\n * Return whether the bounding box has zero dimensions in height,width or both\r\n */\r\n public hasZeroDimensions() {\r\n return this.width === 0 || this.height === 0;\r\n }\r\n\r\n /**\r\n * Returns the center of the bounding box\r\n */\r\n public get center(): Vector {\r\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\r\n }\r\n\r\n public get topLeft(): Vector {\r\n return new Vector(this.left, this.top);\r\n }\r\n\r\n public get bottomRight(): Vector {\r\n return new Vector(this.right, this.bottom);\r\n }\r\n\r\n public get topRight(): Vector {\r\n return new Vector(this.right, this.top);\r\n }\r\n\r\n public get bottomLeft(): Vector {\r\n return new Vector(this.left, this.bottom);\r\n }\r\n\r\n public translate(pos: Vector): BoundingBox {\r\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\r\n }\r\n\r\n /**\r\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\r\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\r\n */\r\n public rotate(angle: number, point: Vector = Vector.Zero): BoundingBox {\r\n const points = this.getPoints().map((p) => p.rotate(angle, point));\r\n return BoundingBox.fromPoints(points);\r\n }\r\n\r\n /**\r\n * Scale a bounding box by a scale factor, optionally provide a point\r\n * @param scale\r\n * @param point\r\n */\r\n public scale(scale: Vector, point: Vector = Vector.Zero): BoundingBox {\r\n const shifted = this.translate(point);\r\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\r\n }\r\n\r\n /**\r\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\r\n * @param matrix\r\n */\r\n public transform(matrix: AffineMatrix) {\r\n // inlined these calculations to not use vectors would speed it up slightly\r\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\r\n // const xa = matFirstColumn.scale(this.left);\r\n const xa1 = matrix.data[0] * this.left;\r\n const xa2 = matrix.data[1] * this.left;\r\n\r\n // const xb = matFirstColumn.scale(this.right);\r\n const xb1 = matrix.data[0] * this.right;\r\n const xb2 = matrix.data[1] * this.right;\r\n\r\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\r\n // const ya = matSecondColumn.scale(this.top);\r\n const ya1 = matrix.data[2] * this.top;\r\n const ya2 = matrix.data[3] * this.top;\r\n\r\n // const yb = matSecondColumn.scale(this.bottom);\r\n const yb1 = matrix.data[2] * this.bottom;\r\n const yb2 = matrix.data[3] * this.bottom;\r\n\r\n const matrixPos = matrix.getPosition();\r\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\r\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\r\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\r\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\r\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\r\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\r\n\r\n return new BoundingBox({\r\n left,//: topLeft.x,\r\n top,//: topLeft.y,\r\n right,//: bottomRight.x,\r\n bottom//: bottomRight.y\r\n });\r\n }\r\n\r\n /**\r\n * Returns the perimeter of the bounding box\r\n */\r\n public getPerimeter(): number {\r\n const wx = this.width;\r\n const wy = this.height;\r\n return 2 * (wx + wy);\r\n }\r\n\r\n\r\n // Cache bounding box point returns\r\n private _points: Vector[] = [];\r\n private _left?: number;\r\n private _right?: number;\r\n private _top?: number;\r\n private _bottom?: number;\r\n\r\n /**\r\n * Returns the world space points that make up the corners of the bounding box as a polygon\r\n */\r\n public getPoints(): Vector[] {\r\n if (this._left !== this.left ||\r\n this._right !== this.right ||\r\n this._top !== this.top ||\r\n this._bottom !== this.bottom\r\n ) {\r\n this._points.length = 0;\r\n this._points.push(new Vector(this.left, this.top));\r\n this._points.push(new Vector(this.right, this.top));\r\n this._points.push(new Vector(this.right, this.bottom));\r\n this._points.push(new Vector(this.left, this.bottom));\r\n this._left = this.left;\r\n this._right = this.right;\r\n this._top = this.top;\r\n this._bottom = this.bottom;\r\n }\r\n return this._points;\r\n }\r\n\r\n /**\r\n * Determines whether a ray intersects with a bounding box\r\n */\r\n public rayCast(ray: Ray, farClipDistance = Infinity): boolean {\r\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\r\n let tmin = -Infinity;\r\n let tmax = +Infinity;\r\n\r\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\r\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\r\n\r\n const tx1 = (this.left - ray.pos.x) * xinv;\r\n const tx2 = (this.right - ray.pos.x) * xinv;\r\n tmin = Math.min(tx1, tx2);\r\n tmax = Math.max(tx1, tx2);\r\n\r\n const ty1 = (this.top - ray.pos.y) * yinv;\r\n const ty2 = (this.bottom - ray.pos.y) * yinv;\r\n tmin = Math.max(tmin, Math.min(ty1, ty2));\r\n tmax = Math.min(tmax, Math.max(ty1, ty2));\r\n\r\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\r\n }\r\n\r\n public rayCastTime(ray: Ray, farClipDistance = Infinity): number {\r\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\r\n let tmin = -Infinity;\r\n let tmax = +Infinity;\r\n\r\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\r\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\r\n\r\n const tx1 = (this.left - ray.pos.x) * xinv;\r\n const tx2 = (this.right - ray.pos.x) * xinv;\r\n tmin = Math.min(tx1, tx2);\r\n tmax = Math.max(tx1, tx2);\r\n\r\n const ty1 = (this.top - ray.pos.y) * yinv;\r\n const ty2 = (this.bottom - ray.pos.y) * yinv;\r\n tmin = Math.max(tmin, Math.min(ty1, ty2));\r\n tmax = Math.min(tmax, Math.max(ty1, ty2));\r\n\r\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) {\r\n return tmin;\r\n }\r\n return -1;\r\n }\r\n\r\n /**\r\n * Tests whether a point is contained within the bounding box\r\n * @param p The point to test\r\n */\r\n public contains(p: Vector): boolean;\r\n\r\n /**\r\n * Tests whether another bounding box is totally contained in this one\r\n * @param bb The bounding box to test\r\n */\r\n public contains(bb: BoundingBox): boolean;\r\n public contains(val: any): boolean {\r\n if (val instanceof Vector) {\r\n return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\r\n } else if (val instanceof BoundingBox) {\r\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Combines this bounding box and another together returning a new bounding box\r\n * @param other The bounding box to combine\r\n */\r\n public combine(other: BoundingBox): BoundingBox {\r\n const compositeBB = new BoundingBox(\r\n Math.min(this.left, other.left),\r\n Math.min(this.top, other.top),\r\n Math.max(this.right, other.right),\r\n Math.max(this.bottom, other.bottom)\r\n );\r\n return compositeBB;\r\n }\r\n\r\n public get dimensions(): Vector {\r\n return new Vector(this.width, this.height);\r\n }\r\n\r\n /**\r\n * Returns true if the bounding boxes overlap.\r\n * @param other\r\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\r\n * This epsilon is useful in stable collision simulations.\r\n */\r\n public overlaps(other: BoundingBox, epsilon?: number): boolean {\r\n const e = epsilon || 0;\r\n if (other.hasZeroDimensions()){\r\n return this.contains(other);\r\n }\r\n if (this.hasZeroDimensions()) {\r\n return other.contains(this);\r\n }\r\n const totalBoundingBox = this.combine(other);\r\n return totalBoundingBox.width + e < other.width + this.width &&\r\n totalBoundingBox.height + e < other.height + this.height;\r\n }\r\n\r\n /**\r\n * Test wether this bounding box intersects with another returning\r\n * the intersection vector that can be used to resolve the collision. If there\r\n * is no intersection null is returned.\r\n * @param other Other [[BoundingBox]] to test intersection with\r\n * @returns A Vector in the direction of the current BoundingBox, this <- other\r\n */\r\n public intersect(other: BoundingBox): Vector {\r\n const totalBoundingBox = this.combine(other);\r\n\r\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\r\n if (\r\n totalBoundingBox.width < other.width + this.width &&\r\n totalBoundingBox.height < other.height + this.height &&\r\n !totalBoundingBox.dimensions.equals(other.dimensions) &&\r\n !totalBoundingBox.dimensions.equals(this.dimensions)\r\n ) {\r\n // collision\r\n let overlapX = 0;\r\n // right edge is between the other's left and right edge\r\n /**\r\n * +-this-+\r\n * | |\r\n * | +-other-+\r\n * +----|-+ |\r\n * | |\r\n * +-------+\r\n * <---\r\n * ^ overlap\r\n */\r\n if (this.right >= other.left && this.right <= other.right) {\r\n overlapX = other.left - this.right;\r\n // right edge is past the other's right edge\r\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+\r\n * +----|--+ |\r\n * | |\r\n * +------+\r\n * --->\r\n * ^ overlap\r\n */\r\n } else {\r\n overlapX = other.right - this.left;\r\n }\r\n\r\n let overlapY = 0;\r\n // top edge is between the other's top and bottom edge\r\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+ | <- overlap\r\n * +----|--+ | |\r\n * | | \\ /\r\n * +------+ '\r\n */\r\n if (this.top <= other.bottom && this.top >= other.top) {\r\n overlapY = other.bottom - this.top;\r\n // top edge is above the other top edge\r\n /**\r\n * +-this-+ .\r\n * | | / \\\r\n * | +-other-+ | <- overlap\r\n * +----|-+ | |\r\n * | |\r\n * +-------+\r\n */\r\n } else {\r\n overlapY = other.top - this.bottom;\r\n }\r\n\r\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\r\n return new Vector(overlapX, 0);\r\n } else {\r\n return new Vector(0, overlapY);\r\n }\r\n // Case of total containment of one bounding box by another\r\n } else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\r\n let overlapX = 0;\r\n // this is wider than the other\r\n if (this.width - other.width >= 0) {\r\n // This right edge is closest to the others right edge\r\n if (this.right - other.right <= other.left - this.left) {\r\n overlapX = other.left - this.right;\r\n // This left edge is closest to the others left edge\r\n } else {\r\n overlapX = other.right - this.left;\r\n }\r\n // other is wider than this\r\n } else {\r\n // This right edge is closest to the others right edge\r\n if (other.right - this.right <= this.left - other.left) {\r\n overlapX = this.left - other.right;\r\n // This left edge is closest to the others left edge\r\n } else {\r\n overlapX = this.right - other.left;\r\n }\r\n }\r\n\r\n let overlapY = 0;\r\n // this is taller than other\r\n if (this.height - other.height >= 0) {\r\n // The bottom edge is closest to the others bottom edge\r\n if (this.bottom - other.bottom <= other.top - this.top) {\r\n overlapY = other.top - this.bottom;\r\n } else {\r\n overlapY = other.bottom - this.top;\r\n }\r\n // other is taller than this\r\n } else {\r\n // The bottom edge is closest to the others bottom edge\r\n if (other.bottom - this.bottom <= this.top - other.top) {\r\n overlapY = this.top - other.bottom;\r\n } else {\r\n overlapY = this.bottom - other.top;\r\n }\r\n }\r\n\r\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\r\n return new Vector(overlapX, 0);\r\n } else {\r\n return new Vector(0, overlapY);\r\n }\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\r\n * @param bb The other actor to test\r\n */\r\n public intersectWithSide(bb: BoundingBox): Side {\r\n const intersect = this.intersect(bb);\r\n return BoundingBox.getSideFromIntersection(intersect);\r\n }\r\n\r\n /**\r\n * Draw a debug bounding box\r\n * @param ex\r\n * @param color\r\n */\r\n public draw(ex: ExcaliburGraphicsContext, color: Color = Color.Yellow) {\r\n ex.debug.drawRect(this.left, this.top, this.width, this.height, { color });\r\n }\r\n}\r\n","import { Vector, vec } from '../Math/vector';\r\nimport { Clock } from './Clock';\r\nimport { Future } from './Future';\r\n\r\n/**\r\n * Find the screen position of an HTML element\r\n */\r\nexport function getPosition(el: HTMLElement): Vector {\r\n // do we need the scroll too? technically the offset method before did that\r\n const rect = el.getBoundingClientRect();\r\n return vec(rect.x + window.scrollX, rect.y + window.scrollY);\r\n}\r\n\r\n/**\r\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\r\n * @deprecated Will be removed in v0.26.0\r\n */\r\nexport function addItemToArray(item: T, array: T[]): boolean {\r\n if (array.indexOf(item) === -1) {\r\n array.push(item);\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Remove an item from an list\r\n * @deprecated Will be removed in v0.26.0\r\n */\r\nexport function removeItemFromArray(item: T, array: T[]): boolean {\r\n let index = -1;\r\n if ((index = array.indexOf(item)) > -1) {\r\n array.splice(index, 1);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * See if an array contains something\r\n */\r\nexport function contains(array: Array, obj: any): boolean {\r\n for (let i = 0; i < array.length; i++) {\r\n if (array[i] === obj) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Used for exhaustive checks at compile time\r\n */\r\nexport function fail(message: never): never {\r\n throw new Error(message);\r\n}\r\n\r\n/**\r\n * Create a promise that resolves after a certain number of milliseconds\r\n *\r\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\r\n * excalibur clock which would be unaffected by stop/pause.\r\n * @param milliseconds\r\n * @param clock\r\n */\r\nexport function delay(milliseconds: number, clock?: Clock): Promise {\r\n const future = new Future();\r\n const schedule = clock?.schedule.bind(clock) ?? setTimeout;\r\n schedule(() => {\r\n future.resolve();\r\n }, milliseconds);\r\n return future.promise;\r\n}\r\n\r\n/**\r\n * Remove keys from object literals\r\n * @param object\r\n * @param keys\r\n */\r\nexport function omit(object: TObject, keys: Keys[]) {\r\n const newObj: Omit = {} as any;\r\n for (const key in object) {\r\n if (!keys.includes(key as any)) {\r\n (newObj as any)[key] = object[key];\r\n }\r\n }\r\n return newObj;\r\n}","import { sign } from './util';\r\nimport { Vector, vec } from './vector';\r\nimport { canonicalizeAngle } from './util';\r\n\r\nexport enum MatrixLocations {\r\n X = 12,\r\n Y = 13\r\n}\r\n\r\n/**\r\n * Excalibur Matrix helper for 4x4 matrices\r\n *\r\n * Useful for webgl 4x4 matrices\r\n */\r\nexport class Matrix {\r\n /**\r\n * 4x4 matrix in column major order\r\n *\r\n * | | | | |\r\n * | ------- | ------- | -------- | -------- |\r\n * | data[0] | data[4] | data[8] | data[12] |\r\n * | data[1] | data[5] | data[9] | data[13] |\r\n * | data[2] | data[6] | data[10] | data[14] |\r\n * | data[3] | data[7] | data[11] | data[15] |\r\n *\r\n */\r\n public data: Float32Array = new Float32Array(16);\r\n\r\n /**\r\n * Creates an orthographic (flat non-perspective) projection\r\n * https://en.wikipedia.org/wiki/Orthographic_projection\r\n * @param left\r\n * @param right\r\n * @param bottom\r\n * @param top\r\n * @param near\r\n * @param far\r\n */\r\n public static ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix {\r\n const mat = new Matrix();\r\n mat.data[0] = 2 / (right - left);\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 2 / (top - bottom);\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = -2 / (far - near);\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = -(right + left) / (right - left);\r\n mat.data[13] = -(top + bottom) / (top - bottom);\r\n mat.data[14] = -(far + near) / (far - near);\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */\r\n public clone(dest?: Matrix): Matrix {\r\n const mat = dest || new Matrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = this.data[2];\r\n mat.data[3] = this.data[3];\r\n\r\n mat.data[4] = this.data[4];\r\n mat.data[5] = this.data[5];\r\n mat.data[6] = this.data[6];\r\n mat.data[7] = this.data[7];\r\n\r\n mat.data[8] = this.data[8];\r\n mat.data[9] = this.data[9];\r\n mat.data[10] = this.data[10];\r\n mat.data[11] = this.data[11];\r\n\r\n mat.data[12] = this.data[12];\r\n mat.data[13] = this.data[13];\r\n mat.data[14] = this.data[14];\r\n mat.data[15] = this.data[15];\r\n return mat;\r\n }\r\n\r\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */\r\n public toDOMMatrix(): DOMMatrix {\r\n return new DOMMatrix([...this.data]);\r\n }\r\n\r\n public static fromFloat32Array(data: Float32Array) {\r\n const matrix = new Matrix();\r\n matrix.data = data;\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Creates a new identity matrix (a matrix that when applied does nothing)\r\n */\r\n public static identity(): Matrix {\r\n const mat = new Matrix();\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 1;\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = 0;\r\n mat.data[13] = 0;\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {Matrix} Current matrix as identity\r\n */\r\n public reset(): Matrix {\r\n const mat = this;\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 1;\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = 0;\r\n mat.data[13] = 0;\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */\r\n public static translation(x: number, y: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[12] = x;\r\n mat.data[13] = y;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */\r\n public static scale(sx: number, sy: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[0] = sx;\r\n mat.data[5] = sy;\r\n mat.data[10] = 1;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */\r\n public static rotation(angleRadians: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[0] = Math.cos(angleRadians);\r\n mat.data[4] = -Math.sin(angleRadians);\r\n mat.data[1] = Math.sin(angleRadians);\r\n mat.data[5] = Math.cos(angleRadians);\r\n return mat;\r\n }\r\n\r\n /**\r\n * Multiply the current matrix by a vector producing a new vector\r\n * @param vector\r\n * @param dest\r\n */\r\n multiply(vector: Vector, dest?: Vector): Vector;\r\n /**\r\n * Multiply the current matrix by another matrix producing a new matrix\r\n * @param matrix\r\n * @param dest\r\n */\r\n multiply(matrix: Matrix, dest?: Matrix): Matrix;\r\n multiply(vectorOrMatrix: Vector | Matrix, dest?: Vector | Matrix): Vector | Matrix {\r\n if (vectorOrMatrix instanceof Vector) {\r\n const result = (dest as Vector) || new Vector(0, 0);\r\n const vector = vectorOrMatrix;\r\n // these shenanigans are to allow dest and vector to be the same instance\r\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\r\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\r\n\r\n result.x = resultX;\r\n result.y = resultY;\r\n return result;\r\n } else {\r\n const result = (dest as Matrix) || new Matrix();\r\n const other = vectorOrMatrix;\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const a13 = this.data[8];\r\n const a23 = this.data[9];\r\n const a33 = this.data[10];\r\n const a43 = this.data[11];\r\n\r\n const a14 = this.data[12];\r\n const a24 = this.data[13];\r\n const a34 = this.data[14];\r\n const a44 = this.data[15];\r\n\r\n const b11 = other.data[0];\r\n const b21 = other.data[1];\r\n const b31 = other.data[2];\r\n const b41 = other.data[3];\r\n\r\n const b12 = other.data[4];\r\n const b22 = other.data[5];\r\n const b32 = other.data[6];\r\n const b42 = other.data[7];\r\n\r\n const b13 = other.data[8];\r\n const b23 = other.data[9];\r\n const b33 = other.data[10];\r\n const b43 = other.data[11];\r\n\r\n const b14 = other.data[12];\r\n const b24 = other.data[13];\r\n const b34 = other.data[14];\r\n const b44 = other.data[15];\r\n\r\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\r\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\r\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\r\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\r\n\r\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\r\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\r\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\r\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\r\n\r\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\r\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\r\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\r\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\r\n\r\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\r\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\r\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\r\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\r\n\r\n const s = this.getScale();\r\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\r\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\r\n\r\n return result;\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const a13 = this.data[8];\r\n const a23 = this.data[9];\r\n const a33 = this.data[10];\r\n const a43 = this.data[11];\r\n\r\n const a14 = this.data[12];\r\n const a24 = this.data[13];\r\n const a34 = this.data[14];\r\n const a44 = this.data[15];\r\n\r\n // Doesn't change z\r\n const z = 0;\r\n const w = 1;\r\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\r\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\r\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\r\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\r\n\r\n return this;\r\n }\r\n\r\n public setPosition(x: number, y: number) {\r\n this.data[12] = x;\r\n this.data[13] = y;\r\n }\r\n\r\n public getPosition(): Vector {\r\n return vec(this.data[12], this.data[13]);\r\n }\r\n\r\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */\r\n rotate(angle: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * a11 + sine * a12;\r\n this.data[1] = cosine * a21 + sine * a22;\r\n this.data[2] = cosine * a31 + sine * a32;\r\n this.data[3] = cosine * a41 + sine * a42;\r\n\r\n this.data[4] = cosine * a12 - sine * a11;\r\n this.data[5] = cosine * a22 - sine * a21;\r\n this.data[6] = cosine * a32 - sine * a31;\r\n this.data[7] = cosine * a42 - sine * a41;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n this.data[0] = a11 * x;\r\n this.data[1] = a21 * x;\r\n this.data[2] = a31 * x;\r\n this.data[3] = a41 * x;\r\n\r\n this.data[4] = a12 * y;\r\n this.data[5] = a22 * y;\r\n this.data[6] = a32 * y;\r\n this.data[7] = a42 * y;\r\n\r\n return this;\r\n }\r\n\r\n public setRotation(angle: number) {\r\n const currentScale = this.getScale();\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * currentScale.x;\r\n this.data[1] = sine * currentScale.y;\r\n this.data[4] = -sine * currentScale.x;\r\n this.data[5] = cosine * currentScale.y;\r\n }\r\n\r\n public getRotation(): number {\r\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\r\n return canonicalizeAngle(angle);\r\n }\r\n\r\n public getScaleX(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const xscale = vec(this.data[0], this.data[4]).size;\r\n return this._scaleSignX * xscale;\r\n }\r\n\r\n public getScaleY(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const yscale = vec(this.data[1], this.data[5]).size;\r\n return this._scaleSignY * yscale;\r\n }\r\n\r\n /**\r\n * Get the scale of the matrix\r\n */\r\n public getScale(): Vector {\r\n return vec(this.getScaleX(), this.getScaleY());\r\n }\r\n\r\n private _scaleX = 1;\r\n private _scaleSignX = 1;\r\n public setScaleX(val: number) {\r\n if (this._scaleX === val) {\r\n return;\r\n }\r\n\r\n this._scaleSignX = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\r\n this.data[0] = xscale.x * val;\r\n this.data[4] = xscale.y * val;\r\n this._scaleX = val;\r\n }\r\n\r\n private _scaleY = 1;\r\n private _scaleSignY = 1;\r\n public setScaleY(val: number) {\r\n if (this._scaleY === val) {\r\n return;\r\n }\r\n this._scaleSignY = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\r\n this.data[1] = yscale.x * val;\r\n this.data[5] = yscale.y * val;\r\n this._scaleY = val;\r\n }\r\n\r\n public setScale(scale: Vector) {\r\n this.setScaleX(scale.x);\r\n this.setScaleY(scale.y);\r\n }\r\n\r\n /**\r\n * Determinant of the upper left 2x2 matrix\r\n */\r\n public getBasisDeterminant() {\r\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\r\n }\r\n\r\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */\r\n public getAffineInverse(target?: Matrix): Matrix {\r\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\r\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\r\n // Since we are actually only doing 2D transformations we can use this hack\r\n // We don't actually use the 3rd or 4th dimension\r\n\r\n const det = this.getBasisDeterminant();\r\n const inverseDet = 1 / det; // todo zero check\r\n const a = this.data[0];\r\n const b = this.data[4];\r\n const c = this.data[1];\r\n const d = this.data[5];\r\n\r\n const m = target || Matrix.identity();\r\n // inverts rotation and scale\r\n m.data[0] = d * inverseDet;\r\n m.data[1] = -c * inverseDet;\r\n m.data[4] = -b * inverseDet;\r\n m.data[5] = a * inverseDet;\r\n\r\n const tx = this.data[12];\r\n const ty = this.data[13];\r\n // invert translation\r\n // transform translation into the matrix basis created by rot/scale\r\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\r\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\r\n\r\n return m;\r\n }\r\n\r\n public isIdentity(): boolean {\r\n return (\r\n this.data[0] === 1 &&\r\n this.data[1] === 0 &&\r\n this.data[2] === 0 &&\r\n this.data[3] === 0 &&\r\n this.data[4] === 0 &&\r\n this.data[5] === 1 &&\r\n this.data[6] === 0 &&\r\n this.data[7] === 0 &&\r\n this.data[8] === 0 &&\r\n this.data[9] === 0 &&\r\n this.data[10] === 1 &&\r\n this.data[11] === 0 &&\r\n this.data[12] === 0 &&\r\n this.data[13] === 0 &&\r\n this.data[14] === 0 &&\r\n this.data[15] === 1\r\n );\r\n }\r\n\r\n public toString() {\r\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\r\n }\r\n}\r\n","import { Matrix } from './matrix';\r\nimport { canonicalizeAngle, sign } from './util';\r\nimport { vec, Vector } from './vector';\r\n\r\n\r\nexport class AffineMatrix {\r\n /**\r\n * | | | |\r\n * | ------- | ------- | -------- |\r\n * | data[0] | data[2] | data[4] |\r\n * | data[1] | data[3] | data[5] |\r\n * | 0 | 0 | 1 |\r\n */\r\n public data = new Float64Array(6);\r\n\r\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */\r\n public toDOMMatrix(): DOMMatrix {\r\n return new DOMMatrix([...this.data]);\r\n }\r\n\r\n public static identity(): AffineMatrix {\r\n const mat = new AffineMatrix();\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n\r\n mat.data[2] = 0;\r\n mat.data[3] = 1;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 0;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */\r\n public static translation(x: number, y: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[4] = x;\r\n mat.data[5] = y;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */\r\n public static scale(sx: number, sy: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[0] = sx;\r\n mat.data[3] = sy;\r\n mat._scale[0] = sx;\r\n mat._scale[1] = sy;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */\r\n public static rotation(angleRadians: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[0] = Math.cos(angleRadians);\r\n mat.data[1] = Math.sin(angleRadians);\r\n mat.data[2] = -Math.sin(angleRadians);\r\n mat.data[3] = Math.cos(angleRadians);\r\n return mat;\r\n }\r\n\r\n public setPosition(x: number, y: number) {\r\n this.data[4] = x;\r\n this.data[5] = y;\r\n }\r\n\r\n public getPosition(): Vector {\r\n return vec(this.data[4], this.data[5]);\r\n }\r\n\r\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */\r\n rotate(angle: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * a11 + sine * a12;\r\n this.data[1] = cosine * a21 + sine * a22;\r\n\r\n this.data[2] = cosine * a12 - sine * a11;\r\n this.data[3] = cosine * a22 - sine * a21;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n // const a31 = 0;\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n // const a32 = 0;\r\n\r\n const a13 = this.data[4];\r\n const a23 = this.data[5];\r\n // const a33 = 1;\r\n\r\n // Doesn't change z\r\n this.data[4] = a11 * x + a12 * y + a13;\r\n this.data[5] = a21 * x + a22 * y + a23;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n\r\n this.data[0] = a11 * x;\r\n this.data[1] = a21 * x;\r\n\r\n this.data[2] = a12 * y;\r\n this.data[3] = a22 * y;\r\n\r\n this._scale[0] = x;\r\n this._scale[1] = y;\r\n return this;\r\n }\r\n\r\n public determinant() {\r\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\r\n }\r\n\r\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */\r\n public inverse(target?: AffineMatrix): AffineMatrix {\r\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\r\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\r\n // Since we are actually only doing 2D transformations we can use this hack\r\n // We don't actually use the 3rd or 4th dimension\r\n\r\n const det = this.determinant();\r\n const inverseDet = 1 / det; // TODO zero check\r\n const a = this.data[0];\r\n const b = this.data[2];\r\n const c = this.data[1];\r\n const d = this.data[3];\r\n\r\n const m = target || AffineMatrix.identity();\r\n // inverts rotation and scale\r\n m.data[0] = d * inverseDet;\r\n m.data[1] = -c * inverseDet;\r\n m.data[2] = -b * inverseDet;\r\n m.data[3] = a * inverseDet;\r\n\r\n const tx = this.data[4];\r\n const ty = this.data[5];\r\n // invert translation\r\n // transform translation into the matrix basis created by rot/scale\r\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\r\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\r\n\r\n return m;\r\n }\r\n\r\n /**\r\n * Multiply the current matrix by a vector producing a new vector\r\n * @param vector\r\n * @param dest\r\n */\r\n multiply(vector: Vector, dest?: Vector): Vector;\r\n /**\r\n * Multiply the current matrix by another matrix producing a new matrix\r\n * @param matrix\r\n * @param dest\r\n */\r\n multiply(matrix: AffineMatrix, dest?: AffineMatrix): AffineMatrix;\r\n multiply(vectorOrMatrix: Vector | AffineMatrix, dest?: Vector | AffineMatrix): Vector | AffineMatrix {\r\n if (vectorOrMatrix instanceof Vector) {\r\n const result = (dest as Vector) || new Vector(0, 0);\r\n const vector = vectorOrMatrix;\r\n // these shenanigans are to allow dest and vector to be the same instance\r\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\r\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\r\n\r\n result.x = resultX;\r\n result.y = resultY;\r\n return result;\r\n } else {\r\n const result = (dest as AffineMatrix) || new AffineMatrix();\r\n const other = vectorOrMatrix;\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n // const a31 = 0;\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n // const a32 = 0;\r\n\r\n const a13 = this.data[4];\r\n const a23 = this.data[5];\r\n // const a33 = 1;\r\n\r\n const b11 = other.data[0];\r\n const b21 = other.data[1];\r\n // const b31 = 0;\r\n\r\n const b12 = other.data[2];\r\n const b22 = other.data[3];\r\n // const b32 = 0;\r\n\r\n const b13 = other.data[4];\r\n const b23 = other.data[5];\r\n // const b33 = 1;\r\n\r\n\r\n result.data[0] = a11 * b11 + a12 * b21;// + a13 * b31; // zero\r\n result.data[1] = a21 * b11 + a22 * b21;// + a23 * b31; // zero\r\n\r\n result.data[2] = a11 * b12 + a12 * b22;// + a13 * b32; // zero\r\n result.data[3] = a21 * b12 + a22 * b22;// + a23 * b32; // zero\r\n\r\n result.data[4] = a11 * b13 + a12 * b23 + a13;// * b33; // one\r\n result.data[5] = a21 * b13 + a22 * b23 + a23;// * b33; // one\r\n\r\n const s = this.getScale();\r\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\r\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\r\n\r\n return result;\r\n }\r\n }\r\n\r\n to4x4() {\r\n const mat = new Matrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = this.data[2];\r\n mat.data[5] = this.data[3];\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = this.data[4];\r\n mat.data[13] = this.data[5];\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n public setRotation(angle: number) {\r\n const currentScale = this.getScale();\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * currentScale.x;\r\n this.data[1] = sine * currentScale.y;\r\n this.data[2] = -sine * currentScale.x;\r\n this.data[3] = cosine * currentScale.y;\r\n }\r\n\r\n public getRotation(): number {\r\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\r\n return canonicalizeAngle(angle);\r\n }\r\n\r\n public getScaleX(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const xscale = vec(this.data[0], this.data[2]).distance();\r\n return this._scaleSignX * xscale;\r\n }\r\n\r\n public getScaleY(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const yscale = vec(this.data[1], this.data[3]).distance();\r\n return this._scaleSignY * yscale;\r\n }\r\n\r\n /**\r\n * Get the scale of the matrix\r\n */\r\n public getScale(): Vector {\r\n return vec(this.getScaleX(), this.getScaleY());\r\n }\r\n\r\n private _scale = new Float64Array([1, 1]);\r\n private _scaleSignX = 1;\r\n public setScaleX(val: number) {\r\n if (val === this._scale[0]) {\r\n return;\r\n }\r\n this._scaleSignX = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\r\n this.data[0] = xscale.x * val;\r\n this.data[2] = xscale.y * val;\r\n this._scale[0] = val;\r\n }\r\n\r\n private _scaleSignY = 1;\r\n public setScaleY(val: number) {\r\n if (val === this._scale[1]) {\r\n return;\r\n }\r\n this._scaleSignY = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\r\n this.data[1] = yscale.x * val;\r\n this.data[3] = yscale.y * val;\r\n this._scale[1] = val;\r\n }\r\n\r\n public setScale(scale: Vector) {\r\n this.setScaleX(scale.x);\r\n this.setScaleY(scale.y);\r\n }\r\n\r\n public isIdentity(): boolean {\r\n return (\r\n this.data[0] === 1 &&\r\n this.data[1] === 0 &&\r\n this.data[2] === 0 &&\r\n this.data[3] === 1 &&\r\n this.data[4] === 0 &&\r\n this.data[5] === 0\r\n );\r\n }\r\n\r\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {AffineMatrix} Current matrix as identity\r\n */\r\n public reset(): AffineMatrix {\r\n const mat = this;\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n\r\n mat.data[2] = 0;\r\n mat.data[3] = 1;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 0;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */\r\n public clone(dest?: AffineMatrix): AffineMatrix {\r\n const mat = dest || new AffineMatrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n\r\n mat.data[2] = this.data[2];\r\n mat.data[3] = this.data[3];\r\n\r\n mat.data[4] = this.data[4];\r\n mat.data[5] = this.data[5];\r\n return mat;\r\n }\r\n\r\n public toString() {\r\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\r\n }\r\n\r\n}","import { AffineMatrix } from '../../Math/affine-matrix';\r\n\r\nexport class TransformStack {\r\n private _transforms: AffineMatrix[] = [];\r\n private _currentTransform: AffineMatrix = AffineMatrix.identity();\r\n\r\n public save(): void {\r\n this._transforms.push(this._currentTransform);\r\n this._currentTransform = this._currentTransform.clone();\r\n }\r\n\r\n public restore(): void {\r\n this._currentTransform = this._transforms.pop();\r\n }\r\n\r\n public translate(x: number, y: number): AffineMatrix {\r\n return this._currentTransform.translate(x, y);\r\n }\r\n\r\n public rotate(angle: number): AffineMatrix {\r\n return this._currentTransform.rotate(angle);\r\n }\r\n\r\n public scale(x: number, y: number): AffineMatrix {\r\n return this._currentTransform.scale(x, y);\r\n }\r\n\r\n public set current(matrix: AffineMatrix) {\r\n this._currentTransform = matrix;\r\n }\r\n\r\n public get current(): AffineMatrix {\r\n return this._currentTransform;\r\n }\r\n}\r\n","import { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContextState } from './ExcaliburGraphicsContext';\r\nimport { Material } from './material';\r\n\r\nexport class StateStack {\r\n private _states: ExcaliburGraphicsContextState[] = [];\r\n private _currentState: ExcaliburGraphicsContextState = this._getDefaultState();\r\n\r\n private _getDefaultState() {\r\n return {\r\n opacity: 1,\r\n z: 0,\r\n tint: Color.White,\r\n material: null as Material\r\n };\r\n }\r\n\r\n private _cloneState() {\r\n return {\r\n opacity: this._currentState.opacity,\r\n z: this._currentState.z,\r\n tint: this._currentState.tint.clone(),\r\n material: this._currentState.material // TODO is this going to cause problems when cloning\r\n };\r\n }\r\n\r\n public save(): void {\r\n this._states.push(this._currentState);\r\n this._currentState = this._cloneState();\r\n }\r\n\r\n public restore(): void {\r\n this._currentState = this._states.pop();\r\n }\r\n\r\n public get current(): ExcaliburGraphicsContextState {\r\n return this._currentState;\r\n }\r\n\r\n public set current(val: ExcaliburGraphicsContextState) {\r\n this._currentState = val;\r\n }\r\n}\r\n","import { Loadable } from '../Interfaces/Loadable';\r\nimport { Logger } from '../Util/Log';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport type ResourceEvents = {\r\n complete: any,\r\n load: ProgressEvent,\r\n loadstart: ProgressEvent,\r\n progress: ProgressEvent,\r\n error: ProgressEvent\r\n}\r\n\r\nexport const ResourceEvents = {\r\n Complete: 'complete',\r\n Load: 'load',\r\n LoadStart: 'loadstart',\r\n Progress: 'progress',\r\n Error: 'error'\r\n};\r\n\r\n/**\r\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\r\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\r\n */\r\nexport class Resource implements Loadable {\r\n public data: T = null;\r\n public logger: Logger = Logger.getInstance();\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * @param path Path to the remote resource\r\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\r\n * @param bustCache Whether or not to cache-bust requests\r\n */\r\n constructor(\r\n public path: string,\r\n public responseType: '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text',\r\n public bustCache: boolean = false\r\n ) {}\r\n\r\n /**\r\n * Returns true if the Resource is completely loaded and is ready\r\n * to be drawn.\r\n */\r\n public isLoaded(): boolean {\r\n return this.data !== null;\r\n }\r\n\r\n\r\n private _cacheBust(uri: string): string {\r\n const query: RegExp = /\\?\\w*=\\w*/;\r\n if (query.test(uri)) {\r\n uri += '&__=' + Date.now();\r\n } else {\r\n uri += '?__=' + Date.now();\r\n }\r\n return uri;\r\n }\r\n /**\r\n * Begin loading the resource and returns a promise to be resolved on completion\r\n */\r\n public load(): Promise {\r\n return new Promise((resolve, reject) => {\r\n // Exit early if we already have data\r\n if (this.data !== null) {\r\n this.logger.debug('Already have data for resource', this.path);\r\n this.events.emit('complete', this.data as any);\r\n resolve(this.data);\r\n return;\r\n }\r\n\r\n const request = new XMLHttpRequest();\r\n request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true);\r\n request.responseType = this.responseType;\r\n request.addEventListener('loadstart', (e) => this.events.emit('loadstart', e as any));\r\n request.addEventListener('progress', (e) => this.events.emit('progress', e as any));\r\n request.addEventListener('error', (e) => this.events.emit('error', e as any));\r\n request.addEventListener('load', (e) => this.events.emit('load', e as any));\r\n request.addEventListener('load', () => {\r\n // XHR on file:// success status is 0, such as with PhantomJS\r\n if (request.status !== 0 && request.status !== 200) {\r\n this.logger.error('Failed to load resource ', this.path, ' server responded with error code', request.status);\r\n this.events.emit('error', request.response);\r\n reject(new Error(request.statusText));\r\n return;\r\n }\r\n\r\n this.data = request.response;\r\n this.events.emit('complete', this.data as any);\r\n this.logger.debug('Completed loading resource', this.path);\r\n resolve(this.data);\r\n });\r\n request.send();\r\n });\r\n }\r\n}\r\n","/**\r\n * Watch an object with a proxy, only fires if property value is different\r\n */\r\nexport function watch(type: T, change: (type: T) => any): T {\r\n if (!type) {\r\n return type;\r\n }\r\n if ((type as any).__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, {\r\n set: (obj, prop, value) => {\r\n // The default behavior to store the value\r\n if ((obj as any)[prop] !== value) {\r\n (obj as any)[prop] = value;\r\n // Avoid watching private junk\r\n if (typeof prop === 'string') {\r\n if (prop[0] !== '_') {\r\n change(obj);\r\n }\r\n }\r\n }\r\n // Indicate success\r\n return true;\r\n },\r\n get: (obj, prop) => {\r\n if (prop !== '__isProxy') {\r\n return (obj as any)[prop];\r\n }\r\n return true;\r\n }\r\n });\r\n }\r\n return type;\r\n}\r\n\r\nconst createHandler = (path: string[] = [], change: (type: T) => any, typeType: T) => ({\r\n get: (target: T, key: string): any => {\r\n if (key === '__isProxy') {\r\n return true;\r\n }\r\n if (typeof (target as any)[key] === 'object' && (target as any)[key] != null) {\r\n return new Proxy(\r\n (target as any)[key],\r\n createHandler([...path, key as string], change, typeType)\r\n );\r\n }\r\n return (target as any)[key];\r\n },\r\n set: (target: T, key: string, value: any) => {\r\n if (typeof key === 'string') {\r\n if (key[0] !== '_') {\r\n change(typeType);\r\n }\r\n }\r\n (target as any)[key] = value;\r\n return true;\r\n }\r\n});\r\n\r\n/**\r\n *\r\n */\r\nexport function watchDeep(type: T, change: (type: T) => any): T {\r\n if (!type) {\r\n return type;\r\n }\r\n if ((type as any).__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, createHandler([], change, type));\r\n }\r\n return type;\r\n}\r\n\r\n/**\r\n * Watch an object with a proxy, fires change on any property value change\r\n */\r\nexport function watchAny(type: T, change: (type: T) => any): T {\r\n if (!type) {\r\n return type;\r\n }\r\n if ((type as any).__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, {\r\n set: (obj, prop, value) => {\r\n // The default behavior to store the value\r\n (obj as any)[prop] = value;\r\n // Avoid watching private junk\r\n if (typeof prop === 'string') {\r\n if (prop[0] !== '_') {\r\n change(obj);\r\n }\r\n }\r\n\r\n // Indicate success\r\n return true;\r\n },\r\n get: (obj, prop) => {\r\n if (prop !== '__isProxy') {\r\n return (obj as any)[prop];\r\n }\r\n return true;\r\n }\r\n });\r\n }\r\n return type;\r\n}\r\n","import { Vector, vec } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { watch } from '../Util/Watch';\r\nimport { AffineMatrix } from '../Math/affine-matrix';\r\n\r\nexport interface GraphicOptions {\r\n /**\r\n * The width of the graphic\r\n */\r\n width?: number;\r\n /**\r\n * The height of the graphic\r\n */\r\n height?: number;\r\n /**\r\n * Should the graphic be flipped horizontally\r\n */\r\n flipHorizontal?: boolean;\r\n /**\r\n * Should the graphic be flipped vertically\r\n */\r\n flipVertical?: boolean;\r\n /**\r\n * The rotation of the graphic\r\n */\r\n rotation?: number;\r\n /**\r\n * The scale of the graphic\r\n */\r\n scale?: Vector;\r\n /**\r\n * The opacity of the graphic between (0 -1)\r\n */\r\n opacity?: number;\r\n /**\r\n * The tint of the graphic, this color will be multiplied by the original pixel colors\r\n */\r\n tint?: Color;\r\n /**\r\n * The origin of the drawing in pixels to use when applying transforms, by default it will be the center of the image in pixels\r\n */\r\n origin?: Vector;\r\n}\r\n\r\n/**\r\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\r\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\r\n * [[Graphic]] abstract class.\r\n *\r\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\r\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\r\n */\r\nexport abstract class Graphic {\r\n private static _ID: number = 0;\r\n readonly id = Graphic._ID++;\r\n\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public tint: Color = null;\r\n\r\n private _transformStale = true;\r\n public isStale() {\r\n return this._transformStale;\r\n }\r\n\r\n /**\r\n * Gets or sets wether to show debug information about the graphic\r\n */\r\n public showDebug: boolean = false;\r\n\r\n\r\n private _flipHorizontal = false;\r\n /**\r\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\r\n */\r\n public get flipHorizontal(): boolean {\r\n return this._flipHorizontal;\r\n }\r\n\r\n public set flipHorizontal(value: boolean) {\r\n this._flipHorizontal = value;\r\n this._transformStale = true;\r\n }\r\n\r\n private _flipVertical = false;\r\n /**\r\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\r\n */\r\n public get flipVertical(): boolean {\r\n return this._flipVertical;\r\n }\r\n\r\n public set flipVertical(value: boolean) {\r\n this._flipVertical = value;\r\n this._transformStale = true;\r\n }\r\n\r\n private _rotation = 0;\r\n /**\r\n * Gets or sets the rotation of the graphic\r\n */\r\n public get rotation(): number {\r\n return this._rotation;\r\n }\r\n\r\n public set rotation(value: number) {\r\n this._rotation = value;\r\n this._transformStale = true;\r\n }\r\n\r\n /**\r\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\r\n */\r\n public opacity: number = 1;\r\n\r\n private _scale = Vector.One;\r\n /**\r\n * Gets or sets the scale of the graphic, this affects the width and\r\n */\r\n public get scale() {\r\n return this._scale;\r\n }\r\n\r\n public set scale(value: Vector) {\r\n this._scale = watch(value, () => {\r\n this._transformStale = true;\r\n });\r\n this._transformStale = true;\r\n }\r\n\r\n private _origin: Vector | null = null;\r\n /**\r\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\r\n */\r\n public get origin(): Vector | null {\r\n return this._origin;\r\n }\r\n\r\n public set origin(value: Vector | null) {\r\n this._origin = watch(value, () => {\r\n this._transformStale = true;\r\n });\r\n this._transformStale = true;\r\n }\r\n\r\n constructor(options?: GraphicOptions) {\r\n if (options) {\r\n this.origin = options.origin ?? this.origin;\r\n this.flipHorizontal = options.flipHorizontal ?? this.flipHorizontal;\r\n this.flipVertical = options.flipVertical ?? this.flipVertical;\r\n this.rotation = options.rotation ?? this.rotation;\r\n this.opacity = options.opacity ?? this.opacity;\r\n this.scale = options.scale ?? this.scale;\r\n this.tint = options.tint ?? this.tint;\r\n }\r\n }\r\n\r\n public cloneGraphicOptions(): GraphicOptions {\r\n return {\r\n width: this.width / this.scale.x,\r\n height: this.height / this.scale.y,\r\n origin: this.origin ? this.origin.clone() : null,\r\n flipHorizontal: this.flipHorizontal,\r\n flipVertical: this.flipVertical,\r\n rotation: this.rotation,\r\n opacity: this.opacity,\r\n scale: this.scale ? this.scale.clone() : null,\r\n tint: this.tint ? this.tint.clone(): null\r\n };\r\n }\r\n\r\n private _width: number = 0;\r\n\r\n /**\r\n * Gets or sets the width of the graphic (always positive)\r\n */\r\n public get width() {\r\n return Math.abs(this._width * this.scale.x);\r\n }\r\n\r\n private _height: number = 0;\r\n\r\n /**\r\n * Gets or sets the height of the graphic (always positive)\r\n */\r\n public get height() {\r\n return Math.abs(this._height * this.scale.y);\r\n }\r\n\r\n public set width(value: number) {\r\n this._width = value;\r\n this._transformStale = true;\r\n }\r\n\r\n public set height(value: number) {\r\n this._height = value;\r\n this._transformStale = true;\r\n }\r\n\r\n /**\r\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\r\n */\r\n public get localBounds(): BoundingBox {\r\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\r\n }\r\n\r\n /**\r\n * Draw the whole graphic to the context including transform\r\n * @param ex The excalibur graphics context\r\n * @param x\r\n * @param y\r\n */\r\n public draw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0);\r\n this._postDraw(ex);\r\n }\r\n\r\n /**\r\n * Meant to be overridden by the graphic implementation to draw the underlying image (HTMLCanvasElement or HTMLImageElement)\r\n * to the graphics context without transform. Transformations like position, rotation, and scale are handled by [[Graphic._preDraw]]\r\n * and [[Graphic._postDraw]]\r\n * @param ex The excalibur graphics context\r\n * @param x\r\n * @param y\r\n */\r\n protected abstract _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number): void;\r\n\r\n /**\r\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\r\n * @param ex\r\n * @param x\r\n * @param y\r\n */\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n ex.save();\r\n ex.translate(x, y);\r\n if (this._transformStale) {\r\n this.transform.reset();\r\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\r\n this._rotate(this.transform);\r\n this._flip(this.transform);\r\n this._transformStale = false;\r\n }\r\n ex.multiply(this.transform);\r\n // it is important to multiply alphas so graphics respect the current context\r\n ex.opacity = ex.opacity * this.opacity;\r\n if (this.tint) {\r\n ex.tint = this.tint;\r\n }\r\n }\r\n\r\n protected _rotate(ex: ExcaliburGraphicsContext | AffineMatrix) {\r\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\r\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\r\n const origin = this.origin ?? vec(this.width / 2, this.height / 2);\r\n ex.translate(origin.x, origin.y);\r\n ex.rotate(this.rotation);\r\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\r\n ex.scale(scaleDirX, scaleDirY);\r\n ex.translate(-origin.x, -origin.y);\r\n }\r\n\r\n protected _flip(ex: ExcaliburGraphicsContext | AffineMatrix) {\r\n if (this.flipHorizontal) {\r\n ex.translate(this.width / this.scale.x, 0);\r\n ex.scale(-1, 1);\r\n }\r\n\r\n if (this.flipVertical) {\r\n ex.translate(0, this.height / this.scale.y);\r\n ex.scale(1, -1);\r\n }\r\n }\r\n\r\n /**\r\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\r\n * @param ex\r\n */\r\n protected _postDraw(ex: ExcaliburGraphicsContext): void {\r\n if (this.showDebug) {\r\n ex.debug.drawRect(0, 0, this.width, this.height);\r\n }\r\n ex.restore();\r\n }\r\n\r\n /**\r\n * Returns a new instance of the graphic that has the same properties\r\n */\r\n abstract clone(): Graphic;\r\n}\r\n","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ImageSource } from './ImageSource';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport type SourceView = { x: number; y: number; width: number; height: number };\r\nexport type DestinationSize = { width: number; height: number };\r\n\r\nexport interface SpriteOptions {\r\n /**\r\n * Image to create a sprite from\r\n */\r\n image: ImageSource;\r\n /**\r\n * By default the source is the entire dimension of the [[ImageSource]]\r\n */\r\n sourceView?: { x: number; y: number; width: number; height: number };\r\n /**\r\n * By default the size of the final sprite is the size of the [[ImageSource]]\r\n */\r\n destSize?: { width: number; height: number };\r\n}\r\n\r\nexport class Sprite extends Graphic {\r\n private _logger = Logger.getInstance();\r\n public image: ImageSource;\r\n public sourceView: SourceView;\r\n public destSize: DestinationSize;\r\n private _dirty = true;\r\n\r\n public static from(image: ImageSource): Sprite {\r\n return new Sprite({\r\n image: image\r\n });\r\n }\r\n\r\n constructor(options: GraphicOptions & SpriteOptions) {\r\n super(options);\r\n this.image = options.image;\r\n const { width, height } = options;\r\n this.sourceView = options.sourceView ?? { x: 0, y: 0, width: width ?? 0, height: height ?? 0 };\r\n this.destSize = options.destSize ?? { width: width ?? 0, height: height ?? 0 };\r\n this._updateSpriteDimensions();\r\n // Fire when loaded\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.image.ready.then(() => {\r\n this._updateSpriteDimensions();\r\n });\r\n }\r\n\r\n public override get width(): number {\r\n return Math.abs(this.destSize.width * this.scale.x);\r\n }\r\n\r\n public override get height(): number {\r\n return Math.abs(this.destSize.height * this.scale.y);\r\n }\r\n\r\n public override set width(newWidth: number) {\r\n newWidth /= Math.abs(this.scale.x);\r\n this.destSize.width = newWidth;\r\n super.width = Math.ceil(this.destSize.width);\r\n }\r\n\r\n public override set height(newHeight: number) {\r\n newHeight /= Math.abs(this.scale.y);\r\n this.destSize.height = newHeight;\r\n super.height = Math.ceil(this.destSize.height);\r\n }\r\n\r\n private _updateSpriteDimensions() {\r\n const { width: nativeWidth, height: nativeHeight } = this.image;\r\n // This code uses || to avoid 0's\r\n // If the source is not specified, use the native dimension\r\n this.sourceView.width = this.sourceView?.width || nativeWidth;\r\n this.sourceView.height = this.sourceView?.height || nativeHeight;\r\n\r\n // If the destination is not specified, use the source if specified, then native\r\n this.destSize.width = this.destSize?.width || this.sourceView?.width || nativeWidth;\r\n this.destSize.height = this.destSize?.height || this.sourceView?.height || nativeHeight;\r\n\r\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\r\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\r\n }\r\n\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.image.isLoaded() && this._dirty) {\r\n this._dirty = false;\r\n this._updateSpriteDimensions();\r\n }\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n public _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.image.isLoaded()) {\r\n ex.drawImage(\r\n this.image.image,\r\n this.sourceView.x,\r\n this.sourceView.y,\r\n this.sourceView.width,\r\n this.sourceView.height,\r\n x,\r\n y,\r\n this.destSize.width,\r\n this.destSize.height\r\n );\r\n } else {\r\n this._logger.warnOnce(\r\n `ImageSource ${this.image.path}` +\r\n ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` +\r\n `Read https://excaliburjs.com/docs/imagesource for more information.`\r\n );\r\n }\r\n }\r\n\r\n public clone(): Sprite {\r\n return new Sprite({\r\n image: this.image,\r\n sourceView: { ...this.sourceView },\r\n destSize: { ...this.destSize },\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n}\r\n","\r\n/**\r\n * Describes the different image filtering modes\r\n */\r\nexport enum ImageFiltering {\r\n\r\n /**\r\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\r\n *\r\n * Useful for Pixel art aesthetics.\r\n */\r\n Pixel = 'Pixel',\r\n\r\n /**\r\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\r\n */\r\n Blended = 'Blended'\r\n}","import { Logger } from '../../Util/Log';\r\nimport { ImageFiltering } from '../Filtering';\r\nimport { HTMLImageSource } from './ExcaliburGraphicsContext';\r\n\r\n/**\r\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\r\n */\r\nexport class TextureLoader {\r\n private static _LOGGER = Logger.getInstance();\r\n\r\n constructor(gl: WebGL2RenderingContext) {\r\n this._gl = gl;\r\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\r\n }\r\n\r\n public dispose() {\r\n for (const [image] of this._textureMap) {\r\n this.delete(image);\r\n }\r\n this._textureMap.clear();\r\n this._gl = null;\r\n }\r\n\r\n /**\r\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\r\n */\r\n public static filtering: ImageFiltering = ImageFiltering.Blended;\r\n\r\n private _gl: WebGL2RenderingContext;\r\n\r\n private _textureMap = new Map();\r\n\r\n private static _MAX_TEXTURE_SIZE: number = 4096;\r\n\r\n /**\r\n * Get the WebGL Texture from a source image\r\n * @param image\r\n */\r\n public get(image: HTMLImageSource): WebGLTexture {\r\n return this._textureMap.get(image);\r\n }\r\n\r\n /**\r\n * Returns whether a source image has been loaded as a texture\r\n * @param image\r\n */\r\n public has(image: HTMLImageSource): boolean {\r\n return this._textureMap.has(image);\r\n }\r\n\r\n /**\r\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\r\n * @param image Source graphic\r\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\r\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\r\n */\r\n public load(image: HTMLImageSource, filtering?: ImageFiltering, forceUpdate = false): WebGLTexture {\r\n // Ignore loading if webgl is not registered\r\n const gl = this._gl;\r\n if (!gl) {\r\n return null;\r\n }\r\n\r\n let tex: WebGLTexture = null;\r\n // If reuse the texture if it's from the same source\r\n if (this.has(image)) {\r\n tex = this.get(image);\r\n }\r\n\r\n // Update existing webgl texture and return early\r\n if (tex) {\r\n if (forceUpdate) {\r\n gl.bindTexture(gl.TEXTURE_2D, tex);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\r\n }\r\n return tex;\r\n }\r\n\r\n // No texture exists create a new one\r\n tex = gl.createTexture();\r\n\r\n // TODO implement texture gc with weakmap and timer\r\n TextureLoader.checkImageSizeSupportedAndLog(image);\r\n\r\n gl.bindTexture(gl.TEXTURE_2D, tex);\r\n\r\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\r\n // TODO make configurable\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n // NEAREST for pixel art, LINEAR for hi-res\r\n const filterMode = filtering ?? TextureLoader.filtering;\r\n\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\r\n\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\r\n\r\n this._textureMap.set(image, tex);\r\n return tex;\r\n }\r\n\r\n public delete(image: HTMLImageSource): void {\r\n // Ignore loading if webgl is not registered\r\n const gl = this._gl;\r\n if (!gl) {\r\n return null;\r\n }\r\n\r\n let tex: WebGLTexture = null;\r\n if (this.has(image)) {\r\n tex = this.get(image);\r\n gl.deleteTexture(tex);\r\n }\r\n }\r\n\r\n /**\r\n * Takes an image and returns if it meets size criteria for hardware\r\n * @param image\r\n * @returns if the image will be supported at runtime\r\n */\r\n public static checkImageSizeSupportedAndLog(image: HTMLImageSource) {\r\n const originalSrc = image.dataset.originalSrc ?? 'internal canvas bitmap';\r\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\r\n TextureLoader._LOGGER.error(\r\n `The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of `+\r\n `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image `\r\n +`for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n`+\r\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\r\n return false;\r\n } else if (image.width > 4096 || image.height > 4096) {\r\n // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\r\n TextureLoader._LOGGER.warn(\r\n `The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, `+\r\n `it is recommended you resize images to a maximum (4096x4096).\\n\\n` +\r\n `Images will likely render as black rectangles on some mobile platforms.\\n\\n` +\r\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\r\n }\r\n return true;\r\n }\r\n}\r\n","import { Resource } from '../Resources/Resource';\r\nimport { Sprite } from './Sprite';\r\nimport { Loadable } from '../Interfaces/Index';\r\nimport { Logger } from '../Util/Log';\r\nimport { ImageFiltering } from './Filtering';\r\nimport { Future } from '../Util/Future';\r\nimport { TextureLoader } from '../Graphics/Context/texture-loader';\r\n\r\nexport interface ImageSourceOptions {\r\n filtering?: ImageFiltering;\r\n bustCache?: boolean;\r\n}\r\n\r\nexport class ImageSource implements Loadable {\r\n private _logger = Logger.getInstance();\r\n private _resource: Resource;\r\n public filtering: ImageFiltering;\r\n\r\n /**\r\n * The original size of the source image in pixels\r\n */\r\n public get width() {\r\n return this.image.naturalWidth;\r\n }\r\n\r\n /**\r\n * The original height of the source image in pixels\r\n */\r\n public get height() {\r\n return this.image.naturalHeight;\r\n }\r\n\r\n private _src: string;\r\n /**\r\n * Returns true if the Texture is completely loaded and is ready\r\n * to be drawn.\r\n */\r\n public isLoaded(): boolean {\r\n if (!this._src) {\r\n // this boosts speed of access\r\n this._src = this.data.src;\r\n }\r\n return !!this._src;\r\n }\r\n\r\n /**\r\n * Access to the underlying html image element\r\n */\r\n public data: HTMLImageElement = new Image();\r\n public get image(): HTMLImageElement {\r\n return this.data;\r\n }\r\n\r\n private _readyFuture = new Future();\r\n /**\r\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\r\n */\r\n public ready: Promise = this._readyFuture.promise;\r\n\r\n /**\r\n * The path to the image, can also be a data url like 'data:image/'\r\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\r\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\r\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\r\n */\r\n constructor(public readonly path: string, bustCache: boolean = false, filtering?: ImageFiltering) {\r\n this._resource = new Resource(path, 'blob', bustCache);\r\n this.filtering = filtering;\r\n if (path.endsWith('.svg') || path.endsWith('.gif')) {\r\n this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\r\n }\r\n }\r\n\r\n /**\r\n * Create an ImageSource from and HTML tag element\r\n * @param image\r\n */\r\n static fromHtmlImageElement(image: HTMLImageElement, options?: ImageSourceOptions) {\r\n const imageSource = new ImageSource('');\r\n imageSource._src = 'image-element';\r\n imageSource.data = image;\r\n imageSource.data.setAttribute('data-original-src', 'image-element');\r\n\r\n if (options?.filtering) {\r\n imageSource.data.setAttribute('filtering', options?.filtering);\r\n } else {\r\n imageSource.data.setAttribute('filtering', ImageFiltering.Blended);\r\n }\r\n\r\n TextureLoader.checkImageSizeSupportedAndLog(image);\r\n imageSource._readyFuture.resolve(image);\r\n return imageSource;\r\n }\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n /**\r\n * Begins loading the image and returns a promise that resolves when the image is loaded\r\n */\r\n async load(): Promise {\r\n if (this.isLoaded()) {\r\n return this.data;\r\n }\r\n try {\r\n // Load base64 or blob if needed\r\n let url: string;\r\n if (!this.path.includes('data:image/')) {\r\n const blob = await this._resource.load();\r\n url = URL.createObjectURL(blob);\r\n } else {\r\n url = this.path;\r\n }\r\n\r\n // Decode the image\r\n const image = new Image();\r\n // Use Image.onload over Image.decode()\r\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\r\n // Otherwise chrome will throw still Image.decode() failures for large textures\r\n const loadedFuture = new Future();\r\n image.onload = () => loadedFuture.resolve();\r\n image.src = url;\r\n image.setAttribute('data-original-src', this.path);\r\n\r\n await loadedFuture.promise;\r\n\r\n // Set results\r\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\r\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\r\n // See image-renderer.ts draw()\r\n this.data = image;\r\n\r\n // emit warning if potentially too big\r\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\r\n } catch (error) {\r\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\r\n }\r\n // Do a bad thing to pass the filtering as an attribute\r\n this.data.setAttribute('filtering', this.filtering);\r\n\r\n // todo emit complete\r\n this._readyFuture.resolve(this.data);\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Build a sprite from this ImageSource\r\n */\r\n public toSprite(): Sprite {\r\n return Sprite.from(this);\r\n }\r\n\r\n /**\r\n * Unload images from memory\r\n */\r\n unload(): void {\r\n this.data = new Image();\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Logger } from '../Util/Log';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { FontRenderer } from './FontCommon';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Sprite } from './Sprite';\r\nimport { SpriteSheet } from './SpriteSheet';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\n\r\nexport interface SpriteFontOptions {\r\n /**\r\n * Alphabet string in spritesheet order (default is row column order)\r\n * example: 'abcdefghijklmnopqrstuvwxyz'\r\n */\r\n alphabet: string;\r\n /**\r\n * [[SpriteSheet]] to source character sprites from\r\n */\r\n spriteSheet: SpriteSheet;\r\n /**\r\n * Optionally ignore case in the supplied text;\r\n */\r\n caseInsensitive?: boolean;\r\n /**\r\n * Optionally override the text line height, useful for multiline text. If unset will use default.\r\n */\r\n lineHeight?: number | undefined;\r\n /**\r\n * Optionally adjust the spacing between character sprites\r\n */\r\n spacing?: number;\r\n /**\r\n * Optionally specify a \"shadow\"\r\n */\r\n shadow?: { offset: Vector };\r\n}\r\n\r\nexport class SpriteFont extends Graphic implements FontRenderer {\r\n private _text: string = '';\r\n public alphabet: string = '';\r\n public spriteSheet: SpriteSheet;\r\n\r\n public shadow: { offset: Vector } = null;\r\n public caseInsensitive = false;\r\n public spacing: number = 0;\r\n public lineHeight: number | undefined = undefined;\r\n\r\n private _logger = Logger.getInstance();\r\n\r\n constructor(options: SpriteFontOptions & GraphicOptions) {\r\n super(options);\r\n const { alphabet, spriteSheet, caseInsensitive, spacing, shadow, lineHeight } = options;\r\n this.alphabet = alphabet;\r\n this.spriteSheet = spriteSheet;\r\n this.caseInsensitive = caseInsensitive ?? this.caseInsensitive;\r\n this.spacing = spacing ?? this.spacing;\r\n this.shadow = shadow ?? this.shadow;\r\n this.lineHeight = lineHeight ?? this.lineHeight;\r\n }\r\n\r\n private _getCharacterSprites(text: string): Sprite[] {\r\n const results: Sprite[] = [];\r\n // handle case insensitive\r\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\r\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\r\n\r\n // for each letter in text\r\n for (let letterIndex = 0; letterIndex < textToRender.length; letterIndex++) {\r\n // find the sprite index in alphabet , if there is an error pick the first\r\n const letter = textToRender[letterIndex];\r\n let spriteIndex = alphabet.indexOf(letter);\r\n if (spriteIndex === -1) {\r\n spriteIndex = 0;\r\n this._logger.warnOnce(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\r\n this._logger.warnOnce('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\r\n }\r\n\r\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\r\n if (letterSprite) {\r\n results.push(letterSprite);\r\n } else {\r\n this._logger.warnOnce(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\r\n this._logger.warnOnce('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n public measureText(text: string, maxWidth?: number): BoundingBox {\r\n const lines = this._getLinesFromText(text, maxWidth);\r\n const maxWidthLine = lines.reduce((a, b) => {\r\n return a.length > b.length ? a : b;\r\n });\r\n const sprites = this._getCharacterSprites(maxWidthLine);\r\n let width = 0;\r\n let height = 0;\r\n for (const sprite of sprites) {\r\n width += sprite.width + this.spacing;\r\n height = Math.max(height, sprite.height);\r\n }\r\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number, maxWidth?: number): void {\r\n let xCursor = 0;\r\n let yCursor = 0;\r\n let height = 0;\r\n const lines = this._getLinesFromText(this._text, maxWidth);\r\n for (const line of lines) {\r\n for (const sprite of this._getCharacterSprites(line)) {\r\n // draw it in the right spot and increase the cursor by sprite width\r\n sprite.draw(ex, x + xCursor, y + yCursor);\r\n xCursor += sprite.width + this.spacing;\r\n height = Math.max(height, sprite.height);\r\n }\r\n xCursor = 0;\r\n yCursor += this.lineHeight ?? height;\r\n }\r\n }\r\n\r\n render(ex: ExcaliburGraphicsContext, text: string, _color: Color, x: number, y: number, maxWidth?: number) {\r\n // SpriteFont doesn't support _color, yet...\r\n this._text = text;\r\n const bounds = this.measureText(text, maxWidth);\r\n this.width = bounds.width;\r\n this.height = bounds.height;\r\n if (this.shadow) {\r\n ex.save();\r\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0, maxWidth);\r\n this._postDraw(ex);\r\n ex.restore();\r\n }\r\n\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0, maxWidth);\r\n this._postDraw(ex);\r\n }\r\n\r\n clone(): SpriteFont {\r\n return new SpriteFont({\r\n alphabet: this.alphabet,\r\n spriteSheet: this.spriteSheet,\r\n spacing: this.spacing\r\n });\r\n }\r\n\r\n /**\r\n * Return array of lines split based on the \\n character, and the maxWidth? constraint\r\n * @param text\r\n * @param maxWidth\r\n */\r\n private _cachedText: string;\r\n private _cachedLines: string[];\r\n private _cachedRenderWidth: number;\r\n private _getLinesFromText(text: string, maxWidth?: number) {\r\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\r\n return this._cachedLines;\r\n }\r\n\r\n const lines = text.split('\\n');\r\n\r\n if (maxWidth == null) {\r\n return lines;\r\n }\r\n\r\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\r\n for (let i = 0; i < lines.length; i++) {\r\n let line = lines[i];\r\n let newLine = '';\r\n // Note: we subtract the spacing to counter the initial padding on the left side.\r\n if (this.measureText(line).width > maxWidth) {\r\n while (this.measureText(line).width > maxWidth) {\r\n newLine = line[line.length - 1] + newLine;\r\n line = line.slice(0, -1); // Remove last character from line\r\n }\r\n\r\n // Update the array with our new values\r\n lines[i] = line;\r\n lines[i + 1] = newLine;\r\n }\r\n }\r\n\r\n this._cachedText = text;\r\n this._cachedLines = lines;\r\n this._cachedRenderWidth = maxWidth;\r\n\r\n return lines;\r\n }\r\n}\r\n","import { ImageSource } from './ImageSource';\r\nimport { SourceView, Sprite } from './Sprite';\r\nimport { GraphicOptions } from './Graphic';\r\n\r\n/**\r\n * Specify sprite sheet spacing options, useful if your sprites are not tightly packed\r\n * and have space between them.\r\n */\r\nexport interface SpriteSheetSpacingDimensions {\r\n /**\r\n * The starting point to offset and start slicing the sprite sheet from the top left of the image.\r\n * Default is (0, 0)\r\n */\r\n originOffset?: { x?: number, y?: number };\r\n\r\n /**\r\n * The margin between sprites.\r\n * Default is (0, 0)\r\n */\r\n margin?: {x?: number, y?: number};\r\n}\r\n\r\n/**\r\n * Sprite sheet options for slicing up images\r\n */\r\nexport interface SpriteSheetGridOptions {\r\n /**\r\n * Source image to use for each sprite\r\n */\r\n image: ImageSource;\r\n /**\r\n * Grid definition for the sprite sheet\r\n */\r\n grid: {\r\n /**\r\n * Number of rows in the sprite sheet\r\n */\r\n rows: number;\r\n /**\r\n * Number of columns in the sprite sheet\r\n */\r\n columns: number;\r\n /**\r\n * Width of each individual sprite\r\n */\r\n spriteWidth: number;\r\n /**\r\n * Height of each individual sprite\r\n */\r\n spriteHeight: number;\r\n };\r\n /**\r\n * Optionally specify any spacing information between sprites\r\n */\r\n spacing?: SpriteSheetSpacingDimensions;\r\n}\r\n\r\nexport interface SpriteSheetSparseOptions {\r\n /**\r\n * Source image to use for each sprite\r\n */\r\n image: ImageSource;\r\n /**\r\n * List of source view rectangles to create a sprite sheet from\r\n */\r\n sourceViews: SourceView[];\r\n}\r\n\r\nexport interface SpriteSheetOptions {\r\n /**\r\n * Source sprites for the sprite sheet\r\n */\r\n sprites: Sprite[];\r\n /**\r\n * Optionally specify the number of rows in a sprite sheet (default 1 row)\r\n */\r\n rows?: number;\r\n /**\r\n * Optionally specify the number of columns in a sprite sheet (default sprites.length)\r\n */\r\n columns?: number;\r\n}\r\n\r\nexport interface GetSpriteOptions extends GraphicOptions {}\r\n\r\n/**\r\n * Represents a collection of sprites from a source image with some organization in a grid\r\n */\r\nexport class SpriteSheet {\r\n public readonly sprites: Sprite[] = [];\r\n public readonly rows: number;\r\n public readonly columns: number;\r\n\r\n /**\r\n * Build a new sprite sheet from a list of sprites\r\n *\r\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n * @param options\r\n */\r\n constructor(options: SpriteSheetOptions) {\r\n const { sprites, rows, columns } = options;\r\n this.sprites = sprites;\r\n this.rows = rows ?? 1;\r\n this.columns = columns ?? this.sprites.length;\r\n }\r\n\r\n /**\r\n * Find a sprite by their x/y integer coordinates in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\r\n * and `getSprite(1, 0)` is the sprite one to the right.\r\n * @param x\r\n * @param y\r\n */\r\n public getSprite(x: number, y: number, options?: GetSpriteOptions): Sprite {\r\n if (x >= this.columns || x < 0) {\r\n throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\r\n }\r\n if (y >= this.rows || y < 0) {\r\n throw Error(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\r\n }\r\n const spriteIndex = x + y * this.columns;\r\n const sprite = this.sprites[spriteIndex];\r\n if (sprite) {\r\n if (options) {\r\n const spriteWithOptions = sprite.clone();\r\n spriteWithOptions.flipHorizontal = options.flipHorizontal ?? spriteWithOptions.flipHorizontal;\r\n spriteWithOptions.flipVertical = options.flipVertical ?? spriteWithOptions.flipVertical;\r\n spriteWithOptions.width = options.width ?? spriteWithOptions.width;\r\n spriteWithOptions.height = options.height ?? spriteWithOptions.height;\r\n spriteWithOptions.rotation = options.rotation ?? spriteWithOptions.rotation;\r\n spriteWithOptions.scale = options.scale ?? spriteWithOptions.scale;\r\n spriteWithOptions.opacity = options.opacity ?? spriteWithOptions.opacity;\r\n spriteWithOptions.tint = options.tint ?? spriteWithOptions.tint;\r\n spriteWithOptions.origin = options.origin ?? spriteWithOptions.origin;\r\n return spriteWithOptions;\r\n }\r\n return sprite;\r\n }\r\n throw Error(`Invalid sprite coordinates (${x}, ${y}`);\r\n }\r\n\r\n /**\r\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\r\n * @param options\r\n */\r\n public static fromImageSourceWithSourceViews(options: SpriteSheetSparseOptions): SpriteSheet {\r\n const sprites: Sprite[] = options.sourceViews.map(sourceView => {\r\n return new Sprite({\r\n image: options.image,\r\n sourceView\r\n });\r\n });\r\n return new SpriteSheet({sprites});\r\n }\r\n\r\n /**\r\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n *\r\n * Example:\r\n * ```\r\n * const spriteSheet = SpriteSheet.fromImageSource({\r\n * image: imageSource,\r\n * grid: {\r\n * rows: 5,\r\n * columns: 2,\r\n * spriteWidth: 32, // pixels\r\n * spriteHeight: 32 // pixels\r\n * },\r\n * // Optionally specify spacing\r\n * spacing: {\r\n * // pixels from the top left to start the sprite parsing\r\n * originOffset: {\r\n * x: 5,\r\n * y: 5\r\n * },\r\n * // pixels between each sprite while parsing\r\n * margin: {\r\n * x: 1,\r\n * y: 1\r\n * }\r\n * }\r\n * })\r\n * ```\r\n * @param options\r\n */\r\n public static fromImageSource(options: SpriteSheetGridOptions): SpriteSheet {\r\n const sprites: Sprite[] = [];\r\n options.spacing = options.spacing ?? {};\r\n const {\r\n image,\r\n grid: { rows, columns: cols, spriteWidth, spriteHeight },\r\n spacing: { originOffset, margin }\r\n } = options;\r\n const offsetDefaults = { x: 0, y: 0, ...originOffset};\r\n const marginDefaults = { x: 0, y: 0, ...margin};\r\n for (let x = 0; x < cols; x++) {\r\n for (let y = 0; y < rows; y++) {\r\n sprites[x + y * cols] = new Sprite({\r\n image: image,\r\n sourceView: {\r\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\r\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\r\n width: spriteWidth,\r\n height: spriteHeight\r\n },\r\n destSize: { height: spriteHeight, width: spriteWidth }\r\n });\r\n }\r\n }\r\n return new SpriteSheet({\r\n sprites: sprites,\r\n rows: rows,\r\n columns: cols\r\n });\r\n }\r\n\r\n public clone(): SpriteSheet {\r\n return new SpriteSheet({\r\n sprites: this.sprites.map(sprite => sprite.clone()),\r\n rows: this.rows,\r\n columns: this.columns\r\n });\r\n }\r\n}\r\n","export default \"data:image/png;base64,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\"","import { ExcaliburGraphicsContext } from '../Context/ExcaliburGraphicsContext';\r\nimport { ImageSource } from '../ImageSource';\r\nimport { SpriteFont } from '../SpriteFont';\r\nimport { SpriteSheet } from '../SpriteSheet';\r\nimport { Vector } from '../../Math/vector';\r\nimport debugFont from './debug-font.png';\r\n\r\n/**\r\n * Internal debugtext helper\r\n */\r\nexport class DebugText {\r\n constructor() {\r\n // We fire and forget, we don't care if it's loaded or not\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.load();\r\n }\r\n\r\n /**\r\n * base64 font\r\n */\r\n public readonly fontSheet = debugFont;\r\n public size: number = 16;\r\n private _imageSource: ImageSource;\r\n private _spriteSheet: SpriteSheet;\r\n private _spriteFont: SpriteFont;\r\n public load() {\r\n this._imageSource = new ImageSource(this.fontSheet);\r\n return this._imageSource.load().then(() => {\r\n this._spriteSheet = SpriteSheet.fromImageSource({\r\n image: this._imageSource,\r\n grid: {\r\n rows: 4,\r\n columns: 16,\r\n spriteWidth: 16,\r\n spriteHeight: 16\r\n }\r\n });\r\n this._spriteFont = new SpriteFont({\r\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!\\'&.\"?-()+# ',\r\n caseInsensitive: true,\r\n spriteSheet: this._spriteSheet,\r\n spacing: -6\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Writes debug text using the built in sprint font\r\n * @param ctx\r\n * @param text\r\n * @param pos\r\n */\r\n public write(ctx: ExcaliburGraphicsContext, text: string, pos: Vector) {\r\n if (this._imageSource.isLoaded()) {\r\n this._spriteFont.render(ctx, text, null, pos.x, pos.y);\r\n }\r\n }\r\n}\r\n","export class RenderSource {\r\n constructor(\r\n private _gl: WebGLRenderingContext,\r\n private _texture: WebGLTexture) {}\r\n\r\n public use() {\r\n const gl = this._gl;\r\n gl.activeTexture(gl.TEXTURE0);\r\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\r\n }\r\n\r\n public disable() {\r\n const gl = this._gl;\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n }\r\n}","import { RenderSource } from './render-source';\r\n\r\ndeclare global {\r\n interface WebGL2RenderingContext {\r\n /**\r\n * Experimental only in chrome\r\n */\r\n drawingBufferFormat?: number;\r\n }\r\n}\r\n\r\n\r\nexport interface RenderTargetOptions {\r\n gl: WebGL2RenderingContext;\r\n width: number;\r\n height: number;\r\n transparency: boolean;\r\n /**\r\n * Optionally enable render buffer multisample anti-aliasing\r\n *\r\n * By default false\r\n */\r\n antialias?: boolean;\r\n /**\r\n * Optionally specify number of anti-aliasing samples to use\r\n *\r\n * By default the max for the platform is used if antialias is on.\r\n */\r\n samples?: number;\r\n}\r\n\r\nexport class RenderTarget {\r\n width: number;\r\n height: number;\r\n transparency: boolean;\r\n antialias: boolean = false;\r\n samples: number = 1;\r\n private _gl: WebGL2RenderingContext;\r\n public readonly bufferFormat: number;\r\n constructor(options: RenderTargetOptions) {\r\n this._gl = options.gl;\r\n this.width = options.width;\r\n this.height = options.height;\r\n this.transparency = options.transparency;\r\n this.antialias = options.antialias ?? this.antialias;\r\n this.samples = options.samples ?? this._gl.getParameter(this._gl.MAX_SAMPLES);\r\n\r\n const gl = this._gl;\r\n // Determine current context format for blitting later needs to match\r\n if (gl.drawingBufferFormat) {\r\n this.bufferFormat = gl.drawingBufferFormat;\r\n } else {\r\n // Documented in webgl spec\r\n // https://registry.khronos.org/webgl/specs/latest/1.0/\r\n if (this.transparency) {\r\n this.bufferFormat = gl.RGBA8;\r\n } else {\r\n this.bufferFormat = gl.RGB8;\r\n }\r\n }\r\n\r\n this._setupRenderBuffer();\r\n this._setupFramebuffer();\r\n }\r\n\r\n setResolution(width: number, height: number) {\r\n const gl = this._gl;\r\n this.width = width;\r\n this.height = height;\r\n\r\n // update backing texture size\r\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n\r\n // update render buffer size\r\n if (this._renderBuffer) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\r\n gl.renderbufferStorageMultisample(\r\n gl.RENDERBUFFER,\r\n Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)),\r\n this.bufferFormat,\r\n this.width,\r\n this.height);\r\n }\r\n }\r\n\r\n private _renderBuffer: WebGLRenderbuffer;\r\n public get renderBuffer() {\r\n return this._renderBuffer;\r\n }\r\n private _renderFrameBuffer: WebGLFramebuffer;\r\n public get renderFrameBuffer() {\r\n return this._renderFrameBuffer;\r\n }\r\n\r\n private _frameBuffer: WebGLFramebuffer;\r\n public get frameBuffer() {\r\n return this._frameBuffer;\r\n }\r\n private _frameTexture: WebGLTexture;\r\n public get frameTexture() {\r\n return this._frameTexture;\r\n }\r\n\r\n private _setupRenderBuffer() {\r\n if (this.antialias) {\r\n const gl = this._gl;\r\n // Render buffers can be used as an input to a shader\r\n this._renderBuffer = gl.createRenderbuffer();\r\n this._renderFrameBuffer = gl.createFramebuffer();\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer);\r\n gl.renderbufferStorageMultisample(\r\n gl.RENDERBUFFER,\r\n Math.min(this.samples, gl.getParameter(gl.MAX_SAMPLES)),\r\n this.bufferFormat,\r\n this.width,\r\n this.height);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\r\n gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._renderBuffer);\r\n }\r\n }\r\n\r\n private _setupFramebuffer() {\r\n // Allocates frame buffer\r\n const gl = this._gl;\r\n this._frameTexture = gl.createTexture();\r\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n\r\n // set the filtering so we don't need mips\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n\r\n // attach the texture as the first color attachment\r\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\r\n\r\n // After this bind all draw calls will draw to this framebuffer texture\r\n this._frameBuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\r\n\r\n // Reset after initialized\r\n this.disable();\r\n }\r\n\r\n public toRenderSource() {\r\n if (this.renderBuffer) {\r\n this.blitRenderBufferToFrameBuffer();\r\n }\r\n const source = new RenderSource(this._gl, this._frameTexture);\r\n return source;\r\n }\r\n\r\n public blitToScreen() {\r\n const gl = this._gl;\r\n // set to size of canvas's drawingBuffer\r\n if (this._renderBuffer) {\r\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\r\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\r\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\r\n gl.blitFramebuffer(\r\n 0, 0, this.width, this.height,\r\n 0, 0, this.width, this.height,\r\n gl.COLOR_BUFFER_BIT, gl.LINEAR);\r\n } else {\r\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.frameBuffer);\r\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\r\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\r\n gl.blitFramebuffer(\r\n 0, 0, this.width, this.height,\r\n 0, 0, this.width, this.height,\r\n gl.COLOR_BUFFER_BIT, gl.LINEAR);\r\n }\r\n }\r\n\r\n public blitRenderBufferToFrameBuffer() {\r\n if (this._renderBuffer) {\r\n const gl = this._gl;\r\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.renderFrameBuffer);\r\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.frameBuffer);\r\n gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 1.0, 1.0]);\r\n gl.blitFramebuffer(\r\n 0, 0, this.width, this.height,\r\n 0, 0, this.width, this.height,\r\n gl.COLOR_BUFFER_BIT, gl.LINEAR);\r\n }\r\n }\r\n\r\n public copyToTexture(texture: WebGLTexture) {\r\n const gl = this._gl;\r\n if (this._renderBuffer) {\r\n this.blitRenderBufferToFrameBuffer();\r\n }\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, this.width, this.height, 0);\r\n }\r\n\r\n /**\r\n * When called, all drawing gets redirected to this render target\r\n */\r\n public use() {\r\n const gl = this._gl;\r\n if (this.antialias) {\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._renderFrameBuffer);\r\n } else {\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n }\r\n\r\n // very important to set the viewport to the size of the framebuffer texture\r\n gl.viewport(0, 0, this.width, this.height);\r\n }\r\n\r\n /**\r\n * When called, all drawing is sent back to the canvas\r\n */\r\n public disable() {\r\n const gl = this._gl;\r\n // passing null switches rendering back to the canvas\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n }\r\n}","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\";","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\";","/**\r\n * Return the size of the GlType in bytes\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getGlTypeSizeBytes(gl: WebGLRenderingContext, type: number): number {\r\n switch (type) {\r\n case gl.FLOAT:\r\n return 4;\r\n case gl.SHORT:\r\n return 2;\r\n case gl.UNSIGNED_SHORT:\r\n return 2;\r\n case gl.BYTE:\r\n return 1;\r\n case gl.UNSIGNED_BYTE:\r\n return 1;\r\n default:\r\n return 1;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Based on the type return the number of attribute components\r\n *\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getAttributeComponentSize(gl: WebGLRenderingContext, type: number): number {\r\n switch (type) {\r\n case gl.LOW_FLOAT:\r\n case gl.HIGH_FLOAT:\r\n case gl.FLOAT:\r\n return 1;\r\n case gl.FLOAT_VEC2:\r\n return 2;\r\n case gl.FLOAT_VEC3:\r\n return 3;\r\n case gl.FLOAT_VEC4:\r\n return 4;\r\n case gl.BYTE:\r\n return 1;\r\n case gl.UNSIGNED_BYTE:\r\n return 1;\r\n case gl.UNSIGNED_SHORT:\r\n case gl.SHORT:\r\n return 1;\r\n default:\r\n return 1;\r\n }\r\n}\r\n\r\n/**\r\n * Based on the attribute return the corresponding supported attrib pointer type\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getAttributePointerType(gl: WebGLRenderingContext, type: number) {\r\n switch (type) {\r\n case gl.LOW_FLOAT:\r\n case gl.HIGH_FLOAT:\r\n case gl.FLOAT:\r\n case gl.FLOAT_VEC2:\r\n case gl.FLOAT_VEC3:\r\n case gl.FLOAT_VEC4:\r\n return gl.FLOAT;\r\n case gl.BYTE:\r\n return gl.BYTE;\r\n case gl.UNSIGNED_BYTE:\r\n return gl.UNSIGNED_BYTE;\r\n case gl.SHORT:\r\n return gl.SHORT;\r\n case gl.UNSIGNED_SHORT:\r\n return gl.UNSIGNED_SHORT;\r\n default:\r\n return gl.FLOAT;\r\n }\r\n}","import { Color, Logger, Vector } from '../..';\r\nimport { Matrix } from '../../Math/matrix';\r\nimport { getAttributeComponentSize, getAttributePointerType } from './webgl-util';\r\n\r\n/**\r\n * List of the possible glsl uniform types\r\n */\r\nexport type UniformTypeNames =\r\n 'uniform1f' |\r\n 'uniform1i' |\r\n 'uniform2f' |\r\n 'uniform2i' |\r\n 'uniform3f' |\r\n 'uniform3i' |\r\n 'uniform4f' |\r\n 'uniform4i' |\r\n 'uniform1fv' |\r\n 'uniform1iv' |\r\n 'uniform2fv' |\r\n 'uniform2iv' |\r\n 'uniform3fv' |\r\n 'uniform3iv' |\r\n 'uniform4fv' |\r\n 'uniform4iv' |\r\n 'uniformMatrix2fv' |\r\n 'uniformMatrix3fv' |\r\n 'uniformMatrix4fv';\r\n\r\ntype RemoveFirstFromTuple =\r\n T['length'] extends 0 ? undefined :\r\n (((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : [])\r\n\r\ntype UniformParameters = RemoveFirstFromTuple>\r\n\r\nexport interface UniformDefinition {\r\n name: string;\r\n glType: number;\r\n location: WebGLUniformLocation;\r\n}\r\n\r\n\r\nexport interface VertexAttributeDefinition {\r\n /**\r\n * string name of the attribute in the shader program, commonly `a_nameofmyvariable`\r\n */\r\n name: string;\r\n /**\r\n * Number of components for a given attribute\r\n * Must be 1, 2, 3, or 4\r\n *\r\n * For example a vec4 attribute would be `4` floats, so 4\r\n */\r\n size: number;\r\n /**\r\n * Supported types in webgl 1\r\n * * gl.BYTE\r\n * * gl.SHORT\r\n * * gl.UNSIGNED_BYTE\r\n * * gl.UNSIGNED_SHORT\r\n * * gl.FLOAT\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n */\r\n glType: number;\r\n /**\r\n * Is the attribute normalized between (0-1)\r\n */\r\n normalized: boolean;\r\n /**\r\n * Location index in the shader program\r\n */\r\n location: number;\r\n}\r\n\r\nexport interface ShaderOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across webgl contexts.\r\n */\r\n gl: WebGL2RenderingContext;\r\n /**\r\n * Vertex shader source code in glsl #version 300 es\r\n */\r\n vertexSource: string;\r\n /**\r\n * Fragment shader source code in glsl #version 300 es\r\n */\r\n fragmentSource: string;\r\n}\r\n\r\nexport class Shader {\r\n private static _ACTIVE_SHADER_INSTANCE: Shader = null;\r\n private _logger = Logger.getInstance();\r\n private _gl: WebGL2RenderingContext;\r\n public program: WebGLProgram;\r\n public uniforms: { [variableName: string]: UniformDefinition } = {};\r\n public attributes: { [variableName: string]: VertexAttributeDefinition } = {};\r\n private _compiled = false;\r\n public readonly vertexSource: string;\r\n public readonly fragmentSource: string;\r\n\r\n public get compiled() {\r\n return this._compiled;\r\n }\r\n\r\n /**\r\n * Create a shader program in excalibur\r\n * @param options specify shader vertex and fragment source\r\n */\r\n constructor(options?: ShaderOptions) {\r\n const { gl, vertexSource, fragmentSource } = options;\r\n this._gl = gl;\r\n this.vertexSource = vertexSource;\r\n this.fragmentSource = fragmentSource;\r\n }\r\n\r\n dispose() {\r\n const gl = this._gl;\r\n gl.deleteProgram(this.program);\r\n this._gl = null;\r\n }\r\n\r\n /**\r\n * Binds the shader program\r\n */\r\n use() {\r\n const gl = this._gl;\r\n gl.useProgram(this.program);\r\n Shader._ACTIVE_SHADER_INSTANCE = this;\r\n }\r\n\r\n isCurrentlyBound() {\r\n return Shader._ACTIVE_SHADER_INSTANCE === this;\r\n }\r\n\r\n /**\r\n * Compile the current shader against a webgl context\r\n */\r\n compile(): WebGLProgram {\r\n const gl = this._gl;\r\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\r\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\r\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\r\n\r\n const attributes = this.getAttributes();\r\n for (const attribute of attributes) {\r\n this.attributes[attribute.name] = attribute;\r\n }\r\n const uniforms = this.getUniforms();\r\n for (const uniform of uniforms) {\r\n this.uniforms[uniform.name] = uniform;\r\n }\r\n\r\n this._compiled = true;\r\n return this.program;\r\n }\r\n\r\n getUniforms(): UniformDefinition[] {\r\n const gl = this._gl;\r\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\r\n const uniforms: UniformDefinition[] = [];\r\n for (let i = 0; i < uniformCount; i++) {\r\n const uniform = gl.getActiveUniform(this.program, i);\r\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\r\n uniforms.push({\r\n name: uniform.name,\r\n glType: uniform.type,\r\n location: uniformLocation\r\n });\r\n }\r\n return uniforms;\r\n }\r\n\r\n getAttributes(): VertexAttributeDefinition[] {\r\n const gl = this._gl;\r\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\r\n const attributes: VertexAttributeDefinition[] = [];\r\n for (let i = 0; i < attributeCount; i++) {\r\n const attribute = gl.getActiveAttrib(this.program, i);\r\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\r\n attributes.push({\r\n name: attribute.name,\r\n glType: getAttributePointerType(gl, attribute.type),\r\n size: getAttributeComponentSize(gl, attribute.type),\r\n location: attributeLocation,\r\n normalized: false\r\n });\r\n }\r\n return attributes;\r\n }\r\n\r\n /**\r\n * Set a texture in a gpu texture slot\r\n * @param slotNumber\r\n * @param texture\r\n */\r\n setTexture(slotNumber: number, texture: WebGLTexture) {\r\n const gl = this._gl;\r\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n }\r\n\r\n /**\r\n * Set an integer uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformInt(name: string, value: number) {\r\n this.setUniform('uniform1i', name, ~~value);\r\n }\r\n\r\n /**\r\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformInt(name: string, value: number): boolean {\r\n return this.trySetUniform('uniform1i', name, ~~value);\r\n }\r\n\r\n /**\r\n * Set an integer array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformIntArray(name: string, value: number[]) {\r\n this.setUniform('uniform1iv', name, value);\r\n }\r\n\r\n /**\r\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformIntArray(name: string, value: number[]): boolean {\r\n return this.trySetUniform('uniform1iv', name, value);\r\n }\r\n\r\n /**\r\n * Set a boolean uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformBoolean(name: string, value: boolean) {\r\n this.setUniform('uniform1i', name, value ? 1 : 0);\r\n }\r\n\r\n /**\r\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformBoolean(name: string, value: boolean): boolean {\r\n return this.trySetUniform('uniform1i', name, value ? 1 : 0);\r\n }\r\n\r\n /**\r\n * Set a float uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloat(name: string, value: number) {\r\n this.setUniform('uniform1f', name, value);\r\n }\r\n\r\n /**\r\n * Set a float uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloat(name: string, value: number): boolean {\r\n return this.trySetUniform('uniform1f', name, value);\r\n }\r\n\r\n /**\r\n * Set a float array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatArray(name: string, value: number[]) {\r\n this.setUniform('uniform1fv', name, value);\r\n }\r\n /**\r\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatArray(name: string, value: number[]): boolean {\r\n return this.trySetUniform('uniform1fv', name, value);\r\n }\r\n\r\n /**\r\n * Set a [[Vector]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatVector(name: string, value: Vector) {\r\n this.setUniform('uniform2f', name, value.x, value.y);\r\n }\r\n\r\n /**\r\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatVector(name: string, value: Vector): boolean {\r\n return this.trySetUniform('uniform2f', name, value.x, value.y);\r\n }\r\n\r\n /**\r\n * Set a [[Color]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatColor(name: string, value: Color) {\r\n this.setUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\r\n }\r\n\r\n /**\r\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatColor(name: string, value: Color): boolean {\r\n return this.trySetUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\r\n }\r\n\r\n /**\r\n * Set an [[Matrix]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n setUniformMatrix(name: string, value: Matrix) {\r\n this.setUniform('uniformMatrix4fv', name, false, value.data);\r\n }\r\n\r\n /**\r\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformMatrix(name: string, value: Matrix): boolean {\r\n return this.trySetUniform('uniformMatrix4fv', name, false, value.data);\r\n }\r\n\r\n /**\r\n * Set any available uniform type in webgl\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n */\r\n setUniform(uniformType: TUniformType, name: string, ...value: UniformParameters) {\r\n if (!this._compiled) {\r\n throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\r\n }\r\n if (!this.isCurrentlyBound()) {\r\n throw Error('Currently accessed shader instance is not the current active shader in WebGL,' +\r\n ' must call `shader.use()` before setting uniforms');\r\n }\r\n const gl = this._gl;\r\n const location = gl.getUniformLocation(this.program, name);\r\n if (location) {\r\n const args = [location, ...value];\r\n this._gl[uniformType].apply(this._gl, args);\r\n } else {\r\n throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,`+\r\n ' unused uniforms are optimized away by most browsers');\r\n }\r\n }\r\n\r\n /**\r\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\r\n * true if it was set.\r\n *\r\n * WILL NOT THROW on error\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n *\r\n */\r\n trySetUniform(\r\n uniformType: TUniformType,\r\n name: string,\r\n ...value: UniformParameters): boolean {\r\n if (!this._compiled) {\r\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\r\n return false;\r\n }\r\n if (!this.isCurrentlyBound()) {\r\n this._logger.warn('Currently accessed shader instance is not the current active shader in WebGL,' +\r\n ' must call `shader.use()` before setting uniforms');\r\n return false;\r\n }\r\n const gl = this._gl;\r\n const location = gl.getUniformLocation(this.program, name);\r\n if (location) {\r\n const args = [location, ...value];\r\n this._gl[uniformType].apply(this._gl, args);\r\n } else {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram {\r\n const program = gl.createProgram();\r\n if (program === null) {\r\n throw Error('Could not create graphics shader program');\r\n }\r\n\r\n // attach the shaders.\r\n gl.attachShader(program, vertexShader);\r\n gl.attachShader(program, fragmentShader);\r\n\r\n // link the program.\r\n gl.linkProgram(program);\r\n\r\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\r\n if (!success) {\r\n throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\r\n }\r\n\r\n return program;\r\n }\r\n\r\n private _compileShader(gl: WebGLRenderingContext, source: string, type: number): WebGLShader {\r\n const typeName = gl.VERTEX_SHADER === type ? 'vertex' : 'fragment';\r\n const shader = gl.createShader(type);\r\n if (shader === null) {\r\n throw Error(`Could not build shader: [${source}]`);\r\n }\r\n\r\n gl.shaderSource(shader, source);\r\n gl.compileShader(shader);\r\n\r\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\r\n if (!success) {\r\n const errorInfo = gl.getShaderInfoLog(shader);\r\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\r\n }\r\n return shader;\r\n }\r\n\r\n private _processSourceForError(source: string, errorInfo: string) {\r\n if (!source) {\r\n return errorInfo;\r\n }\r\n const lines = source.split('\\n');\r\n const errorLineStart = errorInfo.search(/\\d:\\d/);\r\n const errorLineEnd = errorInfo.indexOf(' ', errorLineStart);\r\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(':').map(v => Number(v));\r\n for (let i = 0; i < lines.length; i++) {\r\n lines[i] = `${i+1}: ${lines[i]}${error2 === (i+1)? ' <----- ERROR!' : ''}`;\r\n }\r\n\r\n return '\\n\\nSource:\\n' + lines.join('\\n');\r\n }\r\n}","export interface VertexBufferOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n */\r\n gl: WebGL2RenderingContext,\r\n /**\r\n * Size in number of floats, so [4.2, 4.0, 2.1] is size = 3\r\n *\r\n * Ignored if data is passed directly\r\n */\r\n size?: number;\r\n /**\r\n * If the vertices never change switching 'static' can be more efficient on the gpu\r\n *\r\n * Default is 'dynamic'\r\n */\r\n type?: 'static' | 'dynamic';\r\n\r\n /**\r\n * Optionally pass pre-seeded data, size parameter is ignored\r\n */\r\n data?: Float32Array\r\n}\r\n\r\n/**\r\n * Helper around vertex buffer to simplify creating and uploading geometry\r\n *\r\n * Under the hood uses Float32Array\r\n */\r\nexport class VertexBuffer {\r\n private _gl: WebGL2RenderingContext;\r\n\r\n /**\r\n * Access to the webgl buffer handle\r\n */\r\n public readonly buffer: WebGLBuffer;\r\n /**\r\n * Access to the raw data of the vertex buffer\r\n */\r\n public readonly bufferData: Float32Array;\r\n\r\n /**\r\n * If the vertices never change switching 'static' can be more efficient on the gpu\r\n *\r\n * Default is 'dynamic'\r\n */\r\n public type: 'static' | 'dynamic' = 'dynamic';\r\n\r\n constructor(options: VertexBufferOptions) {\r\n const { gl, size, type, data } = options;\r\n this._gl = gl;\r\n this.buffer = this._gl.createBuffer();\r\n if (!data && !size) {\r\n throw Error('Must either provide data or a size to the VertexBuffer');\r\n }\r\n\r\n if (!data) {\r\n this.bufferData = new Float32Array(size);\r\n } else {\r\n this.bufferData = data;\r\n }\r\n this.type = type ?? this.type;\r\n // Allocate buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\r\n }\r\n\r\n /**\r\n * Bind this vertex buffer\r\n */\r\n bind() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n\r\n }\r\n\r\n /**\r\n * Upload vertex buffer geometry to the GPU\r\n */\r\n upload(count?: number) {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n if (count) {\r\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\r\n } else {\r\n // TODO always use bufferSubData? need to perf test it\r\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\r\n }\r\n }\r\n\r\n dispose() {\r\n const gl = this._gl;\r\n gl.deleteBuffer(this.buffer);\r\n this._gl = null;\r\n }\r\n}","import { Logger } from '../..';\r\nimport { Shader, VertexAttributeDefinition } from './shader';\r\nimport { VertexBuffer } from './vertex-buffer';\r\nimport { getGlTypeSizeBytes } from './webgl-util';\r\n\r\n\r\nexport interface VertexLayoutOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n */\r\n gl: WebGL2RenderingContext,\r\n /**\r\n * Shader that this layout will be for, if null you must set a shader before using it.\r\n */\r\n shader?: Shader;\r\n /**\r\n * Vertex buffer to use for vertex data\r\n */\r\n vertexBuffer: VertexBuffer,\r\n /**\r\n * Specify the attributes that will exist in the vertex buffer\r\n *\r\n * **Important** must specify them in the order that they will be in the vertex buffer!!\r\n */\r\n attributes: [name: string, numberOfComponents: number][]\r\n}\r\n\r\n/**\r\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\r\n * the memory layout for your vertices inside a particular buffer\r\n *\r\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\r\n *\r\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\r\n */\r\nexport class VertexLayout {\r\n private _gl: WebGL2RenderingContext;\r\n private _logger = Logger.getInstance();\r\n private _shader: Shader;\r\n private _layout: VertexAttributeDefinition[] = [];\r\n private _attributes: [name: string, numberOfComponents: number][] = [];\r\n private _vertexBuffer: VertexBuffer;\r\n public get vertexBuffer() {\r\n return this._vertexBuffer;\r\n }\r\n\r\n public get attributes(): readonly [name: string, numberOfComponents: number][] {\r\n return this._attributes;\r\n }\r\n\r\n constructor(options: VertexLayoutOptions) {\r\n const {gl, shader, vertexBuffer, attributes} = options;\r\n this._gl = gl;\r\n this._vertexBuffer = vertexBuffer;\r\n this._attributes = attributes;\r\n this._shader = shader;\r\n if (shader) {\r\n this.initialize();\r\n }\r\n }\r\n\r\n private _vertexTotalSizeBytes = 0;\r\n /**\r\n * Total number of bytes that the vertex will take up\r\n */\r\n public get totalVertexSizeBytes(): number {\r\n return this._vertexTotalSizeBytes;\r\n }\r\n\r\n public set shader(shader: Shader) {\r\n if (shader && this._shader !== shader) {\r\n this._shader = shader;\r\n this.initialize();\r\n }\r\n }\r\n\r\n public get shader() {\r\n return this._shader;\r\n }\r\n\r\n /**\r\n * Layouts need shader locations and must be bound to a shader\r\n */\r\n initialize() {\r\n if (!this._shader) {\r\n return;\r\n }\r\n\r\n if (!this._shader.compiled) {\r\n throw Error('Shader not compiled, shader must be compiled before defining a vertex layout');\r\n }\r\n this._vertexTotalSizeBytes = 0;\r\n this._layout.length = 0;\r\n const shaderAttributes = this._shader.attributes;\r\n for (const attribute of this._attributes) {\r\n const attrib = shaderAttributes[attribute[0]];\r\n if (!attrib) {\r\n throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}`+\r\n ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\r\n }\r\n if (attrib.size !== attribute[1]) {\r\n throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],`\r\n +` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\r\n }\r\n this._layout.push(attrib);\r\n }\r\n\r\n // calc size\r\n let componentsPerVertex = 0;\r\n for (const vertAttribute of this._layout) {\r\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\r\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\r\n componentsPerVertex += vertAttribute.size;\r\n }\r\n\r\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) {\r\n this._logger.warn(`The vertex component size (${componentsPerVertex}) does NOT divide evenly into the specified vertex buffer`\r\n +` (${this._vertexBuffer.bufferData.length})`);\r\n }\r\n }\r\n\r\n /**\r\n * Bind this layout with it's associated vertex buffer\r\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\r\n */\r\n use(uploadBuffer = false, count?: number) {\r\n if (!this._shader) {\r\n throw Error('No shader is associated with this vertex layout, a shader must be set');\r\n }\r\n\r\n const gl = this._gl;\r\n if (!this._shader.isCurrentlyBound()) {\r\n throw Error('Shader associated with this vertex layout is not active! Call shader.use() before layout.use()');\r\n }\r\n this._vertexBuffer.bind();\r\n if (uploadBuffer) {\r\n this._vertexBuffer.upload(count);\r\n }\r\n let offset = 0;\r\n // TODO switch to VAOs if the extension is\r\n for (const vert of this._layout) {\r\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\r\n gl.enableVertexAttribArray(vert.location);\r\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\r\n }\r\n }\r\n}","export class GraphicsDiagnostics {\r\n public static DrawCallCount: number = 0;\r\n public static DrawnImagesCount: number = 0;\r\n public static clear(): void {\r\n GraphicsDiagnostics.DrawCallCount = 0;\r\n GraphicsDiagnostics.DrawnImagesCount = 0;\r\n }\r\n}\r\n","import { Vector } from '../../../Math/vector';\r\nimport { Color } from '../../../Color';\r\nimport lineVertexSource from './line-vertex.glsl';\r\nimport lineFragmentSource from './line-fragment.glsl';\r\nimport { ExcaliburGraphicsContextWebGL } from '../ExcaliburGraphicsContextWebGL';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader, VertexBuffer, VertexLayout } from '../..';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\n\r\nexport interface LineOptions {\r\n color?: Color;\r\n width?: number;\r\n}\r\n\r\nexport class LineRenderer implements RendererPlugin {\r\n public readonly type = 'ex.line';\r\n public priority: number = 0;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGL2RenderingContext;\r\n private _shader: Shader;\r\n private _maxLines: number = 10922;\r\n private _vertexBuffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _vertexIndex = 0;\r\n private _lineCount = 0;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: lineVertexSource,\r\n fragmentSource: lineFragmentSource\r\n });\r\n this._shader.compile();\r\n this._shader.use();\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n this._vertexBuffer = new VertexBuffer({\r\n gl,\r\n size: 6 * 2 * this._maxLines,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n vertexBuffer: this._vertexBuffer,\r\n shader: this._shader,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_color', 4]\r\n ]\r\n });\r\n }\r\n\r\n public dispose() {\r\n this._vertexBuffer.dispose();\r\n this._shader.dispose();\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n draw(start: Vector, end: Vector, color: Color): void {\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._lineCount++;\r\n\r\n const transform = this._context.getTransform();\r\n const finalStart = transform.multiply(start);\r\n const finalEnd = transform.multiply(end);\r\n\r\n\r\n const vertexBuffer = this._vertexBuffer.bufferData;\r\n // Start\r\n vertexBuffer[this._vertexIndex++] = finalStart.x;\r\n vertexBuffer[this._vertexIndex++] = finalStart.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n\r\n // End\r\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\r\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n }\r\n\r\n private _isFull() {\r\n if (this._lineCount >= this._maxLines) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._lineCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._lineCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use(true);\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // reset\r\n this._vertexIndex = 0;\r\n this._lineCount = 0;\r\n }\r\n}\r\n","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\";","export default \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \\\"premultiply\\\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}\";","import pointVertexSource from './point-vertex.glsl';\r\nimport pointFragmentSource from './point-fragment.glsl';\r\nimport { Vector } from '../../../Math/vector';\r\nimport { Color } from '../../../Color';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\n\r\nexport class PointRenderer implements RendererPlugin {\r\n public readonly type = 'ex.point';\r\n public priority: number = 0;\r\n private _shader: Shader;\r\n private _maxPoints: number = 10922;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _gl: WebGLRenderingContext;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _pointCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: pointVertexSource,\r\n fragmentSource: pointFragmentSource\r\n });\r\n this._shader.compile();\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 7 * this._maxPoints,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_color', 4],\r\n ['a_size', 1]\r\n ]\r\n });\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._shader.dispose();\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n draw(point: Vector, color: Color, size: number): void {\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._pointCount++;\r\n\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const finalPoint = transform.multiply(point);\r\n\r\n if (snapToPixel) {\r\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\r\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\r\n }\r\n\r\n const vertexBuffer = this._buffer.bufferData;\r\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\r\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\r\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\r\n }\r\n\r\n private _isFull() {\r\n if (this._pointCount >= this._maxPoints) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._pointCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._pointCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use(true);\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n this._pointCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n}\r\n","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\";","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\";","\r\nimport screenVertex from './screen-vertex.glsl';\r\nimport screenFragment from './screen-fragment.glsl';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport { PostProcessor } from '../../PostProcessor/PostProcessor';\r\n\r\n/**\r\n * This is responsible for painting the entire screen during the render passes\r\n */\r\nexport class ScreenPassPainter {\r\n private _gl: WebGLRenderingContext;\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n constructor(gl: WebGL2RenderingContext) {\r\n this._gl = gl;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: screenVertex,\r\n fragmentSource: screenFragment\r\n });\r\n this._shader.compile();\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n type: 'static',\r\n // clip space quad + uv since we don't need a camera\r\n data: new Float32Array([\r\n -1, -1, 0, 0,\r\n -1, 1, 0, 1,\r\n 1, -1, 1, 0,\r\n\r\n 1, -1, 1, 0,\r\n -1, 1, 0, 1,\r\n 1, 1, 1, 1\r\n ])\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_texcoord', 2]\r\n ]\r\n });\r\n this._buffer.upload();\r\n }\r\n\r\n renderWithPostProcessor(postprocessor: PostProcessor): void {\r\n const gl = this._gl;\r\n postprocessor.getShader().use();\r\n postprocessor.getLayout().use();\r\n gl.drawArrays(gl.TRIANGLES, 0, 6);\r\n }\r\n\r\n renderToScreen(): void {\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use();\r\n gl.drawArrays(gl.TRIANGLES, 0, 6);\r\n }\r\n}","import { Logger } from '../..';\r\n\r\n/**\r\n * Helper that defines and index buffer for quad geometry\r\n *\r\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\r\n * it is almost always worth it in terms of performance to use an index buffer.\r\n */\r\nexport class QuadIndexBuffer {\r\n private _gl: WebGL2RenderingContext;\r\n private _logger: Logger = Logger.getInstance();\r\n /**\r\n * Access to the webgl buffer handle\r\n */\r\n public buffer: WebGLBuffer;\r\n /**\r\n * Access to the raw data of the index buffer\r\n */\r\n public bufferData: Uint16Array | Uint32Array;\r\n /**\r\n * Depending on the browser this is either gl.UNSIGNED_SHORT or gl.UNSIGNED_INT\r\n */\r\n public bufferGlType: number;\r\n\r\n /**\r\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n * @param numberOfQuads Specify the max number of quads you want to draw\r\n * @param useUint16 Optionally force a uint16 buffer\r\n */\r\n constructor(gl: WebGL2RenderingContext, numberOfQuads: number, useUint16?: boolean) {\r\n this._gl = gl;\r\n this.buffer = gl.createBuffer();\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n\r\n const totalVertices = numberOfQuads * 6;\r\n\r\n if (!useUint16) {\r\n this.bufferData = new Uint32Array(totalVertices);\r\n } else {\r\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\r\n const maxUint16 = 65_535;\r\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\r\n\r\n this.bufferGlType = gl.UNSIGNED_SHORT;\r\n this.bufferData = new Uint16Array(totalVertices);\r\n // TODO Should we error if this happens?? maybe not might crash mid game\r\n if (numberOfQuads > maxUint16Index) {\r\n this._logger.warn(\r\n `Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\r\n }\r\n }\r\n\r\n\r\n let currentQuad = 0;\r\n for (let i = 0; i < totalVertices; i += 6) {\r\n // first triangle\r\n this.bufferData[i + 0] = currentQuad + 0;\r\n this.bufferData[i + 1] = currentQuad + 1;\r\n this.bufferData[i + 2] = currentQuad + 2;\r\n // second triangle\r\n this.bufferData[i + 3] = currentQuad + 2;\r\n this.bufferData[i + 4] = currentQuad + 1;\r\n this.bufferData[i + 5] = currentQuad + 3;\r\n currentQuad += 4;\r\n }\r\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\r\n }\r\n\r\n public get size() {\r\n return this.bufferData.length;\r\n }\r\n\r\n /**\r\n * Upload data to the GPU\r\n */\r\n public upload() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\r\n }\r\n\r\n /**\r\n * Bind this index buffer\r\n */\r\n public bind() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n }\r\n\r\n public dispose() {\r\n const gl = this._gl;\r\n gl.deleteBuffer(this.buffer);\r\n this._gl = null;\r\n }\r\n}","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\nuniform bool u_pixelart;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nin vec2 v_res;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\n// Inigo Quilez pixel art filter https://jorenjoestar.github.io/post/pixel_art_filtering/\\r\\nvec2 uv_iq(in vec2 uv, in vec2 texture_size) {\\r\\n vec2 pixel = uv * texture_size;\\r\\n \\r\\n vec2 seam=floor(pixel+.5);\\r\\n vec2 dudv=fwidth(pixel);\\r\\n pixel=seam+clamp((pixel-seam)/dudv,-.5,.5);\\r\\n \\r\\n return pixel/texture_size;\\r\\n}\\r\\n\\r\\nvoid main(){\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n \\r\\n vec4 color=vec4(1.,0,0,1.);\\r\\n \\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n \\r\\n color.rgb=color.rgb*v_opacity;\\r\\n color.a=color.a*v_opacity;\\r\\n fragColor=color*v_tint;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity\\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture res\\r\\nin vec2 a_res;\\r\\nout vec2 v_res;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main(){\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position=u_matrix*vec4(a_position,0.,1.);\\r\\n \\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity=a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord=a_texcoord;\\r\\n\\r\\n v_res = a_res;\\r\\n\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex=a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint=a_tint;\\r\\n}\";","import { sign } from '../../../Math/util';\r\nimport { vec } from '../../../Math/vector';\r\nimport { ImageFiltering } from '../../Filtering';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { HTMLImageSource } from '../ExcaliburGraphicsContext';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport frag from './image-renderer.frag.glsl';\r\nimport vert from './image-renderer.vert.glsl';\r\n\r\nexport interface ImageRendererOptions {\r\n pixelArtSampler: boolean;\r\n uvPadding: number;\r\n}\r\n\r\nexport class ImageRenderer implements RendererPlugin {\r\n public readonly type = 'ex.image';\r\n public priority: number = 0;\r\n\r\n public readonly pixelArtSampler: boolean;\r\n public readonly uvPadding: number;\r\n\r\n private _maxImages: number = 10922; // max(uint16) / 6 verts\r\n private _maxTextures: number = 0;\r\n\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGLRenderingContext;\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n\r\n // Per flush vars\r\n private _imageCount: number = 0;\r\n private _textures: WebGLTexture[] = [];\r\n private _vertexIndex: number = 0;\r\n\r\n constructor(options: ImageRendererOptions) {\r\n this.pixelArtSampler = options.pixelArtSampler;\r\n this.uvPadding = options.uvPadding;\r\n }\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n // Transform shader source\r\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\r\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\r\n const transformedFrag = this._transformFragmentSource(frag, this._maxTextures);\r\n // Compile shader\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: transformedFrag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\r\n this._shader.setUniformIntArray(\r\n 'u_textures',\r\n [...Array(this._maxTextures)].map((_, i) => i)\r\n );\r\n\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 12 * 4 * this._maxImages, // 12 components * 4 verts\r\n type: 'dynamic'\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_opacity', 1],\r\n ['a_res', 2],\r\n ['a_texcoord', 2],\r\n ['a_textureIndex', 1],\r\n ['a_tint', 4]\r\n ]\r\n });\r\n\r\n // Setup index buffer\r\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._quads.dispose();\r\n this._shader.dispose();\r\n this._textures.length = 0;\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n private _transformFragmentSource(source: string, maxTextures: number): string {\r\n let newSource = source.replace('%%count%%', maxTextures.toString());\r\n let texturePickerBuilder = '';\r\n for (let i = 0; i < maxTextures; i++) {\r\n if (i === 0) {\r\n texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\r\n } else {\r\n texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\r\n }\r\n texturePickerBuilder += ` vec2 uv = u_pixelart ? uv_iq(v_texcoord, v_res) : v_texcoord;\\n`;\r\n texturePickerBuilder += ` color = texture(u_textures[${i}], uv);\\n`;\r\n texturePickerBuilder += ` }\\n`;\r\n }\r\n newSource = newSource.replace('%%texture_picker%%', texturePickerBuilder);\r\n return newSource;\r\n }\r\n\r\n private _addImageAsTexture(image: HTMLImageSource) {\r\n const maybeFiltering = image.getAttribute('filtering');\r\n let filtering: ImageFiltering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n\r\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._context.textureLoader.load(image, filtering, force);\r\n // remove force attribute after upload\r\n image.removeAttribute('forceUpload');\r\n if (this._textures.indexOf(texture) === -1) {\r\n this._textures.push(texture);\r\n }\r\n }\r\n\r\n private _bindTextures(gl: WebGLRenderingContext) {\r\n // Bind textures in the correct order\r\n for (let i = 0; i < this._maxTextures; i++) {\r\n gl.activeTexture(gl.TEXTURE0 + i);\r\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\r\n }\r\n }\r\n\r\n private _getTextureIdForImage(image: HTMLImageSource) {\r\n if (image) {\r\n const maybeTexture = this._context.textureLoader.get(image);\r\n return this._textures.indexOf(maybeTexture);\r\n }\r\n return -1;\r\n }\r\n\r\n private _isFull() {\r\n if (this._imageCount >= this._maxImages) {\r\n return true;\r\n }\r\n if (this._textures.length >= this._maxTextures) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n\r\n draw(image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number): void {\r\n\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._imageCount++;\r\n // This creates and uploads the texture if not already done\r\n this._addImageAsTexture(image);\r\n\r\n let width = image?.width || swidth || 0;\r\n let height = image?.height || sheight || 0;\r\n let view = [0, 0, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n let dest = [sx ?? 1, sy ?? 1];\r\n // If destination is specified, update view and dest\r\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\r\n view = [sx ?? 1, sy ?? 1, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n dest = [dx, dy];\r\n width = dwidth;\r\n height = dheight;\r\n }\r\n\r\n sx = view[0];\r\n sy = view[1];\r\n const sw = view[2];\r\n const sh = view[3];\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n let topLeft = vec(dest[0], dest[1]);\r\n let topRight = vec(dest[0] + width, dest[1]);\r\n let bottomLeft = vec(dest[0], dest[1] + height);\r\n let bottomRight = vec(dest[0] + width, dest[1] + height);\r\n\r\n topLeft = transform.multiply(topLeft);\r\n topRight = transform.multiply(topRight);\r\n bottomLeft = transform.multiply(bottomLeft);\r\n bottomRight = transform.multiply(bottomRight);\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + sign(topLeft.x) * pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + sign(topLeft.y) * pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + sign(topRight.x) * pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + sign(topRight.y) * pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + sign(bottomLeft.x) * pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + sign(bottomLeft.y) * pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + sign(bottomRight.x) * pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + sign(bottomRight.y) * pixelSnapEpsilon);\r\n }\r\n\r\n const tint = this._context.tint;\r\n\r\n const textureId = this._getTextureIdForImage(image);\r\n const imageWidth = image.width || width;\r\n const imageHeight = image.height || height;\r\n\r\n const uvx0 = (sx + this.uvPadding) / imageWidth;\r\n const uvy0 = (sy + this.uvPadding) / imageHeight;\r\n const uvx1 = (sx + sw - this.uvPadding) / imageWidth;\r\n const uvy1 = (sy + sh - this.uvPadding) / imageHeight;\r\n\r\n const txWidth = image.width;\r\n const txHeight = image.height;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = txWidth;\r\n vertexBuffer[this._vertexIndex++] = txHeight;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = txWidth;\r\n vertexBuffer[this._vertexIndex++] = txHeight;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = txWidth;\r\n vertexBuffer[this._vertexIndex++] = txHeight;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = txWidth;\r\n vertexBuffer[this._vertexIndex++] = txHeight;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._imageCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._imageCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true, 4 * 12 * this._imageCount); // 4 verts * 12 components\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Turn on pixel art aa sampler\r\n this._shader.setUniformBoolean('u_pixelart', this.pixelArtSampler);\r\n\r\n // Bind textures to\r\n this._bindTextures(gl);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._imageCount = 0;\r\n this._vertexIndex = 0;\r\n this._textures.length = 0;\r\n }\r\n}","export default \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";","import { Color } from '../../../Color';\r\nimport { vec, Vector } from '../../../Math/vector';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\nimport frag from './rectangle-renderer.frag.glsl';\r\nimport vert from './rectangle-renderer.vert.glsl';\r\n\r\nexport class RectangleRenderer implements RendererPlugin {\r\n public readonly type = 'ex.rectangle';\r\n public priority: number = 0;\r\n\r\n private _maxRectangles: number = 10922; // max(uint16) / 6 verts\r\n\r\n private _shader: Shader;\r\n private _gl: WebGLRenderingContext;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n private _rectangleCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: frag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 16 * 4 * this._maxRectangles,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_size', 2],\r\n ['a_opacity', 1],\r\n ['a_color', 4],\r\n ['a_strokeColor', 4],\r\n ['a_strokeThickness', 1]\r\n ]\r\n });\r\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._quads.dispose();\r\n this._shader.dispose();\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n private _isFull() {\r\n if (this._rectangleCount >= this._maxRectangles) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n draw(...args: any[]): void {\r\n if (args[0] instanceof Vector && args[1] instanceof Vector) {\r\n this.drawLine.apply(this, args);\r\n } else {\r\n this.drawRectangle.apply(this, args);\r\n }\r\n }\r\n\r\n drawLine(start: Vector, end: Vector, color: Color, thickness: number = 1) {\r\n\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._rectangleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const dir = end.sub(start);\r\n const length = dir.size;\r\n const normal = dir.normalize().perpendicular();\r\n const halfThick = thickness / 2;\r\n\r\n /**\r\n * +---------------------^----------------------+\r\n * | | (normal) |\r\n * (startx, starty)------------------>(endx, endy)\r\n * | |\r\n * + -------------------------------------------+\r\n */\r\n const startTop = transform.multiply(normal.scale(halfThick).add(start));\r\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\r\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\r\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\r\n\r\n if (snapToPixel) {\r\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\r\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\r\n\r\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\r\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\r\n\r\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\r\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\r\n\r\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\r\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO uv could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n const stroke = Color.Transparent;\r\n const strokeThickness = 0;\r\n const width = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = startTop.x;\r\n vertexBuffer[this._vertexIndex++] = startTop.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = startBottom.x;\r\n vertexBuffer[this._vertexIndex++] = startBottom.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = endTop.x;\r\n vertexBuffer[this._vertexIndex++] = endTop.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = endBottom.x;\r\n vertexBuffer[this._vertexIndex++] = endBottom.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n }\r\n\r\n drawRectangle(\r\n pos: Vector,\r\n width: number,\r\n height: number,\r\n color: Color,\r\n stroke: Color = Color.Transparent,\r\n strokeThickness: number = 0): void {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._rectangleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\r\n const topRight = transform.multiply(pos.add(vec(width, 0)));\r\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\r\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO uv could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._rectangleCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._rectangleCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true);\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._rectangleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n\r\n}","export default \"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";","import { Color } from '../../../Color';\r\nimport { vec, Vector } from '../../../Math/vector';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\nimport frag from './circle-renderer.frag.glsl';\r\nimport vert from './circle-renderer.vert.glsl';\r\n\r\nexport class CircleRenderer implements RendererPlugin {\r\n public readonly type = 'ex.circle';\r\n public priority: number = 0;\r\n\r\n private _maxCircles: number = 10922; // max(uint16) / 6 verts\r\n\r\n private _shader: Shader;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGLRenderingContext;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n\r\n private _circleCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: frag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 14 * 4 * this._maxCircles,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_opacity', 1],\r\n ['a_color', 4],\r\n ['a_strokeColor', 4],\r\n ['a_strokeThickness', 1]\r\n ]\r\n });\r\n\r\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._quads.dispose();\r\n this._shader.dispose();\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n private _isFull() {\r\n if (this._circleCount >= this._maxCircles) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n draw(pos: Vector, radius: number, color: Color, stroke: Color = Color.Transparent, strokeThickness: number = 0): void {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._circleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\r\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\r\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\r\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO UV could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._circleCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._circleCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true);\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._circleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n\r\n}","import { Logger } from '../Util/Log';\r\nexport class Pool {\r\n public totalAllocations = 0;\r\n public index = 0;\r\n public objects: Type[] = [];\r\n public disableWarnings = false;\r\n private _logger = Logger.getInstance();\r\n\r\n constructor(\r\n public builder: (...args: any[]) => Type,\r\n public recycler: (instance: Type, ...args: any[]) => Type,\r\n public maxObjects: number = 100\r\n ) {}\r\n\r\n dispose() {\r\n this.objects.length = 0;\r\n }\r\n\r\n preallocate() {\r\n for (let i = 0; i < this.maxObjects; i++) {\r\n this.objects[i] = this.builder();\r\n }\r\n }\r\n\r\n /**\r\n * Use many instances out of the in the context and return all to the pool.\r\n *\r\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\r\n * @param context\r\n */\r\n using(context: (pool: Pool) => Type[] | void) {\r\n const result = context(this);\r\n if (result) {\r\n return this.done(...result);\r\n }\r\n return this.done();\r\n }\r\n\r\n /**\r\n * Use a single instance out of th pool and immediately return it to the pool\r\n * @param context\r\n */\r\n borrow(context: (object: Type) => void) {\r\n const object = this.get();\r\n context(object);\r\n this.index--;\r\n }\r\n\r\n /**\r\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\r\n * @param args\r\n */\r\n get(...args: any[]): Type {\r\n if (this.index === this.maxObjects) {\r\n if (!this.disableWarnings) {\r\n this._logger.warn('Max pooled objects reached, possible memory leak? Doubling');\r\n }\r\n this.maxObjects = this.maxObjects * 2;\r\n }\r\n\r\n if (this.objects[this.index]) {\r\n // Pool has an available object already constructed\r\n return this.recycler(this.objects[this.index++], ...args);\r\n } else {\r\n // New allocation\r\n this.totalAllocations++;\r\n const object = (this.objects[this.index++] = this.builder(...args));\r\n return object;\r\n }\r\n }\r\n\r\n /**\r\n * Signals we are done with the pool objects for now, Reclaims all objects in the pool.\r\n *\r\n * If a list of pooled objects is passed to done they are un-hooked from the pool and are free\r\n * to be passed to consumers\r\n * @param objects A list of object to separate from the pool\r\n */\r\n done(...objects: Type[]): Type[];\r\n done(): void;\r\n done(...objects: Type[]): Type[] | void {\r\n // All objects in pool now considered \"free\"\r\n this.index = 0;\r\n for (const object of objects) {\r\n const poolIndex = this.objects.indexOf(object);\r\n // Build a new object to take the pool place\r\n this.objects[poolIndex] = (this as any).builder(); // TODO problematic 0-arg only support\r\n this.totalAllocations++;\r\n }\r\n return objects;\r\n }\r\n}\r\n","import { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContextState } from './ExcaliburGraphicsContext';\r\n\r\nexport class DrawCall {\r\n public z: number = 0;\r\n public priority: number = 0;\r\n public renderer: string;\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public state: ExcaliburGraphicsContextState = {\r\n z: 0,\r\n opacity: 1,\r\n tint: Color.White,\r\n material: null\r\n };\r\n public args: any[];\r\n}","import { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContext } from './ExcaliburGraphicsContext';\r\nimport { ExcaliburGraphicsContextWebGL } from './ExcaliburGraphicsContextWebGL';\r\nimport { Shader } from './shader';\r\nimport { Logger } from '../../Util/Log';\r\nimport { ImageSource } from '../ImageSource';\r\nimport { ImageFiltering } from '../Filtering';\r\n\r\nexport interface MaterialOptions {\r\n /**\r\n * Name the material for debugging\r\n */\r\n name?: string;\r\n\r\n /**\r\n * Excalibur graphics context to create the material (only WebGL is supported at the moment)\r\n */\r\n graphicsContext?: ExcaliburGraphicsContext;\r\n\r\n /**\r\n * Optionally specify a vertex shader\r\n *\r\n * If none supplied the default will be used\r\n *\r\n * ```\r\n * #version 300 es\r\n * // vertex position in local space\r\n * in vec2 a_position;\r\n * in vec2 a_uv;\r\n * out vec2 v_uv;\r\n * // orthographic projection matrix\r\n * uniform mat4 u_matrix;\r\n * // world space transform matrix\r\n * uniform mat4 u_transform;\r\n * void main() {\r\n * // Set the vertex position using the ortho & transform matrix\r\n * gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n * // Pass through the UV coord to the fragment shader\r\n * v_uv = a_uv;\r\n * }\r\n * ```\r\n */\r\n vertexSource?: string,\r\n\r\n /**\r\n * Add custom fragment shader\r\n *\r\n * *Note: Excalibur image alpha's are pre-multiplied\r\n *\r\n * Pre-built varyings:\r\n *\r\n * * `in vec2 v_uv` - UV coordinate\r\n *\r\n * Pre-built uniforms:\r\n *\r\n * * `uniform sampler2D u_graphic` - The current graphic displayed by the GraphicsComponent\r\n * * `uniform vec2 u_resolution` - The current resolution of the screen\r\n * * `uniform vec2 u_size;` - The current size of the graphic\r\n * * `uniform vec4 u_color` - The current color of the material\r\n * * `uniform float u_opacity` - The current opacity of the graphics context\r\n *\r\n */\r\n fragmentSource: string,\r\n\r\n /**\r\n * Add custom color, by default ex.Color.Transparent\r\n */\r\n color?: Color,\r\n\r\n /**\r\n * Add additional images to the material, you are limited by the GPU's maximum texture slots\r\n *\r\n * Specify a dictionary of uniform sampler names to ImageSource\r\n */\r\n images?: Record\r\n}\r\n\r\nconst defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nin vec2 a_screenuv;\r\nout vec2 v_screenuv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n v_screenuv = a_screenuv;\r\n}\r\n`;\r\n\r\nexport interface MaterialImageOptions {\r\n filtering?: ImageFiltering,\r\n\r\n}\r\n\r\nexport class Material {\r\n private _logger = Logger.getInstance();\r\n private _name: string;\r\n private _shader: Shader;\r\n private _color: Color = Color.Transparent;\r\n private _initialized = false;\r\n private _fragmentSource: string;\r\n private _vertexSource: string;\r\n\r\n private _images = new Map();\r\n private _textures = new Map();\r\n private _maxTextureSlots: number;\r\n private _graphicsContext: ExcaliburGraphicsContextWebGL;\r\n\r\n constructor(options: MaterialOptions) {\r\n const { color, name, vertexSource, fragmentSource, graphicsContext, images } = options;\r\n this._name = name ?? 'anonymous material';\r\n this._vertexSource = vertexSource ?? defaultVertexSource;\r\n this._fragmentSource = fragmentSource;\r\n this._color = color ?? this._color;\r\n if (!graphicsContext) {\r\n throw Error(`Material ${name} must be provided an excalibur webgl graphics context`);\r\n }\r\n if (graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this._graphicsContext = graphicsContext;\r\n this._initialize(graphicsContext);\r\n } else {\r\n this._logger.warn(`Material ${name} was created in 2D Canvas mode, currently only WebGL is supported`);\r\n }\r\n\r\n if (images) {\r\n for (const key in images) {\r\n this.addImageSource(key, images[key]);\r\n }\r\n }\r\n }\r\n\r\n private _initialize(graphicsContextWebGL: ExcaliburGraphicsContextWebGL) {\r\n if (this._initialized) {\r\n return;\r\n }\r\n const gl = graphicsContextWebGL.__gl;\r\n // max texture slots - 2 for the graphic texture and screen texture\r\n this._maxTextureSlots = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) - 2;\r\n this._shader = graphicsContextWebGL.createShader({\r\n vertexSource: this._vertexSource,\r\n fragmentSource: this._fragmentSource\r\n });\r\n this._shader.compile();\r\n this._initialized = true;\r\n }\r\n\r\n get name() {\r\n return this._name ?? 'anonymous material';\r\n }\r\n\r\n get isUsingScreenTexture() {\r\n return this._fragmentSource.includes('u_screen_texture');\r\n }\r\n\r\n update(callback: (shader: Shader) => any) {\r\n if (this._shader) {\r\n this._shader.use();\r\n callback(this._shader);\r\n }\r\n }\r\n\r\n getShader(): Shader | null {\r\n return this._shader;\r\n }\r\n\r\n addImageSource(textureUniformName: string, image: ImageSource) {\r\n if (this._images.size < this._maxTextureSlots) {\r\n this._images.set(textureUniformName, image);\r\n } else {\r\n this._logger.warn(`Max number texture slots ${this._maxTextureSlots} have been reached for material \"${this.name}\", `+\r\n `no more textures will be uploaded due to hardware constraints.`);\r\n }\r\n }\r\n\r\n removeImageSource(textureName: string) {\r\n const image = this._images.get(textureName);\r\n this._graphicsContext.textureLoader.delete(image.image);\r\n this._images.delete(textureName);\r\n }\r\n\r\n private _loadImageSource(image: ImageSource) {\r\n const imageElement = image.image;\r\n const maybeFiltering = imageElement.getAttribute('filtering');\r\n let filtering: ImageFiltering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n\r\n const force = imageElement.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._graphicsContext.textureLoader.load(imageElement, filtering, force);\r\n // remove force attribute after upload\r\n imageElement.removeAttribute('forceUpload');\r\n if (!this._textures.has(image)) {\r\n this._textures.set(image, texture);\r\n }\r\n\r\n return texture;\r\n }\r\n\r\n uploadAndBind(gl: WebGL2RenderingContext, startingTextureSlot: number = 2) {\r\n\r\n let textureSlot = startingTextureSlot;\r\n for (const [textureName, image] of this._images.entries()) {\r\n if (!image.isLoaded()) {\r\n this._logger.warnOnce(`Image named ${textureName} in material ${this.name} not loaded, nothing will be uploaded to the shader.` +\r\n ` Did you forget to add this to a loader? https://excaliburjs.com/docs/loaders/`);\r\n continue;\r\n } // skip unloaded images, maybe warn\r\n const texture = this._loadImageSource(image);\r\n\r\n gl.activeTexture(gl.TEXTURE0 + textureSlot);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n this._shader.trySetUniformInt(textureName, textureSlot);\r\n\r\n textureSlot++;\r\n }\r\n }\r\n\r\n use() {\r\n if (this._initialized) {\r\n // bind the shader\r\n this._shader.use();\r\n // Apply standard uniforms\r\n this._shader.trySetUniformFloatColor('u_color', this._color);\r\n\r\n } else {\r\n throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\r\n }\r\n }\r\n}","import { vec } from '../../../Math/vector';\r\nimport { ImageFiltering } from '../../Filtering';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { HTMLImageSource } from '../ExcaliburGraphicsContext';\r\nimport { ExcaliburGraphicsContextWebGL } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\n\r\nexport class MaterialRenderer implements RendererPlugin {\r\n public readonly type: string = 'ex.material';\r\n public priority: number = 0;\r\n // private _maxTextures = 8;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGL2RenderingContext;\r\n private _textures: WebGLTexture[] = [];\r\n private _quads: any;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 6 * 4, // 6 components * 4 verts\r\n type: 'dynamic'\r\n });\r\n\r\n // Setup a vertex layout/buffer to the material\r\n this._layout = new VertexLayout({\r\n gl,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_screenuv', 2]\r\n ]\r\n });\r\n\r\n // Setup index buffer\r\n this._quads = new QuadIndexBuffer(gl, 1, true);\r\n }\r\n\r\n public dispose() {\r\n this._buffer.dispose();\r\n this._quads.dispose();\r\n this._textures.length = 0;\r\n this._context = null;\r\n this._gl = null;\r\n }\r\n\r\n draw(image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number): void {\r\n const gl = this._gl;\r\n\r\n // Extract context info\r\n const material = this._context.material;\r\n\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n\r\n // material shader\r\n const shader = material.getShader();\r\n\r\n // construct geometry, or hold on to it in the material?\r\n // geometry primitive for drawing rectangles?\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n let vertexIndex = 0;\r\n\r\n let width = image?.width || swidth || 0;\r\n let height = image?.height || sheight || 0;\r\n let view = [0, 0, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n let dest = [sx ?? 1, sy ?? 1];\r\n // If destination is specified, update view and dest\r\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\r\n view = [sx ?? 1, sy ?? 1, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n dest = [dx, dy];\r\n width = dwidth;\r\n height = dheight;\r\n }\r\n\r\n sx = view[0];\r\n sy = view[1];\r\n const sw = view[2];\r\n const sh = view[3];\r\n\r\n const topLeft = vec(dest[0], dest[1]);\r\n const topRight = vec(dest[0] + width, dest[1]);\r\n const bottomLeft = vec(dest[0], dest[1] + height);\r\n const bottomRight = vec(dest[0] + width, dest[1] + height);\r\n\r\n const imageWidth = image.width || width;\r\n const imageHeight = image.height || height;\r\n\r\n const uvx0 = (sx) / imageWidth;\r\n const uvy0 = (sy) / imageHeight;\r\n const uvx1 = (sx + sw - 0.01) / imageWidth;\r\n const uvy1 = (sy + sh - 0.01) / imageHeight;\r\n\r\n const topLeftScreen = transform.getPosition();\r\n const bottomRightScreen = topLeftScreen.add(bottomRight);\r\n const screenUVX0 = topLeftScreen.x / this._context.width;\r\n const screenUVY0 = topLeftScreen.y / this._context.height;\r\n const screenUVX1 = bottomRightScreen.x / this._context.width;\r\n const screenUVY1 = bottomRightScreen.y / this._context.height;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[vertexIndex++] = topLeft.x;\r\n vertexBuffer[vertexIndex++] = topLeft.y;\r\n vertexBuffer[vertexIndex++] = uvx0;\r\n vertexBuffer[vertexIndex++] = uvy0;\r\n vertexBuffer[vertexIndex++] = screenUVX0;\r\n vertexBuffer[vertexIndex++] = screenUVY0;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[vertexIndex++] = uvx0;\r\n vertexBuffer[vertexIndex++] = uvy1;\r\n vertexBuffer[vertexIndex++] = screenUVX0;\r\n vertexBuffer[vertexIndex++] = screenUVY1;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[vertexIndex++] = topRight.x;\r\n vertexBuffer[vertexIndex++] = topRight.y;\r\n vertexBuffer[vertexIndex++] = uvx1;\r\n vertexBuffer[vertexIndex++] = uvy0;\r\n vertexBuffer[vertexIndex++] = screenUVX1;\r\n vertexBuffer[vertexIndex++] = screenUVY0;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[vertexIndex++] = bottomRight.x;\r\n vertexBuffer[vertexIndex++] = bottomRight.y;\r\n vertexBuffer[vertexIndex++] = uvx1;\r\n vertexBuffer[vertexIndex++] = uvy1;\r\n vertexBuffer[vertexIndex++] = screenUVX1;\r\n vertexBuffer[vertexIndex++] = screenUVY1;\r\n\r\n // This creates and uploads the texture if not already done\r\n const texture = this._addImageAsTexture(image);\r\n\r\n // apply material\r\n material.use();\r\n\r\n this._layout.shader = shader;\r\n // apply layout and geometry\r\n this._layout.use(true);\r\n\r\n // apply time in ms since the page (performance.now())\r\n shader.trySetUniformFloat('u_time_ms', performance.now());\r\n\r\n // apply opacity\r\n shader.trySetUniformFloat('u_opacity', opacity);\r\n\r\n // apply resolution\r\n shader.trySetUniformFloatVector('u_resolution', vec(this._context.width, this._context.height));\r\n\r\n // apply graphic resolution\r\n shader.trySetUniformFloatVector('u_graphic_resolution', vec(imageWidth, imageHeight));\r\n\r\n // apply size\r\n shader.trySetUniformFloatVector('u_size', vec(sw, sh));\r\n\r\n // apply orthographic projection\r\n shader.trySetUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // apply geometry transform\r\n shader.trySetUniformMatrix('u_transform', transform.to4x4());\r\n\r\n // bind graphic image texture 'uniform sampler2D u_graphic;'\r\n gl.activeTexture(gl.TEXTURE0 + 0);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n shader.trySetUniformInt('u_graphic', 0);\r\n\r\n // bind the screen texture\r\n gl.activeTexture(gl.TEXTURE0 + 1);\r\n gl.bindTexture(gl.TEXTURE_2D, this._context.materialScreenTexture);\r\n shader.trySetUniformInt('u_screen_texture', 1);\r\n\r\n // bind any additional textures in the material\r\n material.uploadAndBind(gl);\r\n\r\n // bind quad index buffer\r\n this._quads.bind();\r\n\r\n // Draw a single quad\r\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount++;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n }\r\n\r\n private _addImageAsTexture(image: HTMLImageSource) {\r\n const maybeFiltering = image.getAttribute('filtering');\r\n let filtering: ImageFiltering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n\r\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._context.textureLoader.load(image, filtering, force);\r\n // remove force attribute after upload\r\n image.removeAttribute('forceUpload');\r\n if (this._textures.indexOf(texture) === -1) {\r\n this._textures.push(texture);\r\n }\r\n\r\n return texture;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return false;\r\n }\r\n flush(): void {\r\n // flush does not do anything, material renderer renders immediately per draw\r\n }\r\n\r\n}","import {\r\n ExcaliburGraphicsContext,\r\n LineGraphicsOptions,\r\n RectGraphicsOptions,\r\n PointGraphicsOptions,\r\n ExcaliburGraphicsContextOptions,\r\n DebugDraw,\r\n HTMLImageSource\r\n} from './ExcaliburGraphicsContext';\r\n\r\nimport { Matrix } from '../../Math/matrix';\r\nimport { TransformStack } from './transform-stack';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Color } from '../../Color';\r\nimport { StateStack } from './state-stack';\r\nimport { Logger } from '../../Util/Log';\r\nimport { DebugText } from './debug-text';\r\nimport { ScreenDimension } from '../../Screen';\r\nimport { RenderTarget } from './render-target';\r\nimport { PostProcessor } from '../PostProcessor/PostProcessor';\r\nimport { TextureLoader } from './texture-loader';\r\nimport { RendererPlugin } from './renderer';\r\n\r\n// renderers\r\nimport { LineRenderer } from './line-renderer/line-renderer';\r\nimport { PointRenderer } from './point-renderer/point-renderer';\r\nimport { ScreenPassPainter } from './screen-pass-painter/screen-pass-painter';\r\nimport { ImageRenderer } from './image-renderer/image-renderer';\r\nimport { RectangleRenderer } from './rectangle-renderer/rectangle-renderer';\r\nimport { CircleRenderer } from './circle-renderer/circle-renderer';\r\nimport { Pool } from '../../Util/Pool';\r\nimport { DrawCall } from './draw-call';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Material, MaterialOptions } from './material';\r\nimport { MaterialRenderer } from './material-renderer/material-renderer';\r\nimport { Shader, ShaderOptions } from './shader';\r\n\r\nexport const pixelSnapEpsilon = 0.0001;\r\n\r\nclass ExcaliburGraphicsContextWebGLDebug implements DebugDraw {\r\n private _debugText = new DebugText();\r\n constructor(private _webglCtx: ExcaliburGraphicsContextWebGL) {}\r\n\r\n /**\r\n * Draw a debugging rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */\r\n drawRect(x: number, y: number, width: number, height: number, rectOptions: RectGraphicsOptions = { color: Color.Black }): void {\r\n this.drawLine(vec(x, y), vec(x + width, y), { ...rectOptions });\r\n this.drawLine(vec(x + width, y), vec(x + width, y + height), { ...rectOptions });\r\n this.drawLine(vec(x + width, y + height), vec(x, y + height), { ...rectOptions });\r\n this.drawLine(vec(x, y + height), vec(x, y), { ...rectOptions });\r\n }\r\n\r\n /**\r\n * Draw a debugging line to the context\r\n * @param start\r\n * @param end\r\n * @param lineOptions\r\n */\r\n drawLine(start: Vector, end: Vector, lineOptions: LineGraphicsOptions = { color: Color.Black }): void {\r\n this._webglCtx.draw('ex.line', start, end, lineOptions.color);\r\n }\r\n\r\n /**\r\n * Draw a debugging point to the context\r\n * @param point\r\n * @param pointOptions\r\n */\r\n drawPoint(point: Vector, pointOptions: PointGraphicsOptions = { color: Color.Black, size: 5 }): void {\r\n this._webglCtx.draw('ex.point', point, pointOptions.color, pointOptions.size);\r\n }\r\n\r\n drawText(text: string, pos: Vector) {\r\n this._debugText.write(this._webglCtx, text, pos);\r\n }\r\n}\r\n\r\nexport interface WebGLGraphicsContextInfo {\r\n transform: TransformStack;\r\n state: StateStack;\r\n ortho: Matrix;\r\n context: ExcaliburGraphicsContextWebGL;\r\n}\r\n\r\nexport interface ExcaliburGraphicsContextWebGLOptions extends ExcaliburGraphicsContextOptions {\r\n context?: WebGL2RenderingContext\r\n}\r\n\r\nexport class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext {\r\n private _logger = Logger.getInstance();\r\n private _renderers: Map = new Map();\r\n private _isDrawLifecycle = false;\r\n public useDrawSorting = true;\r\n\r\n private _drawCallPool = new Pool(\r\n () => new DrawCall(),\r\n (instance) => {\r\n instance.priority = 0;\r\n instance.z = 0;\r\n instance.renderer = undefined;\r\n instance.args = undefined;\r\n return instance;\r\n }, 4000);\r\n private _drawCalls: DrawCall[] = [];\r\n\r\n // Main render target\r\n private _renderTarget: RenderTarget;\r\n\r\n // Quad boundary MSAA\r\n private _msaaTarget: RenderTarget;\r\n\r\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\r\n private _postProcessTargets: RenderTarget[] = [];\r\n\r\n private _screenRenderer: ScreenPassPainter;\r\n\r\n private _postprocessors: PostProcessor[] = [];\r\n /**\r\n * Meant for internal use only. Access the internal context at your own risk and no guarantees this will exist in the future.\r\n * @internal\r\n */\r\n public __gl: WebGL2RenderingContext;\r\n\r\n private _transform = new TransformStack();\r\n private _state = new StateStack();\r\n private _ortho!: Matrix;\r\n\r\n /**\r\n * Snaps the drawing x/y coordinate to the nearest whole pixel\r\n */\r\n public snapToPixel: boolean = false;\r\n\r\n /**\r\n * Native context smoothing\r\n */\r\n public readonly smoothing: boolean = false;\r\n\r\n\r\n /**\r\n * Whether the pixel art sampler is enabled for smooth sub pixel anti-aliasing\r\n */\r\n public readonly pixelArtSampler: boolean = false;\r\n\r\n /**\r\n * UV padding in pixels to use in internal image rendering to prevent texture bleed\r\n *\r\n */\r\n public uvPadding = .01;\r\n\r\n public backgroundColor: Color = Color.ExcaliburBlue;\r\n\r\n public textureLoader: TextureLoader;\r\n\r\n public materialScreenTexture: WebGLTexture;\r\n\r\n public get z(): number {\r\n return this._state.current.z;\r\n }\r\n\r\n public set z(value: number) {\r\n this._state.current.z = value;\r\n }\r\n\r\n public get opacity(): number {\r\n return this._state.current.opacity;\r\n }\r\n\r\n public set opacity(value: number) {\r\n this._state.current.opacity = value;\r\n }\r\n\r\n public get tint(): Color {\r\n return this._state.current.tint;\r\n }\r\n\r\n public set tint(color: Color) {\r\n this._state.current.tint = color;\r\n }\r\n\r\n public get width() {\r\n return this.__gl.canvas.width;\r\n }\r\n\r\n public get height() {\r\n return this.__gl.canvas.height;\r\n }\r\n\r\n public get ortho(): Matrix {\r\n return this._ortho;\r\n }\r\n\r\n /**\r\n * Checks the underlying webgl implementation if the requested internal resolution is supported\r\n * @param dim\r\n */\r\n public checkIfResolutionSupported(dim: ScreenDimension): boolean {\r\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\r\n let supported = true;\r\n if (dim.width > 4096 || dim.height > 4096) {\r\n supported = false;\r\n }\r\n return supported;\r\n }\r\n\r\n public readonly multiSampleAntialiasing: boolean = true;\r\n public readonly samples?: number;\r\n public readonly transparency: boolean = true;\r\n\r\n constructor(options: ExcaliburGraphicsContextWebGLOptions) {\r\n const {\r\n canvasElement,\r\n context,\r\n enableTransparency,\r\n antialiasing,\r\n uvPadding,\r\n multiSampleAntialiasing,\r\n pixelArtSampler,\r\n powerPreference,\r\n snapToPixel,\r\n backgroundColor,\r\n useDrawSorting\r\n } = options;\r\n this.__gl = context ?? canvasElement.getContext('webgl2', {\r\n antialias: antialiasing ?? this.smoothing,\r\n premultipliedAlpha: false,\r\n alpha: enableTransparency ?? this.transparency,\r\n depth: false,\r\n powerPreference: powerPreference ?? 'high-performance'\r\n });\r\n if (!this.__gl) {\r\n throw Error('Failed to retrieve webgl context from browser');\r\n }\r\n this.textureLoader = new TextureLoader(this.__gl);\r\n this.snapToPixel = snapToPixel ?? this.snapToPixel;\r\n this.smoothing = antialiasing ?? this.smoothing;\r\n this.transparency = enableTransparency ?? this.transparency;\r\n this.pixelArtSampler = pixelArtSampler ?? this.pixelArtSampler;\r\n this.uvPadding = uvPadding ?? this.uvPadding;\r\n this.multiSampleAntialiasing = typeof multiSampleAntialiasing === 'boolean' ? multiSampleAntialiasing : this.multiSampleAntialiasing;\r\n this.samples = typeof multiSampleAntialiasing === 'object' ? multiSampleAntialiasing.samples : undefined;\r\n this.backgroundColor = backgroundColor ?? this.backgroundColor;\r\n this.useDrawSorting = useDrawSorting ?? this.useDrawSorting;\r\n this._drawCallPool.disableWarnings = true;\r\n this._drawCallPool.preallocate();\r\n this._init();\r\n }\r\n\r\n private _disposed = false;\r\n public dispose() {\r\n if (!this._disposed) {\r\n this._disposed = true;\r\n this.textureLoader.dispose();\r\n for (const renderer of this._renderers.values()) {\r\n renderer.dispose();\r\n }\r\n this._renderers.clear();\r\n this._drawCallPool.dispose();\r\n this._drawCalls.length = 0;\r\n this.__gl = null;\r\n }\r\n }\r\n\r\n private _init() {\r\n const gl = this.__gl;\r\n // Setup viewport and view matrix\r\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\r\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\r\n\r\n // Clear background\r\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\r\n gl.clear(gl.COLOR_BUFFER_BIT);\r\n\r\n // Enable alpha blending\r\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\r\n gl.enable(gl.BLEND);\r\n gl.blendEquation(gl.FUNC_ADD);\r\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\r\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n\r\n // Setup builtin renderers\r\n this.register(new ImageRenderer({\r\n uvPadding: this.uvPadding,\r\n pixelArtSampler: this.pixelArtSampler\r\n }));\r\n this.register(new MaterialRenderer());\r\n this.register(new RectangleRenderer());\r\n this.register(new CircleRenderer());\r\n this.register(new PointRenderer());\r\n this.register(new LineRenderer());\r\n\r\n\r\n this.materialScreenTexture = gl.createTexture();\r\n gl.bindTexture(gl.TEXTURE_2D, this.materialScreenTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n\r\n this._screenRenderer = new ScreenPassPainter(gl);\r\n\r\n this._renderTarget = new RenderTarget({\r\n gl,\r\n transparency: this.transparency,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n });\r\n\r\n this._postProcessTargets = [\r\n new RenderTarget({\r\n gl,\r\n transparency: this.transparency,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n }),\r\n new RenderTarget({\r\n gl,\r\n transparency: this.transparency,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n })\r\n ];\r\n\r\n this._msaaTarget = new RenderTarget({\r\n gl,\r\n transparency: this.transparency,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height,\r\n antialias: this.multiSampleAntialiasing,\r\n samples: this.samples\r\n });\r\n }\r\n\r\n public register(renderer: T) {\r\n this._renderers.set(renderer.type, renderer);\r\n renderer.initialize(this.__gl, this);\r\n }\r\n\r\n public get(rendererName: string): RendererPlugin {\r\n return this._renderers.get(rendererName);\r\n }\r\n\r\n private _currentRenderer: RendererPlugin;\r\n\r\n private _isCurrentRenderer(renderer: RendererPlugin): boolean {\r\n if (!this._currentRenderer || this._currentRenderer === renderer) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n public beginDrawLifecycle() {\r\n this._isDrawLifecycle = true;\r\n }\r\n\r\n public endDrawLifecycle() {\r\n this._isDrawLifecycle = false;\r\n }\r\n\r\n public draw(rendererName: TRenderer['type'], ...args: Parameters) {\r\n if (!this._isDrawLifecycle) {\r\n this._logger.warnOnce(\r\n `Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` +\r\n `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\r\n }\r\n\r\n const renderer = this._renderers.get(rendererName);\r\n if (renderer) {\r\n if (this.useDrawSorting) {\r\n const drawCall = this._drawCallPool.get();\r\n drawCall.z = this._state.current.z;\r\n drawCall.priority = renderer.priority;\r\n drawCall.renderer = rendererName;\r\n this.getTransform().clone(drawCall.transform);\r\n drawCall.state.z = this._state.current.z;\r\n drawCall.state.opacity = this._state.current.opacity;\r\n drawCall.state.tint = this._state.current.tint;\r\n drawCall.state.material = this._state.current.material;\r\n drawCall.args = args;\r\n this._drawCalls.push(drawCall);\r\n } else {\r\n // Set the current renderer if not defined\r\n if (!this._currentRenderer) {\r\n this._currentRenderer = renderer;\r\n }\r\n\r\n if (!this._isCurrentRenderer(renderer)) {\r\n // switching graphics means we must flush the previous\r\n this._currentRenderer.flush();\r\n }\r\n\r\n // If we are still using the same renderer we can add to the current batch\r\n renderer.draw(...args);\r\n\r\n this._currentRenderer = renderer;\r\n }\r\n } else {\r\n throw Error(`No renderer with name ${rendererName} has been registered`);\r\n }\r\n }\r\n\r\n public resetTransform(): void {\r\n this._transform.current = AffineMatrix.identity();\r\n }\r\n\r\n public updateViewport(resolution: ScreenDimension): void {\r\n const gl = this.__gl;\r\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\r\n\r\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\r\n this._msaaTarget.setResolution(gl.canvas.width, gl.canvas.height);\r\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\r\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\r\n }\r\n\r\n drawImage(image: HTMLImageSource, x: number, y: number): void;\r\n drawImage(image: HTMLImageSource, x: number, y: number, width: number, height: number): void;\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void;\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void {\r\n if (swidth === 0 || sheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (dwidth === 0 || dheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (image.width === 0 || image.height === 0) {\r\n return; // zero dimension source exit early\r\n }\r\n\r\n if (!image) {\r\n Logger.getInstance().warn('Cannot draw a null or undefined image');\r\n // tslint:disable-next-line: no-console\r\n if (console.trace) {\r\n // tslint:disable-next-line: no-console\r\n console.trace();\r\n }\r\n return;\r\n }\r\n\r\n if (this._state.current.material) {\r\n this.draw('ex.material', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\r\n } else {\r\n this.draw('ex.image', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\r\n }\r\n }\r\n\r\n public drawLine(start: Vector, end: Vector, color: Color, thickness = 1) {\r\n this.draw('ex.rectangle', start, end, color, thickness);\r\n }\r\n\r\n public drawRectangle(pos: Vector, width: number, height: number, color: Color, stroke?: Color, strokeThickness?: number) {\r\n this.draw('ex.rectangle', pos, width, height, color, stroke, strokeThickness);\r\n }\r\n\r\n public drawCircle(pos: Vector, radius: number, color: Color, stroke?: Color, thickness?: number) {\r\n this.draw('ex.circle', pos, radius, color, stroke, thickness);\r\n }\r\n\r\n debug = new ExcaliburGraphicsContextWebGLDebug(this);\r\n\r\n public save(): void {\r\n this._transform.save();\r\n this._state.save();\r\n }\r\n\r\n public restore(): void {\r\n this._transform.restore();\r\n this._state.restore();\r\n }\r\n\r\n public translate(x: number, y: number): void {\r\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\r\n }\r\n\r\n public rotate(angle: number): void {\r\n this._transform.rotate(angle);\r\n }\r\n\r\n public scale(x: number, y: number): void {\r\n this._transform.scale(x, y);\r\n }\r\n\r\n public transform(matrix: AffineMatrix) {\r\n this._transform.current = matrix;\r\n }\r\n\r\n public getTransform(): AffineMatrix {\r\n return this._transform.current;\r\n }\r\n\r\n public multiply(m: AffineMatrix) {\r\n this._transform.current.multiply(m, this._transform.current);\r\n }\r\n\r\n public addPostProcessor(postprocessor: PostProcessor) {\r\n this._postprocessors.push(postprocessor);\r\n postprocessor.initialize(this.__gl);\r\n }\r\n\r\n public removePostProcessor(postprocessor: PostProcessor) {\r\n const index = this._postprocessors.indexOf(postprocessor);\r\n if (index !== -1) {\r\n this._postprocessors.splice(index, 1);\r\n }\r\n }\r\n\r\n public clearPostProcessors() {\r\n this._postprocessors.length = 0;\r\n }\r\n\r\n private _totalPostProcessorTime = 0;\r\n public updatePostProcessors(delta: number) {\r\n for (const postprocessor of this._postprocessors) {\r\n const shader = postprocessor.getShader();\r\n shader.use();\r\n const uniforms = shader.getUniforms();\r\n this._totalPostProcessorTime += delta;\r\n\r\n if (uniforms.find(u => u.name ==='u_time_ms')) {\r\n shader.setUniformFloat('u_time_ms', this._totalPostProcessorTime);\r\n }\r\n if (uniforms.find(u => u.name ==='u_elapsed_ms')) {\r\n shader.setUniformFloat('u_elapsed_ms', delta);\r\n }\r\n if (uniforms.find(u => u.name ==='u_resolution')) {\r\n shader.setUniformFloatVector('u_resolution', vec(this.width, this.height));\r\n }\r\n\r\n if (postprocessor.onUpdate) {\r\n postprocessor.onUpdate(delta);\r\n }\r\n }\r\n }\r\n\r\n public set material(material: Material) {\r\n this._state.current.material = material;\r\n }\r\n\r\n public get material(): Material | null {\r\n return this._state.current.material;\r\n }\r\n\r\n /**\r\n * Creates and initializes the material which compiles the internal shader\r\n * @param options\r\n * @returns Material\r\n */\r\n public createMaterial(options: Omit): Material {\r\n const material = new Material({...options, graphicsContext: this});\r\n return material;\r\n }\r\n\r\n public createShader(options: Omit): Shader {\r\n const gl = this.__gl;\r\n const { vertexSource, fragmentSource } = options;\r\n const shader = new Shader({\r\n gl,\r\n vertexSource,\r\n fragmentSource\r\n });\r\n shader.compile();\r\n return shader;\r\n }\r\n\r\n clear() {\r\n const gl = this.__gl;\r\n const currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\r\n currentTarget.use();\r\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\r\n // Clear the context with the newly set color. This is\r\n // the function call that actually does the drawing.\r\n gl.clear(gl.COLOR_BUFFER_BIT);\r\n }\r\n\r\n /**\r\n * Flushes all batched rendering to the screen\r\n */\r\n flush() {\r\n // render target captures all draws and redirects to the render target\r\n let currentTarget = this.multiSampleAntialiasing ? this._msaaTarget : this._renderTarget;\r\n currentTarget.use();\r\n\r\n if (this.useDrawSorting) {\r\n // sort draw calls\r\n // Find the original order of the first instance of the draw call\r\n const originalSort = new Map();\r\n for (const [name] of this._renderers) {\r\n const firstIndex = this._drawCalls.findIndex(dc => dc.renderer === name);\r\n originalSort.set(name, firstIndex);\r\n }\r\n\r\n this._drawCalls.sort((a, b) => {\r\n const zIndex = a.z - b.z;\r\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\r\n const priority = a.priority - b.priority;\r\n if (zIndex === 0) { // sort by z first\r\n if (priority === 0) { // sort by priority\r\n return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\r\n }\r\n return priority;\r\n }\r\n return zIndex;\r\n });\r\n\r\n const oldTransform = this._transform.current;\r\n const oldState = this._state.current;\r\n\r\n if (this._drawCalls.length) {\r\n let currentRendererName = this._drawCalls[0].renderer;\r\n let currentRenderer = this._renderers.get(currentRendererName);\r\n for (let i = 0; i < this._drawCalls.length; i++) {\r\n // hydrate the state for renderers\r\n this._transform.current = this._drawCalls[i].transform;\r\n this._state.current = this._drawCalls[i].state;\r\n\r\n if (this._drawCalls[i].renderer !== currentRendererName) {\r\n // switching graphics renderer means we must flush the previous\r\n currentRenderer.flush();\r\n currentRendererName = this._drawCalls[i].renderer;\r\n currentRenderer = this._renderers.get(currentRendererName);\r\n }\r\n\r\n // ! hack to grab screen texture before materials run because they might want it\r\n if (currentRenderer instanceof MaterialRenderer && this.material.isUsingScreenTexture) {\r\n currentTarget.copyToTexture(this.materialScreenTexture);\r\n currentTarget.use();\r\n }\r\n // If we are still using the same renderer we can add to the current batch\r\n currentRenderer.draw(...this._drawCalls[i].args);\r\n }\r\n if (currentRenderer.hasPendingDraws()) {\r\n currentRenderer.flush();\r\n }\r\n }\r\n\r\n // reset state\r\n this._transform.current = oldTransform;\r\n this._state.current = oldState;\r\n\r\n // reclaim draw calls\r\n this._drawCallPool.done();\r\n this._drawCalls.length = 0;\r\n } else {\r\n // This is the final flush at the moment to draw any leftover pending draw\r\n for (const renderer of this._renderers.values()) {\r\n if (renderer.hasPendingDraws()) {\r\n renderer.flush();\r\n }\r\n }\r\n }\r\n\r\n currentTarget.disable();\r\n\r\n // post process step\r\n if (this._postprocessors.length > 0) {\r\n const source = currentTarget.toRenderSource();\r\n source.use();\r\n }\r\n\r\n // flip flop render targets for post processing\r\n for (let i = 0; i < this._postprocessors.length; i++) {\r\n currentTarget = this._postProcessTargets[i % 2];\r\n this._postProcessTargets[i % 2].use();\r\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\r\n this._postProcessTargets[i % 2].toRenderSource().use();\r\n }\r\n\r\n // Final blit to the screen\r\n currentTarget.blitToScreen();\r\n }\r\n}\r\n","import {\r\n ExcaliburGraphicsContext,\r\n LineGraphicsOptions,\r\n PointGraphicsOptions,\r\n ExcaliburGraphicsContextOptions,\r\n DebugDraw,\r\n HTMLImageSource\r\n} from './ExcaliburGraphicsContext';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Color } from '../../Color';\r\nimport { StateStack } from './state-stack';\r\nimport { GraphicsDiagnostics } from '../GraphicsDiagnostics';\r\nimport { DebugText } from './debug-text';\r\nimport { ScreenDimension } from '../../Screen';\r\nimport { PostProcessor } from '../PostProcessor/PostProcessor';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Material, MaterialOptions } from './material';\r\n\r\nconst pixelSnapEpsilon = 0.0001;\r\n\r\nclass ExcaliburGraphicsContext2DCanvasDebug implements DebugDraw {\r\n private _debugText = new DebugText();\r\n constructor(private _ex: ExcaliburGraphicsContext2DCanvas) {}\r\n /**\r\n * Draw a debug rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */\r\n drawRect(x: number, y: number, width: number, height: number): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.strokeStyle = 'red';\r\n this._ex.__ctx.strokeRect(\r\n this._ex.snapToPixel ? ~~(x + pixelSnapEpsilon) : x,\r\n this._ex.snapToPixel ? ~~(y + pixelSnapEpsilon) : y,\r\n this._ex.snapToPixel ? ~~(width + pixelSnapEpsilon) : width,\r\n this._ex.snapToPixel ? ~~(height + pixelSnapEpsilon) : height\r\n );\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawLine(start: Vector, end: Vector, lineOptions: LineGraphicsOptions = { color: Color.Black }): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.beginPath();\r\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\r\n this._ex.__ctx.moveTo(\r\n this._ex.snapToPixel ? ~~(start.x + pixelSnapEpsilon) : start.x,\r\n this._ex.snapToPixel ? ~~(start.y + pixelSnapEpsilon) : start.y\r\n );\r\n this._ex.__ctx.lineTo(\r\n this._ex.snapToPixel ? ~~(end.x + pixelSnapEpsilon) : end.x,\r\n this._ex.snapToPixel ? ~~(end.y + pixelSnapEpsilon) : end.y\r\n );\r\n this._ex.__ctx.lineWidth = 2;\r\n this._ex.__ctx.stroke();\r\n this._ex.__ctx.closePath();\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawPoint(point: Vector, pointOptions: PointGraphicsOptions = { color: Color.Black, size: 5 }): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.beginPath();\r\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\r\n this._ex.__ctx.arc(\r\n this._ex.snapToPixel ? ~~(point.x + pixelSnapEpsilon) : point.x,\r\n this._ex.snapToPixel ? ~~(point.y + pixelSnapEpsilon) : point.y,\r\n pointOptions.size,\r\n 0,\r\n Math.PI * 2\r\n );\r\n this._ex.__ctx.fill();\r\n this._ex.__ctx.closePath();\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawText(text: string, pos: Vector) {\r\n this._debugText.write(this._ex, text, pos);\r\n }\r\n}\r\n\r\nexport interface ExcaliburGraphicsContext2DOptions extends ExcaliburGraphicsContextOptions {\r\n context?: CanvasRenderingContext2D;\r\n}\r\n\r\nexport class ExcaliburGraphicsContext2DCanvas implements ExcaliburGraphicsContext {\r\n /**\r\n * Meant for internal use only. Access the internal context at your own risk and no guarantees this will exist in the future.\r\n * @internal\r\n */\r\n public __ctx: CanvasRenderingContext2D;\r\n public get width() {\r\n return this.__ctx.canvas.width;\r\n }\r\n\r\n public get height() {\r\n return this.__ctx.canvas.height;\r\n }\r\n\r\n /**\r\n * Unused in Canvas implementation\r\n */\r\n public readonly useDrawSorting: boolean = false;\r\n\r\n /**\r\n * Unused in Canvas implementation\r\n */\r\n public z: number = 0;\r\n\r\n public backgroundColor: Color = Color.ExcaliburBlue;\r\n\r\n private _state = new StateStack();\r\n\r\n public get opacity(): number {\r\n return this._state.current.opacity;\r\n }\r\n\r\n public set opacity(value: number) {\r\n this._state.current.opacity = value;\r\n }\r\n\r\n public get tint(): Color {\r\n return this._state.current.tint;\r\n }\r\n\r\n public set tint(color: Color) {\r\n this._state.current.tint = color;\r\n }\r\n\r\n public snapToPixel: boolean = false;\r\n\r\n public get smoothing(): boolean {\r\n return this.__ctx.imageSmoothingEnabled;\r\n }\r\n\r\n public set smoothing(value: boolean) {\r\n this.__ctx.imageSmoothingEnabled = value;\r\n }\r\n\r\n constructor(options: ExcaliburGraphicsContext2DOptions) {\r\n const { canvasElement, context, enableTransparency, snapToPixel, antialiasing: smoothing, backgroundColor } = options;\r\n this.__ctx = context ?? canvasElement.getContext('2d', {\r\n alpha: enableTransparency ?? true\r\n });\r\n if (!this.__ctx) {\r\n throw new Error('Cannot build new ExcaliburGraphicsContext2D for some reason!');\r\n }\r\n this.backgroundColor = backgroundColor ?? this.backgroundColor;\r\n this.snapToPixel = snapToPixel ?? this.snapToPixel;\r\n this.smoothing = smoothing ?? this.smoothing;\r\n }\r\n\r\n public resetTransform(): void {\r\n this.__ctx.resetTransform();\r\n }\r\n\r\n public updateViewport(_resolution: ScreenDimension): void {\r\n // pass\r\n }\r\n\r\n /**\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate using the images width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate with a specific width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number, width: number, height: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context specifying the source image coordinates (sx, sy, swidth, sheight)\r\n * and to a specific destination on the context (dx, dy, dwidth, dheight)\r\n */\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void;\r\n\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void {\r\n if (swidth === 0 || sheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (dwidth === 0 || dheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (image.width === 0 || image.height === 0) {\r\n return; // zero dimension source exit early\r\n }\r\n\r\n this.__ctx.globalAlpha = this.opacity;\r\n const args = [image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight]\r\n .filter((a) => a !== undefined)\r\n .map((a) => (typeof a === 'number' && this.snapToPixel ? ~~a : a));\r\n this.__ctx.drawImage.apply(this.__ctx, args);\r\n GraphicsDiagnostics.DrawCallCount++;\r\n GraphicsDiagnostics.DrawnImagesCount = 1;\r\n }\r\n\r\n public drawLine(start: Vector, end: Vector, color: Color, thickness = 1) {\r\n this.__ctx.save();\r\n this.__ctx.beginPath();\r\n this.__ctx.strokeStyle = color.toString();\r\n this.__ctx.moveTo(\r\n this.snapToPixel ? ~~ (start.x + pixelSnapEpsilon) : start.x,\r\n this.snapToPixel ? ~~(start.y + pixelSnapEpsilon) : start.y\r\n );\r\n this.__ctx.lineTo(\r\n this.snapToPixel ? ~~ (end.x + pixelSnapEpsilon) : end.x,\r\n this.snapToPixel ? ~~(end.y + pixelSnapEpsilon) : end.y\r\n );\r\n this.__ctx.lineWidth = thickness;\r\n this.__ctx.stroke();\r\n this.__ctx.closePath();\r\n this.__ctx.restore();\r\n }\r\n\r\n public drawRectangle(pos: Vector, width: number, height: number, color: Color) {\r\n this.__ctx.save();\r\n this.__ctx.fillStyle = color.toString();\r\n this.__ctx.fillRect(\r\n this.snapToPixel ? ~~(pos.x + pixelSnapEpsilon) : pos.x,\r\n this.snapToPixel ? ~~(pos.y + pixelSnapEpsilon) : pos.y,\r\n this.snapToPixel ? ~~(width + pixelSnapEpsilon) : width,\r\n this.snapToPixel ? ~~(height + pixelSnapEpsilon) : height\r\n );\r\n this.__ctx.restore();\r\n }\r\n\r\n public drawCircle(pos: Vector, radius: number, color: Color, stroke?: Color, thickness?: number) {\r\n this.__ctx.save();\r\n this.__ctx.beginPath();\r\n if (stroke) {\r\n this.__ctx.strokeStyle = stroke.toString();\r\n }\r\n if (thickness) {\r\n this.__ctx.lineWidth = thickness;\r\n }\r\n this.__ctx.fillStyle = color.toString();\r\n this.__ctx.arc(\r\n this.snapToPixel ? ~~(pos.x + pixelSnapEpsilon) : pos.x,\r\n this.snapToPixel ? ~~(pos.y + pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2\r\n );\r\n this.__ctx.fill();\r\n if (stroke) {\r\n this.__ctx.stroke();\r\n }\r\n this.__ctx.closePath();\r\n this.__ctx.restore();\r\n }\r\n\r\n debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\r\n\r\n /**\r\n * Save the current state of the canvas to the stack (transforms and opacity)\r\n */\r\n save(): void {\r\n this.__ctx.save();\r\n this._state.save();\r\n }\r\n\r\n /**\r\n * Restore the state of the canvas from the stack\r\n */\r\n restore(): void {\r\n this.__ctx.restore();\r\n this._state.restore();\r\n }\r\n\r\n /**\r\n * Translate the origin of the context by an x and y\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number): void {\r\n this.__ctx.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\r\n }\r\n\r\n /**\r\n * Rotate the context about the current origin\r\n */\r\n rotate(angle: number): void {\r\n this.__ctx.rotate(angle);\r\n }\r\n\r\n /**\r\n * Scale the context by an x and y factor\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number): void {\r\n this.__ctx.scale(x, y);\r\n }\r\n\r\n public getTransform(): AffineMatrix {\r\n throw new Error('Not implemented');\r\n }\r\n\r\n public multiply(_m: AffineMatrix): void {\r\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\r\n }\r\n\r\n public addPostProcessor(_postprocessor: PostProcessor) {\r\n // pass\r\n }\r\n\r\n public removePostProcessor(_postprocessor: PostProcessor) {\r\n // pass\r\n }\r\n\r\n public clearPostProcessors() {\r\n // pass\r\n }\r\n\r\n public updatePostProcessors(delta: number) {\r\n // pass\r\n }\r\n\r\n public beginDrawLifecycle() {\r\n // pass\r\n }\r\n\r\n public endDrawLifecycle() {\r\n // pass\r\n }\r\n\r\n public set material(material: Material | null) {\r\n this._state.current.material = material;\r\n }\r\n\r\n public get material(): Material | null {\r\n return this._state.current.material;\r\n }\r\n\r\n public createMaterial(options: Omit): Material {\r\n // pass\r\n return null;\r\n }\r\n\r\n clear(): void {\r\n // Clear frame\r\n this.__ctx.clearRect(0, 0, this.width, this.height);\r\n this.__ctx.fillStyle = this.backgroundColor.toString();\r\n this.__ctx.fillRect(0, 0, this.width, this.height);\r\n GraphicsDiagnostics.clear();\r\n }\r\n\r\n /**\r\n * Flushes the batched draw calls to the screen\r\n */\r\n flush(): void {\r\n // pass\r\n }\r\n\r\n dispose(): void {\r\n this.__ctx = null;\r\n }\r\n}\r\n","import { vec, Vector } from './Math/vector';\r\nimport { Logger } from './Util/Log';\r\nimport { Camera } from './Camera';\r\nimport { BrowserEvents } from './Util/Browser';\r\nimport { BoundingBox } from './Collision/Index';\r\nimport { ExcaliburGraphicsContext } from './Graphics/Context/ExcaliburGraphicsContext';\r\nimport { getPosition } from './Util/Util';\r\nimport { ExcaliburGraphicsContextWebGL } from './Graphics/Context/ExcaliburGraphicsContextWebGL';\r\nimport { ExcaliburGraphicsContext2DCanvas } from './Graphics/Context/ExcaliburGraphicsContext2DCanvas';\r\nimport { EventEmitter } from './EventEmitter';\r\n\r\n/**\r\n * Enum representing the different display modes available to Excalibur.\r\n */\r\nexport enum DisplayMode {\r\n /**\r\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\r\n */\r\n Fixed = 'Fixed',\r\n\r\n /**\r\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\r\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */\r\n FitContainerAndFill = 'FitContainerAndFill',\r\n\r\n /**\r\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\r\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */\r\n FitScreenAndFill = 'FitScreenAndFill',\r\n\r\n /**\r\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitContainer]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */\r\n FitContainerAndZoom = 'FitContainerAndZoom',\r\n\r\n /**\r\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitScreen]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */\r\n FitScreenAndZoom = 'FitScreenAndZoom',\r\n\r\n /**\r\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\r\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\r\n *\r\n * You may want to center your game here is an example\r\n * ```html\r\n * \r\n * \r\n *
\r\n * \r\n *
\r\n * \r\n * ```\r\n *\r\n * ```css\r\n * // css\r\n * main {\r\n * display: flex;\r\n * align-items: center;\r\n * justify-content: center;\r\n * height: 100%;\r\n * width: 100%;\r\n * }\r\n * ```\r\n */\r\n FitScreen = 'FitScreen',\r\n\r\n /**\r\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\r\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\r\n */\r\n FillScreen = 'FillScreen',\r\n\r\n /**\r\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\r\n */\r\n FitContainer = 'FitContainer',\r\n\r\n /**\r\n * Use the parent DOM container's css width/height for the game resolution dynamically\r\n */\r\n FillContainer = 'FillContainer'\r\n}\r\n\r\n/**\r\n * Convenience class for quick resolutions\r\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\r\n */\r\nexport class Resolution {\r\n /* istanbul ignore next */\r\n public static get SVGA(): ScreenDimension {\r\n return { width: 800, height: 600 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get Standard(): ScreenDimension {\r\n return { width: 1920, height: 1080 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get Atari2600(): ScreenDimension {\r\n return { width: 160, height: 192 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get GameBoy(): ScreenDimension {\r\n return { width: 160, height: 144 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get GameBoyAdvance(): ScreenDimension {\r\n return { width: 240, height: 160 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get NintendoDS(): ScreenDimension {\r\n return { width: 256, height: 192 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get NES(): ScreenDimension {\r\n return { width: 256, height: 224 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get SNES(): ScreenDimension {\r\n return { width: 256, height: 244 };\r\n }\r\n}\r\n\r\nexport interface ScreenDimension {\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface ScreenOptions {\r\n /**\r\n * Canvas element to build a screen on\r\n */\r\n canvas: HTMLCanvasElement;\r\n\r\n /**\r\n * Graphics context for the screen\r\n */\r\n context: ExcaliburGraphicsContext;\r\n\r\n /**\r\n * Browser abstraction\r\n */\r\n browser: BrowserEvents;\r\n /**\r\n * Optionally set antialiasing, defaults to true. If set to true, images will be smoothed\r\n */\r\n antialiasing?: boolean;\r\n\r\n /**\r\n * Optionally set the image rendering CSS hint on the canvas element, default is auto\r\n */\r\n canvasImageRendering?: 'auto' | 'pixelated';\r\n /**\r\n * Optionally override the pixel ratio to use for the screen, otherwise calculated automatically from the browser\r\n */\r\n pixelRatio?: number;\r\n /**\r\n * Optionally specify the actual pixel resolution in width/height pixels (also known as logical resolution), by default the\r\n * resolution will be the same as the viewport. Resolution will be overridden by [[DisplayMode.FillContainer]] and\r\n * [[DisplayMode.FillScreen]].\r\n */\r\n resolution?: ScreenDimension;\r\n /**\r\n * Visual viewport size in css pixel, if resolution is not specified it will be the same as the viewport\r\n */\r\n viewport: ScreenDimension;\r\n /**\r\n * Set the display mode of the screen, by default DisplayMode.Fixed.\r\n */\r\n displayMode?: DisplayMode;\r\n}\r\n\r\n/**\r\n * Fires when the screen resizes, useful if you have logic that needs to be aware of resolution/viewport constraints\r\n */\r\nexport interface ScreenResizeEvent {\r\n /**\r\n * Current viewport in css pixels of the screen\r\n */\r\n viewport: ScreenDimension;\r\n /**\r\n * Current resolution in world pixels of the screen\r\n */\r\n resolution: ScreenDimension;\r\n}\r\n\r\n/**\r\n * Fires when the pixel ratio changes, useful to know if you've moved to a hidpi screen or back\r\n */\r\nexport interface PixelRatioChangeEvent {\r\n /**\r\n * Current pixel ratio of the screen\r\n */\r\n pixelRatio: number;\r\n}\r\n\r\n/**\r\n * Fires when the browser fullscreen api is successfully engaged or disengaged\r\n */\r\nexport interface FullScreenChangeEvent {\r\n /**\r\n * Current fullscreen state\r\n */\r\n fullscreen: boolean;\r\n}\r\n\r\n/**\r\n * Built in events supported by all entities\r\n */\r\nexport type ScreenEvents = {\r\n /**\r\n * Fires when the screen resizes, useful if you have logic that needs to be aware of resolution/viewport constraints\r\n */\r\n 'resize': ScreenResizeEvent;\r\n /**\r\n * Fires when the pixel ratio changes, useful to know if you've moved to a hidpi screen or back\r\n */\r\n 'pixelratio': PixelRatioChangeEvent;\r\n /**\r\n * Fires when the browser fullscreen api is successfully engaged or disengaged\r\n */\r\n 'fullscreen': FullScreenChangeEvent;\r\n};\r\n\r\nexport const ScreenEvents = {\r\n ScreenResize: 'resize',\r\n PixelRatioChange: 'pixelratio',\r\n FullScreenChange: 'fullscreen'\r\n} as const;\r\n\r\n/**\r\n * The Screen handles all aspects of interacting with the screen for Excalibur.\r\n */\r\nexport class Screen {\r\n public graphicsContext: ExcaliburGraphicsContext;\r\n /**\r\n * Listen to screen events [[ScreenEvents]]\r\n */\r\n public events = new EventEmitter();\r\n private _canvas: HTMLCanvasElement;\r\n private _antialiasing: boolean = true;\r\n private _canvasImageRendering: 'auto' | 'pixelated' = 'auto';\r\n private _contentResolution: ScreenDimension;\r\n private _browser: BrowserEvents;\r\n private _camera: Camera;\r\n private _resolution: ScreenDimension;\r\n private _resolutionStack: ScreenDimension[] = [];\r\n private _viewport: ScreenDimension;\r\n private _viewportStack: ScreenDimension[] = [];\r\n private _pixelRatioOverride: number | null = null;\r\n private _displayMode: DisplayMode;\r\n private _isFullScreen = false;\r\n private _mediaQueryList: MediaQueryList;\r\n private _isDisposed = false;\r\n private _logger = Logger.getInstance();\r\n private _resizeObserver: ResizeObserver;\r\n\r\n constructor(options: ScreenOptions) {\r\n this.viewport = options.viewport;\r\n this.resolution = options.resolution ?? { ...this.viewport };\r\n this._contentResolution = this.resolution;\r\n this._displayMode = options.displayMode ?? DisplayMode.Fixed;\r\n this._canvas = options.canvas;\r\n this.graphicsContext = options.context;\r\n this._antialiasing = options.antialiasing ?? this._antialiasing;\r\n this._canvasImageRendering = options.canvasImageRendering ?? this._canvasImageRendering;\r\n this._browser = options.browser;\r\n this._pixelRatioOverride = options.pixelRatio;\r\n\r\n this._applyDisplayMode();\r\n\r\n this._listenForPixelRatio();\r\n\r\n this._canvas.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n this.applyResolutionAndViewport();\r\n }\r\n\r\n private _listenForPixelRatio() {\r\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) {\r\n // Safari <=13.1 workaround, remove any existing handlers\r\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\r\n }\r\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\r\n\r\n // Safari <=13.1 workaround\r\n if (this._mediaQueryList.addEventListener) {\r\n this._mediaQueryList.addEventListener('change', this._pixelRatioChangeHandler, { once: true });\r\n } else {\r\n this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\r\n }\r\n }\r\n\r\n public dispose(): void {\r\n if (!this._isDisposed) {\r\n // Clean up handlers\r\n this._isDisposed = true;\r\n this.events.clear();\r\n this._browser.window.off('resize', this._resizeHandler);\r\n this._browser.window.clear();\r\n if (this._resizeObserver) {\r\n this._resizeObserver.disconnect();\r\n }\r\n this.parent.removeEventListener('resize', this._resizeHandler);\r\n // Safari <=13.1 workaround\r\n if (this._mediaQueryList.removeEventListener) {\r\n this._mediaQueryList.removeEventListener('change', this._pixelRatioChangeHandler);\r\n } else {\r\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\r\n }\r\n this._canvas.removeEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n this._canvas = null;\r\n }\r\n }\r\n\r\n private _fullscreenChangeHandler = () => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._isFullScreen = !this._isFullScreen;\r\n this._logger.debug('Fullscreen Change', this._isFullScreen);\r\n this.events.emit('fullscreen', {\r\n fullscreen: this.isFullScreen\r\n } satisfies FullScreenChangeEvent);\r\n };\r\n\r\n private _pixelRatioChangeHandler = () => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._logger.debug('Pixel Ratio Change', window.devicePixelRatio);\r\n this._listenForPixelRatio();\r\n this._devicePixelRatio = this._calculateDevicePixelRatio();\r\n this.applyResolutionAndViewport();\r\n this.events.emit('pixelratio', {\r\n pixelRatio: this.pixelRatio\r\n } satisfies PixelRatioChangeEvent);\r\n };\r\n\r\n private _resizeHandler = () => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n const parent = this.parent;\r\n this._logger.debug('View port resized');\r\n this._setResolutionAndViewportByDisplayMode(parent);\r\n this.applyResolutionAndViewport();\r\n // Emit resize event\r\n this.events.emit('resize', {\r\n resolution: this.resolution,\r\n viewport: this.viewport\r\n } satisfies ScreenResizeEvent);\r\n };\r\n\r\n private _calculateDevicePixelRatio() {\r\n if (window.devicePixelRatio < 1) {\r\n return 1;\r\n }\r\n\r\n const devicePixelRatio = window.devicePixelRatio || 1;\r\n\r\n return devicePixelRatio;\r\n }\r\n\r\n // Asking the window.devicePixelRatio is expensive we do it once\r\n private _devicePixelRatio = this._calculateDevicePixelRatio();\r\n\r\n /**\r\n * Returns the computed pixel ratio, first using any override, then the device pixel ratio\r\n */\r\n public get pixelRatio(): number {\r\n if (this._pixelRatioOverride) {\r\n return this._pixelRatioOverride;\r\n }\r\n\r\n return this._devicePixelRatio;\r\n }\r\n\r\n /**\r\n * Get or set the pixel ratio override\r\n *\r\n * You will need to call applyResolutionAndViewport() affect change on the screen\r\n */\r\n public get pixelRatioOverride(): number | undefined {\r\n return this._pixelRatioOverride;\r\n }\r\n\r\n public set pixelRatioOverride(value: number | undefined) {\r\n this._pixelRatioOverride = value;\r\n }\r\n\r\n public get isHiDpi() {\r\n return this.pixelRatio !== 1;\r\n }\r\n\r\n public get displayMode(): DisplayMode {\r\n return this._displayMode;\r\n }\r\n\r\n public get canvas(): HTMLCanvasElement {\r\n return this._canvas;\r\n }\r\n\r\n public get parent(): HTMLElement | Window {\r\n switch (this.displayMode) {\r\n case DisplayMode.FillContainer:\r\n case DisplayMode.FitContainer:\r\n case DisplayMode.FitContainerAndFill:\r\n case DisplayMode.FitContainerAndZoom:\r\n return this.canvas.parentElement || document.body;\r\n default:\r\n return window;\r\n }\r\n }\r\n\r\n public get resolution(): ScreenDimension {\r\n return this._resolution;\r\n }\r\n\r\n public set resolution(resolution: ScreenDimension) {\r\n this._resolution = resolution;\r\n }\r\n\r\n public get viewport(): ScreenDimension {\r\n if (this._viewport) {\r\n return this._viewport;\r\n }\r\n return this._resolution;\r\n }\r\n\r\n public set viewport(viewport: ScreenDimension) {\r\n this._viewport = viewport;\r\n }\r\n\r\n public get aspectRatio() {\r\n return this._resolution.width / this._resolution.height;\r\n }\r\n\r\n public get scaledWidth() {\r\n return this._resolution.width * this.pixelRatio;\r\n }\r\n\r\n public get scaledHeight() {\r\n return this._resolution.height * this.pixelRatio;\r\n }\r\n\r\n public setCurrentCamera(camera: Camera) {\r\n this._camera = camera;\r\n }\r\n\r\n public pushResolutionAndViewport() {\r\n this._resolutionStack.push(this.resolution);\r\n this._viewportStack.push(this.viewport);\r\n\r\n this.resolution = { ...this.resolution };\r\n this.viewport = { ...this.viewport };\r\n }\r\n\r\n public peekViewport(): ScreenDimension {\r\n return this._viewportStack[this._viewportStack.length - 1];\r\n }\r\n\r\n public peekResolution(): ScreenDimension {\r\n return this._resolutionStack[this._resolutionStack.length - 1];\r\n }\r\n\r\n public popResolutionAndViewport() {\r\n if (this._resolutionStack.length && this._viewportStack.length) {\r\n this.resolution = this._resolutionStack.pop();\r\n this.viewport = this._viewportStack.pop();\r\n }\r\n }\r\n\r\n public applyResolutionAndViewport() {\r\n this._canvas.width = this.scaledWidth;\r\n this._canvas.height = this.scaledHeight;\r\n\r\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n const supported = this.graphicsContext.checkIfResolutionSupported({\r\n width: this.scaledWidth,\r\n height: this.scaledHeight\r\n });\r\n if (!supported) {\r\n this._logger.warnOnce(\r\n `The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` +\r\n ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' +\r\n ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' +\r\n ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).');\r\n }\r\n }\r\n\r\n if (this._canvasImageRendering === 'auto') {\r\n this._canvas.style.imageRendering = 'auto';\r\n } else {\r\n this._canvas.style.imageRendering = 'pixelated';\r\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\r\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\r\n if (this._canvas.style.imageRendering === '') {\r\n this._canvas.style.imageRendering = 'crisp-edges';\r\n }\r\n }\r\n this._canvas.style.width = this.viewport.width + 'px';\r\n this._canvas.style.height = this.viewport.height + 'px';\r\n\r\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\r\n this.graphicsContext.updateViewport(this.resolution);\r\n this.graphicsContext.resetTransform();\r\n this.graphicsContext.smoothing = this._antialiasing;\r\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) {\r\n this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\r\n }\r\n }\r\n\r\n public get antialiasing() {\r\n return this._antialiasing;\r\n }\r\n\r\n public set antialiasing(isSmooth: boolean) {\r\n this._antialiasing = isSmooth;\r\n this.graphicsContext.smoothing = this._antialiasing;\r\n }\r\n\r\n /**\r\n * Returns true if excalibur is fullscreen using the browser fullscreen api\r\n */\r\n public get isFullScreen() {\r\n return this._isFullScreen;\r\n }\r\n\r\n /**\r\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\r\n * For example, wire this to a user click handler.\r\n *\r\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\r\n * @param elementId\r\n */\r\n public goFullScreen(elementId?: string): Promise {\r\n if (elementId) {\r\n const maybeElement = document.getElementById(elementId);\r\n if (maybeElement) {\r\n if (!maybeElement.getAttribute('ex-fullscreen-listener')) {\r\n maybeElement.setAttribute('ex-fullscreen-listener', 'true');\r\n maybeElement.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n }\r\n const fullscreenPromise = maybeElement.requestFullscreen();\r\n return fullscreenPromise;\r\n }\r\n }\r\n return this._canvas.requestFullscreen();\r\n }\r\n\r\n /**\r\n * Requests to exit fullscreen using the browser fullscreen api\r\n */\r\n public exitFullScreen(): Promise {\r\n return document.exitFullscreen();\r\n }\r\n\r\n /**\r\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\r\n * Excalibur screen space.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY). When using *AndFill suffixed display modes screen space\r\n * (0, 0) is the top left of the safe content area bounding box not the viewport.\r\n * @param point\r\n */\r\n public pageToScreenCoordinates(point: Vector): Vector {\r\n let newX = point.x;\r\n let newY = point.y;\r\n\r\n if (!this._isFullScreen) {\r\n newX -= getPosition(this._canvas).x;\r\n newY -= getPosition(this._canvas).y;\r\n }\r\n\r\n // if fullscreen api on it centers with black bars\r\n // we need to adjust the screen to world coordinates in this case\r\n if (this._isFullScreen) {\r\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\r\n const screenHeight = window.innerWidth / this.aspectRatio;\r\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\r\n newY = ((newY - screenMarginY) / screenHeight) * this.viewport.height;\r\n newX = (newX / window.innerWidth) * this.viewport.width;\r\n } else {\r\n const screenWidth = window.innerHeight * this.aspectRatio;\r\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\r\n newX = ((newX - screenMarginX) / screenWidth) * this.viewport.width;\r\n newY = (newY / window.innerHeight) * this.viewport.height;\r\n }\r\n }\r\n\r\n newX = (newX / this.viewport.width) * this.resolution.width;\r\n newY = (newY / this.viewport.height) * this.resolution.height;\r\n\r\n // offset by content area\r\n newX = newX - this.contentArea.left;\r\n newY = newY - this.contentArea.top;\r\n\r\n return new Vector(newX, newY);\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\r\n * this is where html elements might live if you want to position them relative to Excalibur.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY)\r\n * @param point\r\n */\r\n public screenToPageCoordinates(point: Vector): Vector {\r\n let newX = point.x;\r\n let newY = point.y;\r\n\r\n // no need to offset by content area, drawing is already offset by this\r\n\r\n newX = (newX / this.resolution.width) * this.viewport.width;\r\n newY = (newY / this.resolution.height) * this.viewport.height;\r\n\r\n if (this._isFullScreen) {\r\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\r\n const screenHeight = window.innerWidth / this.aspectRatio;\r\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\r\n newY = (newY / this.viewport.height) * screenHeight + screenMarginY;\r\n newX = (newX / this.viewport.width) * window.innerWidth;\r\n } else {\r\n const screenWidth = window.innerHeight * this.aspectRatio;\r\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\r\n newX = (newX / this.viewport.width) * screenWidth + screenMarginX;\r\n newY = (newY / this.viewport.height) * window.innerHeight;\r\n }\r\n }\r\n\r\n if (!this._isFullScreen) {\r\n newX += getPosition(this._canvas).x;\r\n newY += getPosition(this._canvas).y;\r\n }\r\n\r\n return new Vector(newX, newY);\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\r\n *\r\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\r\n * and extends infinitely out relative from the [[Camera]].\r\n * @param point Screen coordinate to convert\r\n */\r\n public screenToWorldCoordinates(point: Vector): Vector {\r\n // offset by content area\r\n point = point.add(vec(this.contentArea.left, this.contentArea.top));\r\n\r\n // the only difference between screen & world is the camera transform\r\n if (this._camera) {\r\n return this._camera.inverse.multiply(point);\r\n }\r\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\r\n *\r\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\r\n * @param point World coordinate to convert\r\n */\r\n public worldToScreenCoordinates(point: Vector): Vector {\r\n if (this._camera) {\r\n return this._camera.transform.multiply(point);\r\n }\r\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\r\n }\r\n\r\n public pageToWorldCoordinates(point: Vector): Vector {\r\n const screen = this.pageToScreenCoordinates(point);\r\n return this.screenToWorldCoordinates(screen);\r\n }\r\n\r\n public worldToPageCoordinates(point: Vector): Vector {\r\n const screen = this.worldToScreenCoordinates(point);\r\n return this.screenToPageCoordinates(screen);\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n *\r\n * World bounds are in world coordinates, useful for culling objects offscreen that are in world space\r\n */\r\n public getWorldBounds(): BoundingBox {\r\n const bounds = BoundingBox.fromDimension(\r\n this.resolution.width,\r\n this.resolution.height,\r\n Vector.Half)\r\n .scale(vec(1/this._camera.zoom, 1/this._camera.zoom))\r\n .rotate(this._camera.rotation)\r\n .translate(this._camera.pos);\r\n return bounds;\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen and the bottom right corner of the screen.\r\n *\r\n * Screen bounds are in screen coordinates, useful for culling objects offscreen that are in screen space\r\n */\r\n public getScreenBounds(): BoundingBox {\r\n const bounds = BoundingBox.fromDimension(\r\n this.resolution.width,\r\n this.resolution.height,\r\n Vector.Zero, Vector.Zero);\r\n return bounds;\r\n }\r\n\r\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */\r\n public get canvasWidth(): number {\r\n return this.canvas.width;\r\n }\r\n\r\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */\r\n public get halfCanvasWidth(): number {\r\n return this.canvas.width / 2;\r\n }\r\n\r\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */\r\n public get canvasHeight(): number {\r\n return this.canvas.height;\r\n }\r\n\r\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */\r\n public get halfCanvasHeight(): number {\r\n return this.canvas.height / 2;\r\n }\r\n\r\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawWidth(): number {\r\n if (this._camera) {\r\n return this.resolution.width / this._camera.zoom;\r\n }\r\n return this.resolution.width;\r\n }\r\n\r\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawWidth(): number {\r\n return this.drawWidth / 2;\r\n }\r\n\r\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawHeight(): number {\r\n if (this._camera) {\r\n return this.resolution.height / this._camera.zoom;\r\n }\r\n return this.resolution.height;\r\n }\r\n\r\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawHeight(): number {\r\n return this.drawHeight / 2;\r\n }\r\n\r\n /**\r\n * Returns screen center coordinates including zoom and device pixel ratio.\r\n */\r\n public get center(): Vector {\r\n return vec(this.halfDrawWidth, this.halfDrawHeight);\r\n }\r\n\r\n /**\r\n * Returns the content area in screen space where it is safe to place content\r\n */\r\n public get contentArea(): BoundingBox {\r\n return this._contentArea;\r\n }\r\n\r\n private _computeFit() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n if (window.innerWidth / aspect < window.innerHeight) {\r\n adjustedWidth = window.innerWidth;\r\n adjustedHeight = window.innerWidth / aspect;\r\n } else {\r\n adjustedWidth = window.innerHeight * aspect;\r\n adjustedHeight = window.innerHeight;\r\n }\r\n\r\n this.viewport = {\r\n width: adjustedWidth,\r\n height: adjustedHeight\r\n };\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n }\r\n\r\n private _contentArea: BoundingBox = new BoundingBox();\r\n private _computeFitScreenAndFill() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n this._computeFitAndFill(vw, vh);\r\n }\r\n\r\n\r\n\r\n private _computeFitContainerAndFill() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const parent = this.canvas.parentElement;\r\n const vw = parent.clientWidth;\r\n const vh = parent.clientHeight;\r\n this._computeFitAndFill(vw, vh);\r\n }\r\n\r\n private _computeFitAndFill(vw: number, vh: number) {\r\n this.viewport = {\r\n width: vw,\r\n height: vh\r\n };\r\n // if the current screen aspectRatio is less than the original aspectRatio\r\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\r\n // compute new resolution to match the original aspect ratio\r\n this.resolution = {\r\n width: vw * this._contentResolution.width / vw,\r\n height: vw * this._contentResolution.width / vw * vh / vw\r\n };\r\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\r\n this._contentArea = new BoundingBox({\r\n top: clip,\r\n left: 0,\r\n right: this._contentResolution.width,\r\n bottom: this.resolution.height - clip\r\n });\r\n } else {\r\n this.resolution = {\r\n width: vh * this._contentResolution.height / vh * vw / vh,\r\n height: vh * this._contentResolution.height / vh\r\n };\r\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\r\n this._contentArea = new BoundingBox({\r\n top: 0,\r\n left: clip,\r\n right: this.resolution.width - clip,\r\n bottom: this._contentResolution.height\r\n });\r\n }\r\n }\r\n\r\n private _computeFitScreenAndZoom() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.canvas.style.position = 'absolute';\r\n\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n\r\n this._computeFitAndZoom(vw, vh);\r\n }\r\n\r\n private _computeFitContainerAndZoom() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.canvas.style.position = 'absolute';\r\n const parent = this.canvas.parentElement;\r\n parent.style.position = 'relative';\r\n parent.style.overflow = 'hidden';\r\n\r\n const vw = parent.clientWidth;\r\n const vh = parent.clientHeight;\r\n\r\n this._computeFitAndZoom(vw, vh);\r\n }\r\n\r\n private _computeFitAndZoom(vw: number, vh: number) {\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n if (vw / aspect < vh) {\r\n adjustedWidth = vw;\r\n adjustedHeight = vw / aspect;\r\n } else {\r\n adjustedWidth = vh * aspect;\r\n adjustedHeight = vh;\r\n }\r\n\r\n const scaleX = vw / adjustedWidth;\r\n const scaleY = vh / adjustedHeight;\r\n\r\n const maxScaleFactor = Math.max(scaleX, scaleY);\r\n\r\n const zoomedWidth = adjustedWidth * maxScaleFactor;\r\n const zoomedHeight = adjustedHeight * maxScaleFactor;\r\n\r\n // Center zoomed dimension if bigger than the screen\r\n if (zoomedWidth > vw) {\r\n this.canvas.style.left = -(zoomedWidth - vw) / 2 + 'px';\r\n } else {\r\n this.canvas.style.left = '';\r\n }\r\n\r\n if (zoomedHeight > vh) {\r\n this.canvas.style.top = -(zoomedHeight - vh) / 2 + 'px';\r\n } else {\r\n this.canvas.style.top = '';\r\n }\r\n\r\n this.viewport = {\r\n width: zoomedWidth,\r\n height: zoomedHeight\r\n };\r\n\r\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\r\n // return safe area\r\n if (this.viewport.width > vw) {\r\n const clip = (this.viewport.width - vw)/this.viewport.width * this.resolution.width;\r\n bounds.top = 0;\r\n bounds.left = clip / 2;\r\n bounds.right = this.resolution.width - clip / 2;\r\n bounds.bottom = this.resolution.height;\r\n }\r\n\r\n if (this.viewport.height > vh) {\r\n const clip = (this.viewport.height - vh)/this.viewport.height * this.resolution.height;\r\n bounds.top = clip / 2;\r\n bounds.left = 0;\r\n bounds.bottom = this.resolution.height - clip / 2;\r\n bounds.right = this.resolution.width;\r\n }\r\n this._contentArea = bounds;\r\n }\r\n\r\n private _computeFitContainer() {\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n const parent = this.canvas.parentElement;\r\n if (parent.clientWidth / aspect < parent.clientHeight) {\r\n adjustedWidth = parent.clientWidth;\r\n adjustedHeight = parent.clientWidth / aspect;\r\n } else {\r\n adjustedWidth = parent.clientHeight * aspect;\r\n adjustedHeight = parent.clientHeight;\r\n }\r\n\r\n this.viewport = {\r\n width: adjustedWidth,\r\n height: adjustedHeight\r\n };\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n }\r\n\r\n private _applyDisplayMode() {\r\n this._setResolutionAndViewportByDisplayMode(this.parent);\r\n\r\n // watch resizing\r\n if (this.parent instanceof Window) {\r\n this._browser.window.on('resize', this._resizeHandler);\r\n } else {\r\n this._resizeObserver = new ResizeObserver(() => {\r\n this._resizeHandler();\r\n });\r\n this._resizeObserver.observe(this.parent);\r\n }\r\n this.parent.addEventListener('resize', this._resizeHandler);\r\n }\r\n\r\n /**\r\n * Sets the resolution and viewport based on the selected display mode.\r\n */\r\n private _setResolutionAndViewportByDisplayMode(parent: HTMLElement | Window) {\r\n if (this.displayMode === DisplayMode.FillContainer) {\r\n this.resolution = {\r\n width: ( parent).clientWidth,\r\n height: ( parent).clientHeight\r\n };\r\n\r\n this.viewport = this.resolution;\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FillScreen) {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.resolution = {\r\n width: ( parent).innerWidth,\r\n height: ( parent).innerHeight\r\n };\r\n\r\n this.viewport = this.resolution;\r\n }\r\n\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n\r\n if (this.displayMode === DisplayMode.FitScreen) {\r\n this._computeFit();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainer) {\r\n this._computeFitContainer();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitScreenAndFill) {\r\n this._computeFitScreenAndFill();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainerAndFill){\r\n this._computeFitContainerAndFill();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitScreenAndZoom) {\r\n this._computeFitScreenAndZoom();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainerAndZoom){\r\n this._computeFitContainerAndZoom();\r\n }\r\n }\r\n}\r\n","/**\r\n * Internal class used to build instances of AudioContext\r\n */\r\n/* istanbul ignore next */\r\nexport class AudioContextFactory {\r\n private static _INSTANCE: AudioContext = null;\r\n\r\n public static create(): AudioContext {\r\n if (!this._INSTANCE) {\r\n if ((window).AudioContext || (window).webkitAudioContext) {\r\n this._INSTANCE = new AudioContext();\r\n }\r\n }\r\n\r\n return this._INSTANCE;\r\n }\r\n}\r\n","import { AudioContextFactory } from '../Resources/Sound/AudioContext';\r\nimport { Logger } from './Log';\r\n\r\nexport interface LegacyWebAudioSource {\r\n playbackState: string;\r\n PLAYING_STATE: 'playing';\r\n FINISHED_STATE: 'finished';\r\n}\r\n\r\n/**\r\n * Patch for detecting legacy web audio in browsers\r\n * @internal\r\n * @param source\r\n */\r\nfunction isLegacyWebAudioSource(source: any): source is LegacyWebAudioSource {\r\n return !!source.playbackState;\r\n}\r\n\r\nexport class WebAudio {\r\n private static _UNLOCKED: boolean = false;\r\n\r\n /**\r\n * Play an empty sound to unlock Safari WebAudio context. Call this function\r\n * right after a user interaction event.\r\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\r\n */\r\n static unlock(): Promise {\r\n const promise = new Promise((resolve, reject) => {\r\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) {\r\n return resolve(true);\r\n }\r\n const unlockTimeoutTimer = setTimeout(() => {\r\n Logger.getInstance().warn('Excalibur was unable to unlock the audio context, audio probably will not play in this browser.');\r\n resolve(false);\r\n }, 200);\r\n\r\n const audioContext = AudioContextFactory.create();\r\n audioContext.resume().then(\r\n () => {\r\n // create empty buffer and play it\r\n const buffer = audioContext.createBuffer(1, 1, 22050);\r\n const source = audioContext.createBufferSource();\r\n let ended = false;\r\n\r\n source.buffer = buffer;\r\n source.connect(audioContext.destination);\r\n source.onended = () => (ended = true);\r\n\r\n source.start(0);\r\n\r\n // by checking the play state after some time, we know if we're really unlocked\r\n setTimeout(() => {\r\n if (isLegacyWebAudioSource(source)) {\r\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) {\r\n WebAudio._UNLOCKED = true;\r\n }\r\n } else {\r\n if (audioContext.currentTime > 0 || ended) {\r\n WebAudio._UNLOCKED = true;\r\n }\r\n }\r\n }, 0);\r\n\r\n clearTimeout(unlockTimeoutTimer);\r\n resolve(true);\r\n },\r\n () => {\r\n reject();\r\n }\r\n );\r\n });\r\n\r\n return promise;\r\n }\r\n\r\n static isUnlocked() {\r\n return this._UNLOCKED;\r\n }\r\n}\r\n","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { watch } from '../Util/Watch';\r\nimport { ImageFiltering } from './Filtering';\r\nimport { omit } from '../Util/Util';\r\n\r\nexport interface RasterOptions {\r\n /**\r\n * Optionally specify a quality number, which is how much to scale the internal Raster. Default is 1.\r\n *\r\n * For example if the quality is set to 2, it doubles the internal raster bitmap in memory.\r\n *\r\n * Adjusting this value can be useful if you are working with small rasters.\r\n */\r\n quality?: number;\r\n /**\r\n * Optionally specify \"smoothing\" if you want antialiasing to apply to the raster's bitmap context, by default `false`\r\n */\r\n smoothing?: boolean;\r\n\r\n /**\r\n * Optionally specify the color of the raster's bitmap context, by default [[Color.Black]]\r\n */\r\n color?: Color;\r\n\r\n /**\r\n * Optionally specify the stroke color of the raster's bitmap context, by default undefined\r\n */\r\n strokeColor?: Color;\r\n\r\n /**\r\n * Optionally specify the line width of the raster's bitmap, by default 1 pixel\r\n */\r\n lineWidth?: number;\r\n\r\n /**\r\n * Optionally specify the line dash of the raster's bitmap, by default `[]` which means none\r\n */\r\n lineDash?: number[];\r\n\r\n /**\r\n * Optionally specify the line end style, default is \"butt\".\r\n */\r\n lineCap?: 'butt' | 'round' | 'square';\r\n\r\n /**\r\n * Optionally specify the padding to apply to the bitmap\r\n */\r\n padding?: number;\r\n\r\n /**\r\n * Optionally specify what image filtering mode should be used, [[ImageFiltering.Pixel]] for pixel art,\r\n * [[ImageFiltering.Blended]] for hi-res art\r\n *\r\n * By default unset, rasters defer to the engine antialiasing setting\r\n */\r\n filtering?: ImageFiltering;\r\n}\r\n\r\n/**\r\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\r\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\r\n *\r\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\r\n */\r\nexport abstract class Raster extends Graphic {\r\n public filtering: ImageFiltering = null;\r\n public lineCap: 'butt' | 'round' | 'square' = 'butt';\r\n public quality: number = 1;\r\n\r\n public _bitmap: HTMLCanvasElement;\r\n protected _ctx: CanvasRenderingContext2D;\r\n private _dirty: boolean = true;\r\n\r\n constructor(options?: GraphicOptions & RasterOptions) {\r\n super(omit(options, ['width', 'height'])); // rasters do some special sauce with width/height\r\n if (options) {\r\n this.quality = options.quality ?? this.quality;\r\n this.color = options.color ?? Color.Black;\r\n this.strokeColor = options?.strokeColor;\r\n this.smoothing = options.smoothing ?? this.smoothing;\r\n this.lineWidth = options.lineWidth ?? this.lineWidth;\r\n this.lineDash = options.lineDash ?? this.lineDash;\r\n this.lineCap = options.lineCap ?? this.lineCap;\r\n this.padding = options.padding ?? this.padding;\r\n this.filtering = options.filtering ?? this.filtering;\r\n }\r\n this._bitmap = document.createElement('canvas');\r\n // get the default canvas width/height as a fallback\r\n const bitmapWidth = options?.width ?? this._bitmap.width;\r\n const bitmapHeight = options?.height ?? this._bitmap.height;\r\n this.width = bitmapWidth;\r\n this.height = bitmapHeight;\r\n const maybeCtx = this._bitmap.getContext('2d');\r\n if (!maybeCtx) {\r\n /* istanbul ignore next */\r\n throw new Error('Browser does not support 2d canvas drawing, cannot create Raster graphic');\r\n } else {\r\n this._ctx = maybeCtx;\r\n }\r\n }\r\n\r\n public cloneRasterOptions(): RasterOptions {\r\n return {\r\n color: this.color ? this.color.clone() : null,\r\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\r\n smoothing: this.smoothing,\r\n lineWidth: this.lineWidth,\r\n lineDash: this.lineDash,\r\n lineCap: this.lineCap,\r\n quality: this.quality,\r\n padding: this.padding\r\n };\r\n }\r\n\r\n /**\r\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\r\n */\r\n public get dirty() {\r\n return this._dirty;\r\n }\r\n\r\n /**\r\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\r\n * This should be called any time the graphics state changes such that it affects the outputted drawing\r\n */\r\n public flagDirty() {\r\n this._dirty = true;\r\n }\r\n\r\n private _originalWidth: number;\r\n /**\r\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding`s or `quality` set will be factored into the width\r\n */\r\n public get width() {\r\n return Math.abs(this._getTotalWidth() * this.scale.x);\r\n }\r\n public set width(value: number) {\r\n value /= Math.abs(this.scale.x);\r\n this._bitmap.width = value;\r\n this._originalWidth = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _originalHeight: number;\r\n /**\r\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding` or `quality` set will be factored into the height\r\n */\r\n public get height() {\r\n return Math.abs(this._getTotalHeight() * this.scale.y);\r\n }\r\n\r\n public set height(value: number) {\r\n value /= Math.abs(this.scale.y);\r\n this._bitmap.height = value;\r\n this._originalHeight = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _getTotalWidth() {\r\n return ((this._originalWidth ?? this._bitmap.width) + this.padding * 2) * 1;\r\n }\r\n\r\n private _getTotalHeight() {\r\n return ((this._originalHeight ?? this._bitmap.height) + this.padding * 2) * 1;\r\n }\r\n\r\n /**\r\n * Returns the local bounds of the Raster including the padding\r\n */\r\n public get localBounds() {\r\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\r\n }\r\n\r\n private _smoothing: boolean = false;\r\n /**\r\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get smoothing() {\r\n return this._smoothing;\r\n }\r\n public set smoothing(value: boolean) {\r\n this._smoothing = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _color: Color = watch(Color.Black, () => this.flagDirty());\r\n /**\r\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get color() {\r\n return this._color;\r\n }\r\n public set color(value) {\r\n this.flagDirty();\r\n this._color = watch(value, () => this.flagDirty());\r\n }\r\n\r\n private _strokeColor: Color;\r\n /**\r\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get strokeColor() {\r\n return this._strokeColor;\r\n }\r\n public set strokeColor(value) {\r\n this.flagDirty();\r\n this._strokeColor = watch(value, () => this.flagDirty());\r\n }\r\n\r\n private _lineWidth: number = 1;\r\n /**\r\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get lineWidth() {\r\n return this._lineWidth;\r\n }\r\n public set lineWidth(value) {\r\n this._lineWidth = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _lineDash: number[] = [];\r\n public get lineDash() {\r\n return this._lineDash;\r\n }\r\n\r\n public set lineDash(value) {\r\n this._lineDash = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _padding: number = 0;\r\n public get padding() {\r\n return this._padding;\r\n }\r\n\r\n public set padding(value: number) {\r\n this._padding = value;\r\n this.flagDirty();\r\n }\r\n\r\n /**\r\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\r\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\r\n */\r\n public rasterize(): void {\r\n this._dirty = false;\r\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\r\n this._ctx.save();\r\n this._applyRasterProperties(this._ctx);\r\n this.execute(this._ctx);\r\n this._ctx.restore();\r\n }\r\n\r\n protected _applyRasterProperties(ctx: CanvasRenderingContext2D) {\r\n this._bitmap.width = this._getTotalWidth() * this.quality;\r\n this._bitmap.height = this._getTotalHeight() * this.quality;\r\n // Do a bad thing to pass the filtering as an attribute\r\n this._bitmap.setAttribute('filtering', this.filtering);\r\n this._bitmap.setAttribute('forceUpload', 'true');\r\n ctx.scale(this.quality, this.quality);\r\n ctx.translate(this.padding, this.padding);\r\n ctx.imageSmoothingEnabled = this.smoothing;\r\n ctx.lineWidth = this.lineWidth;\r\n ctx.setLineDash(this.lineDash ?? ctx.getLineDash());\r\n ctx.lineCap = this.lineCap;\r\n ctx.strokeStyle = this.strokeColor?.toString();\r\n ctx.fillStyle = this.color?.toString();\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n if (this._dirty) {\r\n this.rasterize();\r\n }\r\n ex.scale(1 / this.quality, 1 / this.quality);\r\n ex.drawImage(this._bitmap, x, y);\r\n }\r\n\r\n /**\r\n * Executes drawing implementation of the graphic, this is where the specific drawing code for the graphic\r\n * should be implemented. Once `rasterize()` the graphic can be drawn to the [[ExcaliburGraphicsContext]] via `draw(...)`\r\n * @param ctx Canvas to draw the graphic to\r\n */\r\n abstract execute(ctx: CanvasRenderingContext2D): void;\r\n}\r\n","import { GraphicOptions } from './Graphic';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface CanvasOptions {\r\n draw?: (ctx: CanvasRenderingContext2D) => void;\r\n cache?: boolean;\r\n}\r\n\r\n/**\r\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\r\n *\r\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\r\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\r\n *\r\n * **Low performance API**\r\n */\r\nexport class Canvas extends Raster {\r\n /**\r\n * Return the 2D graphics context of this canvas\r\n */\r\n public get ctx() {\r\n return this._ctx;\r\n }\r\n\r\n constructor(private _options: GraphicOptions & RasterOptions & CanvasOptions) {\r\n super(_options);\r\n }\r\n\r\n public clone(): Canvas {\r\n return new Canvas({\r\n ...this._options,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this._options?.draw) {\r\n this._options?.draw(ctx);\r\n }\r\n if (!this._options.cache) {\r\n this.flagDirty();\r\n }\r\n }\r\n}\r\n","import { Audio } from './Audio';\r\n\r\nexport type ExResponseType = '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';\r\n\r\nexport interface ExResponseTypesLookup {\r\n [name: string]: ExResponseType;\r\n}\r\n\r\nexport class ExResponse {\r\n public static type: ExResponseTypesLookup = {\r\n any: '',\r\n blob: 'blob',\r\n json: 'json',\r\n text: 'text',\r\n document: 'document',\r\n arraybuffer: 'arraybuffer'\r\n };\r\n}\r\n\r\n/**\r\n * Represents an audio implementation like [[WebAudioInstance]]\r\n */\r\nexport interface AudioImplementation {\r\n /**\r\n * XHR response type\r\n */\r\n responseType: ExResponseType;\r\n\r\n /**\r\n * Processes raw data and transforms into sound data\r\n */\r\n processData(data: Blob | ArrayBuffer): Promise;\r\n\r\n /**\r\n * Factory method that returns an instance of a played audio track\r\n */\r\n createInstance(data: string | AudioBuffer): Audio;\r\n}\r\n","\r\nexport interface State {\r\n name?: string;\r\n transitions: string[];\r\n onEnter?: (context: {from: string, eventData?: any, data: any}) => boolean | void;\r\n onState?: () => any;\r\n onExit?: (context: {to: string, data: any}) => boolean | void;\r\n onUpdate?: (data: any, elapsedMs: number) => any;\r\n}\r\n\r\nexport interface StateMachineDescription {\r\n start: string,\r\n states: { [name: string]: State }\r\n}\r\n\r\nexport type PossibleStates = TMachine extends StateMachineDescription ? Extract : never;\r\n\r\nexport interface StateMachineState {\r\n data: any;\r\n currentState: string;\r\n}\r\n\r\nexport class StateMachine {\r\n public startState: State;\r\n private _currentState: State;\r\n public get currentState(): State {\r\n return this._currentState;\r\n }\r\n public set currentState(state: State) {\r\n this._currentState = state;\r\n }\r\n public states = new Map();\r\n public data: TData;\r\n\r\n static create(\r\n machineDescription: TMachine, data?: TData): StateMachine, TData> {\r\n const machine = new StateMachine, TData>();\r\n machine.data = data;\r\n for (const stateName in machineDescription.states) {\r\n machine.states.set(stateName as PossibleStates, {\r\n name: stateName,\r\n ...machineDescription.states[stateName]\r\n });\r\n }\r\n\r\n // validate transitions are states\r\n for (const state of machine.states.values()) {\r\n for (const transitionState of state.transitions) {\r\n if (transitionState === '*') {\r\n continue;\r\n }\r\n if (!machine.states.has(transitionState)) {\r\n throw Error(\r\n `Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`\r\n );\r\n }\r\n }\r\n }\r\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\r\n return machine;\r\n }\r\n\r\n in(state: TPossibleStates): boolean {\r\n return this.currentState.name === state;\r\n }\r\n\r\n go(stateName: TPossibleStates, eventData?: any): boolean {\r\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes('*')) {\r\n const potentialNewState = this.states.get(stateName);\r\n if (this.currentState.onExit) {\r\n const canExit = this.currentState?.onExit({to: potentialNewState.name, data: this.data});\r\n if (canExit === false) {\r\n return false;\r\n }\r\n }\r\n\r\n if (potentialNewState?.onEnter) {\r\n const canEnter = potentialNewState?.onEnter({from: this.currentState.name, eventData, data: this.data});\r\n if (canEnter === false) {\r\n return false;\r\n }\r\n }\r\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\r\n this.currentState = potentialNewState;\r\n if (this.currentState?.onState) {\r\n this.currentState.onState();\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n update(elapsedMs: number) {\r\n if (this.currentState.onUpdate) {\r\n this.currentState.onUpdate(this.data, elapsedMs);\r\n }\r\n }\r\n\r\n save(saveKey: string) {\r\n localStorage.setItem(saveKey, JSON.stringify({\r\n currentState: this.currentState.name,\r\n data: this.data\r\n }));\r\n }\r\n\r\n restore(saveKey: string) {\r\n const state: StateMachineState = JSON.parse(localStorage.getItem(saveKey));\r\n this.currentState = this.states.get(state.currentState);\r\n this.data = state.data;\r\n }\r\n}\r\n\r\n","import { StateMachine } from '../../Util/StateMachine';\r\nimport { Audio } from '../../Interfaces/Audio';\r\nimport { clamp } from '../../Math/util';\r\nimport { AudioContextFactory } from './AudioContext';\r\nimport { Future } from '../../Util/Future';\r\n\r\ninterface SoundState {\r\n startedAt: number;\r\n pausedAt: number;\r\n}\r\n\r\n/**\r\n * Internal class representing a Web Audio AudioBufferSourceNode instance\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\r\n */\r\nexport class WebAudioInstance implements Audio {\r\n private _instance: AudioBufferSourceNode;\r\n private _audioContext: AudioContext = AudioContextFactory.create();\r\n private _volumeNode = this._audioContext.createGain();\r\n\r\n private _playingFuture = new Future();\r\n private _stateMachine = StateMachine.create({\r\n start: 'STOPPED',\r\n states: {\r\n PLAYING: {\r\n onEnter: ({data}: {from: string, data: SoundState}) => {\r\n\r\n // Buffer nodes are single use\r\n this._createNewBufferSource();\r\n this._handleEnd();\r\n if (this.loop) {\r\n // when looping don't set a duration\r\n this._instance.start(0, data.pausedAt * this._playbackRate);\r\n } else {\r\n this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\r\n }\r\n data.startedAt = (this._audioContext.currentTime - data.pausedAt);\r\n data.pausedAt = 0;\r\n },\r\n onState: () => this._playStarted(),\r\n onExit: ({to}) => {\r\n // If you've exited early only resolve if explicitly STOPPED\r\n if (to === 'STOPPED') {\r\n this._playingFuture.resolve(true);\r\n }\r\n // Whenever you're not playing... you stop!\r\n this._instance.onended = null; // disconnect the wired on-end handler\r\n this._instance.disconnect();\r\n this._instance.stop(0);\r\n this._instance = null;\r\n },\r\n transitions: ['STOPPED', 'PAUSED', 'SEEK']\r\n },\r\n SEEK: {\r\n onEnter: ({ eventData: position, data }: {eventData?: number, data: SoundState}) => {\r\n data.pausedAt = (position ?? 0) / this._playbackRate;\r\n data.startedAt = 0;\r\n },\r\n transitions: ['*']\r\n },\r\n STOPPED: {\r\n onEnter: ({data}: {from: string, data: SoundState}) => {\r\n data.pausedAt = 0;\r\n data.startedAt = 0;\r\n this._playingFuture.resolve(true);\r\n },\r\n transitions: ['PLAYING', 'PAUSED', 'SEEK']\r\n },\r\n PAUSED: {\r\n onEnter: ({data}: {data: SoundState}) => {\r\n // Playback rate will be a scale factor of how fast/slow the audio is being played\r\n // default is 1.0\r\n // we need to invert it to get the time scale\r\n data.pausedAt = (this._audioContext.currentTime - data.startedAt);\r\n },\r\n transitions: ['PLAYING', 'STOPPED', 'SEEK']\r\n }\r\n }\r\n }, {\r\n startedAt: 0,\r\n pausedAt: 0\r\n } as SoundState);\r\n\r\n private _createNewBufferSource() {\r\n this._instance = this._audioContext.createBufferSource();\r\n this._instance.buffer = this._src;\r\n this._instance.loop = this.loop;\r\n this._instance.playbackRate.value = this._playbackRate;\r\n this._instance.connect(this._volumeNode);\r\n this._volumeNode.connect(this._audioContext.destination);\r\n }\r\n\r\n private _handleEnd() {\r\n if (!this.loop) {\r\n this._instance.onended = () => {\r\n this._playingFuture.resolve(true);\r\n };\r\n }\r\n }\r\n\r\n private _volume = 1;\r\n private _loop = false;\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n private _playStarted: () => any = () => {};\r\n public set loop(value: boolean) {\r\n this._loop = value;\r\n\r\n if (this._instance) {\r\n this._instance.loop = value;\r\n if (!this.loop) {\r\n this._instance.onended = () => {\r\n this._playingFuture.resolve(true);\r\n };\r\n }\r\n }\r\n }\r\n public get loop(): boolean {\r\n return this._loop;\r\n }\r\n\r\n public set volume(value: number) {\r\n value = clamp(value, 0, 1.0);\r\n\r\n this._volume = value;\r\n\r\n if (this._stateMachine.in('PLAYING') && this._volumeNode.gain.setTargetAtTime) {\r\n // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\r\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\r\n // This exponential ramp provides a more pleasant transition in gain\r\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\r\n } else {\r\n this._volumeNode.gain.value = value;\r\n }\r\n }\r\n public get volume(): number {\r\n return this._volume;\r\n }\r\n\r\n private _duration: number | undefined;\r\n /**\r\n * Returns the set duration to play, otherwise returns the total duration if unset\r\n */\r\n public get duration() {\r\n return this._duration ?? this.getTotalPlaybackDuration();\r\n }\r\n\r\n /**\r\n * Set the duration that this audio should play.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */\r\n public set duration(duration: number) {\r\n this._duration = duration;\r\n }\r\n\r\n constructor(private _src: AudioBuffer) {\r\n this._createNewBufferSource();\r\n }\r\n\r\n public isPlaying() {\r\n return this._stateMachine.in('PLAYING');\r\n }\r\n\r\n public isPaused() {\r\n return this._stateMachine.in('PAUSED') || this._stateMachine.in('SEEK');\r\n }\r\n\r\n public isStopped() {\r\n return this._stateMachine.in('STOPPED');\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n public play(playStarted: () => any = () => {}) {\r\n this._playStarted = playStarted;\r\n this._stateMachine.go('PLAYING');\r\n return this._playingFuture.promise;\r\n }\r\n\r\n public pause() {\r\n this._stateMachine.go('PAUSED');\r\n }\r\n\r\n public stop() {\r\n this._stateMachine.go('STOPPED');\r\n }\r\n\r\n public seek(position: number) {\r\n this._stateMachine.go('PAUSED');\r\n this._stateMachine.go('SEEK', position);\r\n }\r\n\r\n public getTotalPlaybackDuration() {\r\n return this._src.duration;\r\n }\r\n\r\n public getPlaybackPosition() {\r\n const {pausedAt, startedAt} = this._stateMachine.data;\r\n if (pausedAt) {\r\n return pausedAt * this._playbackRate;\r\n }\r\n if (startedAt) {\r\n return (this._audioContext.currentTime - startedAt) * this._playbackRate;\r\n }\r\n return 0;\r\n }\r\n\r\n private _playbackRate = 1.0;\r\n public set playbackRate(playbackRate: number) {\r\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\r\n }\r\n\r\n public get playbackRate() {\r\n return this._instance.playbackRate.value;\r\n }\r\n}\r\n","import { Scene } from './Scene';\r\nimport { Vector } from './Math/vector';\r\nimport { Actor } from './Actor';\r\nimport { Trigger } from './Trigger';\r\nimport { FrameStats } from './Debug';\r\nimport { Engine } from './Engine';\r\nimport { TileMap } from './TileMap';\r\nimport { Side } from './Collision/Side';\r\nimport { CollisionContact } from './Collision/Detection/CollisionContact';\r\nimport { Collider } from './Collision/Colliders/Collider';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { OnInitialize, OnPreUpdate, OnPostUpdate, SceneActivationContext } from './Interfaces/LifecycleEvents';\r\nimport { BodyComponent } from './Collision/BodyComponent';\r\nimport { ExcaliburGraphicsContext } from './Graphics';\r\nimport { Axes, Buttons, Gamepad } from './Input/Gamepad';\r\nimport { Action } from './Actions/Action';\r\n\r\nexport enum EventTypes {\r\n Kill = 'kill',\r\n PreKill = 'prekill',\r\n PostKill = 'postkill',\r\n\r\n PreDraw = 'predraw',\r\n PostDraw = 'postdraw',\r\n\r\n PreDebugDraw = 'predebugdraw',\r\n PostDebugDraw = 'postdebugdraw',\r\n\r\n PreUpdate = 'preupdate',\r\n PostUpdate = 'postupdate',\r\n\r\n PreFrame = 'preframe',\r\n PostFrame = 'postframe',\r\n\r\n PreCollision = 'precollision',\r\n CollisionStart = 'collisionstart',\r\n CollisionEnd = 'collisionend',\r\n PostCollision = 'postcollision',\r\n\r\n Initialize = 'initialize',\r\n Activate = 'activate',\r\n Deactivate = 'deactivate',\r\n\r\n ExitViewport = 'exitviewport',\r\n EnterViewport = 'enterviewport',\r\n\r\n ExitTrigger = 'exit',\r\n EnterTrigger = 'enter',\r\n\r\n Connect = 'connect',\r\n Disconnect = 'disconnect',\r\n Button = 'button',\r\n Axis = 'axis',\r\n\r\n Visible = 'visible',\r\n Hidden = 'hidden',\r\n Start = 'start',\r\n Stop = 'stop',\r\n\r\n PointerUp = 'pointerup',\r\n PointerDown = 'pointerdown',\r\n PointerMove = 'pointermove',\r\n PointerEnter = 'pointerenter',\r\n PointerLeave = 'pointerleave',\r\n PointerCancel = 'pointercancel',\r\n PointerWheel = 'pointerwheel',\r\n\r\n Up = 'up',\r\n Down = 'down',\r\n Move = 'move',\r\n Enter = 'enter',\r\n Leave = 'leave',\r\n Cancel = 'cancel',\r\n Wheel = 'wheel',\r\n\r\n Press = 'press',\r\n Release = 'release',\r\n Hold = 'hold',\r\n\r\n PointerDragStart = 'pointerdragstart',\r\n PointerDragEnd = 'pointerdragend',\r\n PointerDragEnter = 'pointerdragenter',\r\n PointerDragLeave = 'pointerdragleave',\r\n PointerDragMove = 'pointerdragmove',\r\n\r\n ActionStart = 'actionstart',\r\n ActionComplete = 'actioncomplete'\r\n}\r\n\r\n/* istanbul ignore next */\r\n/* compiler only: these are internal to lib */\r\nexport type kill = 'kill';\r\nexport type prekill = 'prekill';\r\nexport type postkill = 'postkill';\r\n\r\nexport type predraw = 'predraw';\r\nexport type postdraw = 'postdraw';\r\n\r\nexport type predebugdraw = 'predebugdraw';\r\nexport type postdebugdraw = 'postdebugdraw';\r\n\r\nexport type preupdate = 'preupdate';\r\nexport type postupdate = 'postupdate';\r\n\r\nexport type preframe = 'preframe';\r\nexport type postframe = 'postframe';\r\n\r\nexport type precollision = 'precollision';\r\nexport type collisionstart = 'collisionstart';\r\nexport type collisionend = 'collisionend';\r\nexport type postcollision = 'postcollision';\r\n\r\nexport type initialize = 'initialize';\r\nexport type activate = 'activate';\r\nexport type deactivate = 'deactivate';\r\n\r\nexport type exitviewport = 'exitviewport';\r\nexport type enterviewport = 'enterviewport';\r\n\r\nexport type exittrigger = 'exit';\r\nexport type entertrigger = 'enter';\r\n\r\nexport type connect = 'connect';\r\nexport type disconnect = 'disconnect';\r\nexport type button = 'button';\r\nexport type axis = 'axis';\r\n\r\nexport type subscribe = 'subscribe';\r\nexport type unsubscribe = 'unsubscribe';\r\n\r\nexport type visible = 'visible';\r\nexport type hidden = 'hidden';\r\nexport type start = 'start';\r\nexport type stop = 'stop';\r\n\r\nexport type pointerup = 'pointerup';\r\nexport type pointerdown = 'pointerdown';\r\nexport type pointermove = 'pointermove';\r\nexport type pointerenter = 'pointerenter';\r\nexport type pointerleave = 'pointerleave';\r\nexport type pointercancel = 'pointercancel';\r\nexport type pointerwheel = 'pointerwheel';\r\n\r\nexport type up = 'up';\r\nexport type down = 'down';\r\nexport type move = 'move';\r\nexport type enter = 'enter';\r\nexport type leave = 'leave';\r\nexport type cancel = 'cancel';\r\nexport type wheel = 'wheel';\r\n\r\nexport type press = 'press';\r\nexport type release = 'release';\r\nexport type hold = 'hold';\r\n\r\nexport type pointerdragstart = 'pointerdragstart';\r\nexport type pointerdragend = 'pointerdragend';\r\nexport type pointerdragenter = 'pointerdragenter';\r\nexport type pointerdragleave = 'pointerdragleave';\r\nexport type pointerdragmove = 'pointerdragmove';\r\n\r\n/**\r\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\r\n * some events are unique to a type, others are not.\r\n *\r\n */\r\nexport class GameEvent {\r\n /**\r\n * Target object for this event.\r\n */\r\n public target: T;\r\n\r\n /**\r\n * Other target object for this event\r\n */\r\n public other: U | null;\r\n\r\n /**\r\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\r\n * to all actors that apply.\r\n */\r\n public get bubbles(): boolean {\r\n return this._bubbles;\r\n }\r\n\r\n public set bubbles(value: boolean) {\r\n this._bubbles = value;\r\n }\r\n\r\n private _bubbles: boolean = true;\r\n /**\r\n * Prevents event from bubbling\r\n */\r\n public stopPropagation() {\r\n this.bubbles = false;\r\n }\r\n}\r\n\r\n/**\r\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\r\n */\r\nexport class KillEvent extends GameEvent {\r\n constructor(public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'prekill' event is emitted directly before an actor is killed.\r\n */\r\nexport class PreKillEvent extends GameEvent {\r\n constructor(public target: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postkill' event is emitted directly after the actor is killed.\r\n */\r\nexport class PostKillEvent extends GameEvent {\r\n constructor(public target: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'start' event is emitted on engine when has started and is ready for interaction.\r\n */\r\nexport class GameStartEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\r\n */\r\nexport class GameStopEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */\r\nexport class PreDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity | Scene | Engine | TileMap) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */\r\nexport class PostDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity | Scene | Engine | TileMap) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'pretransformdraw' event is emitted on actors/entities before any graphics transforms have taken place.\r\n * Useful if you need to completely customize the draw or modify the transform before drawing in the draw step (for example needing\r\n * latest camera positions)\r\n *\r\n */\r\nexport class PreTransformDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'posttransformdraw' event is emitted on actors/entities after all graphics have been draw and transforms reset.\r\n * Useful if you need to completely custom the draw after everything is done.\r\n *\r\n */\r\nexport class PostTransformDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\r\n */\r\nexport class PreDebugDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public target: Entity | Actor | Scene | Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\r\n */\r\nexport class PostDebugDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public target: Entity | Actor | Scene | Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\r\n */\r\nexport class PreUpdateEvent extends GameEvent {\r\n constructor(public engine: Engine, public delta: number, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\r\n */\r\nexport class PostUpdateEvent extends GameEvent {\r\n constructor(public engine: Engine, public delta: number, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'preframe' event is emitted on the engine, before the frame begins.\r\n */\r\nexport class PreFrameEvent extends GameEvent {\r\n constructor(public engine: Engine, public prevStats: FrameStats) {\r\n super();\r\n this.target = engine;\r\n }\r\n}\r\n\r\n/**\r\n * The 'postframe' event is emitted on the engine, after a frame ends.\r\n */\r\nexport class PostFrameEvent extends GameEvent {\r\n constructor(public engine: Engine, public stats: FrameStats) {\r\n super();\r\n this.target = engine;\r\n }\r\n}\r\n\r\n/**\r\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\r\n */\r\nexport class GamepadConnectEvent extends GameEvent {\r\n constructor(public index: number, public gamepad: Gamepad) {\r\n super();\r\n this.target = gamepad;\r\n }\r\n}\r\n\r\n/**\r\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\r\n */\r\nexport class GamepadDisconnectEvent extends GameEvent {\r\n constructor(public index: number, public gamepad: Gamepad) {\r\n super();\r\n this.target = gamepad;\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */\r\nexport class GamepadButtonEvent extends GameEvent {\r\n /**\r\n * @param button The Gamepad button\r\n * @param value A numeric value between 0 and 1\r\n */\r\n constructor(public button: Buttons, public value: number, public target: Gamepad) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */\r\nexport class GamepadAxisEvent extends GameEvent {\r\n /**\r\n * @param axis The Gamepad axis\r\n * @param value A numeric value between -1 and 1\r\n */\r\n constructor(public axis: Axes, public value: number, public target: Gamepad) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event received by the [[Engine]] when the browser window is visible on a screen.\r\n */\r\nexport class VisibleEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\r\n */\r\nexport class HiddenEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\r\n */\r\nexport class PreCollisionEvent extends GameEvent {\r\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that will collided with the current actor\r\n * @param side The side that will be collided with the current actor\r\n * @param intersection Intersection vector\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\r\n */\r\nexport class PostCollisionEvent extends GameEvent {\r\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that did collide with the current actor\r\n * @param side The side that did collide with the current actor\r\n * @param intersection Intersection vector\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\nexport class ContactStartEvent {\r\n constructor(public target: T, public other: T, public side: Side, public contact: CollisionContact) {}\r\n}\r\n\r\nexport class ContactEndEvent {\r\n constructor(public target: T, public other: T, public side: Side, public lastContact: CollisionContact) {}\r\n}\r\n\r\nexport class CollisionPreSolveEvent {\r\n constructor(public target: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {}\r\n}\r\n\r\nexport class CollisionPostSolveEvent {\r\n constructor(public target: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {}\r\n}\r\n\r\n/**\r\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\r\n */\r\nexport class CollisionStartEvent extends GameEvent {\r\n /**\r\n *\r\n * @param actor\r\n * @param other\r\n * @param side\r\n * @param contact\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public contact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\r\n */\r\nexport class CollisionEndEvent extends GameEvent {\r\n /**\r\n *\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public lastContact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\r\n */\r\nexport class InitializeEvent extends GameEvent {\r\n /**\r\n * @param engine The reference to the current engine\r\n */\r\n constructor(public engine: Engine, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on a [[Scene]] on activation\r\n */\r\nexport class ActivateEvent extends GameEvent {\r\n /**\r\n * @param context The context for the scene activation\r\n */\r\n constructor(public context: SceneActivationContext, public target: Scene) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on a [[Scene]] on deactivation\r\n */\r\nexport class DeactivateEvent extends GameEvent {\r\n /**\r\n * @param context The context for the scene deactivation\r\n */\r\n constructor(public context: SceneActivationContext, public target: Scene) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when the graphics bounds completely leaves the screen.\r\n */\r\nexport class ExitViewPortEvent extends GameEvent {\r\n constructor(public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when any part of the graphics bounds are on screen.\r\n */\r\nexport class EnterViewPortEvent extends GameEvent {\r\n constructor(public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\nexport class EnterTriggerEvent extends GameEvent {\r\n constructor(public target: Trigger, public actor: Actor) {\r\n super();\r\n }\r\n}\r\n\r\nexport class ExitTriggerEvent extends GameEvent {\r\n constructor(public target: Trigger, public actor: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when an action starts.\r\n */\r\nexport class ActionStartEvent extends GameEvent {\r\n constructor(public action: Action, public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when an action completes.\r\n */\r\nexport class ActionCompleteEvent extends GameEvent {\r\n constructor(public action: Action, public target: Entity) {\r\n super();\r\n }\r\n}\r\n","import { GameEvent } from '../Events';\r\nimport { Sound } from '../Resources/Sound/Sound';\r\nimport { Actor } from '../Actor';\r\nimport { WebAudioInstance } from '../Resources/Sound/WebAudioInstance';\r\n\r\nexport class MediaEvent extends GameEvent {\r\n /**\r\n * Media event cannot bubble\r\n */\r\n public set bubbles(_value: boolean) {\r\n // stubbed\r\n }\r\n /**\r\n * Media event cannot bubble\r\n */\r\n public get bubbles(): boolean {\r\n return false;\r\n }\r\n /**\r\n * Media event cannot bubble, so they have no path\r\n */\r\n protected get _path(): Actor[] {\r\n return null;\r\n }\r\n /**\r\n * Media event cannot bubble, so they have no path\r\n */\r\n protected set _path(_val: Actor[]) {\r\n // stubbed\r\n }\r\n\r\n constructor(public target: Sound, protected _name: string = 'MediaEvent') {\r\n super();\r\n }\r\n\r\n /**\r\n * Prevents event from bubbling\r\n */\r\n public stopPropagation(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n /**\r\n * Action, that calls when event happens\r\n */\r\n public action(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n /**\r\n * Propagate event further through event path\r\n */\r\n public propagate(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n\r\n public layPath(_actor: Actor): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n}\r\n\r\nexport class NativeSoundEvent extends MediaEvent {\r\n constructor(target: Sound, public track?: WebAudioInstance) {\r\n super(target, 'NativeSoundEvent');\r\n }\r\n}\r\n\r\nexport class NativeSoundProcessedEvent extends MediaEvent {\r\n public data: string | AudioBuffer;\r\n\r\n constructor(target: Sound, private _processedData: string | AudioBuffer) {\r\n super(target, 'NativeSoundProcessedEvent');\r\n\r\n this.data = this._processedData;\r\n }\r\n}\r\n","import { Logger } from './Log';\r\n\r\n/**\r\n * Whether or not the browser can play this file as HTML5 Audio\r\n */\r\nexport function canPlayFile(file: string): boolean {\r\n try {\r\n const a = new Audio();\r\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\r\n const type = file.match(filetype)[1];\r\n if (a.canPlayType('audio/' + type)) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n } catch (e) {\r\n Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e);\r\n return false;\r\n }\r\n}\r\n","import { ExResponse } from '../../Interfaces/AudioImplementation';\r\nimport { Audio } from '../../Interfaces/Audio';\r\nimport { Engine } from '../../Engine';\r\nimport { Resource } from '../Resource';\r\nimport { WebAudioInstance } from './WebAudioInstance';\r\nimport { AudioContextFactory } from './AudioContext';\r\nimport { NativeSoundEvent, NativeSoundProcessedEvent } from '../../Events/MediaEvents';\r\nimport { canPlayFile } from '../../Util/Sound';\r\nimport { Loadable } from '../../Interfaces/Index';\r\nimport { Logger } from '../../Util/Log';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../../EventEmitter';\r\n\r\nexport type SoundEvents = {\r\n volumechange: NativeSoundEvent,\r\n processed: NativeSoundProcessedEvent,\r\n pause: NativeSoundEvent,\r\n stop: NativeSoundEvent,\r\n playbackend: NativeSoundEvent,\r\n resume: NativeSoundEvent,\r\n playbackstart: NativeSoundEvent\r\n}\r\n\r\nexport const SoundEvents = {\r\n VolumeChange: 'volumechange',\r\n Processed: 'processed',\r\n Pause: 'pause',\r\n Stop: 'stop',\r\n PlaybackEnd: 'playbackend',\r\n Resume: 'resume',\r\n PlaybackStart: 'playbackstart'\r\n};\r\n\r\n/**\r\n * The [[Sound]] object allows games built in Excalibur to load audio\r\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\r\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\r\n */\r\nexport class Sound implements Audio, Loadable {\r\n public events = new EventEmitter();\r\n public logger: Logger = Logger.getInstance();\r\n public data: AudioBuffer;\r\n private _resource: Resource;\r\n /**\r\n * Indicates whether the clip should loop when complete\r\n * @param value Set the looping flag\r\n */\r\n public set loop(value: boolean) {\r\n this._loop = value;\r\n\r\n for (const track of this._tracks) {\r\n track.loop = this._loop;\r\n }\r\n\r\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._loop);\r\n }\r\n public get loop(): boolean {\r\n return this._loop;\r\n }\r\n\r\n public set volume(value: number) {\r\n this._volume = value;\r\n\r\n for (const track of this._tracks) {\r\n track.volume = this._volume;\r\n }\r\n\r\n this.events.emit('volumechange', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._volume);\r\n }\r\n public get volume(): number {\r\n return this._volume;\r\n }\r\n\r\n private _duration: number | undefined;\r\n /**\r\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\r\n */\r\n public get duration(): number | undefined {\r\n return this._duration;\r\n }\r\n /**\r\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */\r\n public set duration(duration: number | undefined){\r\n this._duration = duration;\r\n }\r\n\r\n /**\r\n * Return array of Current AudioInstances playing or being paused\r\n */\r\n public get instances(): Audio[] {\r\n return this._tracks;\r\n }\r\n\r\n public get path() {\r\n return this._resource.path;\r\n }\r\n\r\n public set path(val: string) {\r\n this._resource.path = val;\r\n }\r\n\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n private _loop = false;\r\n private _volume = 1;\r\n private _isStopped = false;\r\n // private _isPaused = false;\r\n private _tracks: Audio[] = [];\r\n private _engine: Engine;\r\n private _wasPlayingOnHidden: boolean = false;\r\n private _playbackRate = 1.0;\r\n private _audioContext = AudioContextFactory.create();\r\n\r\n /**\r\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\r\n */\r\n constructor(...paths: string[]) {\r\n this._resource = new Resource('', ExResponse.type.arraybuffer);\r\n /**\r\n * Chrome : MP3, WAV, Ogg\r\n * Firefox : WAV, Ogg,\r\n * IE : MP3, WAV coming soon\r\n * Safari MP3, WAV, Ogg\r\n */\r\n for (const path of paths) {\r\n if (canPlayFile(path)) {\r\n this.path = path;\r\n break;\r\n }\r\n }\r\n\r\n if (!this.path) {\r\n this.logger.warn('This browser does not support any of the audio files specified:', paths.join(', '));\r\n this.logger.warn('Attempting to use', paths[0]);\r\n this.path = paths[0]; // select the first specified\r\n }\r\n }\r\n\r\n public isLoaded() {\r\n return !!this.data;\r\n }\r\n\r\n public async load(): Promise {\r\n if (this.data) {\r\n return this.data;\r\n }\r\n const arraybuffer = await this._resource.load();\r\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\r\n this._duration = this._duration ?? audiobuffer?.duration ?? undefined;\r\n this.events.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer));\r\n return this.data = audiobuffer;\r\n }\r\n\r\n public async decodeAudio(data: ArrayBuffer): Promise {\r\n try {\r\n return await this._audioContext.decodeAudioData(data.slice(0));\r\n } catch (e) {\r\n this.logger.error(\r\n 'Unable to decode ' +\r\n ' this browser may not fully support this format, or the file may be corrupt, ' +\r\n 'if this is an mp3 try removing id3 tags and album art from the file.'\r\n );\r\n return await Promise.reject();\r\n }\r\n }\r\n\r\n public wireEngine(engine: Engine) {\r\n if (engine) {\r\n this._engine = engine;\r\n\r\n this._engine.on('hidden', () => {\r\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\r\n this._wasPlayingOnHidden = true;\r\n this.pause();\r\n }\r\n });\r\n\r\n this._engine.on('visible', () => {\r\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.play();\r\n this._wasPlayingOnHidden = false;\r\n }\r\n });\r\n\r\n this._engine.on('start', () => {\r\n this._isStopped = false;\r\n });\r\n\r\n this._engine.on('stop', () => {\r\n this.stop();\r\n this._isStopped = true;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Returns how many instances of the sound are currently playing\r\n */\r\n public instanceCount(): number {\r\n return this._tracks.length;\r\n }\r\n\r\n /**\r\n * Whether or not the sound is playing right now\r\n */\r\n public isPlaying(): boolean {\r\n return this._tracks.some((t) => t.isPlaying());\r\n }\r\n\r\n public isPaused(): boolean {\r\n return this._tracks.some(t => t.isPaused());\r\n }\r\n\r\n public isStopped(): boolean {\r\n return this._tracks.some(t => t.isStopped());\r\n }\r\n\r\n /**\r\n * Play the sound, returns a promise that resolves when the sound is done playing\r\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\r\n */\r\n public play(volume?: number): Promise {\r\n if (!this.isLoaded()) {\r\n this.logger.warn('Cannot start playing. Resource', this.path, 'is not loaded yet');\r\n\r\n return Promise.resolve(true);\r\n }\r\n\r\n if (this._isStopped) {\r\n this.logger.warn('Cannot start playing. Engine is in a stopped state.');\r\n return Promise.resolve(false);\r\n }\r\n\r\n this.volume = volume || this.volume;\r\n\r\n if (this.isPaused()) {\r\n return this._resumePlayback();\r\n } else {\r\n return this._startPlayback();\r\n }\r\n }\r\n\r\n /**\r\n * Stop the sound, and do not rewind\r\n */\r\n public pause() {\r\n if (!this.isPlaying()) {\r\n return;\r\n }\r\n\r\n for (const track of this._tracks) {\r\n track.pause();\r\n }\r\n\r\n this.events.emit('pause', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Paused all instances of sound', this.path);\r\n }\r\n\r\n /**\r\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\r\n */\r\n public stop() {\r\n for (const track of this._tracks) {\r\n track.stop();\r\n }\r\n\r\n this.events.emit('stop', new NativeSoundEvent(this));\r\n\r\n this._tracks.length = 0;\r\n this.logger.debug('Stopped all instances of sound', this.path);\r\n }\r\n\r\n public get playbackRate(): number {\r\n return this._playbackRate;\r\n }\r\n\r\n public set playbackRate(playbackRate: number) {\r\n this._playbackRate = playbackRate;\r\n this._tracks.forEach(t => {\r\n t.playbackRate = this._playbackRate;\r\n });\r\n }\r\n\r\n public seek(position: number, trackId = 0) {\r\n if (this._tracks.length === 0) {\r\n this._getTrackInstance(this.data);\r\n }\r\n\r\n this._tracks[trackId].seek(position);\r\n }\r\n\r\n public getTotalPlaybackDuration() {\r\n if (!this.isLoaded()) {\r\n this.logger.warnOnce(`Sound from ${this.path} is not loaded, cannot return total playback duration.` +\r\n `Did you forget to add Sound to a loader? https://excaliburjs.com/docs/loaders/`);\r\n return 0;\r\n }\r\n return this.data.duration;\r\n }\r\n\r\n /**\r\n * Return the current playback time of the playing track in seconds from the start.\r\n *\r\n * Optionally specify the track to query if multiple are playing at once.\r\n * @param trackId\r\n */\r\n public getPlaybackPosition(trackId = 0) {\r\n if (this._tracks.length) {\r\n return this._tracks[trackId].getPlaybackPosition();\r\n }\r\n return 0;\r\n }\r\n\r\n\r\n\r\n /**\r\n * Get Id of provided AudioInstance in current trackList\r\n * @param track [[Audio]] which Id is to be given\r\n */\r\n public getTrackId(track: Audio): number {\r\n return this._tracks.indexOf(track);\r\n }\r\n\r\n private async _resumePlayback(): Promise {\r\n if (this.isPaused) {\r\n const resumed: Promise[] = [];\r\n // ensure we resume *current* tracks (if paused)\r\n for (const track of this._tracks) {\r\n resumed.push(track.play().then(() => {\r\n this._tracks.splice(this.getTrackId(track), 1);\r\n return true;\r\n }));\r\n }\r\n\r\n this.events.emit('resume', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Resuming paused instances for sound', this.path, this._tracks);\r\n // resolve when resumed tracks are done\r\n await Promise.all(resumed);\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Starts playback, returns a promise that resolves when playback is complete\r\n */\r\n private async _startPlayback(): Promise {\r\n const track = this._getTrackInstance(this.data);\r\n\r\n const complete = await track.play(() => {\r\n this.events.emit('playbackstart', new NativeSoundEvent(this, track));\r\n this.logger.debug('Playing new instance for sound', this.path);\r\n });\r\n\r\n this.events.emit('playbackend', new NativeSoundEvent(this, track));\r\n\r\n // cleanup any done tracks\r\n const trackId = this.getTrackId(track);\r\n if (trackId !== -1) {\r\n this._tracks.splice(trackId, 1);\r\n }\r\n\r\n return complete;\r\n }\r\n\r\n private _getTrackInstance(data: AudioBuffer): WebAudioInstance {\r\n const newTrack = new WebAudioInstance(data);\r\n\r\n newTrack.loop = this.loop;\r\n newTrack.volume = this.volume;\r\n newTrack.duration = this.duration;\r\n newTrack.playbackRate = this._playbackRate;\r\n\r\n this._tracks.push(newTrack);\r\n\r\n return newTrack;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: SoundEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n","import { WebAudio } from '../Util/WebAudio';\r\nimport { Engine } from '../Engine';\r\nimport { Loadable } from '../Interfaces/Loadable';\r\nimport { Canvas } from '../Graphics/Canvas';\r\nimport { ImageFiltering } from '../Graphics/Filtering';\r\nimport { clamp } from '../Math/util';\r\nimport { Sound } from '../Resources/Sound/Sound';\r\nimport { Future } from '../Util/Future';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { Color } from '../Color';\r\nimport { delay } from '../Util/Util';\r\n\r\nexport interface DefaultLoaderOptions {\r\n /**\r\n * List of loadables\r\n */\r\n loadables?: Loadable[];\r\n}\r\n\r\nexport type LoaderEvents = {\r\n // Add event types here\r\n beforeload: void,\r\n afterload: void,\r\n useraction: void,\r\n loadresourcestart: Loadable,\r\n loadresourceend: Loadable,\r\n}\r\n\r\nexport const LoaderEvents = {\r\n // Add event types here\r\n BeforeLoad: 'beforeload',\r\n AfterLoad: 'afterload',\r\n UserAction: 'useraction',\r\n LoadResourceStart: 'loadresourcestart',\r\n LoadResourceEnd: 'loadresourceend'\r\n};\r\n\r\nexport type LoaderConstructor = new (...args: any[]) => DefaultLoader;\r\n/**\r\n * Returns true if the constructor is for an Excalibur Loader\r\n */\r\nexport function isLoaderConstructor(x: any): x is LoaderConstructor {\r\n return !!x?.prototype && !!x?.prototype?.constructor?.name;\r\n}\r\n\r\nexport class DefaultLoader implements Loadable[]> {\r\n public data: Loadable[];\r\n public events = new EventEmitter();\r\n public canvas: Canvas = new Canvas({\r\n filtering: ImageFiltering.Blended,\r\n smoothing: true,\r\n cache: false,\r\n draw: this.onDraw.bind(this)\r\n });\r\n private _resources: Loadable[] = [];\r\n public get resources(): readonly Loadable[] {\r\n return this._resources;\r\n }\r\n private _numLoaded: number = 0;\r\n public engine: Engine;\r\n\r\n\r\n /**\r\n * @param options Optionally provide the list of resources you want to load at constructor time\r\n */\r\n constructor(options?: DefaultLoaderOptions) {\r\n if (options && options.loadables?.length) {\r\n this.addResources(options.loadables);\r\n }\r\n }\r\n\r\n /**\r\n * Called by the engine before loading\r\n * @param engine\r\n */\r\n public onInitialize(engine: Engine) {\r\n this.engine = engine;\r\n this.canvas.width = this.engine.screen.canvasWidth;\r\n this.canvas.height = this.engine.screen.canvasHeight;\r\n }\r\n\r\n /**\r\n * Return a promise that resolves when the user interacts with the loading screen in some way, usually a click.\r\n *\r\n * It's important to implement this in order to unlock the audio context in the browser. Browsers automatically prevent\r\n * audio from playing until the user performs an action.\r\n *\r\n */\r\n public async onUserAction(): Promise {\r\n\r\n return await Promise.resolve();\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called directly before loading starts\r\n */\r\n public async onBeforeLoad() {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called after loading has completed\r\n */\r\n public async onAfterLoad() {\r\n // override me\r\n await delay(500, this.engine.clock); // avoid a flicker\r\n }\r\n\r\n /**\r\n * Add a resource to the loader to load\r\n * @param loadable Resource to add\r\n */\r\n public addResource(loadable: Loadable) {\r\n this._resources.push(loadable);\r\n }\r\n\r\n /**\r\n * Add a list of resources to the loader to load\r\n * @param loadables The list of resources to load\r\n */\r\n public addResources(loadables: Loadable[]) {\r\n let i = 0;\r\n const len = loadables.length;\r\n\r\n for (i; i < len; i++) {\r\n this.addResource(loadables[i]);\r\n }\r\n }\r\n\r\n public markResourceComplete(): void {\r\n this._numLoaded++;\r\n }\r\n\r\n /**\r\n * Returns the progress of the loader as a number between [0, 1] inclusive.\r\n */\r\n public get progress(): number {\r\n const total = this._resources.length;\r\n return total > 0 ? clamp(this._numLoaded, 0, total) / total : 1;\r\n }\r\n\r\n /**\r\n * Returns true if the loader has completely loaded all resources\r\n */\r\n public isLoaded() {\r\n return this._numLoaded === this._resources.length;\r\n }\r\n\r\n private _totalTimeMs = 0;\r\n\r\n /**\r\n * Optionally override the onUpdate\r\n * @param engine\r\n * @param elapsedMilliseconds\r\n */\r\n onUpdate(engine: Engine, elapsedMilliseconds: number): void {\r\n this._totalTimeMs += elapsedMilliseconds;\r\n // override me\r\n }\r\n\r\n /**\r\n * Optionally override the onDraw\r\n */\r\n onDraw(ctx: CanvasRenderingContext2D) {\r\n const seconds = this._totalTimeMs / 1000;\r\n\r\n ctx.fillStyle = Color.Black.toRGBA();\r\n ctx.fillRect(0, 0, this.engine.screen.drawWidth, this.engine.screen.drawHeight);\r\n\r\n ctx.save();\r\n ctx.translate(this.engine.screen.center.x, this.engine.screen.center.y);\r\n const speed = seconds * 10;\r\n ctx.strokeStyle = 'white';\r\n ctx.lineWidth = 10;\r\n ctx.lineCap = 'round';\r\n ctx.arc(0, 0, 40, speed, speed + (Math.PI * 3 / 2));\r\n ctx.stroke();\r\n\r\n ctx.fillStyle = 'white';\r\n ctx.font = '16px sans-serif';\r\n const text = (this.progress * 100).toFixed(0) + '%';\r\n const textbox = ctx.measureText(text);\r\n const width = Math.abs(textbox.actualBoundingBoxLeft) + Math.abs(textbox.actualBoundingBoxRight);\r\n const height = Math.abs(textbox.actualBoundingBoxAscent) + Math.abs(textbox.actualBoundingBoxDescent);\r\n ctx.fillText(text, -width / 2, height / 2); // center\r\n ctx.restore();\r\n }\r\n\r\n\r\n private _loadingFuture = new Future();\r\n public areResourcesLoaded() {\r\n return this._loadingFuture.promise;\r\n }\r\n\r\n /**\r\n * Not meant to be overridden\r\n *\r\n * Begin loading all of the supplied resources, returning a promise\r\n * that resolves when loading of all is complete AND the user has interacted with the loading screen\r\n */\r\n public async load(): Promise[]> {\r\n await this.onBeforeLoad();\r\n this.events.emit('beforeload');\r\n this.canvas.flagDirty();\r\n\r\n await Promise.all(\r\n this._resources.map(async (r) => {\r\n this.events.emit('loadresourcestart', r);\r\n await r.load().finally(() => {\r\n // capture progress\r\n this._numLoaded++;\r\n this.canvas.flagDirty();\r\n this.events.emit('loadresourceend', r);\r\n });\r\n })\r\n );\r\n\r\n // Wire all sound to the engine\r\n for (const resource of this._resources) {\r\n if (resource instanceof Sound) {\r\n resource.wireEngine(this.engine);\r\n }\r\n }\r\n\r\n this._loadingFuture.resolve();\r\n this.canvas.flagDirty();\r\n // Unlock browser AudioContext in after user gesture\r\n // See: https://github.com/excaliburjs/Excalibur/issues/262\r\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\r\n await this.onUserAction();\r\n this.events.emit('useraction');\r\n await WebAudio.unlock();\r\n\r\n await this.onAfterLoad();\r\n this.events.emit('afterload');\r\n return (this.data = this._resources);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: LoaderEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n","import { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\n\r\n/**\r\n * A canvas linecap style. \"butt\" is the default flush style, \"round\" is a semi-circle cap with a radius half the width of\r\n * the line, and \"square\" is a rectangle that is an equal width and half height cap.\r\n */\r\nexport type LineCapStyle = 'butt' | 'round' | 'square';\r\n\r\n/* istanbul ignore next */\r\n/**\r\n * Draw a line on canvas context\r\n * @param ctx The canvas context\r\n * @param color The color of the line\r\n * @param x1 The start x coordinate\r\n * @param y1 The start y coordinate\r\n * @param x2 The ending x coordinate\r\n * @param y2 The ending y coordinate\r\n * @param thickness The line thickness\r\n * @param cap The [[LineCapStyle]] (butt, round, or square)\r\n */\r\nexport function line(\r\n ctx: CanvasRenderingContext2D,\r\n color: Color = Color.Red,\r\n x1: number,\r\n y1: number,\r\n x2: number,\r\n y2: number,\r\n thickness: number = 1,\r\n cap: LineCapStyle = 'butt'\r\n) {\r\n ctx.save();\r\n ctx.beginPath();\r\n ctx.lineWidth = thickness;\r\n ctx.lineCap = cap;\r\n ctx.strokeStyle = color.toString();\r\n ctx.moveTo(x1, y1);\r\n ctx.lineTo(x2, y2);\r\n ctx.closePath();\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n\r\n/* istanbul ignore next */\r\n/**\r\n * Draw the vector as a point onto the canvas.\r\n */\r\nexport function point(ctx: CanvasRenderingContext2D, color: Color = Color.Red, point: Vector): void {\r\n ctx.beginPath();\r\n ctx.strokeStyle = color.toString();\r\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\r\n ctx.closePath();\r\n ctx.stroke();\r\n}\r\n\r\n/**\r\n * Draw the vector as a line onto the canvas starting a origin point.\r\n */\r\n/* istanbul ignore next */\r\n/**\r\n *\r\n */\r\nexport function vector(ctx: CanvasRenderingContext2D, color: Color, origin: Vector, vector: Vector, scale: number = 1.0): void {\r\n const c = color ? color.toString() : 'blue';\r\n const v = vector.scale(scale);\r\n ctx.beginPath();\r\n ctx.strokeStyle = c;\r\n ctx.moveTo(origin.x, origin.y);\r\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\r\n ctx.closePath();\r\n ctx.stroke();\r\n}\r\n\r\n/**\r\n * Represents border radius values\r\n */\r\nexport interface BorderRadius {\r\n /**\r\n * Top-left\r\n */\r\n tl: number;\r\n /**\r\n * Top-right\r\n */\r\n tr: number;\r\n /**\r\n * Bottom-right\r\n */\r\n br: number;\r\n /**\r\n * Bottom-left\r\n */\r\n bl: number;\r\n}\r\n\r\n/**\r\n * Draw a round rectangle on a canvas context\r\n * @param ctx The canvas context\r\n * @param x The top-left x coordinate\r\n * @param y The top-left y coordinate\r\n * @param width The width of the rectangle\r\n * @param height The height of the rectangle\r\n * @param radius The border radius of the rectangle\r\n * @param stroke The [[Color]] to stroke rectangle with\r\n * @param fill The [[Color]] to fill rectangle with\r\n */\r\nexport function roundRect(\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n width: number,\r\n height: number,\r\n radius: number | BorderRadius = 5,\r\n stroke: Color = Color.White,\r\n fill: Color = null\r\n) {\r\n let br: BorderRadius;\r\n\r\n if (typeof radius === 'number') {\r\n br = { tl: radius, tr: radius, br: radius, bl: radius };\r\n } else {\r\n const defaultRadius: BorderRadius = { tl: 0, tr: 0, br: 0, bl: 0 };\r\n\r\n for (const prop in defaultRadius) {\r\n if (defaultRadius.hasOwnProperty(prop)) {\r\n const side = prop;\r\n br[side] = radius[side] || defaultRadius[side];\r\n }\r\n }\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(x + br.tl, y);\r\n ctx.lineTo(x + width - br.tr, y);\r\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\r\n ctx.lineTo(x + width, y + height - br.br);\r\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\r\n ctx.lineTo(x + br.bl, y + height);\r\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\r\n ctx.lineTo(x, y + br.tl);\r\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\r\n ctx.closePath();\r\n\r\n if (fill) {\r\n ctx.fillStyle = fill.toString();\r\n ctx.fill();\r\n }\r\n\r\n if (stroke) {\r\n ctx.strokeStyle = stroke.toString();\r\n ctx.stroke();\r\n }\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function circle(\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n radius: number,\r\n stroke: Color = Color.White,\r\n fill: Color = null\r\n) {\r\n ctx.beginPath();\r\n ctx.arc(x, y, radius, 0, Math.PI * 2);\r\n ctx.closePath();\r\n\r\n if (fill) {\r\n ctx.fillStyle = fill.toString();\r\n ctx.fill();\r\n }\r\n\r\n if (stroke) {\r\n ctx.strokeStyle = stroke.toString();\r\n ctx.stroke();\r\n }\r\n}\r\n","export default \"data:image/png;base64,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\"","import { Color } from '../Color';\r\nimport { Loadable } from '../Interfaces/Loadable';\r\nimport * as DrawUtil from '../Util/DrawUtil';\r\n\r\nimport logoImg from './Loader.logo.png';\r\nimport loaderCss from './Loader.css';\r\nimport { Vector } from '../Math/vector';\r\nimport { delay } from '../Util/Util';\r\nimport { EventEmitter } from '../EventEmitter';\r\nimport { DefaultLoader, DefaultLoaderOptions } from './DefaultLoader';\r\nimport { Engine } from '../Engine';\r\nimport { Screen } from '../Screen';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport interface LoaderOptions extends DefaultLoaderOptions {\r\n /**\r\n * Go fullscreen after loading and clicking play\r\n */\r\n fullscreenAfterLoad?: boolean;\r\n /**\r\n * Fullscreen container element or id\r\n */\r\n fullscreenContainer?: HTMLElement | string;\r\n}\r\n\r\n/**\r\n * Pre-loading assets\r\n *\r\n * The loader provides a mechanism to preload multiple resources at\r\n * one time. The loader must be passed to the engine in order to\r\n * trigger the loading progress bar.\r\n *\r\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\r\n *\r\n * ## Example: Pre-loading resources for a game\r\n *\r\n * ```js\r\n * // create a loader\r\n * var loader = new ex.Loader();\r\n *\r\n * // create a resource dictionary (best practice is to keep a separate file)\r\n * var resources = {\r\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\r\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\r\n * };\r\n *\r\n * // loop through dictionary and add to loader\r\n * for (var loadable in resources) {\r\n * if (resources.hasOwnProperty(loadable)) {\r\n * loader.addResource(resources[loadable]);\r\n * }\r\n * }\r\n *\r\n * // start game\r\n * game.start(loader).then(function () {\r\n * console.log(\"Game started!\");\r\n * });\r\n * ```\r\n *\r\n * ## Customize the Loader\r\n *\r\n * The loader can be customized to show different, text, logo, background color, and button.\r\n *\r\n * ```typescript\r\n * const loader = new ex.Loader([playerTexture]);\r\n *\r\n * // The loaders button text can simply modified using this\r\n * loader.playButtonText = 'Start the best game ever';\r\n *\r\n * // The logo can be changed by inserting a base64 image string here\r\n *\r\n * loader.logo = 'data:image/png;base64,iVBORw...';\r\n * loader.logoWidth = 15;\r\n * loader.logoHeight = 14;\r\n *\r\n * // The background color can be changed like so by supplying a valid CSS color string\r\n *\r\n * loader.backgroundColor = 'red'\r\n * loader.backgroundColor = '#176BAA'\r\n *\r\n * // To build a completely new button\r\n * loader.startButtonFactory = () => {\r\n * let myButton = document.createElement('button');\r\n * myButton.textContent = 'The best button';\r\n * return myButton;\r\n * };\r\n *\r\n * engine.start(loader).then(() => {});\r\n * ```\r\n */\r\nexport class Loader extends DefaultLoader {\r\n private _logger = Logger.getInstance();\r\n private static _DEFAULT_LOADER_OPTIONS: LoaderOptions = {\r\n loadables: [],\r\n fullscreenAfterLoad: false,\r\n fullscreenContainer: undefined\r\n };\r\n private _originalOptions: LoaderOptions = {loadables:[]};\r\n public events = new EventEmitter();\r\n public screen: Screen;\r\n private _playButtonShown: boolean = false;\r\n\r\n // logo drawing stuff\r\n\r\n // base64 string encoding of the excalibur logo (logo-white.png)\r\n public logo = logoImg;\r\n public logoWidth = 468;\r\n public logoHeight = 118;\r\n /**\r\n * Positions the top left corner of the logo image\r\n * If not set, the loader automatically positions the logo\r\n */\r\n public logoPosition: Vector | null;\r\n /**\r\n * Positions the top left corner of the play button.\r\n * If not set, the loader automatically positions the play button\r\n */\r\n public playButtonPosition: Vector | null;\r\n /**\r\n * Positions the top left corner of the loading bar\r\n * If not set, the loader automatically positions the loading bar\r\n */\r\n public loadingBarPosition: Vector | null;\r\n\r\n /**\r\n * Gets or sets the color of the loading bar, default is [[Color.White]]\r\n */\r\n public loadingBarColor: Color = Color.White;\r\n\r\n /**\r\n * Gets or sets the background color of the loader as a hex string\r\n */\r\n public backgroundColor: string = '#176BAA';\r\n\r\n protected _imageElement: HTMLImageElement;\r\n protected get _image() {\r\n if (!this._imageElement) {\r\n this._imageElement = new Image();\r\n this._imageElement.src = this.logo;\r\n }\r\n\r\n return this._imageElement;\r\n }\r\n\r\n public suppressPlayButton: boolean = false;\r\n public get playButtonRootElement(): HTMLElement | null {\r\n return this._playButtonRootElement;\r\n }\r\n public get playButtonElement(): HTMLButtonElement | null {\r\n return this._playButtonElement;\r\n }\r\n protected _playButtonRootElement: HTMLElement;\r\n protected _playButtonElement: HTMLButtonElement;\r\n protected _styleBlock: HTMLStyleElement;\r\n /** Loads the css from Loader.css */\r\n protected _playButtonStyles: string = loaderCss.toString();\r\n protected get _playButton() {\r\n const existingRoot = document.getElementById('excalibur-play-root');\r\n if (existingRoot) {\r\n this._playButtonRootElement = existingRoot;\r\n }\r\n if (!this._playButtonRootElement) {\r\n this._playButtonRootElement = document.createElement('div');\r\n this._playButtonRootElement.id = 'excalibur-play-root';\r\n this._playButtonRootElement.style.position = 'absolute';\r\n document.body.appendChild(this._playButtonRootElement);\r\n }\r\n if (!this._styleBlock) {\r\n this._styleBlock = document.createElement('style');\r\n this._styleBlock.textContent = this._playButtonStyles;\r\n document.head.appendChild(this._styleBlock);\r\n }\r\n if (!this._playButtonElement) {\r\n this._playButtonElement = this.startButtonFactory();\r\n this._playButtonRootElement.appendChild(this._playButtonElement);\r\n }\r\n return this._playButtonElement;\r\n }\r\n\r\n /**\r\n * Get/set play button text\r\n */\r\n public playButtonText: string = 'Play game';\r\n\r\n /**\r\n * Return a html button element for excalibur to use as a play button\r\n */\r\n public startButtonFactory = () => {\r\n let buttonElement: HTMLButtonElement = document.getElementById('excalibur-play') as HTMLButtonElement;\r\n if (!buttonElement) {\r\n buttonElement = document.createElement('button');\r\n }\r\n\r\n buttonElement.id = 'excalibur-play';\r\n buttonElement.textContent = this.playButtonText;\r\n buttonElement.style.display = 'none';\r\n return buttonElement;\r\n };\r\n\r\n /**\r\n * @param options Optionally provide options to loader\r\n */\r\n constructor(options?: LoaderOptions);\r\n /**\r\n * @param loadables Optionally provide the list of resources you want to load at constructor time\r\n */\r\n constructor(loadables?: Loadable[]);\r\n constructor(loadablesOrOptions?: Loadable[] | LoaderOptions) {\r\n const options = Array.isArray(loadablesOrOptions) ? {\r\n loadables: loadablesOrOptions\r\n } : loadablesOrOptions;\r\n super(options);\r\n this._originalOptions = { ...Loader._DEFAULT_LOADER_OPTIONS, ...options };\r\n }\r\n\r\n public override onInitialize(engine: Engine): void {\r\n this.engine = engine;\r\n this.screen = engine.screen;\r\n this.canvas.width = this.engine.canvas.width;\r\n this.canvas.height = this.engine.canvas.height;\r\n }\r\n\r\n /**\r\n * Shows the play button and returns a promise that resolves when clicked\r\n */\r\n public async showPlayButton(): Promise {\r\n if (this.suppressPlayButton) {\r\n this.hidePlayButton();\r\n // Delay is to give the logo a chance to show, otherwise don't delay\r\n await delay(500, this.engine?.clock);\r\n } else {\r\n const resizeHandler = () => {\r\n try {\r\n this._positionPlayButton();\r\n } catch {\r\n // swallow if can't position\r\n };\r\n };\r\n if (this.engine?.browser) {\r\n this.engine.browser.window.on('resize', resizeHandler);\r\n }\r\n this._playButtonShown = true;\r\n this._playButton.style.display = 'block';\r\n document.body.addEventListener('keyup', (evt: KeyboardEvent) => {\r\n if (evt.key === 'Enter') {\r\n this._playButton.click();\r\n }\r\n });\r\n this._positionPlayButton();\r\n const playButtonClicked = new Promise(resolve => {\r\n const startButtonHandler = (e: Event) => {\r\n // We want to stop propagation to keep bubbling to the engine pointer handlers\r\n e.stopPropagation();\r\n // Hide Button after click\r\n this.hidePlayButton();\r\n if (this.engine?.browser) {\r\n this.engine.browser.window.off('resize', resizeHandler);\r\n }\r\n\r\n if (this._originalOptions.fullscreenAfterLoad) {\r\n try {\r\n this._logger.info('requesting fullscreen');\r\n if (this._originalOptions.fullscreenContainer instanceof HTMLElement) {\r\n this._originalOptions.fullscreenContainer.requestFullscreen();\r\n } else {\r\n this.engine.screen.goFullScreen(this._originalOptions.fullscreenContainer);\r\n }\r\n } catch (error) {\r\n this._logger.error('could not go fullscreen', error);\r\n }\r\n }\r\n\r\n resolve();\r\n };\r\n this._playButton.addEventListener('click', startButtonHandler);\r\n this._playButton.addEventListener('touchend', startButtonHandler);\r\n this._playButton.addEventListener('pointerup', startButtonHandler);\r\n });\r\n\r\n return await playButtonClicked;\r\n }\r\n }\r\n\r\n public hidePlayButton() {\r\n this._playButtonShown = false;\r\n this._playButton.style.display = 'none';\r\n }\r\n\r\n /**\r\n * Clean up generated elements for the loader\r\n */\r\n public dispose() {\r\n if (this._playButtonRootElement.parentElement) {\r\n this._playButtonRootElement.removeChild(this._playButtonElement);\r\n document.body.removeChild(this._playButtonRootElement);\r\n document.head.removeChild(this._styleBlock);\r\n this._playButtonRootElement = null;\r\n this._playButtonElement = null;\r\n this._styleBlock = null;\r\n }\r\n }\r\n\r\n data: Loadable[];\r\n\r\n public override async onUserAction(): Promise {\r\n // short delay in showing the button for aesthetics\r\n await delay(200, this.engine?.clock);\r\n this.canvas.flagDirty();\r\n // show play button\r\n await this.showPlayButton();\r\n }\r\n\r\n private _configuredPixelRatio: number | null = null;\r\n public override async onBeforeLoad(): Promise {\r\n this._configuredPixelRatio = this.screen.pixelRatioOverride;\r\n // Push the current user entered resolution/viewport\r\n this.screen.pushResolutionAndViewport();\r\n // Configure resolution for loader, it expects resolution === viewport\r\n this.screen.resolution = this.screen.viewport;\r\n this.screen.pixelRatioOverride = 1;\r\n this.screen.applyResolutionAndViewport();\r\n\r\n this.canvas.width = this.engine.canvas.width;\r\n this.canvas.height = this.engine.canvas.height;\r\n\r\n await this._image?.decode(); // decode logo if it exists\r\n }\r\n\r\n // eslint-disable-next-line require-await\r\n public override async onAfterLoad(): Promise {\r\n this.screen.pixelRatioOverride = this._configuredPixelRatio;\r\n this.screen.popResolutionAndViewport();\r\n this.screen.applyResolutionAndViewport();\r\n this.dispose();\r\n }\r\n\r\n private _positionPlayButton() {\r\n if (this.engine) {\r\n const screenHeight = this.engine.screen.viewport.height;\r\n const screenWidth = this.engine.screen.viewport.width;\r\n if (this._playButtonRootElement) {\r\n const left = this.engine.canvas.offsetLeft;\r\n const top = this.engine.canvas.offsetTop;\r\n const buttonWidth = this._playButton.clientWidth;\r\n const buttonHeight = this._playButton.clientHeight;\r\n if (this.playButtonPosition) {\r\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\r\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\r\n } else {\r\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\r\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Loader draw function. Draws the default Excalibur loading screen.\r\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\r\n * to customize the drawing, or just override entire method.\r\n */\r\n public override onDraw(ctx: CanvasRenderingContext2D) {\r\n const canvasHeight = this.engine.canvasHeight / this.engine.pixelRatio;\r\n const canvasWidth = this.engine.canvasWidth / this.engine.pixelRatio;\r\n\r\n this._positionPlayButton();\r\n\r\n ctx.fillStyle = this.backgroundColor;\r\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\r\n\r\n let logoY = canvasHeight / 2;\r\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\r\n let logoX = canvasWidth / 2 - width / 2;\r\n\r\n if (this.logoPosition) {\r\n logoX = this.logoPosition.x;\r\n logoY = this.logoPosition.y;\r\n }\r\n\r\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\r\n const oldAntialias = this.engine.getAntialiasing();\r\n this.engine.setAntialiasing(true);\r\n if (!this.logoPosition) {\r\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\r\n } else {\r\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\r\n }\r\n\r\n // loading box\r\n if (!this.suppressPlayButton && this._playButtonShown) {\r\n this.engine.setAntialiasing(oldAntialias);\r\n return;\r\n }\r\n\r\n let loadingX = logoX;\r\n let loadingY = logoY;\r\n if (this.loadingBarPosition) {\r\n loadingX = this.loadingBarPosition.x;\r\n loadingY = this.loadingBarPosition.y;\r\n }\r\n\r\n ctx.lineWidth = 2;\r\n DrawUtil.roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\r\n const progress = width * this.progress;\r\n const margin = 5;\r\n const progressWidth = progress - margin * 2;\r\n const height = 20 - margin * 2;\r\n DrawUtil.roundRect(\r\n ctx,\r\n loadingX + margin,\r\n loadingY + margin,\r\n progressWidth > 10 ? progressWidth : 10,\r\n height,\r\n 5,\r\n null,\r\n this.loadingBarColor\r\n );\r\n this.engine.setAntialiasing(oldAntialias);\r\n }\r\n}\r\n","import { Logger } from './Log';\r\n/**\r\n * This is the list of features that will be used to log the supported\r\n * features to the console when Detector.logBrowserFeatures() is called.\r\n */\r\n\r\nconst REPORTED_FEATURES: { [key: string]: string } = {\r\n webgl: 'WebGL',\r\n webaudio: 'WebAudio',\r\n gamepadapi: 'Gamepad API'\r\n};\r\n\r\n/**\r\n * Interface for detected browser features matrix\r\n */\r\nexport interface DetectedFeatures {\r\n readonly canvas: boolean;\r\n readonly arraybuffer: boolean;\r\n readonly dataurl: boolean;\r\n readonly objecturl: boolean;\r\n readonly rgba: boolean;\r\n readonly webaudio: boolean;\r\n readonly webgl: boolean;\r\n readonly gamepadapi: boolean;\r\n}\r\n\r\ninterface CriticalTests {\r\n canvasSupport(): boolean;\r\n arrayBufferSupport(): boolean;\r\n dataUrlSupport(): boolean;\r\n objectUrlSupport(): boolean;\r\n rgbaSupport(): boolean;\r\n}\r\n\r\ninterface WarningTests {\r\n webAudioSupport(): boolean;\r\n webglSupport(): boolean;\r\n}\r\n\r\n/**\r\n * Excalibur internal feature detection helper class\r\n */\r\nexport class Detector {\r\n private _features: DetectedFeatures = null;\r\n\r\n public failedTests: string[] = [];\r\n\r\n public constructor() {\r\n this._features = this._loadBrowserFeatures();\r\n }\r\n\r\n /**\r\n * Returns a map of currently supported browser features. This method\r\n * treats the features as a singleton and will only calculate feature\r\n * support if it has not previously been done.\r\n */\r\n public getBrowserFeatures(): DetectedFeatures {\r\n if (this._features === null) {\r\n this._features = this._loadBrowserFeatures();\r\n }\r\n return this._features;\r\n }\r\n\r\n /**\r\n * Report on non-critical browser support for debugging purposes.\r\n * Use native browser console colors for visibility.\r\n */\r\n public logBrowserFeatures(): void {\r\n let msg = '%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n';\r\n const args = ['font-weight: bold; color: navy', 'font-weight: normal; color: inherit'];\r\n\r\n const supported: any = this.getBrowserFeatures();\r\n for (const feature of Object.keys(REPORTED_FEATURES)) {\r\n if (supported[feature]) {\r\n msg += '(%c\\u2713%c)'; // (✓)\r\n args.push('font-weight: bold; color: green');\r\n args.push('font-weight: normal; color: inherit');\r\n } else {\r\n msg += '(%c\\u2717%c)'; // (✗)\r\n args.push('font-weight: bold; color: red');\r\n args.push('font-weight: normal; color: inherit');\r\n }\r\n\r\n msg += ' ' + REPORTED_FEATURES[feature] + '\\n';\r\n }\r\n\r\n args.unshift(msg);\r\n // eslint-disable-next-line no-console\r\n console.log.apply(console, args);\r\n }\r\n\r\n /**\r\n * Executes several IIFE's to get a constant reference to supported\r\n * features within the current execution context.\r\n */\r\n private _loadBrowserFeatures(): DetectedFeatures {\r\n return {\r\n // IIFE to check canvas support\r\n canvas: (() => {\r\n return this._criticalTests.canvasSupport();\r\n })(),\r\n\r\n // IIFE to check arraybuffer support\r\n arraybuffer: (() => {\r\n return this._criticalTests.arrayBufferSupport();\r\n })(),\r\n\r\n // IIFE to check dataurl support\r\n dataurl: (() => {\r\n return this._criticalTests.dataUrlSupport();\r\n })(),\r\n\r\n // IIFE to check objecturl support\r\n objecturl: (() => {\r\n return this._criticalTests.objectUrlSupport();\r\n })(),\r\n\r\n // IIFE to check rgba support\r\n rgba: (() => {\r\n return this._criticalTests.rgbaSupport();\r\n })(),\r\n\r\n // IIFE to check webaudio support\r\n webaudio: (() => {\r\n return this._warningTest.webAudioSupport();\r\n })(),\r\n\r\n // IIFE to check webgl support\r\n webgl: (() => {\r\n return this._warningTest.webglSupport();\r\n })(),\r\n\r\n // IIFE to check gamepadapi support\r\n gamepadapi: (() => {\r\n return !!(navigator).getGamepads;\r\n })()\r\n };\r\n }\r\n\r\n // critical browser features required for ex to run\r\n private _criticalTests: CriticalTests = {\r\n // Test canvas/2d context support\r\n canvasSupport: function() {\r\n const elem = document.createElement('canvas');\r\n return !!(elem.getContext && elem.getContext('2d'));\r\n },\r\n\r\n // Test array buffer support ex uses for downloading binary data\r\n arrayBufferSupport: function() {\r\n const xhr = new XMLHttpRequest();\r\n xhr.open('GET', '/');\r\n try {\r\n xhr.responseType = 'arraybuffer';\r\n } catch (e) {\r\n return false;\r\n }\r\n return xhr.responseType === 'arraybuffer';\r\n },\r\n\r\n // Test data urls ex uses for sprites\r\n dataUrlSupport: function() {\r\n const canvas = document.createElement('canvas');\r\n return canvas.toDataURL('image/png').indexOf('data:image/png') === 0;\r\n },\r\n\r\n // Test object url support for loading\r\n objectUrlSupport: function() {\r\n return 'URL' in window && 'revokeObjectURL' in URL && 'createObjectURL' in URL;\r\n },\r\n\r\n // RGBA support for colors\r\n rgbaSupport: function() {\r\n const style = document.createElement('a').style;\r\n style.cssText = 'background-color:rgba(150,255,150,.5)';\r\n return ('' + style.backgroundColor).indexOf('rgba') > -1;\r\n }\r\n };\r\n\r\n // warnings excalibur performance will be degraded\r\n private _warningTest: WarningTests = {\r\n webAudioSupport: function() {\r\n return !!(\r\n (window).AudioContext ||\r\n (window).webkitAudioContext ||\r\n (window).mozAudioContext ||\r\n (window).msAudioContext ||\r\n (window).oAudioContext\r\n );\r\n },\r\n webglSupport: function() {\r\n const elem = document.createElement('canvas');\r\n return !!(elem.getContext && elem.getContext('webgl'));\r\n }\r\n };\r\n\r\n public test(): boolean {\r\n // Critical test will for ex not to run\r\n let failedCritical = false;\r\n for (const test in this._criticalTests) {\r\n if (!this._criticalTests[test].call(this)) {\r\n this.failedTests.push(test);\r\n Logger.getInstance().error('Critical browser feature missing, Excalibur requires:', test);\r\n failedCritical = true;\r\n }\r\n }\r\n if (failedCritical) {\r\n return false;\r\n }\r\n\r\n // Warning tests do not for ex to return false to compatibility\r\n for (const warning in this._warningTest) {\r\n if (!this._warningTest[warning]()) {\r\n Logger.getInstance().warn('Warning browser feature missing, Excalibur will have reduced performance:', warning);\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n","/**\r\n * An enum that describes the types of collisions bodies can participate in\r\n */\r\nexport enum CollisionType {\r\n /**\r\n * Bodies with the `PreventCollision` setting do not participate in any\r\n * collisions and do not raise collision events.\r\n */\r\n PreventCollision = 'PreventCollision',\r\n /**\r\n * Bodies with the `Passive` setting only raise collision events, but are not\r\n * influenced or moved by other bodies and do not influence or move other bodies.\r\n * This is useful for use in trigger type behavior.\r\n */\r\n Passive = 'Passive',\r\n /**\r\n * Bodies with the `Active` setting raise collision events and participate\r\n * in collisions with other bodies and will be push or moved by bodies sharing\r\n * the `Active` or `Fixed` setting.\r\n */\r\n Active = 'Active',\r\n /**\r\n * Bodies with the `Fixed` setting raise collision events and participate in\r\n * collisions with other bodies. Actors with the `Fixed` setting will not be\r\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\r\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\r\n * not be pushed or moved by each other, they will not interact except to throw\r\n * collision events.\r\n */\r\n Fixed = 'Fixed'\r\n}\r\n","/**\r\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\r\n */\r\nexport enum CoordPlane {\r\n /**\r\n * The world coordinate plane (default) represents world space, any entities drawn with world\r\n * space move when the camera moves.\r\n */\r\n World = 'world',\r\n /**\r\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\r\n * to screen coordinates ignoring the camera.\r\n */\r\n Screen = 'screen'\r\n}","import { Vector } from './vector';\r\n\r\nexport interface VectorViewOptions {\r\n getX: () => number;\r\n getY: () => number;\r\n setX: (x: number) => void;\r\n setY: (y: number) => void;\r\n}\r\nexport class VectorView extends Vector {\r\n private _getX: () => number;\r\n private _getY: () => number;\r\n private _setX: (x: number) => void;\r\n private _setY: (y: number) => void;\r\n constructor(options: VectorViewOptions) {\r\n super(0, 0);\r\n this._getX = options.getX;\r\n this._getY = options.getY;\r\n this._setX = options.setX;\r\n this._setY = options.setY;\r\n }\r\n public get x() {\r\n return (this._x = this._getX());\r\n }\r\n\r\n public set x(val) {\r\n this._setX(val);\r\n this._x = val;\r\n }\r\n\r\n public get y() {\r\n return (this._y = this._getY());\r\n }\r\n public set y(val) {\r\n this._setY(val);\r\n this._y = val;\r\n }\r\n}\r\n","import { Vector } from './vector';\r\n\r\n/**\r\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\r\n */\r\nexport class WatchVector extends Vector {\r\n constructor(public original: Vector, public change: (x: number, y: number) => any) {\r\n super(original.x, original.y);\r\n }\r\n public get x() {\r\n return this._x = this.original.x;\r\n }\r\n\r\n public set x(newX: number) {\r\n this.change(newX, this._y);\r\n this._x = this.original.x = newX;\r\n }\r\n\r\n public get y() {\r\n return this._y = this.original.y;\r\n }\r\n\r\n public set y(newY: number) {\r\n this.change(this._x, newY);\r\n this._y = this.original.y = newY;\r\n }\r\n}","import { AffineMatrix } from './affine-matrix';\r\nimport { canonicalizeAngle } from './util';\r\nimport { vec, Vector } from './vector';\r\nimport { VectorView } from './vector-view';\r\nimport { WatchVector } from './watch-vector';\r\n\r\nexport class Transform {\r\n private _parent: Transform | null = null;\r\n get parent() {\r\n return this._parent;\r\n }\r\n set parent(transform: Transform | null) {\r\n if (this._parent) {\r\n const index = this._parent._children.indexOf(this);\r\n if (index > -1) {\r\n this._parent._children.splice(index, 1);\r\n }\r\n }\r\n this._parent = transform;\r\n if (this._parent) {\r\n this._parent._children.push(this);\r\n }\r\n this.flagDirty();\r\n }\r\n get children(): readonly Transform[] {\r\n return this._children;\r\n }\r\n private _children: Transform[] = [];\r\n\r\n private _pos: Vector = vec(0, 0);\r\n set pos(v: Vector) {\r\n if (!v.equals(this._pos)) {\r\n this._pos.x = v.x;\r\n this._pos.y = v.y;\r\n this.flagDirty();\r\n }\r\n }\r\n get pos() {\r\n return new WatchVector(this._pos, (x, y) => {\r\n if (x !== this._pos.x || y !== this._pos.y) {\r\n this.flagDirty();\r\n }\r\n });\r\n }\r\n\r\n set globalPos(v: Vector) {\r\n let localPos = v.clone();\r\n if (this.parent) {\r\n localPos = this.parent.inverse.multiply(v);\r\n }\r\n if (!localPos.equals(this._pos)) {\r\n this._pos = localPos;\r\n this.flagDirty();\r\n }\r\n }\r\n get globalPos() {\r\n return new VectorView({\r\n getX: () => this.matrix.data[4],\r\n getY: () => this.matrix.data[5],\r\n setX: (x) => {\r\n if (this.parent) {\r\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\r\n this.pos.x = newX;\r\n } else {\r\n this.pos.x = x;\r\n }\r\n if (x !== this.matrix.data[4]) {\r\n this.flagDirty();\r\n }\r\n },\r\n setY: (y) => {\r\n if (this.parent) {\r\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\r\n this.pos.y = newY;\r\n } else {\r\n this.pos.y = y;\r\n }\r\n if (y !== this.matrix.data[5]) {\r\n this.flagDirty();\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _rotation: number = 0;\r\n set rotation(rotation: number) {\r\n const canonRotation = canonicalizeAngle(rotation);\r\n if (canonRotation !== this._rotation) {\r\n this.flagDirty();\r\n }\r\n this._rotation = canonRotation;\r\n }\r\n get rotation() {\r\n return this._rotation;\r\n }\r\n\r\n set globalRotation(rotation: number) {\r\n let inverseRotation = 0;\r\n if (this.parent) {\r\n inverseRotation = this.parent.globalRotation;\r\n }\r\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\r\n if (canonRotation !== this._rotation) {\r\n this.flagDirty();\r\n }\r\n this._rotation = canonRotation;\r\n }\r\n\r\n get globalRotation() {\r\n if (this.parent) {\r\n return this.matrix.getRotation();\r\n }\r\n return this.rotation;\r\n }\r\n\r\n private _scale: Vector = vec(1, 1);\r\n set scale(v: Vector) {\r\n if (!v.equals(this._scale)) {\r\n this._scale.x = v.x;\r\n this._scale.y = v.y;\r\n this.flagDirty();\r\n }\r\n }\r\n get scale() {\r\n return new WatchVector(this._scale, (x, y) => {\r\n if (x !== this._scale.x || y !== this._scale.y) {\r\n this.flagDirty();\r\n }\r\n });\r\n }\r\n\r\n set globalScale(v: Vector) {\r\n let inverseScale = vec(1, 1);\r\n if (this.parent) {\r\n inverseScale = this.parent.globalScale;\r\n }\r\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\r\n }\r\n\r\n get globalScale() {\r\n return new VectorView({\r\n getX: () => this.parent ? this.matrix.getScaleX() : this.scale.x,\r\n getY: () => this.parent ? this.matrix.getScaleY() : this.scale.y,\r\n setX: (x) => {\r\n if (this.parent) {\r\n const globalScaleX = this.parent.globalScale.x;\r\n this.scale.x = x / globalScaleX;\r\n } else {\r\n this.scale.x = x;\r\n }\r\n },\r\n setY: (y) => {\r\n if (this.parent) {\r\n const globalScaleY = this.parent.globalScale.y;\r\n this.scale.y = y / globalScaleY;\r\n } else {\r\n this.scale.y = y;\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _isDirty = false;\r\n private _isInverseDirty = false;\r\n private _matrix = AffineMatrix.identity();\r\n private _inverse = AffineMatrix.identity();\r\n\r\n public get matrix() {\r\n if (this._isDirty) {\r\n if (this.parent === null) {\r\n this._matrix = this._calculateMatrix();\r\n } else {\r\n this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\r\n }\r\n this._isDirty = false;\r\n }\r\n return this._matrix;\r\n }\r\n\r\n public get inverse() {\r\n if (this._isInverseDirty) {\r\n this._inverse = this.matrix.inverse();\r\n this._isInverseDirty = false;\r\n }\r\n return this._inverse;\r\n }\r\n\r\n private _calculateMatrix(): AffineMatrix {\r\n const matrix = AffineMatrix.identity()\r\n .translate(this.pos.x, this.pos.y)\r\n .rotate(this.rotation)\r\n .scale(this.scale.x, this.scale.y);\r\n return matrix;\r\n }\r\n\r\n\r\n public flagDirty() {\r\n this._isDirty = true;\r\n this._isInverseDirty = true;\r\n for (let i = 0; i < this._children.length; i ++) {\r\n this._children[i].flagDirty();\r\n }\r\n }\r\n\r\n public apply(point: Vector): Vector {\r\n return this.matrix.multiply(point);\r\n }\r\n\r\n public applyInverse(point: Vector): Vector {\r\n return this.inverse.multiply(point);\r\n }\r\n\r\n public setTransform(pos: Vector, rotation: number, scale: Vector) {\r\n this._pos.x = pos.x;\r\n this._pos.y = pos.y;\r\n this._rotation = canonicalizeAngle(rotation);\r\n this._scale.x = scale.x;\r\n this._scale.y = scale.y;\r\n this.flagDirty();\r\n }\r\n\r\n /**\r\n * Clones the current transform\r\n * **Warning does not clone the parent**\r\n * @param dest\r\n */\r\n public clone(dest?: Transform) {\r\n const target = dest ?? new Transform();\r\n this._pos.clone(target._pos);\r\n target._rotation = this._rotation;\r\n this._scale.clone(target._scale);\r\n target.flagDirty();\r\n return target;\r\n }\r\n}","import { Entity } from './Entity';\r\n\r\n/**\r\n * Component Constructor Types\r\n */\r\nexport declare type ComponentCtor = new (...args:any[]) => TComponent;\r\n\r\n/**\r\n *\r\n */\r\nexport function isComponentCtor(value: any): value is ComponentCtor {\r\n return !!value && !!value.prototype && !!value.prototype.constructor;\r\n}\r\n\r\n/**\r\n * Type guard to check if a component implements clone\r\n * @param x\r\n */\r\nfunction hasClone(x: any): x is { clone(): any } {\r\n return !!x?.clone;\r\n}\r\n\r\n/**\r\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\r\n *\r\n * Implementations of Component must have a zero-arg constructor to support dependencies\r\n *\r\n * ```typescript\r\n * class MyComponent extends ex.Component {\r\n * // zero arg support required if you want to use component dependencies\r\n * constructor(public optionalPos?: ex.Vector) {}\r\n * }\r\n * ```\r\n */\r\nexport abstract class Component {\r\n // TODO maybe generate a unique id?\r\n\r\n /**\r\n * Optionally list any component types this component depends on\r\n * If the owner entity does not have these components, new components will be added to the entity\r\n *\r\n * Only components with zero-arg constructors are supported as automatic component dependencies\r\n */\r\n readonly dependencies?: ComponentCtor[];\r\n\r\n /**\r\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\r\n */\r\n owner?: Entity = undefined;\r\n\r\n /**\r\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\r\n */\r\n clone(): Component {\r\n const newComponent = new (this.constructor as any)();\r\n for (const prop in this) {\r\n if (this.hasOwnProperty(prop)) {\r\n const val = this[prop];\r\n if (hasClone(val) && prop !== 'owner' && prop !== 'clone') {\r\n newComponent[prop] = val.clone();\r\n } else {\r\n newComponent[prop] = val;\r\n }\r\n }\r\n }\r\n return newComponent;\r\n }\r\n\r\n /**\r\n * Optional callback called when a component is added to an entity\r\n */\r\n onAdd?(owner: Entity): void;\r\n\r\n /**\r\n * Optional callback called when a component is removed from an entity\r\n */\r\n onRemove?(previousOwner: Entity): void;\r\n}","/**\r\n * Defines a generic message that can contain any data\r\n * @template T is the typescript Type of the data\r\n */\r\nexport interface Message {\r\n type: string;\r\n data: T;\r\n}\r\n\r\n/**\r\n * Defines an interface for an observer to receive a message via a notify() method\r\n */\r\nexport interface Observer {\r\n notify(message: T): void;\r\n}\r\n\r\n/**\r\n * Defines an interface for something that might be an observer if a notify() is present\r\n */\r\nexport type MaybeObserver = Partial>;\r\n\r\n/**\r\n * Simple Observable implementation\r\n * @template T is the typescript Type that defines the data being observed\r\n */\r\nexport class Observable {\r\n public observers: Observer[] = [];\r\n public subscriptions: ((val: T) => any)[] = [];\r\n\r\n /**\r\n * Register an observer to listen to this observable\r\n * @param observer\r\n */\r\n register(observer: Observer) {\r\n this.observers.push(observer);\r\n }\r\n\r\n /**\r\n * Register a callback to listen to this observable\r\n * @param func\r\n */\r\n subscribe(func: (val: T) => any) {\r\n this.subscriptions.push(func);\r\n }\r\n\r\n /**\r\n * Remove an observer from the observable\r\n * @param observer\r\n */\r\n unregister(observer: Observer) {\r\n const i = this.observers.indexOf(observer);\r\n if (i !== -1) {\r\n this.observers.splice(i, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Remove a callback that is listening to this observable\r\n * @param func\r\n */\r\n unsubscribe(func: (val: T) => any) {\r\n const i = this.subscriptions.indexOf(func);\r\n if (i !== -1) {\r\n this.subscriptions.splice(i, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Broadcasts a message to all observers and callbacks\r\n * @param message\r\n */\r\n notifyAll(message: T) {\r\n const observersLength = this.observers.length;\r\n for (let i = 0; i < observersLength; i++) {\r\n this.observers[i].notify(message);\r\n }\r\n const subscriptionsLength = this.subscriptions.length;\r\n for (let i = 0; i < subscriptionsLength; i++) {\r\n this.subscriptions[i](message);\r\n }\r\n }\r\n\r\n /**\r\n * Removes all observers and callbacks\r\n */\r\n clear() {\r\n this.observers.length = 0;\r\n this.subscriptions.length = 0;\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { CoordPlane } from '../../Math/coord-plane';\r\nimport { Transform } from '../../Math/transform';\r\nimport { Component } from '../Component';\r\nimport { Entity } from '../Entity';\r\nimport { Observable } from '../../Util/Observable';\r\nimport { Logger } from '../../Util/Log';\r\n\r\n\r\nexport class TransformComponent extends Component {\r\n private _logger = Logger.getInstance();\r\n private _parentComponent: TransformComponent | null = null;\r\n private _transform = new Transform();\r\n public get() {\r\n return this._transform;\r\n }\r\n\r\n private _addChildTransform = (child: Entity) => {\r\n const childTxComponent = child.get(TransformComponent);\r\n if (childTxComponent) {\r\n childTxComponent._transform.parent = this._transform;\r\n childTxComponent._parentComponent = this;\r\n }\r\n };\r\n onAdd(owner: Entity): void {\r\n for (const child of owner.children) {\r\n this._addChildTransform(child);\r\n }\r\n owner.childrenAdded$.subscribe(child => this._addChildTransform(child));\r\n owner.childrenRemoved$.subscribe(child => {\r\n const childTxComponent = child.get(TransformComponent);\r\n if (childTxComponent) {\r\n childTxComponent._transform.parent = null;\r\n childTxComponent._parentComponent = null;\r\n }\r\n });\r\n }\r\n onRemove(_previousOwner: Entity): void {\r\n this._transform.parent = null;\r\n this._parentComponent = null;\r\n }\r\n\r\n /**\r\n * Observable that emits when the z index changes on this component\r\n */\r\n public zIndexChanged$ = new Observable();\r\n private _z = 0;\r\n\r\n /**\r\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\r\n * For example z=99 would be drawn on top of z=0.\r\n */\r\n public get z(): number {\r\n return this._z;\r\n }\r\n\r\n public set z(val: number) {\r\n const oldz = this._z;\r\n this._z = val;\r\n if (oldz !== val) {\r\n this.zIndexChanged$.notifyAll(val);\r\n }\r\n }\r\n\r\n private _coordPlane = CoordPlane.World;\r\n /**\r\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\r\n */\r\n public get coordPlane() {\r\n if (this._parentComponent) {\r\n return this._parentComponent.coordPlane;\r\n }\r\n return this._coordPlane;\r\n }\r\n\r\n public set coordPlane(value: CoordPlane) {\r\n if (!this._parentComponent) {\r\n this._coordPlane = value;\r\n } else {\r\n this._logger.warn(\r\n `Cannot set coordinate plane on child entity ${this.owner?.name}, children inherit their coordinate plane from their parents.`);\r\n }\r\n }\r\n\r\n get pos() {\r\n return this._transform.pos;\r\n }\r\n set pos(v: Vector) {\r\n this._transform.pos = v;\r\n }\r\n\r\n get globalPos() {\r\n return this._transform.globalPos;\r\n }\r\n set globalPos(v: Vector) {\r\n this._transform.globalPos = v;\r\n }\r\n\r\n get rotation() {\r\n return this._transform.rotation;\r\n }\r\n set rotation(rotation) {\r\n this._transform.rotation = rotation;\r\n }\r\n\r\n get globalRotation() {\r\n return this._transform.globalRotation;\r\n }\r\n set globalRotation(rotation) {\r\n this._transform.globalRotation = rotation;\r\n }\r\n\r\n get scale() {\r\n return this._transform.scale;\r\n }\r\n set scale(v: Vector) {\r\n this._transform.scale = v;\r\n }\r\n\r\n get globalScale() {\r\n return this._transform.globalScale;\r\n }\r\n set globalScale(v: Vector) {\r\n this._transform.globalScale = v;\r\n }\r\n\r\n applyInverse(v: Vector) {\r\n return this._transform.applyInverse(v);\r\n }\r\n\r\n apply(v: Vector) {\r\n return this._transform.apply(v);\r\n }\r\n\r\n clone(): TransformComponent {\r\n const component = new TransformComponent();\r\n component._transform = this._transform.clone();\r\n component._z = this._z;\r\n return component;\r\n }\r\n}","import { Vector } from '../../Math/vector';\r\nimport { Component } from '../Component';\r\n\r\nexport interface Motion {\r\n /**\r\n * The velocity of an entity in pixels per second\r\n */\r\n vel: Vector;\r\n\r\n /**\r\n * The acceleration of entity in pixels per second^2\r\n */\r\n acc: Vector;\r\n\r\n /**\r\n * The scale rate of change in scale units per second\r\n */\r\n scaleFactor: Vector;\r\n\r\n /**\r\n * The angular velocity which is how quickly the entity is rotating in radians per second\r\n */\r\n angularVelocity: number;\r\n\r\n /**\r\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\r\n */\r\n torque: number;\r\n\r\n /**\r\n * Inertia can be thought of as the resistance to motion\r\n */\r\n inertia: number;\r\n}\r\n\r\nexport class MotionComponent extends Component {\r\n\r\n /**\r\n * The velocity of an entity in pixels per second\r\n */\r\n public vel: Vector = Vector.Zero;\r\n\r\n /**\r\n * The acceleration of entity in pixels per second^2\r\n */\r\n public acc: Vector = Vector.Zero;\r\n\r\n /**\r\n * The scale rate of change in scale units per second\r\n */\r\n public scaleFactor: Vector = Vector.Zero;\r\n\r\n /**\r\n * The angular velocity which is how quickly the entity is rotating in radians per second\r\n */\r\n public angularVelocity = 0;\r\n\r\n /**\r\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\r\n */\r\n public torque: number = 0;\r\n\r\n /**\r\n * Inertia can be thought of as the resistance to motion\r\n */\r\n public inertia: number = 1;\r\n}\r\n","import { CollisionGroup } from './CollisionGroup';\r\n\r\n/**\r\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\r\n */\r\nexport class CollisionGroupManager {\r\n // using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\r\n private static _STARTING_BIT = 0b1 | 0;\r\n private static _MAX_GROUPS = 32;\r\n private static _CURRENT_GROUP = 1;\r\n private static _CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\r\n private static _GROUPS: Map = new Map();\r\n\r\n /**\r\n * Create a new named collision group up to a max of 32.\r\n * @param name Name for the collision group\r\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\r\n */\r\n public static create(name: string, mask?: number) {\r\n if (this._CURRENT_GROUP > this._MAX_GROUPS) {\r\n throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\r\n }\r\n if (this._GROUPS.get(name)) {\r\n const existingGroup = this._GROUPS.get(name);\r\n if (existingGroup.mask === mask) {\r\n return existingGroup;\r\n }\r\n throw new Error(`Collision group ${name} already exists with a different mask!`);\r\n }\r\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\r\n this._CURRENT_BIT = (this._CURRENT_BIT << 1) | 0;\r\n this._CURRENT_GROUP++;\r\n this._GROUPS.set(name, group);\r\n return group;\r\n }\r\n\r\n /**\r\n * Get all collision groups currently tracked by excalibur\r\n */\r\n public static get groups(): CollisionGroup[] {\r\n return Array.from(this._GROUPS.values());\r\n }\r\n\r\n /**\r\n * Get a collision group by it's name\r\n * @param name\r\n */\r\n public static groupByName(name: string) {\r\n return this._GROUPS.get(name);\r\n }\r\n\r\n /**\r\n * Resets the managers internal group management state\r\n */\r\n public static reset() {\r\n this._GROUPS = new Map();\r\n this._CURRENT_BIT = this._STARTING_BIT;\r\n this._CURRENT_GROUP = 1;\r\n }\r\n}\r\n","import { CollisionGroupManager } from './CollisionGroupManager';\r\n\r\n/**\r\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\r\n *\r\n * For example:\r\n *\r\n * Players have collision group \"player\"\r\n *\r\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\r\n *\r\n * Enemies have collision group \"enemy\"\r\n *\r\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\r\n *\r\n * Blocks have collision group \"ground\"\r\n *\r\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\r\n *\r\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\r\n * with players and blocks.\r\n *\r\n * This is done with bitmasking, see the following pseudo-code\r\n *\r\n * PlayerGroup = `0b001`\r\n * PlayerGroupMask = `0b110`\r\n *\r\n * EnemyGroup = `0b010`\r\n * EnemyGroupMask = `0b101`\r\n *\r\n * BlockGroup = `0b100`\r\n * BlockGroupMask = `0b011`\r\n *\r\n * Should Players collide? No because the bitwise mask evaluates to 0\r\n * `(player1.group & player2.mask) === 0`\r\n * `(0b001 & 0b110) === 0`\r\n *\r\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & enemy1.mask) === 1`\r\n * `(0b001 & 0b101) === 1`\r\n *\r\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & blocks1.mask) === 1`\r\n * `(0b001 & 0b011) === 1`\r\n */\r\nexport class CollisionGroup {\r\n /**\r\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\r\n * it is the default collision group on colliders.\r\n */\r\n public static All = new CollisionGroup('Collide with all groups', -1, -1);\r\n\r\n private _name: string;\r\n private _category: number;\r\n private _mask: number;\r\n\r\n /**\r\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\r\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\r\n * @param name Name of the collision group\r\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\r\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\r\n */\r\n constructor(name: string, category: number, mask: number) {\r\n this._name = name;\r\n this._category = category;\r\n this._mask = mask;\r\n }\r\n\r\n /**\r\n * Get the name of the collision group\r\n */\r\n public get name() {\r\n return this._name;\r\n }\r\n\r\n /**\r\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\r\n */\r\n public get category() {\r\n return this._category;\r\n }\r\n\r\n /**\r\n * Get the mask for this collision group\r\n */\r\n public get mask() {\r\n return this._mask;\r\n }\r\n\r\n /**\r\n * Evaluates whether 2 collision groups can collide\r\n *\r\n * This means the mask has the same bit set the other category and vice versa\r\n * @param other CollisionGroup\r\n */\r\n public canCollide(other: CollisionGroup): boolean {\r\n const overlap1 = this.category & other.mask;\r\n const overlap2 = this.mask & other.category;\r\n return (overlap1 !== 0) && (overlap2 !== 0);\r\n }\r\n\r\n /**\r\n * Inverts the collision group. For example, if before the group specified \"players\",\r\n * inverting would specify all groups except players\r\n * @returns CollisionGroup\r\n */\r\n public invert(): CollisionGroup {\r\n const group = CollisionGroupManager.create('~(' + this.name + ')', ~this.mask | 0);\r\n group._category = ~this.category;\r\n return group;\r\n }\r\n\r\n /**\r\n * Combine collision groups with each other. The new group includes all of the previous groups.\r\n * @param collisionGroups\r\n */\r\n public static combine(collisionGroups: CollisionGroup[]) {\r\n const combinedName = collisionGroups.map((c) => c.name).join('+');\r\n const combinedCategory = collisionGroups.reduce((current, g) => g.category | current, 0b0);\r\n const combinedMask = ~combinedCategory;\r\n\r\n return CollisionGroupManager.create(combinedName, combinedMask);\r\n }\r\n\r\n /**\r\n * Creates a collision group that collides with the listed groups\r\n * @param collisionGroups\r\n */\r\n public static collidesWith(collisionGroups: CollisionGroup[]) {\r\n const combinedName = `collidesWith(${collisionGroups.map((c) => c.name).join('+')})`;\r\n const combinedMask = collisionGroups.reduce((current, g) => g.category | current, 0b0);\r\n return CollisionGroupManager.create(combinedName, combinedMask);\r\n }\r\n\r\n public toString() {\r\n return `\r\ncategory: ${this.category.toString(2).padStart(32, '0')}\r\nmask: ${(this.mask>>>0).toString(2).padStart(32, '0')}\r\n `;\r\n }\r\n}\r\n","import { CollisionContact } from './CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { Id } from '../../Id';\r\nimport { Collider } from '../Colliders/Collider';\r\n\r\n/**\r\n * Models a potential collision between 2 colliders\r\n */\r\nexport class Pair {\r\n public id: string = null;\r\n constructor(public colliderA: Collider, public colliderB: Collider) {\r\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n }\r\n\r\n /**\r\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\r\n * @param colliderA\r\n * @param colliderB\r\n */\r\n public static canCollide(colliderA: Collider, colliderB: Collider) {\r\n const bodyA = colliderA?.owner?.get(BodyComponent);\r\n const bodyB = colliderB?.owner?.get(BodyComponent);\r\n\r\n // Prevent self collision\r\n if (colliderA.id === colliderB.id) {\r\n return false;\r\n }\r\n\r\n // Colliders with the same owner do not collide (composite colliders)\r\n if (colliderA.owner &&\r\n colliderB.owner &&\r\n colliderA.owner.id === colliderB.owner.id) {\r\n return false;\r\n }\r\n\r\n // if the pair has a member with zero dimension don't collide\r\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) {\r\n return false;\r\n }\r\n\r\n // Body's needed for collision in the current state\r\n // TODO can we collide without a body?\r\n if (!bodyA || !bodyB) {\r\n return false;\r\n }\r\n\r\n // If both are in the same collision group short circuit\r\n if (!bodyA.group.canCollide(bodyB.group)) {\r\n return false;\r\n }\r\n\r\n // if both are fixed short circuit\r\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) {\r\n return false;\r\n }\r\n\r\n // if the either is prevent collision short circuit\r\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) {\r\n return false;\r\n }\r\n\r\n // if either is dead short circuit\r\n if (!bodyA.active || !bodyB.active) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns whether or not it is possible for the pairs to collide\r\n */\r\n public get canCollide(): boolean {\r\n const colliderA = this.colliderA;\r\n const colliderB = this.colliderB;\r\n return Pair.canCollide(colliderA, colliderB);\r\n }\r\n\r\n /**\r\n * Runs the collision intersection logic on the members of this pair\r\n */\r\n public collide(): CollisionContact[] {\r\n return this.colliderA.collide(this.colliderB);\r\n }\r\n\r\n /**\r\n * Check if the collider is part of the pair\r\n * @param collider\r\n */\r\n public hasCollider(collider: Collider) {\r\n return collider === this.colliderA || collider === this.colliderB;\r\n }\r\n\r\n /**\r\n * Calculates the unique pair hash id for this collision pair (owning id)\r\n */\r\n public static calculatePairHash(idA: Id<'collider'>, idB: Id<'collider'>): string {\r\n if (idA.value < idB.value) {\r\n return `#${idA.value}+${idB.value}`;\r\n } else {\r\n return `#${idB.value}+${idA.value}`;\r\n }\r\n }\r\n}\r\n","/**\r\n * A 1 dimensional projection on an axis, used to test overlaps\r\n */\r\n\r\nexport class Projection {\r\n constructor(public min: number, public max: number) {}\r\n public overlaps(projection: Projection): boolean {\r\n return this.max > projection.min && projection.max > this.min;\r\n }\r\n\r\n public getOverlap(projection: Projection): number {\r\n if (this.overlaps(projection)) {\r\n if (this.max > projection.max) {\r\n return projection.max - this.min;\r\n } else {\r\n return this.max - projection.min;\r\n }\r\n }\r\n return 0;\r\n }\r\n}\r\n","import { BoundingBox } from '../BoundingBox';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Id } from '../../Id';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { Color, ExcaliburGraphicsContext } from '../..';\r\nimport { PhysicsConfig } from '../PhysicsConfig';\r\n\r\n/**\r\n * Dynamic Tree Node used for tracking bounds within the tree\r\n */\r\nexport class TreeNode {\r\n public left: TreeNode;\r\n public right: TreeNode;\r\n public bounds: BoundingBox;\r\n public height: number;\r\n public data: T;\r\n constructor(public parent?: TreeNode) {\r\n this.parent = parent || null;\r\n this.data = null;\r\n this.bounds = new BoundingBox();\r\n this.left = null;\r\n this.right = null;\r\n this.height = 0;\r\n }\r\n\r\n public isLeaf(): boolean {\r\n return !this.left && !this.right;\r\n }\r\n}\r\n\r\nexport interface ColliderProxy {\r\n id: Id<'collider'>;\r\n owner: T;\r\n bounds: BoundingBox;\r\n}\r\n\r\n/**\r\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\r\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\r\n *\r\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\r\n * Every non-leaf node is a bounding box that contains child bounding boxes.\r\n */\r\nexport class DynamicTree> {\r\n public root: TreeNode;\r\n public nodes: { [key: number]: TreeNode };\r\n constructor(\r\n private _config: Required['dynamicTree']>,\r\n public worldBounds: BoundingBox = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)) {\r\n this.root = null;\r\n this.nodes = {};\r\n }\r\n\r\n /**\r\n * Inserts a node into the dynamic tree\r\n */\r\n private _insert(leaf: TreeNode): void {\r\n // If there are no nodes in the tree, make this the root leaf\r\n if (this.root === null) {\r\n this.root = leaf;\r\n this.root.parent = null;\r\n return;\r\n }\r\n\r\n // Search the tree for a node that is not a leaf and find the best place to insert\r\n const leafAABB = leaf.bounds;\r\n let currentRoot = this.root;\r\n while (!currentRoot.isLeaf()) {\r\n const left = currentRoot.left;\r\n const right = currentRoot.right;\r\n\r\n const area = currentRoot.bounds.getPerimeter();\r\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\r\n const combinedArea = combinedAABB.getPerimeter();\r\n\r\n // Calculate cost heuristic for creating a new parent and leaf\r\n const cost = 2 * combinedArea;\r\n\r\n // Minimum cost of pushing the leaf down the tree\r\n const inheritanceCost = 2 * (combinedArea - area);\r\n\r\n // Cost of descending\r\n let leftCost = 0;\r\n const leftCombined = leafAABB.combine(left.bounds);\r\n let newArea;\r\n let oldArea;\r\n if (left.isLeaf()) {\r\n leftCost = leftCombined.getPerimeter() + inheritanceCost;\r\n } else {\r\n oldArea = left.bounds.getPerimeter();\r\n newArea = leftCombined.getPerimeter();\r\n leftCost = newArea - oldArea + inheritanceCost;\r\n }\r\n\r\n let rightCost = 0;\r\n const rightCombined = leafAABB.combine(right.bounds);\r\n if (right.isLeaf()) {\r\n rightCost = rightCombined.getPerimeter() + inheritanceCost;\r\n } else {\r\n oldArea = right.bounds.getPerimeter();\r\n newArea = rightCombined.getPerimeter();\r\n rightCost = newArea - oldArea + inheritanceCost;\r\n }\r\n\r\n // cost is acceptable\r\n if (cost < leftCost && cost < rightCost) {\r\n break;\r\n }\r\n\r\n // Descend to the depths\r\n if (leftCost < rightCost) {\r\n currentRoot = left;\r\n } else {\r\n currentRoot = right;\r\n }\r\n }\r\n\r\n // Create the new parent node and insert into the tree\r\n const oldParent = currentRoot.parent;\r\n const newParent = new TreeNode(oldParent);\r\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\r\n newParent.height = currentRoot.height + 1;\r\n\r\n if (oldParent !== null) {\r\n // The sibling node was not the root\r\n if (oldParent.left === currentRoot) {\r\n oldParent.left = newParent;\r\n } else {\r\n oldParent.right = newParent;\r\n }\r\n\r\n newParent.left = currentRoot;\r\n newParent.right = leaf;\r\n\r\n currentRoot.parent = newParent;\r\n leaf.parent = newParent;\r\n } else {\r\n // The sibling node was the root\r\n newParent.left = currentRoot;\r\n newParent.right = leaf;\r\n\r\n currentRoot.parent = newParent;\r\n leaf.parent = newParent;\r\n this.root = newParent;\r\n }\r\n\r\n // Walk up the tree fixing heights and AABBs\r\n let currentNode = leaf.parent;\r\n while (currentNode) {\r\n currentNode = this._balance(currentNode);\r\n\r\n if (!currentNode.left) {\r\n throw new Error('Parent of current leaf cannot have a null left child' + currentNode);\r\n }\r\n if (!currentNode.right) {\r\n throw new Error('Parent of current leaf cannot have a null right child' + currentNode);\r\n }\r\n\r\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\r\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\r\n\r\n currentNode = currentNode.parent;\r\n }\r\n }\r\n\r\n /**\r\n * Removes a node from the dynamic tree\r\n */\r\n private _remove(leaf: TreeNode) {\r\n if (leaf === this.root) {\r\n this.root = null;\r\n return;\r\n }\r\n\r\n const parent = leaf.parent;\r\n const grandParent = parent.parent;\r\n let sibling: TreeNode;\r\n if (parent.left === leaf) {\r\n sibling = parent.right;\r\n } else {\r\n sibling = parent.left;\r\n }\r\n\r\n if (grandParent) {\r\n if (grandParent.left === parent) {\r\n grandParent.left = sibling;\r\n } else {\r\n grandParent.right = sibling;\r\n }\r\n sibling.parent = grandParent;\r\n\r\n let currentNode = grandParent;\r\n while (currentNode) {\r\n currentNode = this._balance(currentNode);\r\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\r\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\r\n\r\n currentNode = currentNode.parent;\r\n }\r\n } else {\r\n this.root = sibling;\r\n sibling.parent = null;\r\n }\r\n }\r\n\r\n /**\r\n * Tracks a body in the dynamic tree\r\n */\r\n public trackCollider(collider: T) {\r\n const node = new TreeNode();\r\n node.data = collider;\r\n node.bounds = collider.bounds;\r\n node.bounds.left -= 2;\r\n node.bounds.top -= 2;\r\n node.bounds.right += 2;\r\n node.bounds.bottom += 2;\r\n this.nodes[collider.id.value] = node;\r\n this._insert(node);\r\n }\r\n\r\n /**\r\n * Updates the dynamic tree given the current bounds of each body being tracked\r\n */\r\n public updateCollider(collider: T) {\r\n const node = this.nodes[collider.id.value];\r\n if (!node) {\r\n return false;\r\n }\r\n const b = collider.bounds;\r\n\r\n // if the body is outside the world no longer update it\r\n if (!this.worldBounds.contains(b)) {\r\n Logger.getInstance().warn(\r\n 'Collider with id ' + collider.id.value + ' is outside the world bounds and will no longer be tracked for physics'\r\n );\r\n this.untrackCollider(collider);\r\n return false;\r\n }\r\n\r\n if (node.bounds.contains(b)) {\r\n return false;\r\n }\r\n\r\n this._remove(node);\r\n b.left -= this._config.boundsPadding;\r\n b.top -= this._config.boundsPadding;\r\n b.right += this._config.boundsPadding;\r\n b.bottom += this._config.boundsPadding;\r\n\r\n // THIS IS CAUSING UNNECESSARY CHECKS\r\n if (collider.owner) {\r\n const body = collider.owner?.get(BodyComponent);\r\n if (body) {\r\n const multdx = ((body.vel.x * 32) / 1000) * this._config.velocityMultiplier;\r\n const multdy = ((body.vel.y * 32) / 1000) * this._config.velocityMultiplier;\r\n\r\n if (multdx < 0) {\r\n b.left += multdx;\r\n } else {\r\n b.right += multdx;\r\n }\r\n\r\n if (multdy < 0) {\r\n b.top += multdy;\r\n } else {\r\n b.bottom += multdy;\r\n }\r\n }\r\n }\r\n\r\n node.bounds = b;\r\n this._insert(node);\r\n return true;\r\n }\r\n\r\n /**\r\n * Untracks a body from the dynamic tree\r\n */\r\n public untrackCollider(collider: T) {\r\n const node = this.nodes[collider.id.value];\r\n if (!node) {\r\n return;\r\n }\r\n this._remove(node);\r\n this.nodes[collider.id.value] = null;\r\n delete this.nodes[collider.id.value];\r\n }\r\n\r\n /**\r\n * Balances the tree about a node\r\n */\r\n private _balance(node: TreeNode) {\r\n if (node === null) {\r\n throw new Error('Cannot balance at null node');\r\n }\r\n\r\n if (node.isLeaf() || node.height < 2) {\r\n return node;\r\n }\r\n\r\n const left = node.left;\r\n const right = node.right;\r\n\r\n const a = node;\r\n const b = left;\r\n const c = right;\r\n const d = left.left;\r\n const e = left.right;\r\n const f = right.left;\r\n const g = right.right;\r\n\r\n const balance = c.height - b.height;\r\n // Rotate c node up\r\n if (balance > 1) {\r\n // Swap the right node with it's parent\r\n c.left = a;\r\n c.parent = a.parent;\r\n a.parent = c;\r\n\r\n // The original node's old parent should point to the right node\r\n // this is mega confusing\r\n if (c.parent) {\r\n if (c.parent.left === a) {\r\n c.parent.left = c;\r\n } else {\r\n c.parent.right = c;\r\n }\r\n } else {\r\n this.root = c;\r\n }\r\n\r\n // Rotate\r\n if (f.height > g.height) {\r\n c.right = f;\r\n a.right = g;\r\n g.parent = a;\r\n\r\n a.bounds = b.bounds.combine(g.bounds);\r\n c.bounds = a.bounds.combine(f.bounds);\r\n\r\n a.height = 1 + Math.max(b.height, g.height);\r\n c.height = 1 + Math.max(a.height, f.height);\r\n } else {\r\n c.right = g;\r\n a.right = f;\r\n f.parent = a;\r\n\r\n a.bounds = b.bounds.combine(f.bounds);\r\n c.bounds = a.bounds.combine(g.bounds);\r\n\r\n a.height = 1 + Math.max(b.height, f.height);\r\n c.height = 1 + Math.max(a.height, g.height);\r\n }\r\n\r\n return c;\r\n }\r\n // Rotate left node up\r\n if (balance < -1) {\r\n // swap\r\n b.left = a;\r\n b.parent = a.parent;\r\n a.parent = b;\r\n\r\n // node's old parent should point to b\r\n if (b.parent) {\r\n if (b.parent.left === a) {\r\n b.parent.left = b;\r\n } else {\r\n if (b.parent.right !== a) {\r\n throw 'Error rotating Dynamic Tree';\r\n }\r\n b.parent.right = b;\r\n }\r\n } else {\r\n this.root = b;\r\n }\r\n\r\n // rotate\r\n if (d.height > e.height) {\r\n b.right = d;\r\n a.left = e;\r\n e.parent = a;\r\n\r\n a.bounds = c.bounds.combine(e.bounds);\r\n b.bounds = a.bounds.combine(d.bounds);\r\n\r\n a.height = 1 + Math.max(c.height, e.height);\r\n b.height = 1 + Math.max(a.height, d.height);\r\n } else {\r\n b.right = e;\r\n a.left = d;\r\n d.parent = a;\r\n\r\n a.bounds = c.bounds.combine(d.bounds);\r\n b.bounds = a.bounds.combine(e.bounds);\r\n\r\n a.height = 1 + Math.max(c.height, d.height);\r\n b.height = 1 + Math.max(a.height, e.height);\r\n }\r\n return b;\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /**\r\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\r\n */\r\n public getHeight(): number {\r\n if (this.root === null) {\r\n return 0;\r\n }\r\n return this.root.height;\r\n }\r\n\r\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\r\n *\r\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\r\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\r\n * the tree until all possible colliders have been returned.\r\n */\r\n public query(collider: T, callback: (other: T) => boolean): void {\r\n const bounds = collider.bounds;\r\n const helper = (currentNode: TreeNode): boolean => {\r\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\r\n if (currentNode.isLeaf() && currentNode.data !== collider) {\r\n if (callback.call(collider, currentNode.data)) {\r\n return true;\r\n }\r\n } else {\r\n return helper(currentNode.left) || helper(currentNode.right);\r\n }\r\n }\r\n return false;\r\n };\r\n helper(this.root);\r\n }\r\n\r\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\r\n * long ray to test the tree specified by `max`.\r\n *\r\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\r\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\r\n * the tree until all possible bodies that would intersect with the ray have been returned.\r\n */\r\n public rayCastQuery(ray: Ray, max: number = Infinity, callback: (other: T) => boolean): void {\r\n const helper = (currentNode: TreeNode): boolean => {\r\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\r\n if (currentNode.isLeaf()) {\r\n if (callback.call(ray, currentNode.data)) {\r\n // ray hit a leaf! return the body\r\n return true;\r\n }\r\n } else {\r\n // ray hit but not at a leaf, recurse deeper\r\n return helper(currentNode.left) || helper(currentNode.right);\r\n }\r\n }\r\n return false; // ray missed\r\n };\r\n helper(this.root);\r\n }\r\n\r\n public getNodes(): TreeNode[] {\r\n const helper = (currentNode: TreeNode): TreeNode[] => {\r\n if (currentNode) {\r\n return [currentNode].concat(helper(currentNode.left), helper(currentNode.right));\r\n } else {\r\n return [];\r\n }\r\n };\r\n return helper(this.root);\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext) {\r\n // draw all the nodes in the Dynamic Tree\r\n const helper = (currentNode: TreeNode) => {\r\n if (currentNode) {\r\n if (currentNode.isLeaf()) {\r\n currentNode.bounds.draw(ex, Color.Green);\r\n } else {\r\n currentNode.bounds.draw(ex, Color.White);\r\n }\r\n\r\n if (currentNode.left) {\r\n helper(currentNode.left);\r\n }\r\n if (currentNode.right) {\r\n helper(currentNode.right);\r\n }\r\n }\r\n };\r\n\r\n helper(this.root);\r\n }\r\n}\r\n","import { LineSegment } from './line-segment';\r\nimport { Vector } from './vector';\r\n\r\n/**\r\n * A 2D ray that can be cast into the scene to do collision detection\r\n */\r\n\r\nexport class Ray {\r\n public pos: Vector;\r\n public dir: Vector;\r\n\r\n /**\r\n * @param pos The starting position for the ray\r\n * @param dir The vector indicating the direction of the ray\r\n */\r\n constructor(pos: Vector, dir: Vector) {\r\n this.pos = pos;\r\n this.dir = dir.normalize();\r\n }\r\n\r\n /**\r\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\r\n * This number indicates the mathematical intersection time.\r\n * @param line The line to test\r\n */\r\n public intersect(line: LineSegment): number {\r\n const numerator = line.begin.sub(this.pos);\r\n\r\n // Test is line and ray are parallel and non intersecting\r\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) {\r\n return -1;\r\n }\r\n\r\n // Lines are parallel\r\n const divisor = this.dir.cross(line.getSlope());\r\n if (divisor === 0) {\r\n return -1;\r\n }\r\n\r\n const t = numerator.cross(line.getSlope()) / divisor;\r\n\r\n if (t >= 0) {\r\n const u = numerator.cross(this.dir) / divisor / line.getLength();\r\n if (u >= 0 && u <= 1) {\r\n return t;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n public intersectPoint(line: LineSegment): Vector {\r\n const time = this.intersect(line);\r\n if (time < 0) {\r\n return null;\r\n }\r\n return this.getPoint(time);\r\n }\r\n\r\n /**\r\n * Returns the point of intersection given the intersection time\r\n */\r\n public getPoint(time: number): Vector {\r\n return this.pos.add(this.dir.scale(time));\r\n }\r\n}\r\n","import { CollisionProcessor } from './CollisionProcessor';\r\nimport { DynamicTree } from './DynamicTree';\r\nimport { Pair } from './Pair';\r\n\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { FrameStats } from '../../Debug';\r\nimport { Logger } from '../../Util/Log';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Collider } from '../Colliders/Collider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { CompositeCollider } from '../Colliders/CompositeCollider';\r\nimport { CollisionGroup } from '../Group/CollisionGroup';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { RayCastHit } from './RayCastHit';\r\nimport { DeepRequired } from '../../Util/Required';\r\nimport { PhysicsConfig } from '../PhysicsConfig';\r\n\r\nexport interface RayCastOptions {\r\n /**\r\n * Optionally specify the maximum distance in pixels to ray cast, default is Infinity\r\n */\r\n maxDistance?: number;\r\n /**\r\n * Optionally specify a collision group to target in the ray cast, default is All.\r\n */\r\n collisionGroup?: CollisionGroup;\r\n /**\r\n * Optionally specify a collision mask to target multiple collision categories\r\n */\r\n collisionMask?: number;\r\n /**\r\n * Optionally specify to search for all colliders that intersect the ray cast, not just the first which is the default\r\n */\r\n searchAllColliders?: boolean;\r\n /**\r\n * Optionally ignore things with CollisionGroup.All and only test against things with an explicit group\r\n *\r\n * Default false\r\n */\r\n ignoreCollisionGroupAll?: boolean;\r\n\r\n /**\r\n * Optionally provide a any filter function to filter on arbitrary qualities of a ray cast hit\r\n *\r\n * Filters run after any collision mask/collision group filtering, it is the last decision\r\n *\r\n * Returning true means you want to include the collider in your results, false means exclude it\r\n */\r\n filter?: (hit: RayCastHit) => boolean;\r\n}\r\n\r\n/**\r\n * Responsible for performing the collision broadphase (locating potential collisions) and\r\n * the narrowphase (actual collision contacts)\r\n */\r\nexport class DynamicTreeCollisionProcessor implements CollisionProcessor {\r\n private _dynamicCollisionTree: DynamicTree;\r\n private _pairs = new Set();\r\n\r\n private _collisionPairCache: Pair[] = [];\r\n private _colliders: Collider[] = [];\r\n\r\n constructor(private _config: DeepRequired) {\r\n this._dynamicCollisionTree = new DynamicTree(_config.dynamicTree);\r\n }\r\n\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n public rayCast(ray: Ray, options?: RayCastOptions): RayCastHit[] {\r\n const results: RayCastHit[] = [];\r\n const maxDistance = options?.maxDistance ?? Infinity;\r\n const collisionGroup = options?.collisionGroup;\r\n const collisionMask = !collisionGroup ? options?.collisionMask ?? CollisionGroup.All.category : collisionGroup.category;\r\n const searchAllColliders = options?.searchAllColliders ?? false;\r\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider) => {\r\n const owner = collider.owner;\r\n const maybeBody = owner.get(BodyComponent);\r\n\r\n if (options?.ignoreCollisionGroupAll && maybeBody.group === CollisionGroup.All) {\r\n return false;\r\n }\r\n\r\n const canCollide = (collisionMask & maybeBody.group.category) !== 0;\r\n\r\n // Early exit if not the right group\r\n if (maybeBody?.group && !canCollide) {\r\n return false;\r\n }\r\n\r\n const hit = collider.rayCast(ray, maxDistance);\r\n\r\n if (hit) {\r\n if (options?.filter) {\r\n if (options.filter(hit)) {\r\n results.push(hit);\r\n if (!searchAllColliders) {\r\n // returning true exits the search\r\n return true;\r\n }\r\n }\r\n } else {\r\n results.push(hit);\r\n if (!searchAllColliders) {\r\n // returning true exits the search\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n return results;\r\n }\r\n\r\n /**\r\n * Tracks a physics body for collisions\r\n */\r\n public track(target: Collider): void {\r\n if (!target) {\r\n Logger.getInstance().warn('Cannot track null collider');\r\n return;\r\n }\r\n if (target instanceof CompositeCollider) {\r\n const colliders = target.getColliders();\r\n for (const c of colliders) {\r\n c.owner = target.owner;\r\n this._colliders.push(c);\r\n this._dynamicCollisionTree.trackCollider(c);\r\n }\r\n } else {\r\n this._colliders.push(target);\r\n this._dynamicCollisionTree.trackCollider(target);\r\n }\r\n }\r\n\r\n /**\r\n * Untracks a physics body\r\n */\r\n public untrack(target: Collider): void {\r\n if (!target) {\r\n Logger.getInstance().warn('Cannot untrack a null collider');\r\n return;\r\n }\r\n\r\n if (target instanceof CompositeCollider) {\r\n const colliders = target.getColliders();\r\n for (const c of colliders) {\r\n const index = this._colliders.indexOf(c);\r\n if (index !== -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this._dynamicCollisionTree.untrackCollider(c);\r\n }\r\n } else {\r\n const index = this._colliders.indexOf(target);\r\n if (index !== -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this._dynamicCollisionTree.untrackCollider(target);\r\n }\r\n }\r\n\r\n private _pairExists(colliderA: Collider, colliderB: Collider) {\r\n // if the collision pair has been calculated already short circuit\r\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n return this._pairs.has(hash);\r\n }\r\n\r\n /**\r\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\r\n */\r\n public broadphase(targets: Collider[], delta: number, stats?: FrameStats): Pair[] {\r\n const seconds = delta / 1000;\r\n\r\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\r\n const potentialColliders = targets.filter((other) => {\r\n const body = other.owner?.get(BodyComponent);\r\n return other.owner?.active && body.collisionType !== CollisionType.PreventCollision;\r\n });\r\n\r\n // clear old list of collision pairs\r\n this._collisionPairCache = [];\r\n this._pairs.clear();\r\n\r\n // check for normal collision pairs\r\n let collider: Collider;\r\n for (let j = 0, l = potentialColliders.length; j < l; j++) {\r\n collider = potentialColliders[j];\r\n // Query the collision tree for potential colliders\r\n this._dynamicCollisionTree.query(collider, (other: Collider) => {\r\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\r\n const pair = new Pair(collider, other);\r\n this._pairs.add(pair.id);\r\n this._collisionPairCache.push(pair);\r\n }\r\n // Always return false, to query whole tree. Returning true in the query method stops searching\r\n return false;\r\n });\r\n }\r\n if (stats) {\r\n stats.physics.pairs = this._collisionPairCache.length;\r\n }\r\n\r\n // Check dynamic tree for fast moving objects\r\n // Fast moving objects are those moving at least there smallest bound per frame\r\n if (this._config.continuous.checkForFastBodies) {\r\n for (const collider of potentialColliders) {\r\n const body = collider.owner.get(BodyComponent);\r\n // Skip non-active objects. Does not make sense on other collision types\r\n if (body.collisionType !== CollisionType.Active) {\r\n continue;\r\n }\r\n\r\n // Maximum travel distance next frame\r\n const updateDistance =\r\n body.vel.size * seconds + // velocity term\r\n body.acc.size * 0.5 * seconds * seconds; // acc term\r\n\r\n // Find the minimum dimension\r\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\r\n if (this._config.continuous.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\r\n if (stats) {\r\n stats.physics.fastBodies++;\r\n }\r\n\r\n // start with the oldPos because the integration for actors has already happened\r\n // objects resting on a surface may be slightly penetrating in the current position\r\n const updateVec = body.globalPos.sub(body.oldPos);\r\n const centerPoint = collider.center;\r\n const furthestPoint = collider.getFurthestPoint(body.vel);\r\n const origin: Vector = furthestPoint.sub(updateVec);\r\n\r\n const ray: Ray = new Ray(origin, body.vel);\r\n\r\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\r\n ray.pos = ray.pos.add(ray.dir.scale(-2 * this._config.continuous.surfaceEpsilon));\r\n let minCollider: Collider;\r\n let minTranslate: Vector = new Vector(Infinity, Infinity);\r\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + this._config.continuous.surfaceEpsilon * 2, (other: Collider) => {\r\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\r\n const hit = other.rayCast(ray, updateDistance + this._config.continuous.surfaceEpsilon * 10);\r\n if (hit) {\r\n const translate = hit.point.sub(origin);\r\n if (translate.size < minTranslate.size) {\r\n minTranslate = translate;\r\n minCollider = other;\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n\r\n if (minCollider && Vector.isValid(minTranslate)) {\r\n const pair = new Pair(collider, minCollider);\r\n if (!this._pairs.has(pair.id)) {\r\n this._pairs.add(pair.id);\r\n this._collisionPairCache.push(pair);\r\n }\r\n // move the fast moving object to the other body\r\n // need to push into the surface by ex.Physics.surfaceEpsilon\r\n const shift = centerPoint.sub(furthestPoint);\r\n body.globalPos = origin\r\n .add(shift)\r\n .add(minTranslate)\r\n .add(ray.dir.scale(10 * this._config.continuous.surfaceEpsilon)); // needed to push the shape slightly into contact\r\n collider.update(body.transform.get());\r\n\r\n if (stats) {\r\n stats.physics.fastBodyCollisions++;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n // return cache\r\n return this._collisionPairCache;\r\n }\r\n\r\n /**\r\n * Applies narrow phase on collision pairs to find actual area intersections\r\n * Adds actual colliding pairs to stats' Frame data\r\n */\r\n public narrowphase(pairs: Pair[], stats?: FrameStats): CollisionContact[] {\r\n let contacts: CollisionContact[] = [];\r\n for (let i = 0; i < pairs.length; i++) {\r\n const newContacts = pairs[i].collide();\r\n contacts = contacts.concat(newContacts);\r\n if (stats && newContacts.length > 0) {\r\n for (const c of newContacts) {\r\n stats.physics.contacts.set(c.id, c);\r\n }\r\n }\r\n }\r\n if (stats) {\r\n stats.physics.collisions += contacts.length;\r\n }\r\n return contacts;\r\n }\r\n\r\n /**\r\n * Update the dynamic tree positions\r\n */\r\n public update(targets: Collider[]): number {\r\n let updated = 0;\r\n const len = targets.length;\r\n\r\n for (let i = 0; i < len; i++) {\r\n if (this._dynamicCollisionTree.updateCollider(targets[i])) {\r\n updated++;\r\n }\r\n }\r\n return updated;\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext) {\r\n this._dynamicCollisionTree.debug(ex);\r\n }\r\n}\r\n","import { Color } from '../../Color';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Clonable } from '../../Interfaces/Clonable';\r\nimport { Entity } from '../../EntityComponentSystem';\r\nimport { createId, Id } from '../../Id';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { EventEmitter } from '../../EventEmitter';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\nimport { CompositeCollider } from './CompositeCollider';\r\n\r\n/**\r\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\r\n * for the purposes of colliding 2 objects in excalibur.\r\n */\r\nexport abstract class Collider implements Clonable {\r\n private static _ID = 0;\r\n public readonly id: Id<'collider'> = createId('collider', Collider._ID++);\r\n /**\r\n * Composite collider if any this collider is attached to\r\n *\r\n * **WARNING** do not tamper with this property\r\n */\r\n public composite: CompositeCollider | null = null;\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Returns a boolean indicating whether this body collided with\r\n * or was in stationary contact with\r\n * the body of the other [[Collider]]\r\n */\r\n public touching(other: Collider): boolean {\r\n const contact = this.collide(other);\r\n\r\n if (contact) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n public owner: Entity;\r\n\r\n /**\r\n * Pixel offset of the collision collider relative to the collider, by default (0, 0) meaning the collider is positioned\r\n * on top of the collider.\r\n */\r\n offset: Vector = Vector.Zero;\r\n\r\n /**\r\n * Position of the collision collider in world coordinates\r\n */\r\n abstract get worldPos(): Vector;\r\n\r\n /**\r\n * The center point of the collision collider, for example if the collider is a circle it would be the center.\r\n */\r\n abstract get center(): Vector;\r\n\r\n /**\r\n * Return the axis-aligned bounding box of the collision collider in world coordinates\r\n */\r\n abstract get bounds(): BoundingBox;\r\n\r\n /**\r\n * Return the axis-aligned bounding box of the collision collider in local coordinates\r\n */\r\n abstract get localBounds(): BoundingBox;\r\n\r\n /**\r\n * Return the axes of this particular collider\r\n */\r\n abstract get axes(): Vector[];\r\n /**\r\n * Find the furthest point on the convex hull of this particular collider in a certain direction.\r\n */\r\n abstract getFurthestPoint(direction: Vector): Vector;\r\n\r\n abstract getInertia(mass: number): number;\r\n\r\n // All new CollisionShape need to do the following\r\n // Create a new collision function in the CollisionJumpTable against all the primitives\r\n // Currently there are 3 primitive collision collider 3! = 6 jump functions\r\n abstract collide(collider: Collider): CollisionContact[];\r\n\r\n /**\r\n * Returns the closest line between the surfaces this collider and another\r\n * @param collider\r\n */\r\n abstract getClosestLineBetween(collider: Collider): LineSegment;\r\n\r\n /**\r\n * Return wether the collider contains a point inclusive to it's border\r\n */\r\n abstract contains(point: Vector): boolean;\r\n\r\n /**\r\n * Return the point on the border of the collision collider that intersects with a ray (if any).\r\n */\r\n abstract rayCast(ray: Ray, max?: number): RayCastHit | null;\r\n\r\n /**\r\n * Create a projection of this collider along an axis. Think of this as casting a \"shadow\" along an axis\r\n */\r\n abstract project(axis: Vector): Projection;\r\n\r\n /**\r\n * Updates collider world space geometry\r\n */\r\n abstract update(transform: Transform): void;\r\n\r\n\r\n abstract debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }): void;\r\n\r\n abstract clone(): Collider;\r\n}\r\n","/**\r\n * Possible collision resolution strategies\r\n *\r\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\r\n * like platformers or top down games.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n */\r\nexport enum SolverStrategy {\r\n Arcade = 'arcade',\r\n Realistic = 'realistic'\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { SolverStrategy } from './SolverStrategy';\r\n\r\n/**\r\n * Possible broadphase collision pair identification strategies\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n * @deprecated Unused in Excalibur, will be removed in v0.30\r\n */\r\nexport enum BroadphaseStrategy {\r\n DynamicAABBTree\r\n}\r\n\r\n/**\r\n * Possible numerical integrators for position and velocity\r\n * @deprecated Unused in Excalibur, will be removed in v0.30\r\n */\r\nexport enum Integrator {\r\n Euler\r\n}\r\n\r\n/**\r\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n/* istanbul ignore next */\r\nexport class Physics {\r\n /**\r\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\r\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\r\n *\r\n * This is a great way to globally simulate effects like gravity.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static acc = new Vector(0, 0);\r\n /**\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static get gravity() {\r\n return Physics.acc;\r\n }\r\n public static set gravity(v: Vector) {\r\n Physics.acc = v;\r\n }\r\n\r\n /**\r\n * Globally switches all Excalibur physics behavior on or off.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static enabled = true;\r\n\r\n /**\r\n * Gets or sets the broadphase pair identification strategy.\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static broadphaseStrategy: BroadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\r\n\r\n /**\r\n * Gets or sets the global collision resolution strategy (narrowphase).\r\n *\r\n * The default is [[SolverStrategy.Arcade]] which performs simple axis aligned arcade style physics.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[SolverStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static collisionResolutionStrategy: SolverStrategy = SolverStrategy.Arcade;\r\n /**\r\n * The default mass to use if none is specified\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static defaultMass: number = 10;\r\n /**\r\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static integrator: Integrator = Integrator.Euler;\r\n\r\n /**\r\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static useArcadePhysics(): void {\r\n Physics.collisionResolutionStrategy = SolverStrategy.Arcade;\r\n }\r\n\r\n /**\r\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\r\n * simulated physical interactions.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static useRealisticPhysics(): void {\r\n Physics.collisionResolutionStrategy = SolverStrategy.Realistic;\r\n }\r\n\r\n /**\r\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static dynamicTreeVelocityMultiplier = 2;\r\n\r\n /**\r\n * Pad RigidBody BoundingBox by a constant amount\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static boundsPadding = 5;\r\n\r\n /**\r\n * Number of position iterations (overlap) to run in the solver\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static positionIterations = 3;\r\n\r\n /**\r\n * Number of velocity iteration (response) to run in the solver\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static velocityIterations = 8;\r\n\r\n /**\r\n * Amount of overlap to tolerate in pixels\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static slop = 1;\r\n\r\n /**\r\n * Amount of positional overlap correction to apply each position iteration of the solver\r\n * O - meaning no correction, 1 - meaning correct all overlap\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static steeringFactor = 0.2;\r\n\r\n /**\r\n * Warm start set to true re-uses impulses from previous frames back in the solver\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static warmStart = true;\r\n\r\n /**\r\n * By default bodies do not sleep\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static bodiesCanSleepByDefault = false;\r\n\r\n /**\r\n * Surface epsilon is used to help deal with surface penetration\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static surfaceEpsilon = 0.1;\r\n\r\n /**\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static sleepEpsilon = 0.07;\r\n\r\n /**\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static wakeThreshold = Physics.sleepEpsilon * 3;\r\n\r\n /**\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static sleepBias = 0.9;\r\n\r\n /**\r\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\r\n * bodies from tunneling through one another.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static checkForFastBodies = true;\r\n\r\n /**\r\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\r\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\r\n * Excalibur will always perform the fast body raycast regardless of speed.\r\n * @deprecated Use engine args to configure Physics `new ex.Engine({physics: {...}})`, will be removed in v0.30\r\n */\r\n public static disableMinimumSpeedForFastBody = false;\r\n}\r\n","\r\n/**\r\n * Tells the Arcade collision solver to prefer certain contacts over others\r\n */\r\nexport enum ContactSolveBias {\r\n None = 'none',\r\n VerticalFirst = 'vertical-first',\r\n HorizontalFirst = 'horizontal-first'\r\n}\r\n\r\n/**\r\n * Contact bias values\r\n */\r\nexport interface ContactBias {\r\n vertical: number;\r\n horizontal: number;\r\n}\r\n\r\n/**\r\n * Vertical First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\r\n */\r\nexport const VerticalFirst: ContactBias = {\r\n 'vertical': 1,\r\n 'horizontal': 2\r\n} as const;\r\n\r\n/**\r\n * Horizontal First contact solve bias Used by the [[ArcadeSolver]] to sort contacts\r\n */\r\nexport const HorizontalFirst: ContactBias = {\r\n 'horizontal': 1,\r\n 'vertical': 2\r\n} as const;\r\n\r\n/**\r\n * None value, [[ArcadeSolver]] sorts contacts using distance by default\r\n */\r\nexport const None: ContactBias = {\r\n 'horizontal': 0,\r\n 'vertical': 0\r\n} as const;","import { Vector, vec } from '../Math/vector';\r\nimport { DeepRequired } from '../Util/Required';\r\nimport { SolverStrategy } from './SolverStrategy';\r\nimport { Physics } from './Physics';\r\nimport { ContactSolveBias } from './Solver/ContactBias';\r\n\r\n\r\nexport interface PhysicsConfig {\r\n /**\r\n * Excalibur physics simulation is enabled\r\n */\r\n enabled?: boolean;\r\n /**\r\n * Configure gravity that applies to all [[CollisionType.Active]] bodies.\r\n *\r\n * This is acceleration in pixels/sec^2\r\n *\r\n * Default vec(0, 0)\r\n *\r\n * [[BodyComponent.useGravity]] to opt out\r\n */\r\n gravity?: Vector;\r\n /**\r\n * Configure the type of physics simulation you would like\r\n *\r\n * * [[SolverStrategy.Arcade]] is suitable for games where you might be doing platforming or top down movement.\r\n * * [[SolverStrategy.Realistic]] is where you need objects to bounce off each other and respond like real world objects.\r\n *\r\n * Default is Arcade\r\n */\r\n solver?: SolverStrategy;\r\n\r\n /**\r\n * Configure colliders\r\n */\r\n colliders?: {\r\n /**\r\n * Treat composite collider's member colliders as either separate colliders for the purposes of onCollisionStart/onCollision\r\n * or as a single collider together.\r\n *\r\n * This property can be overridden on individual [[CompositeColliders]].\r\n *\r\n * For composites without gaps or small groups of colliders, you probably want 'together'\r\n *\r\n * For composites with deliberate gaps, like a platforming level layout, you probably want 'separate'\r\n *\r\n * Default is 'together' if unset\r\n */\r\n compositeStrategy?: 'separate' | 'together'\r\n }\r\n\r\n /**\r\n * Configure excalibur continuous collision (WIP)\r\n */\r\n continuous?: {\r\n\r\n /**\r\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\r\n * bodies from tunneling through one another.\r\n *\r\n * Default true\r\n */\r\n checkForFastBodies?: boolean;\r\n\r\n /**\r\n * Disable minimum fast moving body raycast, by default if checkForFastBodies = true Excalibur will only check if the\r\n * body is moving at least half of its minimum dimension in an update. If disableMinimumSpeedForFastBody is set to true,\r\n * Excalibur will always perform the fast body raycast regardless of speed.\r\n *\r\n * Default false\r\n */\r\n disableMinimumSpeedForFastBody?: boolean;\r\n\r\n /**\r\n * Surface epsilon is used to help deal with predicting collisions by applying a slop\r\n *\r\n * Default 0.1\r\n */\r\n surfaceEpsilon?: number;\r\n }\r\n\r\n /**\r\n * Configure body defaults\r\n */\r\n bodies?: {\r\n /**\r\n * Configure default mass that bodies have\r\n *\r\n * Default 10 mass units\r\n */\r\n defaultMass?: number;\r\n\r\n /**\r\n * Sleep epsilon\r\n *\r\n * Default 0.07\r\n */\r\n sleepEpsilon?: number;\r\n\r\n /**\r\n * Wake Threshold, the amount of \"motion\" need to wake a body from sleep\r\n *\r\n * Default 0.07 * 3;\r\n */\r\n wakeThreshold?: number;\r\n\r\n /**\r\n * Sleep bias\r\n *\r\n * Default 0.9\r\n */\r\n sleepBias?: number;\r\n\r\n /**\r\n * By default bodies do not sleep, this can be turned on to improve perf if you have a lot of bodies.\r\n *\r\n * Default false\r\n */\r\n canSleepByDefault?: boolean;\r\n }\r\n\r\n /**\r\n * Configure the dynamic tree spatial data structure for locating pairs and raycasts\r\n */\r\n dynamicTree?: {\r\n /**\r\n * Pad collider BoundingBox by a constant amount for purposes of potential pairs\r\n *\r\n * Default 5 pixels\r\n */\r\n boundsPadding?: number;\r\n\r\n /**\r\n * Factor to add to the collider BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\r\n *\r\n * Default 2\r\n */\r\n velocityMultiplier?: number;\r\n }\r\n\r\n /**\r\n * Configure the [[ArcadeSolver]]\r\n */\r\n arcade?: {\r\n /**\r\n * Hints the [[ArcadeSolver]] to preferentially solve certain contact directions first.\r\n *\r\n * Options:\r\n * * Solve [[ContactSolveBias.VerticalFirst]] which will do vertical contact resolution first (useful for platformers\r\n * with up/down gravity)\r\n * * Solve [[ContactSolveBias.HorizontalFirst]] which will do horizontal contact resolution first (useful for games with\r\n * left/right forces)\r\n * * By default [[ContactSolveBias.None]] which sorts by distance\r\n */\r\n contactSolveBias?: ContactSolveBias;\r\n }\r\n\r\n /**\r\n * Configure the [[RealisticSolver]]\r\n */\r\n realistic?: {\r\n /**\r\n * Number of position iterations (overlap) to run in the solver\r\n *\r\n * Default 3 iterations\r\n */\r\n positionIterations?: number;\r\n\r\n /**\r\n * Number of velocity iteration (response) to run in the solver\r\n *\r\n * Default 8 iterations\r\n */\r\n velocityIterations?: number;\r\n\r\n /**\r\n * Amount of overlap to tolerate in pixels\r\n *\r\n * Default 1 pixel\r\n */\r\n slop?: number;\r\n\r\n /**\r\n * Amount of positional overlap correction to apply each position iteration of the solver\r\n * 0 - meaning no correction, 1 - meaning correct all overlap. Generally values 0 < .5 look nice.\r\n *\r\n * Default 0.2\r\n */\r\n steeringFactor?: number;\r\n\r\n /**\r\n * Warm start set to true re-uses impulses from previous frames back in the solver. Re-using impulses helps\r\n * the solver converge quicker\r\n *\r\n * Default true\r\n */\r\n warmStart?: boolean;\r\n }\r\n}\r\n\r\nexport const DefaultPhysicsConfig: DeepRequired = {\r\n enabled: true,\r\n gravity: vec(0, 0),\r\n solver: SolverStrategy.Arcade,\r\n colliders: {\r\n compositeStrategy: 'together'\r\n },\r\n continuous: {\r\n checkForFastBodies: true,\r\n disableMinimumSpeedForFastBody: false,\r\n surfaceEpsilon: 0.1\r\n },\r\n bodies: {\r\n canSleepByDefault: false,\r\n sleepEpsilon: 0.07,\r\n wakeThreshold: 0.07 * 3,\r\n sleepBias: 0.9,\r\n defaultMass: 10\r\n },\r\n dynamicTree: {\r\n boundsPadding: 5,\r\n velocityMultiplier: 2\r\n },\r\n arcade: {\r\n contactSolveBias: ContactSolveBias.None\r\n },\r\n realistic: {\r\n positionIterations: 3,\r\n velocityIterations: 8,\r\n slop: 1,\r\n steeringFactor: 0.2,\r\n warmStart: true\r\n }\r\n};\r\n\r\n/**\r\n * @deprecated will be removed in v0.30\r\n */\r\nexport function DeprecatedStaticToConfig(): DeepRequired {\r\n return {\r\n enabled: Physics.enabled,\r\n gravity: Physics.gravity,\r\n solver: Physics.collisionResolutionStrategy,\r\n continuous: {\r\n checkForFastBodies: Physics.checkForFastBodies,\r\n disableMinimumSpeedForFastBody: Physics.disableMinimumSpeedForFastBody,\r\n surfaceEpsilon: Physics.surfaceEpsilon\r\n },\r\n colliders: {\r\n compositeStrategy: 'together'\r\n },\r\n bodies: {\r\n canSleepByDefault: Physics.bodiesCanSleepByDefault,\r\n sleepEpsilon: Physics.sleepEpsilon,\r\n wakeThreshold: Physics.wakeThreshold,\r\n sleepBias: Physics.sleepBias,\r\n defaultMass: Physics.defaultMass\r\n },\r\n dynamicTree: {\r\n boundsPadding: Physics.boundsPadding,\r\n velocityMultiplier: Physics.dynamicTreeVelocityMultiplier\r\n },\r\n arcade: {\r\n contactSolveBias: ContactSolveBias.None\r\n },\r\n realistic: {\r\n positionIterations: Physics.positionIterations,\r\n velocityIterations: Physics.velocityIterations,\r\n slop: Physics.slop,\r\n steeringFactor: Physics.steeringFactor,\r\n warmStart: Physics.warmStart\r\n }\r\n };\r\n}","import { Util } from '../..';\r\nimport { Pair } from '../Detection/Pair';\r\nimport { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Projection } from '../../Math/projection';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Vector } from '../../Math/vector';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { DynamicTree } from '../Detection/DynamicTree';\r\nimport { DynamicTreeCollisionProcessor } from '../Detection/DynamicTreeCollisionProcessor';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\nimport { Collider } from './Collider';\r\nimport { Transform } from '../../Math/transform';\r\nimport { DefaultPhysicsConfig } from '../PhysicsConfig';\r\n\r\nexport class CompositeCollider extends Collider {\r\n private _transform: Transform;\r\n private _collisionProcessor = new DynamicTreeCollisionProcessor(DefaultPhysicsConfig);\r\n private _dynamicAABBTree = new DynamicTree(DefaultPhysicsConfig.dynamicTree);\r\n private _colliders: Collider[] = [];\r\n\r\n private _compositeStrategy?: 'separate' | 'together';\r\n /**\r\n * Treat composite collider's member colliders as either separate colliders for the purposes of onCollisionStart/onCollision\r\n * or as a single collider together.\r\n *\r\n * This property can be overridden on individual [[CompositeColliders]].\r\n *\r\n * For composites without gaps or small groups of colliders, you probably want 'together'\r\n *\r\n * For composites with deliberate gaps, like a platforming level layout, you probably want 'separate'\r\n *\r\n * Default is 'together' if unset\r\n */\r\n public set compositeStrategy(value: 'separate' | 'together') {\r\n this._compositeStrategy = value;\r\n }\r\n public get compositeStrategy() {\r\n return this._compositeStrategy;\r\n }\r\n\r\n constructor(colliders: Collider[]) {\r\n super();\r\n for (const c of colliders) {\r\n this.addCollider(c);\r\n }\r\n }\r\n\r\n clearColliders() {\r\n this._colliders = [];\r\n }\r\n\r\n addCollider(collider: Collider) {\r\n let colliders: Collider[];\r\n if (collider instanceof CompositeCollider) {\r\n colliders = collider.getColliders();\r\n colliders.forEach(c => c.offset.addEqual(collider.offset));\r\n } else {\r\n colliders = [collider];\r\n }\r\n // Flatten composites\r\n for (const c of colliders) {\r\n c.events.pipe(this.events);\r\n c.composite = this;\r\n this._colliders.push(c);\r\n this._collisionProcessor.track(c);\r\n this._dynamicAABBTree.trackCollider(c);\r\n }\r\n }\r\n\r\n removeCollider(collider: Collider) {\r\n collider.events.pipe(this.events);\r\n collider.composite = null;\r\n Util.removeItemFromArray(collider, this._colliders);\r\n this._collisionProcessor.untrack(collider);\r\n this._dynamicAABBTree.untrackCollider(collider);\r\n }\r\n\r\n getColliders(): Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n get worldPos(): Vector {\r\n return (this._transform?.pos ?? Vector.Zero).add(this.offset);\r\n }\r\n\r\n get center(): Vector {\r\n return (this._transform?.pos ?? Vector.Zero).add(this.offset);\r\n }\r\n\r\n get bounds(): BoundingBox {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n const results = colliders.reduce(\r\n (acc, collider) => acc.combine(collider.bounds),\r\n colliders[0]?.bounds ?? new BoundingBox().translate(this.worldPos)\r\n );\r\n\r\n return results.translate(this.offset);\r\n }\r\n\r\n get localBounds(): BoundingBox {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n const results = colliders.reduce((acc, collider) => acc.combine(collider.localBounds), colliders[0]?.localBounds ?? new BoundingBox());\r\n\r\n return results;\r\n }\r\n\r\n get axes(): Vector[] {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n let axes: Vector[] = [];\r\n for (const collider of colliders) {\r\n axes = axes.concat(collider.axes);\r\n }\r\n return axes;\r\n }\r\n\r\n getFurthestPoint(direction: Vector): Vector {\r\n const colliders = this.getColliders();\r\n const furthestPoints: Vector[] = [];\r\n for (const collider of colliders) {\r\n furthestPoints.push(collider.getFurthestPoint(direction));\r\n }\r\n // Pick best point from all colliders\r\n let bestPoint = furthestPoints[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (const point of furthestPoints) {\r\n const distance = point.dot(direction);\r\n if (distance > maxDistance) {\r\n bestPoint = point;\r\n maxDistance = distance;\r\n }\r\n }\r\n return bestPoint;\r\n }\r\n\r\n getInertia(mass: number): number {\r\n const colliders = this.getColliders();\r\n let totalInertia = 0;\r\n for (const collider of colliders) {\r\n totalInertia += collider.getInertia(mass);\r\n }\r\n return totalInertia;\r\n }\r\n\r\n collide(other: Collider): CollisionContact[] {\r\n let otherColliders = [other];\r\n if (other instanceof CompositeCollider) {\r\n otherColliders = other.getColliders();\r\n }\r\n\r\n const pairs: Pair[] = [];\r\n for (const c of otherColliders) {\r\n this._dynamicAABBTree.query(c, (potentialCollider: Collider) => {\r\n pairs.push(new Pair(c, potentialCollider));\r\n return false;\r\n });\r\n }\r\n\r\n let contacts: CollisionContact[] = [];\r\n for (const p of pairs) {\r\n contacts = contacts.concat(p.collide());\r\n }\r\n return contacts;\r\n }\r\n\r\n getClosestLineBetween(other: Collider): LineSegment {\r\n const colliders = this.getColliders();\r\n const lines: LineSegment[] = [];\r\n if (other instanceof CompositeCollider) {\r\n const otherColliders = other.getColliders();\r\n for (const colliderA of colliders) {\r\n for (const colliderB of otherColliders) {\r\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\r\n if (maybeLine) {\r\n lines.push(maybeLine);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const collider of colliders) {\r\n const maybeLine = other.getClosestLineBetween(collider);\r\n if (maybeLine) {\r\n lines.push(maybeLine);\r\n }\r\n }\r\n }\r\n\r\n if (lines.length) {\r\n let minLength = lines[0].getLength();\r\n let minLine = lines[0];\r\n for (const line of lines) {\r\n const length = line.getLength();\r\n if (length < minLength) {\r\n minLength = length;\r\n minLine = line;\r\n }\r\n }\r\n return minLine;\r\n }\r\n return null;\r\n }\r\n contains(point: Vector): boolean {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n if (collider.contains(point)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n rayCast(ray: Ray, max?: number): RayCastHit | null {\r\n const colliders = this.getColliders();\r\n const hits: RayCastHit[] = [];\r\n for (const collider of colliders) {\r\n const hit = collider.rayCast(ray, max);\r\n if (hit) {\r\n hits.push(hit);\r\n }\r\n }\r\n if (hits.length) {\r\n let minHit = hits[0];\r\n let minDistance = minHit.point.dot(ray.dir);\r\n for (const hit of hits) {\r\n const distance = ray.dir.dot(hit.point);\r\n if (distance < minDistance) {\r\n minHit = hit;\r\n minDistance = distance;\r\n }\r\n }\r\n return minHit;\r\n }\r\n return null;\r\n }\r\n project(axis: Vector): Projection {\r\n const colliders = this.getColliders();\r\n const projections: Projection[] = [];\r\n for (const collider of colliders) {\r\n const proj = collider.project(axis);\r\n if (proj) {\r\n projections.push(proj);\r\n }\r\n }\r\n // Merge all proj's on the same axis\r\n if (projections.length) {\r\n const newProjection = new Projection(projections[0].min, projections[0].max);\r\n for (const proj of projections) {\r\n newProjection.min = Math.min(proj.min, newProjection.min);\r\n newProjection.max = Math.max(proj.max, newProjection.max);\r\n }\r\n return newProjection;\r\n }\r\n return null;\r\n }\r\n\r\n update(transform: Transform): void {\r\n if (transform) {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n collider.owner = this.owner;\r\n collider.update(transform);\r\n }\r\n }\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }) {\r\n const colliders = this.getColliders();\r\n ex.save();\r\n ex.translate(this.offset.x, this.offset.y);\r\n for (const collider of colliders) {\r\n collider.debug(ex, color, options);\r\n }\r\n ex.restore();\r\n }\r\n\r\n clone(): Collider {\r\n const result = new CompositeCollider(this._colliders.map((c) => c.clone()));\r\n result.offset = this.offset.clone();\r\n return result;\r\n }\r\n}\r\n","import { Vector } from './vector';\r\n\r\n/**\r\n * A 2D line segment\r\n */\r\n\r\nexport class LineSegment {\r\n\r\n /**\r\n * @param begin The starting point of the line segment\r\n * @param end The ending point of the line segment\r\n */\r\n constructor(public readonly begin: Vector, public readonly end: Vector) {}\r\n\r\n /**\r\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\r\n */\r\n public get slope() {\r\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\r\n }\r\n\r\n /**\r\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\r\n */\r\n public get intercept() {\r\n return this.begin.y - this.slope * this.begin.x;\r\n }\r\n\r\n private _normal: Vector;\r\n /**\r\n * Gets the normal of the line\r\n */\r\n public normal(): Vector {\r\n if (this._normal) {\r\n return this._normal;\r\n }\r\n return this._normal = this.end.sub(this.begin).normal();\r\n }\r\n\r\n private _dir: Vector;\r\n public dir(): Vector {\r\n if (this._dir) {\r\n return this._dir;\r\n }\r\n return this._dir = this.end.sub(this.begin);\r\n }\r\n\r\n public getPoints(): Vector[] {\r\n return [this.begin, this.end];\r\n }\r\n\r\n private _slope: Vector;\r\n /**\r\n * Returns the slope of the line in the form of a vector of length 1\r\n */\r\n public getSlope(): Vector {\r\n if (this._slope) {\r\n return this._slope;\r\n }\r\n const begin = this.begin;\r\n const end = this.end;\r\n const distance = begin.distance(end);\r\n return this._slope = end.sub(begin).scale(1 / distance);\r\n }\r\n\r\n /**\r\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\r\n */\r\n public getEdge(): Vector {\r\n const begin = this.begin;\r\n const end = this.end;\r\n return end.sub(begin);\r\n }\r\n\r\n private _length: number;\r\n /**\r\n * Returns the length of the line segment in pixels\r\n */\r\n public getLength(): number {\r\n if (this._length) {\r\n return this._length;\r\n }\r\n const begin = this.begin;\r\n const end = this.end;\r\n const distance = begin.distance(end);\r\n return this._length = distance;\r\n }\r\n\r\n /**\r\n * Returns the midpoint of the edge\r\n */\r\n public get midpoint(): Vector {\r\n return this.begin.add(this.end).scale(0.5);\r\n }\r\n\r\n /**\r\n * Flips the direction of the line segment\r\n */\r\n public flip(): LineSegment {\r\n return new LineSegment(this.end, this.begin);\r\n }\r\n\r\n /**\r\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\r\n * @param point\r\n */\r\n public below(point: Vector): boolean {\r\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\r\n return above2 >= 0;\r\n }\r\n\r\n /**\r\n * Returns the clip point\r\n * @param sideVector Vector that traces the line\r\n * @param length Length to clip along side\r\n */\r\n public clip(sideVector: Vector, length: number): LineSegment {\r\n let dir = sideVector;\r\n dir = dir.normalize();\r\n\r\n const near = dir.dot(this.begin) - length;\r\n const far = dir.dot(this.end) - length;\r\n\r\n const results = [];\r\n if (near <= 0) {\r\n results.push(this.begin);\r\n }\r\n if (far <= 0) {\r\n results.push(this.end);\r\n }\r\n\r\n if (near * far < 0) {\r\n const clipTime = near / (near - far);\r\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\r\n }\r\n if (results.length !== 2) {\r\n return null;\r\n }\r\n\r\n return new LineSegment(results[0], results[1]);\r\n }\r\n\r\n /**\r\n * Find the perpendicular distance from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * @param point\r\n */\r\n public distanceToPoint(point: Vector, signed: boolean = false) {\r\n const x0 = point.x;\r\n const y0 = point.y;\r\n\r\n const l = this.getLength();\r\n\r\n const dy = this.end.y - this.begin.y;\r\n const dx = this.end.x - this.begin.x;\r\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\r\n return signed ? distance : Math.abs(distance);\r\n }\r\n\r\n /**\r\n * Find the perpendicular line from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * (a - p) - ((a - p) * n)n\r\n * a is a point on the line\r\n * p is the arbitrary point above the line\r\n * n is a unit vector in direction of the line\r\n * @param point\r\n */\r\n public findVectorToPoint(point: Vector): Vector {\r\n const aMinusP = this.begin.sub(point);\r\n const n = this.getSlope();\r\n\r\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\r\n }\r\n\r\n /**\r\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\r\n * a new point with the calculated Y value and vice-versa.\r\n * @param x The known X value of the target point\r\n * @param y The known Y value of the target point\r\n * @returns A new point with the other calculated axis value\r\n */\r\n public findPoint(x: number = null, y: number = null): Vector {\r\n const m = this.slope;\r\n const b = this.intercept;\r\n\r\n if (x !== null) {\r\n return new Vector(x, m * x + b);\r\n } else if (y !== null) {\r\n return new Vector((y - b) / m, y);\r\n } else {\r\n throw new Error('You must provide an X or a Y value');\r\n }\r\n }\r\n\r\n /**\r\n * Whether or not the given point lies on this line. This method is precise by default\r\n * meaning the point must lie exactly on the line. Adjust threshold to\r\n * loosen the strictness of the check for floating-point calculations.\r\n */\r\n public hasPoint(x: number, y: number, threshold?: number): boolean;\r\n\r\n /**\r\n * Whether or not the given point lies on this line. This method is precise by default\r\n * meaning the point must lie exactly on the line. Adjust threshold to\r\n * loosen the strictness of the check for floating-point calculations.\r\n */\r\n public hasPoint(v: Vector, threshold?: number): boolean;\r\n\r\n /**\r\n * @see http://stackoverflow.com/a/11908158/109458\r\n */\r\n public hasPoint(): boolean {\r\n let currPoint: Vector;\r\n let threshold = 0;\r\n\r\n if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') {\r\n currPoint = new Vector(arguments[0], arguments[1]);\r\n threshold = arguments[2] || 0;\r\n } else if (arguments[0] instanceof Vector) {\r\n currPoint = arguments[0];\r\n threshold = arguments[1] || 0;\r\n } else {\r\n throw 'Could not determine the arguments for Vector.hasPoint';\r\n }\r\n\r\n const dxc = currPoint.x - this.begin.x;\r\n const dyc = currPoint.y - this.begin.y;\r\n\r\n const dx1 = this.end.x - this.begin.x;\r\n const dy1 = this.end.y - this.begin.y;\r\n\r\n const cross = dxc * dy1 - dyc * dx1;\r\n\r\n // check whether point lines on the line\r\n if (Math.abs(cross) > threshold) {\r\n return false;\r\n }\r\n\r\n // check whether point lies in-between start and end\r\n if (Math.abs(dx1) >= Math.abs(dy1)) {\r\n return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\r\n } else {\r\n return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\r\n }\r\n }\r\n}\r\n","import { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { CircleCollider } from './CircleCollider';\r\n\r\n/**\r\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\r\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n * @param p0 Point where L1 begins\r\n * @param u Direction and length of L1\r\n * @param q0 Point were L2 begins\r\n * @param v Direction and length of L2\r\n */\r\nexport function ClosestLine(p0: Vector, u: Vector, q0: Vector, v: Vector) {\r\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\r\n\r\n // w(s, t) = P(s) - Q(t)\r\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\r\n //\r\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\r\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\r\n //\r\n // The closest point between 2 lines then satisfies this pair of equations\r\n // 1: u * wClosest = 0\r\n // 2: v * wClosest = 0\r\n //\r\n // Substituting wClosest into the equations we get\r\n //\r\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\r\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\r\n\r\n // simplify w0\r\n const w0 = p0.sub(q0);\r\n\r\n // simplify (u * u);\r\n const a = u.dot(u);\r\n // simplify (u * v);\r\n const b = u.dot(v);\r\n // simplify (v * v)\r\n const c = v.dot(v);\r\n // simplify (u * w0)\r\n const d = u.dot(w0);\r\n // simplify (v * w0)\r\n const e = v.dot(w0);\r\n\r\n // denominator ac - b^2\r\n const denom = a * c - b * b;\r\n let sDenom = denom;\r\n let tDenom = denom;\r\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\r\n if (denom === 0 || denom <= 0.01) {\r\n const tClosestParallel = d / b;\r\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\r\n }\r\n\r\n // Solve for sClosest for infinite line\r\n let sClosest = b * e - c * d; // / denom;\r\n\r\n // Solve for tClosest for infinite line\r\n let tClosest = a * e - b * d; // / denom;\r\n\r\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\r\n if (sClosest < 0) {\r\n sClosest = 0;\r\n tClosest = e;\r\n tDenom = c;\r\n } else if (sClosest > sDenom) {\r\n sClosest = sDenom;\r\n tClosest = e + b;\r\n tDenom = c;\r\n }\r\n\r\n if (tClosest < 0) {\r\n tClosest = 0;\r\n if (-d < 0) {\r\n sClosest = 0;\r\n } else if (-d > a) {\r\n sClosest = sDenom;\r\n } else {\r\n sClosest = -d;\r\n sDenom = a;\r\n }\r\n } else if (tClosest > tDenom) {\r\n tClosest = tDenom;\r\n if (-d + b < 0) {\r\n sClosest = 0;\r\n } else if (-d + b > a) {\r\n sClosest = sDenom;\r\n } else {\r\n sClosest = -d + b;\r\n sDenom = a;\r\n }\r\n }\r\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\r\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\r\n\r\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\r\n}\r\n\r\nexport const ClosestLineJumpTable = {\r\n PolygonPolygonClosestLine(polygonA: PolygonCollider, polygonB: PolygonCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = polygonB.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\r\n const thisDirection = otherDirection.negate();\r\n\r\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\r\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\r\n\r\n const thisPoint = polygonA.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\r\n const otherPoint = polygonB.rayCast(rayTowardsThis).point.add(rayTowardsThis.dir.scale(0.1));\r\n\r\n const thisFace = polygonA.getClosestFace(thisPoint);\r\n const otherFace = polygonB.getClosestFace(otherPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const q0 = otherFace.face.begin;\r\n const v = otherFace.face.getEdge();\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n },\r\n\r\n PolygonEdgeClosestLine(polygon: PolygonCollider, edge: EdgeCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = edge.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\r\n\r\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\r\n\r\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\r\n\r\n const thisFace = polygon.getClosestFace(thisPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const edgeLine = edge.asLine();\r\n const edgeStart = edgeLine.begin;\r\n const edgeVector = edgeLine.getEdge();\r\n const q0 = edgeStart;\r\n const v = edgeVector;\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n },\r\n\r\n PolygonCircleClosestLine(polygon: PolygonCollider, circle: CircleCollider) {\r\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = circle.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\r\n\r\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\r\n\r\n const thisPoint = polygon.rayCast(rayTowardsOther).point.add(rayTowardsOther.dir.scale(0.1));\r\n\r\n const thisFace = polygon.getClosestFace(thisPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // Time of minimum distance\r\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\r\n\r\n // If time of minimum is past the edge clamp\r\n if (t > 1) {\r\n t = 1;\r\n } else if (t < 0) {\r\n t = 0;\r\n }\r\n\r\n // Minimum distance\r\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\r\n\r\n const circlex = ((p0.x + u.x * t - otherWorldPos.x) * circle.radius) / (circle.radius + d);\r\n const circley = ((p0.y + u.y * t - otherWorldPos.y) * circle.radius) / (circle.radius + d);\r\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\r\n },\r\n\r\n CircleCircleClosestLine(circleA: CircleCollider, circleB: CircleCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = circleB.worldPos;\r\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\r\n\r\n const thisWorldPos = circleA.worldPos;\r\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\r\n\r\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\r\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\r\n\r\n const thisPoint = circleA.rayCast(rayTowardsOther);\r\n const otherPoint = circleB.rayCast(rayTowardsThis);\r\n\r\n return new LineSegment(thisPoint.point, otherPoint.point);\r\n },\r\n\r\n CircleEdgeClosestLine(circle: CircleCollider, edge: EdgeCollider) {\r\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\r\n const circleWorldPos = circle.worldPos;\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const edgeLine = edge.asLine();\r\n const edgeStart = edgeLine.begin;\r\n const edgeVector = edgeLine.getEdge();\r\n const p0 = edgeStart;\r\n const u = edgeVector;\r\n\r\n // Time of minimum distance\r\n let t = (u.x * (circleWorldPos.x - p0.x) + u.y * (circleWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\r\n\r\n // If time of minimum is past the edge clamp to edge\r\n if (t > 1) {\r\n t = 1;\r\n } else if (t < 0) {\r\n t = 0;\r\n }\r\n\r\n // Minimum distance\r\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorldPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorldPos.y, 2)) - circle.radius;\r\n\r\n const circlex = ((p0.x + u.x * t - circleWorldPos.x) * circle.radius) / (circle.radius + d);\r\n const circley = ((p0.y + u.y * t - circleWorldPos.y) * circle.radius) / (circle.radius + d);\r\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorldPos.x + circlex, circleWorldPos.y + circley));\r\n },\r\n\r\n EdgeEdgeClosestLine(edgeA: EdgeCollider, edgeB: EdgeCollider) {\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const edgeLineA = edgeA.asLine();\r\n const edgeStartA = edgeLineA.begin;\r\n const edgeVectorA = edgeLineA.getEdge();\r\n const p0 = edgeStartA;\r\n const u = edgeVectorA;\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const edgeLineB = edgeB.asLine();\r\n const edgeStartB = edgeLineB.begin;\r\n const edgeVectorB = edgeLineB.getEdge();\r\n const q0 = edgeStartB;\r\n const v = edgeVectorB;\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n }\r\n};\r\n","import { BoundingBox } from '../BoundingBox';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\n\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Color } from '../../Color';\r\nimport { Collider } from './Collider';\r\n\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { BodyComponent } from '../Index';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\n\r\nexport interface CircleColliderOptions {\r\n /**\r\n * Optional pixel offset to shift the circle relative to the collider, by default (0, 0).\r\n */\r\n offset?: Vector;\r\n /**\r\n * Required radius of the circle\r\n */\r\n radius: number;\r\n}\r\n\r\n/**\r\n * This is a circle collider for the excalibur rigid body physics simulation\r\n */\r\nexport class CircleCollider extends Collider {\r\n /**\r\n * Position of the circle relative to the collider, by default (0, 0).\r\n */\r\n public offset: Vector = Vector.Zero;\r\n\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n public get worldPos(): Vector {\r\n return this._globalMatrix.getPosition();\r\n }\r\n\r\n private _naturalRadius: number;\r\n /**\r\n * Get the radius of the circle\r\n */\r\n public get radius(): number {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\r\n return this._naturalRadius * Math.min(scale.x, scale.y);\r\n }\r\n\r\n /**\r\n * Set the radius of the circle\r\n */\r\n public set radius(val: number) {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\r\n this._naturalRadius = val / Math.min(scale.x, scale.y);\r\n }\r\n\r\n private _transform: Transform;\r\n\r\n constructor(options: CircleColliderOptions) {\r\n super();\r\n this.offset = options.offset || Vector.Zero;\r\n this.radius = options.radius || 0;\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Returns a clone of this shape, not associated with any collider\r\n */\r\n public clone(): CircleCollider {\r\n return new CircleCollider({\r\n offset: this.offset.clone(),\r\n radius: this.radius\r\n });\r\n }\r\n\r\n /**\r\n * Get the center of the collider in world coordinates\r\n */\r\n public get center(): Vector {\r\n return this._globalMatrix.getPosition();\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collider\r\n */\r\n public contains(point: Vector): boolean {\r\n const pos = this._transform?.pos ?? this.offset;\r\n const distance = pos.distance(point);\r\n if (distance <= this.radius) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Casts a ray at the Circle collider and returns the nearest point of collision\r\n * @param ray\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity): RayCastHit | null {\r\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\r\n const c = this.center;\r\n const dir = ray.dir;\r\n const orig = ray.pos;\r\n\r\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\r\n\r\n if (discriminant < 0) {\r\n // no intersection\r\n return null;\r\n } else {\r\n let toi = 0;\r\n // tangent case\r\n if (discriminant === 0) {\r\n toi = -dir.dot(orig.sub(c));\r\n if (toi > 0 && toi < max) {\r\n const point = ray.getPoint(toi);\r\n return {\r\n point,\r\n normal: point.sub(c).normalize(),\r\n collider: this,\r\n body: this.owner?.get(BodyComponent),\r\n distance: toi\r\n } satisfies RayCastHit;\r\n }\r\n return null;\r\n } else { // two point\r\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\r\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\r\n\r\n const positiveToi: number[] = [];\r\n if (toi1 >= 0) {\r\n positiveToi.push(toi1);\r\n }\r\n\r\n if (toi2 >= 0) {\r\n positiveToi.push(toi2);\r\n }\r\n\r\n const minToi = Math.min(...positiveToi);\r\n if (minToi <= max) {\r\n const point = ray.getPoint(minToi);\r\n return {\r\n point,\r\n normal: point.sub(c).normalize(),\r\n collider: this,\r\n body: this.owner?.get(BodyComponent),\r\n distance: minToi\r\n } satisfies RayCastHit;\r\n }\r\n return null;\r\n }\r\n }\r\n }\r\n\r\n public getClosestLineBetween(shape: Collider): LineSegment {\r\n if (shape instanceof CircleCollider) {\r\n return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\r\n } else if (shape instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\r\n } else if (shape instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public collide(collider: Collider): CollisionContact[] {\r\n if (collider instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCircleCircle(this, collider);\r\n } else if (collider instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollideCirclePolygon(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollideCircleEdge(this, collider);\r\n } else {\r\n throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n return this.center.add(direction.normalize().scale(this.radius));\r\n }\r\n\r\n /**\r\n * Find the local point on the shape in the direction specified\r\n * @param direction\r\n */\r\n public getFurthestLocalPoint(direction: Vector): Vector {\r\n const dir = direction.normalize();\r\n return dir.scale(this.radius);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the circle collider in world coordinates\r\n */\r\n public get bounds(): BoundingBox {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n const rotation = tx?.globalRotation ?? 0;\r\n const pos = (tx?.globalPos ?? Vector.Zero);\r\n return new BoundingBox(\r\n this.offset.x - this._naturalRadius,\r\n this.offset.y - this._naturalRadius,\r\n this.offset.x + this._naturalRadius,\r\n this.offset.y + this._naturalRadius\r\n ).rotate(rotation).scale(scale).translate(pos);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the circle collider in local coordinates\r\n */\r\n public get localBounds(): BoundingBox {\r\n return new BoundingBox(\r\n this.offset.x - this._naturalRadius,\r\n this.offset.y - this._naturalRadius,\r\n this.offset.x + this._naturalRadius,\r\n this.offset.y + this._naturalRadius\r\n );\r\n }\r\n\r\n /**\r\n * Get axis not implemented on circles, since there are infinite axis in a circle\r\n */\r\n public get axes(): Vector[] {\r\n return [];\r\n }\r\n\r\n /**\r\n * Returns the moment of inertia of a circle given it's mass\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n return (mass * this.radius * this.radius) / 2;\r\n }\r\n\r\n /* istanbul ignore next */\r\n public update(transform: Transform): void {\r\n this._transform = transform;\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Project the circle along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const scalars = [];\r\n const point = this.center;\r\n const dotProduct = point.dot(axis);\r\n scalars.push(dotProduct);\r\n scalars.push(dotProduct + this.radius);\r\n scalars.push(dotProduct - this.radius);\r\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number }) {\r\n const { lineWidth } = { ...{ lineWidth: 1 }, ...options };\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n const rotation = tx?.globalRotation ?? 0;\r\n const pos = (tx?.globalPos ?? Vector.Zero);\r\n ex.save();\r\n ex.translate(pos.x, pos.y);\r\n ex.rotate(rotation);\r\n ex.scale(scale.x, scale.y);\r\n ex.drawCircle((this.offset ?? Vector.Zero), this._naturalRadius, Color.Transparent, color, lineWidth);\r\n ex.restore();\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { Collider } from '../Colliders/Collider';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Pair } from './Pair';\r\nimport { SeparationInfo } from '../Colliders/SeparatingAxis';\r\nimport { BodyComponent } from '../BodyComponent';\r\n\r\n/**\r\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\r\n * Pair prevents collisions from being evaluated more than one time\r\n */\r\nexport class CollisionContact {\r\n private _canceled = false;\r\n\r\n /**\r\n * Currently the ids between colliders\r\n */\r\n readonly id: string;\r\n\r\n /**\r\n * The first collider in the collision\r\n */\r\n colliderA: Collider;\r\n\r\n /**\r\n * The second collider in the collision\r\n */\r\n colliderB: Collider;\r\n\r\n /**\r\n * The minimum translation vector to resolve overlap, pointing away from colliderA\r\n */\r\n mtv: Vector;\r\n\r\n /**\r\n * World space contact points between colliderA and colliderB\r\n */\r\n points: Vector[];\r\n\r\n /**\r\n * Local space contact points between colliderA and colliderB\r\n */\r\n localPoints: Vector[];\r\n\r\n /**\r\n * The collision normal, pointing away from colliderA\r\n */\r\n normal: Vector;\r\n\r\n /**\r\n * The collision tangent\r\n */\r\n tangent: Vector;\r\n\r\n /**\r\n * Information about the specifics of the collision contact separation\r\n */\r\n info: SeparationInfo;\r\n\r\n constructor(\r\n colliderA: Collider,\r\n colliderB: Collider,\r\n mtv: Vector,\r\n normal: Vector,\r\n tangent: Vector,\r\n points: Vector[],\r\n localPoints: Vector[],\r\n info: SeparationInfo\r\n ) {\r\n this.colliderA = colliderA;\r\n this.colliderB = colliderB;\r\n this.mtv = mtv;\r\n this.normal = normal;\r\n this.tangent = tangent;\r\n this.points = points;\r\n this.localPoints = localPoints;\r\n this.info = info;\r\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n if (colliderA.composite || colliderB.composite) {\r\n // Add on the parent composite pair for start/end contact if 'together\r\n const colliderAId = colliderA.composite?.compositeStrategy === 'separate' ? colliderA.id : colliderA.composite?.id ?? colliderA.id;\r\n const colliderBId = colliderB.composite?.compositeStrategy === 'separate' ? colliderB.id : colliderB.composite?.id ?? colliderB.id;\r\n this.id += '|' + Pair.calculatePairHash(colliderAId, colliderBId);\r\n }\r\n }\r\n\r\n /**\r\n * Match contact awake state, except if body's are Fixed\r\n */\r\n public matchAwake(): void {\r\n const bodyA = this.colliderA.owner.get(BodyComponent);\r\n const bodyB = this.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.sleeping !== bodyB.sleeping) {\r\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= bodyA.wakeThreshold) {\r\n bodyA.setSleeping(false);\r\n }\r\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= bodyB.wakeThreshold) {\r\n bodyB.setSleeping(false);\r\n }\r\n }\r\n }\r\n }\r\n\r\n public isCanceled() {\r\n return this._canceled;\r\n }\r\n\r\n public cancel(): void {\r\n this._canceled = true;\r\n }\r\n}\r\n","import { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Collider } from './Collider';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { PolygonCollider } from './PolygonCollider';\r\n\r\n/**\r\n * Specific information about a contact and it's separation\r\n */\r\nexport interface SeparationInfo {\r\n /**\r\n * Collider A\r\n */\r\n collider: Collider;\r\n\r\n /**\r\n * Signed value (negative means overlap, positive no overlap)\r\n */\r\n separation: number;\r\n\r\n /**\r\n * Axis of separation from the collider's perspective\r\n */\r\n axis: Vector;\r\n\r\n /**\r\n * Side of separation (reference) from the collider's perspective\r\n */\r\n\r\n side?: LineSegment;\r\n\r\n /**\r\n * Local side of separation (reference) from the collider's perspective\r\n */\r\n localSide?: LineSegment;\r\n\r\n /**\r\n * Index of the separation side (reference) from the collider's perspective\r\n */\r\n sideId?: number;\r\n\r\n /**\r\n * Point on collider B (incident point)\r\n */\r\n point: Vector;\r\n\r\n /**\r\n * Local point on collider B (incident point)\r\n */\r\n localPoint?: Vector;\r\n}\r\n\r\nexport class SeparatingAxis {\r\n static findPolygonPolygonSeparation(polyA: PolygonCollider, polyB: PolygonCollider): SeparationInfo {\r\n let bestSeparation = -Number.MAX_VALUE;\r\n let bestSide: LineSegment | null = null;\r\n let bestAxis: Vector | null = null;\r\n let bestSideIndex: number = -1;\r\n let bestOtherPoint: Vector | null = null;\r\n const sides = polyA.getSides();\r\n const localSides = polyA.getLocalSides();\r\n for (let i = 0; i < sides.length; i++) {\r\n const side = sides[i];\r\n const axis = side.normal();\r\n const vertB = polyB.getFurthestPoint(axis.negate());\r\n // Separation on side i's axis\r\n // We are looking for the largest separation between poly A's sides\r\n const vertSeparation = side.distanceToPoint(vertB, true);\r\n if (vertSeparation > bestSeparation) {\r\n bestSeparation = vertSeparation;\r\n bestSide = side;\r\n bestAxis = axis;\r\n bestSideIndex = i;\r\n bestOtherPoint = vertB;\r\n }\r\n }\r\n\r\n return {\r\n collider: polyA,\r\n separation: bestAxis ? bestSeparation : 99,\r\n axis: bestAxis as Vector,\r\n side: bestSide,\r\n localSide: localSides[bestSideIndex],\r\n sideId: bestSideIndex,\r\n point: bestOtherPoint as Vector,\r\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis!.negate()) : null\r\n };\r\n }\r\n\r\n static findCirclePolygonSeparation(circle: CircleCollider, polygon: PolygonCollider): Vector | null {\r\n const axes = polygon.axes;\r\n const pc = polygon.center;\r\n // Special SAT with circles\r\n const polyDir = pc.sub(circle.worldPos);\r\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\r\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\r\n\r\n let minOverlap = Number.MAX_VALUE;\r\n let minAxis = null;\r\n let minIndex = -1;\r\n for (let i = 0; i < axes.length; i++) {\r\n const proj1 = polygon.project(axes[i]);\r\n const proj2 = circle.project(axes[i]);\r\n const overlap = proj1.getOverlap(proj2);\r\n if (overlap <= 0) {\r\n return null;\r\n } else {\r\n if (overlap < minOverlap) {\r\n minOverlap = overlap;\r\n minAxis = axes[i];\r\n minIndex = i;\r\n }\r\n }\r\n }\r\n if (minIndex < 0) {\r\n return null;\r\n }\r\n return minAxis.normalize().scale(minOverlap);\r\n }\r\n}\r\n","import { CircleCollider } from './CircleCollider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { SeparatingAxis, SeparationInfo } from './SeparatingAxis';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { TransformComponent } from '../../EntityComponentSystem';\r\nimport { Pair } from '../Detection/Pair';\r\n\r\nexport const CollisionJumpTable = {\r\n CollideCircleCircle(circleA: CircleCollider, circleB: CircleCollider): CollisionContact[] {\r\n const circleAPos = circleA.worldPos;\r\n const circleBPos = circleB.worldPos;\r\n const combinedRadius = circleA.radius + circleB.radius;\r\n const distance = circleAPos.distance(circleBPos);\r\n\r\n if (distance > combinedRadius) {\r\n return [];\r\n }\r\n\r\n // negative means overlap\r\n const separation = combinedRadius - distance;\r\n\r\n // Normal points from A -> B\r\n const normal = circleBPos.sub(circleAPos).normalize();\r\n const tangent = normal.perpendicular();\r\n const mvt = normal.scale(separation);\r\n\r\n const point = circleA.getFurthestPoint(normal);\r\n const local = circleA.getFurthestLocalPoint(normal);\r\n\r\n const info: SeparationInfo = {\r\n collider: circleA,\r\n separation,\r\n axis: normal,\r\n point: point\r\n };\r\n\r\n return [new CollisionContact(circleA, circleB, mvt, normal, tangent, [point], [local], info)];\r\n },\r\n\r\n CollideCirclePolygon(circle: CircleCollider, polygon: PolygonCollider): CollisionContact[] {\r\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\r\n if (!minAxis) {\r\n return [];\r\n }\r\n\r\n // make sure that the minAxis is pointing away from circle\r\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\r\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\r\n\r\n const point = circle.getFurthestPoint(minAxis);\r\n const xf = circle.owner?.get(TransformComponent) ?? new TransformComponent();\r\n const local = xf.applyInverse(point);\r\n const normal = minAxis.normalize();\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: -minAxis.size,\r\n axis: normal,\r\n point: point,\r\n localPoint: local,\r\n side: polygon.findSide(normal.negate()),\r\n localSide: polygon.findLocalSide(normal.negate())\r\n };\r\n\r\n return [new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [point], [local], info)];\r\n },\r\n\r\n CollideCircleEdge(circle: CircleCollider, edge: EdgeCollider): CollisionContact[] {\r\n // TODO not sure this actually abides by local/world collisions\r\n // Are edge.begin and edge.end local space or world space? I think they should be local\r\n\r\n // center of the circle in world pos\r\n const cc = circle.center;\r\n // vector in the direction of the edge\r\n const edgeWorld = edge.asLine();\r\n const e = edgeWorld.end.sub(edgeWorld.begin);\r\n\r\n // amount of overlap with the circle's center along the edge direction\r\n const u = e.dot(edgeWorld.end.sub(cc));\r\n const v = e.dot(cc.sub(edgeWorld.begin));\r\n const side = edge.asLine();\r\n const localSide = edge.asLocalLine();\r\n\r\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\r\n if (v <= 0) {\r\n const da = edgeWorld.begin.sub(cc);\r\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\r\n // save some sqrts\r\n if (dda > circle.radius * circle.radius) {\r\n return []; // no collision\r\n }\r\n\r\n const normal = da.normalize();\r\n const separation = circle.radius - Math.sqrt(dda);\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: side.begin,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.begin], [localSide.begin], info)\r\n ];\r\n }\r\n\r\n // Potential region B collision (circle is on the right side of the edge, after the end)\r\n if (u <= 0) {\r\n const db = edgeWorld.end.sub(cc);\r\n const ddb = db.dot(db);\r\n if (ddb > circle.radius * circle.radius) {\r\n return [];\r\n }\r\n\r\n const normal = db.normalize();\r\n const separation = circle.radius - Math.sqrt(ddb);\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: side.end,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.end], [localSide.end], info)\r\n ];\r\n }\r\n\r\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\r\n const den = e.dot(e);\r\n const pointOnEdge = edgeWorld.begin\r\n .scale(u)\r\n .add(edgeWorld.end.scale(v))\r\n .scale(1 / den);\r\n const d = cc.sub(pointOnEdge);\r\n\r\n const dd = d.dot(d);\r\n if (dd > circle.radius * circle.radius) {\r\n return []; // no collision\r\n }\r\n\r\n let normal = e.perpendicular();\r\n // flip correct direction\r\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\r\n normal.x = -normal.x;\r\n normal.y = -normal.y;\r\n }\r\n\r\n normal = normal.normalize();\r\n const separation = circle.radius - Math.sqrt(dd);\r\n\r\n const mvt = normal.scale(separation);\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: pointOnEdge,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(\r\n circle,\r\n edge,\r\n mvt,\r\n normal.negate(),\r\n normal.negate().perpendicular(),\r\n [pointOnEdge],\r\n [pointOnEdge.sub(edge.worldPos)],\r\n info\r\n )\r\n ];\r\n },\r\n\r\n CollideEdgeEdge(): CollisionContact[] {\r\n // Edge-edge collision doesn't make sense\r\n return [];\r\n },\r\n\r\n CollidePolygonEdge(polygon: PolygonCollider, edge: EdgeCollider): CollisionContact[] {\r\n const pc = polygon.center;\r\n const ec = edge.center;\r\n const dir = ec.sub(pc).normalize();\r\n\r\n // build a temporary polygon from the edge to use SAT\r\n const linePoly = new PolygonCollider({\r\n points: [edge.begin, edge.end, edge.end.add(dir.scale(100)), edge.begin.add(dir.scale(100))],\r\n offset: edge.offset\r\n });\r\n linePoly.owner = edge.owner;\r\n const tx = edge.owner?.get(TransformComponent);\r\n if (tx) {\r\n linePoly.update(edge.owner.get(TransformComponent).get());\r\n }\r\n // Gross hack but poly-poly works well\r\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\r\n if (contact.length) {\r\n // Fudge the contact back to edge\r\n contact[0].colliderB = edge;\r\n (contact[0].id as any) = Pair.calculatePairHash(polygon.id, edge.id);\r\n }\r\n return contact;\r\n },\r\n\r\n CollidePolygonPolygon(polyA: PolygonCollider, polyB: PolygonCollider): CollisionContact[] {\r\n // Multi contact from SAT\r\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\r\n // do a SAT test to find a min axis if it exists\r\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\r\n // If there is no overlap from boxA's perspective we can end early\r\n if (separationA.separation > 0) {\r\n return [];\r\n }\r\n\r\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\r\n // If there is no overlap from boxB's perspective exit now\r\n if (separationB.separation > 0) {\r\n return [];\r\n }\r\n\r\n // Separations are both negative, we want to pick the least negative (minimal movement)\r\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\r\n\r\n // The incident side is the most opposite from the axes of collision on the other collider\r\n const other = separation.collider === polyA ? polyB : polyA;\r\n const incident = other.findSide(separation.axis.negate()) as LineSegment;\r\n\r\n // Clip incident side by the perpendicular lines at each end of the reference side\r\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\r\n const reference = separation.side;\r\n const refDir = reference.dir().normalize();\r\n\r\n // Find our contact points by clipping the incident by the collision side\r\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\r\n let clipLeft: LineSegment | null = null;\r\n if (clipRight) {\r\n clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\r\n }\r\n\r\n // If there is no left there is no collision\r\n if (clipLeft) {\r\n // We only want clip points below the reference edge, discard the others\r\n const points = clipLeft.getPoints().filter((p) => {\r\n return reference.below(p);\r\n });\r\n\r\n let normal = separation.axis;\r\n let tangent = normal.perpendicular();\r\n // Point Contact A -> B\r\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\r\n normal = normal.negate();\r\n tangent = normal.perpendicular();\r\n }\r\n // Points are clipped from incident which is the other collider\r\n // Store those as locals\r\n let localPoints: Vector[] = [];\r\n if (separation.collider === polyA) {\r\n const xf = polyB.owner?.get(TransformComponent) ?? new TransformComponent();\r\n localPoints = points.map((p) => xf.applyInverse(p));\r\n } else {\r\n const xf = polyA.owner?.get(TransformComponent) ?? new TransformComponent();\r\n localPoints = points.map((p) => xf.applyInverse(p));\r\n }\r\n return [new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)];\r\n }\r\n return [];\r\n },\r\n\r\n FindContactSeparation(contact: CollisionContact, localPoint: Vector) {\r\n const shapeA = contact.colliderA;\r\n const txA = contact.colliderA.owner?.get(TransformComponent) ?? new TransformComponent();\r\n const shapeB = contact.colliderB;\r\n const txB = contact.colliderB.owner?.get(TransformComponent) ?? new TransformComponent();\r\n\r\n // both are circles\r\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\r\n const combinedRadius = shapeA.radius + shapeB.radius;\r\n const distance = txA.pos.distance(txB.pos);\r\n const separation = combinedRadius - distance;\r\n return -separation;\r\n }\r\n\r\n // both are polygons\r\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\r\n if (contact.info.localSide) {\r\n let side: LineSegment;\r\n let worldPoint: Vector;\r\n if (contact.info.collider === shapeA) {\r\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\r\n worldPoint = txB.apply(localPoint);\r\n } else {\r\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\r\n worldPoint = txA.apply(localPoint);\r\n }\r\n\r\n return side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // polygon v circle\r\n if (\r\n (shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider) ||\r\n (shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider)\r\n ) {\r\n const worldPoint = txA.apply(localPoint);\r\n if (contact.info.side) {\r\n return contact.info.side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // polygon v edge\r\n if (\r\n (shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider) ||\r\n (shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider)\r\n ) {\r\n let worldPoint: Vector;\r\n if (contact.info.collider === shapeA) {\r\n worldPoint = txB.apply(localPoint);\r\n } else {\r\n worldPoint = txA.apply(localPoint);\r\n }\r\n if (contact.info.side) {\r\n return contact.info.side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // circle v edge\r\n if (\r\n (shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider) ||\r\n (shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider)\r\n ) {\r\n // Local point is always on the edge which is always shapeB\r\n const worldPoint = txB.apply(localPoint);\r\n\r\n let circlePoint: Vector;\r\n if (shapeA instanceof CircleCollider) {\r\n circlePoint = shapeA.getFurthestPoint(contact.normal);\r\n }\r\n\r\n const dist = worldPoint.distance(circlePoint);\r\n\r\n if (contact.info.side) {\r\n return dist > 0 ? -dist : 0;\r\n }\r\n }\r\n\r\n return 0;\r\n }\r\n};\r\n","import { BoundingBox } from '../BoundingBox';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { PolygonCollider } from './PolygonCollider';\r\n\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Color } from '../../Color';\r\nimport { Collider } from './Collider';\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { BodyComponent } from '../Index';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\n\r\nexport interface EdgeColliderOptions {\r\n /**\r\n * The beginning of the edge defined in local coordinates to the collider\r\n */\r\n begin: Vector;\r\n /**\r\n * The ending of the edge defined in local coordinates to the collider\r\n */\r\n end: Vector;\r\n /**\r\n * Optionally specify an offset\r\n */\r\n offset?: Vector;\r\n}\r\n\r\n/**\r\n * Edge is a single line collider to create collisions with a single line.\r\n */\r\nexport class EdgeCollider extends Collider {\r\n offset: Vector;\r\n begin: Vector;\r\n end: Vector;\r\n\r\n private _transform: Transform;\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n constructor(options: EdgeColliderOptions) {\r\n super();\r\n this.begin = options.begin || Vector.Zero;\r\n this.end = options.end || Vector.Zero;\r\n this.offset = options.offset ?? Vector.Zero;\r\n }\r\n\r\n /**\r\n * Returns a clone of this Edge, not associated with any collider\r\n */\r\n public clone(): EdgeCollider {\r\n return new EdgeCollider({\r\n begin: this.begin.clone(),\r\n end: this.end.clone()\r\n });\r\n }\r\n\r\n public get worldPos(): Vector {\r\n const tx = this._transform;\r\n return tx?.globalPos.add(this.offset) ?? this.offset;\r\n }\r\n\r\n /**\r\n * Get the center of the collision area in world coordinates\r\n */\r\n public get center(): Vector {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const pos = begin.average(end);\r\n return pos;\r\n }\r\n\r\n private _getTransformedBegin(): Vector {\r\n return this._globalMatrix.multiply(this.begin);\r\n }\r\n\r\n private _getTransformedEnd(): Vector {\r\n return this._globalMatrix.multiply(this.end);\r\n }\r\n\r\n /**\r\n * Returns the slope of the line in the form of a vector\r\n */\r\n public getSlope(): Vector {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const distance = begin.distance(end);\r\n return end.sub(begin).scale(1 / distance);\r\n }\r\n\r\n /**\r\n * Returns the length of the line segment in pixels\r\n */\r\n public getLength(): number {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const distance = begin.distance(end);\r\n return distance;\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collision area\r\n */\r\n public contains(): boolean {\r\n return false;\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity): RayCastHit | null {\r\n const numerator = this._getTransformedBegin().sub(ray.pos);\r\n\r\n // Test is line and ray are parallel and non intersecting\r\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) {\r\n return null;\r\n }\r\n\r\n // Lines are parallel\r\n const divisor = ray.dir.cross(this.getSlope());\r\n if (divisor === 0) {\r\n return null;\r\n }\r\n\r\n const t = numerator.cross(this.getSlope()) / divisor;\r\n\r\n if (t >= 0 && t <= max) {\r\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\r\n if (u >= 0 && u <= 1) {\r\n return {\r\n distance: t,\r\n normal: this.asLine().normal(),\r\n collider: this,\r\n body: this.owner?.get(BodyComponent),\r\n point: ray.getPoint(t)\r\n } satisfies RayCastHit;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns the closes line between this and another collider, from this -> collider\r\n * @param shape\r\n */\r\n public getClosestLineBetween(shape: Collider): LineSegment {\r\n if (shape instanceof CircleCollider) {\r\n return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\r\n } else if (shape instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\r\n } else if (shape instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public collide(shape: Collider): CollisionContact[] {\r\n if (shape instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCircleEdge(shape, this);\r\n } else if (shape instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollidePolygonEdge(shape, this);\r\n } else if (shape instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollideEdgeEdge();\r\n } else {\r\n throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n const transformedBegin = this._getTransformedBegin();\r\n const transformedEnd = this._getTransformedEnd();\r\n if (direction.dot(transformedBegin) > 0) {\r\n return transformedBegin;\r\n } else {\r\n return transformedEnd;\r\n }\r\n }\r\n\r\n private _boundsFromBeginEnd(begin: Vector, end: Vector, padding = 10) {\r\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\r\n // this causes problems for the collision system so we give them some padding\r\n return new BoundingBox(\r\n Math.min(begin.x, end.x) - padding,\r\n Math.min(begin.y, end.y) - padding,\r\n Math.max(begin.x, end.x) + padding,\r\n Math.max(begin.y, end.y) + padding\r\n );\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the edge collider in world space\r\n */\r\n public get bounds(): BoundingBox {\r\n const transformedBegin = this._getTransformedBegin();\r\n const transformedEnd = this._getTransformedEnd();\r\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the edge collider in local space\r\n */\r\n public get localBounds(): BoundingBox {\r\n return this._boundsFromBeginEnd(this.begin, this.end);\r\n }\r\n\r\n /**\r\n * Returns this edge represented as a line in world coordinates\r\n */\r\n public asLine(): LineSegment {\r\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\r\n }\r\n\r\n /**\r\n * Return this edge as a line in local line coordinates (relative to the position)\r\n */\r\n public asLocalLine(): LineSegment {\r\n return new LineSegment(this.begin, this.end);\r\n }\r\n\r\n /**\r\n * Get the axis associated with the edge\r\n */\r\n public get axes(): Vector[] {\r\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\r\n const edgeNormal = e.normal();\r\n\r\n const axes = [];\r\n axes.push(edgeNormal);\r\n axes.push(edgeNormal.negate());\r\n axes.push(edgeNormal.normal());\r\n axes.push(edgeNormal.normal().negate());\r\n return axes;\r\n }\r\n\r\n /**\r\n * Get the moment of inertia for an edge\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n const length = this.end.sub(this.begin).distance() / 2;\r\n return mass * length * length;\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public update(transform: Transform): void {\r\n this._transform = transform;\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Project the edge along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const scalars = [];\r\n\r\n const points = [this._getTransformedBegin(), this._getTransformedEnd()];\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n scalars.push(points[i].dot(axis));\r\n }\r\n\r\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color) {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n ex.drawLine(begin, end, color, 2);\r\n ex.drawCircle(begin, 2, color);\r\n ex.drawCircle(end, 2, color);\r\n }\r\n\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext, LineGraphicsOptions, PointGraphicsOptions } from './Context/ExcaliburGraphicsContext';\r\nimport { Color } from '../Color';\r\nimport { Ray } from '../Math/ray';\r\nimport { BoundingBox } from '../excalibur';\r\n\r\nexport class Debug {\r\n static _drawCalls: ((ctx: ExcaliburGraphicsContext) => void)[] = [];\r\n static _ctx: ExcaliburGraphicsContext;\r\n static z: number = Infinity;\r\n static registerGraphicsContext(ctx: ExcaliburGraphicsContext) {\r\n Debug._ctx = ctx;\r\n }\r\n static draw(debugDrawCall: (ctx: ExcaliburGraphicsContext) => void) {\r\n this._drawCalls.push(debugDrawCall);\r\n }\r\n\r\n static drawPoint(point: Vector, options?: PointGraphicsOptions) {\r\n Debug.draw(ctx => {\r\n ctx.debug.drawPoint(point, options);\r\n });\r\n }\r\n\r\n static drawLine(start: Vector, end: Vector, options?: LineGraphicsOptions) {\r\n Debug.draw(ctx => {\r\n ctx.debug.drawLine(start, end, options);\r\n });\r\n }\r\n\r\n static drawLines(points: Vector[], options?: LineGraphicsOptions) {\r\n if (points.length > 1) {\r\n Debug.draw(ctx => {\r\n for (let i = 0; i < points.length - 1; i++) {\r\n ctx.debug.drawLine(points[i], points[i + 1], options);\r\n }\r\n });\r\n }\r\n }\r\n\r\n static drawText(text: string, pos: Vector) {\r\n Debug.draw(ctx => {\r\n ctx.debug.drawText(text, pos);\r\n });\r\n }\r\n\r\n static drawPolygon(points: Vector[], options?: { color?: Color }) {\r\n if (points.length > 1) {\r\n Debug.draw(ctx => {\r\n const firstPoint = points[0];\r\n const polygon = [...points, firstPoint];\r\n for (let i = 0; i < polygon.length - 1; i++) {\r\n ctx.debug.drawLine(polygon[i], polygon[i + 1], options);\r\n }\r\n });\r\n }\r\n }\r\n\r\n static drawCircle(center: Vector, radius: number, options?: {\r\n color?: Color,\r\n strokeColor?: Color,\r\n width?: number\r\n }) {\r\n const { color, strokeColor, width} = {\r\n color: Color.Black,\r\n strokeColor: undefined,\r\n width: undefined,\r\n ...options\r\n };\r\n Debug.draw(ctx => {\r\n ctx.drawCircle(center, radius, color, strokeColor, width);\r\n });\r\n }\r\n\r\n static drawBounds(boundingBox: BoundingBox, options?: { color?: Color }): void {\r\n Debug.draw(ctx => {\r\n ctx.debug.drawRect(boundingBox.left, boundingBox.top, boundingBox.width, boundingBox.height, options);\r\n });\r\n }\r\n\r\n static drawRay(ray: Ray, options?: { distance?: number, color?: Color }) {\r\n const { distance, color } = {\r\n color: Color.Blue,\r\n distance: 10,\r\n ...options\r\n };\r\n Debug.draw((ctx) => {\r\n const start = ray.pos;\r\n const end = ray.pos.add(ray.dir.scale(distance));\r\n\r\n ctx.debug.drawLine(start, end, { color });\r\n });\r\n }\r\n\r\n static flush(ctx: ExcaliburGraphicsContext) {\r\n ctx.save();\r\n ctx.z = Debug.z;\r\n for (const drawCall of Debug._drawCalls) {\r\n drawCall(ctx);\r\n }\r\n ctx.restore();\r\n Debug.clear();\r\n }\r\n\r\n static clear() {\r\n Debug._drawCalls.length = 0;\r\n }\r\n}","import { Color } from '../../Color';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Ray } from '../../Math/ray';\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { Collider } from './Collider';\r\nimport { BodyComponent, Debug, ExcaliburGraphicsContext, Logger } from '../..';\r\nimport { CompositeCollider } from './CompositeCollider';\r\nimport { Shape } from './Shape';\r\nimport { Transform } from '../../Math/transform';\r\nimport { RayCastHit } from '../Detection/RayCastHit';\r\n\r\nexport interface PolygonColliderOptions {\r\n /**\r\n * Pixel offset relative to a collider's body transform position.\r\n */\r\n offset?: Vector;\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n */\r\n points: Vector[];\r\n\r\n /**\r\n * Suppresses convexity warning\r\n */\r\n suppressConvexWarning?: boolean;\r\n}\r\n\r\n/**\r\n * Polygon collider for detecting collisions\r\n */\r\nexport class PolygonCollider extends Collider {\r\n private _logger = Logger.getInstance();\r\n /**\r\n * Pixel offset relative to a collider's body transform position.\r\n */\r\n public offset: Vector;\r\n\r\n public flagDirty() {\r\n this._localBoundsDirty = true;\r\n this._localSidesDirty = true;\r\n this._transformedPointsDirty = true;\r\n this._sidesDirty = true;\r\n }\r\n\r\n private _points: Vector[];\r\n\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */\r\n public set points(points: Vector[]) {\r\n this._points = points;\r\n this.flagDirty();\r\n }\r\n\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */\r\n public get points(): Vector[] {\r\n return this._points;\r\n }\r\n\r\n private _transform: Transform;\r\n\r\n private _transformedPoints: Vector[] = [];\r\n private _sides: LineSegment[] = [];\r\n private _localSides: LineSegment[] = [];\r\n\r\n constructor(options: PolygonColliderOptions) {\r\n super();\r\n this.offset = options.offset ?? Vector.Zero;\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n this.points = options.points ?? [];\r\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\r\n if (!counterClockwise) {\r\n this.points.reverse();\r\n }\r\n\r\n if (!this.isConvex()) {\r\n if (!options.suppressConvexWarning) {\r\n this._logger.warn(\r\n 'Excalibur only supports convex polygon colliders and will not behave properly.' +\r\n 'Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles');\r\n }\r\n }\r\n\r\n // calculate initial transformation\r\n this._calculateTransformation();\r\n }\r\n\r\n private _isCounterClockwiseWinding(points: Vector[]): boolean {\r\n // https://stackoverflow.com/a/1165943\r\n let sum = 0;\r\n for (let i = 0; i < points.length; i++) {\r\n sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\r\n }\r\n return sum < 0;\r\n }\r\n\r\n /**\r\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\r\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\r\n */\r\n public isConvex(): boolean {\r\n // From SO: https://stackoverflow.com/a/45372025\r\n if (this.points.length < 3) {\r\n return false;\r\n }\r\n let oldPoint = this.points[this.points.length - 2];\r\n let newPoint = this.points[this.points.length - 1];\r\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\r\n let oldDirection = 0;\r\n let orientation = 0;\r\n let angleSum = 0;\r\n for (const [i, point] of this.points.entries()) {\r\n oldPoint = newPoint;\r\n oldDirection = direction;\r\n newPoint = point;\r\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\r\n if (oldPoint.equals(newPoint)) {\r\n return false; // repeat point\r\n }\r\n let angle = direction - oldDirection;\r\n if (angle <= -Math.PI) {\r\n angle += Math.PI * 2;\r\n } else if (angle > Math.PI) {\r\n angle -= Math.PI * 2;\r\n }\r\n if (i === 0) {\r\n if (angle === 0.0) {\r\n return false;\r\n }\r\n orientation = angle > 0 ? 1 : -1;\r\n } else {\r\n if (orientation * angle <= 0) {\r\n return false;\r\n }\r\n }\r\n angleSum += angle;\r\n }\r\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\r\n }\r\n\r\n /**\r\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\r\n */\r\n public tessellate(): CompositeCollider {\r\n const polygons: Vector[][] = [];\r\n for (let i = 1; i < this.points.length - 2; i++) {\r\n polygons.push([this.points[0], this.points[i + 1], this.points[i + 2]]);\r\n }\r\n polygons.push([this.points[0], this.points[1], this.points[2]]);\r\n\r\n return new CompositeCollider(polygons.map(points => Shape.Polygon(points)));\r\n }\r\n\r\n /**\r\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\r\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\r\n */\r\n public triangulate(): CompositeCollider {\r\n // https://www.youtube.com/watch?v=hTJFcHutls8\r\n if (this.points.length < 3) {\r\n throw Error('Invalid polygon');\r\n }\r\n\r\n const triangles: [Vector, Vector, Vector][] = [];\r\n // algorithm likes clockwise\r\n const vertices = [...this.points].reverse();\r\n let vertexCount = vertices.length;\r\n\r\n /**\r\n * Returns the previous index based on the current vertex\r\n */\r\n function getPrevIndex(index: number) {\r\n return index === 0 ? vertexCount - 1 : index - 1;\r\n }\r\n\r\n /**\r\n * Retrieves the next index based on the current vertex\r\n */\r\n function getNextIndex(index: number) {\r\n return index === vertexCount - 1 ? 0 : index + 1;\r\n }\r\n\r\n /**\r\n * Whether or not the angle at this vertex index is convex\r\n */\r\n function isConvex(index: number) {\r\n const prev = getPrevIndex(index);\r\n const next = getNextIndex(index);\r\n\r\n const va = vertices[prev];\r\n const vb = vertices[index];\r\n const vc = vertices[next];\r\n\r\n // Check convexity\r\n const leftArm = va.sub(vb);\r\n const rightArm = vc.sub(vb);\r\n // Positive cross product is convex\r\n if (leftArm.cross(rightArm) < 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n const convexVertices = vertices.map((_,i) => isConvex(i));\r\n\r\n /**\r\n * Quick test for point in triangle\r\n */\r\n function isPointInTriangle(point: Vector, a: Vector, b: Vector, c: Vector) {\r\n const ab = b.sub(a);\r\n const bc = c.sub(b);\r\n const ca = a.sub(c);\r\n\r\n const ap = point.sub(a);\r\n const bp = point.sub(b);\r\n const cp = point.sub(c);\r\n\r\n const cross1 = ab.cross(ap);\r\n const cross2 = bc.cross(bp);\r\n const cross3 = ca.cross(cp);\r\n\r\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Calculate the area of the triangle\r\n */\r\n // function triangleArea(a: Vector, b: Vector, c: Vector) {\r\n // return Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - c.y))/2;\r\n // }\r\n\r\n /**\r\n * Find the next suitable ear tip\r\n */\r\n function findEarTip() {\r\n for (let i = 0; i < vertexCount; i++) {\r\n if (convexVertices[i]) {\r\n\r\n const prev = getPrevIndex(i);\r\n const next = getNextIndex(i);\r\n\r\n const va = vertices[prev];\r\n const vb = vertices[i];\r\n const vc = vertices[next];\r\n\r\n let isEar = true;\r\n // Check that if any vertices are in the triangle a, b, c\r\n for (let j = 0; j < vertexCount; j++) {\r\n // We can skip these verts because they are the triangle we are testing\r\n if (j === i || j === prev || j === next) {\r\n continue;\r\n }\r\n const point = vertices[j];\r\n if (isPointInTriangle(point, va, vb, vc)) {\r\n isEar = false;\r\n break;\r\n }\r\n }\r\n\r\n // Add ear to polygon list and remove from list\r\n if (isEar) {\r\n return i;\r\n }\r\n }\r\n }\r\n\r\n // Fall back to any convex vertex\r\n for (let i = 0; i < vertexCount; i++) {\r\n if (convexVertices[i]) {\r\n return i;\r\n }\r\n }\r\n\r\n // bail and return the first one?\r\n return 0;\r\n }\r\n\r\n /**\r\n * Cut the ear and produce a triangle, update internal state\r\n */\r\n function cutEarTip(index: number) {\r\n const prev = getPrevIndex(index);\r\n const next = getNextIndex(index);\r\n\r\n const va = vertices[prev];\r\n const vb = vertices[index];\r\n const vc = vertices[next];\r\n\r\n // Clockwise winding\r\n // if (triangleArea(va, vb, vc) > 0) {\r\n triangles.push([va, vb, vc]);\r\n // }\r\n vertices.splice(index, 1);\r\n convexVertices.splice(index, 1);\r\n vertexCount--;\r\n }\r\n\r\n // Loop over all the vertices finding ears\r\n while (vertexCount > 3) {\r\n const earIndex = findEarTip();\r\n cutEarTip(earIndex);\r\n\r\n // reclassify vertices\r\n for (let i = 0; i < vertexCount; i++) {\r\n convexVertices[i] = isConvex(i);\r\n }\r\n }\r\n\r\n // Last triangle after the loop\r\n triangles.push([vertices[0], vertices[1], vertices[2]]);\r\n\r\n // FIXME: there is a colinear triangle that sneaks in here sometimes\r\n return new CompositeCollider(\r\n triangles.map(points => Shape.Polygon(points, Vector.Zero, true)));\r\n }\r\n\r\n /**\r\n * Returns a clone of this ConvexPolygon, not associated with any collider\r\n */\r\n public clone(): PolygonCollider {\r\n return new PolygonCollider({\r\n offset: this.offset.clone(),\r\n points: this.points.map((p) => p.clone())\r\n });\r\n }\r\n\r\n /**\r\n * Returns the world position of the collider, which is the current body transform plus any defined offset\r\n */\r\n public get worldPos(): Vector {\r\n if (this._transform) {\r\n return this._transform.pos.add(this.offset);\r\n }\r\n return this.offset;\r\n }\r\n\r\n /**\r\n * Get the center of the collider in world coordinates\r\n */\r\n public get center(): Vector {\r\n return this.bounds.center;\r\n }\r\n\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n private _transformedPointsDirty = true;\r\n /**\r\n * Calculates the underlying transformation from the body relative space to world space\r\n */\r\n private _calculateTransformation() {\r\n const points = this.points;\r\n const len = points.length;\r\n this._transformedPoints.length = 0; // clear out old transform\r\n for (let i = 0; i < len; i++) {\r\n this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\r\n }\r\n }\r\n\r\n /**\r\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\r\n */\r\n public getTransformedPoints(): Vector[] {\r\n if (this._transformedPointsDirty) {\r\n this._calculateTransformation();\r\n this._transformedPointsDirty = false;\r\n }\r\n return this._transformedPoints;\r\n }\r\n\r\n private _sidesDirty = true;\r\n /**\r\n * Gets the sides of the polygon in world space\r\n */\r\n public getSides(): LineSegment[] {\r\n if (this._sidesDirty) {\r\n const lines = [];\r\n const points = this.getTransformedPoints();\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n // This winding is important\r\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\r\n }\r\n this._sides = lines;\r\n this._sidesDirty = false;\r\n }\r\n return this._sides;\r\n }\r\n\r\n private _localSidesDirty = true;\r\n /**\r\n * Returns the local coordinate space sides\r\n */\r\n public getLocalSides(): LineSegment[] {\r\n if (this._localSidesDirty) {\r\n const lines = [];\r\n const points = this.points;\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n // This winding is important\r\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\r\n }\r\n this._localSides = lines;\r\n this._localSidesDirty = false;\r\n }\r\n\r\n return this._localSides;\r\n }\r\n\r\n /**\r\n * Given a direction vector find the world space side that is most in that direction\r\n * @param direction\r\n */\r\n public findSide(direction: Vector): LineSegment {\r\n const sides = this.getSides();\r\n let bestSide = sides[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let side = 0; side < sides.length; side++) {\r\n const currentSide = sides[side];\r\n const sideNormal = currentSide.normal();\r\n const mostDirection = sideNormal.dot(direction);\r\n if (mostDirection > maxDistance) {\r\n bestSide = currentSide;\r\n maxDistance = mostDirection;\r\n }\r\n }\r\n return bestSide;\r\n }\r\n\r\n /**\r\n * Given a direction vector find the local space side that is most in that direction\r\n * @param direction\r\n */\r\n public findLocalSide(direction: Vector): LineSegment {\r\n const sides = this.getLocalSides();\r\n let bestSide = sides[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let side = 0; side < sides.length; side++) {\r\n const currentSide = sides[side];\r\n const sideNormal = currentSide.normal();\r\n const mostDirection = sideNormal.dot(direction);\r\n if (mostDirection > maxDistance) {\r\n bestSide = currentSide;\r\n maxDistance = mostDirection;\r\n }\r\n }\r\n return bestSide;\r\n }\r\n\r\n /**\r\n * Get the axis associated with the convex polygon\r\n */\r\n public get axes(): Vector[] {\r\n const axes: Vector[] = [];\r\n const sides = this.getSides();\r\n for (let i = 0; i < sides.length; i++) {\r\n axes.push(sides[i].normal());\r\n }\r\n return axes;\r\n }\r\n\r\n /**\r\n * Updates the transform for the collision geometry\r\n *\r\n * Collision geometry (points/bounds) will not change until this is called.\r\n * @param transform\r\n */\r\n public update(transform: Transform): void {\r\n if (transform) {\r\n this._transform = transform;\r\n this._transformedPointsDirty = true;\r\n this._sidesDirty = true;\r\n // This change means an update must be performed in order for geometry to update\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collider in world space\r\n */\r\n public contains(point: Vector): boolean {\r\n // Always cast to the right, as long as we cast in a consistent fixed direction we\r\n // will be fine\r\n const testRay = new Ray(point, new Vector(1, 0));\r\n const intersectCount = this.getSides().reduce(function (accum, side) {\r\n if (testRay.intersect(side) >= 0) {\r\n return accum + 1;\r\n }\r\n return accum;\r\n }, 0);\r\n\r\n if (intersectCount % 2 === 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public getClosestLineBetween(collider: Collider): LineSegment {\r\n if (collider instanceof CircleCollider) {\r\n return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\r\n } else if (collider instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\r\n * return null.\r\n * @param collider\r\n */\r\n public collide(collider: Collider): CollisionContact[] {\r\n if (collider instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCirclePolygon(collider, this);\r\n } else if (collider instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollidePolygonPolygon(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollidePolygonEdge(this, collider);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n const pts = this.getTransformedPoints();\r\n let furthestPoint = null;\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let i = 0; i < pts.length; i++) {\r\n const distance = direction.dot(pts[i]);\r\n if (distance > maxDistance) {\r\n maxDistance = distance;\r\n furthestPoint = pts[i];\r\n }\r\n }\r\n return furthestPoint;\r\n }\r\n\r\n /**\r\n * Find the local point on the collider furthest in the direction specified\r\n * @param direction\r\n */\r\n public getFurthestLocalPoint(direction: Vector): Vector {\r\n const pts = this.points;\r\n let furthestPoint = pts[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let i = 0; i < pts.length; i++) {\r\n const distance = direction.dot(pts[i]);\r\n if (distance > maxDistance) {\r\n maxDistance = distance;\r\n furthestPoint = pts[i];\r\n }\r\n }\r\n return furthestPoint;\r\n }\r\n\r\n /**\r\n * Finds the closes face to the point using perpendicular distance\r\n * @param point point to test against polygon\r\n */\r\n public getClosestFace(point: Vector): { distance: Vector; face: LineSegment } {\r\n const sides = this.getSides();\r\n let min = Number.POSITIVE_INFINITY;\r\n let faceIndex = -1;\r\n let distance = -1;\r\n for (let i = 0; i < sides.length; i++) {\r\n const dist = sides[i].distanceToPoint(point);\r\n if (dist < min) {\r\n min = dist;\r\n faceIndex = i;\r\n distance = dist;\r\n }\r\n }\r\n\r\n if (faceIndex !== -1) {\r\n return {\r\n distance: sides[faceIndex].normal().scale(distance),\r\n face: sides[faceIndex]\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the polygon collider in world coordinates\r\n */\r\n public get bounds(): BoundingBox {\r\n return this.localBounds.transform(this._globalMatrix);\r\n }\r\n\r\n private _localBoundsDirty = true;\r\n private _localBounds: BoundingBox;\r\n /**\r\n * Get the axis aligned bounding box for the polygon collider in local coordinates\r\n */\r\n public get localBounds(): BoundingBox {\r\n if (this._localBoundsDirty) {\r\n this._localBounds = BoundingBox.fromPoints(this.points);\r\n this._localBoundsDirty = false;\r\n }\r\n\r\n return this._localBounds;\r\n }\r\n\r\n private _cachedMass: number;\r\n private _cachedInertia: number;\r\n /**\r\n * Get the moment of inertia for an arbitrary polygon\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n if (this._cachedMass === mass && this._cachedInertia) {\r\n return this._cachedInertia;\r\n }\r\n let numerator = 0;\r\n let denominator = 0;\r\n const points = this.points;\r\n for (let i = 0; i < points.length; i++) {\r\n const iplusone = (i + 1) % points.length;\r\n const crossTerm = points[iplusone].cross(points[i]);\r\n numerator +=\r\n crossTerm *\r\n (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\r\n denominator += crossTerm;\r\n }\r\n this._cachedMass = mass;\r\n return this._cachedInertia = (mass / 6) * (numerator / denominator);\r\n }\r\n\r\n /**\r\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity): RayCastHit | null {\r\n // find the minimum contact time greater than 0\r\n // contact times less than 0 are behind the ray and we don't want those\r\n const sides = this.getSides();\r\n const len = sides.length;\r\n let minContactTime = Number.MAX_VALUE;\r\n let contactSide: LineSegment;\r\n let contactIndex = -1;\r\n for (let i = 0; i < len; i++) {\r\n const contactTime = ray.intersect(sides[i]);\r\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\r\n minContactTime = contactTime;\r\n contactSide = sides[i];\r\n contactIndex = i;\r\n }\r\n }\r\n\r\n // contact was found\r\n if (contactIndex >= 0) {\r\n return {\r\n collider: this,\r\n distance: minContactTime,\r\n body: this.owner?.get(BodyComponent),\r\n point: ray.getPoint(minContactTime),\r\n normal: contactSide.normal()\r\n } satisfies RayCastHit;\r\n }\r\n\r\n // no contact found\r\n return null;\r\n }\r\n\r\n /**\r\n * Project the edges of the polygon along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const points = this.getTransformedPoints();\r\n const len = points.length;\r\n let min = Number.MAX_VALUE;\r\n let max = -Number.MAX_VALUE;\r\n for (let i = 0; i < len; i++) {\r\n const scalar = points[i].dot(axis);\r\n min = Math.min(min, scalar);\r\n max = Math.max(max, scalar);\r\n }\r\n\r\n return new Projection(min, max);\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color, options?: { lineWidth: number, pointSize: number }) {\r\n const points = this.getTransformedPoints();\r\n Debug.drawPolygon(points, { color });\r\n }\r\n}\r\n","import { PolygonCollider } from './PolygonCollider';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { CompositeCollider } from './CompositeCollider';\r\nimport { Logger } from '../..';\r\n\r\n/**\r\n * Excalibur helper for defining colliders quickly\r\n */\r\nexport class Shape {\r\n /**\r\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\r\n * @param width Width of the box\r\n * @param height Height of the box\r\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Box(width: number, height: number, anchor: Vector = Vector.Half, offset: Vector = Vector.Zero): PolygonCollider {\r\n return new PolygonCollider({\r\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\r\n offset: offset\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\r\n *\r\n * PolygonColliders are useful for creating convex polygon shapes\r\n * @param points Points specified in counter clockwise\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Polygon(points: Vector[], offset: Vector = Vector.Zero, suppressConvexWarning = false): PolygonCollider {\r\n return new PolygonCollider({\r\n points: points,\r\n offset: offset,\r\n suppressConvexWarning\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[CircleCollider|circle]] collider\r\n *\r\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\r\n * @param radius Radius of the circle collider\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Circle(radius: number, offset: Vector = Vector.Zero): CircleCollider {\r\n return new CircleCollider({\r\n radius: radius,\r\n offset: offset\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[EdgeCollider|edge]] collider\r\n *\r\n * Edge colliders are useful for floors, walls, and other barriers\r\n * @param begin Beginning of the edge in local coordinates to the collider\r\n * @param end Ending of the edge in local coordinates to the collider\r\n */\r\n static Edge(begin: Vector, end: Vector): EdgeCollider {\r\n return new EdgeCollider({\r\n begin: begin,\r\n end: end\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\r\n *\r\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\r\n * player experience.\r\n * @param width\r\n * @param height\r\n * @param offset Optional offset\r\n */\r\n static Capsule(width: number, height: number, offset = Vector.Zero): CompositeCollider {\r\n const logger = Logger.getInstance();\r\n if (width === height) {\r\n logger.warn('A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider');\r\n }\r\n\r\n const vertical = height >= width;\r\n\r\n if (vertical) {\r\n // height > width, if equal maybe use a circle\r\n const capsule = new CompositeCollider([\r\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\r\n Shape.Box(width, height - width, Vector.Half, offset),\r\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\r\n ]);\r\n return capsule;\r\n } else {\r\n // width > height, if equal maybe use a circle\r\n const capsule = new CompositeCollider([\r\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\r\n Shape.Box(width - height, height, Vector.Half, offset),\r\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\r\n ]);\r\n return capsule;\r\n }\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { CollisionEndEvent, CollisionStartEvent, PostCollisionEvent, PreCollisionEvent } from '../Events';\r\nimport { Observable } from '../Util/Observable';\r\nimport { BoundingBox } from './BoundingBox';\r\nimport { CollisionContact } from './Detection/CollisionContact';\r\nimport { CircleCollider } from './Colliders/CircleCollider';\r\nimport { Collider } from './Colliders/Collider';\r\nimport { CompositeCollider } from './Colliders/CompositeCollider';\r\nimport { PolygonCollider } from './Colliders/PolygonCollider';\r\nimport { EdgeCollider } from './Colliders/EdgeCollider';\r\nimport { Shape } from './Colliders/Shape';\r\nimport { EventEmitter } from '../EventEmitter';\r\nimport { Actor } from '../Actor';\r\n\r\nexport class ColliderComponent extends Component {\r\n\r\n public events = new EventEmitter();\r\n /**\r\n * Observable that notifies when a collider is added to the body\r\n */\r\n public $colliderAdded = new Observable();\r\n\r\n /**\r\n * Observable that notifies when a collider is removed from the body\r\n */\r\n public $colliderRemoved = new Observable();\r\n\r\n constructor(collider?: Collider) {\r\n super();\r\n this.set(collider);\r\n }\r\n\r\n private _collider: Collider;\r\n /**\r\n * Get the current collider geometry\r\n */\r\n public get() {\r\n return this._collider;\r\n }\r\n\r\n /**\r\n * Set the collider geometry\r\n * @param collider\r\n * @returns the collider you set\r\n */\r\n public set(collider: T): T {\r\n this.clear();\r\n if (collider) {\r\n this._collider = collider;\r\n this._collider.owner = this.owner;\r\n collider.events.pipe(this.events);\r\n this.$colliderAdded.notifyAll(collider);\r\n this.update();\r\n }\r\n return collider;\r\n }\r\n\r\n private _collidersToRemove: Collider[] = [];\r\n /**\r\n * Remove collider geometry from collider component\r\n */\r\n public clear() {\r\n if (this._collider) {\r\n this._collidersToRemove.push(this._collider);\r\n this._collider = null;\r\n }\r\n }\r\n\r\n public processColliderRemoval() {\r\n for (const collider of this._collidersToRemove) {\r\n collider.events.unpipe(this.events);\r\n this.$colliderRemoved.notifyAll(collider);\r\n collider.owner = null;\r\n }\r\n }\r\n\r\n public clone(): ColliderComponent {\r\n const clone = new ColliderComponent(this._collider.clone());\r\n\r\n return clone;\r\n }\r\n\r\n /**\r\n * Return world space bounds\r\n */\r\n public get bounds() {\r\n return this._collider?.bounds ?? new BoundingBox();\r\n }\r\n\r\n /**\r\n * Return local space bounds\r\n */\r\n public get localBounds() {\r\n return this._collider?.localBounds ?? new BoundingBox();\r\n }\r\n\r\n /**\r\n * Update the collider's transformed geometry\r\n */\r\n public update() {\r\n const tx = this.owner?.get(TransformComponent);\r\n if (this._collider) {\r\n this._collider.owner = this.owner;\r\n if (tx) {\r\n this._collider.update(tx.get());\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Collide component with another\r\n * @param other\r\n */\r\n collide(other: ColliderComponent): CollisionContact[] {\r\n let colliderA = this._collider;\r\n let colliderB = other._collider;\r\n if (!colliderA || !colliderB) {\r\n return [];\r\n }\r\n\r\n // If we have a composite left hand side :(\r\n // Might bite us, but to avoid updating all the handlers make composite always left side\r\n let flipped = false;\r\n if (colliderB instanceof CompositeCollider) {\r\n colliderA = colliderB;\r\n colliderB = this._collider;\r\n flipped = true;\r\n }\r\n\r\n if (this._collider) {\r\n const contacts = colliderA.collide(colliderB);\r\n if (contacts) {\r\n if (flipped) {\r\n contacts.forEach((contact) => {\r\n contact.mtv = contact.mtv.negate();\r\n contact.normal = contact.normal.negate();\r\n contact.tangent = contact.normal.perpendicular();\r\n contact.colliderA = this._collider;\r\n contact.colliderB = other._collider;\r\n });\r\n }\r\n return contacts;\r\n }\r\n return [];\r\n }\r\n return [];\r\n }\r\n\r\n onAdd(entity: Entity) {\r\n if (this._collider) {\r\n this.update();\r\n }\r\n // Wire up the collider events to the owning entity\r\n this.events.on('precollision', (evt: any) => {\r\n const precollision = evt as PreCollisionEvent;\r\n entity.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(\r\n precollision.target.owner,\r\n precollision.other.owner,\r\n precollision.side,\r\n precollision.intersection,\r\n precollision.contact\r\n )\r\n );\r\n if (entity instanceof Actor) {\r\n entity.onPreCollisionResolve(precollision.target, precollision.other, precollision.side, precollision.contact);\r\n }\r\n });\r\n this.events.on('postcollision', (evt: any) => {\r\n const postcollision = evt as PostCollisionEvent;\r\n entity.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(\r\n postcollision.target.owner,\r\n postcollision.other.owner,\r\n postcollision.side,\r\n postcollision.intersection,\r\n postcollision.contact)\r\n );\r\n if (entity instanceof Actor) {\r\n entity.onPostCollisionResolve(postcollision.target, postcollision.other, postcollision.side, postcollision.contact);\r\n }\r\n });\r\n this.events.on('collisionstart', (evt: any) => {\r\n const start = evt as CollisionStartEvent;\r\n entity.events.emit('collisionstart', new CollisionStartEvent(start.target.owner, start.other.owner, start.side, start.contact));\r\n if (entity instanceof Actor) {\r\n entity.onCollisionStart(start.target, start.other, start.side, start.contact);\r\n }\r\n });\r\n this.events.on('collisionend', (evt: any) => {\r\n const end = evt as CollisionEndEvent;\r\n entity.events.emit('collisionend', new CollisionEndEvent(end.target.owner, end.other.owner, end.side, end.lastContact));\r\n if (entity instanceof Actor) {\r\n entity.onCollisionEnd(end.target, end.other, end.side, end.lastContact);\r\n }\r\n });\r\n }\r\n\r\n onRemove() {\r\n this.events.clear();\r\n this.$colliderRemoved.notifyAll(this._collider);\r\n }\r\n\r\n /**\r\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\r\n *\r\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useBoxCollider(width: number, height: number, anchor: Vector = Vector.Half, center: Vector = Vector.Zero): PolygonCollider {\r\n const collider = Shape.Box(width, height, anchor, center);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\r\n * to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n usePolygonCollider(points: Vector[], center: Vector = Vector.Zero): PolygonCollider {\r\n const poly = Shape.Polygon(points, center);\r\n return (this.set(poly));\r\n }\r\n\r\n /**\r\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useCircleCollider(radius: number, center: Vector = Vector.Zero): CircleCollider {\r\n const collider = Shape.Circle(radius, center);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useEdgeCollider(begin: Vector, end: Vector): EdgeCollider {\r\n const collider = Shape.Edge(begin, end);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\r\n * @param colliders\r\n */\r\n useCompositeCollider(colliders: Collider[]): CompositeCollider {\r\n return (this.set(new CompositeCollider(colliders)));\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { CollisionType } from './CollisionType';\r\nimport { Clonable } from '../Interfaces/Clonable';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { CollisionGroup } from './Group/CollisionGroup';\r\nimport { createId, Id } from '../Id';\r\nimport { clamp } from '../Math/util';\r\nimport { ColliderComponent } from './ColliderComponent';\r\nimport { Transform } from '../Math/transform';\r\nimport { EventEmitter } from '../EventEmitter';\r\nimport { DefaultPhysicsConfig, PhysicsConfig } from './PhysicsConfig';\r\nimport { DeepRequired } from '../Util/Required';\r\n\r\nexport interface BodyComponentOptions {\r\n type?: CollisionType;\r\n group?: CollisionGroup;\r\n useGravity?: boolean;\r\n config?: Pick['bodies']\r\n}\r\n\r\nexport enum DegreeOfFreedom {\r\n Rotation = 'rotation',\r\n X = 'x',\r\n Y = 'y'\r\n}\r\n\r\n/**\r\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\r\n * of physics simulation.\r\n */\r\nexport class BodyComponent extends Component implements Clonable {\r\n public dependencies = [TransformComponent, MotionComponent];\r\n public static _ID = 0;\r\n public readonly id: Id<'body'> = createId('body', BodyComponent._ID++);\r\n public events = new EventEmitter();\r\n\r\n public oldTransform = new Transform();\r\n\r\n /**\r\n * Indicates whether the old transform has been captured at least once for interpolation\r\n * @internal\r\n */\r\n public __oldTransformCaptured: boolean = false;\r\n\r\n /**\r\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\r\n */\r\n public enableFixedUpdateInterpolate = true;\r\n\r\n private _bodyConfig: DeepRequired['bodies']>;\r\n private static _DEFAULT_CONFIG: DeepRequired['bodies']> = {\r\n ...DefaultPhysicsConfig.bodies\r\n };\r\n public wakeThreshold: number;\r\n\r\n constructor(options?: BodyComponentOptions) {\r\n super();\r\n if (options) {\r\n this.collisionType = options.type ?? this.collisionType;\r\n this.group = options.group ?? this.group;\r\n this.useGravity = options.useGravity ?? this.useGravity;\r\n this._bodyConfig = {\r\n ...DefaultPhysicsConfig.bodies,\r\n ...options.config\r\n };\r\n } else {\r\n this._bodyConfig = {\r\n ...DefaultPhysicsConfig.bodies\r\n };\r\n }\r\n this.updatePhysicsConfig(this._bodyConfig);\r\n this._mass = BodyComponent._DEFAULT_CONFIG.defaultMass;\r\n }\r\n\r\n public get matrix() {\r\n return this.transform.get().matrix;\r\n }\r\n\r\n /**\r\n * Called by excalibur to update physics config defaults if they change\r\n * @param config\r\n */\r\n public updatePhysicsConfig(config: DeepRequired['bodies']>) {\r\n this._bodyConfig = {\r\n ...DefaultPhysicsConfig.bodies,\r\n ...config\r\n };\r\n this.canSleep = this._bodyConfig.canSleepByDefault;\r\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\r\n this.wakeThreshold = this._bodyConfig.wakeThreshold;\r\n }\r\n /**\r\n * Called by excalibur to update defaults\r\n * @param config\r\n */\r\n public static updateDefaultPhysicsConfig(config: DeepRequired['bodies']>) {\r\n BodyComponent._DEFAULT_CONFIG = config;\r\n }\r\n\r\n /**\r\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\r\n */\r\n public collisionType: CollisionType = CollisionType.PreventCollision;\r\n\r\n /**\r\n * The collision group for the body's colliders, by default body colliders collide with everything\r\n */\r\n public group: CollisionGroup = CollisionGroup.All;\r\n\r\n /**\r\n * The amount of mass the body has\r\n */\r\n private _mass: number;\r\n public get mass(): number {\r\n return this._mass;\r\n }\r\n\r\n public set mass(newMass: number) {\r\n this._mass = newMass;\r\n this._cachedInertia = undefined;\r\n this._cachedInverseInertia = undefined;\r\n }\r\n\r\n /**\r\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */\r\n public get inverseMass(): number {\r\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\r\n }\r\n\r\n /**\r\n * Amount of \"motion\" the body has before sleeping. If below [[Physics.sleepEpsilon]] it goes to \"sleep\"\r\n */\r\n public sleepMotion: number;\r\n\r\n /**\r\n * Can this body sleep, by default bodies do not sleep\r\n */\r\n public canSleep: boolean;;\r\n\r\n private _sleeping = false;\r\n /**\r\n * Whether this body is sleeping or not\r\n */\r\n public get sleeping(): boolean {\r\n return this._sleeping;\r\n }\r\n\r\n /**\r\n * Set the sleep state of the body\r\n * @param sleeping\r\n */\r\n public setSleeping(sleeping: boolean) {\r\n this._sleeping = sleeping;\r\n if (!sleeping) {\r\n // Give it a kick to keep it from falling asleep immediately\r\n this.sleepMotion = this._bodyConfig.sleepEpsilon * 5;\r\n } else {\r\n this.vel = Vector.Zero;\r\n this.acc = Vector.Zero;\r\n this.angularVelocity = 0;\r\n this.sleepMotion = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\r\n */\r\n public updateMotion() {\r\n if (this._sleeping) {\r\n this.setSleeping(true);\r\n }\r\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\r\n const bias = this._bodyConfig.sleepBias;\r\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\r\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * this._bodyConfig.sleepEpsilon);\r\n if (this.canSleep && this.sleepMotion < this._bodyConfig.sleepEpsilon) {\r\n this.setSleeping(true);\r\n }\r\n }\r\n\r\n private _cachedInertia: number;\r\n /**\r\n * Get the moment of inertia from the [[ColliderComponent]]\r\n */\r\n public get inertia() {\r\n if (this._cachedInertia) {\r\n return this._cachedInertia;\r\n }\r\n\r\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\r\n const collider = this.owner.get(ColliderComponent);\r\n if (collider) {\r\n collider.$colliderAdded.subscribe(() => {\r\n this._cachedInertia = null;\r\n });\r\n collider.$colliderRemoved.subscribe(() => {\r\n this._cachedInertia = null;\r\n });\r\n const maybeCollider = collider.get();\r\n if (maybeCollider) {\r\n return this._cachedInertia = maybeCollider.getInertia(this.mass);\r\n }\r\n }\r\n return 0;\r\n }\r\n\r\n private _cachedInverseInertia: number;\r\n /**\r\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */\r\n public get inverseInertia() {\r\n if (this._cachedInverseInertia) {\r\n return this._cachedInverseInertia;\r\n }\r\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\r\n }\r\n\r\n /**\r\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\r\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\r\n */\r\n public bounciness: number = 0.2;\r\n\r\n /**\r\n * The coefficient of friction on this actor\r\n */\r\n public friction: number = 0.99;\r\n\r\n /**\r\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\r\n */\r\n public useGravity: boolean = true;\r\n\r\n /**\r\n * Degrees of freedom to limit\r\n *\r\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\r\n */\r\n public limitDegreeOfFreedom: DegreeOfFreedom[] = [];\r\n\r\n /**\r\n * Returns if the owner is active\r\n */\r\n public get active() {\r\n return !!this.owner?.active;\r\n }\r\n\r\n /**\r\n * @deprecated Use globalP0s\r\n */\r\n public get center() {\r\n return this.globalPos;\r\n }\r\n\r\n public get transform(): TransformComponent {\r\n return this.owner?.get(TransformComponent);\r\n }\r\n\r\n public get motion(): MotionComponent {\r\n return this.owner?.get(MotionComponent);\r\n }\r\n\r\n public get pos(): Vector {\r\n return this.transform.pos;\r\n }\r\n\r\n public set pos(val: Vector) {\r\n this.transform.pos = val;\r\n }\r\n\r\n /**\r\n * The (x, y) position of the actor this will be in the middle of the actor if the\r\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\r\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\r\n */\r\n public get globalPos(): Vector {\r\n return this.transform.globalPos;\r\n }\r\n\r\n public set globalPos(val: Vector) {\r\n this.transform.globalPos = val;\r\n }\r\n\r\n /**\r\n * The position of the actor last frame (x, y) in pixels\r\n */\r\n public get oldPos(): Vector {\r\n return this.oldTransform.pos;\r\n }\r\n\r\n /**\r\n * The current velocity vector (vx, vy) of the actor in pixels/second\r\n */\r\n public get vel(): Vector {\r\n return this.motion.vel;\r\n }\r\n\r\n public set vel(val: Vector) {\r\n this.motion.vel = val;\r\n }\r\n\r\n /**\r\n * The velocity of the actor last frame (vx, vy) in pixels/second\r\n */\r\n public oldVel: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\r\n * be useful to simulate a gravitational effect.\r\n */\r\n public get acc(): Vector {\r\n return this.motion.acc;\r\n }\r\n\r\n public set acc(val: Vector) {\r\n this.motion.acc = val;\r\n }\r\n\r\n /**\r\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public oldAcc: Vector = Vector.Zero;\r\n\r\n /**\r\n * The current torque applied to the actor\r\n */\r\n public get torque(): number {\r\n return this.motion.torque;\r\n }\r\n\r\n public set torque(val: number) {\r\n this.motion.torque = val;\r\n }\r\n\r\n /**\r\n * Gets/sets the rotation of the body from the last frame.\r\n */\r\n public get oldRotation(): number {\r\n return this.oldTransform.rotation;\r\n }\r\n\r\n /**\r\n * The rotation of the body in radians\r\n */\r\n public get rotation() {\r\n return this.transform.globalRotation;\r\n }\r\n\r\n public set rotation(val: number) {\r\n this.transform.globalRotation = val;\r\n }\r\n\r\n /**\r\n * The scale vector of the actor\r\n */\r\n public get scale(): Vector {\r\n return this.transform.globalScale;\r\n }\r\n\r\n public set scale(val: Vector) {\r\n this.transform.globalScale = val;\r\n }\r\n\r\n /**\r\n * The scale of the actor last frame\r\n */\r\n public get oldScale(): Vector {\r\n return this.oldTransform.scale;\r\n }\r\n\r\n /**\r\n * The scale rate of change of the actor in scale/second\r\n */\r\n public get scaleFactor(): Vector {\r\n return this.motion.scaleFactor;\r\n }\r\n\r\n public set scaleFactor(scaleFactor: Vector) {\r\n this.motion.scaleFactor = scaleFactor;\r\n }\r\n\r\n /**\r\n * Get the angular velocity in radians/second\r\n */\r\n public get angularVelocity(): number {\r\n return this.motion.angularVelocity;\r\n }\r\n\r\n /**\r\n * Set the angular velocity in radians/second\r\n */\r\n public set angularVelocity(value: number) {\r\n this.motion.angularVelocity = value;\r\n }\r\n\r\n /**\r\n * Apply a specific impulse to the body\r\n * @param point\r\n * @param impulse\r\n */\r\n public applyImpulse(point: Vector, impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n const finalImpulse = impulse.scale(this.inverseMass);\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n finalImpulse.x = 0;\r\n }\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n finalImpulse.y = 0;\r\n }\r\n\r\n this.vel.addEqual(finalImpulse);\r\n\r\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n const distanceFromCenter = point.sub(this.globalPos);\r\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\r\n }\r\n }\r\n\r\n /**\r\n * Apply only linear impulse to the body\r\n * @param impulse\r\n */\r\n public applyLinearImpulse(impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n const finalImpulse = impulse.scale(this.inverseMass);\r\n\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n finalImpulse.x = 0;\r\n }\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n finalImpulse.y = 0;\r\n }\r\n\r\n this.vel = this.vel.add(finalImpulse);\r\n }\r\n\r\n /**\r\n * Apply only angular impulse to the body\r\n * @param point\r\n * @param impulse\r\n */\r\n public applyAngularImpulse(point: Vector, impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n const distanceFromCenter = point.sub(this.globalPos);\r\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\r\n }\r\n }\r\n\r\n /**\r\n * Sets the old versions of pos, vel, acc, and scale.\r\n */\r\n public captureOldTransform() {\r\n // Capture old values before integration step updates them\r\n this.__oldTransformCaptured = true;\r\n const tx = this.transform.get();\r\n tx.clone(this.oldTransform);\r\n this.oldTransform.parent = tx.parent; // also grab parent\r\n this.oldVel.setTo(this.vel.x, this.vel.y);\r\n this.oldAcc.setTo(this.acc.x, this.acc.y);\r\n }\r\n\r\n public clone(): BodyComponent {\r\n const component = super.clone() as BodyComponent;\r\n return component;\r\n }\r\n}\r\n","import { Component, ComponentCtor, isComponentCtor } from './Component';\r\n\r\nimport { Observable, Message } from '../Util/Observable';\r\nimport { OnInitialize, OnPreUpdate, OnPostUpdate } from '../Interfaces/LifecycleEvents';\r\nimport { Engine } from '../Engine';\r\nimport { InitializeEvent, PreUpdateEvent, PostUpdateEvent } from '../Events';\r\nimport { KillEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { Scene } from '../Scene';\r\nimport { removeItemFromArray } from '../Util/Util';\r\nimport { MaybeKnownComponent } from './Types';\r\n\r\n/**\r\n * Interface holding an entity component pair\r\n */\r\nexport interface EntityComponent {\r\n component: Component;\r\n entity: Entity;\r\n}\r\n\r\n/**\r\n * AddedComponent message\r\n */\r\nexport class AddedComponent implements Message {\r\n readonly type: 'Component Added' = 'Component Added';\r\n constructor(public data: EntityComponent) { }\r\n}\r\n\r\n/**\r\n * Type guard to know if message is f an Added Component\r\n */\r\nexport function isAddedComponent(x: Message): x is AddedComponent {\r\n return !!x && x.type === 'Component Added';\r\n}\r\n\r\n/**\r\n * RemovedComponent message\r\n */\r\nexport class RemovedComponent implements Message {\r\n readonly type: 'Component Removed' = 'Component Removed';\r\n constructor(public data: EntityComponent) { }\r\n}\r\n\r\n/**\r\n * Type guard to know if message is for a Removed Component\r\n */\r\nexport function isRemovedComponent(x: Message): x is RemovedComponent {\r\n return !!x && x.type === 'Component Removed';\r\n}\r\n\r\n/**\r\n * Built in events supported by all entities\r\n */\r\nexport type EntityEvents = {\r\n 'initialize': InitializeEvent;\r\n 'preupdate': PreUpdateEvent;\r\n 'postupdate': PostUpdateEvent;\r\n 'kill': KillEvent\r\n};\r\n\r\nexport const EntityEvents = {\r\n Initialize: 'initialize',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n Kill: 'kill'\r\n} as const;\r\n\r\nexport interface EntityOptions {\r\n name?: string;\r\n components: TComponents[];\r\n}\r\n\r\n/**\r\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\r\n *\r\n * Entities can be strongly typed with the components they contain\r\n *\r\n * ```typescript\r\n * const entity = new Entity();\r\n * entity.components.a; // Type ComponentA\r\n * entity.components.b; // Type ComponentB\r\n * ```\r\n */\r\nexport class Entity implements OnInitialize, OnPreUpdate, OnPostUpdate {\r\n private static _ID = 0;\r\n /**\r\n * The unique identifier for the entity\r\n */\r\n public id: number = Entity._ID++;\r\n\r\n public name = `Entity#${this.id}`;\r\n\r\n /**\r\n * Listen to or emit events for an entity\r\n */\r\n public events = new EventEmitter();\r\n private _tags = new Set();\r\n public componentAdded$ = new Observable;\r\n public componentRemoved$ = new Observable;\r\n public tagAdded$ = new Observable;\r\n public tagRemoved$ = new Observable;\r\n /**\r\n * Current components on the entity\r\n *\r\n * **Do not modify**\r\n *\r\n * Use addComponent/removeComponent otherwise the ECS will not be notified of changes.\r\n */\r\n public readonly components = new Map();\r\n private _componentsToRemove: ComponentCtor[] = [];\r\n\r\n private _instanceOfComponentCacheDirty = true;\r\n private _instanceOfComponentCache = new Map();\r\n\r\n constructor(options: EntityOptions);\r\n constructor(components?: TKnownComponents[], name?: string);\r\n constructor(componentsOrOptions?: TKnownComponents[] | EntityOptions, name?: string) {\r\n let componentsToAdd!: TKnownComponents[];\r\n let nameToAdd: string | undefined;\r\n if (Array.isArray(componentsOrOptions)) {\r\n componentsToAdd = componentsOrOptions;\r\n nameToAdd = name;\r\n } else if (componentsOrOptions && typeof componentsOrOptions === 'object') {\r\n const { components, name } = componentsOrOptions;\r\n componentsToAdd = components;\r\n nameToAdd = name;\r\n }\r\n if (nameToAdd) {\r\n this.name = nameToAdd;\r\n }\r\n if (componentsToAdd) {\r\n for (const component of componentsToAdd) {\r\n this.addComponent(component);\r\n }\r\n }\r\n // this.addComponent(this.tagsComponent);\r\n }\r\n\r\n /**\r\n * The current scene that the entity is in, if any\r\n */\r\n public scene: Scene | null = null;\r\n\r\n /**\r\n * Whether this entity is active, if set to false it will be reclaimed\r\n */\r\n public active: boolean = true;\r\n\r\n /**\r\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\r\n * If parented it will be removed from the parent when killed.\r\n */\r\n public kill() {\r\n if (this.active) {\r\n this.active = false;\r\n this.unparent();\r\n }\r\n this.emit('kill', new KillEvent(this));\r\n }\r\n\r\n public isKilled() {\r\n return !this.active;\r\n }\r\n\r\n /**\r\n * Specifically get the tags on the entity from [[TagsComponent]]\r\n */\r\n public get tags(): Set {\r\n return this._tags;\r\n }\r\n\r\n /**\r\n * Check if a tag exists on the entity\r\n * @param tag name to check for\r\n */\r\n public hasTag(tag: string): boolean {\r\n return this._tags.has(tag);\r\n }\r\n\r\n /**\r\n * Adds a tag to an entity\r\n * @param tag\r\n */\r\n public addTag(tag: string) {\r\n this._tags.add(tag);\r\n this.tagAdded$.notifyAll(tag);\r\n }\r\n\r\n /**\r\n * Removes a tag on the entity\r\n *\r\n * Removals are deferred until the end of update\r\n * @param tag\r\n */\r\n public removeTag(tag: string) {\r\n this._tags.delete(tag);\r\n this.tagRemoved$.notifyAll(tag);\r\n }\r\n\r\n /**\r\n * The types of the components on the Entity\r\n */\r\n public get types(): ComponentCtor[] {\r\n return Array.from(this.components.keys()) as ComponentCtor[];\r\n }\r\n\r\n /**\r\n * Returns all component instances on entity\r\n */\r\n public getComponents(): Component[] {\r\n return Array.from(this.components.values());\r\n }\r\n\r\n /**\r\n * Verifies that an entity has all the required types\r\n * @param requiredTypes\r\n */\r\n hasAll(requiredTypes: ComponentCtor[]): boolean {\r\n for (let i = 0; i < requiredTypes.length; i++) {\r\n if (!this.components.has(requiredTypes[i])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Verifies that an entity has all the required tags\r\n * @param requiredTags\r\n */\r\n hasAllTags(requiredTags: string[]): boolean {\r\n for (let i = 0; i < requiredTags.length; i++) {\r\n if (!this.tags.has(requiredTags[i])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n private _getCachedInstanceOfType(\r\n type: ComponentCtor): MaybeKnownComponent | undefined {\r\n if (this._instanceOfComponentCacheDirty) {\r\n this._instanceOfComponentCacheDirty = false;\r\n this._instanceOfComponentCache.clear();\r\n }\r\n\r\n if (this._instanceOfComponentCache.has(type)) {\r\n return this._instanceOfComponentCache.get(type) as MaybeKnownComponent;\r\n }\r\n\r\n for (const instance of this.components.values()) {\r\n if (instance instanceof type) {\r\n this._instanceOfComponentCache.set(type, instance);\r\n return instance as MaybeKnownComponent;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n get(type: ComponentCtor): MaybeKnownComponent {\r\n const maybeComponent = this._getCachedInstanceOfType(type);\r\n return maybeComponent ?? this.components.get(type) as MaybeKnownComponent;\r\n }\r\n\r\n private _parent: Entity | null = null;\r\n public get parent(): Entity | null {\r\n return this._parent;\r\n }\r\n\r\n public childrenAdded$ = new Observable();\r\n public childrenRemoved$ = new Observable();\r\n\r\n private _children: Entity[] = [];\r\n /**\r\n * Get the direct children of this entity\r\n */\r\n public get children(): readonly Entity[] {\r\n return this._children;\r\n }\r\n\r\n /**\r\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\r\n */\r\n public unparent() {\r\n if (this._parent) {\r\n this._parent.removeChild(this);\r\n this._parent = null;\r\n }\r\n }\r\n\r\n /**\r\n * Adds an entity to be a child of this entity\r\n * @param entity\r\n */\r\n public addChild(entity: Entity): Entity {\r\n if (entity.parent === null) {\r\n if (this.getAncestors().includes(entity)) {\r\n throw new Error('Cycle detected, cannot add entity');\r\n }\r\n this._children.push(entity);\r\n entity._parent = this;\r\n this.childrenAdded$.notifyAll(entity);\r\n } else {\r\n throw new Error('Entity already has a parent, cannot add without unparenting');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove an entity from children if it exists\r\n * @param entity\r\n */\r\n public removeChild(entity: Entity): Entity {\r\n if (entity.parent === this) {\r\n removeItemFromArray(entity, this._children);\r\n entity._parent = null;\r\n this.childrenRemoved$.notifyAll(entity);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes all children from this entity\r\n */\r\n public removeAllChildren(): Entity {\r\n // Avoid modifying the array issue by walking backwards\r\n for (let i = this.children.length - 1; i >= 0; i--) {\r\n this.removeChild(this.children[i]);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\r\n */\r\n public getAncestors(): Entity[] {\r\n const result: Entity[] = [this];\r\n let current = this.parent;\r\n while (current) {\r\n result.push(current);\r\n current = current.parent;\r\n }\r\n return result.reverse();\r\n }\r\n\r\n /**\r\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\r\n */\r\n public getDescendants(): Entity[] {\r\n let result: Entity[] = [this];\r\n let queue: Entity[] = [this];\r\n while (queue.length > 0) {\r\n const curr = queue.pop();\r\n if (curr) {\r\n queue = queue.concat(curr.children);\r\n result = result.concat(curr.children);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a deep copy of the entity and a copy of all its components\r\n */\r\n public clone(): Entity {\r\n const newEntity = new Entity();\r\n for (const c of this.types) {\r\n const componentInstance = this.get(c);\r\n if (componentInstance) {\r\n newEntity.addComponent(componentInstance.clone());\r\n }\r\n }\r\n for (const child of this.children) {\r\n newEntity.addChild(child.clone());\r\n }\r\n return newEntity;\r\n }\r\n\r\n /**\r\n * Adds a copy of all the components from another template entity as a \"prefab\"\r\n * @param templateEntity Entity to use as a template\r\n * @param force Force component replacement if it already exists on the target entity\r\n */\r\n public addTemplate(templateEntity: Entity, force: boolean = false): Entity {\r\n for (const c of templateEntity.getComponents()) {\r\n this.addComponent(c.clone(), force);\r\n }\r\n for (const child of templateEntity.children) {\r\n this.addChild(child.clone().addTemplate(child));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds a component to the entity\r\n * @param component Component or Entity to add copy of components from\r\n * @param force Optionally overwrite any existing components of the same type\r\n */\r\n public addComponent(component: TComponent, force: boolean = false): Entity {\r\n this._instanceOfComponentCacheDirty = true;\r\n // if component already exists, skip if not forced\r\n if (this.has(component.constructor as ComponentCtor)) {\r\n if (force) {\r\n // Remove existing component type if exists when forced\r\n this.removeComponent(component.constructor as ComponentCtor, true);\r\n } else {\r\n // early exit component exits\r\n return this as Entity;\r\n }\r\n }\r\n\r\n // TODO circular dependencies will be a problem\r\n if (component.dependencies && component.dependencies.length) {\r\n for (const ctor of component.dependencies) {\r\n this.addComponent(new ctor());\r\n }\r\n }\r\n\r\n component.owner = this;\r\n this.components.set(component.constructor, component);\r\n if (component.onAdd) {\r\n component.onAdd(this);\r\n }\r\n\r\n this.componentAdded$.notifyAll(component);\r\n return this as Entity;\r\n }\r\n\r\n /**\r\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\r\n *\r\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\r\n * @param typeOrInstance\r\n * @param force\r\n */\r\n public removeComponent(\r\n typeOrInstance: ComponentCtor | TComponent, force = false): Entity> {\r\n\r\n let type: ComponentCtor;\r\n if (isComponentCtor(typeOrInstance)) {\r\n type = typeOrInstance;\r\n } else {\r\n type = typeOrInstance.constructor as ComponentCtor;\r\n }\r\n\r\n if (force) {\r\n const componentToRemove = this.components.get(type);\r\n if (componentToRemove) {\r\n this.componentRemoved$.notifyAll(componentToRemove);\r\n componentToRemove.owner = undefined;\r\n if (componentToRemove.onRemove) {\r\n componentToRemove.onRemove(this);\r\n }\r\n }\r\n this.components.delete(type); // remove after the notify to preserve typing\r\n this._instanceOfComponentCacheDirty = true;\r\n } else {\r\n this._componentsToRemove.push(type);\r\n }\r\n\r\n return this as any;\r\n }\r\n\r\n public clearComponents() {\r\n const components = this.types;\r\n for (const c of components) {\r\n this.removeComponent(c);\r\n }\r\n }\r\n\r\n /**\r\n * @hidden\r\n * @internal\r\n */\r\n public processComponentRemoval() {\r\n for (const type of this._componentsToRemove) {\r\n this.removeComponent(type, true);\r\n }\r\n this._componentsToRemove.length = 0;\r\n }\r\n\r\n /**\r\n * Check if a component type exists\r\n * @param type\r\n */\r\n public has(type: ComponentCtor): boolean {\r\n return this.components.has(type);\r\n }\r\n\r\n private _isInitialized = false;\r\n\r\n /**\r\n * Gets whether the actor is Initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n /**\r\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n * @internal\r\n */\r\n public _initialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * `onInitialize` is called before the first update of the entity. This method is meant to be\r\n * overridden.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */\r\n public onInitialize(engine: Engine): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an entity is updated.\r\n */\r\n public onPreUpdate(engine: Engine, delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an entity is updated.\r\n */\r\n public onPostUpdate(engine: Engine, delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n *\r\n * Entity update lifecycle, called internally\r\n * @internal\r\n * @param engine\r\n * @param delta\r\n */\r\n public update(engine: Engine, delta: number): void {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n for (const child of this.children) {\r\n child.update(engine, delta);\r\n }\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: EntityEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n if (handler) {\r\n this.events.off(eventName, handler);\r\n } else {\r\n this.events.off(eventName);\r\n }\r\n }\r\n}\r\n","import { Vector, vec } from '../Math/vector';\r\nimport { Graphic } from './Graphic';\r\nimport { HasTick } from './Animation';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/Index';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Material } from './Context/material';\r\nimport { Logger } from '../Util/Log';\r\nimport { WatchVector } from '../Math/watch-vector';\r\n\r\n/**\r\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\r\n * @param graphic\r\n */\r\nexport function hasGraphicsTick(graphic: Graphic): graphic is Graphic & HasTick {\r\n return !!(graphic as unknown as HasTick).tick;\r\n}\r\nexport interface GraphicsShowOptions {\r\n offset?: Vector;\r\n anchor?: Vector;\r\n}\r\n\r\nexport interface GraphicsComponentOptions {\r\n onPostDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n onPreDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n onPreTransformDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n onPostTransformDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n\r\n /**\r\n * Name of current graphic to use\r\n */\r\n current?: string;\r\n\r\n /**\r\n * Optionally set a material to use on the graphic\r\n */\r\n material?: Material;\r\n\r\n /**\r\n * Optionally copy instances of graphics by calling .clone(), you may set this to false to avoid sharing graphics when added to the\r\n * component for performance reasons. By default graphics are not copied and are shared when added to the component.\r\n */\r\n copyGraphics?: boolean;\r\n\r\n /**\r\n * Optional visible flag, if the graphics component is not visible it will not be displayed\r\n */\r\n visible?: boolean;\r\n\r\n /**\r\n * Optional opacity\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * List of graphics and optionally the options per graphic\r\n */\r\n graphics?: { [graphicName: string]: Graphic | { graphic: Graphic, options: GraphicsShowOptions } };\r\n\r\n /**\r\n * Optional offset in absolute pixels to shift all graphics in this component from each graphic's anchor (default is top left corner)\r\n */\r\n offset?: Vector;\r\n\r\n /**\r\n * Optional anchor\r\n */\r\n anchor?: Vector;\r\n}\r\n\r\n/**\r\n * Component to manage drawings, using with the position component\r\n */\r\nexport class GraphicsComponent extends Component {\r\n private _logger = Logger.getInstance();\r\n\r\n private _current: string = 'default';\r\n private _graphics: Record = {};\r\n private _options: Record = {};\r\n\r\n public material: Material | null = null;\r\n\r\n /**\r\n * Draws after the entity transform has been applied, but before graphics component graphics have been drawn\r\n */\r\n public onPreDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Draws after the entity transform has been applied, and after graphics component graphics has been drawn\r\n */\r\n public onPostDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Draws before the entity transform has been applied before any any graphics component drawing\r\n */\r\n public onPreTransformDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Draws after the entity transform has been applied, and after all graphics component drawing\r\n */\r\n public onPostTransformDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Sets or gets wether any drawing should be visible in this component\r\n */\r\n public visible: boolean = true;\r\n\r\n /**\r\n * Sets or gets wither all drawings should have an opacity applied\r\n */\r\n public opacity: number = 1;\r\n\r\n\r\n private _offset: Vector = Vector.Zero;\r\n\r\n /**\r\n * Offset to apply to graphics by default\r\n */\r\n public get offset(): Vector {\r\n return new WatchVector(this._offset, () => {\r\n this.recalculateBounds();\r\n });\r\n }\r\n public set offset(value: Vector) {\r\n this._offset = value;\r\n this.recalculateBounds();\r\n }\r\n\r\n private _anchor: Vector = Vector.Half;\r\n\r\n /**\r\n * Anchor to apply to graphics by default\r\n */\r\n public get anchor(): Vector {\r\n return new WatchVector(this._anchor, () => {\r\n this.recalculateBounds();\r\n });\r\n }\r\n public set anchor(value: Vector) {\r\n this._anchor = value;\r\n this.recalculateBounds();\r\n }\r\n\r\n /**\r\n * Flip all graphics horizontally along the y-axis\r\n */\r\n public flipHorizontal: boolean = false;\r\n\r\n /**\r\n * Flip all graphics vertically along the x-axis\r\n */\r\n public flipVertical: boolean = false;\r\n\r\n /**\r\n * If set to true graphics added to the component will be copied. This can effect performance, but is useful if you don't want\r\n * changes to a graphic to effect all the places it is used.\r\n */\r\n public copyGraphics: boolean = false;\r\n\r\n constructor(options?: GraphicsComponentOptions) {\r\n super();\r\n // Defaults\r\n options = {\r\n visible: this.visible,\r\n graphics: {},\r\n ...options\r\n };\r\n\r\n const {\r\n current,\r\n anchor,\r\n opacity,\r\n visible,\r\n graphics,\r\n offset,\r\n copyGraphics,\r\n onPreDraw,\r\n onPostDraw,\r\n onPreTransformDraw,\r\n onPostTransformDraw\r\n } = options;\r\n\r\n for (const [key, graphicOrOptions] of Object.entries(graphics)) {\r\n if (graphicOrOptions instanceof Graphic) {\r\n this._graphics[key] = graphicOrOptions;\r\n } else {\r\n this._graphics[key] = graphicOrOptions.graphic;\r\n this._options[key] = graphicOrOptions.options;\r\n }\r\n }\r\n\r\n this.offset = offset ?? this.offset;\r\n this.opacity = opacity ?? this.opacity;\r\n this.anchor = anchor ?? this.anchor;\r\n this.copyGraphics = copyGraphics ?? this.copyGraphics;\r\n this.onPreDraw = onPreDraw ?? this.onPreDraw;\r\n this.onPostDraw = onPostDraw ?? this.onPostDraw;\r\n this.onPreDraw = onPreTransformDraw ?? this.onPreTransformDraw;\r\n this.onPostTransformDraw = onPostTransformDraw ?? this.onPostTransformDraw;\r\n this.visible = !!visible;\r\n this._current = current ?? this._current;\r\n if (current && this._graphics[current]) {\r\n this.use(current);\r\n }\r\n }\r\n\r\n public getGraphic(name: string): Graphic | undefined {\r\n return this._graphics[name];\r\n }\r\n public getOptions(name: string): GraphicsShowOptions | undefined {\r\n return this._options[name];\r\n }\r\n\r\n /**\r\n * Get registered graphics names\r\n */\r\n public getNames(): string[] {\r\n return Object.keys(this._graphics);\r\n }\r\n\r\n /**\r\n * Returns the currently displayed graphic\r\n */\r\n public get current(): Graphic | undefined {\r\n return this._graphics[this._current];\r\n }\r\n\r\n /**\r\n * Returns the currently displayed graphic offsets\r\n */\r\n public get currentOptions(): GraphicsShowOptions | undefined {\r\n return this._options[this._current];\r\n }\r\n\r\n /**\r\n * Returns all graphics associated with this component\r\n */\r\n public get graphics(): { [graphicName: string]: Graphic } {\r\n return this._graphics;\r\n }\r\n\r\n /**\r\n * Returns all graphics options associated with this component\r\n */\r\n public get options(): { [graphicName: string]: GraphicsShowOptions } {\r\n return this._options;\r\n }\r\n\r\n /**\r\n * Adds a named graphic to this component, if the name is \"default\" or not specified, it will be shown by default without needing to call\r\n * @param graphic\r\n */\r\n public add(graphic: Graphic, options?: GraphicsShowOptions): Graphic;\r\n public add(name: string, graphic: Graphic, options?: GraphicsShowOptions): Graphic;\r\n public add(nameOrGraphic: string | Graphic, graphicOrOptions?: Graphic | GraphicsShowOptions, options?: GraphicsShowOptions): Graphic {\r\n let name = 'default';\r\n let graphicToSet: Graphic = null;\r\n let optionsToSet: GraphicsShowOptions | undefined = undefined;\r\n if (typeof nameOrGraphic === 'string' && graphicOrOptions instanceof Graphic) {\r\n name = nameOrGraphic;\r\n graphicToSet = graphicOrOptions;\r\n optionsToSet = options;\r\n }\r\n if (nameOrGraphic instanceof Graphic && !(graphicOrOptions instanceof Graphic)) {\r\n graphicToSet = nameOrGraphic;\r\n optionsToSet = graphicOrOptions;\r\n }\r\n\r\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\r\n this._options[name] = this.copyGraphics ? {...optionsToSet} : optionsToSet;\r\n if (name === 'default') {\r\n this.use('default');\r\n }\r\n return graphicToSet;\r\n }\r\n\r\n /**\r\n * Removes a registered graphic, if the removed graphic is the current it will switch to the default\r\n * @param name\r\n */\r\n public remove(name: string) {\r\n delete this._graphics[name];\r\n delete this._options[name];\r\n if (this._current === name) {\r\n this._current = 'default';\r\n this.recalculateBounds();\r\n }\r\n }\r\n\r\n /**\r\n * Shows a graphic, will be removed\r\n * @param nameOrGraphic\r\n * @param options\r\n * @deprecated will be removed in v0.30.0, use `graphics.use(...)`\r\n */\r\n public show(nameOrGraphic: string | T, options?: GraphicsShowOptions): T {\r\n return this.use(nameOrGraphic, options);\r\n }\r\n\r\n /**\r\n * Use a graphic only, will set the default graphic. Returns the new [[Graphic]]\r\n *\r\n * Optionally override the stored options\r\n * @param nameOrGraphic\r\n * @param options\r\n */\r\n public use(nameOrGraphic: string | T, options?: GraphicsShowOptions): T {\r\n if (nameOrGraphic instanceof Graphic) {\r\n let graphic = nameOrGraphic as Graphic;\r\n if (this.copyGraphics) {\r\n graphic = nameOrGraphic.clone();\r\n }\r\n this._current = 'default';\r\n this._graphics[this._current] = graphic;\r\n this._options[this._current] = options;\r\n } else {\r\n this._current = nameOrGraphic;\r\n this._options[this._current] = options;\r\n if (!(this._current in this._graphics)) {\r\n this._logger.warn(\r\n `Graphic ${this._current} is not registered with the graphics component owned by ${this.owner?.name}. Nothing will be drawn.`);\r\n }\r\n }\r\n this.recalculateBounds();\r\n return this.current as T;\r\n }\r\n\r\n /**\r\n * Hide currently shown graphic\r\n */\r\n public hide(): void {\r\n this._current = 'ex.none';\r\n }\r\n\r\n private _localBounds: BoundingBox = null;\r\n public set localBounds(bounds: BoundingBox) {\r\n this._localBounds = bounds;\r\n }\r\n\r\n public recalculateBounds() {\r\n let bb = new BoundingBox();\r\n const graphic = this._graphics[this._current];\r\n const options = this._options[this._current];\r\n\r\n if (!graphic) {\r\n this._localBounds = bb;\r\n return;\r\n }\r\n\r\n let anchor = this.anchor;\r\n let offset = this.offset;\r\n if (options?.anchor) {\r\n anchor = options.anchor;\r\n }\r\n if (options?.offset) {\r\n offset = options.offset;\r\n }\r\n const bounds = graphic.localBounds;\r\n const offsetX = -bounds.width * anchor.x + offset.x;\r\n const offsetY = -bounds.height * anchor.y + offset.y;\r\n bb = graphic?.localBounds.translate(vec(offsetX, offsetY)).combine(bb);\r\n this._localBounds = bb;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) {\r\n this.recalculateBounds();\r\n }\r\n return this._localBounds;\r\n }\r\n\r\n /**\r\n * Update underlying graphics if necessary, called internally\r\n * @param elapsed\r\n * @internal\r\n */\r\n public update(elapsed: number, idempotencyToken: number = 0) {\r\n const graphic = this.current;\r\n if (graphic && hasGraphicsTick(graphic)) {\r\n graphic.tick(elapsed, idempotencyToken);\r\n }\r\n }\r\n\r\n\r\n public clone(): GraphicsComponent {\r\n const graphics = new GraphicsComponent();\r\n graphics._graphics = { ...this._graphics };\r\n graphics._options = {... this._options};\r\n graphics.offset = this.offset.clone();\r\n graphics.opacity = this.opacity;\r\n graphics.anchor = this.anchor.clone();\r\n graphics.copyGraphics = this.copyGraphics;\r\n graphics.onPreDraw = this.onPreDraw;\r\n graphics.onPostDraw = this.onPostDraw;\r\n graphics.visible = this.visible;\r\n\r\n return graphics;\r\n }\r\n}\r\n","import { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface RectangleOptions {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/**\r\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\r\n */\r\nexport class Rectangle extends Raster {\r\n constructor(options: RasterOptions & RectangleOptions) {\r\n super(options);\r\n this.width = options.width;\r\n this.height = options.height;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Rectangle {\r\n return new Rectangle({\r\n width: this.width,\r\n height: this.height,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.color) {\r\n ctx.fillRect(0, 0, this.width, this.height);\r\n }\r\n if (this.strokeColor) {\r\n ctx.strokeRect(0, 0, this.width, this.height);\r\n }\r\n }\r\n}\r\n","import { ImageFiltering } from './Filtering';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface CircleOptions {\r\n radius: number;\r\n}\r\n\r\n/**\r\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Circles default to [[ImageFiltering.Blended]]\r\n */\r\nexport class Circle extends Raster {\r\n private _radius: number = 0;\r\n public get radius() {\r\n return this._radius;\r\n }\r\n public set radius(value: number) {\r\n this._radius = value;\r\n this.width = this._radius * 2;\r\n this.height = this._radius * 2;\r\n this.flagDirty();\r\n }\r\n constructor(options: RasterOptions & CircleOptions) {\r\n super(options);\r\n const lineWidth = options.lineWidth ?? (options.strokeColor ? 1 : 0); // default lineWidth in canvas is 1px\r\n this.padding = options.padding ?? 2 + (lineWidth / 2); // default 2 padding for circles looks nice\r\n this.radius = options.radius;\r\n this.filtering = options.filtering ?? ImageFiltering.Blended;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Circle {\r\n return new Circle({\r\n radius: this.radius,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.radius > 0) {\r\n ctx.beginPath();\r\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\r\n\r\n if (this.color) {\r\n ctx.fill();\r\n }\r\n\r\n if (this.strokeColor) {\r\n ctx.stroke();\r\n }\r\n }\r\n }\r\n}\r\n","import { Component } from '../EntityComponentSystem/Component';\r\n\r\n/**\r\n * Add this component to optionally configure how the pointer\r\n * system detects pointer events.\r\n *\r\n * By default the collider shape is used and graphics bounds is not.\r\n *\r\n * If both collider shape and graphics bounds are enabled it will fire events if either or\r\n * are intersecting the pointer.\r\n */\r\nexport class PointerComponent extends Component {\r\n /**\r\n * Use any existing Collider component geometry for pointer events. This is useful if you want\r\n * user pointer events only to trigger on the same collision geometry used in the collider component\r\n * for collision resolution. Default is `true`.\r\n */\r\n public useColliderShape = true;\r\n /**\r\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\r\n * bounds around the graphic to trigger pointer events. Default is `true`.\r\n */\r\n public useGraphicsBounds = true;\r\n}","import { Vector } from '../Math/vector';\r\n\r\n/**\r\n * A definition of an EasingFunction. See [[EasingFunctions]].\r\n */\r\n// tslint:disable-next-line\r\nexport interface EasingFunction {\r\n (currentTime: number, startValue: number, endValue: number, duration: number): number;\r\n}\r\n\r\n/**\r\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\r\n * Given a time, the function will return a value from positive startValue to positive endValue.\r\n *\r\n * ```js\r\n * function Linear (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInQuad (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutQuad (t) {\r\n * return t * (2 - t);\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutQuad (t) {\r\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInCubic (t) {\r\n * return t * t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutCubic (t) {\r\n * return (--t) * t * t + 1;\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutCubic (t) {\r\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\r\n * }\r\n * ```\r\n */\r\nexport class EasingFunctions {\r\n public static CreateReversibleEasingFunction(easing: EasingFunction) {\r\n return (time: number, start: number, end: number, duration: number) => {\r\n if (end < start) {\r\n return start - (easing(time, end, start, duration) - end);\r\n } else {\r\n return easing(time, start, end, duration);\r\n }\r\n };\r\n }\r\n\r\n public static CreateVectorEasingFunction(easing: EasingFunction) {\r\n return (time: number, start: Vector, end: Vector, duration: number) => {\r\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\r\n };\r\n }\r\n\r\n public static Linear: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n return (endValue * currentTime) / duration + startValue;\r\n }\r\n );\r\n\r\n public static EaseInQuad = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n\r\n return endValue * currentTime * currentTime + startValue;\r\n }\r\n );\r\n\r\n public static EaseOutQuad: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return -endValue * currentTime * (currentTime - 2) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInOutQuad: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration / 2;\r\n\r\n if (currentTime < 1) {\r\n return (endValue / 2) * currentTime * currentTime + startValue;\r\n }\r\n currentTime--;\r\n\r\n return (-endValue / 2) * (currentTime * (currentTime - 2) - 1) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return endValue * currentTime * currentTime * currentTime + startValue;\r\n }\r\n );\r\n\r\n public static EaseOutCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n currentTime--;\r\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInOutCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration / 2;\r\n if (currentTime < 1) {\r\n return (endValue / 2) * currentTime * currentTime * currentTime + startValue;\r\n }\r\n currentTime -= 2;\r\n return (endValue / 2) * (currentTime * currentTime * currentTime + 2) + startValue;\r\n }\r\n );\r\n}\r\n","import { ActionCompleteEvent, ActionStartEvent } from '../Events';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Action } from './Action';\r\n\r\n/**\r\n * Action Queues represent an ordered sequence of actions\r\n *\r\n * Action queues are part of the [[ActionContext|Action API]] and\r\n * store the list of actions to be executed for an [[Actor]].\r\n *\r\n * Actors implement [[Actor.actions]] which can be manipulated by\r\n * advanced users to adjust the actions currently being executed in the\r\n * queue.\r\n */\r\nexport class ActionQueue {\r\n private _entity: Entity;\r\n private _actions: Action[] = [];\r\n private _currentAction: Action | null = null;\r\n private _completedActions: Action[] = [];\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n }\r\n\r\n /**\r\n * Add an action to the sequence\r\n * @param action\r\n */\r\n public add(action: Action) {\r\n this._actions.push(action);\r\n }\r\n\r\n /**\r\n * Remove an action by reference from the sequence\r\n * @param action\r\n */\r\n public remove(action: Action) {\r\n const index = this._actions.indexOf(action);\r\n this._actions.splice(index, 1);\r\n }\r\n\r\n /**\r\n * Removes all actions from this sequence\r\n */\r\n public clearActions(): void {\r\n this._actions.length = 0;\r\n this._completedActions.length = 0;\r\n if (this._currentAction) {\r\n this._currentAction.stop();\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @returns The total list of actions in this sequence complete or not\r\n */\r\n public getActions(): Action[] {\r\n return this._actions.concat(this._completedActions);\r\n }\r\n\r\n /**\r\n *\r\n * @returns `true` if there are more actions to process in the sequence\r\n */\r\n public hasNext(): boolean {\r\n return this._actions.length > 0;\r\n }\r\n\r\n /**\r\n * @returns `true` if the current sequence of actions is done\r\n */\r\n public isComplete(): boolean {\r\n return this._actions.length === 0;\r\n }\r\n\r\n /**\r\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\r\n */\r\n public reset(): void {\r\n this._actions = this.getActions();\r\n\r\n const len = this._actions.length;\r\n for (let i = 0; i < len; i++) {\r\n this._actions[i].reset();\r\n }\r\n this._completedActions = [];\r\n }\r\n\r\n /**\r\n * Update the queue which updates actions and handles completing actions\r\n * @param elapsedMs\r\n */\r\n public update(elapsedMs: number) {\r\n if (this._actions.length > 0) {\r\n if (this._currentAction !== this._actions[0]) {\r\n this._currentAction = this._actions[0];\r\n this._entity.emit('actionstart', new ActionStartEvent(this._currentAction, this._entity));\r\n }\r\n\r\n this._currentAction.update(elapsedMs);\r\n\r\n if (this._currentAction.isComplete(this._entity)) {\r\n this._entity.emit('actioncomplete', new ActionCompleteEvent(this._currentAction, this._entity));\r\n const complete = this._actions.shift();\r\n if (complete) {\r\n this._completedActions.push(complete);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\nexport class Repeat implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _repeat: number;\r\n private _originalRepeat: number;\r\n private _stopped: boolean = false;\r\n private _repeatContext: ActionContext;\r\n private _repeatBuilder: (repeatContext: ActionContext) => any;\r\n constructor(entity: Entity, repeatBuilder: (repeatContext: ActionContext) => any, repeat: number) {\r\n this._repeatBuilder = repeatBuilder;\r\n this._repeatContext = new ActionContext(entity);\r\n this._actionQueue = this._repeatContext.getQueue();\r\n\r\n this._repeat = repeat;\r\n this._originalRepeat = repeat;\r\n\r\n this._repeatBuilder(this._repeatContext);\r\n this._repeat--; // current execution is the first repeat\r\n }\r\n\r\n public update(delta: number): void {\r\n if (this._actionQueue.isComplete()) {\r\n this._actionQueue.clearActions();\r\n this._repeatBuilder(this._repeatContext);\r\n this._repeat--;\r\n }\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || (this._repeat <= 0 && this._actionQueue.isComplete());\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._repeat = this._originalRepeat;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\n/**\r\n * RepeatForever Action implementation, it is recommended you use the fluent action\r\n * context API.\r\n *\r\n *\r\n */\r\nexport class RepeatForever implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _stopped: boolean = false;\r\n private _repeatContext: ActionContext;\r\n private _repeatBuilder: (repeatContext: ActionContext) => any;\r\n constructor(entity: Entity, repeatBuilder: (repeatContext: ActionContext) => any) {\r\n this._repeatBuilder = repeatBuilder;\r\n this._repeatContext = new ActionContext(entity);\r\n this._actionQueue = this._repeatContext.getQueue();\r\n\r\n this._repeatBuilder(this._repeatContext);\r\n }\r\n\r\n public update(delta: number): void {\r\n if (this._stopped) {\r\n return;\r\n }\r\n\r\n if (this._actionQueue.isComplete()) {\r\n this._actionQueue.clearActions();\r\n this._repeatBuilder(this._repeatContext);\r\n }\r\n\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n this._actionQueue.clearActions();\r\n }\r\n\r\n public reset(): void {\r\n return;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Action } from '../Action';\r\n\r\nexport class MoveBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _entity: Entity;\r\n public x: number;\r\n public y: number;\r\n private _distance: number;\r\n private _speed: number;\r\n\r\n private _start: Vector;\r\n private _offset: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, offsetX: number, offsetY: number, speed: number) {\r\n this._entity = entity;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._speed = speed;\r\n this._offset = new Vector(offsetX, offsetY);\r\n if (speed <= 0) {\r\n Logger.getInstance().error('Attempted to moveBy with speed less than or equal to zero : ' + speed);\r\n throw new Error('Speed must be greater than 0 pixels per second');\r\n }\r\n }\r\n\r\n public update(_delta: number) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = this._start.add(this._offset);\r\n this._distance = this._offset.size;\r\n this._dir = this._end.sub(this._start).normalize();\r\n }\r\n\r\n if (this.isComplete(this._entity)) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n } else {\r\n this._motion.vel = this._dir.scale(this._speed);\r\n }\r\n }\r\n\r\n public isComplete(entity: Entity): boolean {\r\n const tx = entity.get(TransformComponent);\r\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class MoveTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _distance: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(public entity: Entity, destx: number, desty: number, speed: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._end = new Vector(destx, desty);\r\n this._speed = speed;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._distance = this._start.distance(this._end);\r\n this._dir = this._end.sub(this._start).normalize();\r\n }\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n\r\n if (this.isComplete(this.entity)) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public isComplete(entity: Entity): boolean {\r\n const tx = entity.get(TransformComponent);\r\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","/**\r\n * An enum that describes the strategies that rotation actions can use\r\n */\r\nexport enum RotationType {\r\n /**\r\n * Rotation via `ShortestPath` will use the smallest angle\r\n * between the starting and ending points. This strategy is the default behavior.\r\n */\r\n ShortestPath = 0,\r\n /**\r\n * Rotation via `LongestPath` will use the largest angle\r\n * between the starting and ending points.\r\n */\r\n LongestPath = 1,\r\n /**\r\n * Rotation via `Clockwise` will travel in a clockwise direction,\r\n * regardless of the starting and ending points.\r\n */\r\n Clockwise = 2,\r\n /**\r\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\r\n * regardless of the starting and ending points.\r\n */\r\n CounterClockwise = 3\r\n}\r\n","import { Action } from '../Action';\r\nimport { RotationType } from '../RotationType';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { TwoPI } from '../../Math/util';\r\n\r\nexport class RotateTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: number;\r\n private _end: number;\r\n private _speed: number;\r\n private _rotationType: RotationType;\r\n private _direction: number;\r\n private _distance: number;\r\n private _shortDistance: number;\r\n private _longDistance: number;\r\n private _shortestPathIsPositive: boolean;\r\n private _currentNonCannonAngle: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, angleRadians: number, speed: number, rotationType?: RotationType) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._end = angleRadians;\r\n this._speed = speed;\r\n this._rotationType = rotationType || RotationType.ShortestPath;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = this._tx.rotation;\r\n this._currentNonCannonAngle = this._tx.rotation;\r\n const distance1 = Math.abs(this._end - this._start);\r\n const distance2 = TwoPI - distance1;\r\n if (distance1 > distance2) {\r\n this._shortDistance = distance2;\r\n this._longDistance = distance1;\r\n } else {\r\n this._shortDistance = distance1;\r\n this._longDistance = distance2;\r\n }\r\n\r\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\r\n\r\n switch (this._rotationType) {\r\n case RotationType.ShortestPath:\r\n this._distance = this._shortDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = 1;\r\n } else {\r\n this._direction = -1;\r\n }\r\n break;\r\n case RotationType.LongestPath:\r\n this._distance = this._longDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = -1;\r\n } else {\r\n this._direction = 1;\r\n }\r\n break;\r\n case RotationType.Clockwise:\r\n this._direction = 1;\r\n if (this._shortestPathIsPositive) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n case RotationType.CounterClockwise:\r\n this._direction = -1;\r\n if (!this._shortestPathIsPositive) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n this._motion.angularVelocity = this._direction * this._speed;\r\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\r\n\r\n if (this.isComplete()) {\r\n this._tx.rotation = this._end;\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\r\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\r\n }\r\n\r\n public stop(): void {\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\nimport { RotationType } from '../RotationType';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { TwoPI } from '../../Math/util';\r\n\r\nexport class RotateBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: number;\r\n private _end: number;\r\n private _speed: number;\r\n private _offset: number;\r\n\r\n private _rotationType: RotationType;\r\n private _direction: number;\r\n private _distance: number;\r\n private _shortDistance: number;\r\n private _longDistance: number;\r\n private _shortestPathIsPositive: boolean;\r\n private _currentNonCannonAngle: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, angleRadiansOffset: number, speed: number, rotationType?: RotationType) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._speed = speed;\r\n this._offset = angleRadiansOffset;\r\n this._rotationType = rotationType || RotationType.ShortestPath;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = this._tx.rotation;\r\n this._currentNonCannonAngle = this._tx.rotation;\r\n this._end = this._start + this._offset;\r\n\r\n const distance1 = Math.abs(this._end - this._start);\r\n const distance2 = TwoPI - distance1;\r\n if (distance1 > distance2) {\r\n this._shortDistance = distance2;\r\n this._longDistance = distance1;\r\n } else {\r\n this._shortDistance = distance1;\r\n this._longDistance = distance2;\r\n }\r\n\r\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\r\n\r\n switch (this._rotationType) {\r\n case RotationType.ShortestPath:\r\n this._distance = this._shortDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = 1;\r\n } else {\r\n this._direction = -1;\r\n }\r\n break;\r\n case RotationType.LongestPath:\r\n this._distance = this._longDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = -1;\r\n } else {\r\n this._direction = 1;\r\n }\r\n break;\r\n case RotationType.Clockwise:\r\n this._direction = 1;\r\n if (this._shortDistance >= 0) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n case RotationType.CounterClockwise:\r\n this._direction = -1;\r\n if (this._shortDistance <= 0) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n this._motion.angularVelocity = this._direction * this._speed;\r\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\r\n\r\n if (this.isComplete()) {\r\n this._tx.rotation = this._end;\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\r\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\r\n }\r\n\r\n public stop(): void {\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n this._start = undefined;\r\n this._currentNonCannonAngle = undefined;\r\n this._distance = undefined;\r\n }\r\n}\r\n","import { vec } from '../../Math/vector';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Action } from '../Action';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\n\r\nexport class ScaleTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _startX: number;\r\n private _startY: number;\r\n private _endX: number;\r\n private _endY: number;\r\n private _speedX: number;\r\n private _speedY: number;\r\n private _distanceX: number;\r\n private _distanceY: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, scaleX: number, scaleY: number, speedX: number, speedY: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._endX = scaleX;\r\n this._endY = scaleY;\r\n this._speedX = speedX;\r\n this._speedY = speedY;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._startX = this._tx.scale.x;\r\n this._startY = this._tx.scale.y;\r\n this._distanceX = Math.abs(this._endX - this._startX);\r\n this._distanceY = Math.abs(this._endY - this._startY);\r\n }\r\n\r\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\r\n const directionX = this._endY < this._startY ? -1 : 1;\r\n this._motion.scaleFactor.x = this._speedX * directionX;\r\n } else {\r\n this._motion.scaleFactor.x = 0;\r\n }\r\n\r\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\r\n const directionY = this._endY < this._startY ? -1 : 1;\r\n this._motion.scaleFactor.y = this._speedY * directionY;\r\n } else {\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._tx.scale = vec(this._endX, this._endY);\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return (\r\n this._stopped ||\r\n (Math.abs(this._tx.scale.x - this._startX) >= (this._distanceX - 0.01) &&\r\n Math.abs(this._tx.scale.y - this._startY) >= (this._distanceY - 0.01))\r\n );\r\n }\r\n\r\n public stop(): void {\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Action } from '../Action';\r\n\r\nexport class ScaleBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _startScale: Vector;\r\n private _endScale: Vector;\r\n private _offset: Vector;\r\n private _distanceX: number;\r\n private _distanceY: number;\r\n private _directionX: number;\r\n private _directionY: number;\r\n private _started = false;\r\n private _stopped = false;\r\n private _speedX: number;\r\n private _speedY: number;\r\n constructor(entity: Entity, scaleOffsetX: number, scaleOffsetY: number, speed: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\r\n this._speedX = this._speedY = speed;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._startScale = this._tx.scale.clone();\r\n this._endScale = this._startScale.add(this._offset);\r\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\r\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\r\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\r\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\r\n }\r\n\r\n this._motion.scaleFactor.x = this._speedX * this._directionX;\r\n this._motion.scaleFactor.y = this._speedY * this._directionY;\r\n\r\n if (this.isComplete()) {\r\n this._tx.scale = this._endScale;\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return (\r\n this._stopped ||\r\n (Math.abs(this._tx.scale.x - this._startScale.x) >= (this._distanceX - 0.01) &&\r\n Math.abs(this._tx.scale.y - this._startScale.y) >= (this._distanceY - 0.01))\r\n );\r\n }\r\n\r\n public stop(): void {\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\n\r\nexport class CallMethod implements Action {\r\n private _method: () => any = null;\r\n private _hasBeenCalled: boolean = false;\r\n constructor(method: () => any) {\r\n this._method = method;\r\n }\r\n\r\n public update(_delta: number) {\r\n this._method();\r\n this._hasBeenCalled = true;\r\n }\r\n public isComplete() {\r\n return this._hasBeenCalled;\r\n }\r\n public reset() {\r\n this._hasBeenCalled = false;\r\n }\r\n public stop() {\r\n this._hasBeenCalled = true;\r\n }\r\n}\r\n","import { Entity} from '../../EntityComponentSystem/Entity';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class EaseTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1 * 1000; // 1 second\r\n private _lerpStart: Vector = new Vector(0, 0);\r\n private _lerpEnd: Vector = new Vector(0, 0);\r\n private _initialized: boolean = false;\r\n private _stopped: boolean = false;\r\n constructor(\r\n entity: Entity,\r\n x: number,\r\n y: number,\r\n duration: number,\r\n public easingFcn: (currentTime: number, startValue: number, endValue: number, duration: number) => number\r\n ) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._lerpDuration = duration;\r\n this._lerpEnd = new Vector(x, y);\r\n }\r\n private _initialize() {\r\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._currentLerpTime = 0;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._initialized) {\r\n this._initialize();\r\n this._initialized = true;\r\n }\r\n\r\n // Need to update lerp time first, otherwise the first update will always be zero\r\n this._currentLerpTime += delta;\r\n let newX = this._tx.pos.x;\r\n let newY = this._tx.pos.y;\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n if (this._lerpEnd.x < this._lerpStart.x) {\r\n newX =\r\n this._lerpStart.x -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\r\n } else {\r\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\r\n }\r\n\r\n if (this._lerpEnd.y < this._lerpStart.y) {\r\n newY =\r\n this._lerpStart.y -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\r\n } else {\r\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\r\n }\r\n // Given the lerp position figure out the velocity in pixels per second\r\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\r\n } else {\r\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\r\n this._motion.vel = Vector.Zero;\r\n }\r\n }\r\n public isComplete(): boolean {\r\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\r\n }\r\n\r\n public reset(): void {\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._currentLerpTime = 0;\r\n }\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class EaseBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1 * 1000; // 1 second\r\n private _lerpStart: Vector = new Vector(0, 0);\r\n private _lerpEnd: Vector = new Vector(0, 0);\r\n private _offset: Vector;\r\n private _initialized: boolean = false;\r\n private _stopped: boolean = false;\r\n constructor(\r\n entity: Entity,\r\n offsetX: number,\r\n offsetY: number,\r\n duration: number,\r\n public easingFcn: (currentTime: number, startValue: number, endValue: number, duration: number) => number\r\n ) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._lerpDuration = duration;\r\n this._offset = new Vector(offsetX, offsetY);\r\n }\r\n private _initialize() {\r\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._currentLerpTime = 0;\r\n this._lerpEnd = this._lerpStart.add(this._offset);\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._initialized) {\r\n this._initialize();\r\n this._initialized = true;\r\n }\r\n\r\n // Need to update lerp time first, otherwise the first update will always be zero\r\n this._currentLerpTime += delta;\r\n let newX = this._tx.pos.x;\r\n let newY = this._tx.pos.y;\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n if (this._lerpEnd.x < this._lerpStart.x) {\r\n newX =\r\n this._lerpStart.x -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\r\n } else {\r\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\r\n }\r\n\r\n if (this._lerpEnd.y < this._lerpStart.y) {\r\n newY =\r\n this._lerpStart.y -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\r\n } else {\r\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\r\n }\r\n // Given the lerp position figure out the velocity in pixels per second\r\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\r\n } else {\r\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\r\n this._motion.vel = Vector.Zero;\r\n }\r\n }\r\n public isComplete(): boolean {\r\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\r\n }\r\n\r\n public reset(): void {\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._currentLerpTime = 0;\r\n }\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n}","import { GraphicsComponent } from '../../Graphics/GraphicsComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\n\r\nexport class Blink implements Action {\r\n private _graphics: GraphicsComponent;\r\n private _timeVisible: number = 0;\r\n private _timeNotVisible: number = 0;\r\n private _elapsedTime: number = 0;\r\n private _totalTime: number = 0;\r\n private _duration: number;\r\n private _stopped: boolean = false;\r\n private _started: boolean = false;\r\n constructor(entity: Entity, timeVisible: number, timeNotVisible: number, numBlinks: number = 1) {\r\n this._graphics = entity.get(GraphicsComponent);\r\n this._timeVisible = timeVisible;\r\n this._timeNotVisible = timeNotVisible;\r\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n }\r\n if (!this._graphics) {\r\n return;\r\n }\r\n\r\n this._elapsedTime += delta;\r\n this._totalTime += delta;\r\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\r\n this._graphics.visible = false;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\r\n this._graphics.visible = true;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._graphics.visible = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._totalTime >= this._duration;\r\n }\r\n\r\n public stop(): void {\r\n if (this._graphics) {\r\n this._graphics.visible = true;\r\n }\r\n this._stopped = true;\r\n }\r\n\r\n public reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { GraphicsComponent } from '../../Graphics/GraphicsComponent';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Action } from '../Action';\r\n\r\nexport class Fade implements Action {\r\n private _graphics: GraphicsComponent;\r\n public x: number;\r\n public y: number;\r\n\r\n private _endOpacity: number;\r\n private _speed: number;\r\n private _ogspeed: number;\r\n private _multiplier: number = 1;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, endOpacity: number, speed: number) {\r\n this._graphics = entity.get(GraphicsComponent);\r\n this._endOpacity = endOpacity;\r\n this._speed = this._ogspeed = speed;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._graphics) {\r\n return;\r\n }\r\n\r\n if (!this._started) {\r\n this._started = true;\r\n this._speed = this._ogspeed;\r\n\r\n // determine direction when we start\r\n if (this._endOpacity < this._graphics.opacity) {\r\n this._multiplier = -1;\r\n } else {\r\n this._multiplier = 1;\r\n }\r\n }\r\n\r\n if (this._speed > 0) {\r\n this._graphics.opacity += (this._multiplier *\r\n (Math.abs(this._graphics.opacity - this._endOpacity) * delta)) / this._speed;\r\n }\r\n\r\n this._speed -= delta;\r\n\r\n if (this.isComplete()) {\r\n this._graphics.opacity = this._endOpacity;\r\n }\r\n\r\n Logger.getInstance().debug('[Action fade] Actor opacity:', this._graphics.opacity);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\n\r\nexport class Delay implements Action {\r\n private _elapsedTime: number = 0;\r\n private _delay: number;\r\n private _started: boolean = false;\r\n private _stopped = false;\r\n constructor(delay: number) {\r\n this._delay = delay;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n }\r\n\r\n this._elapsedTime += delta;\r\n }\r\n\r\n isComplete(): boolean {\r\n return this._stopped || this._elapsedTime >= this._delay;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n reset(): void {\r\n this._elapsedTime = 0;\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionsComponent } from '../ActionsComponent';\r\n\r\nexport class Die implements Action {\r\n private _entity: Entity;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n }\r\n\r\n public update(_delta: number): void {\r\n this._entity.get(ActionsComponent).clearActions();\r\n this._entity.kill();\r\n this._stopped = true;\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped;\r\n }\r\n\r\n public stop(): void {\r\n return;\r\n }\r\n\r\n public reset(): void {\r\n return;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class Follow implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _followTx: TransformComponent;\r\n private _followMotion: MotionComponent;\r\n\r\n public x: number;\r\n public y: number;\r\n private _current: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _maximumDistance: number;\r\n private _distanceBetween: number;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, entityToFollow: Entity, followDistance?: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._followTx = entityToFollow.get(TransformComponent);\r\n this._followMotion = entityToFollow.get(MotionComponent);\r\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\r\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\r\n this._speed = 0;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n }\r\n\r\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\r\n if (actorToFollowSpeed !== 0) {\r\n this._speed = actorToFollowSpeed;\r\n }\r\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\r\n\r\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n\r\n if (this._distanceBetween >= this._maximumDistance) {\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n } else {\r\n this._motion.vel = vec(0, 0);\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public isComplete(): boolean {\r\n // the actor following should never stop unless specified to do so\r\n return this._stopped;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class Meet implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _meetTx: TransformComponent;\r\n private _meetMotion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _current: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _distanceBetween: number;\r\n private _started = false;\r\n private _stopped = false;\r\n private _speedWasSpecified = false;\r\n\r\n constructor(actor: Entity, actorToMeet: Entity, speed?: number) {\r\n this._tx = actor.get(TransformComponent);\r\n this._motion = actor.get(MotionComponent);\r\n this._meetTx = actorToMeet.get(TransformComponent);\r\n this._meetMotion = actorToMeet.get(MotionComponent);\r\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\r\n this._speed = speed || 0;\r\n\r\n if (speed !== undefined) {\r\n this._speedWasSpecified = true;\r\n }\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n }\r\n\r\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\r\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) {\r\n this._speed = actorToMeetSpeed;\r\n }\r\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\r\n\r\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n\r\n if (this.isComplete()) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._distanceBetween <= 1;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n this._distanceBetween = undefined;\r\n }\r\n}\r\n","import { RotationType } from './RotationType';\r\n\r\nimport { EasingFunction, EasingFunctions } from '../Util/EasingFunctions';\r\nimport { ActionQueue } from './ActionQueue';\r\nimport { Repeat } from './Action/Repeat';\r\nimport { RepeatForever } from './Action/RepeatForever';\r\nimport { MoveBy } from './Action/MoveBy';\r\nimport { MoveTo } from './Action/MoveTo';\r\nimport { RotateTo } from './Action/RotateTo';\r\nimport { RotateBy } from './Action/RotateBy';\r\nimport { ScaleTo } from './Action/ScaleTo';\r\nimport { ScaleBy } from './Action/ScaleBy';\r\nimport { CallMethod } from './Action/CallMethod';\r\nimport { EaseTo } from './Action/EaseTo';\r\nimport { EaseBy } from './Action/EaseBy';\r\nimport { Blink } from './Action/Blink';\r\nimport { Fade } from './Action/Fade';\r\nimport { Delay } from './Action/Delay';\r\nimport { Die } from './Action/Die';\r\nimport { Follow } from './Action/Follow';\r\nimport { Meet } from './Action/Meet';\r\nimport { Vector } from '../Math/vector';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Action } from './Action';\r\n\r\n/**\r\n * The fluent Action API allows you to perform \"actions\" on\r\n * [[Actor|Actors]] such as following, moving, rotating, and\r\n * more. You can implement your own actions by implementing\r\n * the [[Action]] interface.\r\n */\r\nexport class ActionContext {\r\n private _entity: Entity;\r\n private _queue: ActionQueue;\r\n\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n this._queue = new ActionQueue(entity);\r\n }\r\n\r\n public getQueue(): ActionQueue {\r\n return this._queue;\r\n }\r\n\r\n public update(elapsedMs: number) {\r\n this._queue.update(elapsedMs);\r\n }\r\n\r\n /**\r\n * Clears all queued actions from the Actor\r\n */\r\n public clearActions(): void {\r\n this._queue.clearActions();\r\n }\r\n\r\n public runAction(action: Action) {\r\n action.reset();\r\n this._queue.add(action);\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(pos: Vector, duration: number, easingFcn?: EasingFunction): ActionContext\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(x: number, y: number, duration: number, easingFcn?: EasingFunction): ActionContext\r\n public easeTo(...args: any[]): ActionContext {\r\n let x = 0;\r\n let y = 0;\r\n let duration = 0;\r\n let easingFcn = EasingFunctions.Linear;\r\n if (args[0] instanceof Vector) {\r\n x = args[0].x;\r\n y = args[0].y;\r\n duration = args[1];\r\n easingFcn = args[2] ?? easingFcn;\r\n } else {\r\n x = args[0];\r\n y = args[1];\r\n duration = args[2];\r\n easingFcn = args[3] ?? easingFcn;\r\n }\r\n\r\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor by a specified vector offset relative to the current position given\r\n * a duration and a [[EasingFunction]]. This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset Vector offset relative to the current position\r\n * @param duration The duration in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeBy(offset: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n /**\r\n * This method will move an actor by a specified x and y offset relative to the current position given\r\n * a duration and a [[EasingFunction]]. This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset Vector offset relative to the current position\r\n * @param duration The duration in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeBy(offsetX: number, offsetY: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(...args: any[]): ActionContext {\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n let duration = 0;\r\n let easingFcn = EasingFunctions.Linear;\r\n if (args[0] instanceof Vector) {\r\n offsetX = args[0].x;\r\n offsetY = args[0].y;\r\n duration = args[1];\r\n easingFcn = args[2] ?? easingFcn;\r\n } else {\r\n offsetX = args[0];\r\n offsetY = args[1];\r\n duration = args[2];\r\n easingFcn = args[3] ?? easingFcn;\r\n }\r\n\r\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(pos: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(x: number, y: number, speed: number): ActionContext;\r\n public moveTo(xOrPos: number | Vector, yOrSpeed: number, speedOrUndefined?: number | undefined): ActionContext {\r\n let x = 0;\r\n let y = 0;\r\n let speed = 0;\r\n if (xOrPos instanceof Vector) {\r\n x = xOrPos.x;\r\n y = xOrPos.y;\r\n speed = yOrSpeed;\r\n } else {\r\n x = xOrPos;\r\n y = yOrSpeed;\r\n speed = speedOrUndefined;\r\n }\r\n this._queue.add(new MoveTo(this._entity, x, y, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param xOffset The x offset to apply to this actor\r\n * @param yOffset The y location to move the actor to\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(offset: Vector, speed: number): ActionContext;\r\n public moveBy(xOffset: number, yOffset: number, speed: number): ActionContext;\r\n public moveBy(xOffsetOrVector: number | Vector, yOffsetOrSpeed: number, speedOrUndefined?: number | undefined): ActionContext {\r\n let xOffset = 0;\r\n let yOffset = 0;\r\n let speed = 0;\r\n if (xOffsetOrVector instanceof Vector) {\r\n xOffset = xOffsetOrVector.x;\r\n yOffset = xOffsetOrVector.y;\r\n speed = yOffsetOrSpeed;\r\n } else {\r\n xOffset = xOffsetOrVector;\r\n yOffset = yOffsetOrSpeed;\r\n speed = speedOrUndefined;\r\n }\r\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */\r\n public rotateTo(angleRadians: number, speed: number, rotationType?: RotationType): ActionContext {\r\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */\r\n public rotateBy(angleRadiansOffset: number, speed: number, rotationType?: RotationType): ActionContext {\r\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param size The scale to adjust the actor to over time\r\n * @param speed The speed of scaling specified in magnitude increase per second\r\n */\r\n public scaleTo(size: Vector, speed: Vector): ActionContext;\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param sizeX The scaling factor to apply on X axis\r\n * @param sizeY The scaling factor to apply on Y axis\r\n * @param speedX The speed of scaling specified in magnitude increase per second on X axis\r\n * @param speedY The speed of scaling specified in magnitude increase per second on Y axis\r\n */\r\n public scaleTo(sizeX: number, sizeY: number, speedX: number, speedY: number): ActionContext;\r\n public scaleTo(sizeXOrVector: number | Vector,\r\n sizeYOrSpeed: number | Vector,\r\n speedXOrUndefined?: number | undefined,\r\n speedYOrUndefined?: number | undefined): ActionContext {\r\n\r\n let sizeX = 1;\r\n let sizeY = 1;\r\n let speedX = 0;\r\n let speedY = 0;\r\n\r\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\r\n sizeX = sizeXOrVector.x;\r\n sizeY = sizeXOrVector.y;\r\n\r\n speedX = sizeYOrSpeed.x;\r\n speedY = sizeYOrSpeed.y;\r\n }\r\n if (typeof sizeXOrVector === 'number' && typeof sizeYOrSpeed === 'number') {\r\n sizeX = sizeXOrVector;\r\n sizeY = sizeYOrSpeed;\r\n\r\n speedX = speedXOrUndefined;\r\n speedY = speedYOrUndefined;\r\n }\r\n\r\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param offset The scaling factor to apply to the actor\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param sizeOffsetX The scaling factor to apply on X axis\r\n * @param sizeOffsetY The scaling factor to apply on Y axis\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(sizeOffsetX: number, sizeOffsetY: number, speed: number): ActionContext;\r\n public scaleBy(sizeOffsetXOrVector: number | Vector, sizeOffsetYOrSpeed: number, speed?: number | undefined): ActionContext {\r\n let sizeOffsetX = 1;\r\n let sizeOffsetY = 1;\r\n\r\n if (sizeOffsetXOrVector instanceof Vector) {\r\n sizeOffsetX = sizeOffsetXOrVector.x;\r\n sizeOffsetY = sizeOffsetXOrVector.y;\r\n\r\n speed = sizeOffsetYOrSpeed;\r\n }\r\n if (typeof sizeOffsetXOrVector === 'number' && typeof sizeOffsetYOrSpeed === 'number') {\r\n sizeOffsetX = sizeOffsetXOrVector;\r\n sizeOffsetY = sizeOffsetYOrSpeed;\r\n }\r\n\r\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */\r\n public blink(timeVisible: number, timeNotVisible: number, numBlinks: number = 1): ActionContext {\r\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */\r\n public fade(opacity: number, time: number): ActionContext {\r\n this._queue.add(new Fade(this._entity, opacity, time));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */\r\n public delay(time: number): ActionContext {\r\n this._queue.add(new Delay(time));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */\r\n public die(): ActionContext {\r\n this._queue.add(new Die(this._entity));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */\r\n public callMethod(method: () => any): ActionContext {\r\n this._queue.add(new CallMethod(method));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */\r\n public repeat(repeatBuilder: (repeatContext: ActionContext) => any, times?: number): ActionContext {\r\n if (!times) {\r\n this.repeatForever(repeatBuilder);\r\n return this;\r\n }\r\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */\r\n public repeatForever(repeatBuilder: (repeatContext: ActionContext) => any): ActionContext {\r\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */\r\n public follow(entity: Entity, followDistance?: number): ActionContext {\r\n if (followDistance === undefined) {\r\n this._queue.add(new Follow(this._entity, entity));\r\n } else {\r\n this._queue.add(new Follow(this._entity, entity, followDistance));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */\r\n public meet(entity: Entity, speed?: number): ActionContext {\r\n if (speed === undefined) {\r\n this._queue.add(new Meet(this._entity, entity));\r\n } else {\r\n this._queue.add(new Meet(this._entity, entity, speed));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */\r\n public toPromise(): Promise {\r\n const temp = new Promise((resolve) => {\r\n this._queue.add(\r\n new CallMethod(() => {\r\n resolve();\r\n })\r\n );\r\n });\r\n return temp;\r\n }\r\n}\r\n","import { ActionContext } from './ActionContext';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Actor } from '../Actor';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Vector } from '../Math/vector';\r\nimport { EasingFunction } from '../Util/EasingFunctions';\r\nimport { ActionQueue } from './ActionQueue';\r\nimport { RotationType } from './RotationType';\r\nimport { Action } from './Action';\r\n\r\nexport interface ActionContextMethods extends Pick { };\r\n\r\nexport class ActionsComponent extends Component implements ActionContextMethods {\r\n dependencies = [TransformComponent, MotionComponent];\r\n private _ctx: ActionContext | null = null;\r\n\r\n onAdd(entity: Entity) {\r\n this._ctx = new ActionContext(entity);\r\n }\r\n\r\n onRemove() {\r\n this._ctx = null;\r\n }\r\n\r\n private _getCtx() {\r\n if (!this._ctx) {\r\n throw new Error('Actions component not attached to an entity, no context available');\r\n }\r\n return this._ctx;\r\n }\r\n\r\n /**\r\n * Returns the internal action queue\r\n * @returns action queue\r\n */\r\n public getQueue(): ActionQueue {\r\n if (!this._ctx) {\r\n throw new Error('Actions component not attached to an entity, no queue available');\r\n }\r\n return this._ctx.getQueue();\r\n }\r\n\r\n public runAction(action: Action): ActionContext {\r\n if (!this._ctx) {\r\n throw new Error('Actions component not attached to an entity, cannot run action');\r\n }\r\n return this._ctx.runAction(action);\r\n }\r\n\r\n /**\r\n * Updates the internal action context, performing action and moving through the internal queue\r\n * @param elapsedMs\r\n */\r\n public update(elapsedMs: number): void {\r\n return this._ctx?.update(elapsedMs);\r\n }\r\n\r\n /**\r\n * Clears all queued actions from the Actor\r\n */\r\n public clearActions(): void {\r\n this._ctx?.clearActions();\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunctions]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(pos: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunctions]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(x: number, y: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeTo(...args: any[]): ActionContext {\r\n return this._getCtx().easeTo.apply(this._ctx, args as any);\r\n }\r\n\r\n public easeBy(offset: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(offsetX: number, offsetY: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(...args: any[]): ActionContext {\r\n return this._getCtx().easeBy.apply(this._ctx, args as any);\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(pos: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(x: number, y: number, speed: number): ActionContext;\r\n public moveTo(xOrPos: number | Vector, yOrSpeed: number, speedOrUndefined?: number): ActionContext {\r\n return this._getCtx().moveTo.apply(this._ctx, [xOrPos, yOrSpeed, speedOrUndefined] as any);\r\n }\r\n\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset The (x, y) offset to apply to this actor\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param xOffset The x offset to apply to this actor\r\n * @param yOffset The y location to move the actor to\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(xOffset: number, yOffset: number, speed: number): ActionContext;\r\n public moveBy(xOffsetOrVector: number | Vector, yOffsetOrSpeed: number, speedOrUndefined?: number): ActionContext {\r\n return this._getCtx().moveBy.apply(this._ctx, [xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined] as any);\r\n }\r\n\r\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */\r\n public rotateTo(angleRadians: number, speed: number, rotationType?: RotationType): ActionContext {\r\n return this._getCtx().rotateTo(angleRadians, speed, rotationType);\r\n }\r\n\r\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */\r\n public rotateBy(angleRadiansOffset: number, speed: number, rotationType?: RotationType): ActionContext {\r\n return this._getCtx().rotateBy(angleRadiansOffset, speed, rotationType);\r\n }\r\n\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param size The scale to adjust the actor to over time\r\n * @param speed The speed of scaling specified in magnitude increase per second\r\n */\r\n public scaleTo(size: Vector, speed: Vector): ActionContext;\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param sizeX The scaling factor to apply on X axis\r\n * @param sizeY The scaling factor to apply on Y axis\r\n * @param speedX The speed of scaling specified in magnitude increase per second on X axis\r\n * @param speedY The speed of scaling specified in magnitude increase per second on Y axis\r\n */\r\n public scaleTo(sizeX: number, sizeY: number, speedX: number, speedY: number): ActionContext;\r\n public scaleTo(\r\n sizeXOrVector: number | Vector,\r\n sizeYOrSpeed: number | Vector,\r\n speedXOrUndefined?: number,\r\n speedYOrUndefined?: number): ActionContext {\r\n return this._getCtx().scaleTo.apply(this._ctx, [sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined] as any);\r\n }\r\n\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param offset The scaling factor to apply to the actor\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param sizeOffsetX The scaling factor to apply on X axis\r\n * @param sizeOffsetY The scaling factor to apply on Y axis\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(sizeOffsetX: number, sizeOffsetY: number, speed: number): ActionContext;\r\n public scaleBy(sizeOffsetXOrVector: number | Vector, sizeOffsetYOrSpeed: number, speed?: number): ActionContext {\r\n return this._getCtx().scaleBy.apply(this._ctx, [sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed] as any);\r\n }\r\n\r\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */\r\n public blink(timeVisible: number, timeNotVisible: number, numBlinks?: number): ActionContext {\r\n return this._getCtx().blink(timeVisible, timeNotVisible, numBlinks);\r\n }\r\n\r\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */\r\n public fade(opacity: number, time: number): ActionContext {\r\n return this._getCtx().fade(opacity, time);\r\n }\r\n\r\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */\r\n public delay(time: number): ActionContext {\r\n return this._getCtx().delay(time);\r\n }\r\n\r\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */\r\n public die(): ActionContext {\r\n return this._getCtx().die();\r\n }\r\n\r\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */\r\n public callMethod(method: () => any): ActionContext {\r\n return this._getCtx().callMethod(method);\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */\r\n public repeat(repeatBuilder: (repeatContext: ActionContext) => any, times?: number): ActionContext {\r\n return this._getCtx().repeat(repeatBuilder, times);\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */\r\n public repeatForever(repeatBuilder: (repeatContext: ActionContext) => any): ActionContext {\r\n return this._getCtx().repeatForever(repeatBuilder);\r\n }\r\n\r\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */\r\n public follow(entity: Actor, followDistance?: number): ActionContext {\r\n return this._getCtx().follow(entity, followDistance);\r\n }\r\n\r\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */\r\n public meet(entity: Actor, speed?: number): ActionContext {\r\n return this._getCtx().meet(entity, speed);\r\n }\r\n\r\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */\r\n public toPromise(): Promise {\r\n return this._getCtx().toPromise();\r\n }\r\n}","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\n\r\n/**\r\n * Enum representing the different font size units\r\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\r\n */\r\nexport enum FontUnit {\r\n /**\r\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\r\n */\r\n Em = 'em',\r\n /**\r\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\r\n */\r\n Rem = 'rem',\r\n /**\r\n * Pixel is a unit of length in screen pixels\r\n */\r\n Px = 'px',\r\n /**\r\n * Point is a physical unit length (1/72 of an inch)\r\n */\r\n Pt = 'pt',\r\n /**\r\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\r\n */\r\n Percent = '%'\r\n}\r\n\r\n/**\r\n * Enum representing the different horizontal text alignments\r\n */\r\nexport enum TextAlign {\r\n /**\r\n * The text is left-aligned.\r\n */\r\n Left = 'left',\r\n /**\r\n * The text is right-aligned.\r\n */\r\n Right = 'right',\r\n /**\r\n * The text is centered.\r\n */\r\n Center = 'center',\r\n /**\r\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\r\n * right-aligned for right-to-left locales).\r\n */\r\n Start = 'start',\r\n /**\r\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\r\n * left-aligned for right-to-left locales).\r\n */\r\n End = 'end'\r\n}\r\n\r\n/**\r\n * Enum representing the different baseline text alignments\r\n */\r\nexport enum BaseAlign {\r\n /**\r\n * The text baseline is the top of the em square.\r\n */\r\n Top = 'top',\r\n /**\r\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\r\n * alphabetic.\r\n */\r\n Hanging = 'hanging',\r\n /**\r\n * The text baseline is the middle of the em square.\r\n */\r\n Middle = 'middle',\r\n /**\r\n * The text baseline is the normal alphabetic baseline.\r\n */\r\n Alphabetic = 'alphabetic',\r\n /**\r\n * The text baseline is the ideographic baseline; this is the bottom of\r\n * the body of the characters, if the main body of characters protrudes\r\n * beneath the alphabetic baseline. Currently unsupported; this will\r\n * act like alphabetic.\r\n */\r\n Ideographic = 'ideographic',\r\n /**\r\n * The text baseline is the bottom of the bounding box. This differs\r\n * from the ideographic baseline in that the ideographic baseline\r\n * doesn't consider descenders.\r\n */\r\n Bottom = 'bottom'\r\n}\r\n\r\n/**\r\n * Enum representing the different possible font styles\r\n */\r\nexport enum FontStyle {\r\n Normal = 'normal',\r\n Italic = 'italic',\r\n Oblique = 'oblique'\r\n}\r\n\r\n/**\r\n * Enum representing the text direction, useful for other languages, or writing text in reverse\r\n */\r\nexport enum Direction {\r\n LeftToRight = 'ltr',\r\n RightToLeft = 'rtl'\r\n}\r\n\r\n/**\r\n * Font rendering option\r\n */\r\nexport interface FontOptions {\r\n /**\r\n * Optionally the size of the font in the specified [[FontUnit]] by default 10.\r\n */\r\n size?: number;\r\n /**\r\n * Optionally specify unit to measure fonts in, by default Pixels\r\n */\r\n unit?: FontUnit;\r\n /**\r\n * Optionally specify the font family, by default 'sans-serif'\r\n */\r\n family?: string;\r\n /**\r\n * Optionally specify the font style, by default Normal\r\n */\r\n style?: FontStyle;\r\n /**\r\n * Optionally set whether the font is bold, by default false\r\n */\r\n bold?: boolean;\r\n /**\r\n * Optionally specify the text align, by default Left\r\n */\r\n textAlign?: TextAlign;\r\n /**\r\n * Optionally specify the text base align, by default Alphabetic\r\n */\r\n baseAlign?: BaseAlign;\r\n /**\r\n * Optionally specify the text direction, by default LeftToRight\r\n */\r\n direction?: Direction;\r\n /**\r\n * Optionally override the text line height in pixels, useful for multiline text. If unset will use default.\r\n */\r\n lineHeight?: number | undefined;\r\n /**\r\n * Optionally specify the quality of the text bitmap, it is a multiplier on the size size, by default 2.\r\n * Higher quality text has a higher memory impact\r\n */\r\n quality?: number;\r\n /**\r\n * Optionally specify a text shadow, by default none is specified\r\n */\r\n shadow?: {\r\n blur?: number;\r\n offset?: Vector;\r\n color?: Color;\r\n };\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface FontRenderer {\r\n measureText(text: string): BoundingBox;\r\n render(ex: ExcaliburGraphicsContext, text: string, color: Color, x: number, y: number): void;\r\n}\r\n","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { line } from '../Util/DrawUtil';\r\nimport { ExcaliburGraphicsContextWebGL } from './Context/ExcaliburGraphicsContextWebGL';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Font } from './Font';\r\n\r\nexport class FontTextInstance {\r\n public canvas: HTMLCanvasElement;\r\n public ctx: CanvasRenderingContext2D;\r\n private _textFragments: { x: number; y: number; canvas: HTMLCanvasElement }[] = [];\r\n public dimensions: BoundingBox;\r\n public disposed: boolean = false;\r\n private _lastHashCode: string;\r\n\r\n constructor(public readonly font: Font, public readonly text: string, public readonly color: Color, public readonly maxWidth?: number) {\r\n this.canvas = document.createElement('canvas');\r\n this.ctx = this.canvas.getContext('2d');\r\n this.dimensions = this.measureText(text);\r\n this._setDimension(this.dimensions, this.ctx);\r\n this._lastHashCode = this.getHashCode();\r\n }\r\n\r\n measureText(text: string, maxWidth?: number): BoundingBox {\r\n if (this.disposed) {\r\n throw Error('Accessing disposed text instance! ' + this.text);\r\n }\r\n let lines = null;\r\n if (maxWidth != null) {\r\n lines = this._getLinesFromText(text, maxWidth);\r\n } else {\r\n lines = text.split('\\n');\r\n }\r\n\r\n const maxWidthLine = lines.reduce((a, b) => {\r\n return a.length > b.length ? a : b;\r\n });\r\n\r\n this._applyFont(this.ctx); // font must be applied to the context to measure it\r\n const metrics = this.ctx.measureText(maxWidthLine);\r\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\r\n\r\n // TODO lineheight makes the text bounds wonky\r\n const lineAdjustedHeight = textHeight * lines.length;\r\n textHeight = lineAdjustedHeight;\r\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\r\n const x = 0;\r\n const y = 0;\r\n const measurement = new BoundingBox({\r\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\r\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\r\n bottom: y + bottomBounds + this.font.padding,\r\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\r\n });\r\n\r\n return measurement;\r\n }\r\n\r\n private _setDimension(textBounds: BoundingBox, bitmap: CanvasRenderingContext2D) {\r\n let lineHeightRatio = 1;\r\n if (this.font.lineHeight) {\r\n lineHeightRatio = (this.font.lineHeight/this.font.size);\r\n }\r\n // Changing the width and height clears the context properties\r\n // We double the bitmap width to account for all possible alignment\r\n // We scale by \"quality\" so we render text without jaggies\r\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\r\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality * lineHeightRatio;\r\n }\r\n\r\n public static getHashCode(font: Font, text: string, color?: Color) {\r\n const hash =\r\n text +\r\n '__hashcode__' +\r\n font.fontString +\r\n font.showDebug +\r\n font.textAlign +\r\n font.baseAlign +\r\n font.direction +\r\n font.lineHeight +\r\n JSON.stringify(font.shadow) +\r\n (font.padding.toString() +\r\n font.smoothing.toString() +\r\n font.lineWidth.toString() +\r\n font.lineDash.toString() +\r\n font.strokeColor?.toString() +\r\n (color ? color.toString() : font.color.toString()));\r\n return hash;\r\n }\r\n\r\n getHashCode(includeColor: boolean = true) {\r\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\r\n }\r\n\r\n protected _applyRasterProperties(ctx: CanvasRenderingContext2D) {\r\n ctx.translate(this.font.padding, this.font.padding);\r\n ctx.imageSmoothingEnabled = this.font.smoothing;\r\n ctx.lineWidth = this.font.lineWidth;\r\n ctx.setLineDash(this.font.lineDash ?? ctx.getLineDash());\r\n ctx.strokeStyle = this.font.strokeColor?.toString();\r\n ctx.fillStyle = this.color.toString();\r\n }\r\n\r\n private _applyFont(ctx: CanvasRenderingContext2D) {\r\n ctx.resetTransform();\r\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\r\n ctx.scale(this.font.quality, this.font.quality);\r\n ctx.textAlign = this.font.textAlign;\r\n ctx.textBaseline = this.font.baseAlign;\r\n ctx.font = this.font.fontString;\r\n ctx.direction = this.font.direction;\r\n\r\n if (this.font.shadow) {\r\n ctx.shadowColor = this.font.shadow.color.toString();\r\n ctx.shadowBlur = this.font.shadow.blur;\r\n ctx.shadowOffsetX = this.font.shadow.offset.x;\r\n ctx.shadowOffsetY = this.font.shadow.offset.y;\r\n }\r\n }\r\n\r\n private _drawText(ctx: CanvasRenderingContext2D, lines: string[], lineHeight: number): void {\r\n this._applyRasterProperties(ctx);\r\n this._applyFont(ctx);\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (this.color) {\r\n ctx.fillText(line, 0, i * lineHeight);\r\n }\r\n\r\n if (this.font.strokeColor) {\r\n ctx.strokeText(line, 0, i * lineHeight);\r\n }\r\n }\r\n\r\n if (this.font.showDebug) {\r\n // Horizontal line\r\n /* istanbul ignore next */\r\n line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\r\n // Vertical line\r\n /* istanbul ignore next */\r\n line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\r\n }\r\n }\r\n\r\n private _splitTextBitmap(bitmap: CanvasRenderingContext2D) {\r\n const textImages: { x: number; y: number; canvas: HTMLCanvasElement }[] = [];\r\n let currentX = 0;\r\n let currentY = 0;\r\n // 4k is the max for mobile devices\r\n const width = Math.min(4096, bitmap.canvas.width);\r\n const height = Math.min(4096, bitmap.canvas.height);\r\n\r\n // Splits the original bitmap into 4k max chunks\r\n while (currentX < bitmap.canvas.width) {\r\n while (currentY < bitmap.canvas.height) {\r\n // create new bitmap\r\n const canvas = document.createElement('canvas');\r\n canvas.width = width;\r\n canvas.height = height;\r\n const ctx = canvas.getContext('2d');\r\n\r\n // draw current slice to new bitmap in < 4k chunks\r\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\r\n\r\n textImages.push({ x: currentX, y: currentY, canvas });\r\n currentY += height;\r\n }\r\n currentX += width;\r\n currentY = 0;\r\n }\r\n return textImages;\r\n }\r\n\r\n public flagDirty() {\r\n this._dirty = true;\r\n }\r\n private _dirty = true;\r\n private _ex: ExcaliburGraphicsContext;\r\n public render(ex: ExcaliburGraphicsContext, x: number, y: number, maxWidth?: number) {\r\n if (this.disposed) {\r\n throw Error('Accessing disposed text instance! ' + this.text);\r\n }\r\n this._ex = ex;\r\n const hashCode = this.getHashCode();\r\n if (this._lastHashCode !== hashCode) {\r\n this._dirty = true;\r\n }\r\n\r\n // Calculate image chunks\r\n if (this._dirty) {\r\n this.dimensions = this.measureText(this.text, maxWidth);\r\n this._setDimension(this.dimensions, this.ctx);\r\n const lines = this._getLinesFromText(this.text, maxWidth);\r\n const lineHeight = this.font.lineHeight ?? this.dimensions.height / lines.length;\r\n\r\n // draws the text to the main bitmap\r\n this._drawText(this.ctx, lines, lineHeight);\r\n\r\n // clear any out old fragments\r\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n ex.textureLoader.delete(frag.canvas);\r\n }\r\n }\r\n\r\n // splits to < 4k fragments for large text\r\n this._textFragments = this._splitTextBitmap(this.ctx);\r\n\r\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n ex.textureLoader.load(frag.canvas, this.font.filtering, true);\r\n }\r\n }\r\n this._lastHashCode = hashCode;\r\n this._dirty = false;\r\n }\r\n\r\n // draws the bitmap fragments to excalibur graphics context\r\n for (const frag of this._textFragments) {\r\n ex.drawImage(\r\n frag.canvas,\r\n 0,\r\n 0,\r\n frag.canvas.width,\r\n frag.canvas.height,\r\n frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2,\r\n frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2,\r\n frag.canvas.width / this.font.quality,\r\n frag.canvas.height / this.font.quality\r\n );\r\n }\r\n }\r\n\r\n dispose() {\r\n this.disposed = true;\r\n this.dimensions = undefined;\r\n this.canvas = undefined;\r\n this.ctx = undefined;\r\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n this._ex.textureLoader.delete(frag.canvas);\r\n }\r\n }\r\n this._textFragments.length = 0;\r\n }\r\n\r\n /**\r\n * Return array of lines split based on the \\n character, and the maxWidth? constraint\r\n * @param text\r\n * @param maxWidth\r\n */\r\n private _cachedText: string;\r\n private _cachedLines: string[];\r\n private _cachedRenderWidth: number;\r\n private _getLinesFromText(text: string, maxWidth?: number) {\r\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\r\n return this._cachedLines;\r\n }\r\n\r\n const lines = text.split('\\n');\r\n\r\n if (maxWidth == null) {\r\n return lines;\r\n }\r\n\r\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\r\n for (let i = 0; i < lines.length; i++) {\r\n let line = lines[i];\r\n let newLine = '';\r\n if (this.measureText(line).width > maxWidth) {\r\n while (this.measureText(line).width > maxWidth) {\r\n newLine = line[line.length - 1] + newLine;\r\n line = line.slice(0, -1); // Remove last character from line\r\n }\r\n\r\n // Update the array with our new values\r\n lines[i] = line;\r\n lines[i + 1] = newLine;\r\n }\r\n }\r\n\r\n this._cachedText = text;\r\n this._cachedLines = lines;\r\n this._cachedRenderWidth = maxWidth;\r\n\r\n return lines;\r\n }\r\n}\r\n","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Logger } from '../Util/Log';\r\nimport { Font } from './Font';\r\nimport { FontTextInstance } from './FontTextInstance';\r\n\r\nexport class FontCache {\r\n public static FONT_TIMEOUT = 500;\r\n private static _LOGGER = Logger.getInstance();\r\n private static _TEXT_USAGE = new Map();\r\n private static _TEXT_CACHE = new Map();\r\n private static _MEASURE_CACHE = new Map();\r\n\r\n static measureText(text: string, font: Font, maxWidth?: number) {\r\n const hash = FontTextInstance.getHashCode(font, text);\r\n if (FontCache._MEASURE_CACHE.has(hash)) {\r\n return FontCache._MEASURE_CACHE.get(hash);\r\n }\r\n FontCache._LOGGER.debug('Font text measurement cache miss');\r\n const measurement = font.measureTextWithoutCache(text, maxWidth);\r\n FontCache._MEASURE_CACHE.set(hash, measurement);\r\n return measurement;\r\n }\r\n\r\n static getTextInstance(text: string, font: Font, color: Color) {\r\n const hash = FontTextInstance.getHashCode(font, text, color);\r\n let textInstance = FontCache._TEXT_CACHE.get(hash);\r\n if (!textInstance) {\r\n textInstance = new FontTextInstance(font, text, color);\r\n FontCache._TEXT_CACHE.set(hash, textInstance);\r\n FontCache._LOGGER.debug('Font text instance cache miss');\r\n }\r\n\r\n // Cache the bitmap for certain amount of time\r\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\r\n\r\n return textInstance;\r\n }\r\n\r\n static checkAndClearCache() {\r\n const deferred: FontTextInstance[] = [];\r\n const currentHashCodes = new Set();\r\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries()) {\r\n // if bitmap hasn't been used in 100 ms clear it\r\n if (time + FontCache.FONT_TIMEOUT < performance.now()) {\r\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\r\n deferred.push(textInstance);\r\n textInstance.dispose();\r\n } else {\r\n const hash = textInstance.getHashCode(false);\r\n currentHashCodes.add(hash);\r\n }\r\n }\r\n // Deferred removal of text instances\r\n deferred.forEach((t) => {\r\n FontCache._TEXT_USAGE.delete(t);\r\n });\r\n\r\n // Regenerate text instance cache\r\n this._TEXT_CACHE.clear();\r\n for (const [textInstance] of this._TEXT_USAGE.entries()) {\r\n this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\r\n }\r\n\r\n // Regenerated measurement cache\r\n const newTextMeasurementCache = new Map();\r\n for (const current of currentHashCodes) {\r\n if (FontCache._MEASURE_CACHE.has(current)) {\r\n newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\r\n }\r\n }\r\n this._MEASURE_CACHE.clear();\r\n this._MEASURE_CACHE = newTextMeasurementCache;\r\n }\r\n\r\n public static get cacheSize() {\r\n return FontCache._TEXT_USAGE.size;\r\n }\r\n\r\n /**\r\n * Force clear all cached text bitmaps\r\n */\r\n public static clearCache() {\r\n for (const [textInstance] of FontCache._TEXT_USAGE.entries()) {\r\n textInstance.dispose();\r\n }\r\n FontCache._TEXT_USAGE.clear();\r\n FontCache._TEXT_CACHE.clear();\r\n FontCache._MEASURE_CACHE.clear();\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { BoundingBox } from '../Collision/Index';\r\nimport { Color } from '../Color';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BaseAlign, Direction, FontOptions, FontStyle, FontUnit, TextAlign, FontRenderer } from './FontCommon';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { RasterOptions } from './Raster';\r\nimport { ImageFiltering } from './Filtering';\r\nimport { FontTextInstance } from './FontTextInstance';\r\nimport { FontCache } from './FontCache';\r\n/**\r\n * Represents a system or web font in Excalibur\r\n *\r\n * If no options specified, the system sans-serif 10 pixel is used\r\n *\r\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\r\n */\r\nexport class Font extends Graphic implements FontRenderer {\r\n /**\r\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\r\n *\r\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\r\n */\r\n public filtering: ImageFiltering = ImageFiltering.Blended;\r\n constructor(options: FontOptions & GraphicOptions & RasterOptions = {}) {\r\n super(options); // <- Graphics properties\r\n\r\n // Raster properties\r\n this.smoothing = options?.smoothing ?? this.smoothing;\r\n this.padding = options?.padding ?? this.padding;\r\n this.color = options?.color ?? this.color;\r\n this.strokeColor = options?.strokeColor ?? this.strokeColor;\r\n this.lineDash = options?.lineDash ?? this.lineDash;\r\n this.lineWidth = options?.lineWidth ?? this.lineWidth;\r\n this.filtering = options?.filtering ?? this.filtering;\r\n\r\n // Font specific properties\r\n this.family = options?.family ?? this.family;\r\n this.style = options?.style ?? this.style;\r\n this.bold = options?.bold ?? this.bold;\r\n this.size = options?.size ?? this.size;\r\n this.unit = options?.unit ?? this.unit;\r\n this.textAlign = options?.textAlign ?? this.textAlign;\r\n this.baseAlign = options?.baseAlign ?? this.baseAlign;\r\n this.direction = options?.direction ?? this.direction;\r\n this.lineHeight = options?.lineHeight ?? this.lineHeight;\r\n this.quality = options?.quality ?? this.quality;\r\n if (options?.shadow) {\r\n this.shadow = {};\r\n this.shadow.blur = options.shadow.blur ?? this.shadow.blur;\r\n this.shadow.offset = options.shadow.offset ?? this.shadow.offset;\r\n this.shadow.color = options.shadow.color ?? this.shadow.color;\r\n }\r\n }\r\n\r\n public clone() {\r\n return new Font({\r\n ...this.cloneGraphicOptions(),\r\n size: this.size,\r\n unit: this.unit,\r\n family: this.family,\r\n style: this.style,\r\n bold: this.bold,\r\n textAlign: this.textAlign,\r\n baseAlign: this.baseAlign,\r\n direction: this.direction,\r\n shadow: this.shadow\r\n ? {\r\n blur: this.shadow.blur,\r\n offset: this.shadow.offset,\r\n color: this.shadow.color\r\n }\r\n : null\r\n });\r\n }\r\n\r\n /**\r\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\r\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\r\n *\r\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\r\n *\r\n * (Default 2)\r\n */\r\n public quality = 2;\r\n\r\n // Raster properties for fonts\r\n public padding = 2;\r\n public smoothing = false;\r\n public lineWidth = 1;\r\n public lineDash: number[] = [];\r\n public color: Color = Color.Black;\r\n public strokeColor: Color;\r\n\r\n public family: string = 'sans-serif';\r\n public style: FontStyle = FontStyle.Normal;\r\n public bold: boolean = false;\r\n public unit: FontUnit = FontUnit.Px;\r\n public textAlign: TextAlign = TextAlign.Left;\r\n public baseAlign: BaseAlign = BaseAlign.Top;\r\n public direction: Direction = Direction.LeftToRight;\r\n /**\r\n * Font line height in pixels, default line height if unset\r\n */\r\n public lineHeight: number | undefined = undefined;\r\n public size: number = 10;\r\n public shadow: { blur?: number; offset?: Vector; color?: Color } = null;\r\n\r\n public get fontString() {\r\n return `${this.style} ${this.bold ? 'bold' : ''} ${this.size}${this.unit} ${this.family}`;\r\n }\r\n\r\n private _textBounds: BoundingBox = new BoundingBox();\r\n\r\n public get localBounds(): BoundingBox {\r\n return this._textBounds;\r\n }\r\n\r\n protected _drawImage(_ex: ExcaliburGraphicsContext, _x: number, _y: number) {\r\n // TODO weird vestigial drawimage\r\n }\r\n\r\n protected _rotate(ex: ExcaliburGraphicsContext) {\r\n // TODO this needs to change depending on the bounding box...\r\n const origin = this.origin ?? this._textBounds.center;\r\n ex.translate(origin.x, origin.y);\r\n ex.rotate(this.rotation);\r\n ex.translate(-origin.x, -origin.y);\r\n }\r\n\r\n protected _flip(ex: ExcaliburGraphicsContext) {\r\n if (this.flipHorizontal) {\r\n ex.translate(this._textBounds.width / this.scale.x, 0);\r\n ex.scale(-1, 1);\r\n }\r\n\r\n if (this.flipVertical) {\r\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\r\n ex.scale(1, -1);\r\n }\r\n }\r\n\r\n private _textMeasurement = new FontTextInstance(this, '', Color.Black);\r\n\r\n public measureTextWithoutCache(text: string, maxWidth?: number) {\r\n return this._textMeasurement.measureText(text, maxWidth);\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox that is the total size of the text including multiple lines\r\n *\r\n * Does not include any padding or adjustment\r\n * @param text\r\n * @returns BoundingBox\r\n */\r\n public measureText(text: string, maxWidth?: number): BoundingBox {\r\n return FontCache.measureText(text, this, maxWidth);\r\n }\r\n\r\n protected _postDraw(ex: ExcaliburGraphicsContext): void {\r\n ex.restore();\r\n }\r\n\r\n public render(ex: ExcaliburGraphicsContext, text: string, colorOverride: Color, x: number, y: number, maxWidth?: number) {\r\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\r\n\r\n // Apply affine transformations\r\n this._textBounds = textInstance.dimensions;\r\n this._preDraw(ex, x, y);\r\n\r\n textInstance.render(ex, x, y, maxWidth);\r\n\r\n this._postDraw(ex);\r\n }\r\n}\r\n","import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { SpriteFont } from './SpriteFont';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Color } from '../Color';\r\nimport { Font } from './Font';\r\n\r\nexport interface TextOptions {\r\n /**\r\n * Text to draw\r\n */\r\n text: string;\r\n\r\n /**\r\n * Optionally override the font color, currently unsupported by SpriteFont\r\n */\r\n color?: Color;\r\n\r\n /**\r\n * Optionally specify a font, if none specified a default font is used (System sans-serif 10 pixel)\r\n */\r\n font?: Font | SpriteFont;\r\n\r\n /**\r\n * Optionally specify a maximum width in pixels for our text, and wrap to the next line if needed.\r\n */\r\n maxWidth?: number;\r\n}\r\n\r\n/**\r\n * Represent Text graphics in excalibur\r\n *\r\n * Useful for in game labels, ui, or overlays\r\n */\r\nexport class Text extends Graphic {\r\n public color?: Color;\r\n public maxWidth?: number;\r\n constructor(options: TextOptions & GraphicOptions) {\r\n super(options);\r\n // This order is important font, color, then text\r\n this.font = options.font ?? new Font();\r\n this.color = options.color ?? this.color;\r\n this.text = options.text;\r\n this.maxWidth = options.maxWidth;\r\n }\r\n\r\n public clone(): Text {\r\n return new Text({\r\n text: this.text.slice(),\r\n color: this.color?.clone() ?? Color.Black,\r\n font: this.font.clone(),\r\n maxWidth: this.maxWidth\r\n });\r\n }\r\n\r\n private _text: string = '';\r\n public get text() {\r\n return this._text;\r\n }\r\n\r\n public set text(value: string) {\r\n this._text = value;\r\n this._calculateDimension();\r\n }\r\n\r\n private _font: Font | SpriteFont;\r\n public get font(): Font | SpriteFont {\r\n return this._font;\r\n }\r\n public set font(font: Font | SpriteFont) {\r\n this._font = font;\r\n }\r\n\r\n private _textWidth: number = 0;\r\n\r\n public get width() {\r\n if (this._textWidth === 0) {\r\n this._calculateDimension();\r\n }\r\n return this._textWidth * this.scale.x;\r\n }\r\n\r\n private _textHeight: number = 0;\r\n public get height() {\r\n if (this._textHeight === 0) {\r\n this._calculateDimension();\r\n }\r\n return this._textHeight * this.scale.y;\r\n }\r\n\r\n private _calculateDimension() {\r\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\r\n this._textWidth = width;\r\n this._textHeight = height;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\r\n }\r\n\r\n protected override _rotate(_ex: ExcaliburGraphicsContext) {\r\n // None this is delegated to font\r\n // This override erases the default behavior\r\n }\r\n\r\n protected override _flip(_ex: ExcaliburGraphicsContext) {\r\n // None this is delegated to font\r\n // This override erases the default behavior\r\n }\r\n\r\n protected override _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.isStale() || this.font.isStale()) {\r\n this.font.flipHorizontal = this.flipHorizontal;\r\n this.font.flipVertical = this.flipVertical;\r\n this.font.rotation = this.rotation;\r\n this.font.origin = this.origin;\r\n this.font.opacity = this.opacity;\r\n }\r\n this.font.tint = this.tint;\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n protected override _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n let color = Color.Black;\r\n if (this.font instanceof Font) {\r\n color = this.color ?? this.font.color;\r\n }\r\n\r\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\r\n this._textWidth = width;\r\n this._textHeight = height;\r\n\r\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\r\n\r\n if (this.font.showDebug) {\r\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\r\n if (this.maxWidth != null) {\r\n ex.debug.drawRect(x, y, this.maxWidth, this.height, {\r\n color: Color.Yellow\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n KillEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PostCollisionEvent,\r\n PreCollisionEvent,\r\n CollisionStartEvent,\r\n CollisionEndEvent,\r\n PostKillEvent,\r\n PreKillEvent,\r\n EnterViewPortEvent,\r\n ExitViewPortEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n PreDebugDrawEvent,\r\n PostDebugDrawEvent,\r\n ActionStartEvent,\r\n ActionCompleteEvent\r\n} from './Events';\r\nimport { Engine } from './Engine';\r\nimport { Color } from './Color';\r\nimport { CanInitialize, CanUpdate, CanBeKilled } from './Interfaces/LifecycleEvents';\r\nimport { Scene } from './Scene';\r\nimport { Logger } from './Util/Log';\r\nimport { Vector, vec } from './Math/vector';\r\nimport { BodyComponent } from './Collision/BodyComponent';\r\nimport { Eventable } from './Interfaces/Evented';\r\nimport { PointerEvents } from './Interfaces/PointerEventHandlers';\r\nimport { CollisionType } from './Collision/CollisionType';\r\n\r\nimport { Entity, EntityEvents } from './EntityComponentSystem/Entity';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from './EntityComponentSystem/Components/MotionComponent';\r\nimport { GraphicsComponent } from './Graphics/GraphicsComponent';\r\nimport { Rectangle } from './Graphics/Rectangle';\r\nimport { ColliderComponent } from './Collision/ColliderComponent';\r\nimport { Shape } from './Collision/Colliders/Shape';\r\nimport { watch } from './Util/Watch';\r\nimport { Collider, CollisionContact, CollisionGroup, Side } from './Collision/Index';\r\nimport { Circle } from './Graphics/Circle';\r\nimport { PointerEvent } from './Input/PointerEvent';\r\nimport { WheelEvent } from './Input/WheelEvent';\r\nimport { PointerComponent } from './Input/PointerComponent';\r\nimport { ActionsComponent } from './Actions/ActionsComponent';\r\nimport { Raster } from './Graphics/Raster';\r\nimport { Text } from './Graphics/Text';\r\nimport { CoordPlane } from './Math/coord-plane';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { Component } from './EntityComponentSystem';\r\n\r\n/**\r\n * Type guard for checking if something is an Actor\r\n * @param x\r\n */\r\nexport function isActor(x: any): x is Actor {\r\n return x instanceof Actor;\r\n}\r\n\r\n/**\r\n * Actor constructor options\r\n */\r\nexport interface ActorArgs {\r\n /**\r\n * Optionally set the name of the actor, default is 'anonymous'\r\n */\r\n name?: string;\r\n /**\r\n * Optionally set the x position of the actor, default is 0\r\n */\r\n x?: number;\r\n /**\r\n * Optionally set the y position of the actor, default is 0\r\n */\r\n y?: number;\r\n /**\r\n * Optionally set the (x, y) position of the actor as a vector, default is (0, 0)\r\n */\r\n pos?: Vector;\r\n /**\r\n * Optionally set the coordinate plane of the actor, default is [[CoordPlane.World]] meaning actor is subject to camera positioning\r\n */\r\n coordPlane?: CoordPlane;\r\n /**\r\n * Optionally set the width of a box collider for the actor\r\n */\r\n width?: number;\r\n /**\r\n * Optionally set the height of a box collider for the actor\r\n */\r\n height?: number;\r\n /**\r\n * Optionally set the radius of the circle collider for the actor\r\n */\r\n radius?: number;\r\n /**\r\n * Optionally set the velocity of the actor in pixels/sec\r\n */\r\n vel?: Vector;\r\n /**\r\n * Optionally set the acceleration of the actor in pixels/sec^2\r\n */\r\n acc?: Vector;\r\n /**\r\n * Optionally se the rotation in radians (180 degrees = Math.PI radians)\r\n */\r\n rotation?: number;\r\n /**\r\n * Optionally set the angular velocity of the actor in radians/sec (180 degrees = Math.PI radians)\r\n */\r\n angularVelocity?: number;\r\n /**\r\n * Optionally set the scale of the actor's transform\r\n */\r\n scale?: Vector;\r\n /**\r\n * Optionally set the z index of the actor, default is 0\r\n */\r\n z?: number;\r\n /**\r\n * Optionally set the color of an actor, only used if no graphics are present\r\n * If a width/height or a radius was set a default graphic will be added\r\n */\r\n color?: Color;\r\n /**\r\n * Optionally set the color of an actor, only used if no graphics are present\r\n * If a width/height or a radius was set a default graphic will be added\r\n */\r\n opacity?: number;\r\n /**\r\n * Optionally set the visibility of the actor\r\n */\r\n visible?: boolean;\r\n /**\r\n * Optionally set the anchor for graphics in the actor\r\n */\r\n anchor?: Vector;\r\n /**\r\n * Optionally set the anchor for graphics in the actor\r\n */\r\n offset?: Vector;\r\n /**\r\n * Optionally set the collision type\r\n */\r\n collisionType?: CollisionType;\r\n /**\r\n * Optionally supply a collider for an actor, if supplied ignores any supplied width/height\r\n */\r\n collider?: Collider;\r\n /**\r\n * Optionally supply a [[CollisionGroup]]\r\n */\r\n collisionGroup?: CollisionGroup;\r\n}\r\n\r\nexport type ActorEvents = EntityEvents & {\r\n collisionstart: CollisionStartEvent;\r\n collisionend: CollisionEndEvent;\r\n precollision: PreCollisionEvent;\r\n postcollision: PostCollisionEvent;\r\n kill: KillEvent;\r\n prekill: PreKillEvent;\r\n postkill: PostKillEvent;\r\n predraw: PreDrawEvent;\r\n postdraw: PostDrawEvent;\r\n pretransformdraw: PreDrawEvent;\r\n posttransformdraw: PostDrawEvent;\r\n predebugdraw: PreDebugDrawEvent;\r\n postdebugdraw: PostDebugDrawEvent;\r\n pointerup: PointerEvent;\r\n pointerdown: PointerEvent;\r\n pointerenter: PointerEvent;\r\n pointerleave: PointerEvent;\r\n pointermove: PointerEvent;\r\n pointercancel: PointerEvent;\r\n pointerwheel: WheelEvent;\r\n pointerdragstart: PointerEvent;\r\n pointerdragend: PointerEvent;\r\n pointerdragenter: PointerEvent;\r\n pointerdragleave: PointerEvent;\r\n pointerdragmove: PointerEvent;\r\n enterviewport: EnterViewPortEvent;\r\n exitviewport: ExitViewPortEvent;\r\n actionstart: ActionStartEvent;\r\n actioncomplete: ActionCompleteEvent;\r\n}\r\n\r\nexport const ActorEvents = {\r\n CollisionStart: 'collisionstart',\r\n CollisionEnd: 'collisionend',\r\n PreCollision: 'precollision',\r\n PostCollision: 'postcollision',\r\n Kill: 'kill',\r\n PreKill: 'prekill',\r\n PostKill: 'postkill',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw',\r\n PreTransformDraw: 'pretransformdraw',\r\n PostTransformDraw: 'posttransformdraw',\r\n PreDebugDraw: 'predebugdraw',\r\n PostDebugDraw: 'postdebugdraw',\r\n PointerUp: 'pointerup',\r\n PointerDown: 'pointerdown',\r\n PointerEnter: 'pointerenter',\r\n PointerLeave: 'pointerleave',\r\n PointerMove: 'pointermove',\r\n PointerCancel: 'pointercancel',\r\n Wheel: 'pointerwheel',\r\n PointerDrag: 'pointerdragstart',\r\n PointerDragEnd: 'pointerdragend',\r\n PointerDragEnter: 'pointerdragenter',\r\n PointerDragLeave: 'pointerdragleave',\r\n PointerDragMove: 'pointerdragmove',\r\n EnterViewPort: 'enterviewport',\r\n ExitViewPort: 'exitviewport',\r\n ActionStart: 'actionstart',\r\n ActionComplete: 'actioncomplete'\r\n};\r\n\r\n/**\r\n * The most important primitive in Excalibur is an `Actor`. Anything that\r\n * can move on the screen, collide with another `Actor`, respond to events,\r\n * or interact with the current scene, must be an actor. An `Actor` **must**\r\n * be part of a [[Scene]] for it to be drawn to the screen.\r\n */\r\nexport class Actor extends Entity implements Eventable, PointerEvents, CanInitialize, CanUpdate, CanBeKilled {\r\n public events = new EventEmitter();\r\n // #region Properties\r\n\r\n /**\r\n * Set defaults for all Actors\r\n */\r\n public static defaults = {\r\n anchor: Vector.Half\r\n };\r\n\r\n /**\r\n * The physics body the is associated with this actor. The body is the container for all physical properties, like position, velocity,\r\n * acceleration, mass, inertia, etc.\r\n */\r\n public body: BodyComponent;\r\n\r\n /**\r\n * Access the Actor's built in [[TransformComponent]]\r\n */\r\n public transform: TransformComponent;\r\n\r\n /**\r\n * Access the Actor's built in [[MotionComponent]]\r\n */\r\n public motion: MotionComponent;\r\n\r\n /**\r\n * Access to the Actor's built in [[GraphicsComponent]]\r\n */\r\n public graphics: GraphicsComponent;\r\n\r\n /**\r\n * Access to the Actor's built in [[ColliderComponent]]\r\n */\r\n public collider: ColliderComponent;\r\n\r\n /**\r\n * Access to the Actor's built in [[PointerComponent]] config\r\n */\r\n public pointer: PointerComponent;\r\n\r\n /**\r\n * Useful for quickly scripting actor behavior, like moving to a place, patrolling back and forth, blinking, etc.\r\n *\r\n * Access to the Actor's built in [[ActionsComponent]] which forwards to the\r\n * [[ActionContext|Action context]] of the actor.\r\n */\r\n public actions: ActionsComponent;\r\n\r\n /**\r\n * Gets the position vector of the actor in pixels\r\n */\r\n public get pos(): Vector {\r\n return this.transform.pos;\r\n }\r\n\r\n /**\r\n * Sets the position vector of the actor in pixels\r\n */\r\n public set pos(thePos: Vector) {\r\n this.transform.pos = thePos.clone();\r\n }\r\n\r\n /**\r\n * Gets the position vector of the actor from the last frame\r\n */\r\n public get oldPos(): Vector {\r\n return this.body.oldPos;\r\n }\r\n\r\n /**\r\n * Sets the position vector of the actor in the last frame\r\n */\r\n public set oldPos(thePos: Vector) {\r\n this.body.oldPos.setTo(thePos.x, thePos.y);\r\n }\r\n\r\n /**\r\n * Gets the velocity vector of the actor in pixels/sec\r\n */\r\n public get vel(): Vector {\r\n return this.motion.vel;\r\n }\r\n\r\n /**\r\n * Sets the velocity vector of the actor in pixels/sec\r\n */\r\n public set vel(theVel: Vector) {\r\n this.motion.vel = theVel.clone();\r\n }\r\n\r\n /**\r\n * Gets the velocity vector of the actor from the last frame\r\n */\r\n public get oldVel(): Vector {\r\n return this.body.oldVel;\r\n }\r\n\r\n /**\r\n * Sets the velocity vector of the actor from the last frame\r\n */\r\n public set oldVel(theVel: Vector) {\r\n this.body.oldVel.setTo(theVel.x, theVel.y);\r\n }\r\n\r\n /**\r\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\r\n * useful to simulate a gravitational effect.\r\n */\r\n public get acc(): Vector {\r\n return this.motion.acc;\r\n }\r\n\r\n /**\r\n * Sets the acceleration vector of teh actor in pixels/second/second\r\n */\r\n public set acc(theAcc: Vector) {\r\n this.motion.acc = theAcc.clone();\r\n }\r\n\r\n /**\r\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public set oldAcc(theAcc: Vector) {\r\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\r\n }\r\n\r\n /**\r\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public get oldAcc(): Vector {\r\n return this.body.oldAcc;\r\n }\r\n\r\n /**\r\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */\r\n public get rotation(): number {\r\n return this.transform.rotation;\r\n }\r\n\r\n /**\r\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */\r\n public set rotation(theAngle: number) {\r\n this.transform.rotation = theAngle;\r\n }\r\n\r\n /**\r\n * Gets the rotational velocity of the actor in radians/second\r\n */\r\n public get angularVelocity(): number {\r\n return this.motion.angularVelocity;\r\n }\r\n\r\n /**\r\n * Sets the rotational velocity of the actor in radians/sec\r\n */\r\n public set angularVelocity(angularVelocity: number) {\r\n this.motion.angularVelocity = angularVelocity;\r\n }\r\n\r\n public get scale(): Vector {\r\n return this.get(TransformComponent).scale;\r\n }\r\n\r\n public set scale(scale: Vector) {\r\n this.get(TransformComponent).scale = scale;\r\n }\r\n\r\n private _anchor: Vector = watch(Vector.Half, (v) => this._handleAnchorChange(v));\r\n /**\r\n * The anchor to apply all actor related transformations like rotation,\r\n * translation, and scaling. By default the anchor is in the center of\r\n * the actor. By default it is set to the center of the actor (.5, .5)\r\n *\r\n * An anchor of (.5, .5) will ensure that drawings are centered.\r\n *\r\n * Use `anchor.setTo` to set the anchor to a different point using\r\n * values between 0 and 1. For example, anchoring to the top-left would be\r\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\r\n */\r\n public get anchor(): Vector {\r\n return this._anchor;\r\n }\r\n\r\n public set anchor(vec: Vector) {\r\n this._anchor = watch(vec, (v) => this._handleAnchorChange(v));\r\n this._handleAnchorChange(vec);\r\n }\r\n\r\n private _handleAnchorChange(v: Vector) {\r\n if (this.graphics) {\r\n this.graphics.anchor = v;\r\n }\r\n }\r\n\r\n private _offset: Vector = watch(Vector.Zero, (v) => this._handleOffsetChange(v));\r\n /**\r\n * The offset in pixels to apply to all actor graphics\r\n *\r\n * Default offset of (0, 0)\r\n */\r\n public get offset(): Vector {\r\n return this._offset;\r\n }\r\n\r\n public set offset(vec: Vector) {\r\n this._offset = watch(vec, (v) => this._handleOffsetChange(v));\r\n this._handleOffsetChange(vec);\r\n }\r\n\r\n private _handleOffsetChange(v: Vector) {\r\n if (this.graphics) {\r\n this.graphics.offset = v;\r\n }\r\n }\r\n\r\n /**\r\n * Indicates whether the actor is physically in the viewport\r\n */\r\n public get isOffScreen(): boolean {\r\n return this.hasTag('ex.offscreen');\r\n }\r\n\r\n /**\r\n * Convenience reference to the global logger\r\n */\r\n public logger: Logger = Logger.getInstance();\r\n\r\n /**\r\n * Draggable helper\r\n */\r\n private _draggable: boolean = false;\r\n private _dragging: boolean = false;\r\n\r\n private _pointerDragStartHandler = () => {\r\n this._dragging = true;\r\n };\r\n\r\n private _pointerDragEndHandler = () => {\r\n this._dragging = false;\r\n };\r\n\r\n private _pointerDragMoveHandler = (pe: PointerEvent) => {\r\n if (this._dragging) {\r\n this.pos = pe.worldPos;\r\n }\r\n };\r\n\r\n private _pointerDragLeaveHandler = (pe: PointerEvent) => {\r\n if (this._dragging) {\r\n this.pos = pe.worldPos;\r\n }\r\n };\r\n\r\n public get draggable(): boolean {\r\n return this._draggable;\r\n }\r\n\r\n public set draggable(isDraggable: boolean) {\r\n if (isDraggable) {\r\n if (isDraggable && !this._draggable) {\r\n this.events.on('pointerdragstart', this._pointerDragStartHandler);\r\n this.events.on('pointerdragend', this._pointerDragEndHandler);\r\n this.events.on('pointerdragmove', this._pointerDragMoveHandler);\r\n this.events.on('pointerdragleave', this._pointerDragLeaveHandler);\r\n } else if (!isDraggable && this._draggable) {\r\n this.events.off('pointerdragstart', this._pointerDragStartHandler);\r\n this.events.off('pointerdragend', this._pointerDragEndHandler);\r\n this.events.off('pointerdragmove', this._pointerDragMoveHandler);\r\n this.events.off('pointerdragleave', this._pointerDragLeaveHandler);\r\n }\r\n\r\n this._draggable = isDraggable;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the color of the actor's current graphic\r\n */\r\n public get color(): Color {\r\n return this._color;\r\n }\r\n public set color(v: Color) {\r\n this._color = v.clone();\r\n const currentGraphic = this.graphics.current;\r\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) {\r\n currentGraphic.color = this._color;\r\n }\r\n }\r\n private _color: Color;\r\n\r\n // #endregion\r\n\r\n /**\r\n *\r\n * @param config\r\n */\r\n constructor(config?: ActorArgs) {\r\n super();\r\n\r\n const {\r\n name,\r\n x,\r\n y,\r\n pos,\r\n coordPlane,\r\n scale,\r\n width,\r\n height,\r\n radius,\r\n collider,\r\n vel,\r\n acc,\r\n rotation,\r\n angularVelocity,\r\n z,\r\n color,\r\n visible,\r\n opacity,\r\n anchor,\r\n offset,\r\n collisionType,\r\n collisionGroup\r\n } = {\r\n ...config\r\n };\r\n\r\n this.name = name ?? this.name;\r\n this.anchor = anchor ?? Actor.defaults.anchor.clone();\r\n this.offset = offset ?? Vector.Zero;\r\n this.transform = new TransformComponent();\r\n this.addComponent(this.transform);\r\n this.pos = pos ?? vec(x ?? 0, y ?? 0);\r\n this.rotation = rotation ?? 0;\r\n this.scale = scale ?? vec(1, 1);\r\n this.z = z ?? 0;\r\n this.transform.coordPlane = coordPlane ?? CoordPlane.World;\r\n\r\n this.pointer = new PointerComponent;\r\n this.addComponent(this.pointer);\r\n\r\n this.graphics = new GraphicsComponent({\r\n anchor: this.anchor,\r\n offset: this.offset,\r\n opacity: opacity\r\n });\r\n this.addComponent(this.graphics);\r\n\r\n this.motion = new MotionComponent;\r\n this.addComponent(this.motion);\r\n this.vel = vel ?? Vector.Zero;\r\n this.acc = acc ?? Vector.Zero;\r\n this.angularVelocity = angularVelocity ?? 0;\r\n\r\n this.actions = new ActionsComponent;\r\n this.addComponent(this.actions);\r\n\r\n this.body = new BodyComponent;\r\n this.addComponent(this.body);\r\n this.body.collisionType = collisionType ?? CollisionType.Passive;\r\n if (collisionGroup) {\r\n this.body.group = collisionGroup;\r\n }\r\n\r\n if (collider) {\r\n this.collider = new ColliderComponent(collider);\r\n this.addComponent(this.collider);\r\n } else if (radius) {\r\n this.collider = new ColliderComponent(Shape.Circle(radius));\r\n this.addComponent(this.collider);\r\n } else {\r\n if (width > 0 && height > 0) {\r\n this.collider = new ColliderComponent(Shape.Box(width, height, this.anchor));\r\n this.addComponent(this.collider);\r\n } else {\r\n this.collider = new ColliderComponent();\r\n this.addComponent(this.collider); // no collider\r\n }\r\n }\r\n\r\n this.graphics.visible = visible ?? true;\r\n\r\n if (color) {\r\n this.color = color;\r\n if (width && height) {\r\n this.graphics.add(\r\n new Rectangle({\r\n color: color,\r\n width,\r\n height\r\n })\r\n );\r\n } else if (radius) {\r\n this.graphics.add(\r\n new Circle({\r\n color: color,\r\n radius\r\n })\r\n );\r\n }\r\n }\r\n }\r\n\r\n public clone(): Actor {\r\n const clone = new Actor({\r\n color: this.color.clone(),\r\n anchor: this.anchor.clone(),\r\n offset: this.offset.clone()\r\n });\r\n clone.clearComponents();\r\n clone.processComponentRemoval();\r\n\r\n // Clone builtins, order is important, same as ctor\r\n clone.addComponent(clone.transform = this.transform.clone() as TransformComponent, true);\r\n clone.addComponent(clone.pointer = this.pointer.clone() as PointerComponent, true);\r\n clone.addComponent(clone.graphics = this.graphics.clone() as GraphicsComponent, true);\r\n clone.addComponent(clone.motion = this.motion.clone() as MotionComponent, true);\r\n clone.addComponent(clone.actions = this.actions.clone() as ActionsComponent, true);\r\n clone.addComponent(clone.body = this.body.clone() as BodyComponent, true);\r\n clone.addComponent(clone.collider = this.collider.clone() as ColliderComponent, true);\r\n\r\n const builtInComponents: Component[] = [\r\n this.transform,\r\n this.pointer,\r\n this.graphics,\r\n this.motion,\r\n this.actions,\r\n this.body,\r\n this.collider\r\n ];\r\n\r\n // Clone non-builtin the current actors components\r\n const components = this.getComponents();\r\n for (const c of components) {\r\n if (!builtInComponents.includes(c)) {\r\n clone.addComponent(c.clone(), true);\r\n }\r\n }\r\n return clone;\r\n }\r\n\r\n /**\r\n * `onInitialize` is called before the first update of the actor. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */\r\n public onInitialize(engine: Engine): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n * @internal\r\n */\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n for (const child of this.children) {\r\n child._initialize(engine);\r\n }\r\n }\r\n\r\n // #region Events\r\n public emit>(eventName: TEventName, event: ActorEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n // #endregion\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPreKill]] lifecycle event\r\n * @internal\r\n */\r\n public _prekill(scene: Scene) {\r\n this.events.emit('prekill', new PreKillEvent(this));\r\n this.onPreKill(scene);\r\n }\r\n\r\n /**\r\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\r\n *\r\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\r\n */\r\n public onPreKill(scene: Scene) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPostKill]] lifecycle event\r\n * @internal\r\n */\r\n public _postkill(scene: Scene) {\r\n this.events.emit('postkill', new PostKillEvent(this));\r\n this.onPostKill(scene);\r\n }\r\n\r\n /**\r\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\r\n *\r\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\r\n */\r\n public onPostKill(scene: Scene) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * If the current actor is a member of the scene, this will remove\r\n * it from the scene graph. It will no longer be drawn or updated.\r\n */\r\n public kill() {\r\n if (this.scene) {\r\n this._prekill(this.scene);\r\n this.events.emit('kill', new KillEvent(this));\r\n super.kill();\r\n this._postkill(this.scene);\r\n } else {\r\n this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\r\n }\r\n }\r\n\r\n /**\r\n * If the current actor is killed, it will now not be killed.\r\n */\r\n public unkill() {\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Indicates wether the actor has been killed.\r\n */\r\n public isKilled(): boolean {\r\n return !this.active;\r\n }\r\n\r\n /**\r\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n */\r\n public get z(): number {\r\n return this.get(TransformComponent).z;\r\n }\r\n\r\n\r\n /**\r\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\r\n * The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n * @param newZ new z-index to assign\r\n */\r\n public set z(newZ: number) {\r\n this.get(TransformComponent).z = newZ;\r\n }\r\n\r\n /**\r\n * Get the center point of an actor (global position)\r\n */\r\n public get center(): Vector {\r\n const globalPos = this.getGlobalPos();\r\n return new Vector(\r\n globalPos.x + this.width / 2 - this.anchor.x * this.width,\r\n globalPos.y + this.height / 2 - this.anchor.y * this.height);\r\n }\r\n\r\n /**\r\n * Get the local center point of an actor\r\n */\r\n public get localCenter(): Vector {\r\n return new Vector(\r\n this.pos.x + this.width / 2 - this.anchor.x * this.width,\r\n this.pos.y + this.height / 2 - this.anchor.y * this.height);\r\n }\r\n\r\n public get width() {\r\n return this.collider.localBounds.width * this.getGlobalScale().x;\r\n }\r\n\r\n public get height() {\r\n return this.collider.localBounds.height * this.getGlobalScale().y;\r\n }\r\n\r\n /**\r\n * Gets this actor's rotation taking into account any parent relationships\r\n * @returns Rotation angle in radians\r\n */\r\n public getGlobalRotation(): number {\r\n return this.get(TransformComponent).globalRotation;\r\n }\r\n\r\n /**\r\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\r\n * @returns Position in world coordinates\r\n */\r\n public getGlobalPos(): Vector {\r\n return this.get(TransformComponent).globalPos;\r\n }\r\n\r\n /**\r\n * Gets the global scale of the Actor\r\n */\r\n public getGlobalScale(): Vector {\r\n return this.get(TransformComponent).globalScale;\r\n }\r\n\r\n // #region Collision\r\n\r\n /**\r\n * Tests whether the x/y specified are contained in the actor\r\n * @param x X coordinate to test (in world coordinates)\r\n * @param y Y coordinate to test (in world coordinates)\r\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\r\n */\r\n public contains(x: number, y: number, recurse: boolean = false): boolean {\r\n const point = vec(x, y);\r\n const collider = this.get(ColliderComponent);\r\n collider.update();\r\n const geom = collider.get();\r\n if (!geom) {\r\n return false;\r\n }\r\n const containment = geom.contains(point);\r\n\r\n if (recurse) {\r\n return (\r\n containment ||\r\n this.children.some((child: Actor) => {\r\n return child.contains(x, y, true);\r\n })\r\n );\r\n }\r\n\r\n return containment;\r\n }\r\n\r\n /**\r\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\r\n * @param actor Actor to test\r\n * @param distance Distance in pixels to test\r\n */\r\n public within(actor: Actor, distance: number): boolean {\r\n const collider = this.get(ColliderComponent);\r\n const otherCollider = actor.get(ColliderComponent);\r\n const me = collider.get();\r\n const other = otherCollider.get();\r\n if (me && other) {\r\n return me.getClosestLineBetween(other).getLength() <= distance;\r\n }\r\n return false;\r\n }\r\n\r\n // #endregion\r\n\r\n // #region Update\r\n\r\n /**\r\n * Called by the Engine, updates the state of the actor\r\n * @internal\r\n * @param engine The reference to the current game engine\r\n * @param delta The time elapsed since the last update in milliseconds\r\n */\r\n public update(engine: Engine, delta: number) {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an actor is updated.\r\n */\r\n public onPreUpdate(engine: Engine, delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an actor is updated.\r\n */\r\n public onPostUpdate(engine: Engine, delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Fires before every collision resolution for a confirmed contact\r\n * @param self\r\n * @param other\r\n * @param side\r\n * @param contact\r\n */\r\n public onPreCollisionResolve(self: Collider, other: Collider, side: Side, contact: CollisionContact) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Fires after every resolution for a confirmed contact.\r\n * @param self\r\n * @param other\r\n * @param side\r\n * @param contact\r\n */\r\n public onPostCollisionResolve(self: Collider, other: Collider, side: Side, contact: CollisionContact) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Fires once when 2 entities with a ColliderComponent first start colliding or touching, if the Colliders stay in contact this\r\n * does not continue firing until they separate and re-collide.\r\n * @param self\r\n * @param other\r\n * @param side\r\n * @param contact\r\n */\r\n public onCollisionStart(self: Collider, other: Collider, side: Side, contact: CollisionContact) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Fires once when 2 entities with a ColliderComponent separate after having been in contact.\r\n * @param self\r\n * @param other\r\n * @param side\r\n * @param lastContact\r\n */\r\n public onCollisionEnd(self: Collider, other: Collider, side: Side, lastContact: CollisionContact) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n // endregion\r\n}\r\n","import { Vector, vec } from './Math/vector';\r\nimport { Engine } from './Engine';\r\nimport { Actor, ActorArgs } from './Actor';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { CoordPlane } from './Math/coord-plane';\r\n\r\n/**\r\n * Type guard to detect a screen element\r\n */\r\nexport function isScreenElement(actor: Actor) {\r\n return actor instanceof ScreenElement;\r\n}\r\n\r\n/**\r\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\r\n * not participate in collisions. Drawn on top of all other actors.\r\n */\r\nexport class ScreenElement extends Actor {\r\n protected _engine: Engine;\r\n\r\n constructor();\r\n constructor(config?: ActorArgs);\r\n\r\n constructor(config?: ActorArgs) {\r\n super({ ...config });\r\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\r\n this.anchor = config?.anchor ?? vec(0, 0);\r\n this.body.collisionType = config?.collisionType ?? CollisionType.PreventCollision;\r\n this.pointer.useGraphicsBounds = true;\r\n this.pointer.useColliderShape = false;\r\n if (!config?.collider &&\r\n config?.width > 0 &&\r\n config?.height > 0) {\r\n this.collider.useBoxCollider(this.width, this.height, this.anchor);\r\n }\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n this._engine = engine;\r\n super._initialize(engine);\r\n }\r\n\r\n public contains(x: number, y: number, useWorld: boolean = true) {\r\n if (useWorld) {\r\n return super.contains(x, y);\r\n }\r\n\r\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\r\n return super.contains(coords.x, coords.y);\r\n }\r\n}\r\n","import { Scene } from './Scene';\r\nimport { Logger } from './Util/Log';\r\nimport * as ex from './index';\r\nimport { Random } from './Math/Random';\r\n\r\n\r\nexport interface TimerOptions {\r\n repeats?: boolean;\r\n numberOfRepeats?: number;\r\n fcn?: () => void;\r\n interval: number;\r\n randomRange?: [number, number];\r\n random?: ex.Random;\r\n}\r\n\r\n/**\r\n * The Excalibur timer hooks into the internal timer and fires callbacks,\r\n * after a certain interval, optionally repeating.\r\n */\r\nexport class Timer {\r\n private _logger = Logger.getInstance();\r\n private static _MAX_ID: number = 0;\r\n public id: number = 0;\r\n\r\n private _elapsedTime: number = 0;\r\n private _totalTimeAlive: number = 0;\r\n\r\n private _running = false;\r\n\r\n private _numberOfTicks: number = 0;\r\n private _callbacks: Array<() => void>;\r\n\r\n public interval: number = 10;\r\n public repeats: boolean = false;\r\n public maxNumberOfRepeats: number = -1;\r\n public randomRange: [number, number] = [0,0];\r\n public random: ex.Random;\r\n private _baseInterval = 10;\r\n private _generateRandomInterval = () => {\r\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\r\n };\r\n\r\n private _complete = false;\r\n public get complete() {\r\n return this._complete;\r\n }\r\n\r\n public scene: Scene = null;\r\n\r\n /**\r\n * @param options Options - repeats, numberOfRepeats, fcn, interval\r\n * @param repeats Indicates whether this call back should be fired only once, or repeat after every interval as completed.\r\n * @param numberOfRepeats Specifies a maximum number of times that this timer will execute.\r\n * @param fcn The callback to be fired after the interval is complete.\r\n * @param randomRange Indicates a range to select a random number to be added onto the interval\r\n */\r\n constructor(options: TimerOptions);\r\n constructor(fcn: TimerOptions | (() => void), interval?: number,\r\n repeats?: boolean, numberOfRepeats?: number, randomRange?: [number, number], random?: ex.Random) {\r\n if (typeof fcn !== 'function') {\r\n const options = fcn;\r\n fcn = options.fcn;\r\n interval = options.interval;\r\n repeats = options.repeats;\r\n numberOfRepeats = options.numberOfRepeats;\r\n randomRange = options.randomRange;\r\n random= options.random;\r\n }\r\n\r\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\r\n this.maxNumberOfRepeats = numberOfRepeats;\r\n if (!repeats) {\r\n throw new Error('repeats must be set to true if numberOfRepeats is set');\r\n }\r\n }\r\n\r\n this.id = Timer._MAX_ID++;\r\n this._callbacks = [];\r\n this._baseInterval = this.interval = interval;\r\n if (!!randomRange){\r\n if (randomRange[0] > randomRange[1]) {\r\n throw new Error('min value must be lower than max value for range');\r\n }\r\n //We use the instance of ex.Random to generate the range\r\n this.random = random ?? new Random();\r\n this.randomRange = randomRange;\r\n\r\n this.interval = this._generateRandomInterval();\r\n this.on(() => {\r\n this.interval = this._generateRandomInterval();\r\n });\r\n };\r\n this.repeats = repeats || this.repeats;\r\n if (fcn) {\r\n this.on(fcn);\r\n }\r\n }\r\n\r\n /**\r\n * Adds a new callback to be fired after the interval is complete\r\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\r\n */\r\n public on(fcn: () => void) {\r\n this._callbacks.push(fcn);\r\n }\r\n\r\n /**\r\n * Removes a callback from the callback list to be fired after the interval is complete.\r\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\r\n */\r\n public off(fcn: () => void) {\r\n const index = this._callbacks.indexOf(fcn);\r\n this._callbacks.splice(index, 1);\r\n }\r\n /**\r\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\r\n * @param delta Number of elapsed milliseconds since the last update.\r\n */\r\n public update(delta: number) {\r\n if (this._running) {\r\n this._totalTimeAlive += delta;\r\n this._elapsedTime += delta;\r\n\r\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\r\n this._complete = true;\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (!this.complete && this._elapsedTime >= this.interval) {\r\n this._callbacks.forEach((c) => {\r\n c.call(this);\r\n });\r\n this._numberOfTicks++;\r\n if (this.repeats) {\r\n this._elapsedTime = 0;\r\n } else {\r\n this._complete = true;\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\r\n *\r\n * Warning** you may need to call `timer.start()` again if the timer had completed\r\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\r\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\r\n */\r\n public reset(newInterval?: number, newNumberOfRepeats?: number) {\r\n if (!!newInterval && newInterval >= 0) {\r\n this._baseInterval = this.interval= newInterval;\r\n }\r\n\r\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\r\n this.maxNumberOfRepeats = newNumberOfRepeats;\r\n if (!this.repeats) {\r\n throw new Error('repeats must be set to true if numberOfRepeats is set');\r\n }\r\n }\r\n\r\n this._complete = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n }\r\n\r\n public get timesRepeated(): number {\r\n return this._numberOfTicks;\r\n }\r\n\r\n public getTimeRunning(): number {\r\n return this._totalTimeAlive;\r\n }\r\n\r\n /**\r\n * @returns milliseconds until the next action callback, if complete will return 0\r\n */\r\n public get timeToNextAction() {\r\n if (this.complete) {\r\n return 0;\r\n }\r\n return this.interval - this._elapsedTime;\r\n }\r\n\r\n /**\r\n * @returns milliseconds elapsed toward the next action\r\n */\r\n public get timeElapsedTowardNextAction() {\r\n return this._elapsedTime;\r\n }\r\n\r\n public get isRunning() {\r\n return this._running;\r\n }\r\n\r\n /**\r\n * Pauses the timer, time will no longer increment towards the next call\r\n */\r\n public pause(): Timer {\r\n this._running = false;\r\n return this;\r\n }\r\n\r\n /**\r\n * Resumes the timer, time will now increment towards the next call.\r\n */\r\n public resume(): Timer {\r\n this._running = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\r\n */\r\n public start(): Timer {\r\n if (!this.scene) {\r\n this._logger.warn('Cannot start a timer not part of a scene, timer wont start until added');\r\n }\r\n\r\n this._running = true;\r\n if (this.complete) {\r\n this._complete = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Stops the timer and resets the elapsed time counter towards the next action invocation\r\n */\r\n public stop(): Timer {\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n return this;\r\n }\r\n\r\n /**\r\n * Cancels the timer, preventing any further executions.\r\n */\r\n public cancel() {\r\n this.pause();\r\n if (this.scene) {\r\n this.scene.cancelTimer(this);\r\n }\r\n }\r\n}\r\n\r\n","import { Component } from '../EntityComponentSystem/Component';\r\nimport { vec, Vector } from '../Math/vector';\r\n\r\nexport class ParallaxComponent extends Component {\r\n\r\n parallaxFactor = vec(1.0, 1.0);\r\n\r\n constructor(parallaxFactor?: Vector) {\r\n super();\r\n this.parallaxFactor = parallaxFactor ?? this.parallaxFactor;\r\n }\r\n}","import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { DebugConfig } from '../Debug';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\n\r\n\r\n/**\r\n * Provide arbitrary drawing for the purposes of debugging your game\r\n *\r\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\r\n *\r\n */\r\nexport class DebugGraphicsComponent extends Component {\r\n constructor(\r\n public draw: (ctx: ExcaliburGraphicsContext, debugFlags: DebugConfig) => void,\r\n public useTransform = true) {\r\n super();\r\n }\r\n}","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Engine } from '../Engine';\r\nimport { Vector, vec } from '../Math/vector';\r\nimport { Logger } from '../Util/Log';\r\nimport { Entity, EntityEvents } from '../EntityComponentSystem/Entity';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { BodyComponent } from '../Collision/BodyComponent';\r\nimport { CollisionType } from '../Collision/CollisionType';\r\nimport { Shape } from '../Collision/Colliders/Shape';\r\nimport { ExcaliburGraphicsContext, Graphic, GraphicsComponent, hasGraphicsTick, ParallaxComponent } from '../Graphics';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { CompositeCollider } from '../Collision/Colliders/CompositeCollider';\r\nimport { DebugGraphicsComponent } from '../Graphics/DebugGraphicsComponent';\r\nimport { Collider } from '../Collision/Colliders/Collider';\r\nimport { PostDrawEvent, PostUpdateEvent, PreDrawEvent, PreUpdateEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { DebugConfig } from '../Debug';\r\nimport { clamp } from '../Math/util';\r\n\r\nexport interface TileMapOptions {\r\n /**\r\n * Optionally name the tile map\r\n */\r\n name?: string;\r\n /**\r\n * Optionally specify the position of the tile map\r\n */\r\n pos?: Vector;\r\n /**\r\n * Width of an individual tile in pixels\r\n */\r\n tileWidth: number;\r\n /**\r\n * Height of an individual tile in pixels\r\n */\r\n tileHeight: number;\r\n /**\r\n * The number of tile columns, or the number of tiles wide\r\n */\r\n columns: number;\r\n /**\r\n * The number of tile rows, or the number of tiles high\r\n */\r\n rows: number;\r\n\r\n /**\r\n * Optionally render from the top of the graphic, by default tiles are rendered from the bottom\r\n */\r\n renderFromTopOfGraphic?: boolean;\r\n\r\n /**\r\n * Optionally configure the meshing lookbehind for Tilemap, Tilemaps combine solid tiles into optimal\r\n * geometry and the lookbehind configures how far back the Tilemap to look for geometry when combining. Meshing\r\n * is an expensive operation, so when the Tilemap geometry is invalidated it must be recalculated.\r\n *\r\n * Default is 10 slots, but if your Tilemap does not change positions or solid tiles often you can increase this to\r\n * Infinity.\r\n */\r\n meshingLookBehind?: number;\r\n}\r\n\r\nexport type TileMapEvents = EntityEvents & {\r\n preupdate: PreUpdateEvent;\r\n postupdate: PostUpdateEvent;\r\n predraw: PreDrawEvent;\r\n postdraw: PostDrawEvent\r\n}\r\n\r\nexport const TileMapEvents = {\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw'\r\n};\r\n\r\n/**\r\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\r\n *\r\n * TileMaps are useful for top down or side scrolling grid oriented games.\r\n */\r\nexport class TileMap extends Entity {\r\n public events = new EventEmitter();\r\n private _token = 0;\r\n private _engine: Engine;\r\n\r\n public logger: Logger = Logger.getInstance();\r\n public readonly tiles: Tile[] = [];\r\n private _rows: Tile[][] = [];\r\n private _cols: Tile[][] = [];\r\n\r\n public readonly tileWidth: number;\r\n public readonly tileHeight: number;\r\n public readonly rows: number;\r\n public readonly columns: number;\r\n\r\n public renderFromTopOfGraphic = false;\r\n public meshingLookBehind = 10;\r\n\r\n private _collidersDirty = true;\r\n public flagCollidersDirty() {\r\n this._collidersDirty = true;\r\n }\r\n\r\n public flagTilesDirty() {\r\n for (let i = 0; i < this.tiles.length; i++) {\r\n if (this.tiles[i]) {\r\n this.tiles[i].flagDirty();\r\n }\r\n }\r\n }\r\n\r\n public transform: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _graphics: GraphicsComponent;\r\n public collider: ColliderComponent;\r\n private _composite: CompositeCollider;\r\n\r\n public get x(): number {\r\n return this.transform.pos.x ?? 0;\r\n }\r\n\r\n public set x(val: number) {\r\n if (this.transform?.pos) {\r\n this.get(TransformComponent).pos = vec(val, this.y);\r\n }\r\n }\r\n\r\n public get y(): number {\r\n return this.transform?.pos.y ?? 0;\r\n }\r\n\r\n public set y(val: number) {\r\n if (this.transform?.pos) {\r\n this.transform.pos = vec(this.x, val);\r\n }\r\n }\r\n\r\n public get z(): number {\r\n return this.transform.z ?? 0;\r\n }\r\n\r\n public set z(val: number) {\r\n if (this.transform) {\r\n this.transform.z = val;\r\n }\r\n }\r\n\r\n private _oldRotation: number;\r\n public get rotation(): number {\r\n return this.transform?.rotation ?? 0;\r\n }\r\n\r\n public set rotation(val: number) {\r\n if (this.transform) {\r\n this.transform.rotation = val;\r\n }\r\n }\r\n\r\n private _oldScale: Vector;\r\n public get scale(): Vector {\r\n return this.transform?.scale ?? Vector.One;\r\n }\r\n\r\n public set scale(val: Vector) {\r\n if (this.transform?.scale) {\r\n this.transform.scale = val;\r\n }\r\n }\r\n\r\n private _oldPos: Vector;\r\n public get pos(): Vector {\r\n return this.transform.pos;\r\n }\r\n\r\n public set pos(val: Vector) {\r\n this.transform.pos = val;\r\n }\r\n\r\n public get vel(): Vector {\r\n return this._motion.vel;\r\n }\r\n\r\n public set vel(val: Vector) {\r\n this._motion.vel = val;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: TileMapEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n\r\n /**\r\n * @param options\r\n */\r\n constructor(options: TileMapOptions) {\r\n super([], options.name);\r\n this.meshingLookBehind = options.meshingLookBehind ?? this.meshingLookBehind;\r\n this.addComponent(new TransformComponent());\r\n this.addComponent(new MotionComponent());\r\n this.addComponent(\r\n new BodyComponent({\r\n type: CollisionType.Fixed\r\n })\r\n );\r\n this.addComponent(\r\n new GraphicsComponent({\r\n onPostDraw: (ctx, delta) => this.draw(ctx, delta)\r\n })\r\n );\r\n this.addComponent(new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false));\r\n this.addComponent(new ColliderComponent());\r\n this._graphics = this.get(GraphicsComponent);\r\n this.transform = this.get(TransformComponent);\r\n this._motion = this.get(MotionComponent);\r\n this.collider = this.get(ColliderComponent);\r\n this._composite = this.collider.useCompositeCollider([]);\r\n\r\n this.transform.pos = options.pos ?? Vector.Zero;\r\n this._oldPos = this.transform.pos.clone();\r\n this._oldScale = this.transform.scale.clone();\r\n this.renderFromTopOfGraphic = options.renderFromTopOfGraphic ?? this.renderFromTopOfGraphic;\r\n this.tileWidth = options.tileWidth;\r\n this.tileHeight = options.tileHeight;\r\n this.rows = options.rows;\r\n this.columns = options.columns;\r\n\r\n this.tiles = new Array(this.rows * this.columns);\r\n this._rows = new Array(this.rows);\r\n this._cols = new Array(this.columns);\r\n let currentCol: Tile[] = [];\r\n for (let i = 0; i < this.columns; i++) {\r\n for (let j = 0; j < this.rows; j++) {\r\n const tile = new Tile({\r\n x: i,\r\n y: j,\r\n map: this\r\n });\r\n tile.map = this;\r\n this.tiles[i + j * this.columns] = tile;\r\n currentCol.push(tile);\r\n if (!this._rows[j]) {\r\n this._rows[j] = [];\r\n }\r\n this._rows[j].push(tile);\r\n }\r\n this._cols[i] = currentCol;\r\n currentCol = [];\r\n }\r\n\r\n this._graphics.localBounds = new BoundingBox({\r\n left: 0,\r\n top: 0,\r\n right: this.columns * this.tileWidth * this.scale.x,\r\n bottom: this.rows * this.tileHeight * this.scale.y\r\n });\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n this._engine = engine;\r\n }\r\n\r\n\r\n private _originalOffsets = new WeakMap();\r\n private _getOrSetColliderOriginalOffset(collider: Collider): Vector {\r\n if (!this._originalOffsets.has(collider)) {\r\n const originalOffset = collider.offset;\r\n this._originalOffsets.set(collider, originalOffset);\r\n return originalOffset;\r\n } else {\r\n return this._originalOffsets.get(collider);\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Tiles colliders based on the solid tiles in the tilemap.\r\n */\r\n private _updateColliders(): void {\r\n this.collider.$colliderRemoved.notifyAll(this._composite);\r\n this._composite.clearColliders();\r\n const colliders: BoundingBox[] = [];\r\n this._composite = this.collider.useCompositeCollider([]);\r\n let current: BoundingBox;\r\n\r\n /**\r\n * Returns wether or not the 2 boxes share an edge and are the same height\r\n * @param prev\r\n * @param next\r\n * @returns true if they share and edge, false if not\r\n */\r\n const shareEdges = (prev: BoundingBox, next: BoundingBox) => {\r\n if (prev && next) {\r\n // same top/bottom\r\n return prev.top === next.top &&\r\n prev.bottom === next.bottom &&\r\n // Shared right/left edge\r\n prev.right === next.left;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Potentially merges the current collider into a list of previous ones, mutating the list\r\n * If checkAndCombine returns true, the collider was successfully merged and should be thrown away\r\n * @param current current collider to test\r\n * @param colliders List of colliders to consider merging with\r\n * @param maxLookBack The amount of colliders to look back for combination\r\n * @returns false when no combination found, true when successfully combined\r\n */\r\n const checkAndCombine = (current: BoundingBox, colliders: BoundingBox[], maxLookBack = this.meshingLookBehind) => {\r\n if (!current) {\r\n return false;\r\n }\r\n // walk backwards through the list of colliders and combine with the first that shares an edge\r\n for (let i = colliders.length - 1; i >= 0; i--) {\r\n if (maxLookBack-- < 0) {\r\n // blunt the O(n^2) algorithm a bit\r\n return false;\r\n }\r\n const prev = colliders[i];\r\n if (shareEdges(prev, current)) {\r\n colliders[i] = prev.combine(current);\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n\r\n // ? configurable bias perhaps, horizontal strips vs. vertical ones\r\n // Bad tile collider packing algorithm\r\n for (let i = 0; i < this.columns; i++) {\r\n // Scan column for colliders\r\n for (let j = 0; j < this.rows; j++) {\r\n const tile = this.tiles[i + j * this.columns];\r\n // Current tile in column is solid build up current collider\r\n if (tile.solid) {\r\n // Use custom collider otherwise bounding box\r\n if (tile.getColliders().length > 0) {\r\n // tile with custom collider interrupting the current run\r\n for (const collider of tile.getColliders()) {\r\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\r\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n //we push any current collider before nulling the current run\r\n if (current && !checkAndCombine(current, colliders)) {\r\n colliders.push(current);\r\n }\r\n current = null;\r\n // Use the bounding box\r\n } else {\r\n if (!current) {\r\n // no current run, start one\r\n current = tile.defaultGeometry;\r\n } else {\r\n // combine with current run\r\n current = current.combine(tile.defaultGeometry);\r\n }\r\n }\r\n } else {\r\n // Not solid skip and cut off the current collider\r\n // End of run check and combine\r\n if (current && !checkAndCombine(current, colliders)) {\r\n colliders.push(current);\r\n }\r\n current = null;\r\n }\r\n }\r\n // After a column is complete check to see if it can be merged into the last one\r\n // Eno of run check and combine\r\n if (current && !checkAndCombine(current, colliders)) {\r\n // else new collider if no combination\r\n colliders.push(current);\r\n }\r\n current = null;\r\n }\r\n\r\n for (const c of colliders) {\r\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n this.collider.update();\r\n // Notify that colliders have been updated\r\n this.collider.$colliderAdded.notifyAll(this._composite);\r\n }\r\n\r\n /**\r\n * Returns the [[Tile]] by index (row major order)\r\n */\r\n public getTileByIndex(index: number): Tile {\r\n return this.tiles[index];\r\n }\r\n /**\r\n * Returns the [[Tile]] by its x and y integer coordinates\r\n *\r\n * For example, if I want the tile in fifth column (x), and second row (y):\r\n * `getTile(4, 1)` 0 based, so 0 is the first in row/column\r\n */\r\n public getTile(x: number, y: number): Tile {\r\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\r\n return null;\r\n }\r\n return this.tiles[x + y * this.columns];\r\n }\r\n /**\r\n * Returns the [[Tile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */\r\n public getTileByPoint(point: Vector): Tile | null {\r\n const {x, y} = this._getTileCoordinates(point);\r\n const tile = this.getTile(x, y);\r\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) {\r\n return tile;\r\n }\r\n return null;\r\n }\r\n\r\n private _getTileCoordinates(point: Vector): {x: number, y: number} {\r\n // Convert to Tile Space point\r\n point = this.transform.applyInverse(point);\r\n\r\n const x = Math.floor(point.x / this.tileWidth);\r\n const y = Math.floor(point.y / this.tileHeight);\r\n return {x, y};\r\n }\r\n\r\n public getRows(): readonly Tile[][] {\r\n return this._rows;\r\n }\r\n\r\n public getColumns(): readonly Tile[][] {\r\n return this._cols;\r\n }\r\n\r\n /**\r\n * Returns the on screen tiles for a tilemap, this will overshoot by a small amount because of the internal quad tree data structure.\r\n *\r\n * Useful if you need to perform specific logic on onscreen tiles\r\n */\r\n public getOnScreenTiles(): readonly Tile[] {\r\n let worldBounds = this._engine.screen.getWorldBounds();\r\n const maybeParallax = this.get(ParallaxComponent);\r\n if (maybeParallax && this.isInitialized) {\r\n let pos = this.pos;\r\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\r\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\r\n pos = pos.sub(parallaxOffset);\r\n // adjust world bounds by parallax factor\r\n worldBounds = worldBounds.translate(pos);\r\n }\r\n\r\n const bounds = this.transform.coordPlane === CoordPlane.Screen ?\r\n this._engine.screen.getScreenBounds() :\r\n worldBounds;\r\n const topLeft = this._getTileCoordinates(bounds.topLeft);\r\n const topRight = this._getTileCoordinates(bounds.topRight);\r\n const bottomRight = this._getTileCoordinates(bounds.bottomRight);\r\n const bottomLeft = this._getTileCoordinates(bounds.bottomLeft);\r\n\r\n const tileStartX = Math.min(\r\n clamp(topLeft.x, 0, this.columns - 1),\r\n clamp(topRight.x, 0, this.columns - 1)\r\n );\r\n const tileStartY = Math.min(\r\n clamp(topLeft.y, 0, this.rows - 1),\r\n clamp(topRight.y, 0, this.rows - 1)\r\n );\r\n const tileEndX = Math.max(\r\n clamp(bottomRight.x, 0, this.columns - 1),\r\n clamp(bottomLeft.x, 0, this.columns - 1)\r\n );\r\n const tileEndY = Math.max(\r\n clamp(bottomRight.y, 0, this.rows - 1),\r\n clamp(bottomLeft.y, 0, this.rows - 1)\r\n );\r\n\r\n const tiles: Tile[] = [];\r\n for (let x = tileStartX; x <= tileEndX; x++) {\r\n for (let y = tileStartY; y <= tileEndY; y++) {\r\n tiles.push(this.getTile(x, y));\r\n }\r\n }\r\n return tiles;\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n this._initialize(engine);\r\n this.onPreUpdate(engine, delta);\r\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n if (!this._oldPos.equals(this.pos) ||\r\n this._oldRotation !== this.rotation ||\r\n !this._oldScale.equals(this.scale)) {\r\n this.flagCollidersDirty();\r\n this.flagTilesDirty();\r\n }\r\n if (this._collidersDirty) {\r\n this._collidersDirty = false;\r\n this._updateColliders();\r\n }\r\n\r\n this._token++;\r\n\r\n this.pos.clone(this._oldPos);\r\n this._oldRotation = this.rotation;\r\n this.scale.clone(this._oldScale);\r\n this.transform.pos = this.pos;\r\n this.onPostUpdate(engine, delta);\r\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n }\r\n\r\n /**\r\n * Draws the tile map to the screen. Called by the [[Scene]].\r\n * @param ctx ExcaliburGraphicsContext\r\n * @param delta The number of milliseconds since the last draw\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n if (!this.isInitialized) {\n return;\n }\r\n this.emit('predraw', new PreDrawEvent(ctx as any, delta, this)); // TODO fix event\r\n\r\n let graphics: readonly Graphic[], graphicsIndex: number, graphicsLen: number;\r\n\r\n const tiles = this.getOnScreenTiles();\r\n for (let i = 0; i < tiles.length; i++) {\r\n const tile = tiles[i];\r\n // get non-negative tile sprites\r\n const offsets = tile.getGraphicsOffsets();\r\n graphics = tile.getGraphics();\r\n\r\n for (graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++) {\r\n // draw sprite, warning if sprite doesn't exist\r\n const graphic = graphics[graphicsIndex];\r\n const offset = offsets[graphicsIndex];\r\n if (graphic) {\r\n if (hasGraphicsTick(graphic)) {\r\n graphic?.tick(delta, this._token);\r\n }\r\n const offsetY = this.renderFromTopOfGraphic ? 0 : (graphic.height - this.tileHeight);\r\n graphic.draw(ctx, tile.x * this.tileWidth + offset.x, tile.y * this.tileHeight - offsetY + offset.y);\r\n }\r\n }\r\n }\r\n this.emit('postdraw', new PostDrawEvent(ctx as any, delta, this));\r\n }\r\n\r\n public debug(gfx: ExcaliburGraphicsContext, debugFlags: DebugConfig) {\r\n const {\r\n showAll,\r\n showGrid,\r\n gridColor,\r\n gridWidth,\r\n showSolidBounds: showColliderBounds,\r\n solidBoundsColor: colliderBoundsColor,\r\n showColliderGeometry\r\n } = debugFlags.tilemap;\r\n const {\r\n geometryColor,\r\n geometryLineWidth,\r\n geometryPointSize\r\n } = debugFlags.collider;\r\n const width = this.tileWidth * this.columns * this.scale.x;\r\n const height = this.tileHeight * this.rows * this.scale.y;\r\n const pos = this.pos;\r\n if (showGrid || showAll) {\r\n for (let r = 0; r < this.rows + 1; r++) {\r\n const yOffset = vec(0, r * this.tileHeight * this.scale.y);\r\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), gridColor, gridWidth);\r\n }\r\n\r\n for (let c = 0; c < this.columns + 1; c++) {\r\n const xOffset = vec(c * this.tileWidth * this.scale.x, 0);\r\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), gridColor, gridWidth);\r\n }\r\n }\r\n\r\n if (showAll || showColliderBounds || showColliderGeometry) {\r\n const colliders = this._composite.getColliders();\r\n gfx.save();\r\n gfx.translate(this.pos.x, this.pos.y);\r\n gfx.scale(this.scale.x, this.scale.y);\r\n for (const collider of colliders) {\r\n const bounds = collider.localBounds;\r\n const pos = collider.worldPos.sub(this.pos);\r\n if (showColliderBounds) {\r\n gfx.drawRectangle(pos, bounds.width, bounds.height, colliderBoundsColor);\r\n }\r\n }\r\n gfx.restore();\r\n if (showColliderGeometry) {\r\n for (const collider of colliders) {\r\n collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize });\r\n }\r\n }\r\n }\r\n\r\n if (showAll || showColliderBounds) {\r\n gfx.save();\r\n gfx.z = 999;\r\n if (showColliderBounds) {\r\n for (let i = 0; i < this.tiles.length; i++) {\r\n this.tiles[i].bounds.draw(gfx);\r\n }\r\n }\r\n gfx.restore();\r\n }\r\n }\r\n}\r\n\r\nexport interface TileOptions {\r\n /**\r\n * Integer tile x coordinate\r\n */\r\n x: number;\r\n /**\r\n * Integer tile y coordinate\r\n */\r\n y: number;\r\n map: TileMap;\r\n solid?: boolean;\r\n graphics?: Graphic[];\r\n}\r\n\r\n/**\r\n * TileMap Tile\r\n *\r\n * A light-weight object that occupies a space in a collision map. Generally\r\n * created by a [[TileMap]].\r\n *\r\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\r\n * of the sprites in the array so the last one will be drawn on top. You can\r\n * use transparency to create layers this way.\r\n */\r\nexport class Tile extends Entity {\r\n private _bounds: BoundingBox;\r\n private _geometry: BoundingBox;\r\n private _pos: Vector;\r\n private _posDirty = false;\r\n\r\n /**\r\n * Return the world position of the top left corner of the tile\r\n */\r\n public get pos() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n this._posDirty = false;\r\n }\r\n return this._pos;\r\n }\r\n\r\n /**\r\n * Integer x coordinate of the tile\r\n */\r\n public readonly x: number;\r\n\r\n /**\r\n * Integer y coordinate of the tile\r\n */\r\n public readonly y: number;\r\n\r\n private _width: number;\r\n /**\r\n * Width of the tile in pixels\r\n */\r\n public get width(): number {\r\n return this._width;\r\n }\r\n\r\n private _height: number;\r\n /**\r\n * Height of the tile in pixels\r\n */\r\n public get height(): number {\r\n return this._height;\r\n }\r\n\r\n /**\r\n * Reference to the TileMap this tile is associated with\r\n */\r\n public map: TileMap;\r\n\r\n private _solid = false;\r\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */\r\n public get solid(): boolean {\r\n return this._solid;\r\n }\r\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */\r\n public set solid(val: boolean) {\r\n this.map?.flagCollidersDirty();\r\n this._solid = val;\r\n }\r\n\r\n private _graphics: Graphic[] = [];\r\n private _offsets: Vector[] = [];\r\n\r\n /**\r\n * Current list of graphics for this tile\r\n */\r\n public getGraphics(): readonly Graphic[] {\r\n return this._graphics;\r\n }\r\n\r\n /**\r\n * Current list of offsets for this tile's graphics\r\n */\r\n public getGraphicsOffsets(): readonly Vector[] {\r\n return this._offsets;\r\n }\r\n\r\n /**\r\n * Add another [[Graphic]] to this TileMap tile\r\n * @param graphic\r\n */\r\n public addGraphic(graphic: Graphic, options?: { offset?: Vector }) {\r\n this._graphics.push(graphic);\r\n if (options?.offset) {\r\n this._offsets.push(options.offset);\r\n } else {\r\n this._offsets.push(Vector.Zero);\r\n }\r\n }\r\n\r\n /**\r\n * Remove an instance of a [[Graphic]] from this tile\r\n */\r\n public removeGraphic(graphic: Graphic) {\r\n const index = this._graphics.indexOf(graphic);\r\n if (index > -1) {\r\n this._graphics.splice(index, 1);\r\n this._offsets.splice(index, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Clear all graphics from this tile\r\n */\r\n public clearGraphics() {\r\n this._graphics.length = 0;\r\n this._offsets.length = 0;\r\n }\r\n\r\n /**\r\n * Current list of colliders for this tile\r\n */\r\n private _colliders: Collider[] = [];\r\n\r\n /**\r\n * Returns the list of colliders\r\n */\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n /**\r\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\r\n *\r\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */\r\n public addCollider(collider: Collider) {\r\n this._colliders.push(collider);\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Removes a collider from the [[Tile]]\r\n * @param collider\r\n */\r\n public removeCollider(collider: Collider) {\r\n const index = this._colliders.indexOf(collider);\r\n if (index > -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Clears all colliders from the [[Tile]]\r\n */\r\n public clearColliders() {\r\n this._colliders.length = 0;\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Arbitrary data storage per tile, useful for any game specific data\r\n */\r\n public data = new Map();\r\n\r\n constructor(options: TileOptions) {\r\n super();\r\n this.x = options.x;\r\n this.y = options.y;\r\n this.map = options.map;\r\n this._width = options.map.tileWidth * this.map.scale.x;\r\n this._height = options.map.tileHeight * this.map.scale.y;\r\n this.solid = options.solid ?? this.solid;\r\n this._graphics = options.graphics ?? [];\r\n this._recalculate();\r\n }\r\n\r\n public flagDirty() {\r\n return this._posDirty = true;\r\n }\r\n\r\n private _recalculate() {\r\n const geometryPos = this.map.pos.add(vec(this.x * this.map.tileWidth, this.y * this.map.tileHeight));\r\n this._geometry = new BoundingBox(geometryPos.x, geometryPos.y, geometryPos.x + this.map.tileWidth, geometryPos.y + this.map.tileHeight);\r\n\r\n this._width = this.map.tileWidth * this.map.scale.x;\r\n this._height = this.map.tileHeight * this.map.scale.y;\r\n\r\n this._pos = this.map.pos.add(\r\n vec(\r\n this.x * this._width,\r\n this.y * this._height));\r\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\r\n\r\n if (this.map.rotation) {\r\n this._bounds = this._bounds.rotate(this.map.rotation, this.map.pos);\r\n }\r\n this._posDirty = false;\r\n }\r\n\r\n /**\r\n * Tile bounds in world space\r\n */\r\n public get bounds() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n }\r\n return this._bounds;\r\n }\r\n\r\n public get defaultGeometry() {\r\n return this._geometry;\r\n }\r\n\r\n /**\r\n * Tile position in world space\r\n */\r\n public get center(): Vector {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n }\r\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\r\n }\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Screen } from './Screen';\r\nimport { EasingFunction, EasingFunctions } from './Util/EasingFunctions';\r\nimport { Vector, vec } from './Math/vector';\r\nimport { Actor } from './Actor';\r\nimport { removeItemFromArray } from './Util/Util';\r\nimport { CanUpdate, CanInitialize } from './Interfaces/LifecycleEvents';\r\nimport { PreUpdateEvent, PostUpdateEvent, InitializeEvent } from './Events';\r\nimport { BoundingBox } from './Collision/BoundingBox';\r\nimport { Logger } from './Util/Log';\r\nimport { ExcaliburGraphicsContext } from './Graphics/Context/ExcaliburGraphicsContext';\r\nimport { watchAny } from './Util/Watch';\r\nimport { AffineMatrix } from './Math/affine-matrix';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { pixelSnapEpsilon } from './Graphics';\r\nimport { sign } from './Math/util';\r\n\r\n/**\r\n * Interface that describes a custom camera strategy for tracking targets\r\n */\r\nexport interface CameraStrategy {\r\n /**\r\n * Target of the camera strategy that will be passed to the action\r\n */\r\n target: T;\r\n\r\n /**\r\n * Camera strategies perform an action to calculate a new focus returned out of the strategy\r\n * @param target The target object to apply this camera strategy (if any)\r\n * @param camera The current camera implementation in excalibur running the game\r\n * @param engine The current engine running the game\r\n * @param delta The elapsed time in milliseconds since the last frame\r\n */\r\n action: (target: T, camera: Camera, engine: Engine, delta: number) => Vector;\r\n}\r\n\r\n/**\r\n * Container to house convenience strategy methods\r\n * @internal\r\n */\r\nexport class StrategyContainer {\r\n constructor(public camera: Camera) {}\r\n\r\n /**\r\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\r\n * @param actor The actor to lock the camera to\r\n */\r\n public lockToActor(actor: Actor) {\r\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\r\n * @param actor The actor to lock the camera to\r\n * @param axis The axis to follow the actor on\r\n */\r\n public lockToActorAxis(actor: Actor, axis: Axis) {\r\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n * @param actor Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */\r\n public elasticToActor(actor: Actor, cameraElasticity: number, cameraFriction: number) {\r\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\r\n * @param actor Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */\r\n public radiusAroundActor(actor: Actor, radius: number) {\r\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\r\n * @param box The bounding box to limit the camera to.\r\n */\r\n public limitCameraBounds(box: BoundingBox) {\r\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\r\n }\r\n}\r\n\r\n/**\r\n * Camera axis enum\r\n */\r\nexport enum Axis {\r\n X,\r\n Y\r\n}\r\n\r\n/**\r\n * Lock a camera to the exact x/y position of an actor.\r\n */\r\nexport class LockCameraToActorStrategy implements CameraStrategy {\r\n constructor(public target: Actor) {}\r\n public action = (target: Actor, camera: Camera, engine: Engine, delta: number) => {\r\n const center = target.center;\r\n return center;\r\n };\r\n}\r\n\r\n/**\r\n * Lock a camera to a specific axis around an actor.\r\n */\r\nexport class LockCameraToActorAxisStrategy implements CameraStrategy {\r\n constructor(public target: Actor, public axis: Axis) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const center = target.center;\r\n const currentFocus = cam.getFocus();\r\n if (this.axis === Axis.X) {\r\n return new Vector(center.x, currentFocus.y);\r\n } else {\r\n return new Vector(currentFocus.x, center.y);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\r\n */\r\nexport class ElasticToActorStrategy implements CameraStrategy {\r\n /**\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n * @param target Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */\r\n constructor(public target: Actor, public cameraElasticity: number, public cameraFriction: number) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const position = target.center;\r\n let focus = cam.getFocus();\r\n let cameraVel = cam.vel.clone();\r\n\r\n // Calculate the stretch vector, using the spring equation\r\n // F = kX\r\n // https://en.wikipedia.org/wiki/Hooke's_law\r\n // Apply to the current camera velocity\r\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\r\n cameraVel = cameraVel.add(stretch);\r\n\r\n // Calculate the friction (-1 to apply a force in the opposition of motion)\r\n // Apply to the current camera velocity\r\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\r\n cameraVel = cameraVel.add(friction);\r\n\r\n // Update position by velocity deltas\r\n focus = focus.add(cameraVel);\r\n\r\n return focus;\r\n };\r\n}\r\n\r\nexport class RadiusAroundActorStrategy implements CameraStrategy {\r\n /**\r\n *\r\n * @param target Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */\r\n constructor(public target: Actor, public radius: number) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const position = target.center;\r\n const focus = cam.getFocus();\r\n\r\n const direction = position.sub(focus);\r\n const distance = direction.size;\r\n if (distance >= this.radius) {\r\n const offset = distance - this.radius;\r\n return focus.add(direction.normalize().scale(offset));\r\n }\r\n return focus;\r\n };\r\n}\r\n\r\n/**\r\n * Prevent a camera from going beyond the given camera dimensions.\r\n */\r\nexport class LimitCameraBoundsStrategy implements CameraStrategy {\r\n /**\r\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\r\n *\r\n * Note that this strategy does not perform any movement by itself.\r\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\r\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\r\n *\r\n * Make sure that the camera bounds are at least as large as the viewport size.\r\n * @param target The bounding box to limit the camera to\r\n */\r\n\r\n boundSizeChecked: boolean = false; // Check and warn only once\r\n\r\n constructor(public target: BoundingBox) {}\r\n\r\n public action = (target: BoundingBox, cam: Camera, _eng: Engine, _delta: number) => {\r\n const focus = cam.getFocus();\r\n\r\n if (!this.boundSizeChecked) {\r\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) {\r\n Logger.getInstance().warn('Camera bounds should not be smaller than the engine viewport');\r\n }\r\n this.boundSizeChecked = true;\r\n }\r\n\r\n let focusX = focus.x;\r\n let focusY = focus.y;\r\n if (focus.x < target.left + _eng.halfDrawWidth) {\r\n focusX = target.left + _eng.halfDrawWidth;\r\n } else if (focus.x > target.right - _eng.halfDrawWidth) {\r\n focusX = target.right - _eng.halfDrawWidth;\r\n }\r\n\r\n if (focus.y < target.top + _eng.halfDrawHeight) {\r\n focusY = target.top + _eng.halfDrawHeight;\r\n } else if (focus.y > target.bottom - _eng.halfDrawHeight) {\r\n focusY = target.bottom - _eng.halfDrawHeight;\r\n }\r\n\r\n return vec(focusX, focusY);\r\n };\r\n}\r\n\r\nexport type CameraEvents = {\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n initialize: InitializeEvent,\r\n\r\n}\r\n\r\nexport const CameraEvents = {\r\n Initialize: 'initialize',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate'\r\n};\r\n\r\n/**\r\n * Cameras\r\n *\r\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\r\n * to move around your game and set focus. They are used to determine\r\n * what is \"off screen\" and can be used to scale the game.\r\n *\r\n */\r\nexport class Camera implements CanUpdate, CanInitialize {\r\n public events = new EventEmitter();\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public inverse: AffineMatrix = AffineMatrix.identity();\r\n\r\n\r\n protected _follow: Actor;\r\n\r\n private _cameraStrategies: CameraStrategy[] = [];\r\n\r\n public strategy: StrategyContainer = new StrategyContainer(this);\r\n\r\n /**\r\n * Get or set current zoom of the camera, defaults to 1\r\n */\r\n private _z = 1;\r\n public get zoom(): number {\r\n return this._z;\r\n }\r\n\r\n public set zoom(val: number) {\r\n this._z = val;\r\n if (this._engine) {\r\n this._halfWidth = this._engine.halfDrawWidth;\r\n this._halfHeight = this._engine.halfDrawHeight;\r\n }\r\n }\r\n /**\r\n * Get or set rate of change in zoom, defaults to 0\r\n */\r\n public dz: number = 0;\r\n /**\r\n * Get or set zoom acceleration\r\n */\r\n public az: number = 0;\r\n\r\n /**\r\n * Current rotation of the camera\r\n */\r\n public rotation: number = 0;\r\n\r\n private _angularVelocity: number = 0;\r\n\r\n /**\r\n * Get or set the camera's angular velocity\r\n */\r\n public get angularVelocity(): number {\r\n return this._angularVelocity;\r\n }\r\n\r\n public set angularVelocity(value: number) {\r\n this._angularVelocity = value;\r\n }\r\n\r\n /**\r\n * Get or set the camera's position\r\n */\r\n private _posChanged = false;\r\n private _pos: Vector = watchAny(Vector.Zero, () => (this._posChanged = true));\r\n public get pos(): Vector {\r\n return this._pos;\r\n }\r\n public set pos(vec: Vector) {\r\n this._pos = watchAny(vec, () => (this._posChanged = true));\r\n this._posChanged = true;\r\n }\r\n /**\r\n * Interpolated camera position if more draws are running than updates\r\n *\r\n * Enabled when `Engine.fixedUpdateFps` is enabled, in all other cases this will be the same as pos\r\n */\r\n public drawPos: Vector = this.pos.clone();\r\n\r\n private _oldPos = this.pos.clone();\r\n\r\n /**\r\n * Get or set the camera's velocity\r\n */\r\n public vel: Vector = Vector.Zero;\r\n\r\n /**\r\n * Get or set the camera's acceleration\r\n */\r\n public acc: Vector = Vector.Zero;\r\n\r\n private _cameraMoving: boolean = false;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1000; // 1 second\r\n private _lerpStart: Vector = null;\r\n private _lerpEnd: Vector = null;\r\n private _lerpResolve: (value: Vector) => void;\r\n private _lerpPromise: Promise;\r\n\r\n //camera effects\r\n protected _isShaking: boolean = false;\r\n private _shakeMagnitudeX: number = 0;\r\n private _shakeMagnitudeY: number = 0;\r\n private _shakeDuration: number = 0;\r\n private _elapsedShakeTime: number = 0;\r\n private _xShake: number = 0;\r\n private _yShake: number = 0;\r\n\r\n protected _isZooming: boolean = false;\r\n private _zoomStart: number = 1;\r\n private _zoomEnd: number = 1;\r\n private _currentZoomTime: number = 0;\r\n private _zoomDuration: number = 0;\r\n\r\n private _zoomResolve: (val: boolean) => void;\r\n private _zoomPromise: Promise;\r\n private _zoomEasing: EasingFunction = EasingFunctions.EaseInOutCubic;\r\n private _easing: EasingFunction = EasingFunctions.EaseInOutCubic;\r\n\r\n private _halfWidth: number = 0;\r\n private _halfHeight: number = 0;\r\n\r\n /**\r\n * Get the camera's x position\r\n */\r\n public get x() {\r\n return this.pos.x;\r\n }\r\n\r\n /**\r\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\r\n */\r\n public set x(value: number) {\r\n if (!this._follow && !this._cameraMoving) {\r\n this.pos = vec(value, this.pos.y);\r\n }\r\n }\r\n\r\n /**\r\n * Get the camera's y position\r\n */\r\n public get y() {\r\n return this.pos.y;\r\n }\r\n\r\n /**\r\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\r\n */\r\n public set y(value: number) {\r\n if (!this._follow && !this._cameraMoving) {\r\n this.pos = vec(this.pos.x, value);\r\n }\r\n }\r\n\r\n /**\r\n * Get or set the camera's x velocity\r\n */\r\n public get dx() {\r\n return this.vel.x;\r\n }\r\n\r\n public set dx(value: number) {\r\n this.vel = vec(value, this.vel.y);\r\n }\r\n\r\n /**\r\n * Get or set the camera's y velocity\r\n */\r\n public get dy() {\r\n return this.vel.y;\r\n }\r\n\r\n public set dy(value: number) {\r\n this.vel = vec(this.vel.x, value);\r\n }\r\n\r\n /**\r\n * Get or set the camera's x acceleration\r\n */\r\n public get ax() {\r\n return this.acc.x;\r\n }\r\n\r\n public set ax(value: number) {\r\n this.acc = vec(value, this.acc.y);\r\n }\r\n\r\n /**\r\n * Get or set the camera's y acceleration\r\n */\r\n public get ay() {\r\n return this.acc.y;\r\n }\r\n\r\n public set ay(value: number) {\r\n this.acc = vec(this.acc.x, value);\r\n }\r\n\r\n /**\r\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\r\n */\r\n public getFocus() {\r\n return this.pos;\r\n }\r\n\r\n /**\r\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\r\n * @param pos The target position to move to\r\n * @param duration The duration in milliseconds the move should last\r\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\r\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\r\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\r\n */\r\n public move(pos: Vector, duration: number, easingFn: EasingFunction = EasingFunctions.EaseInOutCubic): Promise {\r\n if (typeof easingFn !== 'function') {\r\n throw 'Please specify an EasingFunction';\r\n }\r\n\r\n // cannot move when following an actor\r\n if (this._follow) {\r\n return Promise.reject(pos);\r\n }\r\n\r\n // resolve existing promise, if any\r\n if (this._lerpPromise && this._lerpResolve) {\r\n this._lerpResolve(pos);\r\n }\r\n\r\n this._lerpPromise = new Promise((resolve) => {\r\n this._lerpResolve = resolve;\r\n });\r\n this._lerpStart = this.getFocus().clone();\r\n this._lerpDuration = duration;\r\n this._lerpEnd = pos;\r\n this._currentLerpTime = 0;\r\n this._cameraMoving = true;\r\n this._easing = easingFn;\r\n\r\n return this._lerpPromise;\r\n }\r\n\r\n /**\r\n * Sets the camera to shake at the specified magnitudes for the specified duration\r\n * @param magnitudeX The x magnitude of the shake\r\n * @param magnitudeY The y magnitude of the shake\r\n * @param duration The duration of the shake in milliseconds\r\n */\r\n public shake(magnitudeX: number, magnitudeY: number, duration: number) {\r\n this._isShaking = true;\r\n this._shakeMagnitudeX = magnitudeX;\r\n this._shakeMagnitudeY = magnitudeY;\r\n this._shakeDuration = duration;\r\n }\r\n\r\n /**\r\n * Zooms the camera in or out by the specified scale over the specified duration.\r\n * If no duration is specified, it take effect immediately.\r\n * @param scale The scale of the zoom\r\n * @param duration The duration of the zoom in milliseconds\r\n */\r\n public zoomOverTime(scale: number, duration: number = 0, easingFn: EasingFunction = EasingFunctions.EaseInOutCubic): Promise {\r\n this._zoomPromise = new Promise((resolve) => {\r\n this._zoomResolve = resolve;\r\n });\r\n\r\n if (duration) {\r\n this._isZooming = true;\r\n this._zoomEasing = easingFn;\r\n this._currentZoomTime = 0;\r\n this._zoomDuration = duration;\r\n this._zoomStart = this.zoom;\r\n this._zoomEnd = scale;\r\n } else {\r\n this._isZooming = false;\r\n this.zoom = scale;\r\n return Promise.resolve(true);\r\n }\r\n\r\n return this._zoomPromise;\r\n }\r\n\r\n private _viewport: BoundingBox = null;\r\n /**\r\n * Gets the bounding box of the viewport of this camera in world coordinates\r\n */\r\n public get viewport(): BoundingBox {\r\n if (this._viewport) {\r\n return this._viewport;\r\n }\r\n\r\n return new BoundingBox(0, 0, 0, 0);\r\n }\r\n\r\n /**\r\n * Adds a new camera strategy to this camera\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */\r\n public addStrategy(cameraStrategy: CameraStrategy) {\r\n this._cameraStrategies.push(cameraStrategy);\r\n }\r\n\r\n /**\r\n * Removes a camera strategy by reference\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */\r\n public removeStrategy(cameraStrategy: CameraStrategy) {\r\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\r\n }\r\n\r\n /**\r\n * Clears all camera strategies from the camera\r\n */\r\n public clearAllStrategies() {\r\n this._cameraStrategies.length = 0;\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */\r\n public onPreUpdate(engine: Engine, delta: number): void {\r\n // Overridable\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onPostUpdate(engine: Engine, delta: number): void {\r\n // Overridable\r\n }\r\n\r\n private _engine: Engine;\r\n private _screen: Screen;\r\n private _isInitialized = false;\r\n public get isInitialized() {\r\n return this._isInitialized;\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n this._engine = engine;\r\n this._screen = engine.screen;\r\n\r\n const currentRes = this._screen.contentArea;\r\n let center = vec(currentRes.width / 2, currentRes.height / 2);\r\n if (!this._engine.loadingComplete) {\r\n // If there was a loading screen, we peek the configured resolution\r\n const res = this._screen.peekResolution();\r\n if (res) {\r\n center = vec(res.width / 2, res.height / 2);\r\n }\r\n }\r\n this._halfWidth = center.x;\r\n this._halfHeight = center.y;\r\n\r\n // If the user has not set the camera pos, apply default center screen position\r\n if (!this._posChanged) {\r\n this.pos = center;\r\n }\r\n this.pos.clone(this.drawPos);\r\n // First frame bootstrap\r\n\r\n // Ensure camera tx is correct\r\n // Run update twice to ensure properties are init'd\r\n this.updateTransform(this.pos);\r\n\r\n // Run strategies for first frame\r\n this.runStrategies(engine, engine.clock.elapsed());\r\n\r\n // Setup the first frame viewport\r\n this.updateViewport();\r\n\r\n // It's important to update the camera after strategies\r\n // This prevents jitter\r\n this.updateTransform(this.pos);\r\n this.pos.clone(this._oldPos);\r\n\r\n this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onInitialize(engine: Engine) {\r\n // Overridable\r\n }\r\n\r\n public emit>(eventName: TEventName, event: CameraEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n public runStrategies(engine: Engine, delta: number) {\r\n for (const s of this._cameraStrategies) {\r\n this.pos = s.action.call(s, s.target, this, engine, delta);\r\n }\r\n }\r\n\r\n public updateViewport() {\r\n // recalculate viewport\r\n this._viewport = new BoundingBox(\r\n this.x - this._halfWidth,\r\n this.y - this._halfHeight,\r\n this.x + this._halfWidth,\r\n this.y + this._halfHeight\r\n );\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n this.pos.clone(this._oldPos);\r\n\r\n // Update placements based on linear algebra\r\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\r\n this.zoom += (this.dz * delta) / 1000;\r\n\r\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\r\n this.dz += (this.az * delta) / 1000;\r\n\r\n this.rotation += (this.angularVelocity * delta) / 1000;\r\n\r\n if (this._isZooming) {\r\n if (this._currentZoomTime < this._zoomDuration) {\r\n const zoomEasing = this._zoomEasing;\r\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\r\n\r\n this.zoom = newZoom;\r\n this._currentZoomTime += delta;\r\n } else {\r\n this._isZooming = false;\r\n this.zoom = this._zoomEnd;\r\n this._currentZoomTime = 0;\r\n this._zoomResolve(true);\r\n }\r\n }\r\n\r\n if (this._cameraMoving) {\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\r\n\r\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\r\n\r\n this.pos = lerpPoint;\r\n\r\n this._currentLerpTime += delta;\r\n } else {\r\n this.pos = this._lerpEnd;\r\n const end = this._lerpEnd.clone();\r\n\r\n this._lerpStart = null;\r\n this._lerpEnd = null;\r\n this._currentLerpTime = 0;\r\n this._cameraMoving = false;\r\n // Order matters here, resolve should be last so any chain promises have a clean slate\r\n this._lerpResolve(end);\r\n }\r\n }\r\n\r\n if (this._isDoneShaking()) {\r\n this._isShaking = false;\r\n this._elapsedShakeTime = 0;\r\n this._shakeMagnitudeX = 0;\r\n this._shakeMagnitudeY = 0;\r\n this._shakeDuration = 0;\r\n this._xShake = 0;\r\n this._yShake = 0;\r\n } else {\r\n this._elapsedShakeTime += delta;\r\n this._xShake = ((Math.random() * this._shakeMagnitudeX) | 0) + 1;\r\n this._yShake = ((Math.random() * this._shakeMagnitudeY) | 0) + 1;\r\n }\r\n\r\n this.runStrategies(engine, delta);\r\n\r\n this.updateViewport();\r\n\r\n // It's important to update the camera after strategies\r\n // This prevents jitter\r\n this.updateTransform(this.pos);\r\n\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n private _snapPos = vec(0, 0);\r\n /**\r\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\r\n * @param ctx Canvas context to apply transformations\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext): void {\r\n // default to the current position\r\n this.pos.clone(this.drawPos);\r\n\r\n // interpolation if fixed update is on\r\n // must happen on the draw, because more draws are potentially happening than updates\r\n if (this._engine.fixedUpdateFps) {\r\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\r\n const interpolatedPos = this.pos.scale(blend).add(\r\n this._oldPos.scale(1.0 - blend)\r\n );\r\n interpolatedPos.clone(this.drawPos);\r\n this.updateTransform(interpolatedPos);\r\n }\r\n // Snap camera to pixel\r\n if (ctx.snapToPixel) {\r\n const snapPos = this.drawPos.clone(this._snapPos);\r\n snapPos.x = ~~(snapPos.x + pixelSnapEpsilon * sign(snapPos.x));\r\n snapPos.y = ~~(snapPos.y + pixelSnapEpsilon * sign(snapPos.y));\r\n snapPos.clone(this.drawPos);\r\n this.updateTransform(snapPos);\r\n }\r\n ctx.multiply(this.transform);\r\n }\r\n\r\n public updateTransform(pos: Vector) {\r\n // center the camera\r\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\r\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\r\n const cameraPos = vec(-pos.x + newCanvasWidth / 2 + this._xShake, -pos.y + newCanvasHeight / 2 + this._yShake);\r\n\r\n // Calculate camera transform\r\n this.transform.reset();\r\n\r\n this.transform.scale(this.zoom, this.zoom);\r\n\r\n // rotate about the focus\r\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\r\n this.transform.rotate(this.rotation);\r\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\r\n\r\n this.transform.translate(cameraPos.x, cameraPos.y);\r\n this.transform.inverse(this.inverse);\r\n }\r\n\r\n private _isDoneShaking(): boolean {\r\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\r\n }\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Vector } from './Math/vector';\r\nimport { ExitTriggerEvent, EnterTriggerEvent, CollisionEndEvent, CollisionStartEvent } from './Events';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { Entity } from './EntityComponentSystem';\r\nimport { Actor, ActorEvents } from './Actor';\r\nimport { EventEmitter } from './EventEmitter';\r\n\r\nexport type TriggerEvents = ActorEvents & {\r\n exit: ExitTriggerEvent,\r\n enter: EnterTriggerEvent\r\n}\r\n\r\nexport const TriggerEvents = {\r\n ExitTrigger: 'exit',\r\n EnterTrigger: 'enter'\r\n};\r\n\r\n/**\r\n * TriggerOptions\r\n */\r\nexport interface TriggerOptions {\r\n // position of the trigger\r\n pos: Vector;\r\n // width of the trigger\r\n width: number;\r\n // height of the trigger\r\n height: number;\r\n // whether the trigger is visible or not\r\n visible: boolean;\r\n // action to take when triggered\r\n action: () => void;\r\n // if specified the trigger will only fire on a specific actor and overrides any filter\r\n target: Entity;\r\n // Returns true if the triggers should fire on the collided actor\r\n filter: (actor: Entity) => boolean;\r\n // -1 if it should repeat forever\r\n repeat: number;\r\n}\r\n\r\nconst triggerDefaults: Partial = {\r\n pos: Vector.Zero,\r\n width: 10,\r\n height: 10,\r\n visible: false,\r\n action: () => {\r\n return;\r\n },\r\n filter: () => true,\r\n repeat: -1\r\n};\r\n\r\n/**\r\n * Triggers are a method of firing arbitrary code on collision. These are useful\r\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\r\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\r\n */\r\nexport class Trigger extends Actor {\r\n public events = new EventEmitter();\r\n private _target: Entity;\r\n /**\r\n * Action to fire when triggered by collision\r\n */\r\n public action: () => void = () => {\r\n return;\r\n };\r\n /**\r\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\r\n * filter return true for the collided actor.\r\n */\r\n public filter: (actor: Entity) => boolean = () => true;\r\n /**\r\n * Number of times to repeat before killing the trigger,\r\n */\r\n public repeat: number = -1;\r\n\r\n /**\r\n *\r\n * @param opts Trigger options\r\n */\r\n constructor(opts: Partial) {\r\n super({ x: opts.pos.x, y: opts.pos.y, width: opts.width, height: opts.height });\r\n opts = {\r\n ...triggerDefaults,\r\n ...opts\r\n };\r\n\r\n this.filter = opts.filter || this.filter;\r\n this.repeat = opts.repeat || this.repeat;\r\n this.action = opts.action || this.action;\r\n if (opts.target) {\r\n this.target = opts.target;\r\n }\r\n\r\n this.graphics.visible = opts.visible;\r\n this.body.collisionType = CollisionType.Passive;\r\n\r\n this.events.on('collisionstart', (evt: CollisionStartEvent) => {\r\n if (this.filter(evt.other)) {\r\n this.events.emit('enter', new EnterTriggerEvent(this, evt.other));\r\n this._dispatchAction();\r\n // remove trigger if its done, -1 repeat forever\r\n if (this.repeat === 0) {\r\n this.kill();\r\n }\r\n }\r\n });\r\n\r\n this.events.on('collisionend', (evt: CollisionEndEvent) => {\r\n if (this.filter(evt.other)) {\r\n this.events.emit('exit', new ExitTriggerEvent(this, evt.other));\r\n }\r\n });\r\n }\r\n\r\n public set target(target: Entity) {\r\n this._target = target;\r\n this.filter = (actor: Entity) => actor === target;\r\n }\r\n\r\n public get target() {\r\n return this._target;\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n }\r\n\r\n private _dispatchAction() {\r\n if (this.repeat !== 0) {\r\n this.action.call(this);\r\n this.repeat--;\r\n }\r\n }\r\n}\r\n","/**\r\n * Higher priorities run earlier than others in the system update\r\n */\r\nexport const SystemPriority = {\r\n Highest: -Infinity,\r\n Higher: -5,\r\n Average: 0,\r\n Lower: 5,\r\n Lowest: Infinity\r\n} as const;","import { Scene } from '../Scene';\r\nimport { SystemPriority } from './Priority';\r\nimport { World } from './World';\r\n\r\n/**\r\n * Enum that determines whether to run the system in the update or draw phase\r\n */\r\nexport enum SystemType {\r\n Update = 'update',\r\n Draw = 'draw'\r\n}\r\n\r\n/**\r\n * An Excalibur [[System]] that updates entities of certain types.\r\n * Systems are scene specific\r\n *\r\n *\r\n *\r\n * Excalibur Systems currently require at least 1 Component type to operated\r\n *\r\n * Multiple types are declared as a type union\r\n * For example:\r\n *\r\n * ```typescript\r\n * class MySystem extends System {\r\n * public readonly types = ['a', 'b'] as const;\r\n * public readonly systemType = SystemType.Update;\r\n * public update(entities: Entity) {\r\n * ...\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport abstract class System {\r\n\r\n /**\r\n * Determine whether the system is called in the [[SystemType.Update]] or the [[SystemType.Draw]] phase. Update is first, then Draw.\r\n */\r\n abstract readonly systemType: SystemType;\r\n\r\n /**\r\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\r\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\r\n * For a system to execute after all other a higher priority value (10 for example) must be set.\r\n */\r\n public priority: number = SystemPriority.Average;\r\n\r\n /**\r\n * Optionally specify an initialize handler\r\n * @param scene\r\n */\r\n initialize?(world: World, scene: Scene): void;\r\n\r\n /**\r\n * Update all entities that match this system's types\r\n * @param entities Entities to update that match this system's types\r\n * @param elapsedMs Time in milliseconds\r\n */\r\n abstract update(elapsedMs: number): void;\r\n\r\n /**\r\n * Optionally run a preupdate before the system processes matching entities\r\n * @param scene\r\n * @param elapsedMs Time in milliseconds since the last frame\r\n */\r\n preupdate?(scene: Scene, elapsedMs: number): void;\r\n\r\n /**\r\n * Optionally run a postupdate after the system processes matching entities\r\n * @param scene\r\n * @param elapsedMs Time in milliseconds since the last frame\r\n */\r\n postupdate?(scene: Scene, elapsedMs: number): void;\r\n}\r\n","import { Entity } from './Entity';\r\nimport { World } from './World';\r\nimport { removeItemFromArray } from '../Util/Util';\r\nimport { Scene } from '../Scene';\r\n\r\n// Add/Remove entities and components\r\n\r\nexport class EntityManager {\r\n public entities: Entity[] = [];\r\n public _entityIndex: { [entityId: string]: Entity } = {};\r\n\r\n constructor(private _world: World) {}\r\n\r\n /**\r\n * Runs the entity lifecycle\r\n * @param scene\r\n * @param elapsed\r\n */\r\n public updateEntities(scene: Scene, elapsed: number) {\r\n for (const entity of this.entities) {\r\n entity.update(scene.engine, elapsed);\r\n if (!entity.active) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n }\r\n\r\n public findEntitiesForRemoval() {\r\n for (const entity of this.entities) {\r\n if (!entity.active) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Adds an entity to be tracked by the EntityManager\r\n * @param entity\r\n */\r\n public addEntity(entity: Entity): void {\r\n entity.active = true;\r\n entity.scene = this._world.scene;\r\n if (entity && !this._entityIndex[entity.id]) {\r\n this._entityIndex[entity.id] = entity;\r\n this.entities.push(entity);\r\n this._world.queryManager.addEntity(entity);\r\n\r\n // if entity has children\r\n entity.children.forEach((c) => {\r\n c.scene = entity.scene;\r\n this.addEntity(c);\r\n });\r\n entity.childrenAdded$.register({\r\n notify: (e) => {\r\n this.addEntity(e);\r\n }\r\n });\r\n entity.childrenRemoved$.register({\r\n notify: (e) => {\r\n this.removeEntity(e, false);\r\n }\r\n });\r\n }\r\n }\r\n\r\n public removeEntity(entity: Entity, deferred?: boolean): void;\r\n public removeEntity(id: number, deferred?: boolean): void;\r\n public removeEntity(idOrEntity: number | Entity, deferred = true): void {\r\n let id = 0;\r\n if (idOrEntity instanceof Entity) {\r\n id = idOrEntity.id;\r\n } else {\r\n id = idOrEntity;\r\n }\r\n const entity = this._entityIndex[id];\r\n if (entity && entity.active) {\r\n entity.active = false;\r\n }\r\n\r\n if (entity && deferred) {\r\n this._entitiesToRemove.push(entity);\r\n return;\r\n }\r\n\r\n delete this._entityIndex[id];\r\n if (entity) {\r\n entity.scene = null;\r\n removeItemFromArray(entity, this.entities);\r\n this._world.queryManager.removeEntity(entity);\r\n\r\n // if entity has children\r\n entity.children.forEach((c) => {\r\n c.scene = null;\r\n this.removeEntity(c, deferred);\r\n });\r\n entity.childrenAdded$.clear();\r\n entity.childrenRemoved$.clear();\r\n\r\n // stats\r\n if (this._world?.scene?.engine) {\r\n this._world.scene.engine.stats.currFrame.actors.killed++;\r\n }\r\n }\r\n }\r\n\r\n private _entitiesToRemove: Entity[] = [];\r\n public processEntityRemovals(): void {\r\n for (const entity of this._entitiesToRemove) {\r\n if (entity.active) {\r\n continue;\r\n }\r\n this.removeEntity(entity, false);\r\n }\r\n this._entitiesToRemove.length = 0;\r\n }\r\n\r\n public processComponentRemovals(): void {\r\n for (const entity of this.entities) {\r\n entity.processComponentRemoval();\r\n }\r\n }\r\n\r\n public getById(id: number): Entity {\r\n return this._entityIndex[id];\r\n }\r\n\r\n public getByName(name: string): Entity[]{\r\n return this.entities.filter(e => e.name === name);\r\n }\r\n\r\n public clear(): void {\r\n for (let i = this.entities.length - 1; i >= 0; i--) {\r\n this.removeEntity(this.entities[i]);\r\n }\r\n }\r\n}\r\n","import { Entity } from './Entity';\r\nimport { Observable } from '../Util/Observable';\r\nimport { Component, ComponentCtor } from '../EntityComponentSystem/Component';\r\n\r\nexport type ComponentInstance = T extends ComponentCtor ? R : never;\r\n\r\n/**\r\n * Represents query for entities that match a list of types that is cached and observable\r\n *\r\n * Queries can be strongly typed by supplying a type union in the optional type parameter\r\n * ```typescript\r\n * const queryAB = new ex.Query(['A', 'B']);\r\n * ```\r\n */\r\nexport class Query = never> {\r\n public readonly id: string;\r\n public components = new Set();\r\n public entities: Entity>[] = [];\r\n /**\r\n * This fires right after the component is added\r\n */\r\n public entityAdded$ = new Observable>>();\r\n /**\r\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\r\n */\r\n public entityRemoved$ = new Observable>>();\r\n\r\n constructor(public readonly requiredComponents: TKnownComponentCtors[]) {\r\n if (requiredComponents.length === 0) {\r\n throw new Error('Cannot create query without components');\r\n }\r\n for (const type of requiredComponents) {\r\n this.components.add(type);\r\n }\r\n\r\n this.id = Query.createId(requiredComponents);\r\n }\r\n\r\n static createId(requiredComponents: Function[]) {\r\n // TODO what happens if a user defines the same type name as a built in type\r\n // ! TODO this could be dangerous depending on the bundler's settings for names\r\n // Maybe some kind of hash function is better here?\r\n return requiredComponents.slice().map(c => c.name).sort().join('-');\r\n }\r\n\r\n /**\r\n * Potentially adds an entity to a query index, returns true if added, false if not\r\n * @param entity\r\n */\r\n checkAndAdd(entity: Entity) {\r\n if (!this.entities.includes(entity) && entity.hasAll(Array.from(this.components))) {\r\n this.entities.push(entity);\r\n this.entityAdded$.notifyAll(entity);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n removeEntity(entity: Entity) {\r\n const index = this.entities.indexOf(entity);\r\n if (index > -1) {\r\n this.entities.splice(index, 1);\r\n this.entityRemoved$.notifyAll(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a list of entities that match the query\r\n * @param sort Optional sorting function to sort entities returned from the query\r\n */\r\n public getEntities(sort?: (a: Entity, b: Entity) => number): Entity>[] {\r\n if (sort) {\r\n this.entities.sort(sort);\r\n }\r\n return this.entities;\r\n }\r\n}","import { Observable } from '../Util/Observable';\r\nimport { Entity } from './Entity';\r\n\r\n\r\nexport class TagQuery {\r\n public readonly id: string;\r\n public tags = new Set();\r\n public entities: Entity[] = [];\r\n /**\r\n * This fires right after the component is added\r\n */\r\n public entityAdded$ = new Observable>();\r\n /**\r\n * This fires right before the component is actually removed from the entity, it will still be available for cleanup purposes\r\n */\r\n public entityRemoved$ = new Observable>();\r\n\r\n constructor(public readonly requiredTags: TKnownTags[]) {\r\n if (requiredTags.length === 0) {\r\n throw new Error('Cannot create tag query without tags');\r\n }\r\n for (const tag of requiredTags) {\r\n this.tags.add(tag);\r\n }\r\n\r\n this.id = TagQuery.createId(requiredTags);\r\n }\r\n\r\n static createId(requiredComponents: string[]) {\r\n return requiredComponents.slice().sort().join('-');\r\n }\r\n\r\n checkAndAdd(entity: Entity) {\r\n if (!this.entities.includes(entity) && entity.hasAllTags(Array.from(this.tags))) {\r\n this.entities.push(entity);\r\n this.entityAdded$.notifyAll(entity);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n removeEntity(entity: Entity) {\r\n const index = this.entities.indexOf(entity);\r\n if (index > -1) {\r\n this.entities.splice(index, 1);\r\n this.entityRemoved$.notifyAll(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a list of entities that match the query\r\n * @param sort Optional sorting function to sort entities returned from the query\r\n */\r\n public getEntities(sort?: (a: Entity, b: Entity) => number): Entity[] {\r\n if (sort) {\r\n this.entities.sort(sort);\r\n }\r\n return this.entities;\r\n }\r\n}","import { Entity } from './Entity';\r\nimport { Query } from './Query';\r\nimport { Component, ComponentCtor } from './Component';\r\nimport { World } from './World';\r\nimport { TagQuery } from './TagQuery';\r\n\r\n/**\r\n * The query manager is responsible for updating all queries when entities/components change\r\n */\r\nexport class QueryManager {\r\n private _queries = new Map>();\r\n private _addComponentHandlers = new Map any>();\r\n private _removeComponentHandlers = new Map any>();\r\n private _componentToQueriesIndex = new Map, Query[]>();\r\n\r\n private _tagQueries = new Map>();\r\n private _addTagHandlers = new Map any>();\r\n private _removeTagHandlers = new Map any>();\r\n private _tagToQueriesIndex = new Map[]>();\r\n\r\n constructor(private _world: World) {}\r\n\r\n public createQuery>(\r\n requiredComponents: TKnownComponentCtors[]): Query {\r\n const id = Query.createId(requiredComponents);\r\n if (this._queries.has(id)) {\r\n // short circuit if query is already created\r\n return this._queries.get(id) as Query;\r\n }\r\n\r\n const query = new Query(requiredComponents);\r\n\r\n this._queries.set(query.id, query);\r\n\r\n // index maintenance\r\n for (const component of requiredComponents) {\r\n const queries = this._componentToQueriesIndex.get(component);\r\n if (!queries) {\r\n this._componentToQueriesIndex.set(component, [query]);\r\n } else {\r\n queries.push(query);\r\n }\r\n }\r\n\r\n for (const entity of this._world.entities) {\r\n this.addEntity(entity);\r\n }\r\n\r\n return query;\r\n }\r\n\r\n public createTagQuery(requiredTags: TKnownTags[]): TagQuery {\r\n const id = TagQuery.createId(requiredTags);\r\n if (this._tagQueries.has(id)) {\r\n // short circuit if query is already created\r\n return this._tagQueries.get(id) as TagQuery;\r\n }\r\n\r\n const query = new TagQuery(requiredTags);\r\n\r\n this._tagQueries.set(query.id, query);\r\n\r\n // index maintenance\r\n for (const tag of requiredTags) {\r\n const queries = this._tagToQueriesIndex.get(tag);\r\n if (!queries) {\r\n this._tagToQueriesIndex.set(tag, [query]);\r\n } else {\r\n queries.push(query);\r\n }\r\n }\r\n\r\n for (const entity of this._world.entities) {\r\n this.addEntity(entity);\r\n }\r\n\r\n return query;\r\n }\r\n\r\n private _createAddComponentHandler = (entity: Entity) => (c: Component) => {\r\n this.addComponent(entity, c);\r\n };\r\n\r\n private _createRemoveComponentHandler = (entity: Entity) => (c: Component) => {\r\n this.removeComponent(entity, c);\r\n };\r\n\r\n private _createAddTagHandler = (entity: Entity) => (tag: string) => {\r\n this.addTag(entity, tag);\r\n };\r\n\r\n private _createRemoveTagHandler = (entity: Entity) => (tag: string) => {\r\n this.removeTag(entity, tag);\r\n };\r\n\r\n /**\r\n * Scans queries and locates any that need this entity added\r\n * @param entity\r\n */\r\n addEntity(entity: Entity) {\r\n const maybeAddComponent = this._addComponentHandlers.get(entity);\r\n const maybeRemoveComponent = this._removeComponentHandlers.get(entity);\r\n const addComponent = maybeAddComponent ?? this._createAddComponentHandler(entity);\r\n const removeComponent = maybeRemoveComponent ?? this._createRemoveComponentHandler(entity);\r\n this._addComponentHandlers.set(entity, addComponent);\r\n this._removeComponentHandlers.set(entity, removeComponent);\r\n\r\n const maybeAddTag = this._addTagHandlers.get(entity);\r\n const maybeRemoveTag = this._removeTagHandlers.get(entity);\r\n const addTag = maybeAddTag ?? this._createAddTagHandler(entity);\r\n const removeTag = maybeRemoveTag ?? this._createRemoveTagHandler(entity);\r\n this._addTagHandlers.set(entity, addTag);\r\n this._removeTagHandlers.set(entity, removeTag);\r\n\r\n for (const query of this._queries.values()) {\r\n query.checkAndAdd(entity);\r\n }\r\n for (const tagQuery of this._tagQueries.values()) {\r\n tagQuery.checkAndAdd(entity);\r\n }\r\n entity.componentAdded$.subscribe(addComponent);\r\n entity.componentRemoved$.subscribe(removeComponent);\r\n entity.tagAdded$.subscribe(addTag);\r\n entity.tagRemoved$.subscribe(removeTag);\r\n }\r\n\r\n /**\r\n * Scans queries and locates any that need this entity removed\r\n * @param entity\r\n */\r\n removeEntity(entity: Entity) {\r\n // Handle components\r\n const addComponent = this._addComponentHandlers.get(entity);\r\n const removeComponent = this._removeComponentHandlers.get(entity);\r\n for (const query of this._queries.values()) {\r\n query.removeEntity(entity);\r\n }\r\n if (addComponent) {\r\n entity.componentAdded$.unsubscribe(addComponent);\r\n }\r\n if (removeComponent) {\r\n entity.componentRemoved$.unsubscribe(removeComponent);\r\n }\r\n\r\n // Handle tags\r\n const addTag = this._addTagHandlers.get(entity);\r\n const removeTag = this._removeTagHandlers.get(entity);\r\n for (const tagQuery of this._tagQueries.values()) {\r\n tagQuery.removeEntity(entity);\r\n }\r\n\r\n if (addTag) {\r\n entity.tagAdded$.unsubscribe(addTag);\r\n }\r\n if (removeTag) {\r\n entity.tagRemoved$.unsubscribe(removeTag);\r\n }\r\n }\r\n\r\n /**\r\n * Updates any queries when a component is added to an entity\r\n * @param entity\r\n * @param component\r\n */\r\n addComponent(entity: Entity, component: Component) {\r\n const queries = this._componentToQueriesIndex.get(component.constructor as ComponentCtor) ?? [];\r\n for (const query of queries) {\r\n query.checkAndAdd(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Updates any queries when a component is removed from an entity\r\n * @param entity\r\n * @param component\r\n */\r\n removeComponent(entity: Entity, component: Component) {\r\n const queries = this._componentToQueriesIndex.get(component.constructor as ComponentCtor) ?? [];\r\n for (const query of queries) {\r\n query.removeEntity(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Updates any queries when a tag is added to an entity\r\n * @param entity\r\n * @param tag\r\n */\r\n addTag(entity: Entity, tag: string) {\r\n const queries = this._tagToQueriesIndex.get(tag) ?? [];\r\n for (const query of queries) {\r\n query.checkAndAdd(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Updates any queries when a component is removed from an entity\r\n * @param entity\r\n * @param tag\r\n */\r\n removeTag(entity: Entity, tag: string) {\r\n const queries = this._tagToQueriesIndex.get(tag) ?? [];\r\n for (const query of queries) {\r\n query.removeEntity(entity);\r\n }\r\n }\r\n\r\n\r\n}\r\n","import { System, SystemType } from './System';\r\nimport { Scene } from '../Scene';\r\nimport { World } from './World';\r\nimport { removeItemFromArray } from '../Util/Util';\r\n\r\nexport interface SystemCtor {\r\n new (...args: any[]): T;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function isSystemConstructor(x: any): x is SystemCtor {\r\n return !!x?.prototype && !!x?.prototype?.constructor?.name;\r\n}\r\n\r\n/**\r\n * The SystemManager is responsible for keeping track of all systems in a scene.\r\n * Systems are scene specific\r\n */\r\nexport class SystemManager {\r\n /**\r\n * List of systems, to add a new system call [[SystemManager.addSystem]]\r\n */\r\n public systems: System[] = [];\r\n public initialized = false;\r\n constructor(private _world: World) {}\r\n\r\n /**\r\n * Get a system registered in the manager by type\r\n * @param systemType\r\n */\r\n public get(systemType: SystemCtor): T | null {\r\n return this.systems.find((s) => s instanceof systemType) as unknown as T;\r\n }\r\n\r\n /**\r\n * Adds a system to the manager, it will now be updated every frame\r\n * @param systemOrCtor\r\n */\r\n public addSystem(systemOrCtor: SystemCtor | System): void {\r\n let system: System;\r\n if (systemOrCtor instanceof System) {\r\n system = systemOrCtor;\r\n } else {\r\n system = new systemOrCtor(this._world);\r\n }\r\n\r\n this.systems.push(system);\r\n this.systems.sort((a, b) => a.priority - b.priority);\r\n // If systems are added and the manager has already been init'd\r\n // then immediately init the system\r\n if (this.initialized && system.initialize) {\r\n system.initialize(this._world, this._world.scene);\r\n }\r\n }\r\n\r\n /**\r\n * Removes a system from the manager, it will no longer be updated\r\n * @param system\r\n */\r\n public removeSystem(system: System) {\r\n removeItemFromArray(system, this.systems);\r\n }\r\n\r\n /**\r\n * Initialize all systems in the manager\r\n *\r\n * Systems added after initialize() will be initialized on add\r\n */\r\n public initialize() {\r\n if (!this.initialized) {\r\n this.initialized = true;\r\n for (const s of this.systems) {\r\n if (s.initialize) {\r\n s.initialize(this._world, this._world.scene);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates all systems\r\n * @param type whether this is an update or draw system\r\n * @param scene context reference\r\n * @param delta time in milliseconds\r\n */\r\n public updateSystems(type: SystemType, scene: Scene, delta: number) {\r\n const systems = this.systems.filter((s) => s.systemType === type);\r\n for (const s of systems) {\r\n if (s.preupdate) {\r\n s.preupdate(scene, delta);\r\n }\r\n }\r\n\r\n for (const s of systems) {\r\n s.update(delta);\r\n }\r\n\r\n for (const s of systems) {\r\n if (s.postupdate) {\r\n s.postupdate(scene, delta);\r\n }\r\n }\r\n }\r\n\r\n public clear(): void {\r\n for (let i = this.systems.length - 1; i >= 0; i--) {\r\n this.removeSystem(this.systems[i]);\r\n }\r\n }\r\n}\r\n","import { Scene } from '../Scene';\r\nimport { Component, ComponentCtor } from './Component';\r\nimport { Entity } from './Entity';\r\nimport { EntityManager } from './EntityManager';\r\nimport { Query } from './Query';\r\nimport { QueryManager } from './QueryManager';\r\nimport { System, SystemType } from './System';\r\nimport { SystemCtor, SystemManager, isSystemConstructor } from './SystemManager';\r\nimport { TagQuery } from './TagQuery';\r\n\r\n/**\r\n * The World is a self-contained entity component system for a particular context.\r\n */\r\nexport class World {\r\n public queryManager: QueryManager = new QueryManager(this);\r\n public entityManager: EntityManager = new EntityManager(this);\r\n public systemManager: SystemManager = new SystemManager(this);\r\n\r\n /**\r\n * The context type is passed to the system updates\r\n * @param scene\r\n */\r\n constructor(public scene: Scene) {}\r\n\r\n /**\r\n * Query the ECS world for entities that match your components\r\n * @param requiredTypes\r\n */\r\n query>(\r\n requiredTypes: TKnownComponentCtors[]): Query {\r\n return this.queryManager.createQuery(requiredTypes);\r\n }\r\n\r\n queryTags(requiredTags: TKnownTags[]): TagQuery {\r\n return this.queryManager.createTagQuery(requiredTags);\r\n }\r\n\r\n /**\r\n * Update systems by type and time elapsed in milliseconds\r\n */\r\n update(type: SystemType, delta: number) {\r\n if (type === SystemType.Update) {\r\n this.entityManager.updateEntities(this.scene, delta);\r\n }\r\n this.systemManager.updateSystems(type, this.scene, delta);\r\n this.entityManager.findEntitiesForRemoval();\r\n this.entityManager.processComponentRemovals();\r\n this.entityManager.processEntityRemovals();\r\n }\r\n\r\n /**\r\n * Add an entity to the ECS world\r\n * @param entity\r\n */\r\n add(entity: Entity): void;\r\n /**\r\n * Add a system to the ECS world\r\n * @param system\r\n */\r\n add(system: System): void;\r\n add(system: SystemCtor): void;\r\n add(entityOrSystem: Entity | System | SystemCtor): void {\r\n if (entityOrSystem instanceof Entity) {\r\n this.entityManager.addEntity(entityOrSystem);\r\n }\r\n\r\n if (entityOrSystem instanceof System || isSystemConstructor(entityOrSystem)) {\r\n this.systemManager.addSystem(entityOrSystem);\r\n }\r\n }\r\n\r\n /**\r\n * Get a system out of the ECS world\r\n */\r\n get(system: SystemCtor) {\r\n return this.systemManager.get(system);\r\n }\r\n\r\n /**\r\n * Remove an entity from the ECS world\r\n * @param entity\r\n */\r\n remove(entity: Entity, deferred?: boolean): void;\r\n /**\r\n * Remove a system from the ECS world\r\n * @param system\r\n */\r\n remove(system: System): void;\r\n remove(entityOrSystem: Entity | System, deferred = true): void {\r\n if (entityOrSystem instanceof Entity) {\r\n this.entityManager.removeEntity(entityOrSystem, deferred);\r\n }\r\n\r\n if (entityOrSystem instanceof System) {\r\n this.systemManager.removeSystem(entityOrSystem);\r\n }\r\n }\r\n\r\n get entities() {\r\n return this.entityManager.entities;\r\n }\r\n\r\n clearEntities(): void {\r\n this.entityManager.clear();\r\n }\r\n\r\n clearSystems(): void {\r\n this.systemManager.clear();\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\n\r\nexport class EulerIntegrator {\r\n // Scratch vectors to avoid allocation\r\n private static _POS = new Vector(0, 0);\r\n private static _SCALE = new Vector(1, 1);\r\n\r\n private static _ACC = new Vector(0, 0);\r\n private static _VEL = new Vector(0, 0);\r\n private static _VEL_ACC = new Vector(0, 0);\r\n private static _SCALE_FACTOR = new Vector(0, 0);\r\n\r\n static integrate(transform: TransformComponent, motion: MotionComponent, totalAcc: Vector, elapsedMs: number): void {\r\n const seconds = elapsedMs / 1000;\r\n // This code looks a little wild, but it's to avoid creating any new Vector instances\r\n // integration is done in a tight loop so this is key to avoid GC'ing\r\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\r\n transform.pos\r\n .add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS)\r\n .addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\r\n\r\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\r\n const rotation = transform.rotation + motion.angularVelocity * seconds;\r\n\r\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\r\n const tx = transform.get();\r\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\r\n }\r\n}\r\n","import { Query, SystemPriority, World } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { BodyComponent } from './BodyComponent';\r\nimport { CollisionType } from './CollisionType';\r\nimport { EulerIntegrator } from './Integrator';\r\nimport { PhysicsWorld } from './PhysicsWorld';\r\n\r\nexport class MotionSystem extends System {\r\n public systemType = SystemType.Update;\r\n public priority = SystemPriority.Higher;\r\n private _physicsConfigDirty = false;\r\n query: Query;\r\n constructor(public world: World, public physics: PhysicsWorld) {\r\n super();\r\n physics.$configUpdate.subscribe(() => this._physicsConfigDirty = true);\r\n this.query = this.world.query([TransformComponent, MotionComponent]);\r\n }\r\n\r\n update(elapsedMs: number): void {\r\n let transform: TransformComponent;\r\n let motion: MotionComponent;\r\n const entities = this.query.entities;\r\n for (let i = 0; i < entities.length; i++) {\r\n transform = entities[i].get(TransformComponent);\r\n motion = entities[i].get(MotionComponent);\r\n\r\n const optionalBody = entities[i].get(BodyComponent);\r\n if (this._physicsConfigDirty && optionalBody) {\r\n optionalBody.updatePhysicsConfig(this.physics.config.bodies);\r\n }\r\n\r\n if (optionalBody?.sleeping) {\r\n continue;\r\n }\r\n\r\n const totalAcc = motion.acc.clone();\r\n if (optionalBody?.collisionType === CollisionType.Active && optionalBody?.useGravity) {\r\n totalAcc.addEqual(this.physics.config.gravity);\r\n }\r\n optionalBody?.captureOldTransform();\r\n\r\n // Update transform and motion based on Euler linear algebra\r\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\r\n }\r\n }\r\n}\r\n","import { PostCollisionEvent, PreCollisionEvent } from '../../Events';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Side } from '../Side';\r\nimport { CollisionSolver } from './Solver';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { ContactBias, ContactSolveBias, HorizontalFirst, None, VerticalFirst } from './ContactBias';\r\nimport { PhysicsConfig } from '../PhysicsConfig';\r\nimport { DeepRequired } from '../../Util/Required';\r\n\r\n/**\r\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\r\n * and negates velocity along the collision normal.\r\n *\r\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\r\n *\r\n */\r\nexport class ArcadeSolver implements CollisionSolver {\r\n directionMap = new Map();\r\n distanceMap = new Map();\r\n\r\n constructor(public config: DeepRequired['arcade']>) {}\r\n\r\n public solve(contacts: CollisionContact[]): CollisionContact[] {\r\n // Events and init\r\n this.preSolve(contacts);\r\n\r\n // Remove any canceled contacts\r\n contacts = contacts.filter(c => !c.isCanceled());\r\n\r\n // Locate collision bias order\r\n let bias: ContactBias;\r\n switch (this.config.contactSolveBias) {\r\n case ContactSolveBias.HorizontalFirst: {\r\n bias = HorizontalFirst;\r\n break;\r\n }\r\n case ContactSolveBias.VerticalFirst: {\r\n bias = VerticalFirst;\r\n break;\r\n }\r\n default: {\r\n bias = None;\r\n }\r\n }\r\n\r\n // Sort by bias (None, VerticalFirst, HorizontalFirst) to avoid artifacts with seams\r\n // Sort contacts by distance to avoid artifacts with seams\r\n // It's important to solve in a specific order\r\n contacts.sort((a, b) => {\r\n const aDir = this.directionMap.get(a.id);\r\n const bDir = this.directionMap.get(b.id);\r\n const aDist = this.distanceMap.get(a.id);\r\n const bDist = this.distanceMap.get(b.id);\r\n return (bias[aDir] - bias[bDir]) || (aDist - bDist);\r\n });\r\n\r\n for (const contact of contacts) {\r\n // Solve position first in arcade\r\n this.solvePosition(contact);\r\n\r\n // Solve velocity second in arcade\r\n this.solveVelocity(contact);\r\n }\r\n\r\n // Events and any contact house-keeping the solver needs\r\n this.postSolve(contacts);\r\n\r\n return contacts;\r\n }\r\n\r\n public preSolve(contacts: CollisionContact[]) {\r\n const epsilon = .0001;\r\n for (const contact of contacts) {\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n continue;\r\n }\r\n const side = Side.fromDirection(contact.mtv);\r\n const mtv = contact.mtv.negate();\r\n\r\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\r\n this.distanceMap.set(contact.id, distance);\r\n\r\n this.directionMap.set(contact.id, side === Side.Left || side === Side.Right ? 'horizontal' : 'vertical');\r\n\r\n // Publish collision events on both participants\r\n contact.colliderA.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\r\n contact.colliderB.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact)\r\n );\r\n }\r\n }\r\n\r\n public postSolve(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n if (contact.isCanceled()) {\r\n continue;\r\n }\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n }\r\n\r\n const side = Side.fromDirection(contact.mtv);\r\n const mtv = contact.mtv.negate();\r\n // Publish collision events on both participants\r\n contact.colliderA.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv, contact));\r\n contact.colliderB.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate(), contact)\r\n );\r\n }\r\n }\r\n\r\n public solvePosition(contact: CollisionContact) {\r\n const epsilon = .0001;\r\n // if bounds no longer intersect skip to the next\r\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\r\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\r\n // Cancel the contact to prevent and solving\r\n contact.cancel();\r\n return;\r\n }\r\n\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n return;\r\n }\r\n\r\n let mtv = contact.mtv;\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n return;\r\n }\r\n\r\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) {\r\n // split overlaps if both are Active\r\n mtv = mtv.scale(0.5);\r\n }\r\n\r\n // Resolve overlaps\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n bodyA.globalPos.x -= mtv.x;\r\n bodyA.globalPos.y -= mtv.y;\r\n colliderA.update(bodyA.transform.get());\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n bodyB.globalPos.x += mtv.x;\r\n bodyB.globalPos.y += mtv.y;\r\n colliderB.update(bodyB.transform.get());\r\n }\r\n }\r\n }\r\n\r\n\r\n public solveVelocity(contact: CollisionContact) {\r\n if (contact.isCanceled()) {\r\n return;\r\n }\r\n\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n return;\r\n }\r\n\r\n const normal = contact.normal;\r\n const opposite = normal.negate();\r\n\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n // only adjust velocity if the contact normal is opposite to the current velocity\r\n // this avoids catching edges on a platform when sliding off\r\n if (bodyA.vel.normalize().dot(opposite) < 0) {\r\n // Cancel out velocity opposite direction of collision normal\r\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\r\n bodyA.vel = bodyA.vel.add(velAdj);\r\n }\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n // only adjust velocity if the contact normal is opposite to the current velocity\r\n // this avoids catching edges on a platform\r\n if (bodyB.vel.normalize().dot(normal) < 0) {\r\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\r\n bodyB.vel = bodyB.vel.add(velAdj);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\n\r\n/**\r\n * Holds information about contact points, meant to be reused over multiple frames of contact\r\n */\r\nexport class ContactConstraintPoint {\r\n constructor(public point: Vector, public local: Vector, public contact: CollisionContact) {\r\n this.update();\r\n }\r\n\r\n /**\r\n * Updates the contact information\r\n */\r\n update() {\r\n const bodyA = this.contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = this.contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n const normal = this.contact.normal;\r\n const tangent = this.contact.tangent;\r\n\r\n this.aToContact = this.point.sub(bodyA.globalPos);\r\n this.bToContact = this.point.sub(bodyB.globalPos);\r\n\r\n const aToContactNormal = this.aToContact.cross(normal);\r\n const bToContactNormal = this.bToContact.cross(normal);\r\n\r\n this.normalMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\r\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\r\n\r\n const aToContactTangent = this.aToContact.cross(tangent);\r\n const bToContactTangent = this.bToContact.cross(tangent);\r\n\r\n this.tangentMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\r\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns the relative velocity between bodyA and bodyB\r\n */\r\n public getRelativeVelocity() {\r\n const bodyA = this.contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = this.contact.colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n // Relative velocity in linear terms\r\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\r\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\r\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\r\n return velB.sub(velA);\r\n }\r\n return Vector.Zero;\r\n }\r\n\r\n /**\r\n * Impulse accumulated over time in normal direction\r\n */\r\n public normalImpulse: number = 0;\r\n\r\n /**\r\n * Impulse accumulated over time in the tangent direction\r\n */\r\n public tangentImpulse: number = 0;\r\n\r\n /**\r\n * Effective mass seen in the normal direction\r\n */\r\n public normalMass: number = 0;\r\n\r\n /**\r\n * Effective mass seen in the tangent direction\r\n */\r\n public tangentMass: number = 0;\r\n\r\n /**\r\n * Direction from center of mass of bodyA to contact point\r\n */\r\n public aToContact: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Direction from center of mass of bodyB to contact point\r\n */\r\n public bToContact: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Original contact velocity combined with bounciness\r\n */\r\n public originalVelocityAndRestitution: number = 0;\r\n}\r\n","import { CollisionPostSolveEvent, CollisionPreSolveEvent, PostCollisionEvent, PreCollisionEvent } from '../../Events';\r\nimport { clamp } from '../../Math/util';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { ContactConstraintPoint } from './ContactConstraintPoint';\r\nimport { Side } from '../Side';\r\nimport { CollisionSolver } from './Solver';\r\nimport { BodyComponent, DegreeOfFreedom } from '../BodyComponent';\r\nimport { CollisionJumpTable } from '../Colliders/CollisionJumpTable';\r\nimport { DeepRequired } from '../../Util/Required';\r\nimport { PhysicsConfig } from '../PhysicsConfig';\r\n\r\nexport class RealisticSolver implements CollisionSolver {\r\n constructor(public config: DeepRequired['realistic']>) {}\r\n lastFrameContacts: Map = new Map();\r\n\r\n // map contact id to contact points\r\n idToContactConstraint: Map = new Map();\r\n\r\n getContactConstraints(id: string) {\r\n return this.idToContactConstraint.get(id) ?? [];\r\n }\r\n\r\n public solve(contacts: CollisionContact[]): CollisionContact[] {\r\n // Events and init\r\n this.preSolve(contacts);\r\n\r\n // Remove any canceled contacts\r\n contacts = contacts.filter(c => !c.isCanceled());\r\n\r\n // Solve velocity first\r\n this.solveVelocity(contacts);\r\n\r\n // Solve position last because non-overlap is the most important\r\n this.solvePosition(contacts);\r\n\r\n // Events and any contact house-keeping the solver needs\r\n this.postSolve(contacts);\r\n\r\n return contacts;\r\n }\r\n\r\n preSolve(contacts: CollisionContact[]) {\r\n const epsilon = .0001;\r\n for (const contact of contacts) {\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n continue;\r\n }\r\n // Publish collision events on both participants\r\n const side = Side.fromDirection(contact.mtv);\r\n contact.colliderA.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\r\n contact.colliderA.events.emit(\r\n 'beforecollisionresolve',\r\n new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact) as any\r\n );\r\n contact.colliderB.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact)\r\n );\r\n contact.colliderB.events.emit(\r\n 'beforecollisionresolve',\r\n new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact) as any\r\n );\r\n\r\n // Match awake state for sleeping\r\n contact.matchAwake();\r\n }\r\n\r\n // Keep track of contacts that done\r\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\r\n for (const contact of contacts) {\r\n // Remove all current contacts that are not done\r\n const index = finishedContactIds.indexOf(contact.id);\r\n if (index > -1) {\r\n finishedContactIds.splice(index, 1);\r\n }\r\n const contactPoints = this.idToContactConstraint.get(contact.id) ?? [];\r\n\r\n let pointIndex = 0;\r\n const bodyA = contact.colliderA.owner.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n for (const point of contact.points) {\r\n const normal = contact.normal;\r\n const tangent = contact.tangent;\r\n\r\n const aToContact = point.sub(bodyA.globalPos);\r\n const bToContact = point.sub(bodyB.globalPos);\r\n\r\n const aToContactNormal = aToContact.cross(normal);\r\n const bToContactNormal = bToContact.cross(normal);\r\n\r\n const normalMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\r\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\r\n\r\n const aToContactTangent = aToContact.cross(tangent);\r\n const bToContactTangent = bToContact.cross(tangent);\r\n\r\n const tangentMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\r\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\r\n\r\n // Preserve normal/tangent impulse by re-using the contact point if it's close\r\n if (contactPoints[pointIndex] && contactPoints[pointIndex]?.point?.squareDistance(point) < 4) {\r\n contactPoints[pointIndex].point = point;\r\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\r\n } else {\r\n // new contact if it's not close or doesn't exist\r\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\r\n }\r\n\r\n // Update contact point calculations\r\n contactPoints[pointIndex].aToContact = aToContact;\r\n contactPoints[pointIndex].bToContact = bToContact;\r\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\r\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\r\n\r\n // Calculate relative velocity before solving to accurately do restitution\r\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\r\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\r\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\r\n if (relativeVelocity < -0.1) { // TODO what's a good threshold here?\r\n contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\r\n }\r\n pointIndex++;\r\n }\r\n }\r\n this.idToContactConstraint.set(contact.id, contactPoints);\r\n }\r\n\r\n // Clean up any contacts that did not occur last frame\r\n for (const id of finishedContactIds) {\r\n this.idToContactConstraint.delete(id);\r\n }\r\n\r\n // Warm contacts with accumulated impulse\r\n // Useful for tall stacks\r\n if (this.config.warmStart) {\r\n this.warmStart(contacts);\r\n } else {\r\n for (const contact of contacts) {\r\n const contactPoints = this.getContactConstraints(contact.id);\r\n for (const point of contactPoints) {\r\n point.normalImpulse = 0;\r\n point.tangentImpulse = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n postSolve(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip post solve for active+passive collisions\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n // Update motion values for sleeping\r\n bodyA.updateMotion();\r\n bodyB.updateMotion();\r\n }\r\n\r\n // Publish collision events on both participants\r\n const side = Side.fromDirection(contact.mtv);\r\n contact.colliderA.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact)\r\n );\r\n contact.colliderA.events.emit(\r\n 'aftercollisionresolve',\r\n new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact) as any\r\n );\r\n contact.colliderB.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact)\r\n );\r\n contact.colliderB.events.emit(\r\n 'aftercollisionresolve',\r\n new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact) as any\r\n );\r\n }\r\n\r\n // Store contacts\r\n this.lastFrameContacts.clear();\r\n for (const c of contacts) {\r\n this.lastFrameContacts.set(c.id, c);\r\n }\r\n }\r\n\r\n /**\r\n * Warm up body's based on previous frame contact points\r\n * @param contacts\r\n */\r\n warmStart(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n const contactPoints = this.idToContactConstraint.get(contact.id) ?? [];\r\n for (const point of contactPoints) {\r\n if (this.config.warmStart) {\r\n const normalImpulse = contact.normal.scale(point.normalImpulse);\r\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\r\n const impulse = normalImpulse.add(tangentImpulse);\r\n\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n } else {\r\n point.normalImpulse = 0;\r\n point.tangentImpulse = 0;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Iteratively solve the position overlap constraint\r\n * @param contacts\r\n */\r\n solvePosition(contacts: CollisionContact[]) {\r\n for (let i = 0; i < this.config.positionIterations; i++) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip solving active+passive\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n const constraints = this.idToContactConstraint.get(contact.id) ?? [];\r\n for (const point of constraints) {\r\n const normal = contact.normal;\r\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\r\n\r\n const steeringConstant = this.config.steeringFactor; //0.2;\r\n const maxCorrection = -5;\r\n const slop = this.config.slop; //1;\r\n\r\n // Clamp to avoid over-correction\r\n // Remember that we are shooting for 0 overlap in the end\r\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\r\n const impulse = normal.scale(-steeringForce * point.normalMass);\r\n\r\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\r\n // We adjust position and rotation instead of doing the velocity\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n // TODO make applyPseudoImpulse function?\r\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\r\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n impulseForce.x = 0;\r\n }\r\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n impulseForce.y = 0;\r\n }\r\n\r\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\r\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\r\n }\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n const impulseForce = impulse.scale(bodyB.inverseMass);\r\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n impulseForce.x = 0;\r\n }\r\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n impulseForce.y = 0;\r\n }\r\n\r\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\r\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n solveVelocity(contacts: CollisionContact[]) {\r\n for (let i = 0; i < this.config.velocityIterations; i++) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip solving active+passive\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n const friction = Math.min(bodyA.friction, bodyB.friction);\r\n\r\n const constraints = this.idToContactConstraint.get(contact.id) ?? [];\r\n\r\n // Friction constraint\r\n for (const point of constraints) {\r\n const relativeVelocity = point.getRelativeVelocity();\r\n\r\n // Negate velocity in tangent direction to simulate friction\r\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\r\n let impulseDelta = tangentVelocity * point.tangentMass;\r\n\r\n // Clamping based in Erin Catto's GDC 2006 talk\r\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\r\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\r\n // But deltas can vary\r\n const maxFriction = friction * point.normalImpulse;\r\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\r\n impulseDelta = newImpulse - point.tangentImpulse;\r\n point.tangentImpulse = newImpulse;\r\n\r\n const impulse = contact.tangent.scale(impulseDelta);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n\r\n // Bounce constraint\r\n for (const point of constraints) {\r\n // Need to recalc relative velocity because the previous step could have changed vel\r\n const relativeVelocity = point.getRelativeVelocity();\r\n\r\n // Compute impulse in normal direction\r\n const normalVelocity = relativeVelocity.dot(contact.normal);\r\n\r\n // Per Erin it is a mistake to apply the restitution inside the iteration\r\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\r\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\r\n\r\n // Clamping based in Erin Catto's GDC 2014 talk\r\n // Accumulated impulse stored in the contact is always positive (dV > 0)\r\n // But deltas can be negative\r\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\r\n impulseDelta = newImpulse - point.normalImpulse;\r\n point.normalImpulse = newImpulse;\r\n\r\n const impulse = contact.normal.scale(impulseDelta);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { ComponentCtor, Query, SystemPriority, World } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { CollisionEndEvent, CollisionStartEvent, ContactEndEvent, ContactStartEvent } from '../Events';\r\nimport { SolverStrategy } from './SolverStrategy';\r\nimport { ArcadeSolver } from './Solver/ArcadeSolver';\r\nimport { Collider } from './Colliders/Collider';\r\nimport { CollisionContact } from './Detection/CollisionContact';\r\nimport { RealisticSolver } from './Solver/RealisticSolver';\r\nimport { CollisionSolver } from './Solver/Solver';\r\nimport { ColliderComponent } from './ColliderComponent';\r\nimport { CompositeCollider } from './Colliders/CompositeCollider';\r\nimport { Engine } from '../Engine';\r\nimport { ExcaliburGraphicsContext } from '../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Scene } from '../Scene';\r\nimport { Side } from '../Collision/Side';\r\nimport { DynamicTreeCollisionProcessor } from './Detection/DynamicTreeCollisionProcessor';\r\nimport { PhysicsWorld } from './PhysicsWorld';\r\nexport class CollisionSystem extends System {\r\n public systemType = SystemType.Update;\r\n public priority = SystemPriority.Higher;\r\n public query: Query | ComponentCtor | ComponentCtor>;\r\n\r\n private _engine: Engine;\r\n private _configDirty = false;\r\n private _realisticSolver: RealisticSolver;\r\n private _arcadeSolver: ArcadeSolver;\r\n private _lastFrameContacts = new Map();\r\n private _currentFrameContacts = new Map();\r\n private get _processor(): DynamicTreeCollisionProcessor {\r\n return this._physics.collisionProcessor;\r\n };\r\n\r\n private _trackCollider: (c: Collider) => void;\r\n private _untrackCollider: (c: Collider) => void;\r\n\r\n constructor(world: World, private _physics: PhysicsWorld) {\r\n super();\r\n this._arcadeSolver = new ArcadeSolver(_physics.config.arcade);\r\n this._realisticSolver = new RealisticSolver(_physics.config.realistic);\r\n this._physics.$configUpdate.subscribe(() => this._configDirty = true);\r\n this._trackCollider = (c: Collider) => this._processor.track(c);\r\n this._untrackCollider = (c: Collider) => this._processor.untrack(c);\r\n this.query = world.query([TransformComponent, MotionComponent, ColliderComponent]);\r\n this.query.entityAdded$.subscribe(e => {\r\n const colliderComponent = e.get(ColliderComponent);\r\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\r\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\r\n const collider = colliderComponent.get();\r\n if (collider) {\r\n this._processor.track(collider);\r\n }\r\n });\r\n this.query.entityRemoved$.subscribe(e => {\r\n const colliderComponent = e.get(ColliderComponent);\r\n const collider = colliderComponent.get();\r\n if (colliderComponent && collider) {\r\n this._processor.untrack(collider);\r\n }\r\n });\r\n }\r\n\r\n initialize(world: World, scene: Scene) {\r\n this._engine = scene.engine;\r\n }\r\n\r\n update(elapsedMs: number): void {\r\n if (!this._physics.config.enabled) {\r\n return;\r\n }\r\n\r\n // Collect up all the colliders and update them\r\n let colliders: Collider[] = [];\r\n for (const entity of this.query.entities) {\r\n const colliderComp = entity.get(ColliderComponent);\r\n const collider = colliderComp?.get();\r\n if (colliderComp && colliderComp.owner?.active && collider) {\r\n colliderComp.update();\r\n if (collider instanceof CompositeCollider) {\r\n const compositeColliders = collider.getColliders();\r\n if (!collider.compositeStrategy) {\r\n collider.compositeStrategy = this._physics.config.colliders.compositeStrategy;\r\n }\r\n colliders = colliders.concat(compositeColliders);\r\n } else {\r\n colliders.push(collider);\r\n }\r\n }\r\n }\r\n\r\n // Update the spatial partitioning data structures\r\n // TODO if collider invalid it will break the processor\r\n // TODO rename \"update\" to something more specific\r\n this._processor.update(colliders);\r\n\r\n // Run broadphase on all colliders and locates potential collisions\r\n const pairs = this._processor.broadphase(colliders, elapsedMs);\r\n\r\n this._currentFrameContacts.clear();\r\n\r\n // Given possible pairs find actual contacts\r\n let contacts = this._processor.narrowphase(pairs, this._engine?.debug?.stats?.currFrame);\r\n\r\n const solver: CollisionSolver = this.getSolver();\r\n\r\n // Solve, this resolves the position/velocity so entities aren't overlapping\r\n contacts = solver.solve(contacts);\r\n\r\n // Record contacts for start/end\r\n for (const contact of contacts) {\r\n if (contact.isCanceled()) {\r\n continue;\r\n }\r\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\r\n const index = contact.id.indexOf('|');\r\n if (index > 0) {\r\n const compositeId = contact.id.substring(index + 1);\r\n this._currentFrameContacts.set(compositeId, contact);\r\n } else {\r\n this._currentFrameContacts.set(contact.id, contact);\r\n }\r\n }\r\n\r\n // Emit contact start/end events\r\n this.runContactStartEnd();\r\n\r\n // reset the last frame cache\r\n this._lastFrameContacts.clear();\r\n\r\n // Keep track of collisions contacts that have started or ended\r\n this._lastFrameContacts = new Map(this._currentFrameContacts);\r\n\r\n // Process deferred collider removals\r\n for (const entity of this.query.entities) {\r\n const collider = entity.get(ColliderComponent);\r\n if (collider) {\r\n collider.processColliderRemoval();\r\n }\r\n }\r\n }\r\n\r\n getSolver(): CollisionSolver {\r\n if (this._configDirty) {\r\n this._configDirty = false;\r\n this._arcadeSolver = new ArcadeSolver(this._physics.config.arcade);\r\n this._realisticSolver = new RealisticSolver(this._physics.config.realistic);\r\n }\r\n return this._physics.config.solver === SolverStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\r\n }\r\n\r\n debug(ex: ExcaliburGraphicsContext) {\r\n this._processor.debug(ex);\r\n }\r\n\r\n public runContactStartEnd() {\r\n // If composite colliders are 'together' collisions may have a duplicate id because we want to treat those as a singular start/end\r\n for (const [id, c] of this._currentFrameContacts) {\r\n // find all new contacts\r\n if (!this._lastFrameContacts.has(id)) {\r\n const colliderA = c.colliderA;\r\n const colliderB = c.colliderB;\r\n const side = Side.fromDirection(c.mtv);\r\n const opposite = Side.getOpposite(side);\r\n colliderA.events.emit('collisionstart', new CollisionStartEvent(colliderA, colliderB, side, c));\r\n colliderA.events.emit('contactstart', new ContactStartEvent(colliderA, colliderB, side, c) as any);\r\n colliderB.events.emit('collisionstart', new CollisionStartEvent(colliderB, colliderA, opposite, c));\r\n colliderB.events.emit('contactstart', new ContactStartEvent(colliderB, colliderA, opposite, c) as any);\r\n }\r\n }\r\n\r\n // find all contacts that have ceased\r\n for (const [id, c] of this._lastFrameContacts) {\r\n if (!this._currentFrameContacts.has(id)) {\r\n const colliderA = c.colliderA;\r\n const colliderB = c.colliderB;\r\n const side = Side.fromDirection(c.mtv);\r\n const opposite = Side.getOpposite(side);\r\n colliderA.events.emit('collisionend', new CollisionEndEvent(colliderA, colliderB, side, c));\r\n colliderA.events.emit('contactend', new ContactEndEvent(colliderA, colliderB, side, c) as any);\r\n colliderB.events.emit('collisionend', new CollisionEndEvent(colliderB, colliderA, opposite, c));\r\n colliderB.events.emit('contactend', new ContactEndEvent(colliderB, colliderA, opposite, c) as any);\r\n }\r\n }\r\n }\r\n}\r\n","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { GetSpriteOptions, SpriteSheet } from './SpriteSheet';\r\nimport { Logger } from '../Util/Log';\r\nimport { clamp } from '../Math/util';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport interface HasTick {\r\n /**\r\n *\r\n * @param elapsedMilliseconds The amount of real world time in milliseconds that has elapsed that must be updated in the animation\r\n * @param idempotencyToken Optional idempotencyToken prevents a ticking animation from updating twice per frame\r\n */\r\n tick(elapsedMilliseconds: number, idempotencyToken?: number): void;\r\n}\r\n\r\nexport enum AnimationDirection {\r\n /**\r\n * Animation is playing forwards\r\n */\r\n Forward = 'forward',\r\n /**\r\n * Animation is playing backwards\r\n */\r\n Backward = 'backward'\r\n}\r\n\r\nexport enum AnimationStrategy {\r\n /**\r\n * Animation ends without displaying anything\r\n */\r\n End = 'end',\r\n /**\r\n * Animation loops to the first frame after the last frame\r\n */\r\n Loop = 'loop',\r\n /**\r\n * Animation plays to the last frame, then backwards to the first frame, then repeats\r\n */\r\n PingPong = 'pingpong',\r\n /**\r\n * Animation ends stopping on the last frame\r\n */\r\n Freeze = 'freeze'\r\n}\r\n\r\n/**\r\n * Frame of animation\r\n */\r\nexport interface Frame {\r\n /**\r\n * Optionally specify a graphic to show, no graphic shows an empty frame\r\n */\r\n graphic?: Graphic;\r\n /**\r\n * Optionally specify the number of ms the frame should be visible, overrides the animation duration (default 100 ms)\r\n */\r\n duration?: number;\r\n}\r\n\r\nexport interface FrameEvent extends Frame {\r\n frameIndex: number;\r\n}\r\n\r\n/**\r\n * Animation options for building an animation via constructor.\r\n */\r\nexport interface AnimationOptions {\r\n /**\r\n * List of frames in the order you wish to play them\r\n */\r\n frames: Frame[];\r\n /**\r\n * Optionally set a positive speed multiplier on the animation.\r\n *\r\n * By default 1, meaning 1x speed. If set to 2, it will play the animation twice as fast.\r\n */\r\n speed?: number;\r\n /**\r\n * Optionally reverse the direction of play\r\n */\r\n reverse?: boolean;\r\n /**\r\n * Optionally specify a default frame duration in ms (Default is 100)\r\n */\r\n frameDuration?: number;\r\n /**\r\n * Optionally specify a total duration of the animation in ms to calculate each frame's duration\r\n */\r\n totalDuration?: number;\r\n /**\r\n * Optionally specify the [[AnimationStrategy]] for the Animation\r\n */\r\n strategy?: AnimationStrategy;\r\n}\r\n\r\nexport type AnimationEvents = {\r\n frame: FrameEvent;\r\n loop: Animation;\r\n end: Animation;\r\n};\r\n\r\nexport const AnimationEvents = {\r\n Frame: 'frame',\r\n Loop: 'loop',\r\n End: 'end'\r\n};\r\n\r\nexport interface FromSpriteSheetOptions {\r\n /**\r\n * [[SpriteSheet]] to source the animation frames from\r\n */\r\n spriteSheet: SpriteSheet;\r\n /**\r\n * The list of (x, y) positions of sprites in the [[SpriteSheet]] of each frame, for example (0, 0)\r\n * is the the top left sprite, (0, 1) is the sprite directly below that, and so on.\r\n *\r\n * You may optionally specify a duration for the frame in milliseconds as well, this will override\r\n * the default duration.\r\n */\r\n frameCoordinates: {x: number, y: number, duration?: number, options?: GetSpriteOptions}[];\r\n /**\r\n * Optionally specify a default duration for frames in milliseconds\r\n */\r\n durationPerFrameMs?: number;\r\n /**\r\n * Optionally set a positive speed multiplier on the animation.\r\n *\r\n * By default 1, meaning 1x speed. If set to 2, it will play the animation twice as fast.\r\n */\r\n speed?: number;\r\n /**\r\n * Optionally specify the animation strategy for this animation, by default animations loop [[AnimationStrategy.Loop]]\r\n */\r\n strategy?: AnimationStrategy\r\n /**\r\n * Optionally specify the animation should be reversed\r\n */\r\n reverse?: boolean;\r\n}\r\n\r\n/**\r\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\r\n *\r\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\r\n */\r\nexport class Animation extends Graphic implements HasTick {\r\n private static _LOGGER = Logger.getInstance();\r\n public events = new EventEmitter();\r\n public frames: Frame[] = [];\r\n public strategy: AnimationStrategy = AnimationStrategy.Loop;\r\n public frameDuration: number = 100;\r\n\r\n private _idempotencyToken = -1;\r\n\r\n private _firstTick = true;\r\n private _currentFrame = 0;\r\n private _timeLeftInFrame = 0;\r\n private _pingPongDirection = 1;\r\n private _done = false;\r\n private _playing = true;\r\n private _speed = 1;\r\n\r\n constructor(options: GraphicOptions & AnimationOptions) {\r\n super(options);\r\n this.frames = options.frames;\r\n this.speed = options.speed ?? this.speed;\r\n this.strategy = options.strategy ?? this.strategy;\r\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : options.frameDuration ?? this.frameDuration;\r\n if (options.reverse) {\r\n this.reverse();\r\n }\r\n this.goToFrame(0);\r\n }\r\n\r\n public clone(): Animation {\r\n return new Animation({\r\n frames: this.frames.map((f) => ({ ...f })),\r\n frameDuration: this.frameDuration,\r\n speed: this.speed,\r\n reverse: this._reversed,\r\n strategy: this.strategy,\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n\r\n public override get width(): number {\r\n const maybeFrame = this.currentFrame;\r\n if (maybeFrame) {\r\n return Math.abs(maybeFrame.graphic.width * this.scale.x);\r\n }\r\n return 0;\r\n }\r\n\r\n public override get height(): number {\r\n const maybeFrame = this.currentFrame;\r\n if (maybeFrame) {\r\n return Math.abs(maybeFrame.graphic.height * this.scale.y);\r\n }\r\n return 0;\r\n }\r\n\r\n\r\n /**\r\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\r\n * and optional [[AnimationStrategy]]\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\r\n * ```\r\n * @param spriteSheet\r\n * @param frameIndices\r\n * @param durationPerFrameMs\r\n * @param strategy\r\n */\r\n public static fromSpriteSheet(\r\n spriteSheet: SpriteSheet,\r\n frameIndices: number[],\r\n durationPerFrameMs: number,\r\n strategy: AnimationStrategy = AnimationStrategy.Loop\r\n ): Animation {\r\n const maxIndex = spriteSheet.sprites.length - 1;\r\n const invalidIndices = frameIndices.filter((index) => index < 0 || index > maxIndex);\r\n if (invalidIndices.length) {\r\n Animation._LOGGER.warn(\r\n `Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(',')} no frame will be shown`\r\n );\r\n }\r\n return new Animation({\r\n frames: spriteSheet.sprites\r\n .filter((_, index) => frameIndices.indexOf(index) > -1)\r\n .map((f) => ({\r\n graphic: f,\r\n duration: durationPerFrameMs\r\n })),\r\n strategy: strategy\r\n });\r\n }\r\n\r\n /**\r\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheetCoordinates({\r\n * spriteSheet,\r\n * frameCoordinates: [\r\n * {x: 0, y: 5, duration: 100, options { flipHorizontal: true }},\r\n * {x: 1, y: 5, duration: 200},\r\n * {x: 2, y: 5, duration: 100},\r\n * {x: 3, y: 5, duration: 500}\r\n * ],\r\n * strategy: AnimationStrategy.PingPong\r\n * });\r\n * ```\r\n * @param options\r\n * @returns Animation\r\n */\r\n public static fromSpriteSheetCoordinates(options: FromSpriteSheetOptions): Animation {\r\n const { spriteSheet, frameCoordinates, durationPerFrameMs, speed, strategy, reverse } = options;\r\n const defaultDuration = durationPerFrameMs ?? 100;\r\n const frames: Frame[] = [];\r\n for (const coord of frameCoordinates) {\r\n const {x, y, duration, options } = coord;\r\n const sprite = spriteSheet.getSprite(x, y, options);\r\n if (sprite) {\r\n frames.push({\r\n graphic: sprite,\r\n duration: duration ?? defaultDuration\r\n });\r\n } else {\r\n Animation._LOGGER.warn(\r\n `Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`\r\n );\r\n }\r\n }\r\n\r\n return new Animation({\r\n frames,\r\n strategy,\r\n speed,\r\n reverse\r\n });\r\n }\r\n\r\n /**\r\n * Current animation speed\r\n *\r\n * 1 meaning normal 1x speed.\r\n * 2 meaning 2x speed and so on.\r\n */\r\n public get speed(): number {\r\n return this._speed;\r\n }\r\n\r\n /**\r\n * Current animation speed\r\n *\r\n * 1 meaning normal 1x speed.\r\n * 2 meaning 2x speed and so on.\r\n */\r\n public set speed(val: number) {\r\n this._speed = clamp(Math.abs(val), 0, Infinity);\r\n }\r\n\r\n /**\r\n * Returns the current Frame of the animation\r\n *\r\n * Use [[Animation.currentFrameIndex]] to get the frame number and\r\n * [[Animation.goToFrame]] to set the current frame index\r\n */\r\n public get currentFrame(): Frame | null {\r\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) {\r\n return this.frames[this._currentFrame];\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns the current frame index of the animation\r\n *\r\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\r\n */\r\n public get currentFrameIndex(): number {\r\n return this._currentFrame;\r\n }\r\n\r\n /**\r\n * Returns the amount of time in milliseconds left in the current frame\r\n */\r\n public get currentFrameTimeLeft(): number {\r\n return this._timeLeftInFrame;\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation is playing\r\n */\r\n public get isPlaying(): boolean {\r\n return this._playing;\r\n }\r\n\r\n private _reversed = false;\r\n /**\r\n * Reverses the play direction of the Animation, this preserves the current frame\r\n */\r\n public reverse(): void {\r\n // Don't mutate with the original frame list, create a copy\r\n this.frames = this.frames.slice().reverse();\r\n this._reversed = !this._reversed;\r\n }\r\n\r\n /**\r\n * Returns the current play direction of the animation\r\n */\r\n public get direction(): AnimationDirection {\r\n // Keep logically consistent with ping-pong direction\r\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\r\n const reversed = (this._reversed && this._pingPongDirection === 1) ? true : false;\r\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\r\n }\r\n\r\n /**\r\n * Plays or resumes the animation from the current frame\r\n */\r\n public play(): void {\r\n this._playing = true;\r\n }\r\n\r\n /**\r\n * Pauses the animation on the current frame\r\n */\r\n public pause(): void {\r\n this._playing = false;\r\n this._firstTick = true; // firstTick must be set to emit the proper frame event\r\n }\r\n\r\n /**\r\n * Reset the animation back to the beginning, including if the animation were done\r\n */\r\n public reset(): void {\r\n this._done = false;\r\n this._firstTick = true;\r\n this._currentFrame = 0;\r\n this._timeLeftInFrame = this.frameDuration;\r\n const maybeFrame = this.frames[this._currentFrame];\r\n if (maybeFrame) {\r\n this._timeLeftInFrame = (maybeFrame?.duration || this.frameDuration);\r\n }\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation can end\r\n */\r\n public get canFinish(): boolean {\r\n switch (this.strategy) {\r\n case AnimationStrategy.End:\r\n case AnimationStrategy.Freeze: {\r\n return true;\r\n }\r\n default: {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation is done, for looping type animations\r\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\r\n *\r\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\r\n */\r\n public get done(): boolean {\r\n return this._done;\r\n }\r\n\r\n /**\r\n * Jump the animation immediately to a specific frame if it exists\r\n *\r\n * Optionally specify an override for the duration of the frame, useful for\r\n * keeping multiple animations in sync with one another.\r\n * @param frameNumber\r\n * @param duration\r\n */\r\n public goToFrame(frameNumber: number, duration?: number) {\r\n this._currentFrame = frameNumber;\r\n this._timeLeftInFrame = duration ?? this.frameDuration;\r\n const maybeFrame = this.frames[this._currentFrame];\r\n if (maybeFrame && !this._done) {\r\n this._timeLeftInFrame = duration ?? (maybeFrame?.duration || this.frameDuration);\r\n this.events.emit('frame', {...maybeFrame, frameIndex: this.currentFrameIndex });\r\n }\r\n }\r\n\r\n private _nextFrame(): number {\r\n const currentFrame = this._currentFrame;\r\n if (this._done) {\r\n return currentFrame;\r\n }\r\n let next = -1;\r\n\r\n switch (this.strategy) {\r\n case AnimationStrategy.Loop: {\r\n next = (currentFrame + 1) % this.frames.length;\r\n if (next === 0) {\r\n this.events.emit('loop', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.End: {\r\n next = currentFrame + 1;\r\n if (next >= this.frames.length) {\r\n this._done = true;\r\n this._currentFrame = this.frames.length;\r\n this.events.emit('end', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.Freeze: {\r\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\r\n if (next >= this.frames.length - 1) {\r\n this._done = true;\r\n this.events.emit('end', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.PingPong: {\r\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\r\n this._pingPongDirection = -1;\r\n this.events.emit('loop', this);\r\n }\r\n\r\n if (currentFrame + this._pingPongDirection < 0) {\r\n this._pingPongDirection = 1;\r\n this.events.emit('loop', this);\r\n }\r\n\r\n next = currentFrame + (this._pingPongDirection % this.frames.length);\r\n break;\r\n }\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Called internally by Excalibur to update the state of the animation potential update the current frame\r\n * @param elapsedMilliseconds Milliseconds elapsed\r\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\r\n */\r\n public tick(elapsedMilliseconds: number, idempotencyToken: number = 0): void {\r\n if (this._idempotencyToken === idempotencyToken) {\r\n return;\r\n }\r\n this._idempotencyToken = idempotencyToken;\r\n if (!this._playing) {\r\n return;\r\n }\r\n\r\n // if it's the first frame emit frame event\r\n if (this._firstTick) {\r\n this._firstTick = false;\r\n this.events.emit('frame', {...this.currentFrame, frameIndex: this.currentFrameIndex });\r\n }\r\n\r\n this._timeLeftInFrame -= elapsedMilliseconds * this._speed;\r\n if (this._timeLeftInFrame <= 0) {\r\n this.goToFrame(this._nextFrame());\r\n }\r\n }\r\n\r\n protected _drawImage(ctx: ExcaliburGraphicsContext, x: number, y: number) {\r\n if (this.currentFrame) {\r\n this.currentFrame.graphic.draw(ctx, x, y);\r\n }\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Animation, HasTick } from './Animation';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/Index';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport interface GraphicsGroupingOptions {\r\n members: (GraphicsGrouping | Graphic)[];\r\n}\r\n\r\nexport interface GraphicsGrouping {\r\n offset: Vector;\r\n graphic: Graphic;\r\n /**\r\n * Optionally disable this graphics bounds as part of group calculation, default true\r\n * if unspecified\r\n *\r\n * You may want to do this if you're using text because their bounds will affect\r\n * the centering of the whole group\r\n */\r\n useBounds?: boolean;\r\n}\r\n\r\nexport class GraphicsGroup extends Graphic implements HasTick {\r\n private _logger = Logger.getInstance();\r\n public members: (GraphicsGrouping | Graphic)[] = [];\r\n\r\n constructor(options: GraphicsGroupingOptions & GraphicOptions) {\r\n super(options);\r\n this.members = options.members;\r\n this._updateDimensions();\r\n }\r\n\r\n public clone(): GraphicsGroup {\r\n return new GraphicsGroup({\r\n members: [...this.members],\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n\r\n private _updateDimensions(): BoundingBox {\r\n const bb = this.localBounds;\r\n this.width = bb.width;\r\n this.height = bb.height;\r\n return bb;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n let bb = new BoundingBox();\r\n for (const member of this.members) {\r\n if (member instanceof Graphic) {\r\n bb = member.localBounds.combine(bb);\r\n } else {\r\n const { graphic, offset: pos, useBounds } = member;\r\n const shouldUseBounds = useBounds === undefined ? true : useBounds;\r\n if (graphic) {\r\n if (shouldUseBounds) {\r\n bb = graphic.localBounds.translate(pos).combine(bb);\r\n }\r\n } else {\r\n this._logger.warnOnce(`Graphics group member has an null or undefined graphic, member definition: ${JSON.stringify(member)}.`);\r\n }\r\n }\r\n }\r\n return bb;\r\n }\r\n\r\n private _isAnimationOrGroup(graphic: Graphic): graphic is Animation | GraphicsGroup {\r\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\r\n }\r\n\r\n public tick(elapsedMilliseconds: number, idempotencyToken?: number) {\r\n for (const member of this.members) {\r\n let graphic: Graphic;\r\n if (member instanceof Graphic) {\r\n graphic = member;\r\n } else {\r\n graphic = member.graphic;\r\n }\r\n if (this._isAnimationOrGroup(graphic)) {\r\n graphic.tick(elapsedMilliseconds, idempotencyToken);\r\n }\r\n }\r\n }\r\n\r\n public reset() {\r\n for (const member of this.members) {\r\n let graphic: Graphic;\r\n if (member instanceof Graphic) {\r\n graphic = member;\r\n } else {\r\n graphic = member.graphic;\r\n }\r\n if (this._isAnimationOrGroup(graphic)) {\r\n graphic.reset();\r\n }\r\n }\r\n }\r\n\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n this._updateDimensions();\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n const pos = Vector.Zero;\r\n for (const member of this.members) {\r\n let graphic: Graphic;\r\n if (member instanceof Graphic) {\r\n graphic = member;\r\n } else {\r\n graphic = member.graphic;\r\n member.offset.clone(pos);\r\n }\r\n if (!graphic) {\r\n continue;\r\n }\r\n ex.save();\r\n ex.translate(x, y);\r\n graphic.draw(ex, pos.x, pos.y);\r\n if (this.showDebug) {\r\n /* istanbul ignore next */\r\n ex.debug.drawRect(0, 0, this.width, this.height);\r\n }\r\n ex.restore();\r\n }\r\n }\r\n}\r\n","export type Constructor = {\r\n new (...args: any[]): T;\r\n};\r\n/**\r\n * Configurable helper extends base type and makes all properties available as option bag arguments\r\n * @internal\r\n * @param base\r\n */\r\nexport function Configurable>(base: T): T {\r\n return class extends base {\r\n public assign(props: Partial) {\r\n //set the value of every property that was passed in,\r\n //if the constructor previously set this value, it will be overridden here\r\n for (const k in props) {\r\n // eslint-disable-next-line\r\n if (typeof (this)[k] !== 'function') {\r\n // eslint-disable-next-line\r\n (this)[k] = (props)[k];\r\n }\r\n }\r\n }\r\n\r\n constructor(...args: any[]) {\r\n super(...args);\r\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\r\n //of whatever ctor is the implementation, so args.length doesn't work here.\r\n const size = args.filter(function(value) {\r\n return value !== undefined;\r\n }).length;\r\n if (size === 1 && args[0] && typeof args[0] === 'object' && !(args[0] instanceof Array)) {\r\n this.assign(args[0]);\r\n }\r\n }\r\n };\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Actor } from './Actor';\r\nimport { Color } from './Color';\r\nimport { Vector, vec } from './Math/vector';\r\nimport * as Util from './Util/Util';\r\nimport { Configurable } from './Configurable';\r\nimport { Random } from './Math/Random';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { GraphicsComponent } from './Graphics/GraphicsComponent';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { BoundingBox } from './Collision/BoundingBox';\r\nimport { clamp, randomInRange } from './Math/util';\r\nimport { Graphic } from './Graphics';\r\n\r\n/**\r\n * An enum that represents the types of emitter nozzles\r\n */\r\nexport enum EmitterType {\r\n /**\r\n * Constant for the circular emitter type\r\n */\r\n Circle,\r\n /**\r\n * Constant for the rectangular emitter type\r\n */\r\n Rectangle\r\n}\r\n\r\n/**\r\n * @hidden\r\n */\r\nexport class ParticleImpl extends Entity {\r\n public position: Vector = new Vector(0, 0);\r\n public velocity: Vector = new Vector(0, 0);\r\n public acceleration: Vector = new Vector(0, 0);\r\n public particleRotationalVelocity: number = 0;\r\n public currentRotation: number = 0;\r\n\r\n public focus: Vector = null;\r\n public focusAccel: number = 0;\r\n public opacity: number = 1;\r\n public beginColor: Color = Color.White;\r\n public endColor: Color = Color.White;\r\n\r\n // Life is counted in ms\r\n public life: number = 300;\r\n public fadeFlag: boolean = false;\r\n\r\n // Color transitions\r\n private _rRate: number = 1;\r\n private _gRate: number = 1;\r\n private _bRate: number = 1;\r\n private _aRate: number = 0;\r\n private _currentColor: Color = Color.White;\r\n\r\n public emitter: ParticleEmitter = null;\r\n public particleSize: number = 5;\r\n public particleSprite: Graphic = null;\r\n\r\n public startSize: number;\r\n public endSize: number;\r\n public sizeRate: number = 0;\r\n public elapsedMultiplier: number = 0;\r\n\r\n public visible = true;\r\n public isOffscreen = false;\r\n\r\n public transform: TransformComponent;\r\n public graphics: GraphicsComponent;\r\n\r\n constructor(\r\n emitterOrConfig: ParticleEmitter | ParticleArgs,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number,\r\n particleSprite?: Graphic\r\n ) {\r\n super();\r\n let emitter = emitterOrConfig;\r\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\r\n const config = emitterOrConfig;\r\n emitter = config.emitter;\r\n life = config.life;\r\n opacity = config.opacity;\r\n endColor = config.endColor;\r\n beginColor = config.beginColor;\r\n position = config.position;\r\n velocity = config.velocity;\r\n acceleration = config.acceleration;\r\n startSize = config.startSize;\r\n endSize = config.endSize;\r\n particleSprite = config.particleSprite;\r\n }\r\n this.emitter = emitter;\r\n this.life = life || this.life;\r\n this.opacity = opacity || this.opacity;\r\n this.endColor = endColor || this.endColor.clone();\r\n this.beginColor = beginColor || this.beginColor.clone();\r\n this._currentColor = this.beginColor.clone();\r\n this.particleSprite = particleSprite;\r\n\r\n if (this.emitter.particleTransform === ParticleTransform.Global) {\r\n const globalPos = this.emitter.transform.globalPos;\r\n this.position = (position || this.position).add(globalPos);\r\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\r\n } else {\r\n this.velocity = velocity || this.velocity;\r\n this.position = (position || this.position);\r\n }\r\n this.acceleration = acceleration || this.acceleration;\r\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\r\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\r\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\r\n this._aRate = this.opacity / this.life;\r\n\r\n this.startSize = startSize || 0;\r\n this.endSize = endSize || 0;\r\n\r\n if (this.endSize > 0 && this.startSize > 0) {\r\n this.sizeRate = (this.endSize - this.startSize) / this.life;\r\n this.particleSize = this.startSize;\r\n }\r\n\r\n this.addComponent((this.transform = new TransformComponent()));\r\n this.addComponent((this.graphics = new GraphicsComponent()));\r\n\r\n this.transform.pos = this.position;\r\n this.transform.rotation = this.currentRotation;\r\n this.transform.scale = vec(1, 1); // TODO wut\r\n if (this.particleSprite) {\r\n this.graphics.opacity = this.opacity;\r\n this.graphics.use(this.particleSprite);\r\n } else {\r\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\r\n this.graphics.onPostDraw = (ctx) => {\r\n ctx.save();\r\n this.graphics.opacity = this.opacity;\r\n const tmpColor = this._currentColor.clone();\r\n tmpColor.a = 1;\r\n ctx.debug.drawPoint(vec(0, 0), { color: tmpColor, size: this.particleSize });\r\n ctx.restore();\r\n };\r\n }\r\n }\r\n\r\n public kill() {\r\n this.emitter.removeParticle(this);\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n this.life = this.life - delta;\r\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\r\n\r\n if (this.life < 0) {\r\n this.kill();\r\n }\r\n\r\n if (this.fadeFlag) {\r\n this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\r\n }\r\n\r\n if (this.startSize > 0 && this.endSize > 0) {\r\n this.particleSize = clamp(\r\n this.sizeRate * delta + this.particleSize,\r\n Math.min(this.startSize, this.endSize),\r\n Math.max(this.startSize, this.endSize)\r\n );\r\n }\r\n\r\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\r\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\r\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\r\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\r\n\r\n if (this.focus) {\r\n const accel = this.focus\r\n .sub(this.position)\r\n .normalize()\r\n .scale(this.focusAccel)\r\n .scale(delta / 1000);\r\n this.velocity = this.velocity.add(accel);\r\n } else {\r\n this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\r\n }\r\n this.position = this.position.add(this.velocity.scale(delta / 1000));\r\n\r\n if (this.particleRotationalVelocity) {\r\n this.currentRotation = (this.currentRotation + (this.particleRotationalVelocity * delta) / 1000) % (2 * Math.PI);\r\n }\r\n\r\n this.transform.pos = this.position;\r\n this.transform.rotation = this.currentRotation;\r\n this.transform.scale = vec(1, 1); // todo wut\r\n this.graphics.opacity = this.opacity;\r\n }\r\n}\r\n\r\nexport interface ParticleArgs extends Partial {\r\n emitter: ParticleEmitter;\r\n position?: Vector;\r\n velocity?: Vector;\r\n acceleration?: Vector;\r\n particleRotationalVelocity?: number;\r\n currentRotation?: number;\r\n particleSize?: number;\r\n particleSprite?: Graphic;\r\n}\r\n\r\n/**\r\n * Particle is used in a [[ParticleEmitter]]\r\n */\r\nexport class Particle extends Configurable(ParticleImpl) {\r\n constructor(config: ParticleArgs);\r\n constructor(\r\n emitter: ParticleEmitter,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number,\r\n particleSprite?: Graphic\r\n );\r\n constructor(\r\n emitterOrConfig: ParticleEmitter | ParticleArgs,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number,\r\n particleSprite?: Graphic\r\n ) {\r\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize, particleSprite);\r\n }\r\n}\r\n\r\nexport enum ParticleTransform {\r\n /**\r\n * [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n */\r\n Global = 'global',\r\n /**\r\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n Local = 'local'\r\n}\r\n\r\nexport interface ParticleEmitterArgs {\r\n x?: number;\r\n y?: number;\r\n pos?: Vector;\r\n width?: number;\r\n height?: number;\r\n isEmitting?: boolean;\r\n minVel?: number;\r\n maxVel?: number;\r\n acceleration?: Vector;\r\n minAngle?: number;\r\n maxAngle?: number;\r\n emitRate?: number;\r\n particleLife?: number;\r\n /**\r\n * Optionally set the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n *\r\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n particleTransform?: ParticleTransform;\r\n opacity?: number;\r\n fadeFlag?: boolean;\r\n focus?: Vector;\r\n focusAccel?: number;\r\n startSize?: number;\r\n endSize?: number;\r\n minSize?: number;\r\n maxSize?: number;\r\n beginColor?: Color;\r\n endColor?: Color;\r\n particleSprite?: Graphic;\r\n emitterType?: EmitterType;\r\n radius?: number;\r\n particleRotationalVelocity?: number;\r\n randomRotation?: boolean;\r\n random?: Random;\r\n}\r\n\r\n/**\r\n * Using a particle emitter is a great way to create interesting effects\r\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\r\n * extend [[Actor]] allowing you to use all of the features that come with.\r\n */\r\nexport class ParticleEmitter extends Actor {\r\n private _particlesToEmit: number = 0;\r\n\r\n public numParticles: number = 0;\r\n\r\n /**\r\n * Random number generator\r\n */\r\n public random: Random;\r\n\r\n /**\r\n * Gets or sets the isEmitting flag\r\n */\r\n public isEmitting: boolean = true;\r\n /**\r\n * Gets or sets the backing particle collection\r\n */\r\n public particles: Particle[] = [];\r\n\r\n /**\r\n * Gets or sets the backing deadParticle collection\r\n */\r\n public deadParticles: Particle[] = [];\r\n\r\n /**\r\n * Gets or sets the minimum particle velocity\r\n */\r\n public minVel: number = 0;\r\n /**\r\n * Gets or sets the maximum particle velocity\r\n */\r\n public maxVel: number = 0;\r\n\r\n /**\r\n * Gets or sets the acceleration vector for all particles\r\n */\r\n public acceleration: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Gets or sets the minimum angle in radians\r\n */\r\n public minAngle: number = 0;\r\n /**\r\n * Gets or sets the maximum angle in radians\r\n */\r\n public maxAngle: number = 0;\r\n\r\n /**\r\n * Gets or sets the emission rate for particles (particles/sec)\r\n */\r\n public emitRate: number = 1; //particles/sec\r\n /**\r\n * Gets or sets the life of each particle in milliseconds\r\n */\r\n public particleLife: number = 2000;\r\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */\r\n public get opacity(): number {\r\n return this.graphics.opacity;\r\n }\r\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */\r\n public set opacity(opacity: number) {\r\n this.graphics.opacity = opacity;\r\n }\r\n /**\r\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\r\n */\r\n public fadeFlag: boolean = false;\r\n\r\n /**\r\n * Gets or sets the optional focus where all particles should accelerate towards\r\n */\r\n public focus: Vector = null;\r\n /**\r\n * Gets or sets the acceleration for focusing particles if a focus has been specified\r\n */\r\n public focusAccel: number = null;\r\n /**\r\n * Gets or sets the optional starting size for the particles\r\n */\r\n public startSize: number = null;\r\n /**\r\n * Gets or sets the optional ending size for the particles\r\n */\r\n public endSize: number = null;\r\n\r\n /**\r\n * Gets or sets the minimum size of all particles\r\n */\r\n public minSize: number = 5;\r\n /**\r\n * Gets or sets the maximum size of all particles\r\n */\r\n public maxSize: number = 5;\r\n\r\n /**\r\n * Gets or sets the beginning color of all particles\r\n */\r\n public beginColor: Color = Color.White;\r\n /**\r\n * Gets or sets the ending color of all particles\r\n */\r\n public endColor: Color = Color.White;\r\n\r\n private _sprite: Graphic = null;\r\n /**\r\n * Gets or sets the sprite that a particle should use\r\n */\r\n public get particleSprite(): Graphic {\r\n return this._sprite;\r\n }\r\n\r\n public set particleSprite(val: Graphic) {\r\n if (val) {\r\n this._sprite = val;\r\n }\r\n }\r\n\r\n /**\r\n * Gets or sets the emitter type for the particle emitter\r\n */\r\n public emitterType: EmitterType = EmitterType.Rectangle;\r\n\r\n /**\r\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\r\n */\r\n public radius: number = 0;\r\n\r\n /**\r\n * Gets or sets the particle rotational speed velocity\r\n */\r\n public particleRotationalVelocity: number = 0;\r\n\r\n /**\r\n * Indicates whether particles should start with a random rotation\r\n */\r\n public randomRotation: boolean = false;\r\n\r\n /**\r\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n *\r\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n public particleTransform: ParticleTransform = ParticleTransform.Global;\r\n\r\n /**\r\n * @param config particle emitter options bag\r\n */\r\n constructor(config: ParticleEmitterArgs) {\r\n super({ width: config.width ?? 0, height: config.height ?? 0 });\r\n\r\n const {\r\n x,\r\n y,\r\n pos,\r\n isEmitting,\r\n minVel,\r\n maxVel,\r\n acceleration,\r\n minAngle,\r\n maxAngle,\r\n emitRate,\r\n particleLife,\r\n opacity,\r\n fadeFlag,\r\n focus,\r\n focusAccel,\r\n startSize,\r\n endSize,\r\n minSize,\r\n maxSize,\r\n beginColor,\r\n endColor,\r\n particleSprite,\r\n emitterType,\r\n radius,\r\n particleRotationalVelocity,\r\n particleTransform,\r\n randomRotation,\r\n random\r\n } = { ...config };\r\n\r\n this.pos = pos ?? vec(x ?? 0, y ?? 0);\r\n this.isEmitting = isEmitting ?? this.isEmitting;\r\n this.minVel = minVel ?? this.minVel;\r\n this.maxVel = maxVel ?? this.maxVel;\r\n this.acceleration = acceleration ?? this.acceleration;\r\n this.minAngle = minAngle ?? this.minAngle;\r\n this.maxAngle = maxAngle ?? this.maxAngle;\r\n this.emitRate = emitRate ?? this.emitRate;\r\n this.particleLife = particleLife ?? this.particleLife;\r\n this.opacity = opacity ?? this.opacity;\r\n this.fadeFlag = fadeFlag ?? this.fadeFlag;\r\n this.focus = focus ?? this.focus;\r\n this.focusAccel = focusAccel ?? this.focusAccel;\r\n this.startSize = startSize ?? this.startSize;\r\n this.endSize = endSize ?? this.endSize;\r\n this.minSize = minSize ?? this.minSize;\r\n this.maxSize = maxSize ?? this.maxSize;\r\n this.beginColor = beginColor ?? this.beginColor;\r\n this.endColor = endColor ?? this.endColor;\r\n this.particleSprite = particleSprite ?? this.particleSprite;\r\n this.emitterType = emitterType ?? this.emitterType;\r\n this.radius = radius ?? this.radius;\r\n this.particleRotationalVelocity = particleRotationalVelocity ?? this.particleRotationalVelocity;\r\n this.randomRotation = randomRotation ?? this.randomRotation;\r\n this.particleTransform = particleTransform ?? this.particleTransform;\r\n\r\n this.body.collisionType = CollisionType.PreventCollision;\r\n\r\n this.random = random ?? new Random();\r\n }\r\n\r\n public removeParticle(particle: Particle) {\r\n this.deadParticles.push(particle);\r\n }\r\n\r\n /**\r\n * Causes the emitter to emit particles\r\n * @param particleCount Number of particles to emit right now\r\n */\r\n public emitParticles(particleCount: number) {\r\n for (let i = 0; i < particleCount; i++) {\r\n const p = this._createParticle();\r\n this.particles.push(p);\r\n if (this?.scene?.world) {\r\n if (this.particleTransform === ParticleTransform.Global) {\r\n this.scene.world.add(p);\r\n } else {\r\n this.addChild(p);\r\n }\r\n }\r\n }\r\n }\r\n\r\n public clearParticles() {\r\n this.particles.length = 0;\r\n }\r\n\r\n // Creates a new particle given the constraints of the emitter\r\n private _createParticle(): Particle {\r\n // todo implement emitter constraints;\r\n let ranX = 0;\r\n let ranY = 0;\r\n\r\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\r\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\r\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\r\n const dx = vel * Math.cos(angle);\r\n const dy = vel * Math.sin(angle);\r\n\r\n if (this.emitterType === EmitterType.Rectangle) {\r\n ranX = randomInRange(0, this.width, this.random);\r\n ranY = randomInRange(0, this.height, this.random);\r\n } else if (this.emitterType === EmitterType.Circle) {\r\n const radius = randomInRange(0, this.radius, this.random);\r\n ranX = radius * Math.cos(angle);\r\n ranY = radius * Math.sin(angle);\r\n }\r\n\r\n const p = new Particle(\r\n this,\r\n this.particleLife,\r\n this.opacity,\r\n this.beginColor,\r\n this.endColor,\r\n new Vector(ranX, ranY),\r\n new Vector(dx, dy),\r\n this.acceleration,\r\n this.startSize,\r\n this.endSize,\r\n this.particleSprite\r\n );\r\n p.fadeFlag = this.fadeFlag;\r\n p.particleSize = size;\r\n p.particleRotationalVelocity = this.particleRotationalVelocity;\r\n if (this.randomRotation) {\r\n p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\r\n }\r\n if (this.focus) {\r\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\r\n p.focusAccel = this.focusAccel;\r\n }\r\n return p;\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n super.update(engine, delta);\r\n\r\n if (this.isEmitting) {\r\n this._particlesToEmit += this.emitRate * (delta / 1000);\r\n if (this._particlesToEmit > 1.0) {\r\n this.emitParticles(Math.floor(this._particlesToEmit));\r\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\r\n }\r\n }\r\n\r\n // deferred removal\r\n for (let i = 0; i < this.deadParticles.length; i++) {\r\n Util.removeItemFromArray(this.deadParticles[i], this.particles);\r\n if (this?.scene?.world) {\r\n this.scene.world.remove(this.deadParticles[i], false);\r\n }\r\n }\r\n this.deadParticles.length = 0;\r\n }\r\n}\r\n","import { Transform } from '../Math/transform';\r\n\r\n/**\r\n * Blend 2 transforms for interpolation, will interpolate from the context of newTx's parent if it exists\r\n */\r\nexport function blendTransform(oldTx: Transform, newTx: Transform, blend: number, target?: Transform): Transform {\r\n if (oldTx.parent !== newTx.parent) {\r\n // Caller expects a local transform\r\n // Adjust old tx to be local to the new parent whatever that is\r\n const oldTxWithNewParent = oldTx.clone();\r\n const oldGlobalPos = oldTx.globalPos.clone();\r\n const oldGlobalScale = oldTx.globalScale.clone();\r\n const oldGlobalRotation = oldTx.globalRotation;\r\n oldTxWithNewParent.parent = newTx.parent;\r\n oldTxWithNewParent.globalPos = oldGlobalPos;\r\n oldTxWithNewParent.globalScale = oldGlobalScale;\r\n oldTxWithNewParent.globalRotation = oldGlobalRotation;\r\n oldTx = oldTxWithNewParent;\r\n }\r\n let interpolatedPos = newTx.pos;\r\n let interpolatedScale = newTx.scale;\r\n let interpolatedRotation = newTx.rotation;\r\n\r\n interpolatedPos = newTx.pos.scale(blend).add(\r\n oldTx.pos.scale(1.0 - blend)\r\n );\r\n interpolatedScale = newTx.scale.scale(blend).add(\r\n oldTx.scale.scale(1.0 - blend)\r\n );\r\n // Rotational lerp https://stackoverflow.com/a/30129248\r\n const cosine = (1.0 - blend) * Math.cos(oldTx.rotation) + blend * Math.cos(newTx.rotation);\r\n const sine = (1.0 - blend) * Math.sin(oldTx.rotation) + blend * Math.sin(newTx.rotation);\r\n interpolatedRotation = Math.atan2(sine, cosine);\r\n\r\n const tx = target ?? new Transform();\r\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\r\n return tx;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function blendGlobalTransform(oldTx: Transform, newTx: Transform, blend: number, target?: Transform): Transform {\r\n let interpolatedPos = newTx.globalPos;\r\n let interpolatedScale = newTx.globalScale;\r\n let interpolatedRotation = newTx.globalRotation;\r\n\r\n interpolatedPos = newTx.globalPos.scale(blend).add(\r\n oldTx.globalPos.scale(1.0 - blend)\r\n );\r\n interpolatedScale = newTx.globalScale.scale(blend).add(\r\n oldTx.globalScale.scale(1.0 - blend)\r\n );\r\n // Rotational lerp https://stackoverflow.com/a/30129248\r\n const cosine = (1.0 - blend) * Math.cos(oldTx.globalRotation) + blend * Math.cos(newTx.globalRotation);\r\n const sine = (1.0 - blend) * Math.sin(oldTx.globalRotation) + blend * Math.sin(newTx.globalRotation);\r\n interpolatedRotation = Math.atan2(sine, cosine);\r\n\r\n const tx = target ?? new Transform();\r\n tx.setTransform(interpolatedPos, interpolatedRotation, interpolatedScale);\r\n return tx;\r\n}","import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Scene } from '../Scene';\r\nimport { GraphicsComponent } from './GraphicsComponent';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Camera } from '../Camera';\r\nimport { Query, System, SystemPriority, SystemType, World } from '../EntityComponentSystem';\r\nimport { Engine } from '../Engine';\r\nimport { GraphicsGroup } from './GraphicsGroup';\r\nimport { Particle } from '../Particles'; // this import seems to bomb wallaby\r\nimport { ParallaxComponent } from './ParallaxComponent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { BodyComponent } from '../Collision/BodyComponent';\r\nimport { FontCache } from './FontCache';\r\nimport { PostDrawEvent, PostTransformDrawEvent, PreDrawEvent, PreTransformDrawEvent } from '../Events';\r\nimport { Transform } from '../Math/transform';\r\nimport { blendTransform } from './TransformInterpolation';\r\nimport { Graphic } from './Graphic';\r\n\r\nexport class GraphicsSystem extends System {\r\n public readonly systemType = SystemType.Draw;\r\n public priority = SystemPriority.Average;\r\n private _token = 0;\r\n private _graphicsContext: ExcaliburGraphicsContext;\r\n private _camera: Camera;\r\n private _engine: Engine;\r\n private _sortedTransforms: TransformComponent[] = [];\r\n query: Query;\r\n public get sortedTransforms() {\r\n return this._sortedTransforms;\r\n }\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent, GraphicsComponent]);\r\n this.query.entityAdded$.subscribe(e => {\r\n const tx = e.get(TransformComponent);\r\n this._sortedTransforms.push(tx);\r\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\r\n this._zHasChanged = true;\r\n });\r\n this.query.entityRemoved$.subscribe(e => {\r\n const tx = e.get(TransformComponent);\r\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\r\n const index = this._sortedTransforms.indexOf(tx);\r\n if (index > -1) {\r\n this._sortedTransforms.splice(index, 1);\r\n }\r\n });\r\n }\r\n\r\n public initialize(world: World, scene: Scene): void {\r\n this._camera = scene.camera;\r\n this._engine = scene.engine;\r\n }\r\n\r\n private _zHasChanged = false;\r\n private _zIndexUpdate = () => {\r\n this._zHasChanged = true;\r\n };\r\n\r\n public preupdate(): void {\r\n // Graphics context could be switched to fallback in a new frame\r\n this._graphicsContext = this._engine.graphicsContext;\r\n if (this._zHasChanged) {\r\n this._sortedTransforms.sort((a, b) => {\r\n return a.z - b.z;\r\n });\r\n this._zHasChanged = false;\r\n }\r\n }\r\n\r\n public update(delta: number): void {\r\n this._token++;\r\n let graphics: GraphicsComponent;\r\n FontCache.checkAndClearCache();\r\n\r\n // This is a performance enhancement, most things are in world space\r\n // so if we can only do this once saves a ton of transform updates\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n for (const transform of this._sortedTransforms) {\r\n const entity = transform.owner as Entity;\r\n\r\n // If the entity is offscreen skip\r\n if (entity.hasTag('ex.offscreen')) {\r\n continue;\r\n }\r\n\r\n graphics = entity.get(GraphicsComponent);\r\n // Exit if graphics set to not visible\r\n if (!graphics.visible) {\r\n continue;\r\n }\r\n\r\n // Optionally run the onPreTransformDraw graphics lifecycle draw\r\n if (graphics.onPreTransformDraw) {\r\n graphics.onPreTransformDraw(this._graphicsContext, delta);\r\n }\r\n entity.events.emit('pretransformdraw', new PreTransformDrawEvent(this._graphicsContext, delta, entity));\r\n\r\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.restore();\r\n }\r\n\r\n this._graphicsContext.save();\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\r\n }\r\n\r\n // Tick any graphics state (but only once) for animations and graphics groups\r\n graphics.update(delta, this._token);\r\n\r\n // Apply parallax\r\n const parallax = entity.get(ParallaxComponent);\r\n if (parallax) {\r\n // We use the Tiled formula\r\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\r\n // cameraPos * (1 - parallaxFactor)\r\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\r\n const parallaxOffset = this._camera.drawPos.scale(oneMinusFactor);\r\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\r\n }\r\n\r\n // Position the entity + estimate lag\r\n this._applyTransform(entity);\r\n\r\n // If there is a material enable it on the context\r\n if (graphics.material) {\r\n this._graphicsContext.material = graphics.material;\r\n }\r\n\r\n // Optionally run the onPreDraw graphics lifecycle draw\r\n if (graphics.onPreDraw) {\r\n graphics.onPreDraw(this._graphicsContext, delta);\r\n }\r\n entity.events.emit('predraw', new PreDrawEvent(this._graphicsContext, delta, entity));\r\n\r\n // TODO remove this hack on the particle redo\r\n // Remove this line after removing the wallaby import\r\n const particleOpacity = (entity instanceof Particle) ? entity.opacity : 1;\r\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\r\n\r\n // Draw the graphics component\r\n this._drawGraphicsComponent(graphics, transform);\r\n\r\n // Optionally run the onPostDraw graphics lifecycle draw\r\n if (graphics.onPostDraw) {\r\n graphics.onPostDraw(this._graphicsContext, delta);\r\n }\r\n entity.events.emit('postdraw', new PostDrawEvent(this._graphicsContext, delta, entity));\r\n\r\n this._graphicsContext.restore();\r\n\r\n // Reset the transform back to the original world space\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n }\r\n\r\n // Optionally run the onPreTransformDraw graphics lifecycle draw\r\n if (graphics.onPostTransformDraw) {\r\n graphics.onPostTransformDraw(this._graphicsContext, delta);\r\n }\r\n entity.events.emit('posttransformdraw', new PostTransformDrawEvent(this._graphicsContext, delta, entity));\r\n }\r\n this._graphicsContext.restore();\r\n }\r\n\r\n private _drawGraphicsComponent(graphicsComponent: GraphicsComponent, transformComponent: TransformComponent) {\r\n if (graphicsComponent.visible) {\r\n const flipHorizontal = graphicsComponent.flipHorizontal;\r\n const flipVertical = graphicsComponent.flipVertical;\r\n\r\n const graphic = graphicsComponent.current;\r\n const options = graphicsComponent.currentOptions ?? {};\r\n\r\n if (graphic) {\r\n let anchor = graphicsComponent.anchor;\r\n let offset = graphicsComponent.offset;\r\n let scaleX = 1;\r\n let scaleY = 1;\r\n // handle specific overrides\r\n if (options?.anchor) {\r\n anchor = options.anchor;\r\n }\r\n if (options?.offset) {\r\n offset = options.offset;\r\n }\r\n const globalScale = transformComponent.globalScale;\r\n scaleX *= graphic.scale.x * globalScale.x;\r\n scaleY *= graphic.scale.y * globalScale.y;\r\n\r\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\r\n const offsetX = -graphic.width * anchor.x + offset.x * scaleX;\r\n const offsetY = -graphic.height * anchor.y + offset.y * scaleY;\r\n\r\n const oldFlipHorizontal = graphic.flipHorizontal;\r\n const oldFlipVertical = graphic.flipVertical;\r\n if (flipHorizontal || flipVertical) {\r\n // flip any currently flipped graphics\r\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\r\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\r\n }\r\n\r\n graphic?.draw(\r\n this._graphicsContext,\r\n offsetX,\r\n offsetY);\r\n\r\n if (flipHorizontal || flipVertical) {\r\n graphic.flipHorizontal = oldFlipHorizontal;\r\n graphic.flipVertical = oldFlipVertical;\r\n }\r\n\r\n // TODO move debug code out?\r\n if (this._engine?.isDebug && this._engine.debug.graphics.showBounds) {\r\n const offset = vec(offsetX, offsetY);\r\n if (graphic instanceof GraphicsGroup) {\r\n for (const member of graphic.members) {\r\n let g: Graphic;\r\n let pos: Vector = Vector.Zero;\r\n if (member instanceof Graphic) {\r\n g = member;\r\n } else {\r\n g = member.graphic;\r\n pos = member.offset;\r\n }\r\n g?.localBounds.translate(offset.add(pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\r\n }\r\n } else {\r\n /* istanbul ignore next */\r\n graphic?.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _targetInterpolationTransform = new Transform();\r\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */\r\n private _applyTransform(entity: Entity): void {\r\n const ancestors = entity.getAncestors();\r\n for (const ancestor of ancestors) {\r\n const transform = ancestor?.get(TransformComponent);\r\n const optionalBody = ancestor?.get(BodyComponent);\r\n let tx = transform.get();\r\n if (optionalBody) {\r\n if (this._engine.fixedUpdateFps &&\r\n optionalBody.__oldTransformCaptured &&\r\n optionalBody.enableFixedUpdateInterpolate) {\r\n // Interpolate graphics if needed\r\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\r\n tx = blendTransform(optionalBody.oldTransform, transform.get(), blend, this._targetInterpolationTransform);\r\n }\r\n }\r\n\r\n if (transform) {\r\n this._graphicsContext.z = transform.z;\r\n this._graphicsContext.translate(tx.pos.x, tx.pos.y);\r\n this._graphicsContext.scale(tx.scale.x, tx.scale.y);\r\n this._graphicsContext.rotate(tx.rotation);\r\n }\r\n }\r\n }\r\n}\r\n","import { Engine } from '../Engine';\r\nimport { Scene } from '../Scene';\r\nimport { Camera } from '../Camera';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { Entity, Query, SystemPriority, TransformComponent, World } from '../EntityComponentSystem';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ExcaliburGraphicsContext } from '../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { toDegrees } from '../Math/util';\r\nimport { BodyComponent } from '../Collision/BodyComponent';\r\nimport { CollisionSystem } from '../Collision/CollisionSystem';\r\nimport { CompositeCollider } from '../Collision/Colliders/CompositeCollider';\r\nimport { GraphicsComponent } from '../Graphics/GraphicsComponent';\r\nimport { Particle } from '../Particles';\r\nimport { DebugGraphicsComponent } from '../Graphics/DebugGraphicsComponent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { Debug } from '../Graphics/Debug';\r\n\r\nexport class DebugSystem extends System {\r\n public readonly systemType = SystemType.Draw;\r\n public priority = SystemPriority.Lowest;\r\n private _graphicsContext: ExcaliburGraphicsContext;\r\n private _collisionSystem: CollisionSystem;\r\n private _camera: Camera;\r\n private _engine: Engine;\r\n query: Query;\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent]);\r\n }\r\n\r\n public initialize(world: World, scene: Scene): void {\r\n this._graphicsContext = scene.engine.graphicsContext;\r\n this._camera = scene.camera;\r\n this._engine = scene.engine;\r\n this._collisionSystem = world.systemManager.get(CollisionSystem);\r\n }\r\n\r\n update(): void {\r\n if (!this._engine.isDebug) {\r\n return;\r\n }\r\n\r\n const filterSettings = this._engine.debug.filter;\r\n\r\n let id: number;\r\n let name: string;\r\n const entitySettings = this._engine.debug.entity;\r\n\r\n let tx: TransformComponent;\r\n const txSettings = this._engine.debug.transform;\r\n\r\n let motion: MotionComponent;\r\n const motionSettings = this._engine.debug.motion;\r\n\r\n let colliderComp: ColliderComponent;\r\n const colliderSettings = this._engine.debug.collider;\r\n\r\n const physicsSettings = this._engine.debug.physics;\r\n\r\n let graphics: GraphicsComponent;\r\n const graphicsSettings = this._engine.debug.graphics;\r\n\r\n let debugDraw: DebugGraphicsComponent;\r\n\r\n let body: BodyComponent;\r\n const bodySettings = this._engine.debug.body;\r\n\r\n const cameraSettings = this._engine.debug.camera;\r\n for (const entity of this.query.entities) {\r\n if (entity.hasTag('offscreen')) {\r\n // skip offscreen entities\r\n continue;\r\n }\r\n if (entity instanceof Particle) {\r\n // Particles crush the renderer :(\r\n continue;\r\n }\r\n if (filterSettings.useFilter) {\r\n const allIds = filterSettings.ids.length === 0;\r\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\r\n if (!idMatch) {\r\n continue;\r\n }\r\n const allNames = filterSettings.nameQuery === '';\r\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\r\n if (!nameMatch) {\r\n continue;\r\n }\r\n }\r\n\r\n let cursor = Vector.Zero;\r\n const lineHeight = vec(0, 16);\r\n id = entity.id;\r\n name = entity.name;\r\n tx = entity.get(TransformComponent);\r\n\r\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\r\n this._pushCameraTransform(tx);\r\n\r\n this._graphicsContext.save();\r\n if (tx.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\r\n }\r\n this._graphicsContext.z = txSettings.debugZIndex;\r\n\r\n this._applyTransform(entity);\r\n if (tx) {\r\n if (txSettings.showAll || txSettings.showPosition) {\r\n this._graphicsContext.debug.drawPoint(Vector.Zero, { size: 4, color: txSettings.positionColor });\r\n }\r\n if (txSettings.showAll || txSettings.showPositionLabel) {\r\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (txSettings.showAll || txSettings.showZIndex) {\r\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (entitySettings.showAll || entitySettings.showId) {\r\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? 'child of id(' + entity.parent?.id + ')' : ''}`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (entitySettings.showAll || entitySettings.showName) {\r\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (txSettings.showAll || txSettings.showRotation) {\r\n this._graphicsContext.drawLine(\r\n Vector.Zero,\r\n Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero),\r\n txSettings.rotationColor,\r\n 2\r\n );\r\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (txSettings.showAll || txSettings.showScale) {\r\n this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\r\n }\r\n }\r\n\r\n graphics = entity.get(GraphicsComponent);\r\n if (graphics) {\r\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\r\n const bounds = graphics.localBounds;\r\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\r\n }\r\n }\r\n\r\n debugDraw = entity.get(DebugGraphicsComponent);\r\n if (debugDraw) {\r\n if (!debugDraw.useTransform) {\r\n this._graphicsContext.restore();\r\n }\r\n debugDraw.draw(this._graphicsContext, this._engine.debug);\r\n if (!debugDraw.useTransform) {\r\n this._graphicsContext.save();\r\n this._applyTransform(entity);\r\n }\r\n }\r\n\r\n body = entity.get(BodyComponent);\r\n if (body) {\r\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\r\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showCollisionType) {\r\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showMass) {\r\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showMotion) {\r\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showSleeping) {\r\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping: 'cant sleep'})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n }\r\n\r\n this._graphicsContext.restore();\r\n\r\n // World space\r\n this._graphicsContext.save();\r\n if (tx.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\r\n }\r\n this._graphicsContext.z = txSettings.debugZIndex;\r\n motion = entity.get(MotionComponent);\r\n if (motion) {\r\n if (motionSettings.showAll || motionSettings.showVelocity) {\r\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\r\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (motionSettings.showAll || motionSettings.showAcceleration) {\r\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\r\n }\r\n }\r\n\r\n // Colliders live in world space already so after the restore()\r\n colliderComp = entity.get(ColliderComponent);\r\n if (colliderComp) {\r\n const collider = colliderComp.get();\r\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) {\r\n collider.debug(this._graphicsContext, colliderSettings.geometryColor, {\r\n lineWidth: colliderSettings.geometryLineWidth,\r\n pointSize: colliderSettings.geometryPointSize\r\n });\r\n }\r\n if (colliderSettings.showAll || colliderSettings.showBounds) {\r\n if (collider instanceof CompositeCollider) {\r\n const colliders = collider.getColliders();\r\n for (const collider of colliders) {\r\n const bounds = collider.bounds;\r\n const pos = vec(bounds.left, bounds.top);\r\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\r\n if (colliderSettings.showAll || colliderSettings.showOwner) {\r\n this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\r\n }\r\n }\r\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\r\n } else if (collider) {\r\n const bounds = colliderComp.bounds;\r\n const pos = vec(bounds.left, bounds.top);\r\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\r\n if (colliderSettings.showAll || colliderSettings.showOwner) {\r\n this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\r\n }\r\n }\r\n }\r\n }\r\n\r\n this._graphicsContext.restore();\r\n this._popCameraTransform(tx);\r\n }\r\n\r\n this._graphicsContext.save();\r\n this._camera.draw(this._graphicsContext);\r\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) {\r\n this._collisionSystem.debug(this._graphicsContext);\r\n }\r\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) {\r\n for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts) {\r\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) {\r\n for (const point of contact.points) {\r\n this._graphicsContext.debug.drawPoint(point, {\r\n size: physicsSettings.contactSize,\r\n color: physicsSettings.collisionContactColor\r\n });\r\n }\r\n }\r\n\r\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) {\r\n for (const point of contact.points) {\r\n this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\r\n color: physicsSettings.collisionNormalColor\r\n });\r\n }\r\n }\r\n }\r\n }\r\n this._graphicsContext.restore();\r\n\r\n if (cameraSettings) {\r\n this._graphicsContext.save();\r\n this._camera.draw(this._graphicsContext);\r\n if (cameraSettings.showAll || cameraSettings.showFocus) {\r\n this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\r\n }\r\n if (cameraSettings.showAll || cameraSettings.showZoom) {\r\n this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\r\n }\r\n this._graphicsContext.restore();\r\n }\r\n\r\n this._graphicsContext.flush();\r\n }\r\n\r\n postupdate(engine: Scene, elapsedMs: number): void {\r\n if (this._engine.isDebug) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n Debug.flush(this._graphicsContext);\r\n this._graphicsContext.restore();\r\n }\r\n }\r\n\r\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */\r\n private _applyTransform(entity: Entity): void {\r\n const ancestors = entity.getAncestors();\r\n for (const ancestor of ancestors) {\r\n const transform = ancestor?.get(TransformComponent);\r\n if (transform) {\r\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\r\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\r\n this._graphicsContext.rotate(transform.rotation);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Applies the current camera transform if in world coordinates\r\n * @param transform\r\n */\r\n private _pushCameraTransform(transform: TransformComponent) {\r\n // Establish camera offset per entity\r\n if (transform.coordPlane === CoordPlane.World) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resets the current camera transform if in world coordinates\r\n * @param transform\r\n */\r\n private _popCameraTransform(transform: TransformComponent) {\r\n if (transform.coordPlane === CoordPlane.World) {\r\n // Apply camera world offset\r\n this._graphicsContext.restore();\r\n }\r\n }\r\n}\r\n","import { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { Engine } from '../Engine';\r\nimport {\r\n System,\r\n TransformComponent,\r\n SystemType,\r\n Entity,\r\n World,\r\n Query,\r\n SystemPriority\r\n} from '../EntityComponentSystem';\r\nimport { GraphicsComponent } from '../Graphics/GraphicsComponent';\r\nimport { Scene } from '../Scene';\r\nimport { PointerComponent } from './PointerComponent';\r\nimport { PointerEventReceiver } from './PointerEventReceiver';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\n\r\n/**\r\n * The PointerSystem is responsible for dispatching pointer events to entities\r\n * that need them.\r\n *\r\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\r\n * the [[Collider]]'s shape for pointer events.\r\n */\r\nexport class PointerSystem extends System {\r\n public readonly systemType = SystemType.Update;\r\n public priority = SystemPriority.Higher;\r\n\r\n private _engine: Engine;\r\n private _receivers: PointerEventReceiver[];\r\n private _engineReceiver: PointerEventReceiver;\r\n query: Query;\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent, PointerComponent]);\r\n this.query.entityAdded$.subscribe(e => {\r\n const tx = e.get(TransformComponent);\r\n this._sortedTransforms.push(tx);\r\n this._sortedEntities.push(tx.owner);\r\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\r\n this._zHasChanged = true;\r\n });\r\n\r\n this.query.entityRemoved$.subscribe(e => {\r\n const tx = e.get(TransformComponent);\r\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\r\n const index = this._sortedTransforms.indexOf(tx);\r\n if (index > -1) {\r\n this._sortedTransforms.splice(index, 1);\r\n this._sortedEntities.splice(index, 1);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Optionally override component configuration for all entities\r\n */\r\n public overrideUseColliderShape = false;\r\n /**\r\n * Optionally override component configuration for all entities\r\n */\r\n public overrideUseGraphicsBounds = false;\r\n\r\n public lastFrameEntityToPointers = new Map();\r\n public currentFrameEntityToPointers = new Map();\r\n private _scene: Scene;\r\n\r\n public initialize(world: World, scene: Scene): void {\r\n this._engine = scene.engine;\r\n this._scene = scene;\r\n }\r\n\r\n private _sortedTransforms: TransformComponent[] = [];\r\n private _sortedEntities: Entity[] = [];\r\n\r\n private _zHasChanged = false;\r\n private _zIndexUpdate = () => {\r\n this._zHasChanged = true;\r\n };\r\n\r\n public preupdate(): void {\r\n // event receiver might change per frame\r\n this._receivers = [this._engine.input.pointers, this._scene.input.pointers];\r\n this._engineReceiver = this._engine.input.pointers;\r\n if (this._zHasChanged) {\r\n this._sortedTransforms.sort((a, b) => {\r\n return b.z - a.z;\r\n });\r\n this._sortedEntities = this._sortedTransforms.map(t => t.owner);\r\n this._zHasChanged = false;\r\n }\r\n }\r\n\r\n\r\n\r\n public entityCurrentlyUnderPointer(entity: Entity, pointerId: number) {\r\n return this.currentFrameEntityToPointers.has(entity.id) &&\r\n this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\r\n }\r\n\r\n public entityWasUnderPointer(entity: Entity, pointerId: number) {\r\n return this.lastFrameEntityToPointers.has(entity.id) &&\r\n this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\r\n }\r\n\r\n public entered(entity: Entity, pointerId: number) {\r\n return this.entityCurrentlyUnderPointer(entity, pointerId) &&\r\n !this.lastFrameEntityToPointers.has(entity.id);\r\n }\r\n\r\n public left(entity: Entity, pointerId: number) {\r\n return !this.currentFrameEntityToPointers.has(entity.id) &&\r\n this.entityWasUnderPointer(entity, pointerId);\r\n }\r\n\r\n public addPointerToEntity(entity: Entity, pointerId: number) {\r\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\r\n this.currentFrameEntityToPointers.set(entity.id, [pointerId]);\r\n return;\r\n }\r\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\r\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\r\n }\r\n\r\n public update(): void {\r\n // Locate all the pointer/entity mappings\r\n this._processPointerToEntity(this._sortedEntities);\r\n\r\n // Dispatch pointer events on entities\r\n this._dispatchEvents(this._sortedEntities);\r\n\r\n // Clear last frame's events\r\n this._receivers.forEach(r => r.update());\r\n this.lastFrameEntityToPointers.clear();\r\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\r\n this.currentFrameEntityToPointers.clear();\r\n this._receivers.forEach(r => r.clear());\r\n }\r\n\r\n private _processPointerToEntity(entities: Entity[]) {\r\n let transform: TransformComponent;\r\n let collider: ColliderComponent;\r\n let graphics: GraphicsComponent;\r\n let pointer: PointerComponent;\r\n const receiver = this._engineReceiver;\r\n\r\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\r\n // doesn't seem to cause issues tho for perf\r\n\r\n // Pre-process find entities under pointers\r\n for (const entity of entities) {\r\n transform = entity.get(TransformComponent);\r\n pointer = entity.get(PointerComponent) ?? new PointerComponent;\r\n // Check collider contains pointer\r\n collider = entity.get(ColliderComponent);\r\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\r\n collider.update();\r\n const geom = collider.get();\r\n if (geom) {\r\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries()) {\r\n if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\r\n this.addPointerToEntity(entity, pointerId);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Check graphics contains pointer\r\n graphics = entity.get(GraphicsComponent);\r\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\r\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\r\n for (const [pointerId, pos] of receiver.currentFramePointerCoords.entries()) {\r\n if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\r\n this.addPointerToEntity(entity, pointerId);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _processDownAndEmit(entity: Entity): Map {\r\n const receiver = this._engineReceiver;\r\n const lastDownPerPointer = new Map(); // TODO will this get confused between receivers?\r\n // Loop through down and dispatch to entities\r\n for (const event of receiver.currentFrameDown) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointerdown', event as any);\r\n if (receiver.isDragStart(event.pointerId)) {\r\n entity.events.emit('pointerdragstart', event as any);\r\n }\r\n }\r\n lastDownPerPointer.set(event.pointerId, event);\r\n }\r\n return lastDownPerPointer;\r\n }\r\n\r\n private _processUpAndEmit(entity: Entity): Map {\r\n const receiver = this._engineReceiver;\r\n const lastUpPerPointer = new Map();\r\n // Loop through up and dispatch to entities\r\n for (const event of receiver.currentFrameUp) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointerup', event as any);\r\n if (receiver.isDragEnd(event.pointerId)) {\r\n entity.events.emit('pointerdragend', event as any);\r\n }\r\n }\r\n lastUpPerPointer.set(event.pointerId, event);\r\n }\r\n return lastUpPerPointer;\r\n }\r\n\r\n private _processMoveAndEmit(entity: Entity): Map {\r\n const receiver = this._engineReceiver;\r\n const lastMovePerPointer = new Map();\r\n // Loop through move and dispatch to entities\r\n for (const event of receiver.currentFrameMove) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n // move\r\n entity.events.emit('pointermove', event as any);\r\n\r\n if (receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragmove', event as any);\r\n }\r\n }\r\n lastMovePerPointer.set(event.pointerId, event);\r\n }\r\n return lastMovePerPointer;\r\n }\r\n\r\n private _processEnterLeaveAndEmit(entity: Entity, lastUpDownMoveEvents: PointerEvent[]) {\r\n const receiver = this._engineReceiver;\r\n // up, down, and move are considered for enter and leave\r\n for (const event of lastUpDownMoveEvents) {\r\n // enter\r\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\r\n entity.events.emit('pointerenter', event as any);\r\n if (receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragenter', event as any);\r\n }\r\n break;\r\n }\r\n if (event.active && entity.active &&\r\n // leave can happen on move\r\n (this.left(entity, event.pointerId) ||\r\n // or leave can happen on pointer up\r\n (this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === 'up'))) {\r\n entity.events.emit('pointerleave', event as any);\r\n if (receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragleave', event as any);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private _processCancelAndEmit(entity: Entity) {\r\n const receiver = this._engineReceiver;\r\n // cancel\r\n for (const event of receiver.currentFrameCancel) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)){\r\n entity.events.emit('pointercancel', event as any);\r\n }\r\n }\r\n }\r\n\r\n private _processWheelAndEmit(entity: Entity) {\r\n const receiver = this._engineReceiver;\r\n // wheel\r\n for (const event of receiver.currentFrameWheel) {\r\n // Currently the wheel only fires under the primary pointer '0'\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) {\r\n entity.events.emit('pointerwheel', event as any);\r\n }\r\n }\r\n }\r\n\r\n private _dispatchEvents(entities: Entity[]) {\r\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\r\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\r\n // Filter preserves z order\r\n const entitiesWithEvents = entities.filter(e => lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\r\n let lastMovePerPointer: Map;\r\n let lastUpPerPointer: Map;\r\n let lastDownPerPointer: Map;\r\n // Dispatch events in entity z order\r\n for (const entity of entitiesWithEvents) {\r\n lastDownPerPointer = this._processDownAndEmit(entity);\r\n\r\n lastUpPerPointer = this._processUpAndEmit(entity);\r\n\r\n lastMovePerPointer = this._processMoveAndEmit(entity);\r\n\r\n const lastUpDownMoveEvents = [\r\n ...lastMovePerPointer.values(),\r\n ...lastDownPerPointer.values(),\r\n ...lastUpPerPointer.values()\r\n ];\r\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\r\n\r\n this._processCancelAndEmit(entity);\r\n\r\n this._processWheelAndEmit(entity);\r\n }\r\n }\r\n}","import { Query, SystemPriority, World } from '../EntityComponentSystem';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ActionsComponent } from './ActionsComponent';\r\n\r\nexport class ActionsSystem extends System {\r\n systemType = SystemType.Update;\r\n priority = SystemPriority.Higher;\r\n private _actions: ActionsComponent[] = [];\r\n query: Query;\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([ActionsComponent]);\r\n\r\n this.query.entityAdded$.subscribe(e => this._actions.push(e.get(ActionsComponent)));\r\n this.query.entityRemoved$.subscribe(e => {\r\n const action = e.get(ActionsComponent);\r\n const index = this._actions.indexOf(action);\r\n if (index > -1) {\r\n this._actions.splice(index, 1);\r\n }\r\n });\r\n }\r\n update(delta: number): void {\r\n for (const actions of this._actions) {\r\n actions.update(delta);\r\n }\r\n }\r\n}","import { Component } from '../EntityComponentSystem/Component';\r\nimport { IsometricMap } from './IsometricMap';\r\n\r\nexport interface IsometricEntityComponentOptions {\r\n columns: number;\r\n rows: number;\r\n tileWidth: number;\r\n tileHeight: number;\r\n}\r\n\r\nexport class IsometricEntityComponent extends Component {\r\n /**\r\n * Vertical \"height\" in the isometric world\r\n */\r\n public elevation: number = 0;\r\n\r\n public readonly columns: number;\r\n public readonly rows: number;\r\n public readonly tileWidth: number;\r\n public readonly tileHeight: number;\r\n\r\n /**\r\n * Specify the isometric map to use to position this entity's z-index\r\n * @param mapOrOptions\r\n */\r\n constructor(mapOrOptions: IsometricMap | IsometricEntityComponentOptions) {\r\n super();\r\n this.columns = mapOrOptions.columns;\r\n this.rows = mapOrOptions.rows;\r\n this.tileWidth = mapOrOptions.tileWidth;\r\n this.tileHeight = mapOrOptions.tileHeight;\r\n }\r\n}","import { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { IsometricEntityComponent } from './IsometricEntityComponent';\r\nimport { Query, SystemPriority, World } from '../EntityComponentSystem';\r\n\r\n\r\nexport class IsometricEntitySystem extends System {\r\n public readonly systemType = SystemType.Update;\r\n priority: number = SystemPriority.Lower;\r\n query: Query;\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent, IsometricEntityComponent]);\r\n }\r\n\r\n update(): void {\r\n let transform: TransformComponent;\r\n let iso: IsometricEntityComponent;\r\n for (const entity of this.query.entities) {\r\n transform = entity.get(TransformComponent);\r\n iso = entity.get(IsometricEntityComponent);\r\n\r\n const maxZindexPerElevation = Math.max(iso.columns * iso.tileWidth, iso.rows * iso.tileHeight);\r\n\r\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\r\n transform.z = newZ;\r\n }\r\n }\r\n}","import { GraphicsComponent } from './GraphicsComponent';\r\nimport { EnterViewPortEvent, ExitViewPortEvent } from '../Events';\r\nimport { Scene } from '../Scene';\r\nimport { Screen } from '../Screen';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Camera } from '../Camera';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ParallaxComponent } from './ParallaxComponent';\r\nimport { Vector } from '../Math/vector';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Query, SystemPriority, World } from '../EntityComponentSystem';\r\n\r\nexport class OffscreenSystem extends System {\r\n public systemType = SystemType.Draw;\r\n priority: number = SystemPriority.Higher;\r\n private _camera: Camera;\r\n private _screen: Screen;\r\n private _worldBounds: BoundingBox;\r\n query: Query;\r\n\r\n\r\n constructor(public world: World) {\r\n super();\r\n this.query = this.world.query([TransformComponent, GraphicsComponent]);\r\n }\r\n\r\n public initialize(world: World, scene: Scene): void {\r\n this._camera = scene.camera;\r\n this._screen = scene.engine.screen;\r\n }\r\n\r\n update(): void {\r\n this._worldBounds = this._screen.getWorldBounds();\r\n let transform: TransformComponent;\r\n let graphics: GraphicsComponent;\r\n let maybeParallax: ParallaxComponent;\r\n\r\n for (const entity of this.query.entities) {\r\n graphics = entity.get(GraphicsComponent);\r\n transform = entity.get(TransformComponent);\r\n maybeParallax = entity.get(ParallaxComponent);\r\n\r\n let parallaxOffset: Vector;\r\n if (maybeParallax) {\r\n // We use the Tiled formula\r\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\r\n // cameraPos * (1 - parallaxFactor)\r\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\r\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\r\n }\r\n\r\n // Figure out if entities are offscreen\r\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\r\n if (entityOffscreen && !entity.hasTag('ex.offscreen')) {\r\n entity.events.emit('exitviewport', new ExitViewPortEvent(entity));\r\n entity.addTag('ex.offscreen');\r\n }\r\n\r\n if (!entityOffscreen && entity.hasTag('ex.offscreen')) {\r\n entity.events.emit('enterviewport', new EnterViewPortEvent(entity));\r\n entity.removeTag('ex.offscreen');\r\n }\r\n }\r\n }\r\n\r\n private _isOffscreen(transform: TransformComponent, graphics: GraphicsComponent, parallaxOffset: Vector) {\r\n if (transform.coordPlane === CoordPlane.World) {\r\n let bounds = graphics.localBounds;\r\n if (parallaxOffset) {\r\n bounds = bounds.translate(parallaxOffset);\r\n }\r\n const transformedBounds = bounds.transform(transform.get().matrix);\r\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\r\n return graphicsOffscreen;\r\n } else {\r\n // TODO screen coordinates\r\n return false;\r\n }\r\n }\r\n\r\n}","import { Ray } from '../Math/ray';\r\nimport { DeepRequired } from '../Util/Required';\r\nimport { Observable } from '../Util/Observable';\r\nimport { DynamicTreeCollisionProcessor, RayCastHit, RayCastOptions } from './Index';\r\nimport { BodyComponent } from './BodyComponent';\r\nimport { PhysicsConfig } from './PhysicsConfig';\r\nimport { watchDeep } from '../Util/Watch';\r\n\r\nexport class PhysicsWorld {\r\n\r\n $configUpdate = new Observable>;\r\n\r\n private _configDirty = false;\r\n private _config: DeepRequired;\r\n get config(): DeepRequired {\r\n return watchDeep(this._config, change => {\r\n this.$configUpdate.notifyAll(change);\r\n });\r\n }\r\n set config(newConfig: DeepRequired) {\r\n this._config = newConfig;\r\n this.$configUpdate.notifyAll(newConfig);\r\n }\r\n\r\n private _collisionProcessor: DynamicTreeCollisionProcessor;\r\n /**\r\n * Spatial data structure for locating potential collision pairs and ray casts\r\n */\r\n public get collisionProcessor(): DynamicTreeCollisionProcessor {\r\n if (this._configDirty) {\r\n this._configDirty = false;\r\n // preserve tracked colliders if config updates\r\n const colliders = this._collisionProcessor.getColliders();\r\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this._config);\r\n for (const collider of colliders) {\r\n this._collisionProcessor.track(collider);\r\n }\r\n }\r\n return this._collisionProcessor;\r\n }\r\n constructor(config: DeepRequired) {\r\n this.config = config;\r\n this.$configUpdate.subscribe((config) => {\r\n this._configDirty = true;\r\n BodyComponent.updateDefaultPhysicsConfig(config.bodies);\r\n });\r\n this._collisionProcessor = new DynamicTreeCollisionProcessor(this.config);\r\n }\r\n\r\n /**\r\n * Raycast into the scene's physics world\r\n * @param ray\r\n * @param options\r\n */\r\n public rayCast(ray: Ray, options?: RayCastOptions): RayCastHit[] {\r\n return this.collisionProcessor.rayCast(ray, options);\r\n }\r\n}","import { GamepadConnectEvent, GamepadDisconnectEvent, GamepadButtonEvent, GamepadAxisEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\nexport type GamepadEvents = {\r\n connect: GamepadConnectEvent,\r\n disconnect: GamepadDisconnectEvent,\r\n button: GamepadButtonEvent,\r\n axis: GamepadAxisEvent\r\n}\r\n\r\nexport const GamepadEvents = {\r\n GamepadConnect: 'connect',\r\n GamepadDisconnect: 'disconnect',\r\n GamepadButton: 'button',\r\n GamepadAxis: 'axis'\r\n};\r\n\r\n/**\r\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\r\n * to provide controller support for your games.\r\n */\r\nexport class Gamepads {\r\n public events = new EventEmitter();\r\n /**\r\n * Whether or not to poll for Gamepad input (default: `false`)\r\n */\r\n public enabled = false;\r\n\r\n /**\r\n * Whether or not Gamepad API is supported\r\n */\r\n public supported = !!(navigator).getGamepads;\r\n\r\n /**\r\n * The minimum value an axis has to move before considering it a change\r\n */\r\n public static MinAxisMoveThreshold = 0.05;\r\n\r\n private _gamePadTimeStamps = [0, 0, 0, 0];\r\n private _oldPads: Gamepad[] = [];\r\n private _pads: Gamepad[] = [];\r\n private _initSuccess: boolean = false;\r\n private _navigator: NavigatorGamepads = navigator;\r\n private _minimumConfiguration: GamepadConfiguration = null;\r\n private _enabled = true;\r\n\r\n public init() {\r\n if (!this.supported) {\r\n return;\r\n }\r\n if (this._initSuccess) {\r\n return;\r\n }\r\n\r\n // In Chrome, this will return 4 undefined items until a button is pressed\r\n // In FF, this will not return any items until a button is pressed\r\n this._oldPads = this._clonePads(this._navigator.getGamepads());\r\n if (this._oldPads.length && this._oldPads[0]) {\r\n this._initSuccess = true;\r\n }\r\n }\r\n\r\n public toggleEnabled(enabled: boolean) {\r\n this._enabled = enabled;\r\n }\r\n\r\n /**\r\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\r\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\r\n * all other controllers with more axis or buttons are valid as well. If no minimum\r\n * configuration is set all pads are valid.\r\n */\r\n public setMinimumGamepadConfiguration(config: GamepadConfiguration): void {\r\n this._enableAndUpdate(); // if config is used, implicitly enable\r\n this._minimumConfiguration = config;\r\n }\r\n\r\n /**\r\n * When implicitly enabled, set the enabled flag and run an update so information is updated\r\n */\r\n private _enableAndUpdate() {\r\n if (!this.enabled) {\r\n this.enabled = true;\r\n this.update();\r\n }\r\n }\r\n\r\n /**\r\n * Checks a navigator gamepad against the minimum configuration if present.\r\n */\r\n private _isGamepadValid(pad: NavigatorGamepad): boolean {\r\n if (!this._minimumConfiguration) {\r\n return true;\r\n }\r\n if (!pad) {\r\n return false;\r\n }\r\n const axesLength = pad.axes.filter((value) => {\r\n return typeof value !== undefined;\r\n }).length;\r\n\r\n const buttonLength = pad.buttons.filter((value) => {\r\n return typeof value !== undefined;\r\n }).length;\r\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: GamepadEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._enableAndUpdate(); // implicitly enable\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this._enableAndUpdate(); // implicitly enable\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Updates Gamepad state and publishes Gamepad events\r\n */\r\n public update() {\r\n if (!this.enabled || !this.supported) {\r\n return;\r\n }\r\n if (!this._enabled) {\r\n return;\r\n }\r\n this.init();\r\n\r\n const gamepads = this._navigator.getGamepads();\r\n\r\n for (let i = 0; i < gamepads.length; i++) {\r\n if (!gamepads[i]) {\r\n const gamepad = this.at(i);\r\n // If was connected, but now isn't emit the disconnect event\r\n if (gamepad.connected) {\r\n this.events.emit('disconnect', new GamepadDisconnectEvent(i, gamepad));\r\n }\r\n // Reset connection status\r\n gamepad.connected = false;\r\n continue;\r\n } else {\r\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) {\r\n this.events.emit('connect', new GamepadConnectEvent(i, this.at(i)));\r\n }\r\n // Set connection status\r\n this.at(i).connected = true;\r\n }\r\n\r\n this.at(i).update();\r\n\r\n // Only supported in Chrome\r\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) {\r\n continue;\r\n }\r\n\r\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\r\n\r\n // Add reference to navigator gamepad\r\n this.at(i).navigatorGamepad = gamepads[i];\r\n\r\n // Buttons\r\n let b: string, bi: number, a: string, ai: number, value: number;\r\n\r\n for (b in Buttons) {\r\n bi = Buttons[b];\r\n if (typeof bi === 'number') {\r\n if (gamepads[i].buttons[bi]) {\r\n value = gamepads[i].buttons[bi].value;\r\n if (value !== this._oldPads[i].getButton(bi)) {\r\n if (gamepads[i].buttons[bi].pressed) {\r\n this.at(i).updateButton(bi, value);\r\n this.at(i).events.emit('button', new GamepadButtonEvent(bi, value, this.at(i)));\r\n } else {\r\n this.at(i).updateButton(bi, 0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Axes\r\n for (a in Axes) {\r\n ai = Axes[a];\r\n if (typeof ai === 'number') {\r\n value = gamepads[i].axes[ai];\r\n if (value !== this._oldPads[i].getAxes(ai)) {\r\n this.at(i).updateAxes(ai, value);\r\n this.at(i).events.emit('axis', new GamepadAxisEvent(ai, value, this.at(i)));\r\n }\r\n }\r\n }\r\n\r\n this._oldPads[i] = this._clonePad(gamepads[i]);\r\n }\r\n }\r\n\r\n /**\r\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\r\n */\r\n public at(index: number): Gamepad {\r\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\r\n if (index >= this._pads.length) {\r\n // Ensure there is a pad to retrieve\r\n for (let i = this._pads.length - 1, max = index; i < max; i++) {\r\n this._pads.push(new Gamepad());\r\n this._oldPads.push(new Gamepad());\r\n }\r\n }\r\n\r\n return this._pads[index];\r\n }\r\n\r\n /**\r\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\r\n */\r\n public getValidGamepads(): Gamepad[] {\r\n this._enableAndUpdate();\r\n const result: Gamepad[] = [];\r\n for (let i = 0; i < this._pads.length; i++) {\r\n if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) {\r\n result.push(this.at(i));\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets the number of connected gamepads\r\n */\r\n public count() {\r\n return this._pads.filter((p) => p.connected).length;\r\n }\r\n\r\n private _clonePads(pads: NavigatorGamepad[]): Gamepad[] {\r\n const arr = [];\r\n for (let i = 0, len = pads.length; i < len; i++) {\r\n arr.push(this._clonePad(pads[i]));\r\n }\r\n return arr;\r\n }\r\n\r\n /**\r\n * Fastest way to clone a known object is to do it yourself\r\n */\r\n private _clonePad(pad: NavigatorGamepad): Gamepad {\r\n let i, len;\r\n const clonedPad = new Gamepad();\r\n\r\n if (!pad) {\r\n return clonedPad;\r\n }\r\n\r\n for (i = 0, len = pad.buttons.length; i < len; i++) {\r\n if (pad.buttons[i]) {\r\n clonedPad.updateButton(i, pad.buttons[i].value);\r\n }\r\n }\r\n for (i = 0, len = pad.axes.length; i < len; i++) {\r\n clonedPad.updateAxes(i, pad.axes[i]);\r\n }\r\n\r\n\r\n return clonedPad;\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\r\n * for more information on handling controller input.\r\n */\r\nexport class Gamepad {\r\n public events = new EventEmitter();\r\n public connected = false;\r\n public navigatorGamepad: NavigatorGamepad;\r\n private _axes: number[] = new Array(4);\r\n private _buttons: number[] = new Array(16);\r\n private _buttonsUp: number[] = new Array(16);\r\n private _buttonsDown: number[] = new Array(16);\r\n\r\n constructor() {\r\n for (let i = 0; i < this._buttons.length; i++) {\r\n this._buttons[i] = 0;\r\n }\r\n for (let i = 0; i < this._axes.length; i++) {\r\n this._axes[i] = 0;\r\n }\r\n }\r\n\r\n public update() {\r\n // Reset buttonsDown and buttonsUp after update is complete\r\n this._buttonsDown = new Array(16);\r\n this._buttonsUp = new Array(16);\r\n }\r\n\r\n /**\r\n * Whether or not the given button is pressed\r\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public isButtonPressed(button: Buttons, threshold: number = 1) {\r\n return this._buttons[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button is held down. This is persisted between frames.\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public isButtonHeld(button: Buttons, threshold: number = 1) {\r\n return this._buttons[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\r\n * @param button Test whether a button was just pressed\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public wasButtonPressed(button: Buttons, threshold: number = 1) {\r\n return this._buttonsDown[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\r\n * @param button Test whether a button was just released\r\n */\r\n public wasButtonReleased(button: Buttons) {\r\n return Boolean(this._buttonsUp[button]);\r\n }\r\n\r\n /**\r\n * Gets the given button value between 0 and 1\r\n */\r\n public getButton(button: Buttons) {\r\n return this._buttons[button];\r\n }\r\n\r\n /**\r\n * Gets the given axis value between -1 and 1. Values below\r\n * [[MinAxisMoveThreshold]] are considered 0.\r\n */\r\n public getAxes(axes: Axes) {\r\n const value = this._axes[axes];\r\n\r\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) {\r\n return 0;\r\n } else {\r\n return value;\r\n }\r\n }\r\n\r\n public updateButton(buttonIndex: number, value: number) {\r\n // button was just released\r\n if (value === 0 && this._buttons[buttonIndex]) {\r\n this._buttonsUp[buttonIndex] = 1;\r\n\r\n // button was just pressed\r\n } else {\r\n this._buttonsDown[buttonIndex] = value;\r\n }\r\n\r\n this._buttons[buttonIndex] = value;\r\n }\r\n\r\n public updateAxes(axesIndex: number, value: number) {\r\n this._axes[axesIndex] = value;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: GamepadEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad Buttons enumeration\r\n */\r\nexport enum Buttons {\r\n /**\r\n * Face 1 button (e.g. A)\r\n */\r\n Face1 = 0,\r\n /**\r\n * Face 2 button (e.g. B)\r\n */\r\n Face2 = 1,\r\n /**\r\n * Face 3 button (e.g. X)\r\n */\r\n Face3 = 2,\r\n /**\r\n * Face 4 button (e.g. Y)\r\n */\r\n Face4 = 3,\r\n /**\r\n * Left bumper button\r\n */\r\n LeftBumper = 4,\r\n /**\r\n * Right bumper button\r\n */\r\n RightBumper = 5,\r\n /**\r\n * Left trigger button\r\n */\r\n LeftTrigger = 6,\r\n /**\r\n * Right trigger button\r\n */\r\n RightTrigger = 7,\r\n /**\r\n * Select button\r\n */\r\n Select = 8,\r\n /**\r\n * Start button\r\n */\r\n Start = 9,\r\n /**\r\n * Left analog stick press (e.g. L3)\r\n */\r\n LeftStick = 10,\r\n /**\r\n * Right analog stick press (e.g. R3)\r\n */\r\n RightStick = 11,\r\n /**\r\n * D-pad up\r\n */\r\n DpadUp = 12,\r\n /**\r\n * D-pad down\r\n */\r\n DpadDown = 13,\r\n /**\r\n * D-pad left\r\n */\r\n DpadLeft = 14,\r\n /**\r\n * D-pad right\r\n */\r\n DpadRight = 15\r\n}\r\n\r\n/**\r\n * Gamepad Axes enumeration\r\n */\r\nexport enum Axes {\r\n /**\r\n * Left analogue stick X direction\r\n */\r\n LeftStickX = 0,\r\n /**\r\n * Left analogue stick Y direction\r\n */\r\n LeftStickY = 1,\r\n /**\r\n * Right analogue stick X direction\r\n */\r\n RightStickX = 2,\r\n /**\r\n * Right analogue stick Y direction\r\n */\r\n RightStickY = 3\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepads {\r\n getGamepads(): NavigatorGamepad[];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepad {\r\n axes: number[];\r\n buttons: NavigatorGamepadButton[];\r\n connected: boolean;\r\n id: string;\r\n index: number;\r\n mapping: string;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepadButton {\r\n pressed: boolean;\r\n value: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepadEvent {\r\n gamepad: NavigatorGamepad;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface GamepadConfiguration {\r\n axis: number;\r\n buttons: number;\r\n}\r\n","import { Gamepads } from './Gamepad';\r\nimport { Keyboard } from './Keyboard';\r\nimport { PointerEventReceiver } from './PointerEventReceiver';\r\n\r\nexport interface InputsOptions {\r\n keyboard: Keyboard;\r\n gamepads: Gamepads;\r\n pointers: PointerEventReceiver;\r\n}\r\n\r\n/**\r\n * This allows you to map multiple inputs to specific commands! This is especially useful when\r\n * you need to allow multiple input sources to control a specific action.\r\n */\r\nexport class InputMapper {\r\n\r\n private _handlers = new Map();\r\n constructor(public inputs: InputsOptions) {}\r\n\r\n /**\r\n * Executes the input map, called internally by Excalibur\r\n */\r\n execute() {\r\n for (const [input, command] of this._handlers.entries()) {\r\n const results = input(this.inputs);\r\n if (results) {\r\n command(results);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * This allows you to map multiple inputs to specific commands! This is useful\r\n *\r\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\r\n *\r\n * Example:\r\n * ```typescript\r\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\r\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\r\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\r\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\r\n *\r\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\r\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\r\n * ```\r\n * @param inputHandler\r\n * @param commandHandler\r\n */\r\n on(\r\n inputHandler: (inputs: InputsOptions) => TInputHandlerData | false,\r\n commandHandler: (data: TInputHandlerData) => any) {\r\n this._handlers.set(inputHandler, commandHandler);\r\n }\r\n}","\r\n\r\n/**\r\n * Checks if excalibur is in a x-origin iframe\r\n */\r\nexport function isCrossOriginIframe() {\r\n try {\r\n // Try and listen to events on top window frame if within an iframe.\r\n //\r\n // See https://github.com/excaliburjs/Excalibur/issues/1294\r\n //\r\n // Attempt to add an event listener, which triggers a DOMException on\r\n // cross-origin iframes\r\n const noop = () => {\r\n return;\r\n };\r\n window.top.addEventListener('blur', noop);\r\n window.top.removeEventListener('blur', noop);\r\n } catch {\r\n return true;\r\n }\r\n return false;\r\n}","import { Logger } from '../Util/Log';\r\nimport * as Events from '../Events';\r\nimport { isCrossOriginIframe } from '../Util/IFrame';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\n/**\r\n * Enum representing physical input key codes\r\n */\r\nexport enum Keys {\r\n // NUMPAD\r\n Num0 = 'Numpad0',\r\n Num1 = 'Numpad1',\r\n Num2 = 'Numpad2',\r\n Num3 = 'Numpad3',\r\n Num4 = 'Numpad4',\r\n Num5 = 'Numpad5',\r\n Num6 = 'Numpad6',\r\n Num7 = 'Numpad7',\r\n Num8 = 'Numpad8',\r\n Num9 = 'Numpad9',\r\n NumAdd = 'NumpadAdd',\r\n NumSubtract = 'NumpadSubtract',\r\n NumMultiply = 'NumpadMultiply',\r\n NumDivide = 'NumpadDivide',\r\n // NumComma = 'NumpadComma', // not x-browser\r\n NumDecimal = 'NumpadDecimal',\r\n Numpad0 = 'Numpad0',\r\n Numpad1 = 'Numpad1',\r\n Numpad2 = 'Numpad2',\r\n Numpad3 = 'Numpad3',\r\n Numpad4 = 'Numpad4',\r\n Numpad5 = 'Numpad5',\r\n Numpad6 = 'Numpad6',\r\n Numpad7 = 'Numpad7',\r\n Numpad8 = 'Numpad8',\r\n Numpad9 = 'Numpad9',\r\n NumpadAdd = 'NumpadAdd',\r\n NumpadSubtract = 'NumpadSubtract',\r\n NumpadMultiply = 'NumpadMultiply',\r\n NumpadDivide = 'NumpadDivide',\r\n // NumpadComma = 'NumpadComma', // not x-browser\r\n NumpadDecimal = 'NumpadDecimal',\r\n\r\n // MODIFIERS\r\n NumLock = 'NumLock',\r\n ShiftLeft = 'ShiftLeft',\r\n ShiftRight = 'ShiftRight',\r\n AltLeft = 'AltLeft',\r\n AltRight = 'AltRight',\r\n ControlLeft = 'ControlLeft',\r\n ControlRight = 'ControlRight',\r\n MetaLeft = 'MetaLeft',\r\n MetaRight = 'MetaRight',\r\n\r\n // NUMBERS\r\n Key0 = 'Digit0',\r\n Key1 = 'Digit1',\r\n Key2 = 'Digit2',\r\n Key3 = 'Digit3',\r\n Key4 = 'Digit4',\r\n Key5 = 'Digit5',\r\n Key6 = 'Digit6',\r\n Key7 = 'Digit7',\r\n Key8 = 'Digit8',\r\n Key9 = 'Digit9',\r\n Digit0 = 'Digit0',\r\n Digit1 = 'Digit1',\r\n Digit2 = 'Digit2',\r\n Digit3 = 'Digit3',\r\n Digit4 = 'Digit4',\r\n Digit5 = 'Digit5',\r\n Digit6 = 'Digit6',\r\n Digit7 = 'Digit7',\r\n Digit8 = 'Digit8',\r\n Digit9 = 'Digit9',\r\n\r\n // FUNCTION KEYS\r\n F1 = 'F1',\r\n F2 = 'F2',\r\n F3 = 'F3',\r\n F4 = 'F4',\r\n F5 = 'F5',\r\n F6 = 'F6',\r\n F7 = 'F7',\r\n F8 = 'F8',\r\n F9 = 'F9',\r\n F10 = 'F10',\r\n F11 = 'F11',\r\n F12 = 'F12',\r\n\r\n // LETTERS\r\n A = 'KeyA',\r\n B = 'KeyB',\r\n C = 'KeyC',\r\n D = 'KeyD',\r\n E = 'KeyE',\r\n F = 'KeyF',\r\n G = 'KeyG',\r\n H = 'KeyH',\r\n I = 'KeyI',\r\n J = 'KeyJ',\r\n K = 'KeyK',\r\n L = 'KeyL',\r\n M = 'KeyM',\r\n N = 'KeyN',\r\n O = 'KeyO',\r\n P = 'KeyP',\r\n Q = 'KeyQ',\r\n R = 'KeyR',\r\n S = 'KeyS',\r\n T = 'KeyT',\r\n U = 'KeyU',\r\n V = 'KeyV',\r\n W = 'KeyW',\r\n X = 'KeyX',\r\n Y = 'KeyY',\r\n Z = 'KeyZ',\r\n KeyA = 'KeyA',\r\n KeyB = 'KeyB',\r\n KeyC = 'KeyC',\r\n KeyD = 'KeyD',\r\n KeyE = 'KeyE',\r\n KeyF = 'KeyF',\r\n KeyG = 'KeyG',\r\n KeyH = 'KeyH',\r\n KeyI = 'KeyI',\r\n KeyJ = 'KeyJ',\r\n KeyK = 'KeyK',\r\n KeyL = 'KeyL',\r\n KeyM = 'KeyM',\r\n KeyN = 'KeyN',\r\n KeyO = 'KeyO',\r\n KeyP = 'KeyP',\r\n KeyQ = 'KeyQ',\r\n KeyR = 'KeyR',\r\n KeyS = 'KeyS',\r\n KeyT = 'KeyT',\r\n KeyU = 'KeyU',\r\n KeyV = 'KeyV',\r\n KeyW = 'KeyW',\r\n KeyX = 'KeyX',\r\n KeyY = 'KeyY',\r\n KeyZ = 'KeyZ',\r\n\r\n // SYMBOLS\r\n Semicolon = 'Semicolon',\r\n Quote = 'Quote',\r\n Comma = 'Comma',\r\n Minus = 'Minus',\r\n Period = 'Period',\r\n Slash = 'Slash',\r\n Equal = 'Equal',\r\n BracketLeft = 'BracketLeft',\r\n Backslash = 'Backslash',\r\n BracketRight = 'BracketRight',\r\n Backquote = 'Backquote',\r\n\r\n // DIRECTIONS\r\n Up = 'ArrowUp',\r\n Down = 'ArrowDown',\r\n Left = 'ArrowLeft',\r\n Right = 'ArrowRight',\r\n ArrowUp = 'ArrowUp',\r\n ArrowDown = 'ArrowDown',\r\n ArrowLeft = 'ArrowLeft',\r\n ArrowRight = 'ArrowRight',\r\n\r\n // OTHER\r\n Space = 'Space',\r\n Backspace = 'Backspace',\r\n Delete = 'Delete',\r\n Esc = 'Escape',\r\n Escape = 'Escape',\r\n Enter = 'Enter',\r\n NumpadEnter = 'NumpadEnter',\r\n ContextMenu = 'ContextMenu'\r\n}\r\n\r\n/**\r\n * Event thrown on a game object for a key event\r\n */\r\nexport class KeyEvent extends Events.GameEvent {\r\n /**\r\n * @param key The key responsible for throwing the event\r\n * @param value The key's typed value the browser detected\r\n * @param originalEvent The original keyboard event that Excalibur handled\r\n */\r\n constructor(public key: Keys, public value?: string, public originalEvent?: KeyboardEvent) {\r\n super();\r\n }\r\n}\r\n\r\nexport interface KeyboardInitOptions {\r\n global?: GlobalEventHandlers,\r\n grabWindowFocus?: boolean\r\n}\r\n\r\nexport type KeyEvents = {\r\n press: KeyEvent,\r\n hold: KeyEvent,\r\n release: KeyEvent\r\n};\r\n\r\nexport const KeyEvents = {\r\n Press: 'press',\r\n Hold: 'hold',\r\n Release: 'release'\r\n};\r\n\r\n/**\r\n * Provides keyboard support for Excalibur.\r\n */\r\nexport class Keyboard {\r\n public events = new EventEmitter();\r\n private _enabled = true;\r\n /**\r\n * Keys that are currently held down\r\n */\r\n private _keys: Keys[] = [];\r\n /**\r\n * Keys up in the current frame\r\n */\r\n private _keysUp: Keys[] = [];\r\n /**\r\n * Keys down in the current frame\r\n */\r\n private _keysDown: Keys[] = [];\r\n\r\n public emit>(eventName: TEventName, event: KeyEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Initialize Keyboard event listeners\r\n */\r\n init(keyboardOptions?: KeyboardInitOptions): void {\r\n let { global } = keyboardOptions;\r\n const { grabWindowFocus } = keyboardOptions;\r\n if (!global) {\r\n if (isCrossOriginIframe()) {\r\n global = window;\r\n // Workaround for iframes like for itch.io or codesandbox\r\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\r\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\r\n if (grabWindowFocus) {\r\n window.focus();\r\n }\r\n\r\n Logger.getInstance().warn('Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus');\r\n } else {\r\n global = window.top;\r\n }\r\n }\r\n\r\n global.addEventListener('blur', () => {\r\n this._keys.length = 0; // empties array efficiently\r\n });\r\n\r\n // key up is on window because canvas cannot have focus\r\n global.addEventListener('keyup', this._handleKeyUp);\r\n\r\n // key down is on window because canvas cannot have focus\r\n global.addEventListener('keydown', this._handleKeyDown);\r\n }\r\n\r\n toggleEnabled(enabled: boolean) {\r\n this._enabled = enabled;\r\n }\r\n\r\n private _releaseAllKeys = (ev: KeyboardEvent) => {\r\n for (const code of this._keys) {\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n this.events.emit('up', keyEvent);\r\n this.events.emit('release', keyEvent);\r\n }\r\n this._keysUp = Array.from((new Set(this._keys.concat(this._keysUp))));\r\n this._keys.length = 0;\r\n };\r\n\r\n private _handleKeyDown = (ev: KeyboardEvent) => {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n\r\n // handle macos meta key issue\r\n // https://github.com/excaliburjs/Excalibur/issues/2608\r\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) {\r\n this._releaseAllKeys(ev);\r\n }\r\n\r\n const code = ev.code as Keys;\r\n if (this._keys.indexOf(code) === -1) {\r\n this._keys.push(code);\r\n this._keysDown.push(code);\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n this.events.emit('down', keyEvent);\r\n this.events.emit('press', keyEvent);\r\n }\r\n };\r\n\r\n private _handleKeyUp = (ev: KeyboardEvent) => {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n const code = ev.code as Keys;\r\n const key = this._keys.indexOf(code);\r\n this._keys.splice(key, 1);\r\n this._keysUp.push(code);\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n\r\n // alias the old api, we may want to deprecate this in the future\r\n this.events.emit('up', keyEvent);\r\n this.events.emit('release', keyEvent);\r\n\r\n // handle macos meta key issue\r\n // https://github.com/excaliburjs/Excalibur/issues/2608\r\n if (ev.key === 'Meta') {\r\n this._releaseAllKeys(ev);\r\n }\r\n };\r\n\r\n public update() {\r\n // Reset keysDown and keysUp after update is complete\r\n this._keysDown.length = 0;\r\n this._keysUp.length = 0;\r\n\r\n // Emit synthetic \"hold\" event\r\n for (let i = 0; i < this._keys.length; i++) {\r\n this.events.emit('hold', new KeyEvent(this._keys[i]));\r\n }\r\n }\r\n\r\n /**\r\n * Gets list of keys being pressed down\r\n */\r\n public getKeys(): Keys[] {\r\n return this._keys;\r\n }\r\n\r\n /**\r\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just pressed\r\n */\r\n public wasPressed(key: Keys): boolean {\r\n return this._keysDown.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Tests if a certain key is held down. This is persisted between frames.\r\n * @param key Test whether a key is held down\r\n */\r\n public isHeld(key: Keys): boolean {\r\n return this._keys.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just released\r\n */\r\n public wasReleased(key: Keys): boolean {\r\n return this._keysUp.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Trigger a manual key event\r\n * @param type\r\n * @param key\r\n * @param character\r\n */\r\n public triggerEvent(type: 'down' | 'up', key: Keys, character?: string) {\r\n if (type === 'down') {\r\n this._handleKeyDown(new KeyboardEvent('keydown', {\r\n code: key,\r\n key: character ?? null\r\n }));\r\n }\r\n if (type === 'up') {\r\n this._handleKeyUp(new KeyboardEvent('keyup', {\r\n code: key,\r\n key: character ?? null\r\n }));\r\n }\r\n }\r\n}\r\n","import { Engine } from '../Engine';\r\nimport { Vector } from './vector';\r\n\r\nexport class GlobalCoordinates {\r\n public static fromPagePosition(x: number, y: number, engine: Engine): GlobalCoordinates;\r\n public static fromPagePosition(pos: Vector, engine: Engine): GlobalCoordinates;\r\n public static fromPagePosition(xOrPos: number | Vector, yOrEngine: number | Engine, engineOrUndefined?: Engine): GlobalCoordinates {\r\n let pageX: number;\r\n let pageY: number;\r\n let pagePos: Vector;\r\n let engine: Engine;\r\n\r\n if (arguments.length === 3) {\r\n pageX = xOrPos;\r\n pageY = yOrEngine;\r\n pagePos = new Vector(pageX, pageY);\r\n engine = engineOrUndefined;\r\n } else {\r\n pagePos = xOrPos;\r\n pageX = pagePos.x;\r\n pageY = pagePos.y;\r\n engine = yOrEngine;\r\n }\r\n\r\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\r\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\r\n\r\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\r\n }\r\n\r\n constructor(public worldPos: Vector, public pagePos: Vector, public screenPos: Vector) {}\r\n}\r\n","import { GlobalCoordinates } from '../Math/global-coordinates';\r\nimport { Vector } from '../Math/vector';\r\nimport { PointerButton } from './PointerButton';\r\nimport { PointerType } from './PointerType';\r\n\r\nexport class PointerEvent {\r\n public active = true;\r\n public cancel() {\r\n this.active = false;\r\n }\r\n\r\n get pagePos(): Vector {\r\n return this.coordinates.pagePos;\r\n }\r\n\r\n get screenPos(): Vector {\r\n return this.coordinates.screenPos;\r\n }\r\n\r\n get worldPos(): Vector {\r\n return this.coordinates.worldPos;\r\n }\r\n\r\n constructor(\r\n public type: 'down' | 'up' | 'move' | 'cancel',\r\n public pointerId: number,\r\n public button: PointerButton,\r\n public pointerType: PointerType,\r\n public coordinates: GlobalCoordinates,\r\n public nativeEvent: Event) { };\r\n}\r\n","import { WheelDeltaMode } from './WheelDeltaMode';\r\n\r\n\r\nexport class WheelEvent {\r\n public active = true;\r\n public cancel() {\r\n this.active = false;\r\n }\r\n constructor(\r\n public x: number,\r\n public y: number,\r\n public pageX: number,\r\n public pageY: number,\r\n public screenX: number,\r\n public screenY: number,\r\n public index: number,\r\n public deltaX: number,\r\n public deltaY: number,\r\n public deltaZ: number,\r\n public deltaMode: WheelDeltaMode,\r\n public ev: Event\r\n ) { }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { PointerEvents } from './PointerEventReceiver';\r\n\r\nexport class PointerAbstraction {\r\n public events = new EventEmitter();\r\n /**\r\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastPagePos: Vector = Vector.Zero;\r\n\r\n /**\r\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastScreenPos: Vector = Vector.Zero;\r\n\r\n /**\r\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastWorldPos: Vector = Vector.Zero;\r\n\r\n constructor() {\r\n this.on('move', this._onPointerMove);\r\n this.on('down', this._onPointerDown);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: PointerEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n private _onPointerMove = (ev: PointerEvent): void => {\r\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\r\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\r\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\r\n };\r\n\r\n private _onPointerDown = (ev: PointerEvent): void => {\r\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\r\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\r\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\r\n };\r\n}\r\n","\r\nexport enum WheelDeltaMode {\r\n Pixel = 'Pixel',\r\n Line = 'Line',\r\n Page = 'Page'\r\n}\r\n","/**\r\n * Native browser button enumeration\r\n */\r\nexport enum NativePointerButton {\r\n NoButton = -1,\r\n Left = 0,\r\n Middle = 1,\r\n Right = 2,\r\n Unknown = 3\r\n}\r\n","/**\r\n * The mouse button being pressed.\r\n */\r\nexport enum PointerButton {\r\n Left = 'Left',\r\n Middle = 'Middle',\r\n Right = 'Right',\r\n Unknown = 'Unknown',\r\n NoButton = 'NoButton'\r\n}\r\n","/**\r\n * The type of pointer for a [[PointerEvent]].\r\n */\r\nexport enum PointerType {\r\n Touch = 'Touch',\r\n Mouse = 'Mouse',\r\n Pen = 'Pen',\r\n Unknown = 'Unknown'\r\n}\r\n","import { Engine, ScrollPreventionMode } from '../Engine';\r\nimport { GlobalCoordinates } from '../Math/global-coordinates';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { WheelEvent } from './WheelEvent';\r\nimport { PointerAbstraction } from './PointerAbstraction';\r\n\r\nimport { WheelDeltaMode } from './WheelDeltaMode';\r\nimport { PointerSystem } from './PointerSystem';\r\nimport { NativePointerButton } from './NativePointerButton';\r\nimport { PointerButton } from './PointerButton';\r\nimport { fail } from '../Util/Util';\r\nimport { PointerType } from './PointerType';\r\nimport { isCrossOriginIframe } from '../Util/IFrame';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\n\r\nexport type NativePointerEvent = globalThis.PointerEvent;\r\nexport type NativeMouseEvent = globalThis.MouseEvent;\r\nexport type NativeTouchEvent = globalThis.TouchEvent;\r\nexport type NativeWheelEvent = globalThis.WheelEvent;\r\n\r\nexport type PointerEvents = {\r\n move: PointerEvent,\r\n down: PointerEvent,\r\n up: PointerEvent,\r\n wheel: WheelEvent\r\n}\r\n\r\nexport const PointerEvents = {\r\n Move: 'move',\r\n Down: 'down',\r\n Up: 'up',\r\n Wheel: 'wheel'\r\n};\r\n\r\n/**\r\n * Is this event a native touch event?\r\n */\r\nfunction isTouchEvent(value: any): value is NativeTouchEvent {\r\n // Guard for Safari <= 13.1\r\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\r\n}\r\n\r\n/**\r\n * Is this event a native pointer event\r\n */\r\nfunction isPointerEvent(value: any): value is NativePointerEvent {\r\n // Guard for Safari <= 13.1\r\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\r\n}\r\n\r\nexport interface PointerInitOptions {\r\n grabWindowFocus?: boolean;\r\n}\r\n\r\n/**\r\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\r\n */\r\nexport class PointerEventReceiver {\r\n public events = new EventEmitter();\r\n public primary: PointerAbstraction = new PointerAbstraction();\r\n\r\n private _activeNativePointerIdsToNormalized = new Map();\r\n public lastFramePointerCoords = new Map();\r\n public currentFramePointerCoords = new Map();\r\n\r\n public currentFramePointerDown = new Map();\r\n public lastFramePointerDown = new Map();\r\n\r\n public currentFrameDown: PointerEvent[] = [];\r\n public currentFrameUp: PointerEvent[] = [];\r\n public currentFrameMove: PointerEvent[] = [];\r\n public currentFrameCancel: PointerEvent[] = [];\r\n public currentFrameWheel: WheelEvent[] = [];\r\n\r\n private _enabled = true;\r\n\r\n constructor(public readonly target: GlobalEventHandlers & EventTarget, public engine: Engine) {}\r\n\r\n public toggleEnabled(enabled: boolean) {\r\n this._enabled = enabled;\r\n }\r\n\r\n /**\r\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\r\n * handlers.\r\n * @param target\r\n * @param engine\r\n */\r\n public recreate(target: GlobalEventHandlers & EventTarget, engine: Engine) {\r\n const eventReceiver = new PointerEventReceiver(target, engine);\r\n eventReceiver.primary = this.primary;\r\n eventReceiver._pointers = this._pointers;\r\n return eventReceiver;\r\n }\r\n\r\n private _pointers: PointerAbstraction[] = [this.primary];\r\n /**\r\n * Locates a specific pointer by id, creates it if it doesn't exist\r\n * @param index\r\n */\r\n public at(index: number): PointerAbstraction {\r\n if (index >= this._pointers.length) {\r\n // Ensure there is a pointer to retrieve\r\n for (let i = this._pointers.length - 1, max = index; i < max; i++) {\r\n this._pointers.push(new PointerAbstraction());\r\n }\r\n }\r\n return this._pointers[index];\r\n }\r\n\r\n /**\r\n * The number of pointers currently being tracked by excalibur\r\n */\r\n public count(): number {\r\n return this._pointers.length;\r\n }\r\n\r\n /**\r\n * Is the specified pointer id down this frame\r\n * @param pointerId\r\n */\r\n public isDown(pointerId: number) {\r\n return this.currentFramePointerDown.get(pointerId) ?? false;\r\n }\r\n\r\n /**\r\n * Was the specified pointer id down last frame\r\n * @param pointerId\r\n */\r\n public wasDown(pointerId: number) {\r\n return this.lastFramePointerDown.get(pointerId) ?? false;\r\n }\r\n\r\n /**\r\n * Whether the Pointer is currently dragging.\r\n */\r\n public isDragging(pointerId: number): boolean {\r\n return this.isDown(pointerId);\r\n }\r\n\r\n /**\r\n * Whether the Pointer just started dragging.\r\n */\r\n public isDragStart(pointerId: number): boolean {\r\n return this.isDown(pointerId) && !this.wasDown(pointerId);\r\n }\r\n\r\n /**\r\n * Whether the Pointer just ended dragging.\r\n */\r\n public isDragEnd(pointerId: number): boolean {\r\n return !this.isDown(pointerId) && this.wasDown(pointerId);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: PointerEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Called internally by excalibur\r\n *\r\n * Updates the current frame pointer info and emits raw pointer events\r\n *\r\n * This does not emit events to entities, see PointerSystem\r\n */\r\n public update() {\r\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\r\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\r\n\r\n for (const event of this.currentFrameDown) {\r\n this.emit('down', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('down', event);\r\n this.primary.emit('pointerdown', event);\r\n }\r\n\r\n for (const event of this.currentFrameUp) {\r\n this.emit('up', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('up', event);\r\n }\r\n\r\n for (const event of this.currentFrameMove) {\r\n this.emit('move', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('move', event);\r\n }\r\n\r\n for (const event of this.currentFrameCancel) {\r\n this.emit('cancel', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('cancel', event);\r\n }\r\n\r\n for (const event of this.currentFrameWheel) {\r\n this.emit('wheel', event);\r\n this.primary.emit('pointerwheel', event);\r\n this.primary.emit('wheel', event);\r\n }\r\n }\r\n\r\n /**\r\n * Clears the current frame event and pointer data\r\n */\r\n public clear() {\r\n for (const event of this.currentFrameUp) {\r\n this.currentFramePointerCoords.delete(event.pointerId);\r\n const ids = this._activeNativePointerIdsToNormalized.entries();\r\n for (const [native, normalized] of ids) {\r\n if (normalized === event.pointerId) {\r\n this._activeNativePointerIdsToNormalized.delete(native);\r\n }\r\n }\r\n }\r\n this.currentFrameDown.length = 0;\r\n this.currentFrameUp.length = 0;\r\n this.currentFrameMove.length = 0;\r\n this.currentFrameCancel.length = 0;\r\n this.currentFrameWheel.length = 0;\r\n }\r\n\r\n private _boundHandle = this._handle.bind(this);\r\n private _boundWheel = this._handleWheel.bind(this);\r\n /**\r\n * Initializes the pointer event receiver so that it can start listening to native\r\n * browser events.\r\n */\r\n public init(options?: PointerInitOptions) {\r\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\r\n // It is important on mobile to have touch action 'none'\r\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\r\n if (this.target === this.engine.canvas) {\r\n this.engine.canvas.style.touchAction = 'none';\r\n } else {\r\n document.body.style.touchAction = 'none';\r\n }\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.addEventListener('pointerdown', this._boundHandle);\r\n this.target.addEventListener('pointerup', this._boundHandle);\r\n this.target.addEventListener('pointermove', this._boundHandle);\r\n this.target.addEventListener('pointercancel', this._boundHandle);\r\n } else {\r\n // Touch Events\r\n this.target.addEventListener('touchstart', this._boundHandle);\r\n this.target.addEventListener('touchend', this._boundHandle);\r\n this.target.addEventListener('touchmove', this._boundHandle);\r\n this.target.addEventListener('touchcancel', this._boundHandle);\r\n\r\n // Mouse Events\r\n this.target.addEventListener('mousedown', this._boundHandle);\r\n this.target.addEventListener('mouseup', this._boundHandle);\r\n this.target.addEventListener('mousemove', this._boundHandle);\r\n }\r\n\r\n // MDN MouseWheelEvent\r\n const wheelOptions = {\r\n passive: !(\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas\r\n )\r\n };\r\n if ('onwheel' in document.createElement('div')) {\r\n // Modern Browsers\r\n this.target.addEventListener('wheel', this._boundWheel, wheelOptions);\r\n } else if (document.onmousewheel !== undefined) {\r\n // Webkit and IE\r\n this.target.addEventListener('mousewheel', this._boundWheel, wheelOptions);\r\n } else {\r\n // Remaining browser and older Firefox\r\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel, wheelOptions);\r\n }\r\n\r\n const grabWindowFocus = options?.grabWindowFocus ?? true;\r\n // Handle cross origin iframe\r\n if (grabWindowFocus && isCrossOriginIframe()) {\r\n const grabFocus = () => {\r\n window.focus();\r\n };\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.addEventListener('pointerdown', grabFocus);\r\n } else {\r\n // Touch Events\r\n this.target.addEventListener('touchstart', grabFocus);\r\n\r\n // Mouse Events\r\n this.target.addEventListener('mousedown', grabFocus);\r\n }\r\n }\r\n }\r\n\r\n public detach() {\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.removeEventListener('pointerdown', this._boundHandle);\r\n this.target.removeEventListener('pointerup', this._boundHandle);\r\n this.target.removeEventListener('pointermove', this._boundHandle);\r\n this.target.removeEventListener('pointercancel', this._boundHandle);\r\n } else {\r\n // Touch Events\r\n this.target.removeEventListener('touchstart', this._boundHandle);\r\n this.target.removeEventListener('touchend', this._boundHandle);\r\n this.target.removeEventListener('touchmove', this._boundHandle);\r\n this.target.removeEventListener('touchcancel', this._boundHandle);\r\n\r\n // Mouse Events\r\n this.target.removeEventListener('mousedown', this._boundHandle);\r\n this.target.removeEventListener('mouseup', this._boundHandle);\r\n this.target.removeEventListener('mousemove', this._boundHandle);\r\n }\r\n\r\n if ('onwheel' in document.createElement('div')) {\r\n // Modern Browsers\r\n this.target.removeEventListener('wheel', this._boundWheel);\r\n } else if (document.onmousewheel !== undefined) {\r\n // Webkit and IE\r\n this.target.addEventListener('mousewheel', this._boundWheel);\r\n } else {\r\n // Remaining browser and older Firefox\r\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel);\r\n }\r\n }\r\n\r\n /**\r\n * Take native pointer id and map it to index in active pointers\r\n * @param nativePointerId\r\n */\r\n private _normalizePointerId(nativePointerId: number) {\r\n // Add to the the native pointer set id\r\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\r\n\r\n // Native pointer ids in ascending order\r\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b) => a - b);\r\n\r\n // The index into sorted ids will be the new id, will always have an id\r\n const id = currentPointerIds.findIndex(p => p === nativePointerId);\r\n\r\n // Save the mapping so we can reverse it later\r\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\r\n\r\n // ignore pointer because game isn't watching\r\n return id;\r\n }\r\n\r\n /**\r\n * Responsible for handling and parsing pointer events\r\n */\r\n private _handle(ev: NativeTouchEvent | NativePointerEvent | NativeMouseEvent) {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n ev.preventDefault();\r\n const eventCoords = new Map();\r\n let button: PointerButton;\r\n let pointerType: PointerType;\r\n if (isTouchEvent(ev)) {\r\n button = PointerButton.Unknown;\r\n pointerType = PointerType.Touch;\r\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\r\n for (let i = 0; i < ev.changedTouches.length; i++) {\r\n const touch = ev.changedTouches[i];\r\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\r\n const nativePointerId = i + 1;\r\n const pointerId = this._normalizePointerId(nativePointerId);\r\n this.currentFramePointerCoords.set(pointerId, coordinates);\r\n eventCoords.set(pointerId, coordinates);\r\n }\r\n } else {\r\n button = this._nativeButtonToPointerButton(ev.button);\r\n pointerType = PointerType.Mouse;\r\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\r\n let nativePointerId = 1;\r\n if (isPointerEvent(ev)) {\r\n nativePointerId = ev.pointerId;\r\n pointerType = this._stringToPointerType(ev.pointerType);\r\n }\r\n const pointerId = this._normalizePointerId(nativePointerId);\r\n this.currentFramePointerCoords.set(pointerId, coordinates);\r\n eventCoords.set(pointerId, coordinates);\r\n }\r\n\r\n for (const [pointerId, coord] of eventCoords.entries()) {\r\n switch (ev.type) {\r\n case 'mousedown':\r\n case 'pointerdown':\r\n case 'touchstart':\r\n this.currentFrameDown.push(new PointerEvent('down', pointerId, button, pointerType, coord, ev));\r\n this.currentFramePointerDown.set(pointerId, true);\r\n break;\r\n case 'mouseup':\r\n case 'pointerup':\r\n case 'touchend':\r\n this.currentFrameUp.push(new PointerEvent('up', pointerId, button, pointerType, coord, ev));\r\n this.currentFramePointerDown.set(pointerId, false);\r\n break;\r\n case 'mousemove':\r\n case 'pointermove':\r\n case 'touchmove':\r\n this.currentFrameMove.push(new PointerEvent('move', pointerId, button, pointerType, coord, ev));\r\n break;\r\n case 'touchcancel':\r\n case 'pointercancel':\r\n this.currentFrameCancel.push(new PointerEvent('cancel', pointerId, button, pointerType, coord, ev));\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private _handleWheel(ev: NativeWheelEvent) {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n // Should we prevent page scroll because of this event\r\n if (\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\r\n (this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas)\r\n ) {\r\n ev.preventDefault();\r\n }\r\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\r\n const world = this.engine.screen.screenToWorldCoordinates(screen);\r\n\r\n /**\r\n * A constant used to normalize wheel events across different browsers\r\n *\r\n * This normalization factor is pulled from\r\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\r\n */\r\n const ScrollWheelNormalizationFactor = -1 / 40;\r\n\r\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\r\n const deltaY =\r\n ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\r\n const deltaZ = ev.deltaZ || 0;\r\n let deltaMode = WheelDeltaMode.Pixel;\r\n\r\n if (ev.deltaMode) {\r\n if (ev.deltaMode === 1) {\r\n deltaMode = WheelDeltaMode.Line;\r\n } else if (ev.deltaMode === 2) {\r\n deltaMode = WheelDeltaMode.Page;\r\n }\r\n }\r\n\r\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\r\n this.currentFrameWheel.push(we);\r\n }\r\n\r\n /**\r\n * Triggers an excalibur pointer event in a world space pos\r\n *\r\n * Useful for testing pointers in excalibur\r\n * @param type\r\n * @param pos\r\n */\r\n public triggerEvent(type: 'down' | 'up' | 'move' | 'cancel', pos: Vector) {\r\n const page = this.engine.screen.worldToPageCoordinates(pos);\r\n // Send an event to the event receiver\r\n if (window.PointerEvent) {\r\n this._handle(new window.PointerEvent('pointer' + type, {\r\n pointerId: 0,\r\n clientX: page.x,\r\n clientY: page.y\r\n }));\r\n } else {\r\n // Safari hack\r\n this._handle(new window.MouseEvent('mouse' + type, {\r\n clientX: page.x,\r\n clientY: page.y\r\n }));\r\n }\r\n\r\n // Force update pointer system\r\n const pointerSystem = this.engine.currentScene.world.get(PointerSystem);\r\n pointerSystem.preupdate(this.engine.currentScene, 1);\r\n pointerSystem.update(1);\r\n }\r\n\r\n private _nativeButtonToPointerButton(s: NativePointerButton): PointerButton {\r\n switch (s) {\r\n case NativePointerButton.NoButton:\r\n return PointerButton.NoButton;\r\n case NativePointerButton.Left:\r\n return PointerButton.Left;\r\n case NativePointerButton.Middle:\r\n return PointerButton.Middle;\r\n case NativePointerButton.Right:\r\n return PointerButton.Right;\r\n case NativePointerButton.Unknown:\r\n return PointerButton.Unknown;\r\n default:\r\n return fail(s);\r\n }\r\n }\r\n\r\n private _stringToPointerType(s: string) {\r\n switch (s) {\r\n case 'touch':\r\n return PointerType.Touch;\r\n case 'mouse':\r\n return PointerType.Mouse;\r\n case 'pen':\r\n return PointerType.Pen;\r\n default:\r\n return PointerType.Unknown;\r\n }\r\n }\r\n}","import { Engine } from '../Engine';\r\nimport { Gamepads } from './Gamepad';\r\nimport { InputMapper } from './InputMapper';\r\nimport { Keyboard } from './Keyboard';\r\nimport { PointerEventReceiver } from './PointerEventReceiver';\r\n\r\nexport interface InputHostOptions {\r\n pointerTarget: Document | HTMLCanvasElement\r\n grabWindowFocus: boolean,\r\n engine: Engine\r\n}\r\n\r\nexport class InputHost {\r\n private _enabled = true;\r\n\r\n keyboard: Keyboard;\r\n pointers: PointerEventReceiver;\r\n gamepads: Gamepads;\r\n inputMapper: InputMapper;\r\n\r\n constructor(options: InputHostOptions) {\r\n const { pointerTarget, grabWindowFocus, engine } = options;\r\n this.keyboard = new Keyboard();\r\n this.pointers = new PointerEventReceiver(pointerTarget, engine);\r\n this.gamepads = new Gamepads();\r\n\r\n this.keyboard.init({grabWindowFocus});\r\n this.pointers.init({grabWindowFocus});\r\n this.gamepads.init();\r\n this.inputMapper = new InputMapper({\r\n keyboard: this.keyboard,\r\n pointers: this.pointers,\r\n gamepads: this.gamepads\r\n });\r\n }\r\n\r\n get enabled() {\r\n return this._enabled;\r\n }\r\n\r\n toggleEnabled(enabled: boolean) {\r\n this._enabled = enabled;\r\n this.keyboard.toggleEnabled(this._enabled);\r\n this.pointers.toggleEnabled(this._enabled);\r\n this.gamepads.toggleEnabled(this._enabled);\r\n }\r\n\r\n update() {\r\n if (this._enabled) {\r\n this.inputMapper.execute();\r\n this.keyboard.update();\r\n this.gamepads.update();\r\n }\r\n }\r\n}","import { isScreenElement, ScreenElement } from './ScreenElement';\r\nimport {\r\n InitializeEvent,\r\n ActivateEvent,\r\n DeactivateEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n PreDebugDrawEvent,\r\n PostDebugDrawEvent\r\n} from './Events';\r\nimport { Logger } from './Util/Log';\r\nimport { Timer } from './Timer';\r\nimport { Engine } from './Engine';\r\nimport { TileMap } from './TileMap';\r\nimport { Camera } from './Camera';\r\nimport { Actor } from './Actor';\r\nimport { CanInitialize, CanActivate, CanDeactivate, CanUpdate, CanDraw, SceneActivationContext } from './Interfaces/LifecycleEvents';\r\nimport * as Util from './Util/Util';\r\nimport { Trigger } from './Trigger';\r\nimport { SystemType } from './EntityComponentSystem/System';\r\nimport { World } from './EntityComponentSystem/World';\r\nimport { MotionSystem } from './Collision/MotionSystem';\r\nimport { CollisionSystem } from './Collision/CollisionSystem';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { GraphicsSystem } from './Graphics/GraphicsSystem';\r\nimport { DebugSystem } from './Debug/DebugSystem';\r\nimport { PointerSystem } from './Input/PointerSystem';\r\nimport { ActionsSystem } from './Actions/ActionsSystem';\r\nimport { IsometricEntitySystem } from './TileMap/IsometricEntitySystem';\r\nimport { OffscreenSystem } from './Graphics/OffscreenSystem';\r\nimport { ExcaliburGraphicsContext } from './Graphics';\r\nimport { PhysicsWorld } from './Collision/PhysicsWorld';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { Color } from './Color';\r\nimport { DefaultLoader } from './Director/DefaultLoader';\r\nimport { Transition } from './Director';\r\nimport { InputHost } from './Input/InputHost';\r\nimport { PointerScope } from './Input/PointerScope';\r\nimport { DefaultPhysicsConfig } from './Collision/PhysicsConfig';\r\n\r\nexport class PreLoadEvent {\r\n loader: DefaultLoader;\r\n}\r\n\r\nexport type SceneEvents = {\r\n initialize: InitializeEvent,\r\n activate: ActivateEvent,\r\n deactivate: DeactivateEvent,\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n predraw: PreDrawEvent,\r\n postdraw: PostDrawEvent,\r\n predebugdraw: PreDebugDrawEvent,\r\n postdebugdraw: PostDebugDrawEvent\r\n preload: PreLoadEvent\r\n}\r\n\r\nexport const SceneEvents = {\r\n Initialize: 'initialize',\r\n Activate: 'activate',\r\n Deactivate: 'deactivate',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw',\r\n PreDebugDraw: 'predebugdraw',\r\n PostDebugDraw: 'postdebugdraw',\r\n PreLoad: 'preload'\r\n};\r\n\r\nexport type SceneConstructor = new (...args: any[]) => Scene;\r\n/**\r\n *\r\n */\r\nexport function isSceneConstructor(x: any): x is SceneConstructor {\r\n return !!x?.prototype && !!x?.prototype?.constructor?.name;\r\n}\r\n\r\n/**\r\n * [[Actor|Actors]] are composed together into groupings called Scenes in\r\n * Excalibur. The metaphor models the same idea behind real world\r\n * actors in a scene. Only actors in scenes will be updated and drawn.\r\n *\r\n * Typical usages of a scene include: levels, menus, loading screens, etc.\r\n */\r\nexport class Scene\r\nimplements CanInitialize, CanActivate, CanDeactivate, CanUpdate, CanDraw {\r\n private _logger: Logger = Logger.getInstance();\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Gets or sets the current camera for the scene\r\n */\r\n public camera: Camera = new Camera();\r\n\r\n /**\r\n * Scene specific background color\r\n */\r\n public backgroundColor?: Color;\r\n\r\n /**\r\n * The ECS world for the scene\r\n */\r\n public world: World = new World(this);\r\n\r\n /**\r\n * The Excalibur physics world for the scene. Used to interact\r\n * with colliders included in the scene.\r\n *\r\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\r\n */\r\n public physics = new PhysicsWorld(DefaultPhysicsConfig);\r\n\r\n /**\r\n * The actors in the current scene\r\n */\r\n public get actors(): readonly Actor[] {\r\n return this.world.entityManager.entities.filter((e: Entity) => {\r\n return e instanceof Actor;\r\n }) as Actor[];\r\n }\r\n\r\n /**\r\n * The entities in the current scene\r\n */\r\n public get entities(): readonly Entity[] {\r\n return this.world.entityManager.entities;\r\n }\r\n\r\n /**\r\n * The triggers in the current scene\r\n */\r\n public get triggers(): readonly Trigger[] {\r\n return this.world.entityManager.entities.filter((e: Entity) => {\r\n return e instanceof Trigger;\r\n }) as Trigger[];\r\n }\r\n\r\n /**\r\n * The [[TileMap]]s in the scene, if any\r\n */\r\n public get tileMaps(): readonly TileMap[] {\r\n return this.world.entityManager.entities.filter((e: Entity) => {\r\n return e instanceof TileMap;\r\n }) as TileMap[];\r\n }\r\n\r\n /**\r\n * Access to the Excalibur engine\r\n */\r\n public engine: Engine;\r\n\r\n /**\r\n * Access scene specific input, handlers on this only fire when this scene is active.\r\n */\r\n public input: InputHost;\r\n\r\n private _isInitialized: boolean = false;\r\n private _timers: Timer[] = [];\r\n public get timers(): readonly Timer[] {\r\n return this._timers;\r\n }\r\n private _cancelQueue: Timer[] = [];\r\n\r\n constructor() {\r\n // Initialize systems\r\n\r\n // Update\r\n this.world.add(ActionsSystem);\r\n this.world.add(new MotionSystem(this.world, this.physics));\r\n this.world.add(new CollisionSystem(this.world, this.physics));\r\n this.world.add(PointerSystem);\r\n this.world.add(IsometricEntitySystem);\r\n // Draw\r\n this.world.add(OffscreenSystem);\r\n this.world.add(GraphicsSystem);\r\n this.world.add(DebugSystem);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: SceneEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Event hook to provide Scenes a way of loading scene specific resources.\r\n *\r\n * This is called before the Scene.onInitialize during scene transition. It will only ever fire once for a scene.\r\n * @param loader\r\n */\r\n public onPreLoad(loader: DefaultLoader) {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Event hook fired directly before transition, either \"in\" or \"out\" of the scene\r\n *\r\n * This overrides the Engine scene definition. However transitions specified in goToScene take highest precedence\r\n *\r\n * ```typescript\r\n * // Overrides all\r\n * Engine.goToScene('scene', { destinationIn: ..., sourceOut: ... });\r\n * ```\r\n *\r\n * This can be used to configure custom transitions for a scene dynamically\r\n */\r\n public onTransition(direction: 'in' | 'out'): Transition | undefined {\r\n // will be overridden\r\n return undefined;\r\n }\r\n\r\n /**\r\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n */\r\n public onInitialize(engine: Engine): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * This is called when the scene is made active and started. It is meant to be overridden,\r\n * this is where you should setup any DOM UI or event handlers needed for the scene.\r\n */\r\n public onActivate(context: SceneActivationContext): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\r\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\r\n */\r\n public onDeactivate(context: SceneActivationContext): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */\r\n public onPreUpdate(engine: Engine, delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onPostUpdate(engine: Engine, delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreDraw` is called directly before a scene is drawn.\r\n *\r\n */\r\n public onPreDraw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostDraw` is called directly after a scene is drawn.\r\n *\r\n */\r\n public onPostDraw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Initializes actors in the scene\r\n */\r\n private _initializeChildren() {\r\n for (const child of this.entities) {\r\n child._initialize(this.engine);\r\n }\r\n }\r\n\r\n /**\r\n * Gets whether or not the [[Scene]] has been initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Initializes the scene before the first update, meant to be called by engine not by users of\r\n * Excalibur\r\n * @internal\r\n */\r\n public async _initialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n try {\r\n this.engine = engine;\r\n // PhysicsWorld config is watched so things will automagically update\r\n this.physics.config = this.engine.physics;\r\n this.input = new InputHost({\r\n pointerTarget: engine.pointerScope === PointerScope.Canvas ? engine.canvas : document,\r\n grabWindowFocus: engine.grabWindowFocus,\r\n engine\r\n });\r\n // Initialize camera first\r\n this.camera._initialize(engine);\r\n\r\n this.world.systemManager.initialize();\r\n\r\n // This order is important! we want to be sure any custom init that add actors\r\n // fire before the actor init\r\n await this.onInitialize(engine);\r\n this._initializeChildren();\r\n\r\n this._logger.debug('Scene.onInitialize', this, engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n } catch (e) {\r\n this._logger.error(`Error during scene initialization for scene ${engine.director?.getSceneName(this)}!`);\r\n throw e;\r\n }\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\r\n * @internal\r\n */\r\n public async _activate(context: SceneActivationContext) {\r\n try {\r\n this._logger.debug('Scene.onActivate', this);\r\n this.input.toggleEnabled(true);\r\n await this.onActivate(context);\r\n } catch (e) {\r\n this._logger.error(`Error during scene activation for scene ${this.engine?.director?.getSceneName(this)}!`);\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\r\n * @internal\r\n */\r\n public async _deactivate(context: SceneActivationContext) {\r\n this._logger.debug('Scene.onDeactivate', this);\r\n this.input.toggleEnabled(false);\r\n await this.onDeactivate(context);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\r\n * @internal\r\n */\r\n public _predraw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n this.emit('predraw', new PreDrawEvent(ctx, delta, this));\r\n this.onPreDraw(ctx, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\r\n * @internal\r\n */\r\n public _postdraw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\r\n this.onPostDraw(ctx, delta);\r\n }\r\n\r\n /**\r\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\r\n * @param engine Reference to the current Engine\r\n * @param delta The number of milliseconds since the last update\r\n */\r\n public update(engine: Engine, delta: number) {\r\n if (!this.isInitialized) {\r\n this._logger.warnOnce(`Scene update called before initialize for scene ${engine.director?.getSceneName(this)}!`);\r\n return;\r\n }\r\n this._preupdate(engine, delta);\r\n\r\n // TODO differed entity removal for timers\r\n let i: number, len: number;\r\n // Remove timers in the cancel queue before updating them\r\n for (i = 0, len = this._cancelQueue.length; i < len; i++) {\r\n this.removeTimer(this._cancelQueue[i]);\r\n }\r\n this._cancelQueue.length = 0;\r\n\r\n // Cycle through timers updating timers\r\n for (const timer of this._timers) {\r\n timer.update(delta);\r\n }\r\n\r\n this.world.update(SystemType.Update, delta);\r\n\r\n // Camera last keeps renders smooth that are based on entity/actor\r\n if (this.camera) {\r\n this.camera.update(engine, delta);\r\n }\r\n\r\n this._collectActorStats(engine);\r\n\r\n this._postupdate(engine, delta);\r\n\r\n this.input.update();\r\n }\r\n\r\n /**\r\n * Draws all the actors in the Scene. Called by the [[Engine]].\r\n * @param ctx The current rendering context\r\n * @param delta The number of milliseconds since the last draw\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n if (!this.isInitialized) {\r\n this._logger.warnOnce(`Scene draw called before initialize!`);\r\n return;\r\n }\r\n this._predraw(ctx, delta);\r\n\r\n this.world.update(SystemType.Draw, delta);\r\n\r\n if (this.engine?.isDebug) {\r\n this.debugDraw(ctx);\r\n }\r\n this._postdraw(ctx, delta);\r\n }\r\n\r\n /**\r\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\r\n * @param ctx The current rendering context\r\n */\r\n /* istanbul ignore next */\r\n public debugDraw(ctx: ExcaliburGraphicsContext) {\r\n this.emit('predebugdraw', new PreDebugDrawEvent(ctx, this));\r\n // pass\r\n this.emit('postdebugdraw', new PostDebugDrawEvent(ctx, this));\r\n }\r\n\r\n /**\r\n * Checks whether an actor is contained in this scene or not\r\n */\r\n public contains(actor: Actor): boolean {\r\n return this.actors.indexOf(actor) > -1;\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the current [[Scene]].\r\n * @param timer The timer to add to the current [[Scene]].\r\n */\r\n public add(timer: Timer): void;\r\n\r\n /**\r\n * Adds a [[TileMap]] to the [[Scene]], once this is done the [[TileMap]] will be drawn and updated.\r\n */\r\n public add(tileMap: TileMap): void;\r\n\r\n /**\r\n * Adds a [[Trigger]] to the [[Scene]], once this is done the [[Trigger]] will listen for interactions with other actors.\r\n * @param trigger\r\n */\r\n public add(trigger: Trigger): void;\r\n\r\n /**\r\n * Adds an actor to the scene, once this is done the [[Actor]] will be drawn and updated.\r\n * @param actor The actor to add to the current scene\r\n */\r\n public add(actor: Actor): void;\r\n\r\n /**\r\n * Adds an [[Entity]] to the scene, once this is done the [[Actor]] will be drawn and updated.\r\n * @param entity The entity to add to the current scene\r\n */\r\n public add(entity: Entity): void;\r\n\r\n /**\r\n * Adds a [[ScreenElement]] to the scene.\r\n * @param screenElement The ScreenElement to add to the current scene\r\n */\r\n public add(screenElement: ScreenElement): void;\r\n public add(entity: any): void {\r\n this.emit('entityadded', { target: entity } as any);\r\n this.world.add(entity);\r\n entity.scene = this;\r\n if (entity instanceof Timer) {\r\n if (!Util.contains(this._timers, entity)) {\r\n this.addTimer(entity);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n\r\n\r\n /**\r\n * Removes a [[Timer]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param timer The Timer to transfer to the current scene\r\n */\r\n public transfer(timer: Timer): void;\r\n\r\n /**\r\n * Removes a [[TileMap]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param tileMap The TileMap to transfer to the current scene\r\n */\r\n public transfer(tileMap: TileMap): void;\r\n\r\n /**\r\n * Removes a [[Trigger]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param trigger The Trigger to transfer to the current scene\r\n */\r\n public transfer(trigger: Trigger): void;\r\n\r\n /**\r\n * Removes an [[Actor]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param actor The Actor to transfer to the current scene\r\n */\r\n public transfer(actor: Actor): void;\r\n\r\n /**\r\n * Removes an [[Entity]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param entity The Entity to transfer to the current scene\r\n */\r\n public transfer(entity: Entity): void;\r\n\r\n /**\r\n * Removes a [[ScreenElement]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param screenElement The ScreenElement to transfer to the current scene\r\n */\r\n public transfer(screenElement: ScreenElement): void;\r\n\r\n /**\r\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param entity\r\n */\r\n public transfer(entity: any): void {\r\n let scene: Scene;\r\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\r\n scene = entity.scene;\r\n entity.scene.world.remove(entity, false);\r\n }\r\n if (entity instanceof Timer && entity.scene) {\r\n scene = entity.scene;\r\n entity.scene.removeTimer(entity);\r\n }\r\n scene?.emit('entityremoved', { target: entity } as any);\r\n this.add(entity);\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the current scene, it will no longer be updated.\r\n * @param timer The timer to remove to the current scene.\r\n */\r\n public remove(timer: Timer): void;\r\n\r\n /**\r\n * Removes a [[TileMap]] from the scene, it will no longer be drawn or updated.\r\n * @param tileMap {TileMap}\r\n */\r\n public remove(tileMap: TileMap): void;\r\n\r\n /**\r\n * Removes an actor from the scene, it will no longer be drawn or updated.\r\n * @param actor The actor to remove from the current scene.\r\n */\r\n public remove(actor: Actor): void;\r\n\r\n public remove(entity: Entity): void;\r\n\r\n /**\r\n * Removes a [[ScreenElement]] to the scene, it will no longer be drawn or updated\r\n * @param screenElement The ScreenElement to remove from the current scene\r\n */\r\n public remove(screenElement: ScreenElement): void;\r\n public remove(entity: any): void {\r\n if (entity instanceof Entity) {\r\n this.emit('entityremoved', { target: entity } as any);\r\n if (entity.active) {\r\n entity.kill();\r\n }\r\n this.world.remove(entity);\r\n }\r\n if (entity instanceof Timer) {\r\n this.removeTimer(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\r\n *\r\n * By default entities use deferred removal\r\n * @param deferred\r\n */\r\n public clear(deferred: boolean = true): void {\r\n for (let i = this.entities.length - 1; i >= 0; i--) {\r\n this.world.remove(this.entities[i], deferred);\r\n }\r\n for (let i = this.timers.length - 1; i >= 0; i--) {\r\n this.removeTimer(this.timers[i]);\r\n }\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the scene\r\n * @param timer The timer to add\r\n */\r\n public addTimer(timer: Timer): Timer {\r\n this._timers.push(timer);\r\n timer.scene = this;\r\n return timer;\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the scene.\r\n * @warning Can be dangerous, use [[cancelTimer]] instead\r\n * @param timer The timer to remove\r\n */\r\n public removeTimer(timer: Timer): Timer {\r\n const i = this._timers.indexOf(timer);\r\n if (i !== -1) {\r\n this._timers.splice(i, 1);\r\n }\r\n return timer;\r\n }\r\n\r\n /**\r\n * Cancels a [[Timer]], removing it from the scene nicely\r\n * @param timer The timer to cancel\r\n */\r\n public cancelTimer(timer: Timer): Timer {\r\n this._cancelQueue.push(timer);\r\n return timer;\r\n }\r\n\r\n /**\r\n * Tests whether a [[Timer]] is active in the scene\r\n */\r\n public isTimerActive(timer: Timer): boolean {\r\n return this._timers.indexOf(timer) > -1 && !timer.complete;\r\n }\r\n\r\n public isCurrentScene(): boolean {\r\n if (this.engine) {\r\n return this.engine.currentScene === this;\r\n }\r\n return false;\r\n }\r\n\r\n private _collectActorStats(engine: Engine) {\r\n const screenElements = this.actors.filter((a) => a instanceof ScreenElement) as ScreenElement[];\r\n for (const _ui of screenElements) {\r\n engine.stats.currFrame.actors.ui++;\r\n }\r\n\r\n for (const actor of this.actors) {\r\n engine.stats.currFrame.actors.alive++;\r\n for (const child of actor.children) {\r\n if (isScreenElement(child as Actor)) {\r\n // TODO not true\r\n engine.stats.currFrame.actors.ui++;\r\n } else {\r\n engine.stats.currFrame.actors.alive++;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","\r\n\r\nexport enum ColorBlindnessMode {\r\n Protanope = 'Protanope',\r\n Deuteranope = 'Deuteranope',\r\n Tritanope = 'Tritanope'\r\n}\r\n","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\";","import { Shader } from '../Context/shader';\r\nimport { VertexBuffer } from '../Context/vertex-buffer';\r\nimport { VertexLayout } from '../Context/vertex-layout';\r\n\r\n/**\r\n * Helper that defines a whole screen renderer, just provide a fragment source!\r\n *\r\n * Currently supports 1 varying\r\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\r\n */\r\nexport class ScreenShader {\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n constructor(gl: WebGL2RenderingContext, fragmentSource: string) {\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\r\n fragmentSource: fragmentSource\r\n });\r\n this._shader.compile();\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n type: 'static',\r\n // clip space quad + uv since we don't need a camera\r\n data: new Float32Array([\r\n -1, -1, 0, 0,\r\n -1, 1, 0, 1,\r\n 1, -1, 1, 0,\r\n\r\n 1, -1, 1, 0,\r\n -1, 1, 0, 1,\r\n 1, 1, 1, 1\r\n ])\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_texcoord', 2]\r\n ]\r\n });\r\n this._buffer.upload();\r\n }\r\n\r\n public getShader() {\r\n return this._shader;\r\n }\r\n public getLayout() {\r\n return this._layout;\r\n }\r\n}","import colorBlindCorrectSource from './color-blind-fragment.glsl';\r\nimport { PostProcessor } from './PostProcessor';\r\nimport { ColorBlindnessMode } from './ColorBlindnessMode';\r\nimport { Shader } from '../Context/shader';\r\nimport { VertexLayout } from '../Context/vertex-layout';\r\nimport { ScreenShader } from './ScreenShader';\r\n\r\nexport class ColorBlindnessPostProcessor implements PostProcessor {\r\n private _shader: ScreenShader;\r\n private _simulate = false;\r\n constructor(private _colorBlindnessMode: ColorBlindnessMode, simulate = false) {\r\n this._simulate = simulate;\r\n }\r\n\r\n initialize(gl: WebGL2RenderingContext): void {\r\n this._shader = new ScreenShader(gl, colorBlindCorrectSource);\r\n this.simulate = this._simulate;\r\n this.colorBlindnessMode = this._colorBlindnessMode;\r\n }\r\n\r\n getShader(): Shader {\r\n return this._shader.getShader();\r\n }\r\n\r\n getLayout(): VertexLayout {\r\n return this._shader.getLayout();\r\n }\r\n\r\n set colorBlindnessMode(colorBlindMode: ColorBlindnessMode) {\r\n this._colorBlindnessMode = colorBlindMode;\r\n if (this._shader) {\r\n const shader = this._shader.getShader();\r\n shader.use();\r\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) {\r\n shader.setUniformInt('u_type', 0);\r\n } else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) {\r\n shader.setUniformInt('u_type', 1);\r\n } else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) {\r\n shader.setUniformInt('u_type', 2);\r\n }\r\n }\r\n }\r\n\r\n get colorBlindnessMode(): ColorBlindnessMode {\r\n return this._colorBlindnessMode;\r\n }\r\n\r\n set simulate(value: boolean) {\r\n this._simulate = value;\r\n if (this._shader) {\r\n\r\n const shader = this._shader.getShader();\r\n shader.use();\r\n shader.setUniformBoolean('u_simulate', value);\r\n }\r\n }\r\n\r\n get simulate(): boolean {\r\n return this._simulate;\r\n }\r\n}\r\n","import { ColorBlindnessMode } from '../Graphics/PostProcessor/ColorBlindnessMode';\r\nimport { ColorBlindnessPostProcessor } from '../Graphics/PostProcessor/ColorBlindnessPostProcessor';\r\nimport { Engine } from '../Engine';\r\nimport { ExcaliburGraphicsContextWebGL } from '../Graphics/Context/ExcaliburGraphicsContextWebGL';\r\n\r\nexport class ColorBlindFlags {\r\n private _engine: Engine;\r\n private _colorBlindPostProcessor: ColorBlindnessPostProcessor;\r\n\r\n constructor(engine: Engine) {\r\n this._engine = engine;\r\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\r\n }\r\n\r\n /**\r\n * Correct colors for a specified color blindness\r\n * @param colorBlindness\r\n */\r\n public correct(colorBlindness: ColorBlindnessMode) {\r\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this.clear();\r\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\r\n this._colorBlindPostProcessor.simulate = false;\r\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\r\n }\r\n }\r\n\r\n /**\r\n * Simulate colors for a specified color blindness\r\n * @param colorBlindness\r\n */\r\n public simulate(colorBlindness: ColorBlindnessMode) {\r\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this.clear();\r\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\r\n this._colorBlindPostProcessor.simulate = true;\r\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\r\n }\r\n }\r\n\r\n /**\r\n * Remove color blindness post processor\r\n */\r\n public clear() {\r\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\r\n }\r\n}\r\n","import { ColorBlindFlags } from './DebugFlags';\r\nimport { Engine } from '../Engine';\r\nimport { Color } from '../Color';\r\nimport { CollisionContact } from '../Collision/Detection/CollisionContact';\r\nimport { StandardClock, TestClock } from '../Util/Clock';\r\n\r\n/**\r\n * Debug stats containing current and previous frame statistics\r\n */\r\nexport interface DebugStats {\r\n currFrame: FrameStats;\r\n prevFrame: FrameStats;\r\n}\r\n\r\n/**\r\n * Represents a frame's individual statistics\r\n */\r\nexport interface FrameStatistics {\r\n /**\r\n * The number of the frame\r\n */\r\n id: number;\r\n\r\n /**\r\n * Gets the frame's delta (time since last frame scaled by [[Engine.timescale]]) (in ms)\r\n */\r\n delta: number;\r\n\r\n /**\r\n * Gets the frame's frames-per-second (FPS)\r\n */\r\n fps: number;\r\n\r\n /**\r\n * Duration statistics (in ms)\r\n */\r\n duration: FrameDurationStats;\r\n\r\n /**\r\n * Actor statistics\r\n */\r\n actors: FrameActorStats;\r\n\r\n /**\r\n * Physics statistics\r\n */\r\n physics: PhysicsStatistics;\r\n\r\n /**\r\n * Graphics statistics\r\n */\r\n graphics: GraphicsStatistics;\r\n}\r\n\r\n/**\r\n * Represents actor stats for a frame\r\n */\r\nexport interface FrameActorStats {\r\n /**\r\n * Gets the frame's number of actors (alive)\r\n */\r\n alive: number;\r\n\r\n /**\r\n * Gets the frame's number of actors (killed)\r\n */\r\n killed: number;\r\n\r\n /**\r\n * Gets the frame's number of remaining actors (alive - killed)\r\n */\r\n remaining: number;\r\n\r\n /**\r\n * Gets the frame's number of UI actors\r\n */\r\n ui: number;\r\n\r\n /**\r\n * Gets the frame's number of total actors (remaining + UI)\r\n */\r\n total: number;\r\n}\r\n\r\n/**\r\n * Represents duration stats for a frame\r\n */\r\nexport interface FrameDurationStats {\r\n /**\r\n * Gets the frame's total time to run the update function (in ms)\r\n */\r\n update: number;\r\n\r\n /**\r\n * Gets the frame's total time to run the draw function (in ms)\r\n */\r\n draw: number;\r\n\r\n /**\r\n * Gets the frame's total render duration (update + draw duration) (in ms)\r\n */\r\n total: number;\r\n}\r\n\r\n/**\r\n * Represents physics stats for the current frame\r\n */\r\nexport interface PhysicsStatistics {\r\n /**\r\n * Gets the number of broadphase collision pairs which\r\n */\r\n pairs: number;\r\n\r\n /**\r\n * Gets the number of actual collisions\r\n */\r\n collisions: number;\r\n\r\n /**\r\n * Copy of the current frame contacts (only updated if debug is toggled on)\r\n */\r\n contacts: Map;\r\n\r\n /**\r\n * Gets the number of fast moving bodies using raycast continuous collisions in the scene\r\n */\r\n fastBodies: number;\r\n\r\n /**\r\n * Gets the number of bodies that had a fast body collision resolution\r\n */\r\n fastBodyCollisions: number;\r\n\r\n /**\r\n * Gets the time it took to calculate the broadphase pairs\r\n */\r\n broadphase: number;\r\n\r\n /**\r\n * Gets the time it took to calculate the narrowphase\r\n */\r\n narrowphase: number;\r\n}\r\n\r\nexport interface GraphicsStatistics {\r\n drawCalls: number;\r\n drawnImages: number;\r\n}\r\n\r\n/**\r\n * Debug statistics and flags for Excalibur. If polling these values, it would be\r\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\r\n * updated during a frame.\r\n */\r\nexport class DebugConfig {\r\n private _engine: Engine;\r\n\r\n constructor(engine: Engine) {\r\n this._engine = engine;\r\n\r\n this.colorBlindMode = new ColorBlindFlags(this._engine);\r\n }\r\n\r\n /**\r\n * Switch the current excalibur clock with the [[TestClock]] and return\r\n * it in the same running state.\r\n *\r\n * This is useful when you need to debug frame by frame.\r\n */\r\n public useTestClock(): TestClock {\r\n const clock = this._engine.clock;\r\n const wasRunning = clock.isRunning();\r\n clock.stop();\r\n\r\n const testClock = clock.toTestClock();\r\n if (wasRunning) {\r\n testClock.start();\r\n }\r\n this._engine.clock = testClock;\r\n return testClock;\r\n }\r\n\r\n /**\r\n * Switch the current excalibur clock with the [[StandardClock]] and\r\n * return it in the same running state.\r\n *\r\n * This is useful when you need to switch back to normal mode after\r\n * debugging.\r\n */\r\n public useStandardClock(): StandardClock {\r\n const currentClock = this._engine.clock;\r\n const wasRunning = currentClock.isRunning();\r\n currentClock.stop();\r\n\r\n const standardClock = currentClock.toStandardClock();\r\n if (wasRunning) {\r\n standardClock.start();\r\n }\r\n this._engine.clock = standardClock;\r\n return standardClock;\r\n }\r\n\r\n /**\r\n * Performance statistics\r\n */\r\n public stats: DebugStats = {\r\n /**\r\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[postframe]] event. See [[FrameStats]]\r\n */\r\n currFrame: new FrameStats(),\r\n\r\n /**\r\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\r\n */\r\n prevFrame: new FrameStats()\r\n };\r\n\r\n /**\r\n * Correct or simulate color blindness using [[ColorBlindnessPostProcessor]].\r\n * @warning Will reduce FPS.\r\n */\r\n public colorBlindMode: ColorBlindFlags;\r\n\r\n /**\r\n * Filter debug context to named entities or entity ids\r\n */\r\n public filter: { useFilter: boolean; nameQuery: string; ids: number[] } = {\r\n /**\r\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\r\n */\r\n useFilter: false,\r\n /**\r\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\r\n */\r\n nameQuery: '',\r\n /**\r\n * Query for Entity ids, if the id matches it will be included\r\n */\r\n ids: []\r\n };\r\n\r\n /**\r\n * Entity debug settings\r\n */\r\n public entity = {\r\n showAll: false,\r\n showId: false,\r\n showName: false\r\n };\r\n\r\n /**\r\n * Transform component debug settings\r\n */\r\n public transform = {\r\n showAll: false,\r\n\r\n debugZIndex: 10_000_000,\r\n showPosition: false,\r\n showPositionLabel: false,\r\n positionColor: Color.Yellow,\r\n\r\n showZIndex: false,\r\n\r\n showScale: false,\r\n scaleColor: Color.Green,\r\n\r\n showRotation: false,\r\n rotationColor: Color.Blue\r\n };\r\n\r\n /**\r\n * Graphics component debug settings\r\n */\r\n public graphics = {\r\n showAll: false,\r\n\r\n showBounds: false,\r\n boundsColor: Color.Yellow\r\n };\r\n\r\n /**\r\n * Collider component debug settings\r\n */\r\n public collider = {\r\n showAll: false,\r\n\r\n showBounds: false,\r\n boundsColor: Color.Blue,\r\n\r\n showOwner: false,\r\n\r\n showGeometry: true,\r\n geometryColor: Color.Green,\r\n geometryLineWidth: 1,\r\n geometryPointSize: .5\r\n };\r\n\r\n /**\r\n * Physics simulation debug settings\r\n */\r\n public physics = {\r\n showAll: false,\r\n\r\n showBroadphaseSpacePartitionDebug: false,\r\n\r\n showCollisionNormals: false,\r\n collisionNormalColor: Color.Cyan,\r\n\r\n showCollisionContacts: true,\r\n contactSize: 2,\r\n collisionContactColor: Color.Red\r\n };\r\n\r\n /**\r\n * Motion component debug settings\r\n */\r\n public motion = {\r\n showAll: false,\r\n\r\n showVelocity: false,\r\n velocityColor: Color.Yellow,\r\n\r\n showAcceleration: false,\r\n accelerationColor: Color.Red\r\n };\r\n\r\n /**\r\n * Body component debug settings\r\n */\r\n public body = {\r\n showAll: false,\r\n\r\n showCollisionGroup: false,\r\n showCollisionType: false,\r\n showSleeping: false,\r\n showMotion: false,\r\n showMass: false\r\n };\r\n\r\n /**\r\n * Camera debug settings\r\n */\r\n public camera = {\r\n showAll: false,\r\n\r\n showFocus: false,\r\n focusColor: Color.Red,\r\n\r\n showZoom: false\r\n };\r\n\r\n public tilemap = {\r\n showAll: false,\r\n\r\n showGrid: false,\r\n gridColor: Color.Red,\r\n gridWidth: .5,\r\n showSolidBounds: false,\r\n solidBoundsColor: Color.fromHex('#8080807F'), // grayish\r\n showColliderGeometry: true\r\n };\r\n\r\n public isometric = {\r\n showAll: false,\r\n showPosition: false,\r\n positionColor: Color.Yellow,\r\n positionSize: 1,\r\n showGrid: false,\r\n gridColor: Color.Red,\r\n gridWidth: 1,\r\n showColliderGeometry: true\r\n };\r\n}\r\n\r\n/**\r\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\r\n * creating instances of this every frame.\r\n */\r\nexport class FrameStats implements FrameStatistics {\r\n private _id: number = 0;\r\n private _delta: number = 0;\r\n private _fps: number = 0;\r\n private _actorStats: FrameActorStats = {\r\n alive: 0,\r\n killed: 0,\r\n ui: 0,\r\n get remaining() {\r\n return this.alive - this.killed;\r\n },\r\n get total() {\r\n return this.remaining + this.ui;\r\n }\r\n };\r\n private _durationStats: FrameDurationStats = {\r\n update: 0,\r\n draw: 0,\r\n get total() {\r\n return this.update + this.draw;\r\n }\r\n };\r\n\r\n private _physicsStats: PhysicsStats = new PhysicsStats();\r\n\r\n private _graphicsStats: GraphicsStatistics = {\r\n drawCalls: 0,\r\n drawnImages: 0\r\n };\r\n\r\n /**\r\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\r\n * @param [otherStats] Optional stats to clone\r\n */\r\n public reset(otherStats?: FrameStatistics) {\r\n if (otherStats) {\r\n this.id = otherStats.id;\r\n this.delta = otherStats.delta;\r\n this.fps = otherStats.fps;\r\n this.actors.alive = otherStats.actors.alive;\r\n this.actors.killed = otherStats.actors.killed;\r\n this.actors.ui = otherStats.actors.ui;\r\n this.duration.update = otherStats.duration.update;\r\n this.duration.draw = otherStats.duration.draw;\r\n this._physicsStats.reset(otherStats.physics);\r\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\r\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\r\n } else {\r\n this.id = this.delta = this.fps = 0;\r\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\r\n this.duration.update = this.duration.draw = 0;\r\n this._physicsStats.reset();\r\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Provides a clone of this instance.\r\n */\r\n public clone(): FrameStats {\r\n const fs = new FrameStats();\r\n\r\n fs.reset(this);\r\n\r\n return fs;\r\n }\r\n\r\n /**\r\n * Gets the frame's id\r\n */\r\n public get id() {\r\n return this._id;\r\n }\r\n\r\n /**\r\n * Sets the frame's id\r\n */\r\n public set id(value: number) {\r\n this._id = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's delta (time since last frame)\r\n */\r\n public get delta() {\r\n return this._delta;\r\n }\r\n\r\n /**\r\n * Sets the frame's delta (time since last frame). Internal use only.\r\n * @internal\r\n */\r\n public set delta(value: number) {\r\n this._delta = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's frames-per-second (FPS)\r\n */\r\n public get fps() {\r\n return this._fps;\r\n }\r\n\r\n /**\r\n * Sets the frame's frames-per-second (FPS). Internal use only.\r\n * @internal\r\n */\r\n public set fps(value: number) {\r\n this._fps = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's actor statistics\r\n */\r\n public get actors() {\r\n return this._actorStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's duration statistics\r\n */\r\n public get duration() {\r\n return this._durationStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's physics statistics\r\n */\r\n public get physics() {\r\n return this._physicsStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's graphics statistics\r\n */\r\n public get graphics() {\r\n return this._graphicsStats;\r\n }\r\n}\r\n\r\nexport class PhysicsStats implements PhysicsStatistics {\r\n private _pairs: number = 0;\r\n private _collisions: number = 0;\r\n private _contacts: Map = new Map();\r\n private _fastBodies: number = 0;\r\n private _fastBodyCollisions: number = 0;\r\n private _broadphase: number = 0;\r\n private _narrowphase: number = 0;\r\n\r\n /**\r\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\r\n * @param [otherStats] Optional stats to clone\r\n */\r\n public reset(otherStats?: PhysicsStatistics) {\r\n if (otherStats) {\r\n this.pairs = otherStats.pairs;\r\n this.collisions = otherStats.collisions;\r\n this.contacts = otherStats.contacts;\r\n this.fastBodies = otherStats.fastBodies;\r\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\r\n this.broadphase = otherStats.broadphase;\r\n this.narrowphase = otherStats.narrowphase;\r\n } else {\r\n this.pairs = this.collisions = this.fastBodies = 0;\r\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\r\n this.contacts.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Provides a clone of this instance.\r\n */\r\n public clone(): PhysicsStatistics {\r\n const ps = new PhysicsStats();\r\n\r\n ps.reset(this);\r\n\r\n return ps;\r\n }\r\n\r\n public get pairs(): number {\r\n return this._pairs;\r\n }\r\n\r\n public set pairs(value: number) {\r\n this._pairs = value;\r\n }\r\n\r\n public get collisions(): number {\r\n return this._collisions;\r\n }\r\n\r\n public set collisions(value: number) {\r\n this._collisions = value;\r\n }\r\n\r\n public get contacts(): Map {\r\n return this._contacts;\r\n }\r\n\r\n public set contacts(contacts: Map) {\r\n this._contacts = contacts;\r\n }\r\n\r\n public get fastBodies(): number {\r\n return this._fastBodies;\r\n }\r\n\r\n public set fastBodies(value: number) {\r\n this._fastBodies = value;\r\n }\r\n\r\n public get fastBodyCollisions(): number {\r\n return this._fastBodyCollisions;\r\n }\r\n\r\n public set fastBodyCollisions(value: number) {\r\n this._fastBodyCollisions = value;\r\n }\r\n\r\n public get broadphase(): number {\r\n return this._broadphase;\r\n }\r\n\r\n public set broadphase(value: number) {\r\n this._broadphase = value;\r\n }\r\n\r\n public get narrowphase(): number {\r\n return this._narrowphase;\r\n }\r\n\r\n public set narrowphase(value: number) {\r\n this._narrowphase = value;\r\n }\r\n}\r\n","export interface NativeEventable {\r\n addEventListener(name: string, handler: (...any: any[]) => any): any;\r\n removeEventListener(name: string, handler: (...any: any[]) => any): any;\r\n}\r\n\r\nexport class BrowserComponent {\r\n private _paused = false;\r\n private _nativeHandlers: { [key: string]: (handler: any) => void } = {};\r\n\r\n on(eventName: string, handler: (evt: any) => void): void {\r\n if (this._nativeHandlers[eventName]) {\r\n this.off(eventName, this._nativeHandlers[eventName]);\r\n }\r\n this._nativeHandlers[eventName] = this._decorate(handler);\r\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\r\n }\r\n off(eventName: string, handler?: (event: any) => void): void {\r\n if (!handler) {\r\n handler = this._nativeHandlers[eventName];\r\n }\r\n this.nativeComponent.removeEventListener(eventName, handler);\r\n this._nativeHandlers[eventName] = null;\r\n }\r\n\r\n private _decorate(handler: (evt: any) => void): (evt: any) => void {\r\n return (evt: any) => {\r\n if (!this._paused) {\r\n handler(evt);\r\n }\r\n };\r\n }\r\n\r\n public pause() {\r\n this._paused = true;\r\n }\r\n\r\n public resume() {\r\n this._paused = false;\r\n }\r\n\r\n public clear() {\r\n for (const event in this._nativeHandlers) {\r\n this.off(event);\r\n }\r\n }\r\n\r\n constructor(public nativeComponent: T) {}\r\n}\r\n\r\nexport class BrowserEvents {\r\n private _windowComponent: BrowserComponent;\r\n private _documentComponent: BrowserComponent;\r\n constructor(private _windowGlobal: Window, private _documentGlobal: Document) {\r\n this._windowComponent = new BrowserComponent(this._windowGlobal);\r\n this._documentComponent = new BrowserComponent(this._documentGlobal);\r\n }\r\n\r\n public get window(): BrowserComponent {\r\n return this._windowComponent;\r\n }\r\n\r\n public get document(): BrowserComponent {\r\n return this._documentComponent;\r\n }\r\n\r\n public pause() {\r\n this.window.pause();\r\n this.document.pause();\r\n }\r\n\r\n public resume() {\r\n this.window.resume();\r\n this.document.resume();\r\n }\r\n\r\n public clear() {\r\n this.window.clear();\r\n this.document.clear();\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { Color } from '../../Color';\r\nimport { ScreenDimension } from '../../Screen';\r\nimport { PostProcessor } from '../PostProcessor/PostProcessor';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Material, MaterialOptions } from './material';\r\nimport { ImageFiltering } from '../Filtering';\r\n\r\nexport type HTMLImageSource = HTMLImageElement | HTMLCanvasElement;\r\n\r\nexport interface AntialiasOptions {\r\n /**\r\n * Turns on the special pixel art sampler in excalibur's image shader for sub pixel\r\n * anti-aliasing\r\n *\r\n * Default false\r\n */\r\n pixelArtSampler?: boolean;\r\n /**\r\n * Configures the webgl's getContext('webgl2', {antialias: true | false}) or configures\r\n * Canvas2D imageSmoothing = true;\r\n *\r\n * **Note** this option is incompatible with `multiSampleAntialiasing`\r\n *\r\n * Default false\r\n */\r\n nativeContextAntialiasing?: boolean;\r\n /**\r\n * Configures the internal render buffer multi-sampling settings\r\n *\r\n * Default true, with max samples that the platform supports\r\n */\r\n multiSampleAntialiasing?: boolean | {\r\n /**\r\n * Optionally specify number of samples (will be clamped to the max the platform supports)\r\n *\r\n * Default most platforms are 16 samples\r\n */\r\n samples: number;\r\n };\r\n /**\r\n * Sets the default image filtering for excalibur\r\n *\r\n * Default [[ImageFiltering.Blended]]\r\n */\r\n filtering?: ImageFiltering;\r\n /**\r\n * Sets the canvas image rendering CSS style\r\n *\r\n * Default 'auto'\r\n */\r\n canvasImageRendering?: 'pixelated' | 'auto';\r\n}\r\n\r\nexport const DefaultAntialiasOptions: Required = {\r\n pixelArtSampler: false,\r\n nativeContextAntialiasing: false,\r\n multiSampleAntialiasing: true,\r\n filtering: ImageFiltering.Blended,\r\n canvasImageRendering: 'auto'\r\n};\r\n\r\nexport const DefaultPixelArtOptions: Required = {\r\n pixelArtSampler: true,\r\n nativeContextAntialiasing: false,\r\n multiSampleAntialiasing: true,\r\n filtering: ImageFiltering.Blended,\r\n canvasImageRendering: 'auto'\r\n};\r\n\r\nexport interface ExcaliburGraphicsContextOptions {\r\n /**\r\n * Target existing html canvas element\r\n */\r\n canvasElement: HTMLCanvasElement;\r\n /**\r\n * Enables antialiasing on the canvas context (smooths pixels with default canvas sampling)\r\n */\r\n antialiasing?: boolean;\r\n /**\r\n * Enable the sub pixel antialiasing pixel art sampler for nice looking pixel art\r\n */\r\n pixelArtSampler?: boolean;\r\n /**\r\n * Enable canvas transparency\r\n */\r\n enableTransparency?: boolean;\r\n /**\r\n * Enable or disable multi-sample antialiasing in the internal render buffer.\r\n *\r\n * If true the max number of samples will be used\r\n *\r\n * By default enabled\r\n */\r\n multiSampleAntialiasing?: boolean | {\r\n /**\r\n * Specify number of samples to use during the multi sample anti-alias, if not specified the max will be used.\r\n * Limited by the hardware (usually 16)\r\n */\r\n samples: number\r\n },\r\n /**\r\n * UV padding in pixels to use in the internal image rendering\r\n *\r\n * Recommended .25 - .5 of a pixel\r\n */\r\n uvPadding?: number;\r\n /**\r\n * Hint the power preference to the graphics context\r\n */\r\n powerPreference?: 'default' | 'high-performance' | 'low-power';\r\n /**\r\n * Snaps the pixel to an integer value (floor)\r\n */\r\n snapToPixel?: boolean;\r\n /**\r\n * Current clearing color of the context\r\n */\r\n backgroundColor?: Color;\r\n /**\r\n * Feature flag that enables draw sorting will removed in v0.29\r\n */\r\n useDrawSorting?: boolean;\r\n}\r\n\r\nexport interface ExcaliburGraphicsContextState {\r\n opacity: number;\r\n z: number;\r\n tint: Color;\r\n material: Material;\r\n}\r\nexport interface LineGraphicsOptions {\r\n color?: Color;\r\n}\r\n\r\nexport interface RectGraphicsOptions {\r\n color?: Color;\r\n}\r\n\r\nexport interface PointGraphicsOptions {\r\n color: Color;\r\n size: number;\r\n}\r\n\r\nexport interface DebugDraw {\r\n /**\r\n * Draw a debugging rectangle to the screen\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n * @param rectOptions\r\n */\r\n drawRect(x: number, y: number, width: number, height: number, rectOptions?: RectGraphicsOptions): void;\r\n /**\r\n * Draw a debugging line to the screen\r\n * @param start '\r\n * @param end\r\n * @param lineOptions\r\n */\r\n drawLine(start: Vector, end: Vector, lineOptions?: LineGraphicsOptions): void;\r\n /**\r\n * Draw a debugging point to the screen\r\n * @param point\r\n * @param pointOptions\r\n */\r\n drawPoint(point: Vector, pointOptions?: PointGraphicsOptions): void;\r\n\r\n /**\r\n * Draw debug text\r\n * @param text\r\n * @param pos\r\n */\r\n drawText(text: string, pos: Vector): void;\r\n}\r\n\r\nexport interface ExcaliburGraphicsContext {\r\n width: number;\r\n height: number;\r\n\r\n /**\r\n * Excalibur will automatically sort draw calls by z and priority for maximal draw performance,\r\n * this can disrupt a specific desired painter order.\r\n *\r\n * To force a specific draw call order, use [[ExcaliburGraphicsContext.z]]\r\n *\r\n * By default `useDrawSorting` is `true`, to opt out set this to `false`\r\n */\r\n useDrawSorting: boolean;\r\n\r\n /**\r\n * Set the current z context for the graphics context. Draw calls issued to the context will use this z\r\n * to inform their sort order.\r\n *\r\n * Note it is important to all [[ExcaliburGraphicsContext.save]] and [[ExcaliburGraphicsContext.restore]] when modifying state.\r\n */\r\n z: number;\r\n\r\n /**\r\n * Snaps all drawings to the nearest pixel truncated down, by default false\r\n */\r\n snapToPixel: boolean;\r\n\r\n /**\r\n * Enable smoothed drawing (also known as anti-aliasing), by default true\r\n */\r\n smoothing: boolean;\r\n\r\n /**\r\n * Set the background color of the graphics context, default is [[Color.ExcaliburBlue]]\r\n */\r\n backgroundColor: Color;\r\n\r\n /**\r\n * Sets the opacity of the current [[Graphic]] being drawn, default is 1\r\n */\r\n opacity: number;\r\n\r\n /**\r\n * Sets the tint color to be multiplied by any images drawn, default is black 0xFFFFFFFF\r\n */\r\n tint: Color;\r\n\r\n /**\r\n * Resets the current transform to the identity matrix\r\n */\r\n resetTransform(): void;\r\n\r\n /**\r\n * Gets the current transform\r\n */\r\n getTransform(): AffineMatrix;\r\n\r\n /**\r\n * Multiplies the current transform by a matrix\r\n * @param m\r\n */\r\n multiply(m: AffineMatrix): void;\r\n\r\n /**\r\n * Update the context with the current viewport dimensions (used in resizing)\r\n */\r\n updateViewport(resolution: ScreenDimension): void;\r\n\r\n /**\r\n * Access the debug drawing api\r\n */\r\n debug: DebugDraw;\r\n\r\n /**\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate using the images width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate with a specific width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number, width: number, height: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context specifying the source image coordinates (sx, sy, swidth, sheight)\r\n * and to a specific destination on the context (dx, dy, dwidth, dheight)\r\n */\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void;\r\n\r\n /**\r\n * Draw a solid line to the Excalibur Graphics context\r\n * @param start\r\n * @param end\r\n * @param color\r\n * @param thickness\r\n */\r\n drawLine(start: Vector, end: Vector, color: Color, thickness: number): void;\r\n\r\n /**\r\n * Draw a solid rectangle to the Excalibur Graphics context\r\n * @param pos\r\n * @param width\r\n * @param height\r\n * @param color\r\n */\r\n drawRectangle(pos: Vector, width: number, height: number, color: Color, stroke?: Color, strokeThickness?: number): void;\r\n\r\n /**\r\n * Draw a circle to the Excalibur Graphics context\r\n * @param pos\r\n * @param radius\r\n * @param color\r\n * @param stroke Optionally specify the stroke color\r\n * @param thickness\r\n */\r\n drawCircle(pos: Vector, radius: number, color: Color, stroke?: Color, thickness?: number): void;\r\n\r\n /**\r\n * Save the current state of the canvas to the stack (transforms and opacity)\r\n */\r\n save(): void;\r\n\r\n /**\r\n * Restore the state of the canvas from the stack\r\n */\r\n restore(): void;\r\n\r\n /**\r\n * Translate the origin of the context by an x and y\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number): void;\r\n\r\n /**\r\n * Rotate the context about the current origin\r\n */\r\n rotate(angle: number): void;\r\n\r\n /**\r\n * Scale the context by an x and y factor\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number): void;\r\n\r\n /**\r\n * Add a post processor to the graphics context\r\n *\r\n * Post processors are run in the order they were added.\r\n * @param postprocessor\r\n */\r\n addPostProcessor(postprocessor: PostProcessor): void;\r\n\r\n /**\r\n * Remove a specific post processor from the graphics context\r\n * @param postprocessor\r\n */\r\n removePostProcessor(postprocessor: PostProcessor): void;\r\n\r\n /**\r\n * Remove all post processors from the graphics context\r\n */\r\n clearPostProcessors(): void;\r\n\r\n /**\r\n * Updates all post processors in the graphics context\r\n *\r\n * Called internally by Excalibur\r\n * @param delta\r\n * @internal\r\n */\r\n updatePostProcessors(delta: number): void;\r\n\r\n /**\r\n * Gets or sets the material to be used in the current context's drawings\r\n *\r\n * This allows customs shaders to be used but draw calls are no longer batched by default.\r\n * @param material\r\n */\r\n material: Material;\r\n\r\n /**\r\n * Creates and initializes the material which compiles the internal shader\r\n * @param options\r\n * @returns\r\n */\r\n createMaterial(options: Omit): Material;\r\n\r\n /**\r\n * Clears the screen with the current background color\r\n */\r\n clear(): void;\r\n\r\n /**\r\n * Flushes the batched draw calls to the screen\r\n */\r\n flush(): void;\r\n\r\n beginDrawLifecycle(): void;\r\n\r\n endDrawLifecycle(): void;\r\n\r\n dispose(): void;\r\n}\r\n","export interface FpsSamplerOptions {\r\n /**\r\n * Specify the sampling period in milliseconds (default 100)\r\n */\r\n samplePeriod?: number;\r\n /**\r\n * Specify the initial FPS\r\n */\r\n initialFps: number;\r\n\r\n /**\r\n * Specify the function used to return the current time (in milliseconds)\r\n */\r\n nowFn: () => number;\r\n}\r\n\r\nexport class FpsSampler {\r\n private _fps: number;\r\n private _samplePeriod: number = 100;\r\n private _currentFrameTime: number = 0;\r\n private _frames: number = 0;\r\n private _previousSampleTime: number = 0;\r\n private _beginFrameTime: number = 0;\r\n private _nowFn: () => number;\r\n\r\n constructor(options: FpsSamplerOptions) {\r\n this._fps = options.initialFps;\r\n this._samplePeriod = options.samplePeriod ?? this._samplePeriod;\r\n this._currentFrameTime = 1000/options.initialFps;\r\n this._nowFn = options.nowFn;\r\n this._previousSampleTime = this._nowFn();\r\n }\r\n\r\n /**\r\n * Start of code block to sample FPS for\r\n */\r\n start() {\r\n this._beginFrameTime = this._nowFn();\r\n }\r\n\r\n /**\r\n * End of code block to sample FPS for\r\n */\r\n end() {\r\n this._frames++;\r\n const time = this._nowFn();\r\n\r\n this._currentFrameTime = time - this._beginFrameTime;\r\n\r\n if (time >= this._previousSampleTime + this._samplePeriod) {\r\n this._fps = (this._frames * 1000) / (time - this._previousSampleTime);\r\n this._previousSampleTime = time;\r\n this._frames = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Return the currently sampled fps over the last sample period, by default every 100ms\r\n */\r\n get fps() {\r\n return this._fps;\r\n }\r\n\r\n /**\r\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\r\n */\r\n get instant() {\r\n return 1000 / this._currentFrameTime;\r\n }\r\n}","import { Logger } from '../Util/Log';\r\nimport { FpsSampler } from './Fps';\r\n\r\nexport interface ClockOptions {\r\n /**\r\n * Define the function you'd like the clock to tick when it is started\r\n */\r\n tick: (elapsedMs: number) => any;\r\n /**\r\n * Optionally define the fatal exception handler, used if an error is thrown in tick\r\n */\r\n onFatalException?: (e: unknown) => any;\r\n /**\r\n * Optionally limit the maximum FPS of the clock\r\n */\r\n maxFps?: number;\r\n}\r\n\r\n\r\n/**\r\n * Abstract Clock is the base type of all Clocks\r\n *\r\n * It has a few opinions\r\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\r\n * 2. The default timing api is implemented in now()\r\n *\r\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\r\n * method is unique to your clock implementation.\r\n */\r\nexport abstract class Clock {\r\n protected tick: (elapsedMs: number) => any;\r\n private _onFatalException: (e: unknown) => any = () => { /* default nothing */ };\r\n private _maxFps: number = Infinity;\r\n private _lastTime: number = 0;\r\n public fpsSampler: FpsSampler;\r\n private _options: ClockOptions;\r\n private _elapsed: number = 1;\r\n private _scheduledCbs: [cb: (elapsedMs: number) => any, scheduledTime: number][] = [];\r\n private _totalElapsed: number = 0;\r\n constructor(options: ClockOptions) {\r\n this._options = options;\r\n this.tick = options.tick;\r\n this._lastTime = this.now() ?? 0;\r\n this._maxFps = options.maxFps ?? this._maxFps;\r\n this._onFatalException = options.onFatalException ?? this._onFatalException;\r\n this.fpsSampler = new FpsSampler({\r\n initialFps: 60,\r\n nowFn: () => this.now()\r\n });\r\n }\r\n\r\n /**\r\n * Get the elapsed time for the last completed frame\r\n */\r\n public elapsed(): number {\r\n return this._elapsed;\r\n }\r\n\r\n /**\r\n * Get the current time in milliseconds\r\n */\r\n public now(): number {\r\n return performance.now();\r\n }\r\n\r\n public toTestClock() {\r\n const testClock = new TestClock({\r\n ...this._options,\r\n defaultUpdateMs: 16.6\r\n });\r\n return testClock;\r\n }\r\n\r\n public toStandardClock() {\r\n const clock = new StandardClock({\r\n ...this._options\r\n });\r\n return clock;\r\n }\r\n\r\n public setFatalExceptionHandler(handler: (e: unknown) => any) {\r\n this._onFatalException = handler;\r\n }\r\n\r\n /**\r\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\r\n *\r\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\r\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\r\n * stopped or paused.\r\n * @param cb callback to fire\r\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\r\n */\r\n public schedule(cb: (elapsedMs: number) => any, timeoutMs: number = 0) {\r\n // Scheduled based on internal elapsed time\r\n const scheduledTime = this._totalElapsed + timeoutMs;\r\n this._scheduledCbs.push([cb, scheduledTime]);\r\n }\r\n\r\n private _runScheduledCbs() {\r\n // walk backwards to delete items as we loop\r\n for (let i = this._scheduledCbs.length - 1; i > -1; i--) {\r\n if (this._scheduledCbs[i][1] <= this._totalElapsed) {\r\n this._scheduledCbs[i][0](this._elapsed);\r\n this._scheduledCbs.splice(i, 1);\r\n }\r\n }\r\n }\r\n\r\n protected update(overrideUpdateMs?: number): void {\r\n try {\r\n this.fpsSampler.start();\r\n // Get the time to calculate time-elapsed\r\n const now = this.now();\r\n let elapsed = now - this._lastTime || 1; // first frame\r\n\r\n // Constrain fps\r\n const fpsInterval = (1000 / this._maxFps);\r\n\r\n // only run frame if enough time has elapsed\r\n if (elapsed >= fpsInterval) {\r\n let leftover = 0;\r\n if (fpsInterval !== 0) {\r\n leftover = (elapsed % fpsInterval);\r\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\r\n }\r\n\r\n // Resolves issue #138 if the game has been paused, or blurred for\r\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\r\n // and provides more expected behavior when the engine comes back\r\n // into focus\r\n if (elapsed > 200) {\r\n elapsed = 1;\r\n }\r\n\r\n // tick the mainloop and run scheduled callbacks\r\n this._elapsed = overrideUpdateMs || elapsed;\r\n this._totalElapsed += this._elapsed;\r\n this._runScheduledCbs();\r\n this.tick(overrideUpdateMs || elapsed);\r\n\r\n if (fpsInterval !== 0) {\r\n this._lastTime = now - leftover;\r\n } else {\r\n this._lastTime = now;\r\n }\r\n this.fpsSampler.end();\r\n }\r\n } catch (e) {\r\n this._onFatalException(e);\r\n this.stop();\r\n }\r\n }\r\n\r\n /**\r\n * Returns if the clock is currently running\r\n */\r\n public abstract isRunning(): boolean;\r\n\r\n /**\r\n * Start the clock, it will then periodically call the tick(elapsedMilliseconds) since the last tick\r\n */\r\n public abstract start(): void;\r\n\r\n /**\r\n * Stop the clock, tick() is no longer called\r\n */\r\n public abstract stop(): void;\r\n}\r\n\r\n\r\n/**\r\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\r\n */\r\nexport class StandardClock extends Clock {\r\n\r\n private _running = false;\r\n private _requestId: number;\r\n constructor(options: ClockOptions) {\r\n super(options);\r\n }\r\n\r\n public isRunning(): boolean {\r\n return this._running;\r\n }\r\n\r\n public start(): void {\r\n if (this._running) {\r\n return;\r\n }\r\n this._running = true;\r\n const mainloop = () => {\r\n // stop the loop\r\n if (!this._running) {\r\n return;\r\n }\r\n try {\r\n // request next loop\r\n this._requestId = window.requestAnimationFrame(mainloop);\r\n this.update();\r\n } catch (e) {\r\n window.cancelAnimationFrame(this._requestId);\r\n throw e;\r\n }\r\n };\r\n\r\n // begin the first frame\r\n mainloop();\r\n }\r\n\r\n public stop(): void {\r\n window.cancelAnimationFrame(this._requestId);\r\n this._running = false;\r\n }\r\n}\r\n\r\nexport interface TestClockOptions {\r\n /**\r\n * Specify the update milliseconds to use for each manual step()\r\n */\r\n defaultUpdateMs: number;\r\n}\r\n\r\n/**\r\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\r\n */\r\nexport class TestClock extends Clock {\r\n private _logger = Logger.getInstance();\r\n private _updateMs: number;\r\n private _running: boolean = false;\r\n private _currentTime = 0;\r\n constructor(options: ClockOptions & TestClockOptions) {\r\n super({\r\n ...options\r\n });\r\n this._updateMs = options.defaultUpdateMs;\r\n }\r\n\r\n /**\r\n * Get the current time in milliseconds\r\n */\r\n public override now() {\r\n return this._currentTime ?? 0;\r\n }\r\n\r\n public isRunning(): boolean {\r\n return this._running;\r\n }\r\n public start(): void {\r\n this._running = true;\r\n }\r\n public stop(): void {\r\n this._running = false;\r\n }\r\n\r\n /**\r\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\r\n * @param overrideUpdateMs\r\n */\r\n step(overrideUpdateMs?: number): void {\r\n const time = overrideUpdateMs ?? this._updateMs;\r\n\r\n if (this._running) {\r\n // to be comparable to RAF this needs to be a full blown Task\r\n // For example, images cannot decode synchronously in a single step\r\n this.update(time);\r\n this._currentTime += time;\r\n } else {\r\n this._logger.warn('The clock is not running, no step will be performed');\r\n }\r\n }\r\n\r\n /**\r\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\r\n * @param numberOfSteps\r\n * @param overrideUpdateMs\r\n */\r\n run(numberOfSteps: number, overrideUpdateMs?: number): void {\r\n for (let i = 0; i < numberOfSteps; i++) {\r\n this.step(overrideUpdateMs ?? this._updateMs);\r\n }\r\n }\r\n}","import toasterCss from './Toaster.css';\r\n\r\n/**\r\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\r\n */\r\nexport class Toaster {\r\n private _styleBlock: HTMLStyleElement;\r\n private _container: HTMLDivElement;\r\n private _toasterCss: string = toasterCss.toString();\r\n\r\n private _isInitialized = false;\r\n private _initialize() {\r\n if (!this._isInitialized) {\r\n this._container = document.createElement('div');\r\n this._container.id = 'ex-toast-container';\r\n document.body.appendChild(this._container);\r\n this._isInitialized = true;\r\n\r\n this._styleBlock = document.createElement('style');\r\n this._styleBlock.textContent = this._toasterCss;\r\n document.head.appendChild(this._styleBlock);\r\n }\r\n }\r\n\r\n public dispose() {\r\n this._container.parentElement.removeChild(this._container);\r\n\r\n this._styleBlock.parentElement.removeChild(this._styleBlock);\r\n\r\n this._isInitialized = false;\r\n }\r\n\r\n private _createFragment(message: string) {\r\n const toastMessage = document.createElement('span');\r\n toastMessage.innerText = message;\r\n return toastMessage;\r\n }\r\n\r\n /**\r\n * Display a toast message to a player\r\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\r\n * @param linkTarget Optionally specify a link location\r\n * @param linkName Optionally specify a name for that link location\r\n */\r\n public toast(message: string, linkTarget?: string, linkName?: string) {\r\n this._initialize();\r\n const toast = document.createElement('div');\r\n toast.className = 'ex-toast-message';\r\n\r\n const messageFragments: HTMLElement[] = message.split('[LINK]').map(message => this._createFragment(message));\r\n\r\n if (linkTarget) {\r\n const link = document.createElement('a');\r\n link.href = linkTarget;\r\n if (linkName) {\r\n link.innerText = linkName;\r\n } else {\r\n link.innerText = linkTarget;\r\n }\r\n messageFragments.splice(1, 0, link);\r\n }\r\n\r\n // Assembly message\r\n const finalMessage = document.createElement('div');\r\n messageFragments.forEach(message => {\r\n finalMessage.appendChild(message);\r\n });\r\n toast.appendChild(finalMessage);\r\n\r\n // Dismiss button\r\n const dismissBtn = document.createElement('button');\r\n dismissBtn.innerText = 'x';\r\n dismissBtn.addEventListener('click', () => {\r\n this._container.removeChild(toast);\r\n });\r\n toast.appendChild(dismissBtn);\r\n\r\n // Escape to dismiss\r\n const keydownHandler = (evt: KeyboardEvent) => {\r\n if (evt.key === 'Escape') {\r\n try {\r\n this._container.removeChild(toast);\r\n } catch {\r\n // pass\r\n }\r\n }\r\n document.removeEventListener('keydown', keydownHandler);\r\n };\r\n document.addEventListener('keydown', keydownHandler);\r\n\r\n // Insert into container\r\n const first = this._container.firstChild;\r\n this._container.insertBefore(toast, first);\r\n }\r\n}","import { Engine } from '../Engine';\r\nimport { DefaultLoader, LoaderConstructor, isLoaderConstructor } from './DefaultLoader';\r\nimport { Scene, SceneConstructor, isSceneConstructor } from '../Scene';\r\nimport { Transition } from './Transition';\r\nimport { Loader } from './Loader';\r\nimport { Logger } from '../Util/Log';\r\nimport { ActivateEvent, DeactivateEvent } from '../Events';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport interface DirectorNavigationEvent {\r\n sourceName: string;\r\n sourceScene: Scene;\r\n destinationName: string;\r\n destinationScene: Scene;\r\n}\r\n\r\nexport type DirectorEvents = {\r\n navigationstart: DirectorNavigationEvent,\r\n navigation: DirectorNavigationEvent,\r\n navigationend: DirectorNavigationEvent,\r\n}\r\n\r\nexport const DirectorEvents = {\r\n NavigationStart: 'navigationstart',\r\n Navigation: 'navigation',\r\n NavigationEnd: 'navigationend'\r\n};\r\n\r\nexport interface SceneWithOptions {\r\n /**\r\n * Scene associated with this route\r\n *\r\n * If a constructor is provided it will not be constructed until navigation is requested\r\n */\r\n scene: Scene | SceneConstructor;\r\n /**\r\n * Specify scene transitions\r\n */\r\n transitions?: {\r\n /**\r\n * Optionally specify a transition when going \"in\" to this scene\r\n */\r\n in?: Transition;\r\n /**\r\n * Optionally specify a transition when going \"out\" of this scene\r\n */\r\n out?: Transition;\r\n };\r\n /**\r\n * Optionally specify a loader for the scene\r\n */\r\n loader?: DefaultLoader | LoaderConstructor;\r\n}\r\n\r\nexport type WithRoot = TScenes | 'root';\r\n\r\nexport type SceneMap = Record;\r\n\r\nexport interface StartOptions {\r\n /**\r\n * First transition from the game start screen\r\n */\r\n inTransition: Transition;\r\n /**\r\n * Optionally provide a main loader to run before the game starts\r\n */\r\n loader?: DefaultLoader | LoaderConstructor\r\n}\r\n\r\n\r\n/**\r\n * Provide scene activation data and override any existing configured route transitions or loaders\r\n */\r\nexport interface GoToOptions {\r\n /**\r\n * Optionally supply scene activation data passed to Scene.onActivate\r\n */\r\n sceneActivationData?: TActivationData;\r\n /**\r\n * Optionally supply destination scene \"in\" transition, this will override any previously defined transition\r\n */\r\n destinationIn?: Transition;\r\n /**\r\n * Optionally supply source scene \"out\" transition, this will override any previously defined transition\r\n */\r\n sourceOut?: Transition;\r\n /**\r\n * Optionally supply a different loader for the destination scene, this will override any previously defined loader\r\n */\r\n loader?: DefaultLoader;\r\n}\r\n\r\n/**\r\n * The Director is responsible for managing scenes and changing scenes in Excalibur.\r\n *\r\n * It deals with transitions, scene loaders, switching scenes\r\n *\r\n * This is used internally by Excalibur, generally not mean to\r\n * be instantiated end users directly.\r\n */\r\nexport class Director {\r\n public events = new EventEmitter();\r\n private _logger = Logger.getInstance();\r\n private _deferredGoto: string;\r\n private _initialized = false;\r\n\r\n /**\r\n * Current scene's name\r\n */\r\n currentSceneName: string;\r\n /**\r\n * Current scene playing in excalibur\r\n */\r\n currentScene: Scene;\r\n /**\r\n * Current transition if any\r\n */\r\n currentTransition: Transition | null;\r\n\r\n /**\r\n * All registered scenes in Excalibur\r\n */\r\n public readonly scenes: SceneMap> = {} as SceneMap>;\r\n\r\n /**\r\n * Holds all instantiated scenes\r\n */\r\n private _sceneToInstance = new Map();\r\n\r\n startScene: string;\r\n mainLoader: DefaultLoader;\r\n\r\n /**\r\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\r\n */\r\n public readonly rootScene: Scene;\r\n\r\n private _sceneToLoader = new Map();\r\n private _sceneToTransition = new Map();\r\n /**\r\n * Used to keep track of scenes that have already been loaded so we don't load multiple times\r\n */\r\n private _loadedScenes = new Set();\r\n\r\n private _isTransitioning = false;\r\n\r\n /**\r\n * Gets whether the director currently transitioning between scenes\r\n *\r\n * Useful if you need to block behavior during transition\r\n */\r\n public get isTransitioning() {\r\n return this._isTransitioning;\r\n }\r\n\r\n constructor(private _engine: Engine, scenes: SceneMap) {\r\n this.rootScene = this.currentScene = new Scene();\r\n this.add('root', this.rootScene);\r\n this.currentScene = this.rootScene;\r\n this.currentSceneName = 'root';\r\n for (const sceneKey in scenes) {\r\n const sceneOrOptions = scenes[sceneKey];\r\n this.add(sceneKey, sceneOrOptions);\r\n if (sceneKey === 'root') {\r\n this.rootScene = this.getSceneInstance('root');\r\n this.currentScene = this.rootScene;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initialize the director's internal state\r\n */\r\n async onInitialize() {\r\n if (!this._initialized) {\r\n this._initialized = true;\r\n if (this._deferredGoto) {\r\n const deferredScene = this._deferredGoto;\r\n this._deferredGoto = null;\r\n await this.swapScene(deferredScene);\r\n } else {\r\n await this.swapScene('root');\r\n }\r\n }\r\n }\r\n\r\n get isInitialized() {\r\n return this._initialized;\r\n }\r\n\r\n /**\r\n * Configures the start scene, and optionally the transition & loader for the director\r\n *\r\n * Typically this is called at the beginning of the game to the start scene and transition and never again.\r\n * @param startScene\r\n * @param options\r\n */\r\n configureStart(startScene: WithRoot, options?: StartOptions) {\r\n const maybeLoaderOrCtor = options?.loader;\r\n if (maybeLoaderOrCtor instanceof DefaultLoader) {\r\n this.mainLoader = maybeLoaderOrCtor;\r\n } else if (isLoaderConstructor(maybeLoaderOrCtor)) {\r\n this.mainLoader = new maybeLoaderOrCtor();\r\n } else {\r\n this.mainLoader = new Loader();\r\n }\r\n\r\n let maybeStartTransition: Transition;\r\n\r\n if (options) {\r\n const { inTransition } = options;\r\n maybeStartTransition = inTransition;\r\n }\r\n\r\n this.startScene = startScene;\r\n\r\n // Fire and forget promise for the initial scene\r\n if (maybeStartTransition) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.swapScene(this.startScene);\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.playTransition(maybeStartTransition);\r\n } else {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.swapScene(this.startScene);\r\n }\r\n\r\n this.currentSceneName = this.startScene;\r\n }\r\n\r\n private _getLoader(sceneName: string) {\r\n return this._sceneToLoader.get(sceneName);\r\n }\r\n\r\n private _getInTransition(sceneName: string): Transition | undefined {\r\n const sceneOrRoute = this.scenes[sceneName as TKnownScenes];\r\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) {\r\n return null;\r\n }\r\n return sceneOrRoute?.transitions?.in;\r\n }\r\n\r\n private _getOutTransition(sceneName: string): Transition | undefined {\r\n const sceneOrRoute = this.scenes[sceneName as TKnownScenes];\r\n if (sceneOrRoute instanceof Scene || isSceneConstructor(sceneOrRoute)) {\r\n return null;\r\n }\r\n return sceneOrRoute?.transitions?.out;\r\n }\r\n\r\n getDeferredScene() {\r\n const maybeDeferred = this.getSceneDefinition(this._deferredGoto);\r\n if (this._deferredGoto && maybeDeferred) {\r\n return maybeDeferred;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns a scene by name if it exists, might be the constructor and not the instance of a scene\r\n * @param name\r\n */\r\n getSceneDefinition(name: string): Scene | SceneConstructor | undefined {\r\n const maybeScene = this.scenes[name as TKnownScenes];\r\n if (maybeScene instanceof Scene || isSceneConstructor(maybeScene)) {\r\n return maybeScene;\r\n } else if (maybeScene) {\r\n return maybeScene.scene;\r\n }\r\n return undefined;\r\n }\r\n\r\n getSceneName(scene: Scene) {\r\n for (const [name, sceneInstance] of this._sceneToInstance) {\r\n if (scene === sceneInstance) {\r\n return name;\r\n }\r\n }\r\n return 'unknown scene name';\r\n }\r\n\r\n /**\r\n * Returns the same Director, but asserts a scene DOES exist to the type system\r\n * @param name\r\n */\r\n assertAdded(name: TScene): Director {\r\n return this as Director;\r\n }\r\n\r\n /**\r\n * Returns the same Director, but asserts a scene DOES NOT exist to the type system\r\n * @param name\r\n */\r\n assertRemoved(name: TScene): Director> {\r\n return this as Director>;\r\n }\r\n\r\n /**\r\n * Adds additional Scenes to the game!\r\n * @param name\r\n * @param sceneOrRoute\r\n */\r\n add(name: TScene, sceneOrRoute: Scene | SceneConstructor | SceneWithOptions): Director {\r\n if (!(sceneOrRoute instanceof Scene) && !(isSceneConstructor(sceneOrRoute))) {\r\n const { loader, transitions } = sceneOrRoute;\r\n const {in: inTransition, out: outTransition } = transitions ?? {};\r\n this._sceneToTransition.set(name, {in: inTransition, out: outTransition});\r\n\r\n if (isLoaderConstructor(loader)) {\r\n this._sceneToLoader.set(name, new loader());\r\n } else {\r\n this._sceneToLoader.set(name, loader);\r\n }\r\n }\r\n\r\n if (this.scenes[name as unknown as TKnownScenes]) {\r\n this._logger.warn('Scene', name, 'already exists overwriting');\r\n }\r\n this.scenes[name as unknown as TKnownScenes] = sceneOrRoute;\r\n return this.assertAdded(name);\r\n }\r\n\r\n remove(scene: Scene): void;\r\n remove(sceneCtor: SceneConstructor): void;\r\n remove(name: WithRoot): void;\r\n remove(nameOrScene: TKnownScenes | Scene | SceneConstructor | string) {\r\n\r\n if (nameOrScene instanceof Scene || isSceneConstructor(nameOrScene)) {\r\n const sceneOrCtor = nameOrScene;\r\n // remove scene\r\n for (const key in this.scenes) {\r\n if (this.scenes.hasOwnProperty(key)) {\r\n const potentialSceneOrOptions = this.scenes[key as TKnownScenes];\r\n let scene: Scene | SceneConstructor;\r\n if (potentialSceneOrOptions instanceof Scene || isSceneConstructor(potentialSceneOrOptions)) {\r\n scene = potentialSceneOrOptions;\r\n } else {\r\n scene = potentialSceneOrOptions.scene;\r\n }\r\n\r\n if (scene === sceneOrCtor) {\r\n if (key === this.currentSceneName) {\r\n throw new Error(`Cannot remove a currently active scene: ${key}`);\r\n }\r\n\r\n this._sceneToTransition.delete(key);\r\n this._sceneToLoader.delete(key);\r\n delete this.scenes[key as TKnownScenes];\r\n }\r\n }\r\n }\r\n }\r\n if (typeof nameOrScene === 'string') {\r\n if (nameOrScene === this.currentSceneName) {\r\n throw new Error(`Cannot remove a currently active scene: ${nameOrScene}`);\r\n }\r\n\r\n // remove scene\r\n this._sceneToTransition.delete(nameOrScene);\r\n this._sceneToLoader.delete(nameOrScene);\r\n delete this.scenes[nameOrScene as TKnownScenes];\r\n }\r\n }\r\n\r\n /**\r\n * Go to a specific scene, and optionally override loaders and transitions\r\n * @param destinationScene\r\n * @param options\r\n */\r\n async goto(destinationScene: TKnownScenes | string, options?: GoToOptions) {\r\n\r\n const maybeDest = this.getSceneInstance(destinationScene);\r\n if (!maybeDest) {\r\n this._logger.warn(`Scene ${destinationScene} does not exist! Check the name, are you sure you added it?`);\r\n return;\r\n }\r\n\r\n const sourceScene = this.currentSceneName;\r\n const engineInputEnabled = this._engine.input?.enabled ?? true;\r\n this._isTransitioning = true;\r\n\r\n const maybeSourceOut = this.getSceneInstance(sourceScene)?.onTransition('out');\r\n const maybeDestinationIn = maybeDest?.onTransition('in');\r\n\r\n options = {\r\n // Engine configuration then dynamic scene transitions\r\n ...{ sourceOut: this._getOutTransition(this.currentSceneName) ?? maybeSourceOut},\r\n ...{ destinationIn: this._getInTransition(destinationScene) ?? maybeDestinationIn},\r\n // Goto options\r\n ...options };\r\n\r\n const { sourceOut, destinationIn, sceneActivationData } = options;\r\n\r\n const outTransition = sourceOut ?? this._getOutTransition(this.currentSceneName);\r\n const inTransition = destinationIn ?? this._getInTransition(destinationScene);\r\n\r\n const hideLoader = outTransition?.hideLoader || inTransition?.hideLoader;\r\n if (hideLoader) {\r\n // Start hidden loader early and take advantage of the transition\r\n // Don't await and block on a hidden loader\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.maybeLoadScene(destinationScene, hideLoader);\r\n }\r\n\r\n this._emitEvent('navigationstart', sourceScene, destinationScene);\r\n\r\n // Run the out transition on the current scene if present\r\n await this.playTransition(outTransition);\r\n\r\n // Run the loader if present\r\n await this.maybeLoadScene(destinationScene, hideLoader);\r\n\r\n // Give incoming transition a chance to grab info from previous\r\n await inTransition?.onPreviousSceneDeactivate(this.currentScene);\r\n\r\n // Swap to the new scene\r\n await this.swapScene(destinationScene, sceneActivationData);\r\n this._emitEvent('navigation', sourceScene, destinationScene);\r\n\r\n // Run the in transition on the new scene if present\r\n await this.playTransition(inTransition);\r\n this._emitEvent('navigationend', sourceScene, destinationScene);\r\n\r\n this._engine.input?.toggleEnabled(engineInputEnabled);\r\n this._isTransitioning = false;\r\n }\r\n\r\n /**\r\n * Retrieves a scene instance by key if it's registered.\r\n *\r\n * This will call any constructors that were given as a definition\r\n * @param scene\r\n */\r\n getSceneInstance(scene: string): Scene | undefined {\r\n const sceneDefinition = this.getSceneDefinition(scene);\r\n if (!sceneDefinition) {\r\n return undefined;\r\n }\r\n if (this._sceneToInstance.has(scene)) {\r\n return this._sceneToInstance.get(scene) as Scene;\r\n }\r\n if (sceneDefinition instanceof Scene) {\r\n this._sceneToInstance.set(scene, sceneDefinition);\r\n return sceneDefinition;\r\n }\r\n const newScene = new sceneDefinition();\r\n this._sceneToInstance.set(scene, newScene);\r\n return newScene;\r\n }\r\n\r\n /**\r\n * Triggers scene loading if has not already been loaded\r\n * @param scene\r\n * @param hideLoader\r\n */\r\n async maybeLoadScene(scene: string, hideLoader = false) {\r\n const loader = this._getLoader(scene) ?? new DefaultLoader();\r\n const sceneToLoad = this.getSceneDefinition(scene);\r\n const sceneToLoadInstance = this.getSceneInstance(scene);\r\n if (sceneToLoad && sceneToLoadInstance && !this._loadedScenes.has(sceneToLoadInstance)) {\r\n sceneToLoadInstance.onPreLoad(loader);\r\n sceneToLoadInstance.events.emit('preload', { loader });\r\n if (hideLoader) {\r\n // Don't await a hidden loader\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this._engine.load(loader, hideLoader);\r\n } else {\r\n await this._engine.load(loader);\r\n }\r\n this._loadedScenes.add(sceneToLoadInstance);\r\n }\r\n }\r\n\r\n /**\r\n * Plays a transition in the current scene\r\n * @param transition\r\n */\r\n async playTransition(transition: Transition) {\r\n if (transition) {\r\n this.currentTransition = transition;\r\n const currentScene = this._engine.currentScene;\r\n const sceneInputEnabled = currentScene.input?.enabled ?? true;\r\n\r\n currentScene.input?.toggleEnabled(!transition.blockInput);\r\n this._engine.input?.toggleEnabled(!transition.blockInput);\r\n\r\n await this.currentTransition.play(this._engine);\r\n\r\n currentScene.input?.toggleEnabled(sceneInputEnabled);\r\n }\r\n this.currentTransition?.kill();\r\n this.currentTransition?.reset();\r\n this.currentTransition = null;\r\n }\r\n\r\n /**\r\n * Swaps the current and destination scene after performing required lifecycle events\r\n * @param destinationScene\r\n * @param data\r\n */\r\n async swapScene(destinationScene: string, data?: TData): Promise {\r\n const engine = this._engine;\r\n // if not yet initialized defer goToScene\r\n if (!this.isInitialized) {\r\n this._deferredGoto = destinationScene;\r\n return;\r\n }\r\n\r\n const maybeDest = this.getSceneInstance(destinationScene);\r\n\r\n if (maybeDest) {\r\n const previousScene = this.currentScene;\r\n const nextScene = maybeDest;\r\n\r\n this._logger.debug('Going to scene:', destinationScene);\r\n // only deactivate when initialized\r\n if (this.currentScene.isInitialized) {\r\n const context = { engine, previousScene, nextScene };\r\n await this.currentScene._deactivate(context);\r\n this.currentScene.events.emit('deactivate', new DeactivateEvent(context, this.currentScene));\r\n }\r\n\r\n // wait for the scene to be loaded if needed\r\n const destLoader = this._sceneToLoader.get(destinationScene);\r\n await destLoader?.areResourcesLoaded();\r\n\r\n // set current scene to new one\r\n this.currentScene = nextScene;\r\n this.currentSceneName = destinationScene;\r\n engine.screen.setCurrentCamera(nextScene.camera);\r\n\r\n // initialize the current scene if has not been already\r\n await this.currentScene._initialize(engine);\r\n\r\n const context = { engine, previousScene, nextScene, data };\r\n await this.currentScene._activate(context);\r\n this.currentScene.events.emit('activate', new ActivateEvent(context, this.currentScene));\r\n } else {\r\n this._logger.error('Scene', destinationScene, 'does not exist!');\r\n }\r\n }\r\n\r\n private _emitEvent(eventName: keyof DirectorEvents, sourceScene: string, destinationScene: string) {\r\n const source = this.getSceneDefinition(sourceScene)!;\r\n const dest = this.getSceneDefinition(destinationScene)!;\r\n this.events.emit(eventName, {\r\n sourceScene: source,\r\n sourceName: sourceScene,\r\n destinationScene: dest,\r\n destinationName: destinationScene\r\n } as DirectorNavigationEvent);\r\n }\r\n}\r\n\r\n\r\n","import { EX_VERSION } from './';\r\nimport { Future } from './Util/Future';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { PointerScope } from './Input/PointerScope';\r\nimport { Flags } from './Flags';\r\nimport { polyfill } from './Polyfill';\r\npolyfill();\r\nimport { CanUpdate, CanDraw, CanInitialize } from './Interfaces/LifecycleEvents';\r\nimport { Vector } from './Math/vector';\r\nimport { Screen, DisplayMode, ScreenDimension, Resolution } from './Screen';\r\nimport { ScreenElement } from './ScreenElement';\r\nimport { Actor } from './Actor';\r\nimport { Timer } from './Timer';\r\nimport { TileMap } from './TileMap';\r\nimport { DefaultLoader } from './Director/DefaultLoader';\r\nimport { Loader } from './Director/Loader';\r\nimport { Detector } from './Util/Detector';\r\nimport {\r\n VisibleEvent,\r\n HiddenEvent,\r\n GameStartEvent,\r\n GameStopEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PreFrameEvent,\r\n PostFrameEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n InitializeEvent\r\n} from './Events';\r\nimport { Logger, LogLevel } from './Util/Log';\r\nimport { Color } from './Color';\r\nimport { Scene, SceneConstructor, isSceneConstructor } from './Scene';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { DebugConfig, DebugStats } from './Debug/DebugConfig';\r\nimport { BrowserEvents } from './Util/Browser';\r\nimport {\r\n AntialiasOptions,\r\n DefaultAntialiasOptions,\r\n DefaultPixelArtOptions,\r\n ExcaliburGraphicsContext,\r\n ExcaliburGraphicsContext2DCanvas,\r\n ExcaliburGraphicsContextWebGL,\r\n TextureLoader\r\n} from './Graphics';\r\nimport { Clock, StandardClock } from './Util/Clock';\r\nimport { ImageFiltering } from './Graphics/Filtering';\r\nimport { GraphicsDiagnostics } from './Graphics/GraphicsDiagnostics';\r\nimport { Toaster } from './Util/Toaster';\r\nimport { InputMapper } from './Input/InputMapper';\r\nimport { GoToOptions, SceneMap, Director, StartOptions, SceneWithOptions, WithRoot } from './Director/Director';\r\nimport { InputHost } from './Input/InputHost';\r\nimport { DefaultPhysicsConfig, DeprecatedStaticToConfig, PhysicsConfig } from './Collision/PhysicsConfig';\r\nimport { DeepRequired } from './Util/Required';\r\n\r\nexport type EngineEvents = {\r\n fallbackgraphicscontext: ExcaliburGraphicsContext2DCanvas,\r\n initialize: InitializeEvent,\r\n visible: VisibleEvent,\r\n hidden: HiddenEvent,\r\n start: GameStartEvent,\r\n stop: GameStopEvent,\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n preframe: PreFrameEvent,\r\n postframe: PostFrameEvent,\r\n predraw: PreDrawEvent,\r\n postdraw: PostDrawEvent,\r\n}\r\n\r\nexport const EngineEvents = {\r\n FallbackGraphicsContext: 'fallbackgraphicscontext',\r\n Initialize: 'initialize',\r\n Visible: 'visible',\r\n Hidden: 'hidden',\r\n Start: 'start',\r\n Stop: 'stop',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreFrame: 'preframe',\r\n PostFrame: 'postframe',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw'\r\n} as const;\r\n\r\n\r\n\r\n/**\r\n * Enum representing the different mousewheel event bubble prevention\r\n */\r\nexport enum ScrollPreventionMode {\r\n /**\r\n * Do not prevent any page scrolling\r\n */\r\n None,\r\n /**\r\n * Prevent page scroll if mouse is over the game canvas\r\n */\r\n Canvas,\r\n /**\r\n * Prevent all page scrolling via mouse wheel\r\n */\r\n All\r\n}\r\n\r\n/**\r\n * Defines the available options to configure the Excalibur engine at constructor time.\r\n */\r\nexport interface EngineOptions {\r\n /**\r\n * Optionally configure the width of the viewport in css pixels\r\n */\r\n width?: number;\r\n\r\n /**\r\n * Optionally configure the height of the viewport in css pixels\r\n */\r\n height?: number;\r\n\r\n /**\r\n * Optionally configure the width & height of the viewport in css pixels.\r\n * Use `viewport` instead of [[EngineOptions.width]] and [[EngineOptions.height]], or vice versa.\r\n */\r\n viewport?: ScreenDimension;\r\n\r\n /**\r\n * Optionally specify the size the logical pixel resolution, if not specified it will be width x height.\r\n * See [[Resolution]] for common presets.\r\n */\r\n resolution?: ScreenDimension;\r\n\r\n /**\r\n * Optionally specify antialiasing (smoothing), by default true (smooth pixels)\r\n *\r\n * * `true` - useful for high resolution art work you would like smoothed, this also hints excalibur to load images\r\n * with default blending [[ImageFiltering.Blended]]\r\n *\r\n * * `false` - useful for pixel art style art work you would like sharp, this also hints excalibur to load images\r\n * with default blending [[ImageFiltering.Pixel]]\r\n *\r\n * * [[AntialiasOptions]] Optionally deeply configure the different antialiasing settings, **WARNING** thar be dragons here.\r\n * It is recommended you stick to `true` or `false` unless you understand what you're doing and need to control rendering to\r\n * a high degree.\r\n */\r\n antialiasing?: boolean | AntialiasOptions\r\n\r\n /**\r\n * Quick convenience property to configure Excalibur to use special settings for \"pretty\" anti-aliased pixel art\r\n *\r\n * 1. Turns on special shader condition to blend for pixel art and enables various antialiasing settings,\r\n * notice blending is ON for this special mode.\r\n *\r\n * Equivalent to:\r\n * ```javascript\r\n * antialiasing: {\r\n * pixelArtSampler: true,\r\n * canvasImageRendering: 'auto',\r\n * filtering: ImageFiltering.Blended,\r\n * webglAntialiasing: true\r\n * }\r\n * ```\r\n */\r\n pixelArt?: boolean;\r\n\r\n /**\r\n * Specify any UV padding you want use in pixels, this brings sampling into the texture if you're using\r\n * a sprite sheet in one image to prevent sampling bleed.\r\n *\r\n * Defaults:\r\n * * `antialiasing: false` or `filtering: ImageFiltering.Pixel` - 0.0;\r\n * * `pixelArt: true` - 0.25\r\n * * All else 0.01\r\n */\r\n uvPadding?: number;\r\n\r\n /**\r\n * Optionally hint the graphics context into a specific power profile\r\n *\r\n * Default \"high-performance\"\r\n */\r\n powerPreference?: 'default' | 'high-performance' | 'low-power';\r\n\r\n /**\r\n * Optionally upscale the number of pixels in the canvas. Normally only useful if you need a smoother look to your assets, especially\r\n * [[Text]] or Pixel Art assets.\r\n *\r\n * **WARNING** It is recommended you try using `antialiasing: true` before adjusting pixel ratio. Pixel ratio will consume more memory\r\n * and on mobile may break if the internal size of the canvas exceeds 4k pixels in width or height.\r\n *\r\n * Default is based the display's pixel ratio, for example a HiDPI screen might have the value 2;\r\n */\r\n pixelRatio?: number;\r\n\r\n /**\r\n * Optionally configure the native canvas transparent backdrop\r\n */\r\n enableCanvasTransparency?: boolean;\r\n\r\n /**\r\n * Optionally specify the target canvas DOM element to render the game in\r\n */\r\n canvasElementId?: string;\r\n\r\n /**\r\n * Optionally specify the target canvas DOM element directly\r\n */\r\n canvasElement?: HTMLCanvasElement;\r\n\r\n /**\r\n * Optionally snap graphics to nearest pixel, default is false\r\n */\r\n snapToPixel?: boolean;\r\n\r\n /**\r\n * The [[DisplayMode]] of the game, by default [[DisplayMode.FitScreen]] with aspect ratio 4:3 (800x600).\r\n * Depending on this value, [[width]] and [[height]] may be ignored.\r\n */\r\n displayMode?: DisplayMode;\r\n\r\n /**\r\n * Configures the pointer scope. Pointers scoped to the 'Canvas' can only fire events within the canvas viewport; whereas, 'Document'\r\n * (default) scoped will fire anywhere on the page.\r\n */\r\n pointerScope?: PointerScope;\r\n\r\n /**\r\n * Suppress boot up console message, which contains the \"powered by Excalibur message\"\r\n */\r\n suppressConsoleBootMessage?: boolean;\r\n\r\n /**\r\n * Suppress minimum browser feature detection, it is not recommended users of excalibur switch this off. This feature ensures that\r\n * the currently running browser meets the minimum requirements for running excalibur. This can be useful if running on non-standard\r\n * browsers or if there is a bug in excalibur preventing execution.\r\n */\r\n suppressMinimumBrowserFeatureDetection?: boolean;\r\n\r\n /**\r\n * Suppress HiDPI auto detection and scaling, it is not recommended users of excalibur switch off this feature. This feature detects\r\n * and scales the drawing canvas appropriately to accommodate HiDPI screens.\r\n */\r\n suppressHiDPIScaling?: boolean;\r\n\r\n /**\r\n * Suppress play button, it is not recommended users of excalibur switch this feature. Some browsers require a user gesture (like a click)\r\n * for certain browser features to work like web audio.\r\n */\r\n suppressPlayButton?: boolean;\r\n\r\n /**\r\n * Sets the focus of the window, this is needed when hosting excalibur in a cross-origin iframe in order for certain events\r\n * (like keyboard) to work.\r\n * For example: itch.io or codesandbox.io\r\n *\r\n * By default set to true,\r\n */\r\n grabWindowFocus?: boolean;\r\n\r\n /**\r\n * Scroll prevention method.\r\n */\r\n scrollPreventionMode?: ScrollPreventionMode;\r\n\r\n /**\r\n * Optionally set the background color\r\n */\r\n backgroundColor?: Color;\r\n\r\n /**\r\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\r\n *\r\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\r\n * one that bounces between 30fps and 60fps\r\n */\r\n maxFps?: number;\r\n\r\n /**\r\n * Optionally configure a fixed update fps, this can be desireable if you need the physics simulation to be very stable. When set\r\n * the update step and physics will use the same elapsed time for each tick even if the graphical framerate drops. In order for the\r\n * simulation to be correct, excalibur will run multiple updates in a row (at the configured update elapsed) to catch up, for example\r\n * there could be X updates and 1 draw each clock step.\r\n *\r\n * **NOTE:** This does come at a potential perf cost because each catch-up update will need to be run if the fixed rate is greater than\r\n * the current instantaneous framerate, or perf gain if the fixed rate is less than the current framerate.\r\n *\r\n * By default is unset and updates will use the current instantaneous framerate with 1 update and 1 draw each clock step.\r\n */\r\n fixedUpdateFps?: number\r\n\r\n /**\r\n * Default `true`, optionally configure excalibur to use optimal draw call sorting, to opt out set this to `false`.\r\n *\r\n * Excalibur will automatically sort draw calls by z and priority into renderer batches for maximal draw performance,\r\n * this can disrupt a specific desired painter order.\r\n */\r\n useDrawSorting?: boolean;\r\n\r\n /**\r\n * Optionally configure how excalibur handles poor performance on a player's browser\r\n */\r\n configurePerformanceCanvas2DFallback?: {\r\n /**\r\n * By default `false`, this will switch the internal graphics context to Canvas2D which can improve performance on non hardware\r\n * accelerated browsers.\r\n */\r\n allow: boolean;\r\n /**\r\n * By default `false`, if set to `true` a dialogue will be presented to the player about their browser and how to potentially\r\n * address any issues.\r\n */\r\n showPlayerMessage?: boolean;\r\n /**\r\n * Default `{ numberOfFrames: 100, fps: 20 }`, optionally configure excalibur to fallback to the 2D Canvas renderer\r\n * if bad performance is detected.\r\n *\r\n * In this example of the default if excalibur is running at 20fps or less for 100 frames it will trigger the fallback to the 2D\r\n * Canvas renderer.\r\n */\r\n threshold?: { numberOfFrames: number, fps: number };\r\n },\r\n\r\n /**\r\n * Optionally configure the physics simulation in excalibur\r\n *\r\n * If false, Excalibur will not produce a physics simulation.\r\n *\r\n * Default is configured to use [[SolverStrategy.Arcade]] physics simulation\r\n */\r\n physics?: boolean | PhysicsConfig\r\n\r\n /**\r\n * Optionally specify scenes with their transitions and loaders to excalibur's scene [[Director]]\r\n *\r\n * Scene transitions can can overridden dynamically by the `Scene` or by the call to `.goToScene`\r\n */\r\n scenes?: SceneMap\r\n}\r\n\r\n/**\r\n * The Excalibur Engine\r\n *\r\n * The [[Engine]] is the main driver for a game. It is responsible for\r\n * starting/stopping the game, maintaining state, transmitting events,\r\n * loading resources, and managing the scene.\r\n */\r\nexport class Engine implements CanInitialize, CanUpdate, CanDraw {\r\n /**\r\n * Current Excalibur version string\r\n *\r\n * Useful for plugins or other tools that need to know what features are available\r\n */\r\n public readonly version = EX_VERSION;\r\n\r\n /**\r\n * Listen to and emit events on the Engine\r\n */\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Excalibur browser events abstraction used for wiring to native browser events safely\r\n */\r\n public browser: BrowserEvents;\r\n\r\n /**\r\n * Screen abstraction\r\n */\r\n public screen: Screen;\r\n\r\n /**\r\n * Scene director, manages all scenes, scene transitions, and loaders in excalibur\r\n */\r\n public director: Director;\r\n\r\n /**\r\n * Direct access to the engine's canvas element\r\n */\r\n public canvas: HTMLCanvasElement;\r\n\r\n /**\r\n * Direct access to the ExcaliburGraphicsContext used for drawing things to the screen\r\n */\r\n public graphicsContext: ExcaliburGraphicsContext;\r\n\r\n /**\r\n * Direct access to the canvas element ID, if an ID exists\r\n */\r\n public canvasElementId: string;\r\n\r\n /**\r\n * Direct access to the physics configuration for excalibur\r\n */\r\n public physics: DeepRequired;\r\n\r\n /**\r\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\r\n *\r\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\r\n * one that bounces between 30fps and 60fps\r\n */\r\n public maxFps: number = Number.POSITIVE_INFINITY;\r\n\r\n /**\r\n * Optionally configure a fixed update fps, this can be desireable if you need the physics simulation to be very stable. When set\r\n * the update step and physics will use the same elapsed time for each tick even if the graphical framerate drops. In order for the\r\n * simulation to be correct, excalibur will run multiple updates in a row (at the configured update elapsed) to catch up, for example\r\n * there could be X updates and 1 draw each clock step.\r\n *\r\n * **NOTE:** This does come at a potential perf cost because each catch-up update will need to be run if the fixed rate is greater than\r\n * the current instantaneous framerate, or perf gain if the fixed rate is less than the current framerate.\r\n *\r\n * By default is unset and updates will use the current instantaneous framerate with 1 update and 1 draw each clock step.\r\n */\r\n public fixedUpdateFps?: number;\r\n\r\n /**\r\n * Direct access to the excalibur clock\r\n */\r\n public clock: Clock;\r\n\r\n public readonly pointerScope: PointerScope;\r\n public readonly grabWindowFocus: boolean;\r\n\r\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */\r\n public get canvasWidth(): number {\r\n return this.screen.canvasWidth;\r\n }\r\n\r\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */\r\n public get halfCanvasWidth(): number {\r\n return this.screen.halfCanvasWidth;\r\n }\r\n\r\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */\r\n public get canvasHeight(): number {\r\n return this.screen.canvasHeight;\r\n }\r\n\r\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */\r\n public get halfCanvasHeight(): number {\r\n return this.screen.halfCanvasHeight;\r\n }\r\n\r\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawWidth(): number {\r\n return this.screen.drawWidth;\r\n }\r\n\r\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawWidth(): number {\r\n return this.screen.halfDrawWidth;\r\n }\r\n\r\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawHeight(): number {\r\n return this.screen.drawHeight;\r\n }\r\n\r\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawHeight(): number {\r\n return this.screen.halfDrawHeight;\r\n }\r\n\r\n /**\r\n * Returns whether excalibur detects the current screen to be HiDPI\r\n */\r\n public get isHiDpi(): boolean {\r\n return this.screen.isHiDpi;\r\n }\r\n\r\n /**\r\n * Access engine input like pointer, keyboard, or gamepad\r\n */\r\n public input: InputHost;\r\n\r\n /**\r\n * Map multiple input sources to specific game actions actions\r\n */\r\n public inputMapper: InputMapper;\r\n\r\n private _inputEnabled: boolean = true;\r\n\r\n /**\r\n * Access Excalibur debugging functionality.\r\n *\r\n * Useful when you want to debug different aspects of built in engine features like\r\n * * Transform\r\n * * Graphics\r\n * * Colliders\r\n */\r\n public debug: DebugConfig;\r\n\r\n /**\r\n * Access [[stats]] that holds frame statistics.\r\n */\r\n public get stats(): DebugStats {\r\n return this.debug.stats;\r\n }\r\n\r\n /**\r\n * The current [[Scene]] being drawn and updated on screen\r\n */\r\n public get currentScene(): Scene {\r\n return this.director.currentScene;\r\n }\r\n\r\n\r\n /**\r\n * The current [[Scene]] being drawn and updated on screen\r\n */\r\n public get currentSceneName(): string {\r\n return this.director.currentSceneName;\r\n }\r\n\r\n /**\r\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\r\n */\r\n public get rootScene(): Scene {\r\n return this.director.rootScene;\r\n }\r\n\r\n /**\r\n * Contains all the scenes currently registered with Excalibur\r\n */\r\n public get scenes(): { [key: string]: Scene | SceneConstructor | SceneWithOptions } {\r\n return this.director.scenes;\r\n };\r\n\r\n /**\r\n * Indicates whether the engine is set to fullscreen or not\r\n */\r\n public get isFullscreen(): boolean {\r\n return this.screen.isFullScreen;\r\n }\r\n\r\n /**\r\n * Indicates the current [[DisplayMode]] of the engine.\r\n */\r\n public get displayMode(): DisplayMode {\r\n return this.screen.displayMode;\r\n }\r\n\r\n private _suppressPlayButton: boolean = false;\r\n /**\r\n * Returns the calculated pixel ration for use in rendering\r\n */\r\n public get pixelRatio(): number {\r\n return this.screen.pixelRatio;\r\n }\r\n\r\n /**\r\n * Indicates whether audio should be paused when the game is no longer visible.\r\n */\r\n public pauseAudioWhenHidden: boolean = true;\r\n\r\n /**\r\n * Indicates whether the engine should draw with debug information\r\n */\r\n private _isDebug: boolean = false;\r\n public get isDebug(): boolean {\r\n return this._isDebug;\r\n }\r\n\r\n /**\r\n * Sets the background color for the engine.\r\n */\r\n public backgroundColor: Color;\r\n\r\n /**\r\n * Sets the Transparency for the engine.\r\n */\r\n public enableCanvasTransparency: boolean = true;\r\n\r\n /**\r\n * Hints the graphics context to truncate fractional world space coordinates\r\n */\r\n public get snapToPixel(): boolean {\r\n return this.graphicsContext.snapToPixel;\r\n };\r\n\r\n public set snapToPixel(shouldSnapToPixel: boolean) {\r\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\r\n };\r\n\r\n /**\r\n * The action to take when a fatal exception is thrown\r\n */\r\n public onFatalException = (e: any) => {\r\n Logger.getInstance().fatal(e, e.stack);\r\n };\r\n\r\n /**\r\n * The mouse wheel scroll prevention mode\r\n */\r\n public pageScrollPreventionMode: ScrollPreventionMode;\r\n\r\n private _logger: Logger;\r\n\r\n private _toaster: Toaster = new Toaster();\r\n\r\n // this determines whether excalibur is compatible with your browser\r\n private _compatible: boolean;\r\n\r\n private _timescale: number = 1.0;\r\n\r\n // loading\r\n private _loader: DefaultLoader;\r\n\r\n private _isInitialized: boolean = false;\r\n\r\n public emit>(eventName: TEventName, event: EngineEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Default [[EngineOptions]]\r\n */\r\n private static _DEFAULT_ENGINE_OPTIONS: EngineOptions = {\r\n width: 0,\r\n height: 0,\r\n enableCanvasTransparency: true,\r\n useDrawSorting: true,\r\n configurePerformanceCanvas2DFallback: {\r\n allow: false,\r\n showPlayerMessage: false,\r\n threshold: { fps: 20, numberOfFrames: 100 }\r\n },\r\n canvasElementId: '',\r\n canvasElement: undefined,\r\n snapToPixel: false,\r\n antialiasing: true,\r\n pixelArt: false,\r\n powerPreference: 'high-performance',\r\n pointerScope: PointerScope.Canvas,\r\n suppressConsoleBootMessage: null,\r\n suppressMinimumBrowserFeatureDetection: null,\r\n suppressHiDPIScaling: null,\r\n suppressPlayButton: null,\r\n grabWindowFocus: true,\r\n scrollPreventionMode: ScrollPreventionMode.Canvas,\r\n backgroundColor: Color.fromHex('#2185d0') // Excalibur blue\r\n };\r\n\r\n private _originalOptions: EngineOptions = {};\r\n public readonly _originalDisplayMode: DisplayMode;\r\n\r\n /**\r\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\r\n * the game will be rendered full screen (taking up all available browser window space).\r\n * You can customize the game rendering through [[EngineOptions]].\r\n *\r\n * Example:\r\n *\r\n * ```js\r\n * var game = new ex.Engine({\r\n * width: 0, // the width of the canvas\r\n * height: 0, // the height of the canvas\r\n * enableCanvasTransparency: true, // the transparencySection of the canvas\r\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\r\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\r\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\r\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\r\n * });\r\n *\r\n * // call game.start, which is a Promise\r\n * game.start().then(function () {\r\n * // ready, set, go!\r\n * });\r\n * ```\r\n */\r\n constructor(options?: EngineOptions) {\r\n options = { ...Engine._DEFAULT_ENGINE_OPTIONS, ...options };\r\n this._originalOptions = options;\r\n\r\n Flags.freeze();\r\n\r\n // Initialize browser events facade\r\n this.browser = new BrowserEvents(window, document);\r\n\r\n // Check compatibility\r\n const detector = new Detector();\r\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\r\n const message = document.createElement('div');\r\n message.innerText = 'Sorry, your browser does not support all the features needed for Excalibur';\r\n document.body.appendChild(message);\r\n\r\n detector.failedTests.forEach(function (test) {\r\n const testMessage = document.createElement('div');\r\n testMessage.innerText = 'Browser feature missing ' + test;\r\n document.body.appendChild(testMessage);\r\n });\r\n\r\n if (options.canvasElementId) {\r\n const canvas = document.getElementById(options.canvasElementId);\r\n if (canvas) {\r\n canvas.parentElement.removeChild(canvas);\r\n }\r\n }\r\n\r\n return;\r\n } else {\r\n this._compatible = true;\r\n }\r\n\r\n // Use native console API for color fun\r\n // eslint-disable-next-line no-console\r\n if (console.log && !options.suppressConsoleBootMessage) {\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `%cPowered by Excalibur.js (v${EX_VERSION})`,\r\n 'background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;'\r\n );\r\n // eslint-disable-next-line no-console\r\n console.log('\\n\\\r\n /| ________________\\n\\\r\nO|===|* >________________>\\n\\\r\n \\\\|');\r\n // eslint-disable-next-line no-console\r\n console.log('Visit', 'http://excaliburjs.com', 'for more information');\r\n }\r\n\r\n // Suppress play button\r\n if (options.suppressPlayButton) {\r\n this._suppressPlayButton = true;\r\n }\r\n\r\n this._logger = Logger.getInstance();\r\n\r\n // If debug is enabled, let's log browser features to the console.\r\n if (this._logger.defaultLevel === LogLevel.Debug) {\r\n detector.logBrowserFeatures();\r\n }\r\n\r\n this._logger.debug('Building engine...');\r\n\r\n this.canvasElementId = options.canvasElementId;\r\n\r\n if (options.canvasElementId) {\r\n this._logger.debug('Using Canvas element specified: ' + options.canvasElementId);\r\n\r\n //test for existence of element\r\n if (document.getElementById(options.canvasElementId) === null) {\r\n throw new Error('Cannot find existing element in the DOM, please ensure element is created prior to engine creation.');\r\n }\r\n\r\n this.canvas = document.getElementById(options.canvasElementId);\r\n } else if (options.canvasElement) {\r\n this._logger.debug('Using Canvas element specified:', options.canvasElement);\r\n this.canvas = options.canvasElement;\r\n } else {\r\n this._logger.debug('Using generated canvas element');\r\n this.canvas = document.createElement('canvas');\r\n }\r\n\r\n let displayMode = options.displayMode ?? DisplayMode.Fixed;\r\n if ((options.width && options.height) || options.viewport) {\r\n if (options.displayMode === undefined) {\r\n displayMode = DisplayMode.Fixed;\r\n }\r\n this._logger.debug('Engine viewport is size ' + options.width + ' x ' + options.height);\r\n } else if (!options.displayMode) {\r\n this._logger.debug('Engine viewport is fit');\r\n displayMode = DisplayMode.FitScreen;\r\n }\r\n\r\n this._originalDisplayMode = displayMode;\r\n\r\n let pixelArtSampler: boolean;\r\n let uvPadding: number;\r\n let nativeContextAntialiasing: boolean;\r\n let canvasImageRendering: 'pixelated' | 'auto';\r\n let filtering: ImageFiltering;\r\n let multiSampleAntialiasing: boolean | { samples: number };\r\n if (typeof options.antialiasing === 'object') {\r\n ({\r\n pixelArtSampler,\r\n nativeContextAntialiasing,\r\n multiSampleAntialiasing,\r\n filtering,\r\n canvasImageRendering\r\n } = {\r\n ...(options.pixelArt ? DefaultPixelArtOptions : DefaultAntialiasOptions),\r\n ...options.antialiasing\r\n });\r\n\r\n } else {\r\n pixelArtSampler = !!options.pixelArt;\r\n nativeContextAntialiasing = false;\r\n multiSampleAntialiasing = options.antialiasing;\r\n canvasImageRendering = options.antialiasing ? 'auto' : 'pixelated';\r\n filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\r\n }\r\n\r\n if (nativeContextAntialiasing && multiSampleAntialiasing) {\r\n this._logger.warnOnce(`Cannot use antialias setting nativeContextAntialiasing and multiSampleAntialiasing` +\r\n ` at the same time, they are incompatible settings. If you aren\\'t sure use multiSampleAntialiasing`);\r\n }\r\n\r\n if (options.pixelArt) {\r\n uvPadding = .25;\r\n }\r\n\r\n if (!options.antialiasing || filtering === ImageFiltering.Pixel) {\r\n uvPadding = 0;\r\n }\r\n\r\n // Override with any user option, if non default to .25 for pixel art, 0.01 for everything else\r\n uvPadding = options.uvPadding ?? uvPadding ?? 0.01;\r\n\r\n // Canvas 2D fallback can be flagged on\r\n let useCanvasGraphicsContext = Flags.isEnabled('use-canvas-context');\r\n if (!useCanvasGraphicsContext) {\r\n // Attempt webgl first\r\n try {\r\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n pixelArtSampler: pixelArtSampler,\r\n antialiasing: nativeContextAntialiasing,\r\n multiSampleAntialiasing: multiSampleAntialiasing,\r\n uvPadding: uvPadding,\r\n powerPreference: options.powerPreference,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n } catch (e) {\r\n this._logger.warn(\r\n `Excalibur could not load webgl for some reason (${(e as Error).message}) and loaded a Canvas 2D fallback. ` +\r\n `Some features of Excalibur will not work in this mode. \\n\\n` +\r\n 'Read more about this issue at https://excaliburjs.com/docs/webgl'\r\n );\r\n // fallback to canvas in case of failure\r\n useCanvasGraphicsContext = true;\r\n }\r\n }\r\n\r\n if (useCanvasGraphicsContext) {\r\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n antialiasing: nativeContextAntialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n }\r\n\r\n this.screen = new Screen({\r\n canvas: this.canvas,\r\n context: this.graphicsContext,\r\n antialiasing: nativeContextAntialiasing,\r\n canvasImageRendering: canvasImageRendering,\r\n browser: this.browser,\r\n viewport: options.viewport ?? (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\r\n resolution: options.resolution,\r\n displayMode,\r\n pixelRatio: options.suppressHiDPIScaling ? 1 : (options.pixelRatio ?? null)\r\n });\r\n\r\n // TODO REMOVE STATIC!!!\r\n // Set default filtering based on antialiasing\r\n TextureLoader.filtering = filtering;\r\n\r\n if (options.backgroundColor) {\r\n this.backgroundColor = options.backgroundColor.clone();\r\n }\r\n\r\n this.grabWindowFocus = options.grabWindowFocus;\r\n this.pointerScope = options.pointerScope;\r\n\r\n this.maxFps = options.maxFps ?? this.maxFps;\r\n this.fixedUpdateFps = options.fixedUpdateFps ?? this.fixedUpdateFps;\r\n\r\n this.clock = new StandardClock({\r\n maxFps: this.maxFps,\r\n tick: this._mainloop.bind(this),\r\n onFatalException: (e) => this.onFatalException(e)\r\n });\r\n\r\n this.enableCanvasTransparency = options.enableCanvasTransparency;\r\n\r\n if (typeof options.physics === 'boolean') {\r\n this.physics = {\r\n ...DefaultPhysicsConfig,\r\n ...DeprecatedStaticToConfig(),\r\n enabled: options.physics\r\n };\r\n } else {\r\n this.physics = {\r\n ...DefaultPhysicsConfig,\r\n ...DeprecatedStaticToConfig(),\r\n ...options.physics as DeepRequired\r\n };\r\n }\r\n\r\n this.debug = new DebugConfig(this);\r\n\r\n this.director = new Director(this, options.scenes);\r\n\r\n this._initialize(options);\r\n\r\n (window as any).___EXCALIBUR_DEVTOOL = this;\r\n }\r\n\r\n private _performanceThresholdTriggered = false;\r\n private _fpsSamples: number[] = [];\r\n private _monitorPerformanceThresholdAndTriggerFallback() {\r\n const { allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\r\n let { threshold, showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\r\n if (threshold === undefined) {\r\n threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\r\n }\r\n if (showPlayerMessage === undefined) {\r\n showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\r\n }\r\n if (!Flags.isEnabled('use-canvas-context') && allow && this.ready && !this._performanceThresholdTriggered) {\r\n // Calculate Average fps for last X number of frames after start\r\n if (this._fpsSamples.length === threshold.numberOfFrames) {\r\n this._fpsSamples.splice(0, 1);\r\n }\r\n this._fpsSamples.push(this.clock.fpsSampler.fps);\r\n let total = 0;\r\n for (let i = 0; i < this._fpsSamples.length; i++) {\r\n total += this._fpsSamples[i];\r\n }\r\n const average = total / this._fpsSamples.length;\r\n\r\n if (this._fpsSamples.length === threshold.numberOfFrames) {\r\n if (average <= threshold.fps) {\r\n this._performanceThresholdTriggered = true;\r\n this._logger.warn(\r\n `Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` +\r\n 'this might mean your browser doesn\\'t have webgl enabled or hardware acceleration is unavailable.\\n\\n' +\r\n 'If in Chrome:\\n' +\r\n ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n'+\r\n ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' +\r\n 'If in Firefox, visit about:config\\n' +\r\n ' * Ensure webgl.disabled = false\\n' +\r\n ' * Ensure webgl.force-enabled = true\\n' +\r\n ' * Ensure layers.acceleration.force-enabled = true\\n\\n' +\r\n 'Read more about this issue at https://excaliburjs.com/docs/performance'\r\n );\r\n\r\n if (showPlayerMessage) {\r\n this._toaster.toast(\r\n 'Excalibur is encountering performance issues. '+\r\n 'It\\'s possible that your browser doesn\\'t have hardware acceleration enabled. ' +\r\n 'Visit [LINK] for more information and potential solutions.',\r\n 'https://excaliburjs.com/docs/performance'\r\n );\r\n }\r\n this.useCanvas2DFallback();\r\n this.emit('fallbackgraphicscontext', this.graphicsContext);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Switches the engine's graphics context to the 2D Canvas.\r\n * @warning Some features of Excalibur will not work in this mode.\r\n */\r\n public useCanvas2DFallback() {\r\n // Swap out the canvas\r\n const newCanvas = this.canvas.cloneNode(false) as HTMLCanvasElement;\r\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\r\n this.canvas = newCanvas;\r\n\r\n const options = { ...this._originalOptions, antialiasing: this.getAntialiasing() };\r\n const displayMode = this._originalDisplayMode;\r\n\r\n // New graphics context\r\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n antialiasing: options.antialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n\r\n // Reset screen\r\n if (this.screen) {\r\n this.screen.dispose();\r\n }\r\n\r\n this.screen = new Screen({\r\n canvas: this.canvas,\r\n context: this.graphicsContext,\r\n antialiasing: options.antialiasing ?? true,\r\n browser: this.browser,\r\n viewport: options.viewport ?? (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\r\n resolution: options.resolution,\r\n displayMode,\r\n pixelRatio: options.suppressHiDPIScaling ? 1 : (options.pixelRatio ?? null)\r\n });\r\n this.screen.setCurrentCamera(this.currentScene.camera);\r\n\r\n // Reset pointers\r\n this.input.pointers.detach();\r\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\r\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\r\n this.input.pointers.init();\r\n }\r\n\r\n private _disposed = false;\r\n /**\r\n * Attempts to completely clean up excalibur resources, including removing the canvas from the dom.\r\n *\r\n * To start again you will need to new up an Engine.\r\n */\r\n public dispose() {\r\n if (!this._disposed) {\r\n this._disposed = true;\r\n this.stop();\r\n this.input.toggleEnabled(false);\r\n this.canvas.parentNode.removeChild(this.canvas);\r\n this.canvas = null;\r\n this.screen.dispose();\r\n this.graphicsContext.dispose();\r\n this.graphicsContext = null;\r\n }\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n */\r\n public getWorldBounds() {\r\n return this.screen.getWorldBounds();\r\n }\r\n\r\n /**\r\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\r\n */\r\n public get timescale() {\r\n return this._timescale;\r\n }\r\n\r\n /**\r\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\r\n * when using time-based movement.\r\n */\r\n public set timescale(value: number) {\r\n if (value <= 0) {\r\n Logger.getInstance().error('Cannot set engine.timescale to a value of 0 or less than 0.');\r\n return;\r\n }\r\n\r\n this._timescale = value;\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the [[currentScene]].\r\n * @param timer The timer to add to the [[currentScene]].\r\n */\r\n public addTimer(timer: Timer): Timer {\r\n return this.currentScene.addTimer(timer);\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the [[currentScene]].\r\n * @param timer The timer to remove to the [[currentScene]].\r\n */\r\n public removeTimer(timer: Timer): Timer {\r\n return this.currentScene.removeTimer(timer);\r\n }\r\n\r\n /**\r\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\r\n * would levels or menus.\r\n * @param key The name of the scene, must be unique\r\n * @param scene The scene to add to the engine\r\n */\r\n public addScene(key: TScene, scene: Scene | SceneConstructor | SceneWithOptions): Engine {\r\n this.director.add(key, scene);\r\n return this as Engine;\r\n }\r\n\r\n /**\r\n * Removes a [[Scene]] instance from the engine\r\n * @param scene The scene to remove\r\n */\r\n public removeScene(scene: Scene | SceneConstructor): void;\r\n /**\r\n * Removes a scene from the engine by key\r\n * @param key The scene key to remove\r\n */\r\n public removeScene(key: string): void;\r\n /**\r\n * @internal\r\n */\r\n public removeScene(entity: any): void {\r\n this.director.remove(entity);\r\n }\r\n\r\n /**\r\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\r\n * would levels or menus.\r\n * @param sceneKey The key of the scene, must be unique\r\n * @param scene The scene to add to the engine\r\n */\r\n public add(sceneKey: string, scene: Scene | SceneConstructor | SceneWithOptions): void;\r\n /**\r\n * Adds a [[Timer]] to the [[currentScene]].\r\n * @param timer The timer to add to the [[currentScene]].\r\n */\r\n public add(timer: Timer): void;\r\n /**\r\n * Adds a [[TileMap]] to the [[currentScene]], once this is done the TileMap\r\n * will be drawn and updated.\r\n */\r\n public add(tileMap: TileMap): void;\r\n /**\r\n * Adds an actor to the [[currentScene]] of the game. This is synonymous\r\n * to calling `engine.currentScene.add(actor)`.\r\n *\r\n * Actors can only be drawn if they are a member of a scene, and only\r\n * the [[currentScene]] may be drawn or updated.\r\n * @param actor The actor to add to the [[currentScene]]\r\n */\r\n public add(actor: Actor): void;\r\n\r\n public add(entity: Entity): void;\r\n\r\n /**\r\n * Adds a [[ScreenElement]] to the [[currentScene]] of the game,\r\n * ScreenElements do not participate in collisions, instead the\r\n * remain in the same place on the screen.\r\n * @param screenElement The ScreenElement to add to the [[currentScene]]\r\n */\r\n public add(screenElement: ScreenElement): void;\r\n public add(entity: any): void {\r\n if (arguments.length === 2) {\r\n this.director.add(arguments[0], arguments[1]);\r\n return;\r\n }\r\n const maybeDeferred = this.director.getDeferredScene();\r\n if (maybeDeferred instanceof Scene) {\r\n maybeDeferred.add(entity);\r\n } else {\r\n this.currentScene.add(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Removes a scene instance from the engine\r\n * @param scene The scene to remove\r\n */\r\n public remove(scene: Scene | SceneConstructor): void;\r\n /**\r\n * Removes a scene from the engine by key\r\n * @param sceneKey The scene to remove\r\n */\r\n public remove(sceneKey: string): void;\r\n /**\r\n * Removes a [[Timer]] from the [[currentScene]].\r\n * @param timer The timer to remove to the [[currentScene]].\r\n */\r\n public remove(timer: Timer): void;\r\n /**\r\n * Removes a [[TileMap]] from the [[currentScene]], it will no longer be drawn or updated.\r\n */\r\n public remove(tileMap: TileMap): void;\r\n /**\r\n * Removes an actor from the [[currentScene]] of the game. This is synonymous\r\n * to calling `engine.currentScene.removeChild(actor)`.\r\n * Actors that are removed from a scene will no longer be drawn or updated.\r\n * @param actor The actor to remove from the [[currentScene]].\r\n */\r\n public remove(actor: Actor): void;\r\n /**\r\n * Removes a [[ScreenElement]] to the scene, it will no longer be drawn or updated\r\n * @param screenElement The ScreenElement to remove from the [[currentScene]]\r\n */\r\n public remove(screenElement: ScreenElement): void;\r\n public remove(entity: any): void {\r\n if (entity instanceof Entity) {\r\n this.currentScene.remove(entity);\r\n }\r\n\r\n if (entity instanceof Scene || isSceneConstructor(entity)) {\r\n this.removeScene(entity);\r\n }\r\n\r\n if (typeof entity === 'string') {\r\n this.removeScene(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Changes the current scene with optionally supplied:\r\n * * Activation data\r\n * * Transitions\r\n * * Loaders\r\n *\r\n * Example:\r\n * ```typescript\r\n * game.goToScene('myScene', {\r\n * sceneActivationData: {any: 'thing at all'},\r\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\r\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\r\n * loader: MyLoader\r\n * });\r\n * ```\r\n *\r\n * Scenes are defined in the Engine constructor\r\n * ```typescript\r\n * const engine = new ex.Engine({\r\n scenes: {...}\r\n });\r\n * ```\r\n * Or by adding dynamically\r\n *\r\n * ```typescript\r\n * engine.addScene('myScene', new ex.Scene());\r\n * ```\r\n * @param destinationScene\r\n * @param options\r\n * @deprecated use goToScene, it now behaves the same as goto\r\n */\r\n public async goto(destinationScene: WithRoot, options?: GoToOptions) {\r\n await this.director.goto(destinationScene, options);\r\n }\r\n\r\n /**\r\n * Changes the current scene with optionally supplied:\r\n * * Activation data\r\n * * Transitions\r\n * * Loaders\r\n *\r\n * Example:\r\n * ```typescript\r\n * game.goToScene('myScene', {\r\n * sceneActivationData: {any: 'thing at all'},\r\n * destinationIn: new FadeInOut({duration: 1000, direction: 'in'}),\r\n * sourceOut: new FadeInOut({duration: 1000, direction: 'out'}),\r\n * loader: MyLoader\r\n * });\r\n * ```\r\n *\r\n * Scenes are defined in the Engine constructor\r\n * ```typescript\r\n * const engine = new ex.Engine({\r\n scenes: {...}\r\n });\r\n * ```\r\n * Or by adding dynamically\r\n *\r\n * ```typescript\r\n * engine.addScene('myScene', new ex.Scene());\r\n * ```\r\n * @param destinationScene\r\n * @param options\r\n */\r\n public async goToScene(destinationScene: WithRoot, options?: GoToOptions): Promise {\r\n await this.director.goto(destinationScene, options);\r\n }\r\n\r\n /**\r\n * Transforms the current x, y from screen coordinates to world coordinates\r\n * @param point Screen coordinate to convert\r\n */\r\n public screenToWorldCoordinates(point: Vector): Vector {\r\n return this.screen.screenToWorldCoordinates(point);\r\n }\r\n\r\n /**\r\n * Transforms a world coordinate, to a screen coordinate\r\n * @param point World coordinate to convert\r\n */\r\n public worldToScreenCoordinates(point: Vector): Vector {\r\n return this.screen.worldToScreenCoordinates(point);\r\n }\r\n\r\n /**\r\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\r\n */\r\n private _initialize(options?: EngineOptions) {\r\n this.pageScrollPreventionMode = options.scrollPreventionMode;\r\n\r\n // initialize inputs\r\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\r\n const grabWindowFocus = this._originalOptions?.grabWindowFocus ?? true;\r\n this.input = new InputHost({\r\n pointerTarget,\r\n grabWindowFocus,\r\n engine: this\r\n });\r\n this.inputMapper = this.input.inputMapper;\r\n\r\n // Issue #385 make use of the visibility api\r\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\r\n\r\n this.browser.document.on('visibilitychange', () => {\r\n if (document.visibilityState === 'hidden') {\r\n this.events.emit('hidden', new HiddenEvent(this));\r\n this._logger.debug('Window hidden');\r\n } else if (document.visibilityState === 'visible') {\r\n this.events.emit('visible', new VisibleEvent(this));\r\n this._logger.debug('Window visible');\r\n }\r\n });\r\n\r\n if (!this.canvasElementId && !options.canvasElement) {\r\n document.body.appendChild(this.canvas);\r\n }\r\n }\r\n\r\n public toggleInputEnabled(enabled: boolean) {\r\n this._inputEnabled = enabled;\r\n this.input.toggleEnabled(this._inputEnabled);\r\n }\r\n\r\n public onInitialize(engine: Engine) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * If supported by the browser, this will set the antialiasing flag on the\r\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\r\n * image resources.\r\n * @param isSmooth Set smoothing to true or false\r\n * @deprecated Set in engine constructor, will be removed in v0.30\r\n */\r\n public setAntialiasing(isSmooth: boolean) {\r\n this.screen.antialiasing = isSmooth;\r\n }\r\n\r\n /**\r\n * Return the current smoothing status of the canvas\r\n * @deprecated Set in engine constructor, will be removed in v0.30\r\n */\r\n public getAntialiasing(): boolean {\r\n return this.screen.antialiasing;\r\n }\r\n\r\n /**\r\n * Gets whether the actor is Initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n private async _overrideInitialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n await this.director.onInitialize();\r\n await this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * Updates the entire state of the game\r\n * @param delta Number of milliseconds elapsed since the last update.\r\n */\r\n private _update(delta: number) {\r\n if (this._isLoading) {\r\n // suspend updates until loading is finished\r\n this._loader?.onUpdate(this, delta);\r\n // Update input listeners\r\n this.input.update();\r\n return;\r\n }\r\n\r\n // Publish preupdate events\r\n this._preupdate(delta);\r\n\r\n // process engine level events\r\n this.currentScene.update(this, delta);\r\n\r\n // Update graphics postprocessors\r\n this.graphicsContext.updatePostProcessors(delta);\r\n\r\n // Publish update event\r\n this._postupdate(delta);\r\n\r\n // Update input listeners\r\n this.input.update();\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _preupdate(delta: number) {\r\n this.emit('preupdate', new PreUpdateEvent(this, delta, this));\r\n this.onPreUpdate(this, delta);\r\n }\r\n\r\n public onPreUpdate(engine: Engine, delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _postupdate(delta: number) {\r\n this.emit('postupdate', new PostUpdateEvent(this, delta, this));\r\n this.onPostUpdate(this, delta);\r\n }\r\n\r\n public onPostUpdate(engine: Engine, delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Draws the entire game\r\n * @param delta Number of milliseconds elapsed since the last draw.\r\n */\r\n private _draw(delta: number) {\r\n this.graphicsContext.beginDrawLifecycle();\r\n this.graphicsContext.clear();\r\n this._predraw(this.graphicsContext, delta);\r\n\r\n // Drawing nothing else while loading\r\n if (this._isLoading) {\r\n if (!this._hideLoader) {\r\n this._loader?.canvas.draw(this.graphicsContext, 0, 0);\r\n this.graphicsContext.flush();\r\n this.graphicsContext.endDrawLifecycle();\r\n }\r\n return;\r\n }\r\n\r\n // Use scene background color if present, fallback to engine\r\n this.graphicsContext.backgroundColor = this.currentScene.backgroundColor ?? this.backgroundColor;\r\n\r\n this.currentScene.draw(this.graphicsContext, delta);\r\n\r\n this._postdraw(this.graphicsContext, delta);\r\n\r\n // Flush any pending drawings\r\n this.graphicsContext.flush();\r\n this.graphicsContext.endDrawLifecycle();\r\n\r\n this._checkForScreenShots();\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _predraw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n this.emit('predraw', new PreDrawEvent(ctx, delta, this));\r\n this.onPreDraw(ctx, delta);\r\n }\r\n\r\n public onPreDraw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _postdraw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\r\n this.onPostDraw(ctx, delta);\r\n }\r\n\r\n public onPostDraw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Enable or disable Excalibur debugging functionality.\r\n * @param toggle a value that debug drawing will be changed to\r\n */\r\n public showDebug(toggle: boolean): void {\r\n this._isDebug = toggle;\r\n }\r\n\r\n /**\r\n * Toggle Excalibur debugging functionality.\r\n */\r\n public toggleDebug(): boolean {\r\n this._isDebug = !this._isDebug;\r\n return this._isDebug;\r\n }\r\n\r\n /**\r\n * Returns true when loading is totally complete and the player has clicked start\r\n */\r\n public get loadingComplete() {\r\n return !this._isLoading;\r\n }\r\n\r\n private _isLoading = false;\r\n private _hideLoader = false;\r\n private _isReadyFuture = new Future();\r\n public get ready() {\r\n return this._isReadyFuture.isCompleted;\r\n }\r\n public isReady(): Promise {\r\n return this._isReadyFuture.promise;\r\n }\r\n\r\n\r\n\r\n /**\r\n * Starts the internal game loop for Excalibur after loading\r\n * any provided assets.\r\n * @param loader Optional [[Loader]] to use to load resources. The default loader is [[Loader]],\r\n * override to provide your own custom loader.\r\n *\r\n * Note: start() only resolves AFTER the user has clicked the play button\r\n */\r\n public async start(loader?: DefaultLoader): Promise;\r\n /**\r\n * Starts the internal game loop for Excalibur after configuring any routes, loaders, or transitions\r\n * @param startOptions Optional [[StartOptions]] to configure the routes for scenes in Excalibur\r\n *\r\n * Note: start() only resolves AFTER the user has clicked the play button\r\n */\r\n public async start(sceneName: WithRoot, options?: StartOptions): Promise;\r\n /**\r\n * Starts the internal game loop after any loader is finished\r\n * @param loader\r\n */\r\n public async start(loader?: DefaultLoader): Promise;\r\n public async start(sceneNameOrLoader?: WithRoot | DefaultLoader, options?: StartOptions): Promise {\r\n if (!this._compatible) {\r\n throw new Error('Excalibur is incompatible with your browser');\r\n }\r\n this._isLoading = true;\r\n let loader: DefaultLoader;\r\n if (sceneNameOrLoader instanceof DefaultLoader) {\r\n loader = sceneNameOrLoader;\r\n } else if (typeof sceneNameOrLoader === 'string') {\r\n this.director.configureStart(sceneNameOrLoader, options);\r\n loader = this.director.mainLoader;\r\n }\r\n\r\n // Start the excalibur clock which drives the mainloop\r\n this._logger.debug('Starting game clock...');\r\n this.browser.resume();\r\n this.clock.start();\r\n this._logger.debug('Game clock started');\r\n\r\n await this.load(loader ?? new Loader());\r\n\r\n // Initialize before ready\r\n await this._overrideInitialize(this);\r\n\r\n this._isReadyFuture.resolve();\r\n this.emit('start', new GameStartEvent(this));\r\n return this._isReadyFuture.promise;\r\n }\r\n\r\n /**\r\n * Returns the current frames elapsed milliseconds\r\n */\r\n public currentFrameElapsedMs = 0;\r\n\r\n /**\r\n * Returns the current frame lag when in fixed update mode\r\n */\r\n public currentFrameLagMs = 0;\r\n\r\n private _lagMs = 0;\r\n private _mainloop(elapsed: number) {\r\n this.emit('preframe', new PreFrameEvent(this, this.stats.prevFrame));\r\n const delta = elapsed * this.timescale;\r\n this.currentFrameElapsedMs = delta;\r\n\r\n // reset frame stats (reuse existing instances)\r\n const frameId = this.stats.prevFrame.id + 1;\r\n this.stats.currFrame.reset();\r\n this.stats.currFrame.id = frameId;\r\n this.stats.currFrame.delta = delta;\r\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\r\n GraphicsDiagnostics.clear();\r\n\r\n const beforeUpdate = this.clock.now();\r\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\r\n if (this.fixedUpdateFps) {\r\n this._lagMs += delta;\r\n while (this._lagMs >= fixedTimestepMs) {\r\n this._update(fixedTimestepMs);\r\n this._lagMs -= fixedTimestepMs;\r\n }\r\n } else {\r\n this._update(delta);\r\n }\r\n const afterUpdate = this.clock.now();\r\n this.currentFrameLagMs = this._lagMs;\r\n this._draw(delta);\r\n const afterDraw = this.clock.now();\r\n\r\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\r\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\r\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\r\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\r\n\r\n this.emit('postframe', new PostFrameEvent(this, this.stats.currFrame));\r\n this.stats.prevFrame.reset(this.stats.currFrame);\r\n\r\n this._monitorPerformanceThresholdAndTriggerFallback();\r\n }\r\n\r\n /**\r\n * Stops Excalibur's main loop, useful for pausing the game.\r\n */\r\n public stop() {\r\n if (this.clock.isRunning()) {\r\n this.emit('stop', new GameStopEvent(this));\r\n this.browser.pause();\r\n this.clock.stop();\r\n this._logger.debug('Game stopped');\r\n }\r\n }\r\n\r\n /**\r\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\r\n */\r\n public isRunning() {\r\n return this.clock.isRunning();\r\n }\r\n\r\n\r\n private _screenShotRequests: { preserveHiDPIResolution: boolean, resolve: (image: HTMLImageElement) => void }[] = [];\r\n /**\r\n * Takes a screen shot of the current viewport and returns it as an\r\n * HTML Image Element.\r\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\r\n */\r\n public screenshot(preserveHiDPIResolution = false): Promise {\r\n const screenShotPromise = new Promise((resolve) => {\r\n this._screenShotRequests.push({preserveHiDPIResolution, resolve});\r\n });\r\n return screenShotPromise;\r\n }\r\n\r\n private _checkForScreenShots() {\r\n // We must grab the draw buffer before we yield to the browser\r\n // the draw buffer is cleared after compositing\r\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\r\n // forces the browser to copy buffers which can have a mass perf impact on mobile\r\n for (const request of this._screenShotRequests) {\r\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\r\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\r\n const screenshot = document.createElement('canvas');\r\n screenshot.width = finalWidth;\r\n screenshot.height = finalHeight;\r\n const ctx = screenshot.getContext('2d');\r\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\r\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\r\n\r\n const result = new Image();\r\n const raw = screenshot.toDataURL('image/png');\r\n result.src = raw;\r\n request.resolve(result);\r\n }\r\n // Reset state\r\n this._screenShotRequests.length = 0;\r\n }\r\n\r\n /**\r\n * Another option available to you to load resources into the game.\r\n * Immediately after calling this the game will pause and the loading screen\r\n * will appear.\r\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\r\n */\r\n public async load(loader: DefaultLoader, hideLoader = false): Promise {\r\n try {\r\n // early exit if loaded\r\n if (loader.isLoaded()) {\r\n return;\r\n }\r\n this._loader = loader;\r\n this._isLoading = true;\r\n this._hideLoader = hideLoader;\r\n\r\n if (loader instanceof Loader) {\r\n loader.suppressPlayButton = this._suppressPlayButton;\r\n }\r\n this._loader.onInitialize(this);\r\n\r\n await loader.load();\r\n } catch (e) {\r\n this._logger.error('Error loading resources, things may not behave properly', e);\r\n await Promise.resolve();\r\n } finally {\r\n this._isLoading = false;\r\n this._hideLoader = false;\r\n this._loader = null;\r\n }\r\n }\r\n}","export * from './vector';\r\nexport * from './vector-view';\r\nexport * from './matrix';\r\nexport * from './affine-matrix';\r\nexport * from './transform';\r\nexport * from './coord-plane';\r\nexport * from './Random';\r\nexport * from './global-coordinates';\r\nexport * from './line-segment';\r\nexport * from './projection';\r\nexport * from './ray';\r\nexport * from './util';","export * from './DebugConfig';\r\nexport * from './DebugFlags';\r\nexport * from './DebugSystem';\r\n","import { GameEvent } from './Events';\r\nimport { Eventable } from './Interfaces/Evented';\r\n\r\n/**\r\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\r\n */\r\nexport class EventDispatcher implements Eventable {\r\n private _handlers: { [key: string]: { (event: GameEvent): void }[] } = {};\r\n private _wiredEventDispatchers: Eventable[] = [];\r\n\r\n /**\r\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\r\n */\r\n public clear() {\r\n this._handlers = {};\r\n this._wiredEventDispatchers = [];\r\n }\r\n\r\n private _deferedHandlerRemovals: {name: string, handler?: (...args: any[]) => any }[] = [];\r\n private _processDeferredHandlerRemovals() {\r\n for (const eventHandler of this._deferedHandlerRemovals) {\r\n this._removeHandler(eventHandler.name, eventHandler.handler);\r\n }\r\n this._deferedHandlerRemovals.length = 0;\r\n }\r\n\r\n /**\r\n * Emits an event for target\r\n * @param eventName The name of the event to publish\r\n * @param event Optionally pass an event data object to the handler\r\n */\r\n public emit(eventName: string, event: GameEvent) {\r\n this._processDeferredHandlerRemovals();\r\n if (!eventName) {\r\n // key not mapped\r\n return;\r\n }\r\n eventName = eventName.toLowerCase();\r\n if (typeof event === 'undefined' || event === null) {\r\n event = new GameEvent();\r\n }\r\n let i: number, len: number;\r\n\r\n if (this._handlers[eventName]) {\r\n i = 0;\r\n len = this._handlers[eventName].length;\r\n for (i; i < len; i++) {\r\n this._handlers[eventName][i](event);\r\n }\r\n }\r\n\r\n i = 0;\r\n len = this._wiredEventDispatchers.length;\r\n\r\n for (i; i < len; i++) {\r\n this._wiredEventDispatchers[i].emit(eventName, event);\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\r\n * @param eventName The name of the event to subscribe to\r\n * @param handler The handler callback to fire on this event\r\n */\r\n public on(eventName: string, handler: (event: GameEvent) => void) {\r\n this._processDeferredHandlerRemovals();\r\n eventName = eventName.toLowerCase();\r\n\r\n if (!this._handlers[eventName]) {\r\n this._handlers[eventName] = [];\r\n }\r\n this._handlers[eventName].push(handler);\r\n }\r\n\r\n /**\r\n * Unsubscribe an event handler(s) from an event. If a specific handler\r\n * is specified for an event, only that handler will be unsubscribed.\r\n * Otherwise all handlers will be unsubscribed for that event.\r\n * @param eventName The name of the event to unsubscribe\r\n * @param handler Optionally the specific handler to unsubscribe\r\n */\r\n public off(eventName: string, handler?: (event: GameEvent) => void) {\r\n this._deferedHandlerRemovals.push({name: eventName, handler});\r\n }\r\n\r\n private _removeHandler(eventName: string, handler?: (event: GameEvent) => void) {\r\n eventName = eventName.toLowerCase();\r\n const eventHandlers = this._handlers[eventName];\r\n\r\n if (eventHandlers) {\r\n // if no explicit handler is give with the event name clear all handlers\r\n if (!handler) {\r\n this._handlers[eventName].length = 0;\r\n } else {\r\n const index = eventHandlers.indexOf(handler);\r\n if (index > -1) {\r\n this._handlers[eventName].splice(index, 1);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Once listens to an event one time, then unsubscribes from that event\r\n * @param eventName The name of the event to subscribe to once\r\n * @param handler The handler of the event that will be auto unsubscribed\r\n */\r\n public once(eventName: string, handler: (event: GameEvent) => void) {\r\n this._processDeferredHandlerRemovals();\r\n const metaHandler = (event: GameEvent) => {\r\n const ev = event || new GameEvent();\r\n this.off(eventName, metaHandler);\r\n handler(ev);\r\n };\r\n\r\n this.on(eventName, metaHandler);\r\n }\r\n\r\n /**\r\n * Wires this event dispatcher to also receive events from another\r\n */\r\n public wire(eventDispatcher: EventDispatcher): void {\r\n eventDispatcher._wiredEventDispatchers.push(this);\r\n }\r\n\r\n /**\r\n * Unwires this event dispatcher from another\r\n */\r\n public unwire(eventDispatcher: EventDispatcher): void {\r\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\r\n if (index > -1) {\r\n eventDispatcher._wiredEventDispatchers.splice(index, 1);\r\n }\r\n }\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Color } from './Color';\r\nimport { vec, Vector } from './Math/vector';\r\nimport { Text } from './Graphics/Text';\r\nimport { GraphicsComponent, SpriteFont } from './Graphics';\r\nimport { Font } from './Graphics/Font';\r\nimport { Actor } from './Actor';\r\nimport { ActorArgs } from './Actor';\r\n\r\n/**\r\n * Option for creating a label\r\n */\r\nexport interface LabelOptions {\r\n /**\r\n * Specify the label text\r\n */\r\n text?: string;\r\n /**\r\n * Specify the color of the text (does not apply to SpriteFonts)\r\n */\r\n color?: Color;\r\n x?: number;\r\n y?: number;\r\n pos?: Vector;\r\n /**\r\n * Optionally specify a sprite font, will take precedence over any other [[Font]]\r\n */\r\n spriteFont?: SpriteFont;\r\n /**\r\n * Specify a custom font\r\n */\r\n font?: Font\r\n}\r\n\r\n/**\r\n * Labels are the way to draw small amounts of text to the screen. They are\r\n * actors and inherit all of the benefits and capabilities.\r\n */\r\nexport class Label extends Actor {\r\n private _font: Font = new Font();\r\n private _text: Text = new Text({ text: '', font: this._font });\r\n\r\n public get font(): Font {\r\n return this._font;\r\n }\r\n\r\n public set font(newFont: Font) {\r\n this._font = newFont;\r\n this._text.font = newFont;\r\n }\r\n\r\n /**\r\n * The text to draw.\r\n */\r\n public get text(): string {\r\n return this._text.text;\r\n }\r\n\r\n public set text(text: string) {\r\n this._text.text = text;\r\n }\r\n\r\n public override get color(): Color {\r\n return this._text.color;\r\n }\r\n\r\n public override set color(color: Color) {\r\n if (this._text) {\r\n this._text.color = color;\r\n }\r\n }\r\n\r\n public get opacity(): number {\r\n return this._text.opacity;\r\n }\r\n\r\n public set opacity(opacity: number) {\r\n this._text.opacity = opacity;\r\n }\r\n\r\n private _spriteFont: SpriteFont;\r\n /**\r\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\r\n */\r\n public get spriteFont(): SpriteFont {\r\n return this._spriteFont;\r\n }\r\n\r\n public set spriteFont(sf: SpriteFont) {\r\n if (sf) {\r\n this._spriteFont = sf;\r\n this._text.font = this._spriteFont;\r\n }\r\n }\r\n\r\n /**\r\n * Build a new label\r\n * @param options\r\n */\r\n constructor(options?: LabelOptions & ActorArgs) {\r\n super(options);\r\n const {text, pos, x, y, spriteFont, font, color} = { text: '', ...options };\r\n\r\n this.pos = pos ?? (x && y ? vec(x, y) : this.pos);\r\n this.text = text ?? this.text;\r\n this.font = font ?? this.font;\r\n this.spriteFont = spriteFont ?? this.spriteFont;\r\n this._text.color = color ?? this.color;\r\n const gfx = this.get(GraphicsComponent);\r\n gfx.anchor = Vector.Zero;\r\n gfx.use(this._text);\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n }\r\n\r\n /**\r\n * Returns the width of the text in the label (in pixels);\r\n */\r\n public getTextWidth(): number {\r\n return this._text.width;\r\n }\r\n}\r\n","import { BodyComponent } from '../Collision/BodyComponent';\r\nimport { BoundingBox} from '../Collision/BoundingBox';\r\nimport { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { Collider } from '../Collision/Colliders/Collider';\r\nimport { CollisionType } from '../Collision/CollisionType';\r\nimport { CompositeCollider } from '../Collision/Colliders/CompositeCollider';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { DebugGraphicsComponent, ExcaliburGraphicsContext, Graphic, GraphicsComponent } from '../Graphics';\r\nimport { IsometricEntityComponent } from './IsometricEntityComponent';\r\nimport { DebugConfig } from '../Debug';\r\nexport class IsometricTile extends Entity {\r\n /**\r\n * Indicates whether this tile is solid\r\n */\r\n public solid: boolean = false;\r\n\r\n private _gfx: GraphicsComponent;\r\n private _tileBounds = new BoundingBox();\r\n private _graphics: Graphic[] = [];\r\n public getGraphics(): readonly Graphic[] {\r\n return this._graphics;\r\n }\r\n /**\r\n * Tile graphics\r\n */\r\n public addGraphic(graphic: Graphic, options?: {offset?: Vector}) {\r\n this._graphics.push(graphic);\r\n this._gfx.visible = this.map.visible;\r\n this._gfx.opacity = this.map.opacity;\r\n if (options?.offset) {\r\n this._gfx.offset = options.offset;\r\n }\r\n // TODO detect when this changes on the map and apply to all tiles\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n private _recalculateBounds(): BoundingBox {\r\n let bounds = this._tileBounds.clone();\r\n for (const graphic of this._graphics) {\r\n const offset = vec(\r\n this.map.graphicsOffset.x - this.map.tileWidth / 2,\r\n this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\r\n bounds = bounds.combine(graphic.localBounds.translate(offset));\r\n }\r\n return bounds;\r\n }\r\n\r\n public removeGraphic(graphic: Graphic) {\r\n const index = this._graphics.indexOf(graphic);\r\n if (index > -1) {\r\n this._graphics.splice(index, 1);\r\n }\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n public clearGraphics() {\r\n this._graphics.length = 0;\r\n this._gfx.visible = false;\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n /**\r\n * Tile colliders\r\n */\r\n private _colliders: Collider[] = [];\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n /**\r\n * Adds a collider to the IsometricTile\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */\r\n public addCollider(collider: Collider) {\r\n this._colliders.push(collider);\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Removes a collider from the IsometricTile\r\n * @param collider\r\n */\r\n public removeCollider(collider: Collider) {\r\n const index = this._colliders.indexOf(collider);\r\n if (index > -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Clears all colliders from the IsometricTile\r\n */\r\n public clearColliders(): void {\r\n this._colliders.length = 0;\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Integer tile x coordinate\r\n */\r\n public readonly x: number;\r\n /**\r\n * Integer tile y coordinate\r\n */\r\n public readonly y: number;\r\n /**\r\n * Reference to the [[IsometricMap]] this tile is part of\r\n */\r\n public readonly map: IsometricMap;\r\n\r\n private _transform: TransformComponent;\r\n private _isometricEntityComponent: IsometricEntityComponent;\r\n\r\n /**\r\n * Returns the top left corner of the [[IsometricTile]] in world space\r\n */\r\n public get pos(): Vector {\r\n return this.map.tileToWorld(vec(this.x, this.y));\r\n }\r\n\r\n /**\r\n * Returns the center of the [[IsometricTile]]\r\n */\r\n public get center(): Vector {\r\n return this.pos.add(vec(0, this.map.tileHeight / 2));\r\n }\r\n\r\n /**\r\n * Arbitrary data storage per tile, useful for any game specific data\r\n */\r\n public data = new Map();\r\n\r\n /**\r\n * Construct a new IsometricTile\r\n * @param x tile coordinate in x (not world position)\r\n * @param y tile coordinate in y (not world position)\r\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\r\n * @param map reference to owning IsometricMap\r\n */\r\n constructor(x: number, y: number, graphicsOffset: Vector | null, map: IsometricMap) {\r\n super([\r\n new TransformComponent(),\r\n new GraphicsComponent({\r\n offset: graphicsOffset ?? Vector.Zero,\r\n onPostDraw: (gfx, elapsed) => this.draw(gfx, elapsed)\r\n }),\r\n new IsometricEntityComponent(map)\r\n ]);\r\n this.x = x;\r\n this.y = y;\r\n this.map = map;\r\n this._transform = this.get(TransformComponent);\r\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\r\n\r\n const halfTileWidth = this.map.tileWidth / 2;\r\n const halfTileHeight = this.map.tileHeight / 2;\r\n // See https://clintbellanger.net/articles/isometric_math/ for formula\r\n // The x position shifts left with every y step\r\n const xPos = (this.x - this.y) * halfTileWidth;\r\n // The y position needs to go down with every x step\r\n const yPos = (this.x + this.y) * halfTileHeight;\r\n this._transform.pos = vec(xPos, yPos);\r\n this._isometricEntityComponent.elevation = map.elevation;\r\n\r\n this._gfx = this.get(GraphicsComponent);\r\n this._gfx.visible = false; // start not visible\r\n const totalWidth = this.map.tileWidth;\r\n const totalHeight = this.map.tileHeight;\r\n\r\n // initial guess at gfx bounds based on the tile\r\n const offset = vec(0, (this.map.renderFromTopOfGraphic ? totalHeight : 0));\r\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\r\n left: -totalWidth / 2,\r\n top: -totalHeight,\r\n right: totalWidth / 2,\r\n bottom: totalHeight\r\n }).translate(offset);\r\n }\r\n\r\n draw(gfx: ExcaliburGraphicsContext, _elapsed: number) {\r\n const halfTileWidth = this.map.tileWidth / 2;\r\n gfx.save();\r\n // shift left origin to corner of map, not the left corner of the first sprite\r\n gfx.translate(-halfTileWidth, 0);\r\n for (const graphic of this._graphics) {\r\n graphic.draw(\r\n gfx,\r\n this.map.graphicsOffset.x,\r\n this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\r\n }\r\n gfx.restore();\r\n }\r\n}\r\n\r\nexport interface IsometricMapOptions {\r\n /**\r\n * Optionally name the isometric tile map\r\n */\r\n name?: string;\r\n /**\r\n * Optionally specify the position of the isometric tile map\r\n */\r\n pos?: Vector;\r\n /**\r\n * Optionally render from the top of the graphic, by default tiles are rendered from the bottom\r\n */\r\n renderFromTopOfGraphic?: boolean;\r\n /**\r\n * Optionally present a graphics offset, this can be useful depending on your tile graphics\r\n */\r\n graphicsOffset?: Vector;\r\n /**\r\n * Width of an individual tile in pixels, this should be the width of the parallelogram of the base of the tile art asset.\r\n */\r\n tileWidth: number;\r\n /**\r\n * Height of an individual tile in pixels, this should be the height of the parallelogram of the base of the tile art asset.\r\n */\r\n tileHeight: number;\r\n /**\r\n * The number of tile columns, or the number of tiles wide\r\n */\r\n columns: number;\r\n /**\r\n * The number of tile rows, or the number of tiles high\r\n */\r\n rows: number;\r\n\r\n elevation?: number;\r\n}\r\n\r\n/**\r\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\r\n *\r\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\r\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\r\n *\r\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\r\n * your art assets.\r\n */\r\nexport class IsometricMap extends Entity {\r\n public readonly elevation: number = 0;\r\n\r\n /**\r\n * Width of individual tile in pixels\r\n */\r\n public readonly tileWidth: number;\r\n /**\r\n * Height of individual tile in pixels\r\n */\r\n public readonly tileHeight: number;\r\n /**\r\n * Number of tiles wide\r\n */\r\n public readonly columns: number;\r\n /**\r\n * Number of tiles high\r\n */\r\n public readonly rows: number;\r\n /**\r\n * List containing all of the tiles in IsometricMap\r\n */\r\n public readonly tiles: IsometricTile[];\r\n\r\n /**\r\n * Whether tiles should be visible\r\n */\r\n public visible = true;\r\n\r\n /**\r\n * Opacity of tiles\r\n */\r\n public opacity = 1.0;\r\n\r\n /**\r\n * Render the tile graphic from the top instead of the bottom\r\n *\r\n * default is `false` meaning rendering from the bottom\r\n */\r\n public renderFromTopOfGraphic: boolean = false;\r\n public graphicsOffset: Vector = vec(0, 0);\r\n\r\n /**\r\n * Isometric map [[TransformComponent]]\r\n */\r\n public transform: TransformComponent;\r\n\r\n /**\r\n * Isometric map [[ColliderComponent]]\r\n */\r\n public collider: ColliderComponent;\r\n\r\n private _composite: CompositeCollider;\r\n\r\n constructor(options: IsometricMapOptions) {\r\n super([\r\n new TransformComponent(),\r\n new BodyComponent({\r\n type: CollisionType.Fixed\r\n }),\r\n new ColliderComponent(),\r\n new DebugGraphicsComponent((ctx, debugFlags) => this.debug(ctx, debugFlags), false)\r\n ], options.name);\r\n const { pos, tileWidth, tileHeight, columns: width, rows: height, renderFromTopOfGraphic, graphicsOffset, elevation } = options;\r\n\r\n this.transform = this.get(TransformComponent);\r\n if (pos) {\r\n this.transform.pos = pos;\r\n }\r\n\r\n this.collider = this.get(ColliderComponent);\r\n if (this.collider) {\r\n this.collider.set(this._composite = new CompositeCollider([]));\r\n }\r\n\r\n\r\n this.renderFromTopOfGraphic = renderFromTopOfGraphic ?? this.renderFromTopOfGraphic;\r\n this.graphicsOffset = graphicsOffset ?? this.graphicsOffset;\r\n\r\n this.elevation = elevation ?? this.elevation;\r\n this.tileWidth = tileWidth;\r\n this.tileHeight = tileHeight;\r\n this.columns = width;\r\n this.rows = height;\r\n\r\n this.tiles = new Array(width * height);\r\n\r\n // build up tile representation\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\r\n this.tiles[x + y * width] = tile;\r\n this.addChild(tile);\r\n }\r\n }\r\n }\r\n\r\n public update(): void {\r\n if (this._collidersDirty) {\r\n this.updateColliders();\r\n this._collidersDirty = false;\r\n }\r\n }\r\n\r\n private _collidersDirty = false;\r\n public flagCollidersDirty() {\r\n this._collidersDirty = true;\r\n }\r\n\r\n private _originalOffsets = new WeakMap();\r\n private _getOrSetColliderOriginalOffset(collider: Collider): Vector {\r\n if (!this._originalOffsets.has(collider)) {\r\n const originalOffset = collider.offset;\r\n this._originalOffsets.set(collider, originalOffset);\r\n return originalOffset;\r\n } else {\r\n return this._originalOffsets.get(collider);\r\n }\r\n }\r\n public updateColliders() {\r\n this._composite.clearColliders();\r\n const pos = this.get(TransformComponent).pos;\r\n for (const tile of this.tiles) {\r\n if (tile.solid) {\r\n for (const collider of tile.getColliders()) {\r\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\r\n collider.offset = this.tileToWorld(vec(tile.x, tile.y))\r\n .sub(pos)\r\n .add(originalOffset)\r\n .sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n }\r\n }\r\n this.collider.update();\r\n }\r\n\r\n /**\r\n * Convert world space coordinates to the tile x, y coordinate\r\n * @param worldCoordinate\r\n */\r\n public worldToTile(worldCoordinate: Vector): Vector {\r\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\r\n\r\n const halfTileWidth = this.tileWidth / 2;\r\n const halfTileHeight = this.tileHeight / 2;\r\n // See https://clintbellanger.net/articles/isometric_math/ for formula\r\n return vec(\r\n ~~((worldCoordinate.x / halfTileWidth + (worldCoordinate.y / halfTileHeight)) / 2),\r\n ~~((worldCoordinate.y / halfTileHeight - (worldCoordinate.x / halfTileWidth)) / 2));\r\n }\r\n\r\n /**\r\n * Given a tile coordinate, return the top left corner in world space\r\n * @param tileCoordinate\r\n */\r\n public tileToWorld(tileCoordinate: Vector): Vector {\r\n const halfTileWidth = this.tileWidth / 2;\r\n const halfTileHeight = this.tileHeight / 2;\r\n // The x position shifts left with every y step\r\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\r\n // The y position needs to go down with every x step\r\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\r\n return vec(xPos, yPos).add(this.transform.pos);\r\n }\r\n\r\n /**\r\n * Returns the [[IsometricTile]] by its x and y coordinates\r\n */\r\n public getTile(x: number, y: number): IsometricTile | null {\r\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\r\n return null;\r\n }\r\n return this.tiles[x + y * this.columns];\r\n }\r\n\r\n /**\r\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */\r\n public getTileByPoint(point: Vector): IsometricTile | null {\r\n const tileCoord = this.worldToTile(point);\r\n const tile = this.getTile(tileCoord.x, tileCoord.y);\r\n return tile;\r\n }\r\n\r\n private _getMaxZIndex(): number {\r\n let maxZ = Number.NEGATIVE_INFINITY;\r\n for (const tile of this.tiles) {\r\n const currentZ = tile.get(TransformComponent).z;\r\n if (currentZ > maxZ) {\r\n maxZ = currentZ;\r\n }\r\n }\r\n return maxZ;\r\n }\r\n\r\n /**\r\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\r\n * @param gfx\r\n */\r\n public debug(gfx: ExcaliburGraphicsContext, debugFlags: DebugConfig) {\r\n const {\r\n showAll,\r\n showPosition,\r\n positionColor,\r\n positionSize,\r\n showGrid,\r\n gridColor,\r\n gridWidth,\r\n showColliderGeometry\r\n } = debugFlags.isometric;\r\n\r\n const {\r\n geometryColor,\r\n geometryLineWidth,\r\n geometryPointSize\r\n } = debugFlags.collider;\r\n gfx.save();\r\n gfx.z = this._getMaxZIndex() + 0.5;\r\n if (showAll || showGrid) {\r\n for (let y = 0; y < this.rows + 1; y++) {\r\n const left = this.tileToWorld(vec(0, y));\r\n const right = this.tileToWorld(vec(this.columns, y));\r\n gfx.drawLine(left, right, gridColor, gridWidth);\r\n }\r\n\r\n for (let x = 0; x < this.columns + 1; x++) {\r\n const top = this.tileToWorld(vec(x, 0));\r\n const bottom = this.tileToWorld(vec(x, this.rows));\r\n gfx.drawLine(top, bottom, gridColor, gridWidth);\r\n }\r\n }\r\n\r\n if (showAll || showPosition) {\r\n for (const tile of this.tiles) {\r\n gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), positionSize, positionColor);\r\n }\r\n }\r\n if (showAll || showColliderGeometry) {\r\n for (const tile of this.tiles) {\r\n if (tile.solid) { // only draw solid tiles\r\n for (const collider of tile.getColliders()) {\r\n collider.debug(gfx, geometryColor, { lineWidth: geometryLineWidth, pointSize: geometryPointSize });\r\n }\r\n }\r\n }\r\n }\r\n gfx.restore();\r\n }\r\n}","export * from './TileMap';\r\nexport * from './IsometricMap';\r\nexport * from './IsometricEntityComponent';\r\nexport * from './IsometricEntitySystem';","import { Entity } from '../../EntityComponentSystem';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\n/**\r\n * Action that can represent a sequence of actions, this can be useful in conjunction with\r\n * [[ParallelActions]] to run multiple sequences in parallel.\r\n */\r\nexport class ActionSequence implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _stopped: boolean = false;\r\n private _sequenceContext: ActionContext;\r\n private _sequenceBuilder: (actionContext: ActionContext) => any;\r\n constructor(entity: Entity, actionBuilder: (actionContext: ActionContext) => any) {\r\n this._sequenceBuilder = actionBuilder;\r\n this._sequenceContext = new ActionContext(entity);\r\n this._actionQueue = this._sequenceContext.getQueue();\r\n this._sequenceBuilder(this._sequenceContext);\r\n }\r\n\r\n public update(delta: number): void {\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._actionQueue.isComplete();\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._stopped = false;\r\n this._actionQueue.reset();\r\n }\r\n\r\n public clone(entity: Entity) {\r\n return new ActionSequence(entity, this._sequenceBuilder);\r\n }\r\n}","import { Entity } from '../../EntityComponentSystem';\r\nimport { Action } from '../Action';\r\n\r\n\r\n/**\r\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\r\n */\r\nexport class ParallelActions implements Action {\r\n private _actions: Action[];\r\n\r\n constructor(parallelActions: Action[]) {\r\n this._actions = parallelActions;\r\n }\r\n\r\n update(delta: number): void {\r\n for (let i = 0; i < this._actions.length; i++) {\r\n this._actions[i].update(delta);\r\n }\r\n }\r\n isComplete(entity: Entity): boolean {\r\n return this._actions.every(a => a.isComplete(entity));\r\n }\r\n reset(): void {\r\n this._actions.forEach(a => a.reset());\r\n }\r\n stop(): void {\r\n this._actions.forEach(a => a.stop());\r\n }\r\n}","export * from './ActionContext';\r\nexport * from './ActionQueue';\r\nexport * from './Actionable';\r\nexport * from './RotationType';\r\n\r\nexport * from './Action';\r\nexport * from './Action/ActionSequence';\r\nexport * from './Action/ParallelActions';\r\nexport * from './Action/Repeat';\r\nexport * from './Action/RepeatForever';\r\nexport * from './Action/Blink';\r\nexport * from './Action/Die';\r\nexport * from './Action/EaseTo';\r\nexport * from './Action/EaseBy';\r\nexport * from './Action/Fade';\r\nexport * from './Action/Follow';\r\nexport * from './Action/Meet';\r\nexport * from './Action/MoveBy';\r\nexport * from './Action/MoveTo';\r\nexport * from './Action/RotateBy';\r\nexport * from './Action/RotateTo';\r\nexport * from './Action/ScaleBy';\r\nexport * from './Action/ScaleTo';\r\nexport * from './Action/Delay';\r\n\r\nexport * from './ActionsComponent';\r\nexport * from './ActionsSystem';","import { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics';\r\nimport { BoundingBox } from '../BoundingBox';\r\n\r\nexport interface QuadTreeItem {\r\n bounds: BoundingBox;\r\n}\r\n\r\nexport interface QuadTreeOptions {\r\n maxDepth?: number;\r\n capacity: number;\r\n level?: number;\r\n}\r\n\r\n/**\r\n * QuadTree spatial data structure. Useful for quickly retrieving all objects that might\r\n * be in a specific location.\r\n */\r\nexport class QuadTree {\r\n private _defaultOptions: QuadTreeOptions = {\r\n maxDepth: 10,\r\n capacity: 10,\r\n level: 0\r\n };\r\n\r\n public halfWidth: number;\r\n public halfHeight: number;\r\n public items: TItem[] = [];\r\n private _isDivided = false;\r\n\r\n public topLeft: QuadTree | null = null;\r\n public topRight: QuadTree | null = null;\r\n public bottomLeft: QuadTree | null = null;\r\n public bottomRight: QuadTree | null = null;\r\n\r\n constructor(public bounds: BoundingBox, public options?: QuadTreeOptions) {\r\n this.options = {...this._defaultOptions, ...options};\r\n this.halfWidth = bounds.width / 2;\r\n this.halfHeight = bounds.height / 2;\r\n }\r\n\r\n /**\r\n * Splits the quad tree one level deeper\r\n */\r\n private _split() {\r\n this._isDivided = true;\r\n const newLevelOptions = {\r\n maxDepth: this.options.maxDepth,\r\n capacity: this.options.capacity,\r\n level: this.options.level + 1\r\n };\r\n this.topLeft = new QuadTree(\r\n new BoundingBox({\r\n left: this.bounds.left,\r\n top: this.bounds.top,\r\n right: this.bounds.left + this.halfWidth,\r\n bottom: this.bounds.top + this.halfHeight\r\n }), newLevelOptions);\r\n this.topRight = new QuadTree(\r\n new BoundingBox({\r\n left: this.bounds.left + this.halfWidth,\r\n top: this.bounds.top,\r\n right: this.bounds.right,\r\n bottom: this.bounds.top + this.halfHeight\r\n }), newLevelOptions);\r\n this.bottomLeft = new QuadTree(new BoundingBox({\r\n left: this.bounds.left,\r\n top: this.bounds.top + this.halfHeight,\r\n right: this.bounds.left + this.halfWidth,\r\n bottom: this.bounds.bottom\r\n }), newLevelOptions);\r\n this.bottomRight = new QuadTree(\r\n new BoundingBox({\r\n left: this.bounds.left + this.halfWidth,\r\n top: this.bounds.top + this.halfHeight,\r\n right: this.bounds.right,\r\n bottom: this.bounds.bottom\r\n }), newLevelOptions);\r\n }\r\n\r\n private _insertIntoSubNodes(item: TItem) {\r\n if (this.topLeft?.bounds.overlaps(item.bounds)) {\r\n this.topLeft.insert(item);\r\n }\r\n\r\n if (this.topRight?.bounds.overlaps(item.bounds)) {\r\n this.topRight.insert(item);\r\n }\r\n\r\n if (this.bottomLeft?.bounds.overlaps(item.bounds)) {\r\n this.bottomLeft.insert(item);\r\n }\r\n\r\n if (this.bottomRight?.bounds.overlaps(item.bounds)) {\r\n this.bottomRight.insert(item);\r\n }\r\n }\r\n\r\n /**\r\n * Insert an item to be tracked in the QuadTree\r\n * @param item\r\n */\r\n insert(item: TItem): void {\r\n // add to subnodes if it matches\r\n if (this._isDivided) {\r\n this._insertIntoSubNodes(item);\r\n return;\r\n }\r\n\r\n\r\n // leaf case\r\n this.items.push(item);\r\n\r\n // capacity\r\n if (this.items.length > this.options.capacity && this.options.level < this.options.maxDepth) {\r\n if (!this._isDivided) {\r\n this._split();\r\n }\r\n // divide this level's items into it's subnodes\r\n for (const item of this.items) {\r\n this._insertIntoSubNodes(item);\r\n }\r\n // clear this level\r\n this.items.length = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Remove a tracked item in the QuadTree\r\n * @param item\r\n */\r\n remove(item: TItem): void {\r\n if (!this.bounds.overlaps(item.bounds)) {\r\n return;\r\n }\r\n\r\n if (!this._isDivided) {\r\n const index = this.items.indexOf(item);\r\n if (index > -1) {\r\n this.items.splice(index, 1);\r\n }\r\n return;\r\n }\r\n\r\n if (this.topLeft?.bounds.overlaps(item.bounds)) {\r\n this.topLeft.remove(item);\r\n }\r\n\r\n if (this.topRight?.bounds.overlaps(item.bounds)) {\r\n this.topRight.remove(item);\r\n }\r\n\r\n if (this.bottomLeft?.bounds.overlaps(item.bounds)) {\r\n this.bottomLeft.remove(item);\r\n }\r\n\r\n if (this.bottomRight?.bounds.overlaps(item.bounds)) {\r\n this.bottomRight.remove(item);\r\n }\r\n }\r\n\r\n /**\r\n * Query the structure for all objects that intersect the bounding box\r\n * @param boundingBox\r\n * @returns items\r\n */\r\n query(boundingBox: BoundingBox): TItem[] {\r\n\r\n let results = this.items;\r\n\r\n if (this._isDivided) {\r\n if (this.topLeft.bounds.overlaps(boundingBox)) {\r\n results = results.concat(this.topLeft.query(boundingBox));\r\n }\r\n if (this.topRight.bounds.overlaps(boundingBox)) {\r\n results = results.concat(this.topRight.query(boundingBox));\r\n }\r\n if (this.bottomLeft.bounds.overlaps(boundingBox)) {\r\n results = results.concat(this.bottomLeft.query(boundingBox));\r\n }\r\n if (this.bottomRight.bounds.overlaps(boundingBox)) {\r\n results = results.concat(this.bottomRight.query(boundingBox));\r\n }\r\n }\r\n\r\n results = results.filter((item, index) => {\r\n return results.indexOf(item) >= index;\r\n });\r\n\r\n return results;\r\n }\r\n\r\n clear() {\r\n this.items = [];\r\n this._isDivided = false;\r\n\r\n this.topLeft = null;\r\n this.topRight = null;\r\n this.bottomLeft = null;\r\n this.bottomRight = null;\r\n }\r\n\r\n getAllItems(): TItem[] {\r\n let results = this.items;\r\n\r\n if (this._isDivided) {\r\n results = results.concat(this.topLeft.getAllItems());\r\n results = results.concat(this.topRight.getAllItems());\r\n results = results.concat(this.bottomLeft.getAllItems());\r\n results = results.concat(this.bottomRight.getAllItems());\r\n }\r\n\r\n results = results.filter((item, index) => {\r\n return results.indexOf(item) >= index;\r\n });\r\n\r\n return results;\r\n }\r\n\r\n getTreeDepth(): number {\r\n if (!this._isDivided) {\r\n return 0;\r\n }\r\n\r\n return 1 + Math.max(\r\n this.topLeft.getTreeDepth(),\r\n this.topRight.getTreeDepth(),\r\n this.bottomLeft.getTreeDepth(),\r\n this.bottomRight.getTreeDepth()\r\n );\r\n }\r\n\r\n debug(ctx: ExcaliburGraphicsContext) {\r\n this.bounds.draw(ctx, Color.Yellow);\r\n if (this._isDivided) {\r\n this.topLeft.bounds.draw(ctx, Color.Yellow);\r\n this.topRight.bounds.draw(ctx, Color.Yellow);\r\n this.bottomLeft.bounds.draw(ctx, Color.Yellow);\r\n this.bottomRight.bounds.draw(ctx, Color.Yellow);\r\n }\r\n }\r\n}","export * from './BodyComponent';\r\nexport * from './ColliderComponent';\r\nexport * from './CollisionType';\r\nexport * from './SolverStrategy';\r\n\r\nexport * from './Colliders/Collider';\r\nexport * from './BoundingBox';\r\n\r\nexport * from './Colliders/Shape';\r\nexport * from './Colliders/Collider';\r\nexport * from './Colliders/CompositeCollider';\r\nexport * from './Colliders/CircleCollider';\r\nexport * from './Colliders/EdgeCollider';\r\nexport * from './Colliders/PolygonCollider';\r\nexport * from './Colliders/CollisionJumpTable';\r\nexport * from './Colliders/ClosestLineJumpTable';\r\n\r\nexport * from './Group/CollisionGroup';\r\nexport * from './Group/CollisionGroupManager';\r\n\r\nexport * from './Detection/Pair';\r\nexport * from './Detection/CollisionContact';\r\nexport * from './Detection/RayCastHit';\r\nexport * from './Detection/CollisionProcessor';\r\nexport * from './Detection/DynamicTree';\r\nexport * from './Detection/DynamicTreeCollisionProcessor';\r\nexport * from './Detection/QuadTree';\r\n\r\nexport * from './Solver/ArcadeSolver';\r\nexport * from './Solver/ContactBias';\r\nexport * from './Solver/ContactConstraintPoint';\r\nexport * from './Solver/RealisticSolver';\r\nexport * from './Solver/Solver';\r\n\r\nexport * from './CollisionSystem';\r\nexport * from './MotionSystem';\r\n\r\nexport * from './PhysicsWorld';\r\nexport * from './PhysicsConfig';\r\nexport * from './Physics';\r\nexport * from './Side';\r\n","import { Engine } from './../Engine';\r\nimport * as Events from './../Events';\r\nimport { Scene } from '../Scene';\r\nimport { ExcaliburGraphicsContext } from '../Graphics';\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _initialize {\r\n _initialize(engine: Engine): void;\r\n}\r\n\r\n/**\r\n * Type guard checking for internal initialize method\r\n * @internal\r\n * @param a\r\n */\r\nexport function has_initialize(a: any): a is _initialize {\r\n return !!a._initialize;\r\n}\r\n\r\nexport interface OnInitialize {\r\n onInitialize(engine: Engine): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnInitialize(a: any): a is OnInitialize {\r\n return !!a.onInitialize;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _preupdate {\r\n _preupdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function has_preupdate(a: any): a is _preupdate {\r\n return !!a._preupdate;\r\n}\r\n\r\nexport interface OnPreUpdate {\r\n onPreUpdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnPreUpdate(a: any): a is OnPreUpdate {\r\n return !!a.onPreUpdate;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _postupdate {\r\n _postupdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function has_postupdate(a: any): a is _postupdate {\r\n return !!a.onPostUpdate;\r\n}\r\n\r\nexport interface OnPostUpdate {\r\n onPostUpdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnPostUpdate(a: any): a is OnPostUpdate {\r\n return !!a.onPostUpdate;\r\n}\r\n\r\nexport interface CanInitialize {\r\n /**\r\n * Overridable implementation\r\n */\r\n onInitialize(engine: Engine): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.initialize, handler: (event: Events.InitializeEvent) => void): void;\r\n once(eventName: Events.initialize, handler: (event: Events.InitializeEvent) => void): void;\r\n off(eventName: Events.initialize, handler?: (event: Events.InitializeEvent) => void): void;\r\n}\r\n\r\nexport interface SceneActivationContext {\r\n data?: TData;\r\n previousScene: Scene;\r\n nextScene: Scene;\r\n engine: Engine;\r\n}\r\n\r\nexport interface CanActivate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onActivate(context: SceneActivationContext): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.activate, handler: (event: Events.ActivateEvent) => void): void;\r\n once(eventName: Events.activate, handler: (event: Events.ActivateEvent) => void): void;\r\n off(eventName: Events.activate, handler?: (event: Events.ActivateEvent) => void): void;\r\n}\r\n\r\nexport interface CanDeactivate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onDeactivate(context: SceneActivationContext): void;\r\n\r\n /**\r\n * Event signature\r\n */\r\n on(eventName: Events.deactivate, handler: (event: Events.DeactivateEvent) => void): void;\r\n once(eventName: Events.deactivate, handler: (event: Events.DeactivateEvent) => void): void;\r\n off(eventName: Events.deactivate, handler?: (event: Events.DeactivateEvent) => void): void;\r\n}\r\n\r\nexport interface CanUpdate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreUpdate(engine: Engine, delta: number): void;\r\n\r\n /**\r\n * Event signature\r\n */\r\n on(eventName: Events.preupdate, handler: (event: Events.PreUpdateEvent) => void): void;\r\n once(eventName: Events.preupdate, handler: (event: Events.PreUpdateEvent) => void): void;\r\n off(eventName: Events.preupdate, handler?: (event: Events.PreUpdateEvent) => void): void;\r\n\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostUpdate(engine: Engine, delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postupdate, handler: (event: Events.PostUpdateEvent) => void): void;\r\n once(eventName: Events.postupdate, handler: (event: Events.PostUpdateEvent) => void): void;\r\n off(eventName: Events.postupdate, handler?: (event: Events.PostUpdateEvent) => void): void;\r\n}\r\n\r\nexport interface OnPreDraw {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreDraw(ctx: ExcaliburGraphicsContext, delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n once(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n off(eventName: Events.predraw, handler?: (event: Events.PreDrawEvent) => void): void;\r\n}\r\n\r\nexport interface OnPostDraw {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostDraw(ctx: ExcaliburGraphicsContext, delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n once(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n off(eventName: Events.postdraw, handler?: (event: Events.PostDrawEvent) => void): void;\r\n}\r\n\r\nexport interface CanDraw extends OnPreDraw, OnPostDraw {\r\n on(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n on(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n\r\n once(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n once(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n\r\n off(eventName: Events.predraw, handler?: (event: Events.PreDrawEvent) => void): void;\r\n off(eventName: Events.postdraw, handler?: (event: Events.PostDrawEvent) => void): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasPreDraw(a: any): a is OnPreDraw {\r\n return !!a.onPreDraw;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasPostDraw(a: any): a is OnPostDraw {\r\n return !!a.onPostDraw;\r\n}\r\n\r\nexport interface CanBeKilled {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreKill(_scene: Scene): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n once(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n off(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostKill(_scene: Scene): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n once(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n off(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n}\r\n","export * from './Clonable';\r\nexport * from './Audio';\r\nexport * from './AudioImplementation';\r\nexport * from './Evented';\r\nexport * from './Loadable';\r\nexport * from './LifecycleEvents';\r\nexport * from './PointerEventHandlers';\r\n","export * from './Sound';\r\nexport * from './AudioContext';\r\nexport * from './WebAudioInstance';\r\n","import { Resource } from './Resource';\r\nimport { Sprite } from '../Graphics/Sprite';\r\nimport { Color } from '../Color';\r\nimport { SpriteSheet } from '../Graphics/SpriteSheet';\r\nimport { Animation } from '../Graphics/Animation';\r\nimport { Loadable } from '../Interfaces/Index';\r\nimport { ImageSource } from '../Graphics/ImageSource';\r\nimport { range } from '../Math/util';\r\n/**\r\n * The [[Texture]] object allows games built in Excalibur to load image resources.\r\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\r\n * to pre-load before starting a level or game.\r\n */\r\nexport class Gif implements Loadable {\r\n private _resource: Resource;\r\n\r\n /**\r\n * The width of the texture in pixels\r\n */\r\n public width: number;\r\n\r\n /**\r\n * The height of the texture in pixels\r\n */\r\n public height: number;\r\n\r\n\r\n private _stream: Stream = null;\r\n private _gif: ParseGif = null;\r\n private _textures: ImageSource[] = [];\r\n private _animation: Animation = null;\r\n private _transparentColor: Color = null;\r\n\r\n public data: ImageSource[];\r\n\r\n /**\r\n * @param path Path to the image resource\r\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\r\n * @param bustCache Optionally load texture with cache busting\r\n */\r\n constructor(public path: string, public color: Color = Color.Magenta, bustCache = false) {\r\n this._resource = new Resource(path, 'arraybuffer', bustCache);\r\n this._transparentColor = color;\r\n }\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n /**\r\n * Begins loading the texture and returns a promise to be resolved on completion\r\n */\r\n public async load(): Promise {\r\n const arraybuffer = await this._resource.load();\r\n this._stream = new Stream(arraybuffer);\r\n this._gif = new ParseGif(this._stream, this._transparentColor);\r\n const images = this._gif.images.map(i => new ImageSource(i.src, false));\r\n\r\n // Load all textures\r\n await Promise.all(images.map(t => t.load()));\r\n return this.data = this._textures = images;\r\n }\r\n\r\n public isLoaded() {\r\n return !!this.data;\r\n }\r\n\r\n /**\r\n * Return a frame of the gif as a sprite by id\r\n * @param id\r\n */\r\n public toSprite(id: number = 0): Sprite {\r\n const sprite = this._textures[id].toSprite();\r\n return sprite;\r\n }\r\n\r\n /**\r\n * Return the gif as a spritesheet\r\n */\r\n public toSpriteSheet(): SpriteSheet {\r\n const sprites: Sprite[] = this._textures.map((image) => {\r\n return image.toSprite();\r\n });\r\n return new SpriteSheet({ sprites });\r\n }\r\n\r\n /**\r\n * Transform the GIF into an animation with duration per frame\r\n */\r\n public toAnimation(durationPerFrameMs: number): Animation {\r\n const spriteSheet: SpriteSheet = this.toSpriteSheet();\r\n const length = spriteSheet.sprites.length;\r\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\r\n return this._animation;\r\n }\r\n\r\n public get readCheckBytes(): number[] {\r\n return this._gif.checkBytes;\r\n }\r\n}\r\n\r\nexport interface GifFrame {\r\n sentinel: number;\r\n type: string;\r\n leftPos: number;\r\n topPos: number;\r\n width: number;\r\n height: number;\r\n lctFlag: boolean;\r\n interlaced: boolean;\r\n sorted: boolean;\r\n reserved: boolean[];\r\n lctSize: number;\r\n lzwMinCodeSize: number;\r\n pixels: number[];\r\n}\r\n\r\nconst bitsToNum = (ba: any) => {\r\n return ba.reduce(function (s: number, n: number) {\r\n return s * 2 + n;\r\n }, 0);\r\n};\r\n\r\nconst byteToBitArr = (bite: any) => {\r\n const a = [];\r\n for (let i = 7; i >= 0; i--) {\r\n a.push(!!(bite & (1 << i)));\r\n }\r\n return a;\r\n};\r\n\r\nexport class Stream {\r\n data: any = null;\r\n len: number = 0;\r\n position: number = 0;\r\n\r\n constructor(dataArray: ArrayBuffer) {\r\n this.data = new Uint8Array(dataArray);\r\n this.len = this.data.byteLength;\r\n if (this.len === 0) {\r\n throw new Error('No data loaded from file');\r\n }\r\n }\r\n\r\n public readByte = () => {\r\n if (this.position >= this.data.byteLength) {\r\n throw new Error('Attempted to read past end of stream.');\r\n }\r\n return this.data[this.position++];\r\n };\r\n\r\n public readBytes = (n: number) => {\r\n const bytes = [];\r\n for (let i = 0; i < n; i++) {\r\n bytes.push(this.readByte());\r\n }\r\n return bytes;\r\n };\r\n\r\n public read = (n: number) => {\r\n let s = '';\r\n for (let i = 0; i < n; i++) {\r\n s += String.fromCharCode(this.readByte());\r\n }\r\n return s;\r\n };\r\n\r\n public readUnsigned = () => {\r\n // Little-endian.\r\n const a = this.readBytes(2);\r\n return (a[1] << 8) + a[0];\r\n };\r\n}\r\n\r\nconst lzwDecode = function (minCodeSize: number, data: any) {\r\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\r\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\r\n\r\n const readCode = function (size: number) {\r\n let code = 0;\r\n for (let i = 0; i < size; i++) {\r\n if (data.charCodeAt(pos >> 3) & (1 << (pos & 7))) {\r\n code |= 1 << i;\r\n }\r\n pos++;\r\n }\r\n return code;\r\n };\r\n\r\n const output: any[] = [];\r\n\r\n const clearCode = 1 << minCodeSize;\r\n const eoiCode = clearCode + 1;\r\n\r\n let codeSize = minCodeSize + 1;\r\n\r\n let dict: any[] = [];\r\n\r\n const clear = function () {\r\n dict = [];\r\n codeSize = minCodeSize + 1;\r\n for (let i = 0; i < clearCode; i++) {\r\n dict[i] = [i];\r\n }\r\n dict[clearCode] = [];\r\n dict[eoiCode] = null;\r\n };\r\n\r\n let code;\r\n let last;\r\n\r\n while (true) {\r\n last = code;\r\n code = readCode(codeSize);\r\n if (code === clearCode) {\r\n clear();\r\n continue;\r\n }\r\n if (code === eoiCode) {\r\n break;\r\n }\r\n\r\n if (code < dict.length) {\r\n if (last !== clearCode) {\r\n dict.push(dict[last].concat(dict[code][0]));\r\n }\r\n } else {\r\n if (code !== dict.length) {\r\n throw new Error('Invalid LZW code.');\r\n }\r\n dict.push(dict[last].concat(dict[last][0]));\r\n }\r\n output.push.apply(output, dict[code]);\r\n\r\n if (dict.length === 1 << codeSize && codeSize < 12) {\r\n // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\r\n codeSize++;\r\n }\r\n }\r\n\r\n // I don't know if this is technically an error, but some GIFs do it.\r\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\r\n return output;\r\n};\r\n\r\n// The actual parsing; returns an object with properties.\r\nexport class ParseGif {\r\n private _st: Stream = null;\r\n private _handler: any = {};\r\n private _transparentColor: Color = null;\r\n public frames: GifFrame[] = [];\r\n public images: HTMLImageElement[] = [];\r\n public globalColorTable: any[] = [];\r\n public checkBytes: number[] = [];\r\n\r\n constructor(stream: Stream, color: Color = Color.Magenta) {\r\n this._st = stream;\r\n this._handler = {};\r\n this._transparentColor = color;\r\n this.parseHeader();\r\n this.parseBlock();\r\n }\r\n\r\n // LZW (GIF-specific)\r\n parseColorTable = (entries: any) => {\r\n // Each entry is 3 bytes, for RGB.\r\n const ct = [];\r\n for (let i = 0; i < entries; i++) {\r\n const rgb: number[] = this._st.readBytes(3);\r\n const rgba =\r\n '#' +\r\n rgb\r\n .map((x: any) => {\r\n const hex = x.toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n })\r\n .join('');\r\n ct.push(rgba);\r\n }\r\n return ct;\r\n };\r\n\r\n readSubBlocks = () => {\r\n let size, data;\r\n data = '';\r\n do {\r\n size = this._st.readByte();\r\n data += this._st.read(size);\r\n } while (size !== 0);\r\n return data;\r\n };\r\n\r\n parseHeader = () => {\r\n const hdr: any = {\r\n sig: null,\r\n ver: null,\r\n width: null,\r\n height: null,\r\n colorRes: null,\r\n globalColorTableSize: null,\r\n gctFlag: null,\r\n sorted: null,\r\n globalColorTable: [],\r\n bgColor: null,\r\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\r\n };\r\n\r\n hdr.sig = this._st.read(3);\r\n hdr.ver = this._st.read(3);\r\n if (hdr.sig !== 'GIF') {\r\n throw new Error('Not a GIF file.'); // XXX: This should probably be handled more nicely.\r\n }\r\n\r\n hdr.width = this._st.readUnsigned();\r\n hdr.height = this._st.readUnsigned();\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n hdr.gctFlag = bits.shift();\r\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\r\n hdr.sorted = bits.shift();\r\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\r\n\r\n hdr.bgColor = this._st.readByte();\r\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\r\n\r\n if (hdr.gctFlag) {\r\n hdr.globalColorTable = this.parseColorTable(1 << (hdr.globalColorTableSize + 1));\r\n this.globalColorTable = hdr.globalColorTable;\r\n }\r\n if (this._handler.hdr && this._handler.hdr(hdr)) {\r\n this.checkBytes.push(this._handler.hdr);\r\n }\r\n };\r\n\r\n parseExt = (block: any) => {\r\n const parseGCExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 4\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\r\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\r\n block.userInput = bits.shift();\r\n block.transparencyGiven = bits.shift();\r\n\r\n block.delayTime = this._st.readUnsigned();\r\n\r\n block.transparencyIndex = this._st.readByte();\r\n\r\n block.terminator = this._st.readByte();\r\n\r\n if (this._handler.gce && this._handler.gce(block)) {\r\n this.checkBytes.push(this._handler.gce);\r\n }\r\n };\r\n\r\n const parseComExt = (block: any) => {\r\n block.comment = this.readSubBlocks();\r\n if (this._handler.com && this._handler.com(block)) {\r\n this.checkBytes.push(this._handler.com);\r\n }\r\n };\r\n\r\n const parsePTExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 12\r\n block.ptHeader = this._st.readBytes(12);\r\n block.ptData = this.readSubBlocks();\r\n if (this._handler.pte && this._handler.pte(block)) {\r\n this.checkBytes.push(this._handler.pte);\r\n }\r\n };\r\n\r\n const parseAppExt = (block: any) => {\r\n const parseNetscapeExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 3\r\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\r\n block.iterations = this._st.readUnsigned();\r\n block.terminator = this._st.readByte();\r\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) {\r\n this.checkBytes.push(this._handler.app);\r\n }\r\n };\r\n\r\n const parseUnknownAppExt = (block: any) => {\r\n block.appData = this.readSubBlocks();\r\n // FIXME: This won't work if a handler wants to match on any identifier.\r\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) {\r\n this.checkBytes.push(this._handler.app[block.identifier]);\r\n }\r\n };\r\n\r\n this.checkBytes.push(this._st.readByte()); // Always 11\r\n block.identifier = this._st.read(8);\r\n block.authCode = this._st.read(3);\r\n switch (block.identifier) {\r\n case 'NETSCAPE':\r\n parseNetscapeExt(block);\r\n break;\r\n default:\r\n parseUnknownAppExt(block);\r\n break;\r\n }\r\n };\r\n\r\n const parseUnknownExt = (block: any) => {\r\n block.data = this.readSubBlocks();\r\n if (this._handler.unknown && this._handler.unknown(block)) {\r\n this.checkBytes.push(this._handler.unknown);\r\n }\r\n };\r\n\r\n block.label = this._st.readByte();\r\n switch (block.label) {\r\n case 0xf9:\r\n block.extType = 'gce';\r\n parseGCExt(block);\r\n break;\r\n case 0xfe:\r\n block.extType = 'com';\r\n parseComExt(block);\r\n break;\r\n case 0x01:\r\n block.extType = 'pte';\r\n parsePTExt(block);\r\n break;\r\n case 0xff:\r\n block.extType = 'app';\r\n parseAppExt(block);\r\n break;\r\n default:\r\n block.extType = 'unknown';\r\n parseUnknownExt(block);\r\n break;\r\n }\r\n };\r\n\r\n parseImg = (img: any) => {\r\n const deinterlace = (pixels: any, width: any) => {\r\n // Of course this defeats the purpose of interlacing. And it's *probably*\r\n // the least efficient way it's ever been implemented. But nevertheless...\r\n\r\n const newPixels = new Array(pixels.length);\r\n const rows = pixels.length / width;\r\n const cpRow = (toRow: any, fromRow: any) => {\r\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\r\n newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels));\r\n };\r\n\r\n const offsets = [0, 4, 2, 1];\r\n const steps = [8, 8, 4, 2];\r\n\r\n let fromRow = 0;\r\n for (let pass = 0; pass < 4; pass++) {\r\n for (let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) {\r\n cpRow(toRow, fromRow);\r\n fromRow++;\r\n }\r\n }\r\n\r\n return newPixels;\r\n };\r\n\r\n img.leftPos = this._st.readUnsigned();\r\n img.topPos = this._st.readUnsigned();\r\n img.width = this._st.readUnsigned();\r\n img.height = this._st.readUnsigned();\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n img.lctFlag = bits.shift();\r\n img.interlaced = bits.shift();\r\n img.sorted = bits.shift();\r\n img.reserved = bits.splice(0, 2);\r\n img.lctSize = bitsToNum(bits.splice(0, 3));\r\n\r\n if (img.lctFlag) {\r\n img.lct = this.parseColorTable(1 << (img.lctSize + 1));\r\n }\r\n\r\n img.lzwMinCodeSize = this._st.readByte();\r\n\r\n const lzwData = this.readSubBlocks();\r\n\r\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\r\n\r\n if (img.interlaced) {\r\n // Move\r\n img.pixels = deinterlace(img.pixels, img.width);\r\n }\r\n\r\n this.frames.push(img);\r\n this.arrayToImage(img);\r\n if (this._handler.img && this._handler.img(img)) {\r\n this.checkBytes.push(this._handler);\r\n }\r\n };\r\n\r\n public parseBlock = () => {\r\n const block = {\r\n sentinel: this._st.readByte(),\r\n type: ''\r\n };\r\n const blockChar = String.fromCharCode(block.sentinel);\r\n switch (blockChar) {\r\n case '!':\r\n block.type = 'ext';\r\n this.parseExt(block);\r\n break;\r\n case ',':\r\n block.type = 'img';\r\n this.parseImg(block);\r\n break;\r\n case ';':\r\n block.type = 'eof';\r\n if (this._handler.eof && this._handler.eof(block)) {\r\n this.checkBytes.push(this._handler.eof);\r\n }\r\n break;\r\n default:\r\n throw new Error('Unknown block: 0x' + block.sentinel.toString(16));\r\n }\r\n\r\n if (block.type !== 'eof') {\r\n this.parseBlock();\r\n }\r\n };\r\n\r\n arrayToImage = (frame: GifFrame) => {\r\n let count = 0;\r\n const c = document.createElement('canvas');\r\n c.id = count.toString();\r\n c.width = frame.width;\r\n c.height = frame.height;\r\n count++;\r\n const context = c.getContext('2d');\r\n const pixSize = 1;\r\n let y = 0;\r\n let x = 0;\r\n for (let i = 0; i < frame.pixels.length; i++) {\r\n if (x % frame.width === 0) {\r\n y++;\r\n x = 0;\r\n }\r\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) {\r\n context.fillStyle = `rgba(0, 0, 0, 0)`;\r\n } else {\r\n context.fillStyle = this.globalColorTable[frame.pixels[i]];\r\n }\r\n\r\n context.fillRect(x, y, pixSize, pixSize);\r\n x++;\r\n }\r\n const img = new Image();\r\n img.src = c.toDataURL();\r\n this.images.push(img);\r\n };\r\n}\r\n","import { Font } from '../Graphics/Font';\r\nimport { FontOptions } from '../Graphics/FontCommon';\r\nimport { GraphicOptions, RasterOptions } from '../Graphics';\r\nimport { Loadable } from '../Interfaces/Loadable';\r\nimport { Resource } from './Resource';\r\n\r\n\r\nexport interface FontSourceOptions\r\n extends Omit,\r\n GraphicOptions,\r\n RasterOptions {\r\n /**\r\n * Whether or not to cache-bust requests\r\n */\r\n bustCache?: boolean\r\n}\r\n\r\nexport class FontSource implements Loadable {\r\n private _resource: Resource;\r\n private _isLoaded = false;\r\n private _options: FontSourceOptions;\r\n\r\n data!: FontFace;\r\n\r\n\r\n constructor(\r\n /**\r\n * Path to the font resource relative from the HTML document hosting the game, or absolute\r\n */\r\n public readonly path: string,\r\n /**\r\n * The font family name\r\n */\r\n public readonly family: string,\r\n { bustCache, ...options }: FontSourceOptions = {}\r\n ) {\r\n this._resource = new Resource(path, 'blob', bustCache);\r\n this._options = options;\r\n }\r\n\r\n async load(): Promise {\r\n if (this.isLoaded()) {\r\n return this.data;\r\n }\r\n\r\n try {\r\n const blob = await this._resource.load();\r\n const url = URL.createObjectURL(blob);\r\n\r\n if (!this.data) {\r\n this.data = new FontFace(this.family, `url(${url})`);\r\n document.fonts.add(this.data);\r\n }\r\n\r\n await this.data.load();\r\n this._isLoaded = true;\r\n } catch (error) {\r\n throw `Error loading FontSource from path '${this.path}' with error [${\r\n (error as Error).message\r\n }]`;\r\n }\r\n return this.data;\r\n }\r\n\r\n isLoaded(): boolean {\r\n return this._isLoaded;\r\n }\r\n\r\n /**\r\n * Build a font from this FontSource.\r\n * @param options {FontOptions} Override the font options\r\n */\r\n toFont(options?: FontOptions): Font {\r\n return new Font({ family: this.family, ...this._options, ...options });\r\n }\r\n}\r\n","export * from './Resource';\r\nexport * from './Sound/Index';\r\nexport * from './Gif';\r\nexport * from './Font';","export * from './Component';\r\nexport * from './Entity';\r\nexport * from './EntityManager';\r\nexport * from './Query';\r\nexport * from './TagQuery';\r\nexport * from './QueryManager';\r\nexport * from './System';\r\nexport * from './SystemManager';\r\nexport * from './World';\r\nexport * from './Types';\r\nexport * from './Priority';\r\n\r\nexport * from './Components/TransformComponent';\r\nexport * from './Components/MotionComponent';\r\n","import { Engine } from '../Engine';\r\nexport type CoroutineGenerator = () => Generator, void, number>;\r\n\r\n/**\r\n * Excalibur coroutine helper, returns a promise when complete. Coroutines run before frame update.\r\n *\r\n * Each coroutine yield is 1 excalibur frame. Coroutines get passed the elapsed time our of yield. Coroutines\r\n * run internally on the excalibur clock.\r\n *\r\n * If you yield a promise it will be awaited before resumed\r\n * If you yield a number it will wait that many ms before resumed\r\n * @param engine\r\n * @param coroutineGenerator\r\n */\r\nexport function coroutine(engine: Engine, coroutineGenerator: CoroutineGenerator): Promise {\r\n return new Promise((resolve, reject) => {\r\n const generator = coroutineGenerator();\r\n const loop = (elapsedMs: number) => {\r\n try {\r\n const { done, value } = generator.next(elapsedMs);\r\n if (done) {\r\n resolve();\r\n }\r\n\r\n if (value instanceof Promise) {\r\n value.then(() => {\r\n // schedule next loop\r\n engine.clock.schedule(loop);\r\n });\r\n } else if (value === undefined || value === (void 0)) {\r\n // schedule next frame\r\n engine.clock.schedule(loop);\r\n } else {\r\n // schedule value milliseconds from now\r\n engine.clock.schedule(loop, value || 0);\r\n }\r\n } catch (e) {\r\n reject(e);\r\n }\r\n };\r\n loop(engine.clock.elapsed());// run first frame immediately\r\n });\r\n}","import { Engine } from '../Engine';\r\nimport { Scene } from '../Scene';\r\nimport { Future } from '../Util/Future';\r\nimport { Entity, TransformComponent } from '../EntityComponentSystem';\r\nimport { GraphicsComponent } from '../Graphics';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { Vector } from '../Math/vector';\r\nimport { clamp } from '../Math/util';\r\nimport { EasingFunction, EasingFunctions } from '../Util/EasingFunctions';\r\nimport { coroutine } from '../Util/Coroutine';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport interface TransitionOptions {\r\n /**\r\n * Transition duration in milliseconds\r\n */\r\n duration: number;\r\n\r\n /**\r\n * Optionally hides the loader during the transition\r\n *\r\n * If either the out or in transition have this set to true, then the loader will be hidden.\r\n *\r\n * Default false\r\n */\r\n hideLoader?: boolean;\r\n\r\n /**\r\n * Optionally blocks user input during a transition\r\n *\r\n * Default false\r\n */\r\n blockInput?: boolean;\r\n\r\n /**\r\n * Optionally specify a easing function, by default linear\r\n */\r\n easing?: EasingFunction;\r\n /**\r\n * Optionally specify a transition direction, by default 'out'\r\n *\r\n * * For 'in' direction transitions start at 1 and complete is at 0\r\n * * For 'out' direction transitions start at 0 and complete is at 1\r\n */\r\n direction?: 'out' | 'in';\r\n}\r\n\r\n/**\r\n * Base Transition that can be extended to provide custom scene transitions in Excalibur.\r\n */\r\nexport class Transition extends Entity {\r\n private _logger: Logger = Logger.getInstance();\r\n transform = new TransformComponent();\r\n graphics = new GraphicsComponent();\r\n readonly hideLoader: boolean;\r\n readonly blockInput: boolean;\r\n readonly duration: number;\r\n readonly easing: EasingFunction;\r\n readonly direction: 'out' | 'in';\r\n private _completeFuture = new Future();\r\n\r\n // State needs to be reset between uses\r\n public started = false;\r\n private _currentDistance: number = 0;\r\n private _currentProgress: number = 0;\r\n\r\n public done = this._completeFuture.promise;\r\n\r\n /**\r\n * Returns a number between [0, 1] indicating what state the transition is in.\r\n *\r\n * * For 'out' direction transitions start at 0 and end at 1\r\n * * For 'in' direction transitions start at 1 and end at 0\r\n */\r\n get progress(): number {\r\n return this._currentProgress;\r\n }\r\n\r\n get complete(): boolean {\r\n if (this.direction === 'out') {\r\n return this.progress >= 1;\r\n } else {\r\n return this.progress <= 0;\r\n }\r\n }\r\n\r\n constructor(options: TransitionOptions) {\r\n super();\r\n this.name = `Transition#${this.id}`;\r\n this.duration = options.duration;\r\n this.easing = options.easing ?? EasingFunctions.Linear;\r\n this.direction = options.direction ?? 'out';\r\n this.hideLoader = options.hideLoader ?? false;\r\n this.blockInput = options.blockInput ?? false;\r\n this.transform.coordPlane = CoordPlane.Screen;\r\n this.transform.pos = Vector.Zero;\r\n this.transform.z = Infinity; // Transitions sit on top of everything\r\n this.graphics.anchor = Vector.Zero;\r\n this.addComponent(this.transform);\r\n this.addComponent(this.graphics);\r\n\r\n if (this.direction === 'out') {\r\n this._currentProgress = 0;\r\n } else {\r\n this._currentProgress = 1;\r\n }\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called before each update.\r\n *\r\n * **WARNING BE SURE** to call `super.updateTransition()` if overriding in your own custom implementation\r\n * @param engine\r\n * @param delta\r\n */\r\n public updateTransition(engine: Engine, delta: number): void {\r\n if (this.complete) {\r\n return;\r\n }\r\n\r\n this._currentDistance += clamp(delta / this.duration, 0, 1);\r\n if (this._currentDistance >= 1) {\r\n this._currentDistance = 1;\r\n }\r\n\r\n if (this.direction === 'out') {\r\n this._currentProgress = clamp(this.easing(this._currentDistance, 0, 1, 1), 0, 1);\r\n } else {\r\n this._currentProgress = clamp(this.easing(this._currentDistance, 1, 0, 1), 0, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called right before the previous scene has deactivated.\r\n *\r\n * This gives incoming transition a chance to grab info from previous scene if desired\r\n * @param scene\r\n */\r\n async onPreviousSceneDeactivate(scene: Scene) {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called once at the beginning of the transition\r\n *\r\n * `progress` is given between 0 and 1\r\n * @param progress\r\n */\r\n onStart(progress: number) {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called every frame of the transition\r\n *\r\n * `progress` is given between 0 and 1\r\n * @param progress\r\n */\r\n onUpdate(progress: number) {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called at the end of the transition,\r\n *\r\n * `progress` is given between 0 and 1\r\n * @param progress\r\n */\r\n onEnd(progress: number) {\r\n // override me\r\n }\r\n\r\n /**\r\n * Overridable lifecycle method, called when the transition is reset\r\n *\r\n * Use this to override and provide your own reset logic for internal state in custom transition implementations\r\n */\r\n onReset() {\r\n // override me\r\n }\r\n\r\n /**\r\n * reset() is called by the engine to reset transitions\r\n */\r\n reset() {\r\n this.started = false;\r\n this._completeFuture = new Future();\r\n this.done = this._completeFuture.promise;\r\n this._currentDistance = 0;\r\n if (this.direction === 'out') {\r\n this._currentProgress = 0;\r\n } else {\r\n this._currentProgress = 1;\r\n }\r\n this.onReset();\r\n }\r\n\r\n play(engine: Engine) {\r\n if (this.started) {\r\n this._logger.warn(`Attempted to play a transition ${this.name} that is already playing`);\r\n return Promise.resolve();\r\n }\r\n\r\n engine.add(this);\r\n const self = this;\r\n return coroutine(engine, function * () {\r\n while (!self.complete) {\r\n const elapsed = yield; // per frame\r\n self.updateTransition(engine, elapsed);\r\n self.execute();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * execute() is called by the engine every frame to update the Transition lifecycle onStart/onUpdate/onEnd\r\n */\r\n execute() {\r\n if (!this.isInitialized) {\r\n return;\r\n }\r\n\r\n if (!this.started) {\r\n this.started = true;\r\n this.onStart(this.progress);\r\n }\r\n\r\n this.onUpdate(this.progress);\r\n\r\n if (this.complete && !this._completeFuture.isCompleted) {\r\n this.onEnd(this.progress);\r\n this._completeFuture.resolve();\r\n }\r\n }\r\n}","import { Engine } from '../Engine';\r\nimport { Color } from '../Color';\r\nimport { vec } from '../Math/vector';\r\nimport { Rectangle } from '../Graphics';\r\nimport { Transition, TransitionOptions } from './Transition';\r\n\r\nexport interface FadeOptions {\r\n duration?: number;\r\n color?: Color;\r\n}\r\n\r\nexport class FadeInOut extends Transition {\r\n screenCover: Rectangle;\r\n color: Color;\r\n constructor(options: FadeOptions & TransitionOptions) {\r\n super({\r\n ...options,\r\n duration: options.duration ?? 2000\r\n });\r\n this.name = `FadeInOut#${this.id}`;\r\n this.color = options.color ?? Color.Black;\r\n }\r\n\r\n public onInitialize(engine: Engine): void {\r\n const bounds = engine.screen.getWorldBounds();\r\n this.transform.pos = vec(bounds.left, bounds.top);\r\n this.screenCover = new Rectangle({\r\n width: bounds.width,\r\n height: bounds.height,\r\n color: this.color\r\n });\r\n this.graphics.add(this.screenCover);\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onReset() {\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onStart(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n\r\n override onEnd(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n\r\n override onUpdate(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n}","import { ImageSource, Sprite } from '../Graphics';\r\nimport { Engine } from '../Engine';\r\nimport { Scene } from '../Scene';\r\nimport { Transition, TransitionOptions } from './Transition';\r\nimport { vec } from '../Math/vector';\r\n\r\nexport interface CrossFadeOptions {\r\n duration: number;\r\n}\r\n\r\n/**\r\n * CrossFades between the previous scene and the destination scene\r\n *\r\n * Note: CrossFade only works as an \"in\" transition\r\n */\r\nexport class CrossFade extends Transition {\r\n engine: Engine;\r\n image: HTMLImageElement;\r\n screenCover: Sprite;\r\n constructor(options: TransitionOptions & CrossFadeOptions) {\r\n super({direction: 'in', ...options}); // default the correct direction\r\n this.name = `CrossFade#${this.id}`;\r\n }\r\n\r\n override async onPreviousSceneDeactivate(scene: Scene) {\r\n this.image = await scene.engine.screenshot(true);\r\n // Firefox is particularly slow\r\n // needed in case the image isn't ready yet\r\n await this.image.decode();\r\n }\r\n\r\n override onInitialize(engine: Engine): void {\r\n this.engine = engine;\r\n const bounds = engine.screen.getWorldBounds();\r\n this.transform.pos = vec(bounds.left, bounds.top);\r\n this.screenCover = ImageSource.fromHtmlImageElement(this.image).toSprite();\r\n this.graphics.add(this.screenCover);\r\n this.transform.scale = vec(1 / engine.screen.pixelRatio, 1 / engine.screen.pixelRatio);\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onStart(_progress: number): void {\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onReset() {\r\n this.graphics.opacity = this.progress;\r\n }\r\n\r\n override onEnd(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n\r\n override onUpdate(progress: number): void {\r\n this.graphics.opacity = progress;\r\n }\r\n}","\r\nexport * from './Transition';\r\nexport * from './FadeInOut';\r\nexport * from './CrossFade';\r\nexport * from './Director';\r\nexport * from './Loader';\r\nexport * from './DefaultLoader';","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Graphic } from './Graphic';\r\n\r\nexport interface LineOptions {\r\n start: Vector;\r\n end: Vector;\r\n color?: Color;\r\n thickness?: number;\r\n}\r\nexport class Line extends Graphic {\r\n readonly start: Vector;\r\n readonly end: Vector;\r\n color: Color = Color.Black;\r\n thickness: number = 1;\r\n private _localBounds: BoundingBox;\r\n constructor(options: LineOptions) {\r\n super();\r\n const { start, end, color, thickness } = options;\r\n this.start = start;\r\n this.end = end;\r\n this.color = color ?? this.color;\r\n this.thickness = thickness ?? this.thickness;\r\n this._localBounds = this._calculateBounds();\r\n const { width, height } = this._localBounds;\r\n\r\n this.width = width;\r\n this.height = height;\r\n }\r\n\r\n public get localBounds() {\r\n return this._localBounds;\r\n }\r\n\r\n private _calculateBounds(): BoundingBox {\r\n const lineNormal = this.end.sub(this.start).normal();\r\n\r\n const halfThickness = this.thickness / 2;\r\n\r\n const points = [\r\n this.start.add(lineNormal.scale(halfThickness)),\r\n this.end.add(lineNormal.scale(halfThickness)),\r\n this.end.add(lineNormal.scale(-halfThickness)),\r\n this.start.add(lineNormal.scale(-halfThickness))\r\n ];\r\n\r\n return BoundingBox.fromPoints(points);\r\n }\r\n\r\n protected _drawImage(ctx: ExcaliburGraphicsContext, _x: number, _y: number): void {\r\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\r\n }\r\n\r\n clone(): Line {\r\n return new Line({\r\n start: this.start,\r\n end: this.end,\r\n color: this.color,\r\n thickness: this.thickness\r\n });\r\n }\r\n}","import { ImageFiltering } from './Filtering';\r\nimport { Vector, vec } from '../Math/vector';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface PolygonOptions {\r\n points: Vector[];\r\n}\r\n\r\n/**\r\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Polygons default to [[ImageFiltering.Blended]]\r\n */\r\nexport class Polygon extends Raster {\r\n private _points: Vector[];\r\n public get points(): Vector[] {\r\n return this._points;\r\n }\r\n public set points(points: Vector[]) {\r\n this._points = points;\r\n const min = this.minPoint;\r\n this.width = this._points.reduce((max, p) => Math.max(p.x, max), 0) - min.x;\r\n this.height = this._points.reduce((max, p) => Math.max(p.y, max), 0) - min.y;\r\n this.flagDirty();\r\n }\r\n\r\n public get minPoint() {\r\n const minX = this._points.reduce((min, p) => Math.min(p.x, min), Infinity);\r\n const minY = this._points.reduce((min, p) => Math.min(p.y, min), Infinity);\r\n return vec(minX, minY);\r\n }\r\n\r\n constructor(options: RasterOptions & PolygonOptions) {\r\n super(options);\r\n this.points = options.points;\r\n this.filtering = ImageFiltering.Blended;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Polygon {\r\n return new Polygon({\r\n points: this.points.map((p) => p.clone()),\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.points && this.points.length) {\r\n ctx.beginPath();\r\n // Iterate through the supplied points and construct a 'polygon'\r\n const min = this.minPoint.negate();\r\n const firstPoint = this.points[0].add(min);\r\n ctx.moveTo(firstPoint.x, firstPoint.y);\r\n this.points.forEach((point) => {\r\n ctx.lineTo(point.x + min.x, point.y + min.y);\r\n });\r\n ctx.lineTo(firstPoint.x, firstPoint.y);\r\n ctx.closePath();\r\n if (this.color) {\r\n ctx.fill();\r\n }\r\n if (this.strokeColor) {\r\n ctx.stroke();\r\n }\r\n }\r\n }\r\n}\r\n","// Graphics\r\nexport * from './Graphic';\r\nexport * from './Sprite';\r\nexport * from './SpriteSheet';\r\nexport * from './GraphicsGroup';\r\nexport * from './ImageSource';\r\nexport * from './Animation';\r\nexport * from './Line';\r\n\r\n// Graphics ECS\r\nexport * from './GraphicsComponent';\r\nexport * from './DebugGraphicsComponent';\r\nexport * from './GraphicsSystem';\r\nexport * from './OffscreenSystem';\r\nexport * from './ParallaxComponent';\r\n\r\n// Raster graphics\r\nexport * from './Raster';\r\nexport * from './Circle';\r\nexport * from './Rectangle';\r\nexport * from './Polygon';\r\nexport * from './Text';\r\nexport * from './FontCommon';\r\nexport * from './Font';\r\nexport * from './FontCache';\r\nexport * from './SpriteFont';\r\nexport * from './Canvas';\r\n\r\nexport * from './Context/ExcaliburGraphicsContext';\r\nexport * from './Context/ExcaliburGraphicsContext2DCanvas';\r\nexport * from './Context/ExcaliburGraphicsContextWebGL';\r\n\r\nexport * from './Context/debug-text';\r\n\r\n// Post Processor\r\nexport * from './PostProcessor/PostProcessor';\r\nexport * from './PostProcessor/ScreenShader';\r\nexport * from './PostProcessor/ColorBlindnessMode';\r\nexport * from './PostProcessor/ColorBlindnessPostProcessor';\r\n\r\nexport * from './Context/texture-loader';\r\nexport * from './Filtering';\r\n\r\n\r\n// Rendering\r\nexport * from './Context/shader';\r\nexport * from './Context/vertex-buffer';\r\nexport * from './Context/vertex-layout';\r\nexport * from './Context/quad-index-buffer';\r\nexport * from './Context/material';\r\n\r\n// Debug\r\nexport * from './Debug';\r\n\r\n// Util\r\n\r\nimport * as webgl from './Context/webgl-util';\r\nexport { webgl };","// This import site is deprecated\r\n// TODO remove deprecated exports in v0.29.0\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.WheelEvent import site will be removed in v0.29.0, use ex.WheelEvent\r\n */\r\n WheelEvent\r\n} from './WheelEvent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerEvent import site will be removed in v0.29.0, use ex.PointerEvent\r\n */\r\n PointerEvent\r\n} from './PointerEvent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.WheelDeltaMode import site will be removed in v0.29.0, use ex.WheelDeltaMode\r\n */\r\n WheelDeltaMode\r\n} from './WheelDeltaMode';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerButton import site will be removed in v0.29.0, use ex.PointerButton\r\n */\r\n PointerButton\r\n} from './PointerButton';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.NativePointerButton import site will be removed in v0.29.0, use ex.NativePointerButton\r\n */\r\n NativePointerButton\r\n} from './NativePointerButton';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.CapturePointerConfig import site will be removed in v0.29.0, use ex.CapturePointerConfig\r\n */\r\n CapturePointerConfig\r\n} from './CapturePointerConfig';\r\n\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.NativePointerEvent import site will be removed in v0.29.0, use ex.NativePointerEvent\r\n */\r\n NativePointerEvent,\r\n /**\r\n * @deprecated ex.Input.NativeMouseEvent import site will be removed in v0.29.0, use ex.NativeMouseEvent\r\n */\r\n NativeMouseEvent,\r\n /**\r\n * @deprecated ex.Input.NativeTouchEvent import site will be removed in v0.29.0, use ex.NativeTouchEvent\r\n */\r\n NativeTouchEvent,\r\n /**\r\n * @deprecated ex.Input.NativeWheelEvent import site will be removed in v0.29.0, use ex.NativeWheelEvent\r\n */\r\n NativeWheelEvent,\r\n /**\r\n * @deprecated ex.Input.PointerInitOptions import site will be removed in v0.29.0, use ex.PointerInitOptions\r\n */\r\n PointerInitOptions,\r\n /**\r\n * @deprecated ex.Input.PointerEventReceiver import site will be removed in v0.29.0, use ex.PointerEventReceiver\r\n */\r\n PointerEventReceiver\r\n} from './PointerEventReceiver';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerComponent import site will be removed in v0.29.0, use ex.PointerComponent\r\n */\r\n PointerComponent\r\n} from './PointerComponent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerSystem import site will be removed in v0.29.0, use ex.PointerSystem\r\n */\r\n PointerSystem\r\n} from './PointerSystem';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerType import site will be removed in v0.29.0, use ex.PointerType\r\n */\r\n PointerType\r\n} from './PointerType';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerScope import site will be removed in v0.29.0, use ex.PointerScope\r\n */\r\n PointerScope\r\n} from './PointerScope';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.Keys import site will be removed in v0.29.0, use ex.Keys\r\n */\r\n Keys,\r\n /**\r\n * @deprecated ex.Input.KeyEvent import site will be removed in v0.29.0, use ex.KeyEvent\r\n */\r\n KeyEvent,\r\n /**\r\n * @deprecated ex.Input.KeyboardInitOptions import site will be removed in v0.29.0, use ex.KeyboardInitOptions\r\n */\r\n KeyboardInitOptions,\r\n /**\r\n * @deprecated ex.Input.Keyboard import site will be removed in v0.29.0, use ex.Keyboard\r\n */\r\n Keyboard\r\n} from './Keyboard';\r\n\r\n// Re-export hack to deprecate import site gently\r\nexport {\r\n /**\r\n * @deprecated ex.Input.Gamepads import site will be removed in v0.29.0, use ex.Gamepads\r\n */\r\n Gamepads,\r\n /**\r\n * @deprecated ex.Input.Gamepad import site will be removed in v0.29.0, use ex.Gamepad\r\n */\r\n Gamepad,\r\n /**\r\n * @deprecated ex.Input.Buttons import site will be removed in v0.29.0, use ex.Buttons\r\n */\r\n Buttons,\r\n /**\r\n * @deprecated ex.Input.Axes import site will be removed in v0.29.0, use ex.Axes\r\n */\r\n Axes,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepads import site will be removed in v0.29.0, use ex.NavigatorGamepads\r\n */\r\n NavigatorGamepads,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepad import site will be removed in v0.29.0, use ex.NavigatorGamepad\r\n */\r\n NavigatorGamepad,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepadButton import site will be removed in v0.29.0, use ex.NavigatorGamepadButton\r\n */\r\n NavigatorGamepadButton,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepadEvent import site will be removed in v0.29.0, use ex.NavigatorGamepadEvent\r\n */\r\n NavigatorGamepadEvent,\r\n /**\r\n * @deprecated ex.Input.GamepadConfiguration import site will be removed in v0.29.0, use ex.GamepadConfiguration\r\n */\r\n GamepadConfiguration\r\n} from './Gamepad';","export * from './Util';\r\n\r\nexport * from './Log';\r\n\r\nexport * from './Observable';\r\n\r\nexport * from './EasingFunctions';\r\n\r\nimport * as drawUtil from './DrawUtil';\r\nexport { drawUtil as DrawUtil };\r\n","import { Flags } from '../Flags';\r\nimport { Logger } from './Log';\r\n\r\n/**\r\n * Obsolete decorator options\r\n */\r\nexport interface ObsoleteOptions {\r\n // Optionally specify a custom message\r\n message?: string;\r\n // Optionally indicate that an alternate method to the obsolete one exists\r\n alternateMethod?: string;\r\n // Optional show stack trace, by default off\r\n showStackTrace?: boolean;\r\n}\r\n\r\nexport const maxMessages = 5;\r\nconst obsoleteMessage: { [messageCount: string]: number } = {};\r\nexport const resetObsoleteCounter = () => {\r\n for (const message in obsoleteMessage) {\r\n obsoleteMessage[message] = 0;\r\n }\r\n};\r\n\r\nconst logMessage = (message: string, options: ObsoleteOptions) => {\r\n const suppressObsoleteMessages = Flags.isEnabled('suppress-obsolete-message');\r\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\r\n Logger.getInstance().warn(message);\r\n\r\n // tslint:disable-next-line: no-console\r\n if (console.trace && options.showStackTrace) {\r\n // tslint:disable-next-line: no-console\r\n console.trace();\r\n }\r\n }\r\n obsoleteMessage[message]++;\r\n};\r\n\r\n/**\r\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\r\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\r\n */\r\nexport function obsolete(options?: ObsoleteOptions): any {\r\n options = {\r\n message: 'This feature will be removed in future versions of Excalibur.',\r\n alternateMethod: null,\r\n showStackTrace: false,\r\n ...options\r\n };\r\n\r\n return function (target: any, property: string, descriptor: PropertyDescriptor): any {\r\n if (\r\n descriptor &&\r\n !(typeof descriptor.value === 'function' || typeof descriptor.get === 'function' || typeof descriptor.set === 'function')\r\n ) {\r\n throw new SyntaxError('Only classes/functions/getters/setters can be marked as obsolete');\r\n }\r\n const methodSignature = `${target.name || ''}${target.name && property ? '.' : ''}${property ? property : ''}`;\r\n\r\n const message =\r\n `${methodSignature} is marked obsolete: ${options.message}` +\r\n (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : '');\r\n\r\n if (!obsoleteMessage[message]) {\r\n obsoleteMessage[message] = 0;\r\n }\r\n\r\n // If descriptor is null it is a class\r\n const method = descriptor ? { ...descriptor } : target;\r\n if (!descriptor) {\r\n // with es2015 classes we need to change our decoration tactic\r\n class DecoratedClass extends method {\r\n constructor(...args: any) {\r\n logMessage(message, options);\r\n super(...args);\r\n }\r\n }\r\n return DecoratedClass;\r\n }\r\n\r\n if (descriptor && descriptor.value) {\r\n method.value = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.value.apply(this, arguments);\r\n };\r\n return method;\r\n }\r\n\r\n if (descriptor && descriptor.get) {\r\n method.get = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.get.apply(this, arguments);\r\n };\r\n }\r\n\r\n if (descriptor && descriptor.set) {\r\n method.set = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.set.apply(this, arguments);\r\n };\r\n }\r\n return method;\r\n };\r\n}\r\n","import { Future } from './Future';\r\n\r\nclass AsyncWaitQueue {\r\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\r\n private _queue: Future[] = [];\r\n\r\n public get length(): number {\r\n return this._queue.length;\r\n }\r\n\r\n public enqueue(): Promise {\r\n const future = new Future();\r\n this._queue.push(future);\r\n return future.promise;\r\n }\r\n\r\n public dequeue(value: T): void {\r\n const future = this._queue.shift();\r\n future.resolve(value);\r\n }\r\n}\r\n\r\n/**\r\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\r\n *\r\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\r\n * around browser limitations like max Image.decode() calls in chromium being 256.\r\n */\r\nexport class Semaphore {\r\n private _waitQueue = new AsyncWaitQueue();\r\n constructor(private _count: number) { }\r\n\r\n public get count() {\r\n return this._count;\r\n }\r\n\r\n public get waiting() {\r\n return this._waitQueue.length;\r\n }\r\n\r\n // eslint-disable-next-line require-await\r\n public async enter() {\r\n if (this._count !== 0) {\r\n this._count--;\r\n return Promise.resolve();\r\n }\r\n return this._waitQueue.enqueue();\r\n }\r\n\r\n public exit(count: number = 1) {\r\n if (count === 0) {\r\n return;\r\n }\r\n while (count !== 0 && this._waitQueue.length !== 0) {\r\n this._waitQueue.dequeue(null);\r\n count--;\r\n }\r\n this._count += count;\r\n }\r\n}","/**\r\n * The current Excalibur version string\r\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\r\n */\r\nexport const EX_VERSION = process.env.__EX_VERSION;\r\nimport { polyfill } from './Polyfill';\r\npolyfill();\r\n\r\n// This file is used as the bundle entry point and exports everything\r\n// that will be exposed as the `ex` global variable.\r\nexport * from './Flags';\r\nexport * from './Id';\r\nexport * from './Engine';\r\nexport * from './Screen';\r\nexport { Actor, ActorArgs } from './Actor';\r\nexport * from './Math/Index';\r\nexport * from './Camera';\r\nexport * from './Configurable';\r\nexport * from './Debug/index';\r\nexport * from './EventDispatcher';\r\nexport * from './EventEmitter';\r\nexport * from './Events/MediaEvents';\r\nexport * from './Events';\r\nexport * from './Label';\r\nexport { FontStyle, FontUnit, TextAlign, BaseAlign } from './Graphics/FontCommon';\r\nexport { Particle, ParticleTransform, ParticleEmitter, ParticleArgs, ParticleEmitterArgs, EmitterType } from './Particles';\r\nexport * from './Collision/Physics';\r\nexport * from './Scene';\r\n\r\nexport * from './TileMap/index';\r\n\r\nexport * from './Timer';\r\nexport * from './Trigger';\r\nexport * from './ScreenElement';\r\n\r\nexport * from './Actions/Index';\r\nexport * from './Collision/Index';\r\n\r\nexport * from './Interfaces/Index';\r\nexport * from './Resources/Index';\r\n\r\nexport * from './EntityComponentSystem/index';\r\n\r\nexport * from './Director/index';\r\n\r\nexport * from './Color';\r\n\r\nexport * from './Graphics/index';\r\n\r\n// ex.Events namespace\r\nimport * as events from './Events';\r\nexport { events as Events };\r\n\r\n// ex.Input namespace\r\n// TODO deprecated import site remove in v0.29.0\r\nimport * as input from './Input/Index';\r\nexport { input as Input };\r\n\r\nexport {\r\n WheelEvent\r\n} from './Input/WheelEvent';\r\n\r\nexport {\r\n PointerEvent\r\n} from './Input/PointerEvent';\r\n\r\nexport {\r\n WheelDeltaMode\r\n} from './Input/WheelDeltaMode';\r\n\r\nexport {\r\n PointerButton\r\n} from './Input/PointerButton';\r\n\r\nexport {\r\n NativePointerButton\r\n} from './Input/NativePointerButton';\r\n\r\nexport {\r\n CapturePointerConfig\r\n} from './Input/CapturePointerConfig';\r\n\r\n\r\nexport {\r\n NativePointerEvent,\r\n NativeMouseEvent,\r\n NativeTouchEvent,\r\n NativeWheelEvent,\r\n PointerInitOptions,\r\n PointerEventReceiver\r\n} from './Input/PointerEventReceiver';\r\n\r\nexport { PointerAbstraction } from './Input/PointerAbstraction';\r\nexport { PointerComponent } from './Input/PointerComponent';\r\nexport { PointerSystem } from './Input/PointerSystem';\r\nexport { PointerType } from './Input/PointerType';\r\nexport { PointerScope } from './Input/PointerScope';\r\n\r\nexport {\r\n Gamepads,\r\n Gamepad,\r\n Buttons,\r\n Axes,\r\n NavigatorGamepads,\r\n NavigatorGamepad,\r\n NavigatorGamepadButton,\r\n NavigatorGamepadEvent,\r\n GamepadConfiguration\r\n} from './Input/Gamepad';\r\n\r\nexport {\r\n Keys,\r\n KeyEvent,\r\n KeyboardInitOptions,\r\n Keyboard\r\n} from './Input/Keyboard';\r\nexport * from './Input/InputHost';\r\nexport * from './Input/InputMapper';\r\n\r\n// ex.Util namespaces\r\nimport * as util from './Util/Index';\r\nexport { util as Util };\r\n\r\nexport * from './Util/Browser';\r\nexport * from './Util/Decorators';\r\nexport * from './Util/Detector';\r\nexport * from './Util/EasingFunctions';\r\nexport * from './Util/Observable';\r\nexport * from './Util/Log';\r\nexport * from './Util/Pool';\r\nexport * from './Util/Fps';\r\nexport * from './Util/Clock';\r\nexport * from './Util/WebAudio';\r\nexport * from './Util/Toaster';\r\nexport * from './Util/StateMachine';\r\nexport * from './Util/Future';\r\nexport * from './Util/Semaphore';\r\nexport * from './Util/Coroutine';\r\n\r\n// ex.Deprecated\r\n// import * as deprecated from './Deprecated';\r\n// export { deprecated as Deprecated };\r\n// export * from './Deprecated';\r\n","\nimport * as ex from \"excalibur\";\nimport { Player } from './player';\nimport { Resources, loader } from \"./resources\";\n\nconst game = new ex.Engine({\n resolution: {\n width: 256,\n height: 256,\n },\n viewport: {\n width: 256 * 4,\n height: 256 * 4\n },\n suppressPlayButton: true,\n pixelArt: true,\n pixelRatio: 4,\n});\n\ngame.start(loader).then(() => {\n console.log('Game start!');\n\n Resources.LdtkResource.registerEntityIdentifierFactory('PlayerStart', (props) => {\n const player = new Player({\n name: 'player',\n anchor: ex.vec(props.entity.__pivot[0],props.entity.__pivot[1]),\n width: props.entity.width,\n height: props.entity.height,\n pos: props.worldPos,\n z: props.layer.order\n });\n game.currentScene.camera.strategy.lockToActor(player);\n return player;\n });\n // Resources.LdtkResource.getLevel('Level_0')?.layers\n // Provide a type to the plugin to use for a specific entity identifier\n // Player.ts\n Resources.LdtkResource.addToScene(game.currentScene, {\n pos: ex.vec(0, 0),\n // levelFilter: ['Level_0']\n });\n});","import * as ex from 'excalibur';\nimport { Resources } from './resources';\nimport { Config } from './config';\n\nexport class Player extends ex.Actor {\n constructor(args: ex.ActorArgs) {\n super({\n ...args,\n collisionType: ex.CollisionType.Active\n })\n }\n\n onInitialize(engine: ex.Engine): void {\n const playerSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.HeroSpriteSheetPng as ex.ImageSource,\n grid: {\n spriteWidth: 16,\n spriteHeight: 16,\n rows: 8,\n columns: 8\n }\n });\n\n const leftIdle = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 1) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 1) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 1) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 1) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('left-idle', leftIdle);\n\n const rightIdle = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 2) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 2) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 2) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 2) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('right-idle', rightIdle);\n\n\n const upIdle = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 3) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 3) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 3) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 3) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('up-idle', upIdle);\n\n const downIdle = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 0) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 0) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 0) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 0) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('down-idle', downIdle);\n\n const leftWalk = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 5) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 5) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 5) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 5) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n })\n this.graphics.add('left-walk', leftWalk);\n\n const rightWalk = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 6) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 6) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 6) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 6) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n });\n this.graphics.add('right-walk', rightWalk);\n\n const upWalk = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 7) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 7) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 7) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 7) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n });\n this.graphics.add('up-walk', upWalk);\n\n const downWalk = new ex.Animation({\n frames: [\n {graphic: playerSpriteSheet.getSprite(0, 4) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(1, 4) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(2, 4) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n {graphic: playerSpriteSheet.getSprite(3, 4) as ex.Sprite, duration: Config.PlayerFrameSpeed},\n ]\n });\n this.graphics.add('down-walk', downWalk);\n }\n\n onPreUpdate(engine: ex.Engine, elapsedMs: number): void {\n this.vel = ex.Vector.Zero;\n\n this.graphics.use('down-idle');\n if (engine.input.keyboard.isHeld(ex.Input.Keys.ArrowRight)) {\n this.vel = ex.vec(Config.PlayerSpeed, 0);\n this.graphics.use('right-walk');\n }\n if (engine.input.keyboard.isHeld(ex.Input.Keys.ArrowLeft)) {\n this.vel = ex.vec(-Config.PlayerSpeed, 0);\n this.graphics.use('left-walk');\n }\n if (engine.input.keyboard.isHeld(ex.Input.Keys.ArrowUp)) {\n this.vel = ex.vec(0, -Config.PlayerSpeed);\n this.graphics.use('up-walk');\n }\n if (engine.input.keyboard.isHeld(ex.Input.Keys.ArrowDown)) {\n this.vel = ex.vec(0, Config.PlayerSpeed);\n this.graphics.use('down-walk');\n }\n\n }\n}","import { ImageFiltering, ImageSource, Loader } from \"excalibur\";\nimport { LdtkResource } from '@excaliburjs/plugin-ldtk';\nimport heroImgPath from '../res/Solaria Demo Pack Update 03/Solaria Demo Pack Update 03/16x16/Sprites/Hero 01.png';\nimport tilesetPath from '../res/Solaria Demo Pack Update 03/Solaria Demo Pack Update 03/16x16/Tilesets/Solaria Demo Update 01.png';\nimport ldtkLevel0 from '../res/top-down/Level_0.ldtkl';\nimport ldtkLevel1 from '../res/top-down/Level_1.ldtkl';\nimport ldtkPath from '../res/top-down.ldtk';\n\nexport const Resources = {\n HeroSpriteSheetPng: new ImageSource(heroImgPath, false, ImageFiltering.Pixel),\n LdtkResource: new LdtkResource(ldtkPath, {\n useTilemapCameraStrategy: true,\n useMapBackgroundColor: true,\n // Path map intercepts and redirects to work around parcel's static bundling\n pathMap: [\n { path: 'Hero 01.png', output: heroImgPath },\n { path: 'Level_0.ldtkl', output: ldtkLevel0 },\n { path: 'Level_1.ldtkl', output: ldtkLevel1 },\n { path: 'Solaria Demo Update 01.png', output: tilesetPath },\n ]\n })\n} as const;\n\n\nexport const loader = new Loader();\nfor (let resource of Object.values(Resources)) {\n loader.addResource(resource);\n}","!function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t(require(\"excalibur\")):\"function\"==typeof define&&define.amd?define([\"excalibur\"],t):\"object\"==typeof exports?exports.ex=t(require(\"excalibur\")):(e.ex=e.ex||{},e.ex.Plugin=e.ex.Plugin||{},e.ex.Plugin.Ldtk=t(e.ex))}(self,(e=>(()=>{\"use strict\";var t={445:(e,t,s)=>{s.r(t),s.d(t,{compare:()=>u,compareVersions:()=>l,satisfies:()=>f,validate:()=>m,validateStrict:()=>y});const r=/^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i,i=e=>{if(\"string\"!=typeof e)throw new TypeError(\"Invalid argument expected string\");const t=e.match(r);if(!t)throw new Error(`Invalid argument not valid semver ('${e}' received)`);return t.shift(),t},a=e=>\"*\"===e||\"x\"===e||\"X\"===e,n=e=>{const t=parseInt(e,10);return isNaN(t)?e:t},o=(e,t)=>{if(a(e)||a(t))return 0;const[s,r]=((e,t)=>typeof e!=typeof t?[String(e),String(t)]:[e,t])(n(e),n(t));return s>r?1:s{for(let s=0;s{const s=i(e),r=i(t),a=s.pop(),n=r.pop(),o=d(s,r);return 0!==o?o:a&&n?d(a.split(\".\"),n.split(\".\")):a||n?a?-1:1:0},u=(e,t,s)=>{h(s);const r=l(e,t);return c[s].includes(r)},c={\">\":[1],\">=\":[0,1],\"=\":[0],\"<=\":[-1,0],\"<\":[-1],\"!=\":[-1,1]},p=Object.keys(c),h=e=>{if(\"string\"!=typeof e)throw new TypeError(\"Invalid operator type, expected string but got \"+typeof e);if(-1===p.indexOf(e))throw new Error(`Invalid operator, expected one of ${p.join(\"|\")}`)},f=(e,t)=>{if((t=t.replace(/([><=]+)\\s+/g,\"$1\")).includes(\"||\"))return t.split(\"||\").some((t=>f(e,t)));if(t.includes(\" - \")){const[s,r]=t.split(\" - \",2);return f(e,`>=${s} <=${r}`)}if(t.includes(\" \"))return t.trim().replace(/\\s{2,}/g,\" \").split(\" \").every((t=>f(e,t)));const s=t.match(/^([<>=~^]+)/),r=s?s[1]:\"=\";if(\"^\"!==r&&\"~\"!==r)return u(e,t,r);const[a,n,o,,l]=i(e),[c,p,h,,m]=i(t),y=[a,n,o],_=[c,null!=p?p:\"x\",null!=h?h:\"x\"];if(m){if(!l)return!1;if(0!==d(y,_))return!1;if(-1===d(l.split(\".\"),m.split(\".\")))return!1}const v=_.findIndex((e=>\"0\"!==e))+1,g=\"~\"===r?2:v>1?v:1;return 0===d(y.slice(0,g),_.slice(0,g))&&-1!==d(y.slice(g),_.slice(g))},m=e=>\"string\"==typeof e&&/^[v\\d]/.test(e)&&r.test(e),y=e=>\"string\"==typeof e&&/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/.test(e)},961:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.EntityLayer=void 0;const r=s(205);t.EntityLayer=class{constructor(e,t,s,i){var a,n;if(this.ldtkLayer=t,this.resource=s,this.order=i,this.entities=[],this.ldtkToEntity=new Map,this.entityToLdtk=new Map,this.worldPos=(0,r.vec)(e.ldtkLevel.worldX,e.ldtkLevel.worldY),this.offset=(0,r.vec)(t.__pxTotalOffsetX,t.__pxTotalOffsetY),t.entityInstances)for(let e of t.entityInstances){const t=s.projectMetadata.defs.entities.find((t=>t.identifier===e.__identifier));if(s.factories.has(e.__identifier)){const i=s.factories.get(e.__identifier);if(i){const s=i({type:e.__identifier,worldPos:(0,r.vec)(e.px[0],e.px[1]).add(this.worldPos.add(this.offset)),entity:e,definition:t,layer:this});s&&(this.entities.push(s),this.ldtkToEntity.set(e,s),this.entityToLdtk.set(s,e))}}else{const o=new r.Actor({name:e.__identifier,pos:(0,r.vec)(e.px[0],e.px[1]).add(this.worldPos.add(this.offset)),width:e.width,height:e.height,anchor:(0,r.vec)(null!==(a=null==t?void 0:t.pivotX)&&void 0!==a?a:0,null!==(n=null==t?void 0:t.pivotY)&&void 0!==n?n:0),z:i});if(e.__tile){const t=s.tilesets.get(e.__tile.tilesetUid);if(t){const s=Math.floor(e.__tile.x/e.__tile.w),r=Math.floor(e.__tile.y/e.__tile.h),i=t.spritesheet.getSprite(s,r);i&&o.graphics.use(i)}}this.entities.push(o),this.ldtkToEntity.set(e,o),this.entityToLdtk.set(o,e)}}}runFactory(e){if(this.resource.factories.has(e)&&this.ldtkLayer.entityInstances)for(let e of this.ldtkLayer.entityInstances){const t=this.resource.projectMetadata.defs.entities.find((t=>t.identifier===e.__identifier)),s=this.resource.factories.get(e.__identifier);if(s){const i=s({type:e.__identifier,worldPos:(0,r.vec)(e.px[0],e.px[1]).add(this.worldPos.add(this.offset)),entity:e,definition:t,layer:this});if(i){const t=this.ldtkToEntity.get(e);if(t){const s=this.entities.indexOf(t);s>-1&&(this.entities.splice(s,1),this.ldtkToEntity.delete(e),this.entityToLdtk.delete(t))}return this.entities.push(i),this.ldtkToEntity.set(e,i),this.entityToLdtk.set(i,e),i}}}}getEntitiesByIdentifier(e){const t=this.getLdtkEntitiesByIdentifier(e);let s=[];for(const e of t){const t=this.ldtkToEntity.get(e);t&&s.push(t)}return s}getEntitiesByField(e,t){const s=this.getLdtkEntitiesByField(e,t);let r=[];for(const e of s){const t=this.ldtkToEntity.get(e);t&&r.push(t)}return r}getLdtkEntitiesByIdentifier(e){return this.ldtkLayer.entityInstances.filter((t=>t.__identifier.toLocaleLowerCase()===e.toLowerCase()))}getLdtkEntitiesByField(e,t){return this.ldtkLayer.entityInstances.filter((s=>{if(void 0!==t){let r=t;\"string\"==typeof t&&(r=t.toLocaleLowerCase());const i=s.fieldInstances.find((t=>t.__identifier.toLocaleLowerCase()===e.toLocaleLowerCase()));return!!i&&i.__value===r}return!!s.fieldInstances.find((t=>t.__identifier.toLocaleLowerCase()===e.toLocaleLowerCase()))}))}}},710:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.FetchLoader=void 0,t.FetchLoader=async(e,t)=>{const s=await fetch(e);switch(t.toLowerCase()){case\"xml\":default:return await s.text();case\"json\":return await s.json()}}},607:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s);var i=Object.getOwnPropertyDescriptor(t,s);i&&!(\"get\"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,r,i)}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__exportStar||function(e,t){for(var s in e)\"default\"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)};Object.defineProperty(t,\"__esModule\",{value:!0}),i(s(398),t),i(s(961),t),i(s(710),t),i(s(920),t),i(s(515),t),i(s(512),t),i(s(289),t),i(s(32),t),i(s(692),t),i(s(245),t),i(s(699),t)},920:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.IntGridLayer=void 0;const r=s(205);t.IntGridLayer=class{constructor(e,t,s,i){if(this.order=i,this.worldPos=(0,r.vec)(e.ldtkLevel.worldX,e.ldtkLevel.worldY),this.offset=(0,r.vec)(t.__pxTotalOffsetX,t.__pxTotalOffsetY),this.ldtkLayer=t,t.intGridCsv.length){const e=t.__cHei,i=t.__cWid;this.tilemap=new r.TileMap({name:t.__identifier,pos:this.worldPos.add(this.offset),tileWidth:t.__gridSize,tileHeight:t.__gridSize,rows:e,columns:i});const a=s.projectMetadata.defs.layers.find((e=>t.__identifier===e.identifier));if(a){const e=a.intGridValues.find((e=>{var t;return\"solid\"===(null===(t=null==e?void 0:e.identifier)||void 0===t?void 0:t.toLocaleLowerCase())}));for(let s=0;s{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LdtkResource=void 0;const r=s(692),i=s(32),a=s(710),n=s(699),o=s(445),d=s(289),l=s(205),u=s(515),c=s(245),p=s(512),h=s(961),f=s(920);class m{constructor(e,t){this.path=e,this.tilesets=new Map,this.levels=new Map,this.levelsByName=new Map,this.factories=new Map,this.fileLoader=a.FetchLoader,this._imageLoader=new d.LoaderCache(l.ImageSource),this._levelLoader=new d.LoaderCache(u.LevelResource),this.startZIndex=0,this.textQuality=4,this.useExcaliburWiring=!0,this.useMapBackgroundColor=!1,this.useTilemapCameraStrategy=!1,this.headless=!1,this.strict=!0;const{useExcaliburWiring:s,useTilemapCameraStrategy:r,entityIdentifierFactories:i,pathMap:n,useMapBackgroundColor:o,fileLoader:c,strict:p,headless:h,startZIndex:f}={...t};this.strict=null!=p?p:this.strict,this.headless=null!=h?h:this.headless,this.useExcaliburWiring=null!=s?s:this.useExcaliburWiring,this.useTilemapCameraStrategy=null!=r?r:this.useTilemapCameraStrategy,this.useMapBackgroundColor=null!=o?o:this.useMapBackgroundColor,this.startZIndex=null!=f?f:this.startZIndex,this.fileLoader=null!=c?c:this.fileLoader,this.pathMap=n;for(const e in i)this.registerEntityIdentifierFactory(e,i[e])}async load(){var e;const t=await this.fileLoader(this.path,\"json\");if(this.strict)try{this.projectMetadata=n.LdtkProjectMetadata.parse(t)}catch(e){throw console.error(`Could not parse LDtk map from location ${this.path}.\\nExcalibur only supports the latest version of LDtk formats as of the plugin's release.`),console.error(\"Is your map file corrupted or being interpreted as the wrong type?\"),e}else this.projectMetadata=t;(0,o.compare)(m.supportedLdtkVersion,null!==(e=this.projectMetadata.jsonVersion)&&void 0!==e?e:\"0.0.0\",\">\")&&console.warn(`The excalibur ldtk plugin officially supports ${m.supportedLdtkVersion}+, the current map has LDtk version ${this.projectMetadata.jsonVersion}`);for(let e of this.projectMetadata.defs.tilesets)if(e.relPath){const t=(0,i.pathRelativeToBase)(this.path,e.relPath,this.pathMap),s=this._imageLoader.getOrAdd(t),r=new c.Tileset({image:s,ldtkTileset:e});this.tilesets.set(e.uid,r)}else\"Internal_Icons\"!==e.identifier&&console.warn(`No tileset image provided for ${e.identifier}`);for(let e of this.projectMetadata.levels)if(e.externalRelPath){const t=(0,i.pathRelativeToBase)(this.path,e.externalRelPath,this.pathMap);this._levelLoader.getOrAdd(t,this,{headless:this.headless,strict:this.strict,fileLoader:this.fileLoader,imageLoader:this._imageLoader,pathMap:this.pathMap})}else{const t=new p.Level(e,this);this.levels.set(e.uid,t),this.levelsByName.set(e.identifier,t)}return await Promise.all([this._imageLoader.load(),this._levelLoader.load()]),this._levelLoader.values().forEach((e=>{this.levels.set(e.data.ldtkLevel.uid,e.data),this.levelsByName.set(e.data.ldtkLevel.identifier,e.data)})),this.data=this.projectMetadata}isLoaded(){return!!this.data}registerEntityIdentifierFactory(e,t){if(this.factories.set(e,t),this.isLoaded())for(let t of this.getEntityLayers())t.runFactory(e)}getLevel(e){return this.levelsByName.get(e)}getEntityLayers(e){let t=[];if(e){const s=this.getLevel(e);if(s)for(let e of s.layers)e instanceof h.EntityLayer&&t.push(e)}else for(const e of this.levels.values())for(let s of e.layers)s instanceof h.EntityLayer&&t.push(s);return t}getTileLayers(e){let t=[];if(e){const s=this.getLevel(e);if(s)for(let e of s.layers)e instanceof r.TileLayer&&t.push(e)}else for(const e of this.levels.values())for(let s of e.layers)s instanceof r.TileLayer&&t.push(s);return t}getIntGridLayers(e){let t=[];if(e){const s=this.getLevel(e);if(s)for(let e of s.layers)e instanceof f.IntGridLayer&&t.push(e)}else for(const e of this.levels.values())for(let s of e.layers)s instanceof f.IntGridLayer&&t.push(s);return t}getLdtkEntitiesByIdentifier(e){let t=[];const s=this.getEntityLayers();for(let r of s)t=t.concat(r.getLdtkEntitiesByIdentifier(e));return t}getLdtkEntitiesByField(e,t){let s=[];const r=this.getEntityLayers();for(let i of r)s=s.concat(i.getLdtkEntitiesByField(e,t));return s}addToScene(e,t){var s,i;const{pos:a,useLevelOffsets:n}={pos:(0,l.vec)(0,0),useLevelOffsets:!0,...t};for(let[i,o]of this.levels.entries())if(!(null===(s=null==t?void 0:t.levelFilter)||void 0===s?void 0:s.length)||t.levelFilter.includes(o.ldtkLevel.identifier))for(let t of o.layers)if(t instanceof r.TileLayer||t instanceof f.IntGridLayer)t.tilemap.pos=t.tilemap.pos.add(a),n||(t.tilemap.pos=t.tilemap.pos.sub(t.worldPos)),e.add(t.tilemap);else for(let s of t.entities){const r=s.get(l.TransformComponent);r&&(r.pos=r.pos.add(a),n||(r.pos=r.pos.sub(t.worldPos))),e.add(s)}if(this.useExcaliburWiring){const t=this.getLdtkEntitiesByField(\"camera\",!0)[0];if(t){e.camera.pos=(0,l.vec)(t.px[0],t.px[0]);const s=t.fieldInstances.find((e=>\"zoom\"===e.__identifier.toLocaleLowerCase()));s&&(e.camera.zoom=+s.__value)}}if(this.useTilemapCameraStrategy){let t=new l.BoundingBox;for(const e of this.levels.values()){const s=this.getTileLayers(e.ldtkLevel.identifier)[0];s&&(t=t.combine(l.BoundingBox.fromDimension(s.tilemap.tileWidth*s.tilemap.columns,s.tilemap.tileHeight*s.tilemap.rows,l.Vector.Zero,s.tilemap.pos)))}e.camera.strategy.limitCameraBounds(t)}if(this.useMapBackgroundColor)for(let[s,r]of this.levels.entries())if(!(null===(i=null==t?void 0:t.levelFilter)||void 0===i?void 0:i.length)||t.levelFilter.includes(r.ldtkLevel.identifier)){e.backgroundColor=r.backgroundColor;break}}}t.LdtkResource=m,m.supportedLdtkVersion=\"1.5.3\"},515:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LevelResource=void 0;const r=s(205),i=s(289),a=s(710),n=s(512),o=s(699);t.LevelResource=class{constructor(e,t,s){this.path=e,this.resource=t,this.fileLoader=a.FetchLoader,this.strict=!0,this.headless=!1;const{headless:n,strict:o,fileLoader:d,imageLoader:l,pathMap:u}={...s};this.fileLoader=null!=d?d:this.fileLoader,this.strict=null!=o?o:this.strict,this.headless=null!=n?n:this.headless,this.imageLoader=null!=l?l:new i.LoaderCache(r.ImageSource),this.pathMap=null!=u?u:this.pathMap}async load(){const e=await this.fileLoader(this.path,\"json\");let t;if(this.strict)try{t=o.LdtkLevel.parse(e)}catch(e){throw console.error(`Could not parse LDtk level data at ${this.path} are you sure a level is there and not corrupt?`),e}else t=e;return this.data=new n.Level(t,this.resource)}isLoaded(){return!!this.data}}},512:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Level=void 0;const r=s(205),i=s(961),a=s(920),n=s(692);t.Level=class{constructor(e,t){var s,o,d;if(this.ldtkLevel=e,this.resource=t,this.layers=[],e.__bgColor&&(this.backgroundColor=r.Color.fromHex(e.__bgColor)),e.layerInstances){let r=t.startZIndex,l=e.layerInstances.slice().reverse();for(let e of l)0!==(null===(s=e.entityInstances)||void 0===s?void 0:s.length)&&this.layers.push(new i.EntityLayer(this,e,t,r)),0!==(null===(o=e.gridTiles)||void 0===o?void 0:o.length)&&this.layers.push(new n.TileLayer(this,e,t,r)),0!==(null===(d=e.intGridCsv)||void 0===d?void 0:d.length)&&this.layers.push(new a.IntGridLayer(this,e,t,r)),r++}}}},289:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LoaderCache=void 0,t.LoaderCache=class{constructor(e){this.type=e,this._loaded=!1,this.cache=new Map}getOrAdd(...e){let t=this.cache.get(e.join(\"+\"));return t||(t=new this.type(...e),this.cache.set(e.join(\"+\"),t),t)}values(){if(this._loaded)return Array.from(this.cache.values());throw new Error(\"Read through cache not yet loaded! No values to return!\")}async load(){const e=Array.from(this.cache.entries()),t=await Promise.allSettled(e.map((e=>e[1].load())));let s=0;for(let r=0;r{function s(e,t){for(const{path:s,output:r}of t)if(\"string\"==typeof s){if(e.includes(s))return r}else{const t=e.match(s);if(t)return r.replace(\"[match]\",t[0])}return e}function r(e,t){if(!t)return!1;for(const{path:s,output:r}of t)if(\"string\"==typeof s){if(e.includes(s))return!0}else if(e.match(s))return!0;return!1}Object.defineProperty(t,\"__esModule\",{value:!0}),t.pathRelativeToBase=t.pathInMap=t.mapPath=t.filenameFromPath=void 0,t.filenameFromPath=function(e){const t=e.match(/[^/\\\\&\\?]+\\.\\w{2,4}(?=([\\#\\?&].*$|$))/gi);if(t)return t[0];throw new Error(`Could not locate filename from path: ${e}`)},t.mapPath=s,t.pathInMap=r,t.pathRelativeToBase=function(e,t,i){if(r(t,i)&&i)return s(t,i);if(0===t.indexOf(\"/\"))return t;const a=e.split(\"/\"),n=t.split(\"/\");return a[a.length-1].includes(\".\")&&a.pop(),a.concat(n).join(\"/\")}},692:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.TileLayer=void 0;const r=s(205);t.TileLayer=class{constructor(e,t,s,i){this.order=i,this.worldPos=(0,r.vec)(e.ldtkLevel.worldX,e.ldtkLevel.worldY),this.offset=(0,r.vec)(t.__pxTotalOffsetX,t.__pxTotalOffsetY),this.ldtkLayer=t,this.tilemap=new r.TileMap({name:t.__identifier,pos:this.worldPos.add(this.offset),tileWidth:t.__gridSize,tileHeight:t.__gridSize,rows:t.__cHei,columns:t.__cWid}),this.tilemap.z=i;for(let e of t.gridTiles){const r=Math.floor(e.px[0]/t.__gridSize),i=Math.floor(e.px[1]/t.__gridSize),a=this.tilemap.getTile(r,i);if(t.__tilesetDefUid){const r=s.tilesets.get(t.__tilesetDefUid);if(r){const t=Math.floor(e.src[0]/r.ldtkTileset.tileGridSize),s=Math.floor(e.src[1]/r.ldtkTileset.tileGridSize),i=r.spritesheet.getSprite(t,s);i?a.addGraphic(i):console.error(\"Could not find sprite in LDtk spritesheet at\",t,s)}}else console.error(\"Could not tileset in LDtk\",t.__tilesetDefUid,t.__tilesetRelPath)}}}},245:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.Tileset=void 0;const r=s(205);t.Tileset=class{constructor(e){const{image:t,ldtkTileset:s}=e;this.image=t,this.ldtkTileset=s,this.spritesheet=r.SpriteSheet.fromImageSource({image:t,grid:{rows:s.pxHei/s.tileGridSize,columns:s.pxWid/s.tileGridSize,spriteHeight:s.tileGridSize,spriteWidth:s.tileGridSize}})}}},699:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.LdtkProjectMetadata=t.LdtkEntityDefinition=t.LdtkLayerDefinition=t.LdtkLevel=t.LdtkLayerInstance=t.LdtkEntityInstance=void 0;const r=s(754),i=r.z.object({h:r.z.number(),tilesetUid:r.z.number(),w:r.z.number(),x:r.z.number(),y:r.z.number()}),a=r.z.tuple([r.z.number(),r.z.number()]),n=r.z.object({__identifier:r.z.string(),__tile:i.nullable(),__type:r.z.string(),__value:r.z.any(),defUid:r.z.number()}),o=r.z.object({a:r.z.number(),f:r.z.number(),px:a,src:a,t:r.z.number()});t.LdtkEntityInstance=r.z.object({__grid:a,__identifier:r.z.string(),__pivot:a,__smartColor:r.z.string(),__tags:r.z.array(r.z.string()),__tile:i.nullable(),__worldX:r.z.number().nullable(),__worldY:r.z.number().nullable(),defUid:r.z.number(),fieldInstances:r.z.array(n),height:r.z.number(),iid:r.z.string(),px:a,width:r.z.number()}),t.LdtkLayerInstance=r.z.object({__cHei:r.z.number(),__cWid:r.z.number(),__gridSize:r.z.number(),__identifier:r.z.string(),__opacity:r.z.number(),__pxTotalOffsetX:r.z.number(),__pxTotalOffsetY:r.z.number(),__tilesetDefUid:r.z.number().nullable(),__tilesetRelPath:r.z.string().nullable(),__type:r.z.union([r.z.literal(\"IntGrid\"),r.z.literal(\"Entities\"),r.z.literal(\"Tiles\"),r.z.literal(\"AutoLayer\")]),autoLayerTiles:r.z.array(o),entityInstances:r.z.array(t.LdtkEntityInstance),gridTiles:r.z.array(o),iid:r.z.string(),intGridCsv:r.z.array(r.z.number()),layerDefUid:r.z.number(),levelId:r.z.number(),overrideTilesetUid:r.z.number().nullable(),pxOffsetX:r.z.number(),pxOffsetY:r.z.number(),visible:r.z.boolean()}),t.LdtkLevel=r.z.object({__bgColor:r.z.string().nullable(),bgColor:r.z.string().nullable(),__bgPos:r.z.object({cropRect:r.z.array(r.z.tuple([r.z.number(),r.z.number(),r.z.number(),r.z.number()])),scale:r.z.tuple([r.z.number(),r.z.number()]),topLeftPx:a}).nullable(),__neighbours:r.z.array(r.z.object({dir:r.z.union([r.z.literal(\"n\"),r.z.literal(\"s\"),r.z.literal(\"w\"),r.z.literal(\"e\"),r.z.literal(\"ne\"),r.z.literal(\"nw\"),r.z.literal(\"se\"),r.z.literal(\"sw\"),r.z.literal(\"o\"),r.z.literal(\"<\"),r.z.literal(\">\")]),levelIid:r.z.string()})),bgRelPath:r.z.string().nullable(),externalRelPath:r.z.string().nullable(),fieldInstances:r.z.array(n),identifier:r.z.string(),iid:r.z.string(),layerInstances:r.z.array(t.LdtkLayerInstance).nullable(),pxHei:r.z.number(),pxWid:r.z.number(),uid:r.z.number(),worldDepth:r.z.number(),worldX:r.z.number(),worldY:r.z.number()});const d=r.z.object({identifier:r.z.string(),iid:r.z.string(),levels:r.z.array(t.LdtkLevel),worldGridHeight:r.z.number(),worldGridWidth:r.z.number(),worldLayout:r.z.union([r.z.literal(\"Free\"),r.z.literal(\"GridVania\"),r.z.literal(\"LinearHorizontal\"),r.z.literal(\"LinearVertical\")])}),l=r.z.object({color:r.z.number(),id:r.z.string(),tileRect:i.nullable()}),u=r.z.object({externalRelPath:r.z.string().nullable(),iconTilesetUid:r.z.number().nullable(),identifier:r.z.string(),tags:r.z.array(r.z.string()),uid:r.z.number(),values:r.z.array(l)}),c=r.z.object({__cHei:r.z.number(),__cWid:r.z.number(),customData:r.z.array(r.z.object({data:r.z.string(),tileId:r.z.number()})),embedAtlas:r.z.string().nullable(),enumsTags:r.z.optional(r.z.array(r.z.object({enumValueId:r.z.string(),tileIds:r.z.array(r.z.number())}))),identifier:r.z.string(),padding:r.z.number(),pxHei:r.z.number(),pxWid:r.z.number(),relPath:r.z.string().nullable(),spacing:r.z.number(),tags:r.z.array(r.z.string()),tagsSourceEnumUid:r.z.number().nullable(),tileGridSize:r.z.number(),uid:r.z.number()});t.LdtkLayerDefinition=r.z.object({__type:r.z.union([r.z.literal(\"IntGrid\"),r.z.literal(\"Entities\"),r.z.literal(\"Tiles\"),r.z.literal(\"AutoLayer\")]),autoSourceLayerDefUid:r.z.number().nullable(),displayOpacity:r.z.number(),gridSize:r.z.number(),identifier:r.z.string(),intGridValues:r.z.array(r.z.object({color:r.z.string(),groupUid:r.z.number(),identifier:r.z.string().nullable(),tile:i.nullable(),value:r.z.number()})),intGridValuesGroups:r.z.array(r.z.object({color:r.z.string().nullable(),identifier:r.z.string().nullable(),uid:r.z.number()})),parallaxFactorX:r.z.number(),parallaxFactorY:r.z.number(),parallaxScaling:r.z.boolean(),pxOffsetX:r.z.number(),pxOffsetY:r.z.number(),tilesetDefUid:r.z.number().nullable(),uid:r.z.number()}),t.LdtkEntityDefinition=r.z.object({color:r.z.string(),height:r.z.number(),identifier:r.z.string(),nineSliceBorders:r.z.array(r.z.number()),pivotX:r.z.number(),pivotY:r.z.number(),tileRect:i.nullable(),tileRenderMode:r.z.union([r.z.literal(\"Cover\"),r.z.literal(\"FitInside\"),r.z.literal(\"Repeat\"),r.z.literal(\"Stretch\"),r.z.literal(\"FullSizeCropped\"),r.z.literal(\"FullSizeUncropped\"),r.z.literal(\"NineSlice\")]),tilesetId:r.z.number().nullable(),uiTileRect:i.nullable(),uid:r.z.number(),width:r.z.number()});const p=r.z.object({tilesets:r.z.array(c),enums:r.z.array(u),layers:r.z.array(t.LdtkLayerDefinition),entities:r.z.array(t.LdtkEntityDefinition)});t.LdtkProjectMetadata=r.z.object({iid:r.z.string(),bgColor:r.z.string().nullable(),defs:p,externalLevels:r.z.boolean(),jsonVersion:r.z.string(),levels:r.z.array(t.LdtkLevel),toc:r.z.array(r.z.object({identifier:r.z.string(),instancesData:r.z.array(r.z.object({fields:r.z.any(),heiPx:r.z.number(),iids:r.z.string(),widPix:r.z.number(),worldX:r.z.number(),worldY:r.z.number()}))})),worldGridHeight:r.z.number().nullable(),worldGridWidth:r.z.number().nullable(),worldLayout:r.z.union([r.z.literal(\"Free\"),r.z.literal(\"GridVania\"),r.z.literal(\"LinearHorizontal\"),r.z.literal(\"LinearVertical\")]).nullable(),worlds:r.z.array(d)})},280:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ZodError=t.quotelessJson=t.ZodIssueCode=void 0;const r=s(110);t.ZodIssueCode=r.util.arrayToEnum([\"invalid_type\",\"invalid_literal\",\"custom\",\"invalid_union\",\"invalid_union_discriminator\",\"invalid_enum_value\",\"unrecognized_keys\",\"invalid_arguments\",\"invalid_return_type\",\"invalid_date\",\"invalid_string\",\"too_small\",\"too_big\",\"invalid_intersection_types\",\"not_multiple_of\",\"not_finite\"]),t.quotelessJson=e=>JSON.stringify(e,null,2).replace(/\"([^\"]+)\":/g,\"$1:\");class i extends Error{constructor(e){super(),this.issues=[],this.addIssue=e=>{this.issues=[...this.issues,e]},this.addIssues=(e=[])=>{this.issues=[...this.issues,...e]};const t=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,t):this.__proto__=t,this.name=\"ZodError\",this.issues=e}get errors(){return this.issues}format(e){const t=e||function(e){return e.message},s={_errors:[]},r=e=>{for(const i of e.issues)if(\"invalid_union\"===i.code)i.unionErrors.map(r);else if(\"invalid_return_type\"===i.code)r(i.returnTypeError);else if(\"invalid_arguments\"===i.code)r(i.argumentsError);else if(0===i.path.length)s._errors.push(t(i));else{let e=s,r=0;for(;re.message)){const t={},s=[];for(const r of this.issues)r.path.length>0?(t[r.path[0]]=t[r.path[0]]||[],t[r.path[0]].push(e(r))):s.push(e(r));return{formErrors:s,fieldErrors:t}}get formErrors(){return this.flatten()}}t.ZodError=i,i.create=e=>new i(e)},996:function(e,t,s){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.getErrorMap=t.setErrorMap=t.defaultErrorMap=void 0;const i=r(s(325));t.defaultErrorMap=i.default;let a=i.default;t.setErrorMap=function(e){a=e},t.getErrorMap=function(){return a}},349:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[s]}})}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__exportStar||function(e,t){for(var s in e)\"default\"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)};Object.defineProperty(t,\"__esModule\",{value:!0}),i(s(996),t),i(s(187),t),i(s(116),t),i(s(110),t),i(s(433),t),i(s(280),t)},762:(e,t)=>{var s;Object.defineProperty(t,\"__esModule\",{value:!0}),t.errorUtil=void 0,(s=t.errorUtil||(t.errorUtil={})).errToObj=e=>\"string\"==typeof e?{message:e}:e||{},s.toString=e=>\"string\"==typeof e?e:null==e?void 0:e.message},187:function(e,t,s){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.isAsync=t.isValid=t.isDirty=t.isAborted=t.OK=t.DIRTY=t.INVALID=t.ParseStatus=t.addIssueToContext=t.EMPTY_PATH=t.makeIssue=void 0;const i=s(996),a=r(s(325));t.makeIssue=e=>{const{data:t,path:s,errorMaps:r,issueData:i}=e,a=[...s,...i.path||[]],n={...i,path:a};let o=\"\";const d=r.filter((e=>!!e)).slice().reverse();for(const e of d)o=e(n,{data:t,defaultError:o}).message;return{...i,path:a,message:i.message||o}},t.EMPTY_PATH=[],t.addIssueToContext=function(e,s){const r=(0,t.makeIssue)({issueData:s,data:e.data,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,(0,i.getErrorMap)(),a.default].filter((e=>!!e))});e.common.issues.push(r)};class n{constructor(){this.value=\"valid\"}dirty(){\"valid\"===this.value&&(this.value=\"dirty\")}abort(){\"aborted\"!==this.value&&(this.value=\"aborted\")}static mergeArray(e,s){const r=[];for(const i of s){if(\"aborted\"===i.status)return t.INVALID;\"dirty\"===i.status&&e.dirty(),r.push(i.value)}return{status:e.value,value:r}}static async mergeObjectAsync(e,t){const s=[];for(const e of t)s.push({key:await e.key,value:await e.value});return n.mergeObjectSync(e,s)}static mergeObjectSync(e,s){const r={};for(const i of s){const{key:s,value:a}=i;if(\"aborted\"===s.status)return t.INVALID;if(\"aborted\"===a.status)return t.INVALID;\"dirty\"===s.status&&e.dirty(),\"dirty\"===a.status&&e.dirty(),\"__proto__\"===s.value||void 0===a.value&&!i.alwaysSet||(r[s.value]=a.value)}return{status:e.value,value:r}}}t.ParseStatus=n,t.INVALID=Object.freeze({status:\"aborted\"}),t.DIRTY=e=>({status:\"dirty\",value:e}),t.OK=e=>({status:\"valid\",value:e}),t.isAborted=e=>\"aborted\"===e.status,t.isDirty=e=>\"dirty\"===e.status,t.isValid=e=>\"valid\"===e.status,t.isAsync=e=>\"undefined\"!=typeof Promise&&e instanceof Promise},116:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0})},110:(e,t)=>{var s;Object.defineProperty(t,\"__esModule\",{value:!0}),t.getParsedType=t.ZodParsedType=t.objectUtil=t.util=void 0,function(e){e.assertEqual=e=>e,e.assertIs=function(e){},e.assertNever=function(e){throw new Error},e.arrayToEnum=e=>{const t={};for(const s of e)t[s]=s;return t},e.getValidEnumValues=t=>{const s=e.objectKeys(t).filter((e=>\"number\"!=typeof t[t[e]])),r={};for(const e of s)r[e]=t[e];return e.objectValues(r)},e.objectValues=t=>e.objectKeys(t).map((function(e){return t[e]})),e.objectKeys=\"function\"==typeof Object.keys?e=>Object.keys(e):e=>{const t=[];for(const s in e)Object.prototype.hasOwnProperty.call(e,s)&&t.push(s);return t},e.find=(e,t)=>{for(const s of e)if(t(s))return s},e.isInteger=\"function\"==typeof Number.isInteger?e=>Number.isInteger(e):e=>\"number\"==typeof e&&isFinite(e)&&Math.floor(e)===e,e.joinValues=function(e,t=\" | \"){return e.map((e=>\"string\"==typeof e?`'${e}'`:e)).join(t)},e.jsonStringifyReplacer=(e,t)=>\"bigint\"==typeof t?t.toString():t}(s=t.util||(t.util={})),(t.objectUtil||(t.objectUtil={})).mergeShapes=(e,t)=>({...e,...t}),t.ZodParsedType=s.arrayToEnum([\"string\",\"nan\",\"number\",\"integer\",\"float\",\"boolean\",\"date\",\"bigint\",\"symbol\",\"function\",\"undefined\",\"null\",\"array\",\"object\",\"unknown\",\"promise\",\"void\",\"never\",\"map\",\"set\"]),t.getParsedType=e=>{switch(typeof e){case\"undefined\":return t.ZodParsedType.undefined;case\"string\":return t.ZodParsedType.string;case\"number\":return isNaN(e)?t.ZodParsedType.nan:t.ZodParsedType.number;case\"boolean\":return t.ZodParsedType.boolean;case\"function\":return t.ZodParsedType.function;case\"bigint\":return t.ZodParsedType.bigint;case\"symbol\":return t.ZodParsedType.symbol;case\"object\":return Array.isArray(e)?t.ZodParsedType.array:null===e?t.ZodParsedType.null:e.then&&\"function\"==typeof e.then&&e.catch&&\"function\"==typeof e.catch?t.ZodParsedType.promise:\"undefined\"!=typeof Map&&e instanceof Map?t.ZodParsedType.map:\"undefined\"!=typeof Set&&e instanceof Set?t.ZodParsedType.set:\"undefined\"!=typeof Date&&e instanceof Date?t.ZodParsedType.date:t.ZodParsedType.object;default:return t.ZodParsedType.unknown}}},754:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[s]}})}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var s in e)\"default\"!==s&&Object.prototype.hasOwnProperty.call(e,s)&&r(t,e,s);return i(t,e),t},n=this&&this.__exportStar||function(e,t){for(var s in e)\"default\"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)};Object.defineProperty(t,\"__esModule\",{value:!0}),t.z=void 0;const o=a(s(349));t.z=o,n(s(349),t),t.default=o},325:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0});const r=s(110),i=s(280);t.default=(e,t)=>{let s;switch(e.code){case i.ZodIssueCode.invalid_type:s=e.received===r.ZodParsedType.undefined?\"Required\":`Expected ${e.expected}, received ${e.received}`;break;case i.ZodIssueCode.invalid_literal:s=`Invalid literal value, expected ${JSON.stringify(e.expected,r.util.jsonStringifyReplacer)}`;break;case i.ZodIssueCode.unrecognized_keys:s=`Unrecognized key(s) in object: ${r.util.joinValues(e.keys,\", \")}`;break;case i.ZodIssueCode.invalid_union:s=\"Invalid input\";break;case i.ZodIssueCode.invalid_union_discriminator:s=`Invalid discriminator value. Expected ${r.util.joinValues(e.options)}`;break;case i.ZodIssueCode.invalid_enum_value:s=`Invalid enum value. Expected ${r.util.joinValues(e.options)}, received '${e.received}'`;break;case i.ZodIssueCode.invalid_arguments:s=\"Invalid function arguments\";break;case i.ZodIssueCode.invalid_return_type:s=\"Invalid function return type\";break;case i.ZodIssueCode.invalid_date:s=\"Invalid date\";break;case i.ZodIssueCode.invalid_string:\"object\"==typeof e.validation?\"includes\"in e.validation?(s=`Invalid input: must include \"${e.validation.includes}\"`,\"number\"==typeof e.validation.position&&(s=`${s} at one or more positions greater than or equal to ${e.validation.position}`)):\"startsWith\"in e.validation?s=`Invalid input: must start with \"${e.validation.startsWith}\"`:\"endsWith\"in e.validation?s=`Invalid input: must end with \"${e.validation.endsWith}\"`:r.util.assertNever(e.validation):s=\"regex\"!==e.validation?`Invalid ${e.validation}`:\"Invalid\";break;case i.ZodIssueCode.too_small:s=\"array\"===e.type?`Array must contain ${e.exact?\"exactly\":e.inclusive?\"at least\":\"more than\"} ${e.minimum} element(s)`:\"string\"===e.type?`String must contain ${e.exact?\"exactly\":e.inclusive?\"at least\":\"over\"} ${e.minimum} character(s)`:\"number\"===e.type?`Number must be ${e.exact?\"exactly equal to \":e.inclusive?\"greater than or equal to \":\"greater than \"}${e.minimum}`:\"date\"===e.type?`Date must be ${e.exact?\"exactly equal to \":e.inclusive?\"greater than or equal to \":\"greater than \"}${new Date(Number(e.minimum))}`:\"Invalid input\";break;case i.ZodIssueCode.too_big:s=\"array\"===e.type?`Array must contain ${e.exact?\"exactly\":e.inclusive?\"at most\":\"less than\"} ${e.maximum} element(s)`:\"string\"===e.type?`String must contain ${e.exact?\"exactly\":e.inclusive?\"at most\":\"under\"} ${e.maximum} character(s)`:\"number\"===e.type?`Number must be ${e.exact?\"exactly\":e.inclusive?\"less than or equal to\":\"less than\"} ${e.maximum}`:\"bigint\"===e.type?`BigInt must be ${e.exact?\"exactly\":e.inclusive?\"less than or equal to\":\"less than\"} ${e.maximum}`:\"date\"===e.type?`Date must be ${e.exact?\"exactly\":e.inclusive?\"smaller than or equal to\":\"smaller than\"} ${new Date(Number(e.maximum))}`:\"Invalid input\";break;case i.ZodIssueCode.custom:s=\"Invalid input\";break;case i.ZodIssueCode.invalid_intersection_types:s=\"Intersection results could not be merged\";break;case i.ZodIssueCode.not_multiple_of:s=`Number must be a multiple of ${e.multipleOf}`;break;case i.ZodIssueCode.not_finite:s=\"Number must be finite\";break;default:s=t.defaultError,r.util.assertNever(e)}return{message:s}}},433:(e,t,s)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.date=t.boolean=t.bigint=t.array=t.any=t.coerce=t.ZodFirstPartyTypeKind=t.late=t.ZodSchema=t.Schema=t.custom=t.ZodReadonly=t.ZodPipeline=t.ZodBranded=t.BRAND=t.ZodNaN=t.ZodCatch=t.ZodDefault=t.ZodNullable=t.ZodOptional=t.ZodTransformer=t.ZodEffects=t.ZodPromise=t.ZodNativeEnum=t.ZodEnum=t.ZodLiteral=t.ZodLazy=t.ZodFunction=t.ZodSet=t.ZodMap=t.ZodRecord=t.ZodTuple=t.ZodIntersection=t.ZodDiscriminatedUnion=t.ZodUnion=t.ZodObject=t.ZodArray=t.ZodVoid=t.ZodNever=t.ZodUnknown=t.ZodAny=t.ZodNull=t.ZodUndefined=t.ZodSymbol=t.ZodDate=t.ZodBoolean=t.ZodBigInt=t.ZodNumber=t.ZodString=t.ZodType=void 0,t.NEVER=t.void=t.unknown=t.union=t.undefined=t.tuple=t.transformer=t.symbol=t.string=t.strictObject=t.set=t.record=t.promise=t.preprocess=t.pipeline=t.ostring=t.optional=t.onumber=t.oboolean=t.object=t.number=t.nullable=t.null=t.never=t.nativeEnum=t.nan=t.map=t.literal=t.lazy=t.intersection=t.instanceof=t.function=t.enum=t.effect=t.discriminatedUnion=void 0;const r=s(996),i=s(762),a=s(187),n=s(110),o=s(280);class d{constructor(e,t,s,r){this._cachedPath=[],this.parent=e,this.data=t,this._path=s,this._key=r}get path(){return this._cachedPath.length||(this._key instanceof Array?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}}const l=(e,t)=>{if((0,a.isValid)(t))return{success:!0,data:t.value};if(!e.common.issues.length)throw new Error(\"Validation failed but no issues detected.\");return{success:!1,get error(){if(this._error)return this._error;const t=new o.ZodError(e.common.issues);return this._error=t,this._error}}};function u(e){if(!e)return{};const{errorMap:t,invalid_type_error:s,required_error:r,description:i}=e;if(t&&(s||r))throw new Error('Can\\'t use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.');return t?{errorMap:t,description:i}:{errorMap:(e,t)=>\"invalid_type\"!==e.code?{message:t.defaultError}:void 0===t.data?{message:null!=r?r:t.defaultError}:{message:null!=s?s:t.defaultError},description:i}}class c{constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this)}get description(){return this._def.description}_getType(e){return(0,n.getParsedType)(e.data)}_getOrReturnCtx(e,t){return t||{common:e.parent.common,data:e.data,parsedType:(0,n.getParsedType)(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new a.ParseStatus,ctx:{common:e.parent.common,data:e.data,parsedType:(0,n.getParsedType)(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){const t=this._parse(e);if((0,a.isAsync)(t))throw new Error(\"Synchronous parse encountered promise.\");return t}_parseAsync(e){const t=this._parse(e);return Promise.resolve(t)}parse(e,t){const s=this.safeParse(e,t);if(s.success)return s.data;throw s.error}safeParse(e,t){var s;const r={common:{issues:[],async:null!==(s=null==t?void 0:t.async)&&void 0!==s&&s,contextualErrorMap:null==t?void 0:t.errorMap},path:(null==t?void 0:t.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:(0,n.getParsedType)(e)},i=this._parseSync({data:e,path:r.path,parent:r});return l(r,i)}async parseAsync(e,t){const s=await this.safeParseAsync(e,t);if(s.success)return s.data;throw s.error}async safeParseAsync(e,t){const s={common:{issues:[],contextualErrorMap:null==t?void 0:t.errorMap,async:!0},path:(null==t?void 0:t.path)||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:(0,n.getParsedType)(e)},r=this._parse({data:e,path:s.path,parent:s}),i=await((0,a.isAsync)(r)?r:Promise.resolve(r));return l(s,i)}refine(e,t){const s=e=>\"string\"==typeof t||void 0===t?{message:t}:\"function\"==typeof t?t(e):t;return this._refinement(((t,r)=>{const i=e(t),a=()=>r.addIssue({code:o.ZodIssueCode.custom,...s(t)});return\"undefined\"!=typeof Promise&&i instanceof Promise?i.then((e=>!!e||(a(),!1))):!!i||(a(),!1)}))}refinement(e,t){return this._refinement(((s,r)=>!!e(s)||(r.addIssue(\"function\"==typeof t?t(s,r):t),!1)))}_refinement(e){return new J({schema:this,typeName:oe.ZodEffects,effect:{type:\"refinement\",refinement:e}})}superRefine(e){return this._refinement(e)}optional(){return Q.create(this,this._def)}nullable(){return ee.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return E.create(this,this._def)}promise(){return X.create(this,this._def)}or(e){return M.create([this,e],this._def)}and(e){return R.create(this,e,this._def)}transform(e){return new J({...u(this._def),schema:this,typeName:oe.ZodEffects,effect:{type:\"transform\",transform:e}})}default(e){const t=\"function\"==typeof e?e:()=>e;return new te({...u(this._def),innerType:this,defaultValue:t,typeName:oe.ZodDefault})}brand(){return new ie({typeName:oe.ZodBranded,type:this,...u(this._def)})}catch(e){const t=\"function\"==typeof e?e:()=>e;return new se({...u(this._def),innerType:this,catchValue:t,typeName:oe.ZodCatch})}describe(e){return new(0,this.constructor)({...this._def,description:e})}pipe(e){return ae.create(this,e)}readonly(){return ne.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}}t.ZodType=c,t.Schema=c,t.ZodSchema=c;const p=/^c[^\\s-]{8,}$/i,h=/^[a-z][a-z0-9]*$/,f=/^[0-9A-HJKMNP-TV-Z]{26}$/,m=/^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i,y=/^(?!\\.)(?!.*\\.\\.)([A-Z0-9_+-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;let _;const v=/^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/,g=/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;class b extends c{_parse(e){if(this._def.coerce&&(e.data=String(e.data)),this._getType(e)!==n.ZodParsedType.string){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.string,received:t.parsedType}),a.INVALID}const t=new a.ParseStatus;let s;for(const l of this._def.checks)if(\"min\"===l.kind)e.data.lengthl.value&&(s=this._getOrReturnCtx(e,s),(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.too_big,maximum:l.value,type:\"string\",inclusive:!0,exact:!1,message:l.message}),t.dirty());else if(\"length\"===l.kind){const r=e.data.length>l.value,i=e.data.lengthe.test(t)),{validation:t,code:o.ZodIssueCode.invalid_string,...i.errorUtil.errToObj(s)})}_addCheck(e){return new b({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:\"email\",...i.errorUtil.errToObj(e)})}url(e){return this._addCheck({kind:\"url\",...i.errorUtil.errToObj(e)})}emoji(e){return this._addCheck({kind:\"emoji\",...i.errorUtil.errToObj(e)})}uuid(e){return this._addCheck({kind:\"uuid\",...i.errorUtil.errToObj(e)})}cuid(e){return this._addCheck({kind:\"cuid\",...i.errorUtil.errToObj(e)})}cuid2(e){return this._addCheck({kind:\"cuid2\",...i.errorUtil.errToObj(e)})}ulid(e){return this._addCheck({kind:\"ulid\",...i.errorUtil.errToObj(e)})}ip(e){return this._addCheck({kind:\"ip\",...i.errorUtil.errToObj(e)})}datetime(e){var t;return\"string\"==typeof e?this._addCheck({kind:\"datetime\",precision:null,offset:!1,message:e}):this._addCheck({kind:\"datetime\",precision:void 0===(null==e?void 0:e.precision)?null:null==e?void 0:e.precision,offset:null!==(t=null==e?void 0:e.offset)&&void 0!==t&&t,...i.errorUtil.errToObj(null==e?void 0:e.message)})}regex(e,t){return this._addCheck({kind:\"regex\",regex:e,...i.errorUtil.errToObj(t)})}includes(e,t){return this._addCheck({kind:\"includes\",value:e,position:null==t?void 0:t.position,...i.errorUtil.errToObj(null==t?void 0:t.message)})}startsWith(e,t){return this._addCheck({kind:\"startsWith\",value:e,...i.errorUtil.errToObj(t)})}endsWith(e,t){return this._addCheck({kind:\"endsWith\",value:e,...i.errorUtil.errToObj(t)})}min(e,t){return this._addCheck({kind:\"min\",value:e,...i.errorUtil.errToObj(t)})}max(e,t){return this._addCheck({kind:\"max\",value:e,...i.errorUtil.errToObj(t)})}length(e,t){return this._addCheck({kind:\"length\",value:e,...i.errorUtil.errToObj(t)})}nonempty(e){return this.min(1,i.errorUtil.errToObj(e))}trim(){return new b({...this._def,checks:[...this._def.checks,{kind:\"trim\"}]})}toLowerCase(){return new b({...this._def,checks:[...this._def.checks,{kind:\"toLowerCase\"}]})}toUpperCase(){return new b({...this._def,checks:[...this._def.checks,{kind:\"toUpperCase\"}]})}get isDatetime(){return!!this._def.checks.find((e=>\"datetime\"===e.kind))}get isEmail(){return!!this._def.checks.find((e=>\"email\"===e.kind))}get isURL(){return!!this._def.checks.find((e=>\"url\"===e.kind))}get isEmoji(){return!!this._def.checks.find((e=>\"emoji\"===e.kind))}get isUUID(){return!!this._def.checks.find((e=>\"uuid\"===e.kind))}get isCUID(){return!!this._def.checks.find((e=>\"cuid\"===e.kind))}get isCUID2(){return!!this._def.checks.find((e=>\"cuid2\"===e.kind))}get isULID(){return!!this._def.checks.find((e=>\"ulid\"===e.kind))}get isIP(){return!!this._def.checks.find((e=>\"ip\"===e.kind))}get minLength(){let e=null;for(const t of this._def.checks)\"min\"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxLength(){let e=null;for(const t of this._def.checks)\"max\"===t.kind&&(null===e||t.valuer?s:r;return parseInt(e.toFixed(i).replace(\".\",\"\"))%parseInt(t.toFixed(i).replace(\".\",\"\"))/Math.pow(10,i)}t.ZodString=b,b.create=e=>{var t;return new b({checks:[],typeName:oe.ZodString,coerce:null!==(t=null==e?void 0:e.coerce)&&void 0!==t&&t,...u(e)})};class I extends c{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(e){if(this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==n.ZodParsedType.number){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.number,received:t.parsedType}),a.INVALID}let t;const s=new a.ParseStatus;for(const r of this._def.checks)\"int\"===r.kind?n.util.isInteger(e.data)||(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:\"integer\",received:\"float\",message:r.message}),s.dirty()):\"min\"===r.kind?(r.inclusive?e.datar.value:e.data>=r.value)&&(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.too_big,maximum:r.value,type:\"number\",inclusive:r.inclusive,exact:!1,message:r.message}),s.dirty()):\"multipleOf\"===r.kind?0!==x(e.data,r.value)&&(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.not_multiple_of,multipleOf:r.value,message:r.message}),s.dirty()):\"finite\"===r.kind?Number.isFinite(e.data)||(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.not_finite,message:r.message}),s.dirty()):n.util.assertNever(r);return{status:s.value,value:e.data}}gte(e,t){return this.setLimit(\"min\",e,!0,i.errorUtil.toString(t))}gt(e,t){return this.setLimit(\"min\",e,!1,i.errorUtil.toString(t))}lte(e,t){return this.setLimit(\"max\",e,!0,i.errorUtil.toString(t))}lt(e,t){return this.setLimit(\"max\",e,!1,i.errorUtil.toString(t))}setLimit(e,t,s,r){return new I({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:s,message:i.errorUtil.toString(r)}]})}_addCheck(e){return new I({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:\"int\",message:i.errorUtil.toString(e)})}positive(e){return this._addCheck({kind:\"min\",value:0,inclusive:!1,message:i.errorUtil.toString(e)})}negative(e){return this._addCheck({kind:\"max\",value:0,inclusive:!1,message:i.errorUtil.toString(e)})}nonpositive(e){return this._addCheck({kind:\"max\",value:0,inclusive:!0,message:i.errorUtil.toString(e)})}nonnegative(e){return this._addCheck({kind:\"min\",value:0,inclusive:!0,message:i.errorUtil.toString(e)})}multipleOf(e,t){return this._addCheck({kind:\"multipleOf\",value:e,message:i.errorUtil.toString(t)})}finite(e){return this._addCheck({kind:\"finite\",message:i.errorUtil.toString(e)})}safe(e){return this._addCheck({kind:\"min\",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:i.errorUtil.toString(e)})._addCheck({kind:\"max\",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:i.errorUtil.toString(e)})}get minValue(){let e=null;for(const t of this._def.checks)\"min\"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxValue(){let e=null;for(const t of this._def.checks)\"max\"===t.kind&&(null===e||t.value\"int\"===e.kind||\"multipleOf\"===e.kind&&n.util.isInteger(e.value)))}get isFinite(){let e=null,t=null;for(const s of this._def.checks){if(\"finite\"===s.kind||\"int\"===s.kind||\"multipleOf\"===s.kind)return!0;\"min\"===s.kind?(null===t||s.value>t)&&(t=s.value):\"max\"===s.kind&&(null===e||s.valuenew I({checks:[],typeName:oe.ZodNumber,coerce:(null==e?void 0:e.coerce)||!1,...u(e)});class Z extends c{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(e){if(this._def.coerce&&(e.data=BigInt(e.data)),this._getType(e)!==n.ZodParsedType.bigint){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.bigint,received:t.parsedType}),a.INVALID}let t;const s=new a.ParseStatus;for(const r of this._def.checks)\"min\"===r.kind?(r.inclusive?e.datar.value:e.data>=r.value)&&(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.too_big,type:\"bigint\",maximum:r.value,inclusive:r.inclusive,message:r.message}),s.dirty()):\"multipleOf\"===r.kind?e.data%r.value!==BigInt(0)&&(t=this._getOrReturnCtx(e,t),(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.not_multiple_of,multipleOf:r.value,message:r.message}),s.dirty()):n.util.assertNever(r);return{status:s.value,value:e.data}}gte(e,t){return this.setLimit(\"min\",e,!0,i.errorUtil.toString(t))}gt(e,t){return this.setLimit(\"min\",e,!1,i.errorUtil.toString(t))}lte(e,t){return this.setLimit(\"max\",e,!0,i.errorUtil.toString(t))}lt(e,t){return this.setLimit(\"max\",e,!1,i.errorUtil.toString(t))}setLimit(e,t,s,r){return new Z({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:s,message:i.errorUtil.toString(r)}]})}_addCheck(e){return new Z({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!1,message:i.errorUtil.toString(e)})}negative(e){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!1,message:i.errorUtil.toString(e)})}nonpositive(e){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!0,message:i.errorUtil.toString(e)})}nonnegative(e){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!0,message:i.errorUtil.toString(e)})}multipleOf(e,t){return this._addCheck({kind:\"multipleOf\",value:e,message:i.errorUtil.toString(t)})}get minValue(){let e=null;for(const t of this._def.checks)\"min\"===t.kind&&(null===e||t.value>e)&&(e=t.value);return e}get maxValue(){let e=null;for(const t of this._def.checks)\"max\"===t.kind&&(null===e||t.value{var t;return new Z({checks:[],typeName:oe.ZodBigInt,coerce:null!==(t=null==e?void 0:e.coerce)&&void 0!==t&&t,...u(e)})};class T extends c{_parse(e){if(this._def.coerce&&(e.data=Boolean(e.data)),this._getType(e)!==n.ZodParsedType.boolean){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.boolean,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodBoolean=T,T.create=e=>new T({typeName:oe.ZodBoolean,coerce:(null==e?void 0:e.coerce)||!1,...u(e)});class k extends c{_parse(e){if(this._def.coerce&&(e.data=new Date(e.data)),this._getType(e)!==n.ZodParsedType.date){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.date,received:t.parsedType}),a.INVALID}if(isNaN(e.data.getTime())){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_date}),a.INVALID}const t=new a.ParseStatus;let s;for(const r of this._def.checks)\"min\"===r.kind?e.data.getTime()r.value&&(s=this._getOrReturnCtx(e,s),(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.too_big,message:r.message,inclusive:!0,exact:!1,maximum:r.value,type:\"date\"}),t.dirty()):n.util.assertNever(r);return{status:t.value,value:new Date(e.data.getTime())}}_addCheck(e){return new k({...this._def,checks:[...this._def.checks,e]})}min(e,t){return this._addCheck({kind:\"min\",value:e.getTime(),message:i.errorUtil.toString(t)})}max(e,t){return this._addCheck({kind:\"max\",value:e.getTime(),message:i.errorUtil.toString(t)})}get minDate(){let e=null;for(const t of this._def.checks)\"min\"===t.kind&&(null===e||t.value>e)&&(e=t.value);return null!=e?new Date(e):null}get maxDate(){let e=null;for(const t of this._def.checks)\"max\"===t.kind&&(null===e||t.valuenew k({checks:[],coerce:(null==e?void 0:e.coerce)||!1,typeName:oe.ZodDate,...u(e)});class w extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.symbol){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.symbol,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodSymbol=w,w.create=e=>new w({typeName:oe.ZodSymbol,...u(e)});class C extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.undefined){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.undefined,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodUndefined=C,C.create=e=>new C({typeName:oe.ZodUndefined,...u(e)});class z extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.null){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.null,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodNull=z,z.create=e=>new z({typeName:oe.ZodNull,...u(e)});class L extends c{constructor(){super(...arguments),this._any=!0}_parse(e){return(0,a.OK)(e.data)}}t.ZodAny=L,L.create=e=>new L({typeName:oe.ZodAny,...u(e)});class P extends c{constructor(){super(...arguments),this._unknown=!0}_parse(e){return(0,a.OK)(e.data)}}t.ZodUnknown=P,P.create=e=>new P({typeName:oe.ZodUnknown,...u(e)});class O extends c{_parse(e){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.never,received:t.parsedType}),a.INVALID}}t.ZodNever=O,O.create=e=>new O({typeName:oe.ZodNever,...u(e)});class j extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.undefined){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.void,received:t.parsedType}),a.INVALID}return(0,a.OK)(e.data)}}t.ZodVoid=j,j.create=e=>new j({typeName:oe.ZodVoid,...u(e)});class E extends c{_parse(e){const{ctx:t,status:s}=this._processInputParams(e),r=this._def;if(t.parsedType!==n.ZodParsedType.array)return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.array,received:t.parsedType}),a.INVALID;if(null!==r.exactLength){const e=t.data.length>r.exactLength.value,i=t.data.lengthr.maxLength.value&&((0,a.addIssueToContext)(t,{code:o.ZodIssueCode.too_big,maximum:r.maxLength.value,type:\"array\",inclusive:!0,exact:!1,message:r.maxLength.message}),s.dirty()),t.common.async)return Promise.all([...t.data].map(((e,s)=>r.type._parseAsync(new d(t,e,t.path,s))))).then((e=>a.ParseStatus.mergeArray(s,e)));const i=[...t.data].map(((e,s)=>r.type._parseSync(new d(t,e,t.path,s))));return a.ParseStatus.mergeArray(s,i)}get element(){return this._def.type}min(e,t){return new E({...this._def,minLength:{value:e,message:i.errorUtil.toString(t)}})}max(e,t){return new E({...this._def,maxLength:{value:e,message:i.errorUtil.toString(t)}})}length(e,t){return new E({...this._def,exactLength:{value:e,message:i.errorUtil.toString(t)}})}nonempty(e){return this.min(1,e)}}function S(e){if(e instanceof N){const t={};for(const s in e.shape){const r=e.shape[s];t[s]=Q.create(S(r))}return new N({...e._def,shape:()=>t})}return e instanceof E?new E({...e._def,type:S(e.element)}):e instanceof Q?Q.create(S(e.unwrap())):e instanceof ee?ee.create(S(e.unwrap())):e instanceof V?V.create(e.items.map((e=>S(e)))):e}t.ZodArray=E,E.create=(e,t)=>new E({type:e,minLength:null,maxLength:null,exactLength:null,typeName:oe.ZodArray,...u(t)});class N extends c{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(null!==this._cached)return this._cached;const e=this._def.shape(),t=n.util.objectKeys(e);return this._cached={shape:e,keys:t}}_parse(e){if(this._getType(e)!==n.ZodParsedType.object){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.object,received:t.parsedType}),a.INVALID}const{status:t,ctx:s}=this._processInputParams(e),{shape:r,keys:i}=this._getCached(),l=[];if(!(this._def.catchall instanceof O&&\"strip\"===this._def.unknownKeys))for(const e in s.data)i.includes(e)||l.push(e);const u=[];for(const e of i){const t=r[e],i=s.data[e];u.push({key:{status:\"valid\",value:e},value:t._parse(new d(s,i,s.path,e)),alwaysSet:e in s.data})}if(this._def.catchall instanceof O){const e=this._def.unknownKeys;if(\"passthrough\"===e)for(const e of l)u.push({key:{status:\"valid\",value:e},value:{status:\"valid\",value:s.data[e]}});else if(\"strict\"===e)l.length>0&&((0,a.addIssueToContext)(s,{code:o.ZodIssueCode.unrecognized_keys,keys:l}),t.dirty());else if(\"strip\"!==e)throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\")}else{const e=this._def.catchall;for(const t of l){const r=s.data[t];u.push({key:{status:\"valid\",value:t},value:e._parse(new d(s,r,s.path,t)),alwaysSet:t in s.data})}}return s.common.async?Promise.resolve().then((async()=>{const e=[];for(const t of u){const s=await t.key;e.push({key:s,value:await t.value,alwaysSet:t.alwaysSet})}return e})).then((e=>a.ParseStatus.mergeObjectSync(t,e))):a.ParseStatus.mergeObjectSync(t,u)}get shape(){return this._def.shape()}strict(e){return i.errorUtil.errToObj,new N({...this._def,unknownKeys:\"strict\",...void 0!==e?{errorMap:(t,s)=>{var r,a,n,o;const d=null!==(n=null===(a=(r=this._def).errorMap)||void 0===a?void 0:a.call(r,t,s).message)&&void 0!==n?n:s.defaultError;return\"unrecognized_keys\"===t.code?{message:null!==(o=i.errorUtil.errToObj(e).message)&&void 0!==o?o:d}:{message:d}}}:{}})}strip(){return new N({...this._def,unknownKeys:\"strip\"})}passthrough(){return new N({...this._def,unknownKeys:\"passthrough\"})}extend(e){return new N({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new N({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:oe.ZodObject})}setKey(e,t){return this.augment({[e]:t})}catchall(e){return new N({...this._def,catchall:e})}pick(e){const t={};return n.util.objectKeys(e).forEach((s=>{e[s]&&this.shape[s]&&(t[s]=this.shape[s])})),new N({...this._def,shape:()=>t})}omit(e){const t={};return n.util.objectKeys(this.shape).forEach((s=>{e[s]||(t[s]=this.shape[s])})),new N({...this._def,shape:()=>t})}deepPartial(){return S(this)}partial(e){const t={};return n.util.objectKeys(this.shape).forEach((s=>{const r=this.shape[s];e&&!e[s]?t[s]=r:t[s]=r.optional()})),new N({...this._def,shape:()=>t})}required(e){const t={};return n.util.objectKeys(this.shape).forEach((s=>{if(e&&!e[s])t[s]=this.shape[s];else{let e=this.shape[s];for(;e instanceof Q;)e=e._def.innerType;t[s]=e}})),new N({...this._def,shape:()=>t})}keyof(){return Y(n.util.objectKeys(this.shape))}}t.ZodObject=N,N.create=(e,t)=>new N({shape:()=>e,unknownKeys:\"strip\",catchall:O.create(),typeName:oe.ZodObject,...u(t)}),N.strictCreate=(e,t)=>new N({shape:()=>e,unknownKeys:\"strict\",catchall:O.create(),typeName:oe.ZodObject,...u(t)}),N.lazycreate=(e,t)=>new N({shape:e,unknownKeys:\"strip\",catchall:O.create(),typeName:oe.ZodObject,...u(t)});class M extends c{_parse(e){const{ctx:t}=this._processInputParams(e),s=this._def.options;if(t.common.async)return Promise.all(s.map((async e=>{const s={...t,common:{...t.common,issues:[]},parent:null};return{result:await e._parseAsync({data:t.data,path:t.path,parent:s}),ctx:s}}))).then((function(e){for(const t of e)if(\"valid\"===t.result.status)return t.result;for(const s of e)if(\"dirty\"===s.result.status)return t.common.issues.push(...s.ctx.common.issues),s.result;const s=e.map((e=>new o.ZodError(e.ctx.common.issues)));return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_union,unionErrors:s}),a.INVALID}));{let e;const r=[];for(const i of s){const s={...t,common:{...t.common,issues:[]},parent:null},a=i._parseSync({data:t.data,path:t.path,parent:s});if(\"valid\"===a.status)return a;\"dirty\"!==a.status||e||(e={result:a,ctx:s}),s.common.issues.length&&r.push(s.common.issues)}if(e)return t.common.issues.push(...e.ctx.common.issues),e.result;const i=r.map((e=>new o.ZodError(e)));return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_union,unionErrors:i}),a.INVALID}}get options(){return this._def.options}}t.ZodUnion=M,M.create=(e,t)=>new M({options:e,typeName:oe.ZodUnion,...u(t)});const A=e=>e instanceof G?A(e.schema):e instanceof J?A(e.innerType()):e instanceof W?[e.value]:e instanceof H?e.options:e instanceof q?Object.keys(e.enum):e instanceof te?A(e._def.innerType):e instanceof C?[void 0]:e instanceof z?[null]:null;class D extends c{_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==n.ZodParsedType.object)return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.object,received:t.parsedType}),a.INVALID;const s=this.discriminator,r=t.data[s],i=this.optionsMap.get(r);return i?t.common.async?i._parseAsync({data:t.data,path:t.path,parent:t}):i._parseSync({data:t.data,path:t.path,parent:t}):((0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[s]}),a.INVALID)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,t,s){const r=new Map;for(const s of t){const t=A(s.shape[e]);if(!t)throw new Error(`A discriminator value for key \\`${e}\\` could not be extracted from all schema options`);for(const i of t){if(r.has(i))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(i)}`);r.set(i,s)}}return new D({typeName:oe.ZodDiscriminatedUnion,discriminator:e,options:t,optionsMap:r,...u(s)})}}function U(e,t){const s=(0,n.getParsedType)(e),r=(0,n.getParsedType)(t);if(e===t)return{valid:!0,data:e};if(s===n.ZodParsedType.object&&r===n.ZodParsedType.object){const s=n.util.objectKeys(t),r=n.util.objectKeys(e).filter((e=>-1!==s.indexOf(e))),i={...e,...t};for(const s of r){const r=U(e[s],t[s]);if(!r.valid)return{valid:!1};i[s]=r.data}return{valid:!0,data:i}}if(s===n.ZodParsedType.array&&r===n.ZodParsedType.array){if(e.length!==t.length)return{valid:!1};const s=[];for(let r=0;r{if((0,a.isAborted)(e)||(0,a.isAborted)(r))return a.INVALID;const i=U(e.value,r.value);return i.valid?(((0,a.isDirty)(e)||(0,a.isDirty)(r))&&t.dirty(),{status:t.value,value:i.data}):((0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_intersection_types}),a.INVALID)};return s.common.async?Promise.all([this._def.left._parseAsync({data:s.data,path:s.path,parent:s}),this._def.right._parseAsync({data:s.data,path:s.path,parent:s})]).then((([e,t])=>r(e,t))):r(this._def.left._parseSync({data:s.data,path:s.path,parent:s}),this._def.right._parseSync({data:s.data,path:s.path,parent:s}))}}t.ZodIntersection=R,R.create=(e,t,s)=>new R({left:e,right:t,typeName:oe.ZodIntersection,...u(s)});class V extends c{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==n.ZodParsedType.array)return(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.array,received:s.parsedType}),a.INVALID;if(s.data.lengththis._def.items.length&&((0,a.addIssueToContext)(s,{code:o.ZodIssueCode.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),t.dirty());const r=[...s.data].map(((e,t)=>{const r=this._def.items[t]||this._def.rest;return r?r._parse(new d(s,e,s.path,t)):null})).filter((e=>!!e));return s.common.async?Promise.all(r).then((e=>a.ParseStatus.mergeArray(t,e))):a.ParseStatus.mergeArray(t,r)}get items(){return this._def.items}rest(e){return new V({...this._def,rest:e})}}t.ZodTuple=V,V.create=(e,t)=>{if(!Array.isArray(e))throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");return new V({items:e,typeName:oe.ZodTuple,rest:null,...u(t)})};class $ extends c{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==n.ZodParsedType.object)return(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.object,received:s.parsedType}),a.INVALID;const r=[],i=this._def.keyType,l=this._def.valueType;for(const e in s.data)r.push({key:i._parse(new d(s,e,s.path,e)),value:l._parse(new d(s,s.data[e],s.path,e))});return s.common.async?a.ParseStatus.mergeObjectAsync(t,r):a.ParseStatus.mergeObjectSync(t,r)}get element(){return this._def.valueType}static create(e,t,s){return new $(t instanceof c?{keyType:e,valueType:t,typeName:oe.ZodRecord,...u(s)}:{keyType:b.create(),valueType:e,typeName:oe.ZodRecord,...u(t)})}}t.ZodRecord=$;class B extends c{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==n.ZodParsedType.map)return(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.map,received:s.parsedType}),a.INVALID;const r=this._def.keyType,i=this._def.valueType,l=[...s.data.entries()].map((([e,t],a)=>({key:r._parse(new d(s,e,s.path,[a,\"key\"])),value:i._parse(new d(s,t,s.path,[a,\"value\"]))})));if(s.common.async){const e=new Map;return Promise.resolve().then((async()=>{for(const s of l){const r=await s.key,i=await s.value;if(\"aborted\"===r.status||\"aborted\"===i.status)return a.INVALID;\"dirty\"!==r.status&&\"dirty\"!==i.status||t.dirty(),e.set(r.value,i.value)}return{status:t.value,value:e}}))}{const e=new Map;for(const s of l){const r=s.key,i=s.value;if(\"aborted\"===r.status||\"aborted\"===i.status)return a.INVALID;\"dirty\"!==r.status&&\"dirty\"!==i.status||t.dirty(),e.set(r.value,i.value)}return{status:t.value,value:e}}}}t.ZodMap=B,B.create=(e,t,s)=>new B({valueType:t,keyType:e,typeName:oe.ZodMap,...u(s)});class F extends c{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==n.ZodParsedType.set)return(0,a.addIssueToContext)(s,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.set,received:s.parsedType}),a.INVALID;const r=this._def;null!==r.minSize&&s.data.sizer.maxSize.value&&((0,a.addIssueToContext)(s,{code:o.ZodIssueCode.too_big,maximum:r.maxSize.value,type:\"set\",inclusive:!0,exact:!1,message:r.maxSize.message}),t.dirty());const i=this._def.valueType;function l(e){const s=new Set;for(const r of e){if(\"aborted\"===r.status)return a.INVALID;\"dirty\"===r.status&&t.dirty(),s.add(r.value)}return{status:t.value,value:s}}const u=[...s.data.values()].map(((e,t)=>i._parse(new d(s,e,s.path,t))));return s.common.async?Promise.all(u).then((e=>l(e))):l(u)}min(e,t){return new F({...this._def,minSize:{value:e,message:i.errorUtil.toString(t)}})}max(e,t){return new F({...this._def,maxSize:{value:e,message:i.errorUtil.toString(t)}})}size(e,t){return this.min(e,t).max(e,t)}nonempty(e){return this.min(1,e)}}t.ZodSet=F,F.create=(e,t)=>new F({valueType:e,minSize:null,maxSize:null,typeName:oe.ZodSet,...u(t)});class K extends c{constructor(){super(...arguments),this.validate=this.implement}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==n.ZodParsedType.function)return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.function,received:t.parsedType}),a.INVALID;function s(e,s){return(0,a.makeIssue)({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,(0,r.getErrorMap)(),r.defaultErrorMap].filter((e=>!!e)),issueData:{code:o.ZodIssueCode.invalid_arguments,argumentsError:s}})}function i(e,s){return(0,a.makeIssue)({data:e,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,(0,r.getErrorMap)(),r.defaultErrorMap].filter((e=>!!e)),issueData:{code:o.ZodIssueCode.invalid_return_type,returnTypeError:s}})}const d={errorMap:t.common.contextualErrorMap},l=t.data;if(this._def.returns instanceof X){const e=this;return(0,a.OK)((async function(...t){const r=new o.ZodError([]),a=await e._def.args.parseAsync(t,d).catch((e=>{throw r.addIssue(s(t,e)),r})),n=await Reflect.apply(l,this,a);return await e._def.returns._def.type.parseAsync(n,d).catch((e=>{throw r.addIssue(i(n,e)),r}))}))}{const e=this;return(0,a.OK)((function(...t){const r=e._def.args.safeParse(t,d);if(!r.success)throw new o.ZodError([s(t,r.error)]);const a=Reflect.apply(l,this,r.data),n=e._def.returns.safeParse(a,d);if(!n.success)throw new o.ZodError([i(a,n.error)]);return n.data}))}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new K({...this._def,args:V.create(e).rest(P.create())})}returns(e){return new K({...this._def,returns:e})}implement(e){return this.parse(e)}strictImplement(e){return this.parse(e)}static create(e,t,s){return new K({args:e||V.create([]).rest(P.create()),returns:t||P.create(),typeName:oe.ZodFunction,...u(s)})}}t.ZodFunction=K;class G extends c{get schema(){return this._def.getter()}_parse(e){const{ctx:t}=this._processInputParams(e);return this._def.getter()._parse({data:t.data,path:t.path,parent:t})}}t.ZodLazy=G,G.create=(e,t)=>new G({getter:e,typeName:oe.ZodLazy,...u(t)});class W extends c{_parse(e){if(e.data!==this._def.value){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{received:t.data,code:o.ZodIssueCode.invalid_literal,expected:this._def.value}),a.INVALID}return{status:\"valid\",value:e.data}}get value(){return this._def.value}}function Y(e,t){return new H({values:e,typeName:oe.ZodEnum,...u(t)})}t.ZodLiteral=W,W.create=(e,t)=>new W({value:e,typeName:oe.ZodLiteral,...u(t)});class H extends c{_parse(e){if(\"string\"!=typeof e.data){const t=this._getOrReturnCtx(e),s=this._def.values;return(0,a.addIssueToContext)(t,{expected:n.util.joinValues(s),received:t.parsedType,code:o.ZodIssueCode.invalid_type}),a.INVALID}if(-1===this._def.values.indexOf(e.data)){const t=this._getOrReturnCtx(e),s=this._def.values;return(0,a.addIssueToContext)(t,{received:t.data,code:o.ZodIssueCode.invalid_enum_value,options:s}),a.INVALID}return(0,a.OK)(e.data)}get options(){return this._def.values}get enum(){const e={};for(const t of this._def.values)e[t]=t;return e}get Values(){const e={};for(const t of this._def.values)e[t]=t;return e}get Enum(){const e={};for(const t of this._def.values)e[t]=t;return e}extract(e){return H.create(e)}exclude(e){return H.create(this.options.filter((t=>!e.includes(t))))}}t.ZodEnum=H,H.create=Y;class q extends c{_parse(e){const t=n.util.getValidEnumValues(this._def.values),s=this._getOrReturnCtx(e);if(s.parsedType!==n.ZodParsedType.string&&s.parsedType!==n.ZodParsedType.number){const e=n.util.objectValues(t);return(0,a.addIssueToContext)(s,{expected:n.util.joinValues(e),received:s.parsedType,code:o.ZodIssueCode.invalid_type}),a.INVALID}if(-1===t.indexOf(e.data)){const e=n.util.objectValues(t);return(0,a.addIssueToContext)(s,{received:s.data,code:o.ZodIssueCode.invalid_enum_value,options:e}),a.INVALID}return(0,a.OK)(e.data)}get enum(){return this._def.values}}t.ZodNativeEnum=q,q.create=(e,t)=>new q({values:e,typeName:oe.ZodNativeEnum,...u(t)});class X extends c{unwrap(){return this._def.type}_parse(e){const{ctx:t}=this._processInputParams(e);if(t.parsedType!==n.ZodParsedType.promise&&!1===t.common.async)return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.promise,received:t.parsedType}),a.INVALID;const s=t.parsedType===n.ZodParsedType.promise?t.data:Promise.resolve(t.data);return(0,a.OK)(s.then((e=>this._def.type.parseAsync(e,{path:t.path,errorMap:t.common.contextualErrorMap}))))}}t.ZodPromise=X,X.create=(e,t)=>new X({type:e,typeName:oe.ZodPromise,...u(t)});class J extends c{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===oe.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(e){const{status:t,ctx:s}=this._processInputParams(e),r=this._def.effect||null,i={addIssue:e=>{(0,a.addIssueToContext)(s,e),e.fatal?t.abort():t.dirty()},get path(){return s.path}};if(i.addIssue=i.addIssue.bind(i),\"preprocess\"===r.type){const e=r.transform(s.data,i);return s.common.issues.length?{status:\"dirty\",value:s.data}:s.common.async?Promise.resolve(e).then((e=>this._def.schema._parseAsync({data:e,path:s.path,parent:s}))):this._def.schema._parseSync({data:e,path:s.path,parent:s})}if(\"refinement\"===r.type){const e=e=>{const t=r.refinement(e,i);if(s.common.async)return Promise.resolve(t);if(t instanceof Promise)throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");return e};if(!1===s.common.async){const r=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});return\"aborted\"===r.status?a.INVALID:(\"dirty\"===r.status&&t.dirty(),e(r.value),{status:t.value,value:r.value})}return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then((s=>\"aborted\"===s.status?a.INVALID:(\"dirty\"===s.status&&t.dirty(),e(s.value).then((()=>({status:t.value,value:s.value}))))))}if(\"transform\"===r.type){if(!1===s.common.async){const e=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});if(!(0,a.isValid)(e))return e;const n=r.transform(e.value,i);if(n instanceof Promise)throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");return{status:t.value,value:n}}return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then((e=>(0,a.isValid)(e)?Promise.resolve(r.transform(e.value,i)).then((e=>({status:t.value,value:e}))):e))}n.util.assertNever(r)}}t.ZodEffects=J,t.ZodTransformer=J,J.create=(e,t,s)=>new J({schema:e,typeName:oe.ZodEffects,effect:t,...u(s)}),J.createWithPreprocess=(e,t,s)=>new J({schema:t,effect:{type:\"preprocess\",transform:e},typeName:oe.ZodEffects,...u(s)});class Q extends c{_parse(e){return this._getType(e)===n.ZodParsedType.undefined?(0,a.OK)(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}t.ZodOptional=Q,Q.create=(e,t)=>new Q({innerType:e,typeName:oe.ZodOptional,...u(t)});class ee extends c{_parse(e){return this._getType(e)===n.ZodParsedType.null?(0,a.OK)(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}t.ZodNullable=ee,ee.create=(e,t)=>new ee({innerType:e,typeName:oe.ZodNullable,...u(t)});class te extends c{_parse(e){const{ctx:t}=this._processInputParams(e);let s=t.data;return t.parsedType===n.ZodParsedType.undefined&&(s=this._def.defaultValue()),this._def.innerType._parse({data:s,path:t.path,parent:t})}removeDefault(){return this._def.innerType}}t.ZodDefault=te,te.create=(e,t)=>new te({innerType:e,typeName:oe.ZodDefault,defaultValue:\"function\"==typeof t.default?t.default:()=>t.default,...u(t)});class se extends c{_parse(e){const{ctx:t}=this._processInputParams(e),s={...t,common:{...t.common,issues:[]}},r=this._def.innerType._parse({data:s.data,path:s.path,parent:{...s}});return(0,a.isAsync)(r)?r.then((e=>({status:\"valid\",value:\"valid\"===e.status?e.value:this._def.catchValue({get error(){return new o.ZodError(s.common.issues)},input:s.data})}))):{status:\"valid\",value:\"valid\"===r.status?r.value:this._def.catchValue({get error(){return new o.ZodError(s.common.issues)},input:s.data})}}removeCatch(){return this._def.innerType}}t.ZodCatch=se,se.create=(e,t)=>new se({innerType:e,typeName:oe.ZodCatch,catchValue:\"function\"==typeof t.catch?t.catch:()=>t.catch,...u(t)});class re extends c{_parse(e){if(this._getType(e)!==n.ZodParsedType.nan){const t=this._getOrReturnCtx(e);return(0,a.addIssueToContext)(t,{code:o.ZodIssueCode.invalid_type,expected:n.ZodParsedType.nan,received:t.parsedType}),a.INVALID}return{status:\"valid\",value:e.data}}}t.ZodNaN=re,re.create=e=>new re({typeName:oe.ZodNaN,...u(e)}),t.BRAND=Symbol(\"zod_brand\");class ie extends c{_parse(e){const{ctx:t}=this._processInputParams(e),s=t.data;return this._def.type._parse({data:s,path:t.path,parent:t})}unwrap(){return this._def.type}}t.ZodBranded=ie;class ae extends c{_parse(e){const{status:t,ctx:s}=this._processInputParams(e);if(s.common.async)return(async()=>{const e=await this._def.in._parseAsync({data:s.data,path:s.path,parent:s});return\"aborted\"===e.status?a.INVALID:\"dirty\"===e.status?(t.dirty(),(0,a.DIRTY)(e.value)):this._def.out._parseAsync({data:e.value,path:s.path,parent:s})})();{const e=this._def.in._parseSync({data:s.data,path:s.path,parent:s});return\"aborted\"===e.status?a.INVALID:\"dirty\"===e.status?(t.dirty(),{status:\"dirty\",value:e.value}):this._def.out._parseSync({data:e.value,path:s.path,parent:s})}}static create(e,t){return new ae({in:e,out:t,typeName:oe.ZodPipeline})}}t.ZodPipeline=ae;class ne extends c{_parse(e){const t=this._def.innerType._parse(e);return(0,a.isValid)(t)&&(t.value=Object.freeze(t.value)),t}}var oe;t.ZodReadonly=ne,ne.create=(e,t)=>new ne({innerType:e,typeName:oe.ZodReadonly,...u(t)}),t.custom=(e,t={},s)=>e?L.create().superRefine(((r,i)=>{var a,n;if(!e(r)){const e=\"function\"==typeof t?t(r):\"string\"==typeof t?{message:t}:t,o=null===(n=null!==(a=e.fatal)&&void 0!==a?a:s)||void 0===n||n,d=\"string\"==typeof e?{message:e}:e;i.addIssue({code:\"custom\",...d,fatal:o})}})):L.create(),t.late={object:N.lazycreate},function(e){e.ZodString=\"ZodString\",e.ZodNumber=\"ZodNumber\",e.ZodNaN=\"ZodNaN\",e.ZodBigInt=\"ZodBigInt\",e.ZodBoolean=\"ZodBoolean\",e.ZodDate=\"ZodDate\",e.ZodSymbol=\"ZodSymbol\",e.ZodUndefined=\"ZodUndefined\",e.ZodNull=\"ZodNull\",e.ZodAny=\"ZodAny\",e.ZodUnknown=\"ZodUnknown\",e.ZodNever=\"ZodNever\",e.ZodVoid=\"ZodVoid\",e.ZodArray=\"ZodArray\",e.ZodObject=\"ZodObject\",e.ZodUnion=\"ZodUnion\",e.ZodDiscriminatedUnion=\"ZodDiscriminatedUnion\",e.ZodIntersection=\"ZodIntersection\",e.ZodTuple=\"ZodTuple\",e.ZodRecord=\"ZodRecord\",e.ZodMap=\"ZodMap\",e.ZodSet=\"ZodSet\",e.ZodFunction=\"ZodFunction\",e.ZodLazy=\"ZodLazy\",e.ZodLiteral=\"ZodLiteral\",e.ZodEnum=\"ZodEnum\",e.ZodEffects=\"ZodEffects\",e.ZodNativeEnum=\"ZodNativeEnum\",e.ZodOptional=\"ZodOptional\",e.ZodNullable=\"ZodNullable\",e.ZodDefault=\"ZodDefault\",e.ZodCatch=\"ZodCatch\",e.ZodPromise=\"ZodPromise\",e.ZodBranded=\"ZodBranded\",e.ZodPipeline=\"ZodPipeline\",e.ZodReadonly=\"ZodReadonly\"}(oe=t.ZodFirstPartyTypeKind||(t.ZodFirstPartyTypeKind={})),t.instanceof=(e,s={message:`Input not instance of ${e.name}`})=>(0,t.custom)((t=>t instanceof e),s);const de=b.create;t.string=de;const le=I.create;t.number=le;const ue=re.create;t.nan=ue;const ce=Z.create;t.bigint=ce;const pe=T.create;t.boolean=pe;const he=k.create;t.date=he;const fe=w.create;t.symbol=fe;const me=C.create;t.undefined=me;const ye=z.create;t.null=ye;const _e=L.create;t.any=_e;const ve=P.create;t.unknown=ve;const ge=O.create;t.never=ge;const be=j.create;t.void=be;const xe=E.create;t.array=xe;const Ie=N.create;t.object=Ie;const Ze=N.strictCreate;t.strictObject=Ze;const Te=M.create;t.union=Te;const ke=D.create;t.discriminatedUnion=ke;const we=R.create;t.intersection=we;const Ce=V.create;t.tuple=Ce;const ze=$.create;t.record=ze;const Le=B.create;t.map=Le;const Pe=F.create;t.set=Pe;const Oe=K.create;t.function=Oe;const je=G.create;t.lazy=je;const Ee=W.create;t.literal=Ee;const Se=H.create;t.enum=Se;const Ne=q.create;t.nativeEnum=Ne;const Me=X.create;t.promise=Me;const Ae=J.create;t.effect=Ae,t.transformer=Ae;const De=Q.create;t.optional=De;const Ue=ee.create;t.nullable=Ue;const Re=J.createWithPreprocess;t.preprocess=Re;const Ve=ae.create;t.pipeline=Ve,t.ostring=()=>de().optional(),t.onumber=()=>le().optional(),t.oboolean=()=>pe().optional(),t.coerce={string:e=>b.create({...e,coerce:!0}),number:e=>I.create({...e,coerce:!0}),boolean:e=>T.create({...e,coerce:!0}),bigint:e=>Z.create({...e,coerce:!0}),date:e=>k.create({...e,coerce:!0})},t.NEVER=a.INVALID},205:t=>{t.exports=e}},s={};function r(e){var i=s[e];if(void 0!==i)return i.exports;var a=s[e]={exports:{}};return t[e].call(a.exports,a,a.exports,r),a.exports}return r.d=(e,t)=>{for(var s in t)r.o(t,s)&&!r.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},r(607)})()));\n//# sourceMappingURL=excalibur-ldtk.min.js.map","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"excalibur\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"excalibur\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ex\"] = factory(require(\"excalibur\"));\n\telse\n\t\troot[\"ex\"] = root[\"ex\"] || {}, root[\"ex\"][\"Plugin\"] = root[\"ex\"][\"Plugin\"] || {}, root[\"ex\"][\"Plugin\"][\"Ldtk\"] = factory(root[\"ex\"]);\n})(self, (__WEBPACK_EXTERNAL_MODULE__205__) => {\nreturn ","export const semver = /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\nexport const validateAndParse = (version) => {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n const match = version.match(semver);\n if (!match) {\n throw new Error(`Invalid argument not valid semver ('${version}' received)`);\n }\n match.shift();\n return match;\n};\nconst isWildcard = (s) => s === '*' || s === 'x' || s === 'X';\nconst tryParse = (v) => {\n const n = parseInt(v, 10);\n return isNaN(n) ? v : n;\n};\nconst forceType = (a, b) => typeof a !== typeof b ? [String(a), String(b)] : [a, b];\nconst compareStrings = (a, b) => {\n if (isWildcard(a) || isWildcard(b))\n return 0;\n const [ap, bp] = forceType(tryParse(a), tryParse(b));\n if (ap > bp)\n return 1;\n if (ap < bp)\n return -1;\n return 0;\n};\nexport const compareSegments = (a, b) => {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const r = compareStrings(a[i] || '0', b[i] || '0');\n if (r !== 0)\n return r;\n }\n return 0;\n};\n//# sourceMappingURL=utils.js.map","import { compareSegments, validateAndParse } from './utils';\n/**\n * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser.\n * This library supports the full semver specification, including comparing versions with different number of digits like `1.0.0`, `1.0`, `1`, and pre-release versions like `1.0.0-alpha`.\n * @param v1 - First version to compare\n * @param v2 - Second version to compare\n * @returns Numeric value compatible with the [Array.sort(fn) interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters).\n */\nexport const compareVersions = (v1, v2) => {\n // validate input and split into segments\n const n1 = validateAndParse(v1);\n const n2 = validateAndParse(v2);\n // pop off the patch\n const p1 = n1.pop();\n const p2 = n2.pop();\n // validate numbers\n const r = compareSegments(n1, n2);\n if (r !== 0)\n return r;\n // validate pre-release\n if (p1 && p2) {\n return compareSegments(p1.split('.'), p2.split('.'));\n }\n else if (p1 || p2) {\n return p1 ? -1 : 1;\n }\n return 0;\n};\n//# sourceMappingURL=compareVersions.js.map","import { compareVersions } from './compareVersions';\n/**\n * Compare [semver](https://semver.org/) version strings using the specified operator.\n *\n * @param v1 First version to compare\n * @param v2 Second version to compare\n * @param operator Allowed arithmetic operator to use\n * @returns `true` if the comparison between the firstVersion and the secondVersion satisfies the operator, `false` otherwise.\n *\n * @example\n * ```\n * compare('10.1.8', '10.0.4', '>'); // return true\n * compare('10.0.1', '10.0.1', '='); // return true\n * compare('10.1.1', '10.2.2', '<'); // return true\n * compare('10.1.1', '10.2.2', '<='); // return true\n * compare('10.1.1', '10.2.2', '>='); // return false\n * ```\n */\nexport const compare = (v1, v2, operator) => {\n // validate input operator\n assertValidOperator(operator);\n // since result of compareVersions can only be -1 or 0 or 1\n // a simple map can be used to replace switch\n const res = compareVersions(v1, v2);\n return operatorResMap[operator].includes(res);\n};\nconst operatorResMap = {\n '>': [1],\n '>=': [0, 1],\n '=': [0],\n '<=': [-1, 0],\n '<': [-1],\n '!=': [-1, 1],\n};\nconst allowedOperators = Object.keys(operatorResMap);\nconst assertValidOperator = (op) => {\n if (typeof op !== 'string') {\n throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);\n }\n if (allowedOperators.indexOf(op) === -1) {\n throw new Error(`Invalid operator, expected one of ${allowedOperators.join('|')}`);\n }\n};\n//# sourceMappingURL=compare.js.map","import { compare } from './compare';\nimport { compareSegments, validateAndParse } from './utils';\n/**\n * Match [npm semver](https://docs.npmjs.com/cli/v6/using-npm/semver) version range.\n *\n * @param version Version number to match\n * @param range Range pattern for version\n * @returns `true` if the version number is within the range, `false` otherwise.\n *\n * @example\n * ```\n * satisfies('1.1.0', '^1.0.0'); // return true\n * satisfies('1.1.0', '~1.0.0'); // return false\n * ```\n */\nexport const satisfies = (version, range) => {\n // clean input\n range = range.replace(/([><=]+)\\s+/g, '$1');\n // handle multiple comparators\n if (range.includes('||')) {\n return range.split('||').some((r) => satisfies(version, r));\n }\n else if (range.includes(' - ')) {\n const [a, b] = range.split(' - ', 2);\n return satisfies(version, `>=${a} <=${b}`);\n }\n else if (range.includes(' ')) {\n return range\n .trim()\n .replace(/\\s{2,}/g, ' ')\n .split(' ')\n .every((r) => satisfies(version, r));\n }\n // if no range operator then \"=\"\n const m = range.match(/^([<>=~^]+)/);\n const op = m ? m[1] : '=';\n // if gt/lt/eq then operator compare\n if (op !== '^' && op !== '~')\n return compare(version, range, op);\n // else range of either \"~\" or \"^\" is assumed\n const [v1, v2, v3, , vp] = validateAndParse(version);\n const [r1, r2, r3, , rp] = validateAndParse(range);\n const v = [v1, v2, v3];\n const r = [r1, r2 !== null && r2 !== void 0 ? r2 : 'x', r3 !== null && r3 !== void 0 ? r3 : 'x'];\n // validate pre-release\n if (rp) {\n if (!vp)\n return false;\n if (compareSegments(v, r) !== 0)\n return false;\n if (compareSegments(vp.split('.'), rp.split('.')) === -1)\n return false;\n }\n // first non-zero number\n const nonZero = r.findIndex((v) => v !== '0') + 1;\n // pointer to where segments can be >=\n const i = op === '~' ? 2 : nonZero > 1 ? nonZero : 1;\n // before pointer must be equal\n if (compareSegments(v.slice(0, i), r.slice(0, i)) !== 0)\n return false;\n // after pointer must be >=\n if (compareSegments(v.slice(i), r.slice(i)) === -1)\n return false;\n return true;\n};\n//# sourceMappingURL=satisfies.js.map","import { semver } from './utils';\n/**\n * Validate [semver](https://semver.org/) version strings.\n *\n * @param version Version number to validate\n * @returns `true` if the version number is a valid semver version number, `false` otherwise.\n *\n * @example\n * ```\n * validate('1.0.0-rc.1'); // return true\n * validate('1.0-rc.1'); // return false\n * validate('foo'); // return false\n * ```\n */\nexport const validate = (version) => typeof version === 'string' && /^[v\\d]/.test(version) && semver.test(version);\n/**\n * Validate [semver](https://semver.org/) version strings strictly. Will not accept wildcards and version ranges.\n *\n * @param version Version number to validate\n * @returns `true` if the version number is a valid semver version number `false` otherwise\n *\n * @example\n * ```\n * validate('1.0.0-rc.1'); // return true\n * validate('1.0-rc.1'); // return false\n * validate('foo'); // return false\n * ```\n */\nexport const validateStrict = (version) => typeof version === 'string' &&\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/.test(version);\n//# sourceMappingURL=validate.js.map","import { Actor, Entity, Vector, vec } from \"excalibur\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\nimport { LdtkEntityInstance, LdtkLayerInstance } from \"./types\";\r\nimport { Level } from \"./level\";\r\n\r\nexport class EntityLayer {\r\n public worldPos: Vector;\r\n public offset: Vector;\r\n public entities: Entity[] = [];\r\n public ldtkToEntity = new Map();\r\n public entityToLdtk = new Map();\r\n constructor(level: Level, public readonly ldtkLayer: LdtkLayerInstance, private resource: LdtkResource, public readonly order: number) {\r\n this.worldPos = vec(level.ldtkLevel.worldX, level.ldtkLevel.worldY);\r\n this.offset = vec(ldtkLayer.__pxTotalOffsetX, ldtkLayer.__pxTotalOffsetY);\r\n if (ldtkLayer.entityInstances) {\r\n for (let entity of ldtkLayer.entityInstances) {\r\n const entityMetadata = resource.projectMetadata.defs.entities.find(e => {\r\n return e.identifier === entity.__identifier\r\n });\r\n if (resource.factories.has(entity.__identifier)) {\r\n const factory = resource.factories.get(entity.__identifier);\r\n if (factory) {\r\n const newEntity = factory({\r\n type: entity.__identifier,\r\n worldPos: vec(entity.px[0], entity.px[1]).add(this.worldPos.add(this.offset)),\r\n entity,\r\n definition: entityMetadata,\r\n layer: this,\r\n });\r\n if (newEntity) {\r\n this.entities.push(newEntity);\r\n this.ldtkToEntity.set(entity, newEntity);\r\n this.entityToLdtk.set(newEntity, entity);\r\n }\r\n }\r\n } else {\r\n const actor = new Actor({\r\n name: entity.__identifier,\r\n pos: vec(entity.px[0], entity.px[1]).add(this.worldPos.add(this.offset)),\r\n width: entity.width,\r\n height: entity.height,\r\n anchor: vec(entityMetadata?.pivotX ?? 0, entityMetadata?.pivotY ?? 0),\r\n z: order\r\n });\r\n if (entity.__tile) {\r\n const ts = resource.tilesets.get(entity.__tile.tilesetUid);\r\n if (ts) {\r\n const tsxCoord = Math.floor(entity.__tile.x / entity.__tile.w);\r\n const tsyCoord = Math.floor(entity.__tile.y / entity.__tile.h);\r\n const sprite = ts.spritesheet.getSprite(tsxCoord, tsyCoord);\r\n if (sprite) {\r\n actor.graphics.use(sprite);\r\n }\r\n }\r\n }\r\n this.entities.push(actor);\r\n this.ldtkToEntity.set(entity, actor);\r\n this.entityToLdtk.set(actor, entity);\r\n }\r\n }\r\n }\r\n }\r\n\r\n runFactory(ldtkEntityIdentifier: string): Entity | undefined {\r\n if (this.resource.factories.has(ldtkEntityIdentifier)) {\r\n if (this.ldtkLayer.entityInstances) {\r\n for (let entity of this.ldtkLayer.entityInstances) {\r\n const entityMetadata = this.resource.projectMetadata.defs.entities.find(e => {\r\n return e.identifier === entity.__identifier\r\n });\r\n const factory = this.resource.factories.get(entity.__identifier);\r\n if (factory) {\r\n const newEntity = factory({\r\n type: entity.__identifier,\r\n worldPos: vec(entity.px[0], entity.px[1]).add(this.worldPos.add(this.offset)),\r\n entity,\r\n definition: entityMetadata,\r\n layer: this,\r\n });\r\n if (newEntity) {\r\n // remove any pre done entities if a factor covered it\r\n const preExisting = this.ldtkToEntity.get(entity);\r\n if (preExisting) {\r\n const index = this.entities.indexOf(preExisting);\r\n if (index > -1) {\r\n this.entities.splice(index, 1);\r\n this.ldtkToEntity.delete(entity);\r\n this.entityToLdtk.delete(preExisting);\r\n }\r\n }\r\n\r\n this.entities.push(newEntity);\r\n this.ldtkToEntity.set(entity, newEntity);\r\n this.entityToLdtk.set(newEntity, entity);\r\n return newEntity;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n getEntitiesByIdentifier(identifier: string): Entity[] {\r\n const ldtkEntities = this.getLdtkEntitiesByIdentifier(identifier);\r\n let results: Entity[] = [];\r\n for (const ldtk of ldtkEntities) {\r\n const maybeEntity = this.ldtkToEntity.get(ldtk);\r\n if (maybeEntity) {\r\n results.push(maybeEntity);\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n getEntitiesByField(fieldIdentifier: string, value?: any): Entity[] {\r\n const ldtkEntities = this.getLdtkEntitiesByField(fieldIdentifier, value);\r\n let results: Entity[] = [];\r\n for (const ldtk of ldtkEntities) {\r\n const maybeEntity = this.ldtkToEntity.get(ldtk);\r\n if (maybeEntity) {\r\n results.push(maybeEntity);\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Search layer for entities that match an identifier (case insensitive)\r\n * @param identifier \r\n * @returns \r\n */\r\n getLdtkEntitiesByIdentifier(identifier: string): LdtkEntityInstance[] {\r\n return this.ldtkLayer.entityInstances.filter(e => e.__identifier.toLocaleLowerCase() === identifier.toLowerCase());\r\n }\r\n\r\n /**\r\n * Search layer for entities that match a field and optionally a value (both case insensitive)\r\n * @param fieldIdentifier \r\n * @param value\r\n */\r\n getLdtkEntitiesByField(fieldIdentifier: string, value?: any): LdtkEntityInstance[] {\r\n return this.ldtkLayer.entityInstances.filter(e => {\r\n if (value !== undefined) {\r\n let normalizedValue = value;\r\n if (typeof value === 'string') {\r\n normalizedValue = value.toLocaleLowerCase();\r\n }\r\n\r\n const field = e.fieldInstances.find(f => f.__identifier.toLocaleLowerCase() === fieldIdentifier.toLocaleLowerCase());\r\n if (field) {\r\n return field.__value === normalizedValue;\r\n }\r\n return false;\r\n } else {\r\n return !!e.fieldInstances.find(f => f.__identifier.toLocaleLowerCase() === fieldIdentifier.toLocaleLowerCase());\r\n }\r\n });\r\n }\r\n}","\r\n\r\nexport type FileLoader = (path: string, contentType: 'json' | 'xml') => Promise;\r\n\r\nexport const FetchLoader: FileLoader = async (path: string, contentType: 'json' | 'xml') => {\r\n const response = await fetch(path);\r\n switch(contentType.toLowerCase()) {\r\n case 'xml': return await response.text();\r\n case 'json': return await response.json();\r\n default: return await response.text();\r\n }\r\n}","\r\nexport * from './ldtk-resource';\r\nexport * from './entity-layer';\r\nexport * from './file-loader';\r\nexport * from './intgrid-layer';\r\nexport * from './level-resource';\r\nexport * from './level';\r\nexport * from './loader-cache';\r\nexport * from './path-util';\r\nexport * from './tile-layer';\r\nexport * from './tileset';\r\nexport * from './types';","import { TileMap, Vector, vec } from \"excalibur\";\r\nimport { LdtkLayerInstance } from \"./types\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\nimport { Level } from \"./level\";\r\n\r\nexport class IntGridLayer {\r\n\r\n public ldtkLayer: LdtkLayerInstance;\r\n public worldPos: Vector;\r\n public offset: Vector;\r\n public tilemap!: TileMap;\r\n constructor(level: Level, ldtkLayer: LdtkLayerInstance, resource: LdtkResource, public readonly order: number) {\r\n this.worldPos = vec(level.ldtkLevel.worldX, level.ldtkLevel.worldY);\r\n this.offset = vec(ldtkLayer.__pxTotalOffsetX, ldtkLayer.__pxTotalOffsetY);\r\n this.ldtkLayer = ldtkLayer;\r\n if (ldtkLayer.intGridCsv.length) {\r\n\r\n const rows = ldtkLayer.__cHei;\r\n const columns = ldtkLayer.__cWid;\r\n this.tilemap = new TileMap({\r\n name: ldtkLayer.__identifier,\r\n pos: this.worldPos.add(this.offset),\r\n tileWidth: ldtkLayer.__gridSize,\r\n tileHeight: ldtkLayer.__gridSize,\r\n rows,\r\n columns,\r\n });\r\n\r\n // find the intgrid metadata\r\n const layerMetadata = resource.projectMetadata.defs.layers.find(l => {\r\n return ldtkLayer.__identifier === l.identifier;\r\n });\r\n\r\n if (layerMetadata) {\r\n const solidValue = layerMetadata.intGridValues.find(val => {\r\n return val?.identifier?.toLocaleLowerCase() === 'solid';\r\n });\r\n\r\n for (let i = 0; i < ldtkLayer.intGridCsv.length; i++) {\r\n const xCoord = i % columns;\r\n const yCoord = Math.floor(i / columns);\r\n const tile = this.tilemap.getTile(xCoord, yCoord);\r\n if (solidValue && ldtkLayer.intGridCsv[i] === solidValue.value) {\r\n tile.solid = true;\r\n }\r\n\r\n // TODO might be a mistake to treat 1 as solid if there isn't a labelled solid\r\n if (!solidValue && ldtkLayer.intGridCsv[i] === 1) {\r\n tile.solid = true;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}","import { TileLayer } from './tile-layer';\r\nimport { PathMap, pathRelativeToBase } from './path-util';\r\nimport { FetchLoader, FileLoader } from './file-loader';\r\nimport { LdtkEntityDefinition, LdtkEntityInstance, LdtkProjectMetadata } from './types';\r\nimport { compare } from 'compare-versions';\r\nimport { LoaderCache } from './loader-cache';\r\nimport { BoundingBox, Entity, ImageSource, Loadable, Scene, TransformComponent, Vector, vec } from 'excalibur';\r\nimport { LevelResource } from './level-resource';\r\nimport { Tileset } from './tileset';\r\nimport { Level } from './level';\r\nimport { EntityLayer } from './entity-layer';\r\nimport { IntGridLayer } from './intgrid-layer';\r\n\r\nexport interface AddToSceneOptions {\r\n /**\r\n * Optionally set the position to place the levels\r\n * \r\n * Default is vec(0, 0)\r\n */\r\n pos?: Vector;\r\n /**\r\n * Optionally add only specific levels to the scene\r\n * \r\n * Default includes all levels\r\n */\r\n levelFilter?: string[];\r\n\r\n /**\r\n * Optionally use the level world offsets, this is useful if your levels are arranged the way you want them\r\n * to appear in your game.\r\n * \r\n * Default is true\r\n */\r\n useLevelOffsets?: boolean;\r\n}\r\n\r\nexport interface FactoryProps {\r\n /**\r\n * Excalibur world position\r\n */\r\n worldPos: Vector;\r\n /**\r\n * LDtk name in UI\r\n */\r\n name?: string;\r\n /**\r\n * LDtk type in UI\r\n */\r\n type: string;\r\n /**\r\n * LDtk entity\r\n */\r\n entity: LdtkEntityInstance;\r\n /**\r\n * LDtk entity metadata\r\n */\r\n definition: LdtkEntityDefinition | undefined;\r\n /**\r\n * Layer\r\n */\r\n layer: EntityLayer;\r\n}\r\n\r\nexport interface LdtkResourceOptions {\r\n /**\r\n * Add a starting z index for the layers to use. By default the layers count up from 0.\r\n *\r\n * If you'd like to manually override a z-index on a layer use the 'zindex' custom property on a layer.\r\n */\r\n startZIndex?: number;\r\n\r\n /**\r\n * Default true. If false, only tilemap will be parsed and displayed, it's up to you to wire up any excalibur behavior.\r\n * Automatically wires excalibur to the following\r\n * * Wire up current scene camera\r\n *\r\n * Read more at excaliburjs.com!\r\n */\r\n useExcaliburWiring?: boolean;\r\n\r\n /**\r\n * Sets excalibur's background color to match the LDtk map\r\n */\r\n useMapBackgroundColor?: boolean;\r\n\r\n /**\r\n * The pathMap helps work around odd things bundlers do with static files by providing a way to redirect the original\r\n * source paths in the LDtk files to new locations.\r\n *\r\n * When the LDtk resource comes across something that matches `path`, it will use the output string instead.\r\n * \r\n * Example:\r\n * ```typescript\r\n * const newResource = new LdtkResource('./example-city.ldtk', {\r\n * pathMap: [\r\n * // If the \"path\" is included in the source path, the output will be used\r\n * { path: 'cone.png', output: '/static/assets/cone.png' },\r\n * // Regex matching with special [match] in output string that is replaced with the first match from the regex\r\n * { path: /(.*\\..*$)/, output: '/static/assets/[match]'}\r\n * ]\r\n * }\r\n * ```\r\n */\r\n pathMap?: PathMap;\r\n\r\n /**\r\n * Optionally provide a custom file loader implementation instead of using the built in ajax (fetch) loader\r\n * that takes a path and returns file data\r\n * \r\n */\r\n fileLoader?: FileLoader;\r\n\r\n /**\r\n * By default `true`, means LDtk files must pass the plugins Typed parse pass.\r\n *\r\n * If you have something that the LDtk plugin does not expect, you can set this to false and it will do it's best\r\n * to parse the LDtk source map file.\r\n */\r\n strict?: boolean;\r\n\r\n /**\r\n * Plugin will operate in headless mode and skip all graphics related\r\n * excalibur items including creating ImageSource's for LDtk items.\r\n *\r\n * Default false.\r\n */\r\n headless?: boolean;\r\n\r\n /**\r\n * Keeps the camera viewport within the bounds of the TileMap, uses the first tile layer's bounds.\r\n *\r\n * Defaults true, if false the camera will use the layer bounds to keep the camera from showing the background.\r\n */\r\n useTilemapCameraStrategy?: boolean;\r\n\r\n /**\r\n * Configure custom Actor/Entity factory functions to construct Actors/Entities\r\n * given a LDtk type name\r\n */\r\n entityIdentifierFactories?: Record Entity | undefined>;\r\n}\r\n\r\nexport class LdtkResource implements Loadable {\r\n public static supportedLdtkVersion = \"1.5.3\";\r\n public projectMetadata!: LdtkProjectMetadata;\r\n data!: LdtkProjectMetadata;\r\n\r\n\r\n public tilesets = new Map();\r\n public levels = new Map();\r\n public levelsByName = new Map();\r\n public factories = new Map Entity | undefined>();\r\n public fileLoader: FileLoader = FetchLoader;\r\n public pathMap: PathMap | undefined;\r\n\r\n private _imageLoader = new LoaderCache(ImageSource);\r\n private _levelLoader = new LoaderCache(LevelResource);\r\n\r\n\r\n public readonly startZIndex: number = 0;\r\n public readonly textQuality: number = 4;\r\n public readonly useExcaliburWiring: boolean = true;\r\n public readonly useMapBackgroundColor: boolean = false;\r\n public readonly useTilemapCameraStrategy: boolean = false;\r\n public readonly headless: boolean = false;\r\n public readonly strict: boolean = true;\r\n\r\n constructor(public readonly path: string, options?: LdtkResourceOptions) {\r\n const {\r\n useExcaliburWiring,\r\n useTilemapCameraStrategy,\r\n entityIdentifierFactories,\r\n pathMap,\r\n useMapBackgroundColor,\r\n fileLoader,\r\n strict,\r\n headless,\r\n startZIndex\r\n } = { ...options };\r\n this.strict = strict ?? this.strict;\r\n this.headless = headless ?? this.headless;\r\n this.useExcaliburWiring = useExcaliburWiring ?? this.useExcaliburWiring;\r\n this.useTilemapCameraStrategy = useTilemapCameraStrategy ?? this.useTilemapCameraStrategy;\r\n this.useMapBackgroundColor = useMapBackgroundColor ?? this.useMapBackgroundColor;\r\n this.startZIndex = startZIndex ?? this.startZIndex;\r\n this.fileLoader = fileLoader ?? this.fileLoader;\r\n this.pathMap = pathMap;\r\n for (const key in entityIdentifierFactories) {\r\n this.registerEntityIdentifierFactory(key, entityIdentifierFactories[key]);\r\n }\r\n\r\n }\r\n async load(): Promise {\r\n const data = await this.fileLoader(this.path, 'json');\r\n if (this.strict) {\r\n try {\r\n this.projectMetadata = LdtkProjectMetadata.parse(data);\r\n } catch (e) {\r\n console.error(`Could not parse LDtk map from location ${this.path}.\\nExcalibur only supports the latest version of LDtk formats as of the plugin's release.`);\r\n console.error(`Is your map file corrupted or being interpreted as the wrong type?`)\r\n throw e;\r\n }\r\n } else {\r\n this.projectMetadata = data as LdtkProjectMetadata;\r\n }\r\n\r\n if (compare(LdtkResource.supportedLdtkVersion, this.projectMetadata.jsonVersion ?? '0.0.0', \">\")) {\r\n console.warn(`The excalibur ldtk plugin officially supports ${LdtkResource.supportedLdtkVersion}+, the current map has LDtk version ${this.projectMetadata.jsonVersion}`)\r\n }\r\n\r\n // iterate through the defs\r\n // load the tilesets\r\n const imagesToLoad: Promise[] = [];\r\n for (let tileset of this.projectMetadata.defs.tilesets) {\r\n if (tileset.relPath) {\r\n const imagePath = pathRelativeToBase(this.path, tileset.relPath, this.pathMap);\r\n const image = this._imageLoader.getOrAdd(imagePath);\r\n const friendlyTileset = new Tileset({\r\n image,\r\n ldtkTileset: tileset\r\n });\r\n this.tilesets.set(tileset.uid, friendlyTileset);\r\n } else {\r\n if (tileset.identifier !== 'Internal_Icons') {\r\n console.warn(`No tileset image provided for ${tileset.identifier}`);\r\n }\r\n }\r\n }\r\n\r\n // iterate through the levels\r\n // load the level metadata\r\n for (let level of this.projectMetadata.levels) {\r\n if (level.externalRelPath) {\r\n // external levels\r\n const levelPath = pathRelativeToBase(this.path, level.externalRelPath, this.pathMap);\r\n this._levelLoader.getOrAdd(levelPath, this, {\r\n headless: this.headless,\r\n strict: this.strict,\r\n fileLoader: this.fileLoader,\r\n imageLoader: this._imageLoader,\r\n pathMap: this.pathMap\r\n });\r\n } else {\r\n // embedded levels\r\n const friendlyLevel = new Level(level, this);\r\n this.levels.set(level.uid, friendlyLevel);\r\n this.levelsByName.set(level.identifier, friendlyLevel);\r\n }\r\n }\r\n\r\n await Promise.all([this._imageLoader.load(), this._levelLoader.load()]);\r\n this._levelLoader.values().forEach(level => {\r\n this.levels.set(level.data.ldtkLevel.uid, level.data);\r\n this.levelsByName.set(level.data.ldtkLevel.identifier, level.data);\r\n });\r\n\r\n return this.data = this.projectMetadata;\r\n };\r\n\r\n isLoaded(): boolean {\r\n return !!this.data;\r\n }\r\n\r\n registerEntityIdentifierFactory(ldtkEntityIdentifier: string, factory: (props: FactoryProps) => Entity | undefined): void {\r\n this.factories.set(ldtkEntityIdentifier, factory);\r\n if (this.isLoaded()) {\r\n for (let entityLayer of this.getEntityLayers()) {\r\n entityLayer.runFactory(ldtkEntityIdentifier);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get a level by identifier\r\n * @param identifier \r\n * @returns \r\n */\r\n getLevel(identifier: string): Level | undefined {\r\n return this.levelsByName.get(identifier);\r\n }\r\n\r\n /**\r\n * Get the entity layers, optionally provide a level identifier to filter to\r\n * @param identifier \r\n */\r\n getEntityLayers(identifier?: string): EntityLayer[] {\r\n let results: EntityLayer[] = [];\r\n if (identifier) {\r\n const level = this.getLevel(identifier);\r\n if (level) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof EntityLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const level of this.levels.values()) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof EntityLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return results\r\n }\r\n\r\n getTileLayers(identifier?: string): TileLayer[] {\r\n let results: TileLayer[] = [];\r\n if (identifier) {\r\n const level = this.getLevel(identifier);\r\n if (level) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof TileLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const level of this.levels.values()) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof TileLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n getIntGridLayers(identifier?: string): IntGridLayer[] {\r\n let results: IntGridLayer[] = [];\r\n if (identifier) {\r\n const level = this.getLevel(identifier);\r\n if (level) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof IntGridLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const level of this.levels.values()) {\r\n for (let layer of level.layers) {\r\n if (layer instanceof IntGridLayer) {\r\n results.push(layer);\r\n }\r\n }\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Search layer for entities that match an identifier (case insensitive)\r\n * @param identifier \r\n * @returns \r\n */\r\n getLdtkEntitiesByIdentifier(identifier: string): LdtkEntityInstance[] {\r\n let results: LdtkEntityInstance[] = [];\r\n const layers = this.getEntityLayers();\r\n for (let layer of layers) {\r\n results = results.concat(layer.getLdtkEntitiesByIdentifier(identifier));\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Search layer for entities that match a field and optionally a value (both case insensitive)\r\n * @param fieldIdentifier \r\n * @param value\r\n */\r\n getLdtkEntitiesByField(fieldIdentifier: string, value?: any): LdtkEntityInstance[] {\r\n let results: LdtkEntityInstance[] = [];\r\n const layers = this.getEntityLayers();\r\n for (let layer of layers) {\r\n results = results.concat(layer.getLdtkEntitiesByField(fieldIdentifier, value));\r\n }\r\n return results;\r\n }\r\n\r\n addToScene(scene: Scene, options?: AddToSceneOptions) {\r\n const { pos, useLevelOffsets } = {pos: vec(0, 0), useLevelOffsets: true, ...options};\r\n\r\n for (let [id, level] of this.levels.entries()) {\r\n if (options?.levelFilter?.length) {\r\n if (!options.levelFilter.includes(level.ldtkLevel.identifier)) {\r\n continue;\r\n }\r\n }\r\n for (let layer of level.layers) {\r\n if (layer instanceof TileLayer || layer instanceof IntGridLayer) {\r\n layer.tilemap.pos = layer.tilemap.pos.add(pos);\r\n if (!useLevelOffsets) {\r\n layer.tilemap.pos = layer.tilemap.pos.sub(layer.worldPos);\r\n }\r\n scene.add(layer.tilemap)\r\n } else {\r\n for (let entity of layer.entities) {\r\n const tx = entity.get(TransformComponent);\r\n if (tx) {\r\n tx.pos = tx.pos.add(pos);\r\n if (!useLevelOffsets) {\r\n tx.pos = tx.pos.sub(layer.worldPos);\r\n }\r\n }\r\n scene.add(entity);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(this.useExcaliburWiring) {\r\n const camera = this.getLdtkEntitiesByField('camera', true)[0];\r\n if (camera) {\r\n scene.camera.pos = vec(camera.px[0], camera.px[0]);\r\n const zoom = camera.fieldInstances.find(f => f.__identifier.toLocaleLowerCase() === 'zoom');\r\n if (zoom) {\r\n scene.camera.zoom = +zoom.__value;\r\n }\r\n }\r\n }\r\n\r\n if (this.useTilemapCameraStrategy) {\r\n let bounds = new BoundingBox();\r\n for (const level of this.levels.values()) {\r\n const firstTileLayer = this.getTileLayers(level.ldtkLevel.identifier)[0];\r\n if (firstTileLayer) {\r\n bounds = bounds.combine(\r\n BoundingBox.fromDimension(\r\n firstTileLayer.tilemap.tileWidth * firstTileLayer.tilemap.columns,\r\n firstTileLayer.tilemap.tileHeight * firstTileLayer.tilemap.rows,\r\n Vector.Zero,\r\n firstTileLayer.tilemap.pos)\r\n );\r\n }\r\n }\r\n scene.camera.strategy.limitCameraBounds(bounds);\r\n }\r\n\r\n if (this.useMapBackgroundColor) {\r\n for (let [id, level] of this.levels.entries()) {\r\n if (options?.levelFilter?.length) {\r\n if (!options.levelFilter.includes(level.ldtkLevel.identifier)) {\r\n continue;\r\n }\r\n }\r\n scene.backgroundColor = level.backgroundColor;\r\n break;\r\n }\r\n }\r\n\r\n\r\n }\r\n}","import { ImageSource, Loadable } from \"excalibur\";\r\nimport { PathMap } from \"./path-util\";\r\nimport { LoaderCache } from \"./loader-cache\";\r\nimport { FetchLoader, FileLoader } from \"./file-loader\";\r\nimport { Level } from \"./level\";\r\nimport { LdtkLevel } from \"./types\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\n\r\nexport interface LevelResourceOptions {\r\n headless?: boolean;\r\n strict?: boolean;\r\n fileLoader?: FileLoader;\r\n imageLoader?: LoaderCache;\r\n pathMap?: PathMap;\r\n}\r\n\r\n/**\r\n * Loads LDtk levels that are stored in separate files\r\n */\r\nexport class LevelResource implements Loadable {\r\n private fileLoader: FileLoader = FetchLoader;\r\n private imageLoader: LoaderCache;\r\n private pathMap?: PathMap;\r\n public readonly strict: boolean = true;\r\n public readonly headless: boolean = false;\r\n constructor(public readonly path: string, public readonly resource: LdtkResource, options?: LevelResourceOptions) {\r\n const { headless, strict, fileLoader, imageLoader, pathMap } = { ...options };\r\n this.fileLoader = fileLoader ?? this.fileLoader;\r\n this.strict = strict ?? this.strict;\r\n this.headless = headless ?? this.headless;\r\n this.imageLoader = imageLoader ?? new LoaderCache(ImageSource);\r\n this.pathMap = pathMap ?? this.pathMap;\r\n }\r\n data!: Level;\r\n async load(): Promise {\r\n const data = await this.fileLoader(this.path, 'json');\r\n let level: LdtkLevel;\r\n if (this.strict) {\r\n try {\r\n level = LdtkLevel.parse(data)\r\n } catch (e) {\r\n console.error(`Could not parse LDtk level data at ${this.path} are you sure a level is there and not corrupt?`);\r\n throw e;\r\n }\r\n } else {\r\n level = data as LdtkLevel;\r\n }\r\n return this.data = new Level(level, this.resource);\r\n }\r\n isLoaded(): boolean {\r\n return !!this.data;\r\n }\r\n\r\n}","import { Color } from \"excalibur\";\r\nimport { EntityLayer } from \"./entity-layer\";\r\nimport { IntGridLayer } from \"./intgrid-layer\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\nimport { TileLayer } from \"./tile-layer\";\r\nimport { LdtkLevel } from \"./types\";\r\n\r\nexport class Level {\r\n\r\n public backgroundColor?: Color;\r\n public layers: (TileLayer | IntGridLayer | EntityLayer)[] = []; \r\n\r\n constructor(public ldtkLevel: LdtkLevel, public resource: LdtkResource) {\r\n if (ldtkLevel.__bgColor) {\r\n this.backgroundColor = Color.fromHex(ldtkLevel.__bgColor);\r\n }\r\n if (ldtkLevel.layerInstances) {\r\n let order = resource.startZIndex;\r\n let layers = ldtkLevel.layerInstances.slice().reverse();\r\n for (let layer of layers) {\r\n if (layer.entityInstances?.length !== 0) {\r\n this.layers.push(new EntityLayer(this, layer, resource, order));\r\n }\r\n\r\n if (layer.gridTiles?.length !== 0) {\r\n this.layers.push(new TileLayer(this, layer, resource, order));\r\n }\r\n\r\n if (layer.intGridCsv?.length !== 0) {\r\n this.layers.push(new IntGridLayer(this, layer, resource, order));\r\n }\r\n order++;\r\n }\r\n }\r\n }\r\n}","export interface CanLoad {\r\n load(): Promise;\r\n }\r\n \r\n /**\r\n * Read through cache for loadables\r\n */\r\n export class LoaderCache {\r\n private _loaded = false;\r\n cache = new Map();\r\n \r\n constructor(public readonly type: new (...args: any[]) => T){}\r\n \r\n getOrAdd(...args: any[]): T {\r\n let resource = this.cache.get(args.join('+'));\r\n if (resource) {\r\n return resource;\r\n }\r\n \r\n resource = new this.type(...args);\r\n this.cache.set(args.join('+'), resource);\r\n return resource;\r\n }\r\n \r\n values(): T[] {\r\n if (this._loaded) {\r\n return Array.from(this.cache.values());\r\n }\r\n throw new Error(`Read through cache not yet loaded! No values to return!`);\r\n }\r\n \r\n async load() {\r\n const resources = Array.from(this.cache.entries());\r\n const results = await Promise.allSettled(resources.map(i => i[1].load()));\r\n \r\n // Check for errors loading resources\r\n let errored = 0;\r\n for (let i = 0; i < results.length; i++) {\r\n const result = results[i];\r\n if (result.status === 'rejected') {\r\n console.error(`Error loading resource at ${resources[i][0]}, is your pathMap correct? or your LDtk map corrupted?`, result.reason);\r\n errored++;\r\n }\r\n }\r\n if (errored) {\r\n throw new Error(`Error loading ${errored} resources`);\r\n }\r\n this._loaded = true;\r\n }\r\n }","\r\n\r\nexport type PathMap = { path: string | RegExp, output: string }[];\r\n\r\nexport function filenameFromPath(inputPath: string): string {\r\n const filenameExpression = /[^/\\\\&\\?]+\\.\\w{2,4}(?=([\\#\\?&].*$|$))/ig\r\n\r\n const matches = inputPath.match(filenameExpression);\r\n\r\n if (matches) {\r\n const match = matches[0];\r\n return match;\r\n }\r\n\r\n throw new Error(`Could not locate filename from path: ${inputPath}`);\r\n}\r\n\r\nexport function mapPath(inputPath: string, pathMap: PathMap): string {\r\n\r\n for (const { path, output } of pathMap) {\r\n if (typeof path === 'string') {\r\n if (inputPath.includes(path)) {\r\n return output;\r\n }\r\n } else {\r\n const match = inputPath.match(path);\r\n if (match) {\r\n return output.replace('[match]', match[0]);;\r\n }\r\n }\r\n }\r\n return inputPath;\r\n}\r\n\r\nexport function pathInMap(inputPath: string, pathMap?: PathMap): boolean {\r\n if (!pathMap) return false;\r\n for (const { path, output } of pathMap) {\r\n if (typeof path === 'string') {\r\n if (inputPath.includes(path)) {\r\n return true;\r\n }\r\n } else {\r\n const match = inputPath.match(path);\r\n if (match) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n\r\nexport function pathRelativeToBase(basePath: string, relativeToBase: string, pathMap?: PathMap) {\r\n if (pathInMap(relativeToBase, pathMap) && pathMap) {\r\n return mapPath(relativeToBase, pathMap);\r\n }\r\n\r\n // Use absolute path if specified\r\n if (relativeToBase.indexOf('/') === 0) {\r\n return relativeToBase;\r\n }\r\n\r\n const originSplit = basePath.split('/');\r\n const relativeSplit = relativeToBase.split('/');\r\n // if origin path is a file, remove it so it's a directory\r\n if (originSplit[originSplit.length - 1].includes('.')) {\r\n originSplit.pop();\r\n }\r\n return originSplit.concat(relativeSplit).join('/');\r\n}","import { TileMap, Vector, vec } from \"excalibur\";\r\nimport { LdtkResource } from \"./ldtk-resource\";\r\nimport { LdtkLayerInstance } from \"./types\";\r\nimport { Level } from \"./level\";\r\n\r\n\r\nexport class TileLayer {\r\n public ldtkLayer: LdtkLayerInstance;\r\n public worldPos: Vector;\r\n public offset: Vector;\r\n public tilemap: TileMap;\r\n constructor(level: Level, ldtkLayer: LdtkLayerInstance, resource: LdtkResource, public readonly order: number) {\r\n this.worldPos = vec(level.ldtkLevel.worldX, level.ldtkLevel.worldY);\r\n this.offset = vec(ldtkLayer.__pxTotalOffsetX, ldtkLayer.__pxTotalOffsetY);\r\n this.ldtkLayer = ldtkLayer;\r\n this.tilemap = new TileMap({\r\n name: ldtkLayer.__identifier,\r\n pos: this.worldPos.add(this.offset),\r\n tileWidth: ldtkLayer.__gridSize,\r\n tileHeight: ldtkLayer.__gridSize,\r\n rows: ldtkLayer.__cHei,\r\n columns: ldtkLayer.__cWid,\r\n });\r\n this.tilemap.z = order;\r\n\r\n for (let tile of ldtkLayer.gridTiles) {\r\n const xCoord = Math.floor(tile.px[0] / ldtkLayer.__gridSize);\r\n const yCoord = Math.floor(tile.px[1] / ldtkLayer.__gridSize);\r\n const exTile = this.tilemap.getTile(xCoord, yCoord);\r\n if (ldtkLayer.__tilesetDefUid) {\r\n const ts = resource.tilesets.get(ldtkLayer.__tilesetDefUid);\r\n if (ts) {\r\n const tsxCoord = Math.floor(tile.src[0] / ts.ldtkTileset.tileGridSize);\r\n const tsyCoord = Math.floor(tile.src[1] / ts.ldtkTileset.tileGridSize);\r\n const sprite = ts.spritesheet.getSprite(tsxCoord, tsyCoord);\r\n if (sprite) {\r\n exTile.addGraphic(sprite);\r\n } else {\r\n console.error('Could not find sprite in LDtk spritesheet at', tsxCoord, tsyCoord);\r\n }\r\n }\r\n } else {\r\n console.error('Could not tileset in LDtk', ldtkLayer.__tilesetDefUid, ldtkLayer.__tilesetRelPath);\r\n }\r\n }\r\n }\r\n}","import { ImageSource, SpriteSheet } from \"excalibur\";\r\nimport { LdtkTilesetDefinition } from \"./types\";\r\n\r\nexport interface TilesetOptions {\r\n image: ImageSource,\r\n ldtkTileset: LdtkTilesetDefinition\r\n}\r\n\r\nexport class Tileset {\r\n public readonly image: ImageSource;\r\n public readonly ldtkTileset: LdtkTilesetDefinition;\r\n public readonly spritesheet: SpriteSheet;\r\n constructor(options: TilesetOptions) {\r\n const {image, ldtkTileset} = options;\r\n this.image = image;\r\n this.ldtkTileset = ldtkTileset;\r\n this.spritesheet = SpriteSheet.fromImageSource({\r\n image,\r\n grid: {\r\n rows: ldtkTileset.pxHei / ldtkTileset.tileGridSize,\r\n columns: ldtkTileset.pxWid / ldtkTileset.tileGridSize,\r\n spriteHeight: ldtkTileset.tileGridSize,\r\n spriteWidth: ldtkTileset.tileGridSize\r\n }\r\n });\r\n }\r\n}","import { z } from 'zod';\r\n\r\n\r\n\r\nconst LdtkTilesetRectangle = z.object({\r\n h: z.number(),\r\n tilesetUid: z.number(),\r\n w: z.number(),\r\n x: z.number(),\r\n y: z.number()\r\n});\r\nconst LdtkPixel = z.tuple([z.number(), z.number()]);\r\nconst LdtkFieldInstance = z.object({\r\n __identifier: z.string(),\r\n __tile: LdtkTilesetRectangle.nullable(),\r\n __type: z.string(),//z.union([z.literal('Int'), z.literal('Float'), z.literal('String'), z.literal('Bool'), z.literal('Enum')]), // TODO this might not work with ENUM\r\n __value: z.any(),\r\n defUid: z.number()\r\n})\r\nconst LdtkTileInstance = z.object({\r\n a: z.number(),\r\n f: z.number(), // 2-bit int 0bXY flip\r\n px: LdtkPixel,\r\n src: LdtkPixel,\r\n t: z.number()\r\n});\r\n\r\nexport const LdtkEntityInstance = z.object({\r\n __grid: LdtkPixel,\r\n __identifier: z.string(),\r\n __pivot: LdtkPixel,\r\n __smartColor: z.string(),\r\n __tags: z.array(z.string()),\r\n __tile: LdtkTilesetRectangle.nullable(),\r\n __worldX: z.number().nullable(),\r\n __worldY: z.number().nullable(),\r\n defUid: z.number(),\r\n fieldInstances: z.array(LdtkFieldInstance),\r\n height: z.number(),\r\n iid: z.string(),\r\n px: LdtkPixel,\r\n width: z.number()\r\n});\r\nexport type LdtkEntityInstance = z.infer;\r\n\r\nexport const LdtkLayerInstance = z.object({\r\n __cHei: z.number(),\r\n __cWid: z.number(),\r\n __gridSize: z.number(),\r\n __identifier: z.string(),\r\n __opacity: z.number(),\r\n __pxTotalOffsetX: z.number(),\r\n __pxTotalOffsetY: z.number(),\r\n __tilesetDefUid: z.number().nullable(),\r\n __tilesetRelPath:z.string().nullable(),\r\n __type: z.union([z.literal('IntGrid'), z.literal('Entities'), z.literal('Tiles'), z.literal('AutoLayer')]),\r\n autoLayerTiles: z.array(LdtkTileInstance), // only in auto layers\r\n entityInstances: z.array(LdtkEntityInstance),// only in entity layers\r\n gridTiles: z.array(LdtkTileInstance),\r\n iid: z.string(),\r\n intGridCsv: z.array(z.number()), // __cWid x __cHei, 0 means empty, values start at 1\r\n layerDefUid: z.number(),\r\n levelId: z.number(),\r\n overrideTilesetUid: z.number().nullable(),\r\n pxOffsetX: z.number(),\r\n pxOffsetY: z.number(),\r\n visible: z.boolean()\r\n});\r\nexport type LdtkLayerInstance = z.infer;\r\n\r\nexport const LdtkLevel = z.object({\r\n __bgColor: z.string().nullable(),\r\n bgColor: z.string().nullable(),\r\n __bgPos: z.object({\r\n cropRect: z.array(z.tuple([z.number(), z.number(), z.number(), z.number()])), // cropX, cropY, cropWidth, cropHeight\r\n scale: z.tuple([z.number(), z.number()]),\r\n topLeftPx: LdtkPixel\r\n }).nullable(),\r\n __neighbours: z.array(z.object({\r\n dir: z.union([z.literal('n'), z.literal('s'), z.literal('w'), z.literal('e'), z.literal('ne'), z.literal('nw'), z.literal('se'), z.literal('sw'), z.literal('o'), z.literal('<'), z.literal('>')]),\r\n levelIid: z.string()\r\n })),\r\n bgRelPath: z.string().nullable(),\r\n externalRelPath: z.string().nullable(),\r\n fieldInstances: z.array(LdtkFieldInstance),\r\n identifier: z.string(),\r\n iid: z.string(),\r\n layerInstances: z.array(LdtkLayerInstance).nullable(), // null if the save levels separately is enabled\r\n pxHei: z.number(),\r\n pxWid: z.number(),\r\n uid: z.number(),\r\n worldDepth: z.number(),\r\n worldX: z.number(),\r\n worldY: z.number()\r\n});\r\nexport type LdtkLevel = z.infer;\r\n\r\nconst LdtkWorld = z.object({\r\n identifier: z.string(),\r\n iid: z.string(),\r\n levels: z.array(LdtkLevel),\r\n worldGridHeight:z.number(),\r\n worldGridWidth: z.number(),\r\n // TODO is this a typo Vania?\r\n worldLayout: z.union([z.literal('Free'), z.literal('GridVania'), z.literal('LinearHorizontal'), z.literal('LinearVertical')]),\r\n});\r\nexport type LdtkWorld = z.infer;\r\n\r\nconst LdtkEnumValueDefinition = z.object({\r\n color: z.number(),\r\n id: z.string(),\r\n tileRect: LdtkTilesetRectangle.nullable()\r\n});\r\n\r\nconst LdtkEnumDefinition = z.object({\r\n externalRelPath: z.string().nullable(),\r\n iconTilesetUid: z.number().nullable(),\r\n identifier: z.string(),\r\n tags: z.array(z.string()),\r\n uid: z.number(),\r\n values: z.array(LdtkEnumValueDefinition)\r\n})\r\n\r\nexport type LdtkEnumDefinition = z.infer;\r\n\r\nconst LdtkTilesetDefinition = z.object({\r\n __cHei: z.number(),\r\n __cWid: z.number(),\r\n customData: z.array(z.object({\r\n data: z.string(),\r\n tileId: z.number()\r\n })),\r\n embedAtlas: z.string().nullable(),\r\n enumsTags: z.optional(z.array(z.object({\r\n enumValueId: z.string(),\r\n tileIds: z.array(z.number())\r\n }))),\r\n identifier: z.string(),\r\n padding: z.number(),\r\n pxHei: z.number(),\r\n pxWid: z.number(),\r\n relPath: z.string().nullable(),\r\n spacing: z.number(),\r\n tags: z.array(z.string()),\r\n tagsSourceEnumUid: z.number().nullable(),\r\n tileGridSize: z.number(),\r\n uid: z.number()\r\n})\r\nexport type LdtkTilesetDefinition = z.infer;\r\n\r\nexport const LdtkLayerDefinition = z.object({\r\n __type: z.union([z.literal(\"IntGrid\"), z.literal(\"Entities\"), z.literal(\"Tiles\"), z.literal(\"AutoLayer\")]),\r\n autoSourceLayerDefUid: z.number().nullable(),\r\n displayOpacity: z.number(),\r\n gridSize: z.number(),\r\n identifier: z.string(),\r\n intGridValues: z.array(z.object({\r\n color: z.string(),\r\n groupUid: z.number(),\r\n identifier: z.string().nullable(),\r\n tile: LdtkTilesetRectangle.nullable(),\r\n value: z.number()\r\n })),\r\n intGridValuesGroups: z.array(z.object({\r\n color: z.string().nullable(),\r\n identifier: z.string().nullable(),\r\n uid: z.number()\r\n })),\r\n parallaxFactorX: z.number(),\r\n parallaxFactorY: z.number(),\r\n parallaxScaling: z.boolean(),\r\n pxOffsetX: z.number(),\r\n pxOffsetY: z.number(),\r\n tilesetDefUid: z.number().nullable(),\r\n uid: z.number(),\r\n});\r\nexport type LdtkLayerDefinition = z.infer;\r\n\r\nexport const LdtkEntityDefinition = z.object({\r\n color: z.string(),\r\n height: z.number(),\r\n identifier: z.string(),\r\n nineSliceBorders: z.array(z.number()),\r\n pivotX: z.number(),\r\n pivotY: z.number(),\r\n tileRect: LdtkTilesetRectangle.nullable(),\r\n tileRenderMode: z.union([\r\n z.literal(\"Cover\"),\r\n z.literal(\"FitInside\"),\r\n z.literal(\"Repeat\"),\r\n z.literal(\"Stretch\"),\r\n z.literal(\"FullSizeCropped\"),\r\n z.literal(\"FullSizeUncropped\"),\r\n z.literal(\"NineSlice\")\r\n ]),\r\n tilesetId: z.number().nullable(),\r\n uiTileRect: LdtkTilesetRectangle.nullable(),\r\n uid: z.number(),\r\n width: z.number()\r\n});\r\nexport type LdtkEntityDefinition = z.infer;\r\n\r\nconst LdtkDefinitions = z.object({\r\n tilesets: z.array(LdtkTilesetDefinition),\r\n enums: z.array(LdtkEnumDefinition),\r\n layers: z.array(LdtkLayerDefinition),\r\n entities: z.array(LdtkEntityDefinition)\r\n})\r\nexport type LdtkDefinitions = z.infer;\r\n\r\nexport const LdtkProjectMetadata = z.object({\r\n iid: z.string(),\r\n bgColor: z.string().nullable(),\r\n defs: LdtkDefinitions,\r\n externalLevels: z.boolean(),\r\n jsonVersion: z.string(),\r\n levels: z.array(LdtkLevel),\r\n toc: z.array(z.object({\r\n identifier: z.string(),\r\n instancesData: z.array(z.object({\r\n fields: z.any(),\r\n heiPx: z.number(),\r\n iids: z.string(),\r\n widPix: z.number(),\r\n worldX: z.number(),\r\n worldY: z.number()\r\n }))\r\n })),\r\n // Moving to worlds array\r\n worldGridHeight: z.number().nullable(),\r\n worldGridWidth: z.number().nullable(),\r\n // TODO is this a LDtk docs typo Vania?\r\n worldLayout: z.union([z.literal('Free'), z.literal('GridVania'), z.literal('LinearHorizontal'), z.literal('LinearVertical')]).nullable(),\r\n worlds: z.array(LdtkWorld)\r\n});\r\nexport type LdtkProjectMetadata = z.infer;\r\n\r\n\r\n\r\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ZodError = exports.quotelessJson = exports.ZodIssueCode = void 0;\nconst util_1 = require(\"./helpers/util\");\nexports.ZodIssueCode = util_1.util.arrayToEnum([\n \"invalid_type\",\n \"invalid_literal\",\n \"custom\",\n \"invalid_union\",\n \"invalid_union_discriminator\",\n \"invalid_enum_value\",\n \"unrecognized_keys\",\n \"invalid_arguments\",\n \"invalid_return_type\",\n \"invalid_date\",\n \"invalid_string\",\n \"too_small\",\n \"too_big\",\n \"invalid_intersection_types\",\n \"not_multiple_of\",\n \"not_finite\",\n]);\nconst quotelessJson = (obj) => {\n const json = JSON.stringify(obj, null, 2);\n return json.replace(/\"([^\"]+)\":/g, \"$1:\");\n};\nexports.quotelessJson = quotelessJson;\nclass ZodError extends Error {\n constructor(issues) {\n super();\n this.issues = [];\n this.addIssue = (sub) => {\n this.issues = [...this.issues, sub];\n };\n this.addIssues = (subs = []) => {\n this.issues = [...this.issues, ...subs];\n };\n const actualProto = new.target.prototype;\n if (Object.setPrototypeOf) {\n // eslint-disable-next-line ban/ban\n Object.setPrototypeOf(this, actualProto);\n }\n else {\n this.__proto__ = actualProto;\n }\n this.name = \"ZodError\";\n this.issues = issues;\n }\n get errors() {\n return this.issues;\n }\n format(_mapper) {\n const mapper = _mapper ||\n function (issue) {\n return issue.message;\n };\n const fieldErrors = { _errors: [] };\n const processError = (error) => {\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\") {\n issue.unionErrors.map(processError);\n }\n else if (issue.code === \"invalid_return_type\") {\n processError(issue.returnTypeError);\n }\n else if (issue.code === \"invalid_arguments\") {\n processError(issue.argumentsError);\n }\n else if (issue.path.length === 0) {\n fieldErrors._errors.push(mapper(issue));\n }\n else {\n let curr = fieldErrors;\n let i = 0;\n while (i < issue.path.length) {\n const el = issue.path[i];\n const terminal = i === issue.path.length - 1;\n if (!terminal) {\n curr[el] = curr[el] || { _errors: [] };\n // if (typeof el === \"string\") {\n // curr[el] = curr[el] || { _errors: [] };\n // } else if (typeof el === \"number\") {\n // const errorArray: any = [];\n // errorArray._errors = [];\n // curr[el] = curr[el] || errorArray;\n // }\n }\n else {\n curr[el] = curr[el] || { _errors: [] };\n curr[el]._errors.push(mapper(issue));\n }\n curr = curr[el];\n i++;\n }\n }\n }\n };\n processError(this);\n return fieldErrors;\n }\n toString() {\n return this.message;\n }\n get message() {\n return JSON.stringify(this.issues, util_1.util.jsonStringifyReplacer, 2);\n }\n get isEmpty() {\n return this.issues.length === 0;\n }\n flatten(mapper = (issue) => issue.message) {\n const fieldErrors = {};\n const formErrors = [];\n for (const sub of this.issues) {\n if (sub.path.length > 0) {\n fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];\n fieldErrors[sub.path[0]].push(mapper(sub));\n }\n else {\n formErrors.push(mapper(sub));\n }\n }\n return { formErrors, fieldErrors };\n }\n get formErrors() {\n return this.flatten();\n }\n}\nexports.ZodError = ZodError;\nZodError.create = (issues) => {\n const error = new ZodError(issues);\n return error;\n};\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getErrorMap = exports.setErrorMap = exports.defaultErrorMap = void 0;\nconst en_1 = __importDefault(require(\"./locales/en\"));\nexports.defaultErrorMap = en_1.default;\nlet overrideErrorMap = en_1.default;\nfunction setErrorMap(map) {\n overrideErrorMap = map;\n}\nexports.setErrorMap = setErrorMap;\nfunction getErrorMap() {\n return overrideErrorMap;\n}\nexports.getErrorMap = getErrorMap;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./errors\"), exports);\n__exportStar(require(\"./helpers/parseUtil\"), exports);\n__exportStar(require(\"./helpers/typeAliases\"), exports);\n__exportStar(require(\"./helpers/util\"), exports);\n__exportStar(require(\"./types\"), exports);\n__exportStar(require(\"./ZodError\"), exports);\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.errorUtil = void 0;\nvar errorUtil;\n(function (errorUtil) {\n errorUtil.errToObj = (message) => typeof message === \"string\" ? { message } : message || {};\n errorUtil.toString = (message) => typeof message === \"string\" ? message : message === null || message === void 0 ? void 0 : message.message;\n})(errorUtil = exports.errorUtil || (exports.errorUtil = {}));\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isAsync = exports.isValid = exports.isDirty = exports.isAborted = exports.OK = exports.DIRTY = exports.INVALID = exports.ParseStatus = exports.addIssueToContext = exports.EMPTY_PATH = exports.makeIssue = void 0;\nconst errors_1 = require(\"../errors\");\nconst en_1 = __importDefault(require(\"../locales/en\"));\nconst makeIssue = (params) => {\n const { data, path, errorMaps, issueData } = params;\n const fullPath = [...path, ...(issueData.path || [])];\n const fullIssue = {\n ...issueData,\n path: fullPath,\n };\n let errorMessage = \"\";\n const maps = errorMaps\n .filter((m) => !!m)\n .slice()\n .reverse();\n for (const map of maps) {\n errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;\n }\n return {\n ...issueData,\n path: fullPath,\n message: issueData.message || errorMessage,\n };\n};\nexports.makeIssue = makeIssue;\nexports.EMPTY_PATH = [];\nfunction addIssueToContext(ctx, issueData) {\n const issue = (0, exports.makeIssue)({\n issueData: issueData,\n data: ctx.data,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n (0, errors_1.getErrorMap)(),\n en_1.default, // then global default map\n ].filter((x) => !!x),\n });\n ctx.common.issues.push(issue);\n}\nexports.addIssueToContext = addIssueToContext;\nclass ParseStatus {\n constructor() {\n this.value = \"valid\";\n }\n dirty() {\n if (this.value === \"valid\")\n this.value = \"dirty\";\n }\n abort() {\n if (this.value !== \"aborted\")\n this.value = \"aborted\";\n }\n static mergeArray(status, results) {\n const arrayValue = [];\n for (const s of results) {\n if (s.status === \"aborted\")\n return exports.INVALID;\n if (s.status === \"dirty\")\n status.dirty();\n arrayValue.push(s.value);\n }\n return { status: status.value, value: arrayValue };\n }\n static async mergeObjectAsync(status, pairs) {\n const syncPairs = [];\n for (const pair of pairs) {\n syncPairs.push({\n key: await pair.key,\n value: await pair.value,\n });\n }\n return ParseStatus.mergeObjectSync(status, syncPairs);\n }\n static mergeObjectSync(status, pairs) {\n const finalObject = {};\n for (const pair of pairs) {\n const { key, value } = pair;\n if (key.status === \"aborted\")\n return exports.INVALID;\n if (value.status === \"aborted\")\n return exports.INVALID;\n if (key.status === \"dirty\")\n status.dirty();\n if (value.status === \"dirty\")\n status.dirty();\n if (key.value !== \"__proto__\" &&\n (typeof value.value !== \"undefined\" || pair.alwaysSet)) {\n finalObject[key.value] = value.value;\n }\n }\n return { status: status.value, value: finalObject };\n }\n}\nexports.ParseStatus = ParseStatus;\nexports.INVALID = Object.freeze({\n status: \"aborted\",\n});\nconst DIRTY = (value) => ({ status: \"dirty\", value });\nexports.DIRTY = DIRTY;\nconst OK = (value) => ({ status: \"valid\", value });\nexports.OK = OK;\nconst isAborted = (x) => x.status === \"aborted\";\nexports.isAborted = isAborted;\nconst isDirty = (x) => x.status === \"dirty\";\nexports.isDirty = isDirty;\nconst isValid = (x) => x.status === \"valid\";\nexports.isValid = isValid;\nconst isAsync = (x) => typeof Promise !== \"undefined\" && x instanceof Promise;\nexports.isAsync = isAsync;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getParsedType = exports.ZodParsedType = exports.objectUtil = exports.util = void 0;\nvar util;\n(function (util) {\n util.assertEqual = (val) => val;\n function assertIs(_arg) { }\n util.assertIs = assertIs;\n function assertNever(_x) {\n throw new Error();\n }\n util.assertNever = assertNever;\n util.arrayToEnum = (items) => {\n const obj = {};\n for (const item of items) {\n obj[item] = item;\n }\n return obj;\n };\n util.getValidEnumValues = (obj) => {\n const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== \"number\");\n const filtered = {};\n for (const k of validKeys) {\n filtered[k] = obj[k];\n }\n return util.objectValues(filtered);\n };\n util.objectValues = (obj) => {\n return util.objectKeys(obj).map(function (e) {\n return obj[e];\n });\n };\n util.objectKeys = typeof Object.keys === \"function\" // eslint-disable-line ban/ban\n ? (obj) => Object.keys(obj) // eslint-disable-line ban/ban\n : (object) => {\n const keys = [];\n for (const key in object) {\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n keys.push(key);\n }\n }\n return keys;\n };\n util.find = (arr, checker) => {\n for (const item of arr) {\n if (checker(item))\n return item;\n }\n return undefined;\n };\n util.isInteger = typeof Number.isInteger === \"function\"\n ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban\n : (val) => typeof val === \"number\" && isFinite(val) && Math.floor(val) === val;\n function joinValues(array, separator = \" | \") {\n return array\n .map((val) => (typeof val === \"string\" ? `'${val}'` : val))\n .join(separator);\n }\n util.joinValues = joinValues;\n util.jsonStringifyReplacer = (_, value) => {\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n return value;\n };\n})(util = exports.util || (exports.util = {}));\nvar objectUtil;\n(function (objectUtil) {\n objectUtil.mergeShapes = (first, second) => {\n return {\n ...first,\n ...second, // second overwrites first\n };\n };\n})(objectUtil = exports.objectUtil || (exports.objectUtil = {}));\nexports.ZodParsedType = util.arrayToEnum([\n \"string\",\n \"nan\",\n \"number\",\n \"integer\",\n \"float\",\n \"boolean\",\n \"date\",\n \"bigint\",\n \"symbol\",\n \"function\",\n \"undefined\",\n \"null\",\n \"array\",\n \"object\",\n \"unknown\",\n \"promise\",\n \"void\",\n \"never\",\n \"map\",\n \"set\",\n]);\nconst getParsedType = (data) => {\n const t = typeof data;\n switch (t) {\n case \"undefined\":\n return exports.ZodParsedType.undefined;\n case \"string\":\n return exports.ZodParsedType.string;\n case \"number\":\n return isNaN(data) ? exports.ZodParsedType.nan : exports.ZodParsedType.number;\n case \"boolean\":\n return exports.ZodParsedType.boolean;\n case \"function\":\n return exports.ZodParsedType.function;\n case \"bigint\":\n return exports.ZodParsedType.bigint;\n case \"symbol\":\n return exports.ZodParsedType.symbol;\n case \"object\":\n if (Array.isArray(data)) {\n return exports.ZodParsedType.array;\n }\n if (data === null) {\n return exports.ZodParsedType.null;\n }\n if (data.then &&\n typeof data.then === \"function\" &&\n data.catch &&\n typeof data.catch === \"function\") {\n return exports.ZodParsedType.promise;\n }\n if (typeof Map !== \"undefined\" && data instanceof Map) {\n return exports.ZodParsedType.map;\n }\n if (typeof Set !== \"undefined\" && data instanceof Set) {\n return exports.ZodParsedType.set;\n }\n if (typeof Date !== \"undefined\" && data instanceof Date) {\n return exports.ZodParsedType.date;\n }\n return exports.ZodParsedType.object;\n default:\n return exports.ZodParsedType.unknown;\n }\n};\nexports.getParsedType = getParsedType;\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.z = void 0;\nconst z = __importStar(require(\"./external\"));\nexports.z = z;\n__exportStar(require(\"./external\"), exports);\nexports.default = z;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst util_1 = require(\"../helpers/util\");\nconst ZodError_1 = require(\"../ZodError\");\nconst errorMap = (issue, _ctx) => {\n let message;\n switch (issue.code) {\n case ZodError_1.ZodIssueCode.invalid_type:\n if (issue.received === util_1.ZodParsedType.undefined) {\n message = \"Required\";\n }\n else {\n message = `Expected ${issue.expected}, received ${issue.received}`;\n }\n break;\n case ZodError_1.ZodIssueCode.invalid_literal:\n message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util_1.util.jsonStringifyReplacer)}`;\n break;\n case ZodError_1.ZodIssueCode.unrecognized_keys:\n message = `Unrecognized key(s) in object: ${util_1.util.joinValues(issue.keys, \", \")}`;\n break;\n case ZodError_1.ZodIssueCode.invalid_union:\n message = `Invalid input`;\n break;\n case ZodError_1.ZodIssueCode.invalid_union_discriminator:\n message = `Invalid discriminator value. Expected ${util_1.util.joinValues(issue.options)}`;\n break;\n case ZodError_1.ZodIssueCode.invalid_enum_value:\n message = `Invalid enum value. Expected ${util_1.util.joinValues(issue.options)}, received '${issue.received}'`;\n break;\n case ZodError_1.ZodIssueCode.invalid_arguments:\n message = `Invalid function arguments`;\n break;\n case ZodError_1.ZodIssueCode.invalid_return_type:\n message = `Invalid function return type`;\n break;\n case ZodError_1.ZodIssueCode.invalid_date:\n message = `Invalid date`;\n break;\n case ZodError_1.ZodIssueCode.invalid_string:\n if (typeof issue.validation === \"object\") {\n if (\"includes\" in issue.validation) {\n message = `Invalid input: must include \"${issue.validation.includes}\"`;\n if (typeof issue.validation.position === \"number\") {\n message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;\n }\n }\n else if (\"startsWith\" in issue.validation) {\n message = `Invalid input: must start with \"${issue.validation.startsWith}\"`;\n }\n else if (\"endsWith\" in issue.validation) {\n message = `Invalid input: must end with \"${issue.validation.endsWith}\"`;\n }\n else {\n util_1.util.assertNever(issue.validation);\n }\n }\n else if (issue.validation !== \"regex\") {\n message = `Invalid ${issue.validation}`;\n }\n else {\n message = \"Invalid\";\n }\n break;\n case ZodError_1.ZodIssueCode.too_small:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact\n ? `exactly equal to `\n : issue.inclusive\n ? `greater than or equal to `\n : `greater than `}${issue.minimum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact\n ? `exactly equal to `\n : issue.inclusive\n ? `greater than or equal to `\n : `greater than `}${new Date(Number(issue.minimum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodError_1.ZodIssueCode.too_big:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `less than or equal to`\n : `less than`} ${issue.maximum}`;\n else if (issue.type === \"bigint\")\n message = `BigInt must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `less than or equal to`\n : `less than`} ${issue.maximum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `smaller than or equal to`\n : `smaller than`} ${new Date(Number(issue.maximum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodError_1.ZodIssueCode.custom:\n message = `Invalid input`;\n break;\n case ZodError_1.ZodIssueCode.invalid_intersection_types:\n message = `Intersection results could not be merged`;\n break;\n case ZodError_1.ZodIssueCode.not_multiple_of:\n message = `Number must be a multiple of ${issue.multipleOf}`;\n break;\n case ZodError_1.ZodIssueCode.not_finite:\n message = \"Number must be finite\";\n break;\n default:\n message = _ctx.defaultError;\n util_1.util.assertNever(issue);\n }\n return { message };\n};\nexports.default = errorMap;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.date = exports.boolean = exports.bigint = exports.array = exports.any = exports.coerce = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.custom = exports.ZodReadonly = exports.ZodPipeline = exports.ZodBranded = exports.BRAND = exports.ZodNaN = exports.ZodCatch = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodSymbol = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.ZodType = void 0;\nexports.NEVER = exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.symbol = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.pipeline = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = exports.intersection = exports.instanceof = exports.function = exports.enum = exports.effect = exports.discriminatedUnion = void 0;\nconst errors_1 = require(\"./errors\");\nconst errorUtil_1 = require(\"./helpers/errorUtil\");\nconst parseUtil_1 = require(\"./helpers/parseUtil\");\nconst util_1 = require(\"./helpers/util\");\nconst ZodError_1 = require(\"./ZodError\");\nclass ParseInputLazyPath {\n constructor(parent, value, path, key) {\n this._cachedPath = [];\n this.parent = parent;\n this.data = value;\n this._path = path;\n this._key = key;\n }\n get path() {\n if (!this._cachedPath.length) {\n if (this._key instanceof Array) {\n this._cachedPath.push(...this._path, ...this._key);\n }\n else {\n this._cachedPath.push(...this._path, this._key);\n }\n }\n return this._cachedPath;\n }\n}\nconst handleResult = (ctx, result) => {\n if ((0, parseUtil_1.isValid)(result)) {\n return { success: true, data: result.value };\n }\n else {\n if (!ctx.common.issues.length) {\n throw new Error(\"Validation failed but no issues detected.\");\n }\n return {\n success: false,\n get error() {\n if (this._error)\n return this._error;\n const error = new ZodError_1.ZodError(ctx.common.issues);\n this._error = error;\n return this._error;\n },\n };\n }\n};\nfunction processCreateParams(params) {\n if (!params)\n return {};\n const { errorMap, invalid_type_error, required_error, description } = params;\n if (errorMap && (invalid_type_error || required_error)) {\n throw new Error(`Can't use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.`);\n }\n if (errorMap)\n return { errorMap: errorMap, description };\n const customMap = (iss, ctx) => {\n if (iss.code !== \"invalid_type\")\n return { message: ctx.defaultError };\n if (typeof ctx.data === \"undefined\") {\n return { message: required_error !== null && required_error !== void 0 ? required_error : ctx.defaultError };\n }\n return { message: invalid_type_error !== null && invalid_type_error !== void 0 ? invalid_type_error : ctx.defaultError };\n };\n return { errorMap: customMap, description };\n}\nclass ZodType {\n constructor(def) {\n /** Alias of safeParseAsync */\n this.spa = this.safeParseAsync;\n this._def = def;\n this.parse = this.parse.bind(this);\n this.safeParse = this.safeParse.bind(this);\n this.parseAsync = this.parseAsync.bind(this);\n this.safeParseAsync = this.safeParseAsync.bind(this);\n this.spa = this.spa.bind(this);\n this.refine = this.refine.bind(this);\n this.refinement = this.refinement.bind(this);\n this.superRefine = this.superRefine.bind(this);\n this.optional = this.optional.bind(this);\n this.nullable = this.nullable.bind(this);\n this.nullish = this.nullish.bind(this);\n this.array = this.array.bind(this);\n this.promise = this.promise.bind(this);\n this.or = this.or.bind(this);\n this.and = this.and.bind(this);\n this.transform = this.transform.bind(this);\n this.brand = this.brand.bind(this);\n this.default = this.default.bind(this);\n this.catch = this.catch.bind(this);\n this.describe = this.describe.bind(this);\n this.pipe = this.pipe.bind(this);\n this.readonly = this.readonly.bind(this);\n this.isNullable = this.isNullable.bind(this);\n this.isOptional = this.isOptional.bind(this);\n }\n get description() {\n return this._def.description;\n }\n _getType(input) {\n return (0, util_1.getParsedType)(input.data);\n }\n _getOrReturnCtx(input, ctx) {\n return (ctx || {\n common: input.parent.common,\n data: input.data,\n parsedType: (0, util_1.getParsedType)(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n });\n }\n _processInputParams(input) {\n return {\n status: new parseUtil_1.ParseStatus(),\n ctx: {\n common: input.parent.common,\n data: input.data,\n parsedType: (0, util_1.getParsedType)(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n },\n };\n }\n _parseSync(input) {\n const result = this._parse(input);\n if ((0, parseUtil_1.isAsync)(result)) {\n throw new Error(\"Synchronous parse encountered promise.\");\n }\n return result;\n }\n _parseAsync(input) {\n const result = this._parse(input);\n return Promise.resolve(result);\n }\n parse(data, params) {\n const result = this.safeParse(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n safeParse(data, params) {\n var _a;\n const ctx = {\n common: {\n issues: [],\n async: (_a = params === null || params === void 0 ? void 0 : params.async) !== null && _a !== void 0 ? _a : false,\n contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,\n },\n path: (params === null || params === void 0 ? void 0 : params.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: (0, util_1.getParsedType)(data),\n };\n const result = this._parseSync({ data, path: ctx.path, parent: ctx });\n return handleResult(ctx, result);\n }\n async parseAsync(data, params) {\n const result = await this.safeParseAsync(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n async safeParseAsync(data, params) {\n const ctx = {\n common: {\n issues: [],\n contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,\n async: true,\n },\n path: (params === null || params === void 0 ? void 0 : params.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: (0, util_1.getParsedType)(data),\n };\n const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });\n const result = await ((0, parseUtil_1.isAsync)(maybeAsyncResult)\n ? maybeAsyncResult\n : Promise.resolve(maybeAsyncResult));\n return handleResult(ctx, result);\n }\n refine(check, message) {\n const getIssueProperties = (val) => {\n if (typeof message === \"string\" || typeof message === \"undefined\") {\n return { message };\n }\n else if (typeof message === \"function\") {\n return message(val);\n }\n else {\n return message;\n }\n };\n return this._refinement((val, ctx) => {\n const result = check(val);\n const setError = () => ctx.addIssue({\n code: ZodError_1.ZodIssueCode.custom,\n ...getIssueProperties(val),\n });\n if (typeof Promise !== \"undefined\" && result instanceof Promise) {\n return result.then((data) => {\n if (!data) {\n setError();\n return false;\n }\n else {\n return true;\n }\n });\n }\n if (!result) {\n setError();\n return false;\n }\n else {\n return true;\n }\n });\n }\n refinement(check, refinementData) {\n return this._refinement((val, ctx) => {\n if (!check(val)) {\n ctx.addIssue(typeof refinementData === \"function\"\n ? refinementData(val, ctx)\n : refinementData);\n return false;\n }\n else {\n return true;\n }\n });\n }\n _refinement(refinement) {\n return new ZodEffects({\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: \"refinement\", refinement },\n });\n }\n superRefine(refinement) {\n return this._refinement(refinement);\n }\n optional() {\n return ZodOptional.create(this, this._def);\n }\n nullable() {\n return ZodNullable.create(this, this._def);\n }\n nullish() {\n return this.nullable().optional();\n }\n array() {\n return ZodArray.create(this, this._def);\n }\n promise() {\n return ZodPromise.create(this, this._def);\n }\n or(option) {\n return ZodUnion.create([this, option], this._def);\n }\n and(incoming) {\n return ZodIntersection.create(this, incoming, this._def);\n }\n transform(transform) {\n return new ZodEffects({\n ...processCreateParams(this._def),\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: \"transform\", transform },\n });\n }\n default(def) {\n const defaultValueFunc = typeof def === \"function\" ? def : () => def;\n return new ZodDefault({\n ...processCreateParams(this._def),\n innerType: this,\n defaultValue: defaultValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n });\n }\n brand() {\n return new ZodBranded({\n typeName: ZodFirstPartyTypeKind.ZodBranded,\n type: this,\n ...processCreateParams(this._def),\n });\n }\n catch(def) {\n const catchValueFunc = typeof def === \"function\" ? def : () => def;\n return new ZodCatch({\n ...processCreateParams(this._def),\n innerType: this,\n catchValue: catchValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n });\n }\n describe(description) {\n const This = this.constructor;\n return new This({\n ...this._def,\n description,\n });\n }\n pipe(target) {\n return ZodPipeline.create(this, target);\n }\n readonly() {\n return ZodReadonly.create(this);\n }\n isOptional() {\n return this.safeParse(undefined).success;\n }\n isNullable() {\n return this.safeParse(null).success;\n }\n}\nexports.ZodType = ZodType;\nexports.Schema = ZodType;\nexports.ZodSchema = ZodType;\nconst cuidRegex = /^c[^\\s-]{8,}$/i;\nconst cuid2Regex = /^[a-z][a-z0-9]*$/;\nconst ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/;\n// const uuidRegex =\n// /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i;\nconst uuidRegex = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i;\n// from https://stackoverflow.com/a/46181/1550155\n// old version: too slow, didn't support unicode\n// const emailRegex = /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i;\n//old email regex\n// const emailRegex = /^(([^<>()[\\].,;:\\s@\"]+(\\.[^<>()[\\].,;:\\s@\"]+)*)|(\".+\"))@((?!-)([^<>()[\\].,;:\\s@\"]+\\.)+[^<>()[\\].,;:\\s@\"]{1,})[^-<>()[\\].,;:\\s@\"]$/i;\n// eslint-disable-next-line\n// const emailRegex =\n// /^(([^<>()[\\]\\\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@((\\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\])|(\\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\\.[A-Za-z]{2,})+))$/;\n// const emailRegex =\n// /^[a-zA-Z0-9\\.\\!\\#\\$\\%\\&\\'\\*\\+\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~\\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n// const emailRegex =\n// /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$/i;\nconst emailRegex = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_+-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\n// const emailRegex =\n// /^[a-z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\\.[a-z0-9\\-]+)*$/i;\n// from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression\nconst _emojiRegex = `^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$`;\nlet emojiRegex;\nconst ipv4Regex = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/;\nconst ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;\n// Adapted from https://stackoverflow.com/a/3143231\nconst datetimeRegex = (args) => {\n if (args.precision) {\n if (args.offset) {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{${args.precision}}(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$`);\n }\n else {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}\\\\.\\\\d{${args.precision}}Z$`);\n }\n }\n else if (args.precision === 0) {\n if (args.offset) {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$`);\n }\n else {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}Z$`);\n }\n }\n else {\n if (args.offset) {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?(([+-]\\\\d{2}(:?\\\\d{2})?)|Z)$`);\n }\n else {\n return new RegExp(`^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?Z$`);\n }\n }\n};\nfunction isValidIP(ip, version) {\n if ((version === \"v4\" || !version) && ipv4Regex.test(ip)) {\n return true;\n }\n if ((version === \"v6\" || !version) && ipv6Regex.test(ip)) {\n return true;\n }\n return false;\n}\nclass ZodString extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = String(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.string) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.string,\n received: ctx.parsedType,\n }\n //\n );\n return parseUtil_1.INVALID;\n }\n const status = new parseUtil_1.ParseStatus();\n let ctx = undefined;\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n if (input.data.length < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: check.value,\n type: \"string\",\n inclusive: true,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n if (input.data.length > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: check.value,\n type: \"string\",\n inclusive: true,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"length\") {\n const tooBig = input.data.length > check.value;\n const tooSmall = input.data.length < check.value;\n if (tooBig || tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n if (tooBig) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: check.value,\n type: \"string\",\n inclusive: true,\n exact: true,\n message: check.message,\n });\n }\n else if (tooSmall) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: check.value,\n type: \"string\",\n inclusive: true,\n exact: true,\n message: check.message,\n });\n }\n status.dirty();\n }\n }\n else if (check.kind === \"email\") {\n if (!emailRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"email\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"emoji\") {\n if (!emojiRegex) {\n emojiRegex = new RegExp(_emojiRegex, \"u\");\n }\n if (!emojiRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"emoji\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"uuid\") {\n if (!uuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"uuid\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cuid\") {\n if (!cuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"cuid\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cuid2\") {\n if (!cuid2Regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"cuid2\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"ulid\") {\n if (!ulidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"ulid\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"url\") {\n try {\n new URL(input.data);\n }\n catch (_a) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"url\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"regex\") {\n check.regex.lastIndex = 0;\n const testResult = check.regex.test(input.data);\n if (!testResult) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"regex\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"trim\") {\n input.data = input.data.trim();\n }\n else if (check.kind === \"includes\") {\n if (!input.data.includes(check.value, check.position)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_string,\n validation: { includes: check.value, position: check.position },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"toLowerCase\") {\n input.data = input.data.toLowerCase();\n }\n else if (check.kind === \"toUpperCase\") {\n input.data = input.data.toUpperCase();\n }\n else if (check.kind === \"startsWith\") {\n if (!input.data.startsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_string,\n validation: { startsWith: check.value },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"endsWith\") {\n if (!input.data.endsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_string,\n validation: { endsWith: check.value },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"datetime\") {\n const regex = datetimeRegex(check);\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_string,\n validation: \"datetime\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"ip\") {\n if (!isValidIP(input.data, check.version)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n validation: \"ip\",\n code: ZodError_1.ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util_1.util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n _regex(regex, validation, message) {\n return this.refinement((data) => regex.test(data), {\n validation,\n code: ZodError_1.ZodIssueCode.invalid_string,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n _addCheck(check) {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n email(message) {\n return this._addCheck({ kind: \"email\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n url(message) {\n return this._addCheck({ kind: \"url\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n emoji(message) {\n return this._addCheck({ kind: \"emoji\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n uuid(message) {\n return this._addCheck({ kind: \"uuid\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n cuid(message) {\n return this._addCheck({ kind: \"cuid\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n cuid2(message) {\n return this._addCheck({ kind: \"cuid2\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n ulid(message) {\n return this._addCheck({ kind: \"ulid\", ...errorUtil_1.errorUtil.errToObj(message) });\n }\n ip(options) {\n return this._addCheck({ kind: \"ip\", ...errorUtil_1.errorUtil.errToObj(options) });\n }\n datetime(options) {\n var _a;\n if (typeof options === \"string\") {\n return this._addCheck({\n kind: \"datetime\",\n precision: null,\n offset: false,\n message: options,\n });\n }\n return this._addCheck({\n kind: \"datetime\",\n precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === \"undefined\" ? null : options === null || options === void 0 ? void 0 : options.precision,\n offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false,\n ...errorUtil_1.errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),\n });\n }\n regex(regex, message) {\n return this._addCheck({\n kind: \"regex\",\n regex: regex,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n includes(value, options) {\n return this._addCheck({\n kind: \"includes\",\n value: value,\n position: options === null || options === void 0 ? void 0 : options.position,\n ...errorUtil_1.errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),\n });\n }\n startsWith(value, message) {\n return this._addCheck({\n kind: \"startsWith\",\n value: value,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n endsWith(value, message) {\n return this._addCheck({\n kind: \"endsWith\",\n value: value,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n min(minLength, message) {\n return this._addCheck({\n kind: \"min\",\n value: minLength,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n max(maxLength, message) {\n return this._addCheck({\n kind: \"max\",\n value: maxLength,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n length(len, message) {\n return this._addCheck({\n kind: \"length\",\n value: len,\n ...errorUtil_1.errorUtil.errToObj(message),\n });\n }\n /**\n * @deprecated Use z.string().min(1) instead.\n * @see {@link ZodString.min}\n */\n nonempty(message) {\n return this.min(1, errorUtil_1.errorUtil.errToObj(message));\n }\n trim() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"trim\" }],\n });\n }\n toLowerCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"toLowerCase\" }],\n });\n }\n toUpperCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"toUpperCase\" }],\n });\n }\n get isDatetime() {\n return !!this._def.checks.find((ch) => ch.kind === \"datetime\");\n }\n get isEmail() {\n return !!this._def.checks.find((ch) => ch.kind === \"email\");\n }\n get isURL() {\n return !!this._def.checks.find((ch) => ch.kind === \"url\");\n }\n get isEmoji() {\n return !!this._def.checks.find((ch) => ch.kind === \"emoji\");\n }\n get isUUID() {\n return !!this._def.checks.find((ch) => ch.kind === \"uuid\");\n }\n get isCUID() {\n return !!this._def.checks.find((ch) => ch.kind === \"cuid\");\n }\n get isCUID2() {\n return !!this._def.checks.find((ch) => ch.kind === \"cuid2\");\n }\n get isULID() {\n return !!this._def.checks.find((ch) => ch.kind === \"ulid\");\n }\n get isIP() {\n return !!this._def.checks.find((ch) => ch.kind === \"ip\");\n }\n get minLength() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxLength() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n}\nexports.ZodString = ZodString;\nZodString.create = (params) => {\n var _a;\n return new ZodString({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodString,\n coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,\n ...processCreateParams(params),\n });\n};\n// https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034\nfunction floatSafeRemainder(val, step) {\n const valDecCount = (val.toString().split(\".\")[1] || \"\").length;\n const stepDecCount = (step.toString().split(\".\")[1] || \"\").length;\n const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;\n const valInt = parseInt(val.toFixed(decCount).replace(\".\", \"\"));\n const stepInt = parseInt(step.toFixed(decCount).replace(\".\", \"\"));\n return (valInt % stepInt) / Math.pow(10, decCount);\n}\nclass ZodNumber extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n this.step = this.multipleOf;\n }\n _parse(input) {\n if (this._def.coerce) {\n input.data = Number(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.number) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.number,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n let ctx = undefined;\n const status = new parseUtil_1.ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === \"int\") {\n if (!util_1.util.isInteger(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: \"integer\",\n received: \"float\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"min\") {\n const tooSmall = check.inclusive\n ? input.data < check.value\n : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: check.value,\n type: \"number\",\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n const tooBig = check.inclusive\n ? input.data > check.value\n : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: check.value,\n type: \"number\",\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"multipleOf\") {\n if (floatSafeRemainder(input.data, check.value) !== 0) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"finite\") {\n if (!Number.isFinite(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.not_finite,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util_1.util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n gte(value, message) {\n return this.setLimit(\"min\", value, true, errorUtil_1.errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit(\"min\", value, false, errorUtil_1.errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit(\"max\", value, true, errorUtil_1.errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit(\"max\", value, false, errorUtil_1.errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodNumber({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil_1.errorUtil.toString(message),\n },\n ],\n });\n }\n _addCheck(check) {\n return new ZodNumber({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n int(message) {\n return this._addCheck({\n kind: \"int\",\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n positive(message) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: false,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n negative(message) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: false,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: true,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: true,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: \"multipleOf\",\n value: value,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n finite(message) {\n return this._addCheck({\n kind: \"finite\",\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n safe(message) {\n return this._addCheck({\n kind: \"min\",\n inclusive: true,\n value: Number.MIN_SAFE_INTEGER,\n message: errorUtil_1.errorUtil.toString(message),\n })._addCheck({\n kind: \"max\",\n inclusive: true,\n value: Number.MAX_SAFE_INTEGER,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n get isInt() {\n return !!this._def.checks.find((ch) => ch.kind === \"int\" ||\n (ch.kind === \"multipleOf\" && util_1.util.isInteger(ch.value)));\n }\n get isFinite() {\n let max = null, min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"finite\" ||\n ch.kind === \"int\" ||\n ch.kind === \"multipleOf\") {\n return true;\n }\n else if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n else if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return Number.isFinite(min) && Number.isFinite(max);\n }\n}\nexports.ZodNumber = ZodNumber;\nZodNumber.create = (params) => {\n return new ZodNumber({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodNumber,\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n ...processCreateParams(params),\n });\n};\nclass ZodBigInt extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n }\n _parse(input) {\n if (this._def.coerce) {\n input.data = BigInt(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.bigint) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.bigint,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n let ctx = undefined;\n const status = new parseUtil_1.ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n const tooSmall = check.inclusive\n ? input.data < check.value\n : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n type: \"bigint\",\n minimum: check.value,\n inclusive: check.inclusive,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n const tooBig = check.inclusive\n ? input.data > check.value\n : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n type: \"bigint\",\n maximum: check.value,\n inclusive: check.inclusive,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"multipleOf\") {\n if (input.data % check.value !== BigInt(0)) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util_1.util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n gte(value, message) {\n return this.setLimit(\"min\", value, true, errorUtil_1.errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit(\"min\", value, false, errorUtil_1.errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit(\"max\", value, true, errorUtil_1.errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit(\"max\", value, false, errorUtil_1.errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodBigInt({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil_1.errorUtil.toString(message),\n },\n ],\n });\n }\n _addCheck(check) {\n return new ZodBigInt({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n positive(message) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n negative(message) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: \"multipleOf\",\n value,\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n}\nexports.ZodBigInt = ZodBigInt;\nZodBigInt.create = (params) => {\n var _a;\n return new ZodBigInt({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodBigInt,\n coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,\n ...processCreateParams(params),\n });\n};\nclass ZodBoolean extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = Boolean(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.boolean) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.boolean,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodBoolean = ZodBoolean;\nZodBoolean.create = (params) => {\n return new ZodBoolean({\n typeName: ZodFirstPartyTypeKind.ZodBoolean,\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n ...processCreateParams(params),\n });\n};\nclass ZodDate extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = new Date(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.date) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.date,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n if (isNaN(input.data.getTime())) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_date,\n });\n return parseUtil_1.INVALID;\n }\n const status = new parseUtil_1.ParseStatus();\n let ctx = undefined;\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n if (input.data.getTime() < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n message: check.message,\n inclusive: true,\n exact: false,\n minimum: check.value,\n type: \"date\",\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n if (input.data.getTime() > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n message: check.message,\n inclusive: true,\n exact: false,\n maximum: check.value,\n type: \"date\",\n });\n status.dirty();\n }\n }\n else {\n util_1.util.assertNever(check);\n }\n }\n return {\n status: status.value,\n value: new Date(input.data.getTime()),\n };\n }\n _addCheck(check) {\n return new ZodDate({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n min(minDate, message) {\n return this._addCheck({\n kind: \"min\",\n value: minDate.getTime(),\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n max(maxDate, message) {\n return this._addCheck({\n kind: \"max\",\n value: maxDate.getTime(),\n message: errorUtil_1.errorUtil.toString(message),\n });\n }\n get minDate() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min != null ? new Date(min) : null;\n }\n get maxDate() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max != null ? new Date(max) : null;\n }\n}\nexports.ZodDate = ZodDate;\nZodDate.create = (params) => {\n return new ZodDate({\n checks: [],\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n typeName: ZodFirstPartyTypeKind.ZodDate,\n ...processCreateParams(params),\n });\n};\nclass ZodSymbol extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.symbol) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.symbol,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodSymbol = ZodSymbol;\nZodSymbol.create = (params) => {\n return new ZodSymbol({\n typeName: ZodFirstPartyTypeKind.ZodSymbol,\n ...processCreateParams(params),\n });\n};\nclass ZodUndefined extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.undefined,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodUndefined = ZodUndefined;\nZodUndefined.create = (params) => {\n return new ZodUndefined({\n typeName: ZodFirstPartyTypeKind.ZodUndefined,\n ...processCreateParams(params),\n });\n};\nclass ZodNull extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.null) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.null,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodNull = ZodNull;\nZodNull.create = (params) => {\n return new ZodNull({\n typeName: ZodFirstPartyTypeKind.ZodNull,\n ...processCreateParams(params),\n });\n};\nclass ZodAny extends ZodType {\n constructor() {\n super(...arguments);\n // to prevent instances of other classes from extending ZodAny. this causes issues with catchall in ZodObject.\n this._any = true;\n }\n _parse(input) {\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodAny = ZodAny;\nZodAny.create = (params) => {\n return new ZodAny({\n typeName: ZodFirstPartyTypeKind.ZodAny,\n ...processCreateParams(params),\n });\n};\nclass ZodUnknown extends ZodType {\n constructor() {\n super(...arguments);\n // required\n this._unknown = true;\n }\n _parse(input) {\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodUnknown = ZodUnknown;\nZodUnknown.create = (params) => {\n return new ZodUnknown({\n typeName: ZodFirstPartyTypeKind.ZodUnknown,\n ...processCreateParams(params),\n });\n};\nclass ZodNever extends ZodType {\n _parse(input) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.never,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n}\nexports.ZodNever = ZodNever;\nZodNever.create = (params) => {\n return new ZodNever({\n typeName: ZodFirstPartyTypeKind.ZodNever,\n ...processCreateParams(params),\n });\n};\nclass ZodVoid extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.void,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n}\nexports.ZodVoid = ZodVoid;\nZodVoid.create = (params) => {\n return new ZodVoid({\n typeName: ZodFirstPartyTypeKind.ZodVoid,\n ...processCreateParams(params),\n });\n};\nclass ZodArray extends ZodType {\n _parse(input) {\n const { ctx, status } = this._processInputParams(input);\n const def = this._def;\n if (ctx.parsedType !== util_1.ZodParsedType.array) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.array,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n if (def.exactLength !== null) {\n const tooBig = ctx.data.length > def.exactLength.value;\n const tooSmall = ctx.data.length < def.exactLength.value;\n if (tooBig || tooSmall) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: tooBig ? ZodError_1.ZodIssueCode.too_big : ZodError_1.ZodIssueCode.too_small,\n minimum: (tooSmall ? def.exactLength.value : undefined),\n maximum: (tooBig ? def.exactLength.value : undefined),\n type: \"array\",\n inclusive: true,\n exact: true,\n message: def.exactLength.message,\n });\n status.dirty();\n }\n }\n if (def.minLength !== null) {\n if (ctx.data.length < def.minLength.value) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: def.minLength.value,\n type: \"array\",\n inclusive: true,\n exact: false,\n message: def.minLength.message,\n });\n status.dirty();\n }\n }\n if (def.maxLength !== null) {\n if (ctx.data.length > def.maxLength.value) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: def.maxLength.value,\n type: \"array\",\n inclusive: true,\n exact: false,\n message: def.maxLength.message,\n });\n status.dirty();\n }\n }\n if (ctx.common.async) {\n return Promise.all([...ctx.data].map((item, i) => {\n return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));\n })).then((result) => {\n return parseUtil_1.ParseStatus.mergeArray(status, result);\n });\n }\n const result = [...ctx.data].map((item, i) => {\n return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));\n });\n return parseUtil_1.ParseStatus.mergeArray(status, result);\n }\n get element() {\n return this._def.type;\n }\n min(minLength, message) {\n return new ZodArray({\n ...this._def,\n minLength: { value: minLength, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n max(maxLength, message) {\n return new ZodArray({\n ...this._def,\n maxLength: { value: maxLength, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n length(len, message) {\n return new ZodArray({\n ...this._def,\n exactLength: { value: len, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n nonempty(message) {\n return this.min(1, message);\n }\n}\nexports.ZodArray = ZodArray;\nZodArray.create = (schema, params) => {\n return new ZodArray({\n type: schema,\n minLength: null,\n maxLength: null,\n exactLength: null,\n typeName: ZodFirstPartyTypeKind.ZodArray,\n ...processCreateParams(params),\n });\n};\nfunction deepPartialify(schema) {\n if (schema instanceof ZodObject) {\n const newShape = {};\n for (const key in schema.shape) {\n const fieldSchema = schema.shape[key];\n newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));\n }\n return new ZodObject({\n ...schema._def,\n shape: () => newShape,\n });\n }\n else if (schema instanceof ZodArray) {\n return new ZodArray({\n ...schema._def,\n type: deepPartialify(schema.element),\n });\n }\n else if (schema instanceof ZodOptional) {\n return ZodOptional.create(deepPartialify(schema.unwrap()));\n }\n else if (schema instanceof ZodNullable) {\n return ZodNullable.create(deepPartialify(schema.unwrap()));\n }\n else if (schema instanceof ZodTuple) {\n return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));\n }\n else {\n return schema;\n }\n}\nclass ZodObject extends ZodType {\n constructor() {\n super(...arguments);\n this._cached = null;\n /**\n * @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped.\n * If you want to pass through unknown properties, use `.passthrough()` instead.\n */\n this.nonstrict = this.passthrough;\n // extend<\n // Augmentation extends ZodRawShape,\n // NewOutput extends util.flatten<{\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k][\"_output\"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // }>,\n // NewInput extends util.flatten<{\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k][\"_input\"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }>\n // >(\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape,\n // UnknownKeys,\n // Catchall,\n // NewOutput,\n // NewInput\n // > {\n // return new ZodObject({\n // ...this._def,\n // shape: () => ({\n // ...this._def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // }\n /**\n * @deprecated Use `.extend` instead\n * */\n this.augment = this.extend;\n }\n _getCached() {\n if (this._cached !== null)\n return this._cached;\n const shape = this._def.shape();\n const keys = util_1.util.objectKeys(shape);\n return (this._cached = { shape, keys });\n }\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.object) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.object,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const { status, ctx } = this._processInputParams(input);\n const { shape, keys: shapeKeys } = this._getCached();\n const extraKeys = [];\n if (!(this._def.catchall instanceof ZodNever &&\n this._def.unknownKeys === \"strip\")) {\n for (const key in ctx.data) {\n if (!shapeKeys.includes(key)) {\n extraKeys.push(key);\n }\n }\n }\n const pairs = [];\n for (const key of shapeKeys) {\n const keyValidator = shape[key];\n const value = ctx.data[key];\n pairs.push({\n key: { status: \"valid\", value: key },\n value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),\n alwaysSet: key in ctx.data,\n });\n }\n if (this._def.catchall instanceof ZodNever) {\n const unknownKeys = this._def.unknownKeys;\n if (unknownKeys === \"passthrough\") {\n for (const key of extraKeys) {\n pairs.push({\n key: { status: \"valid\", value: key },\n value: { status: \"valid\", value: ctx.data[key] },\n });\n }\n }\n else if (unknownKeys === \"strict\") {\n if (extraKeys.length > 0) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.unrecognized_keys,\n keys: extraKeys,\n });\n status.dirty();\n }\n }\n else if (unknownKeys === \"strip\") {\n }\n else {\n throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);\n }\n }\n else {\n // run catchall validation\n const catchall = this._def.catchall;\n for (const key of extraKeys) {\n const value = ctx.data[key];\n pairs.push({\n key: { status: \"valid\", value: key },\n value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value)\n ),\n alwaysSet: key in ctx.data,\n });\n }\n }\n if (ctx.common.async) {\n return Promise.resolve()\n .then(async () => {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n syncPairs.push({\n key,\n value: await pair.value,\n alwaysSet: pair.alwaysSet,\n });\n }\n return syncPairs;\n })\n .then((syncPairs) => {\n return parseUtil_1.ParseStatus.mergeObjectSync(status, syncPairs);\n });\n }\n else {\n return parseUtil_1.ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get shape() {\n return this._def.shape();\n }\n strict(message) {\n errorUtil_1.errorUtil.errToObj;\n return new ZodObject({\n ...this._def,\n unknownKeys: \"strict\",\n ...(message !== undefined\n ? {\n errorMap: (issue, ctx) => {\n var _a, _b, _c, _d;\n const defaultError = (_c = (_b = (_a = this._def).errorMap) === null || _b === void 0 ? void 0 : _b.call(_a, issue, ctx).message) !== null && _c !== void 0 ? _c : ctx.defaultError;\n if (issue.code === \"unrecognized_keys\")\n return {\n message: (_d = errorUtil_1.errorUtil.errToObj(message).message) !== null && _d !== void 0 ? _d : defaultError,\n };\n return {\n message: defaultError,\n };\n },\n }\n : {}),\n });\n }\n strip() {\n return new ZodObject({\n ...this._def,\n unknownKeys: \"strip\",\n });\n }\n passthrough() {\n return new ZodObject({\n ...this._def,\n unknownKeys: \"passthrough\",\n });\n }\n // const AugmentFactory =\n // (def: Def) =>\n // (\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape, Augmentation>,\n // Def[\"unknownKeys\"],\n // Def[\"catchall\"]\n // > => {\n // return new ZodObject({\n // ...def,\n // shape: () => ({\n // ...def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // };\n extend(augmentation) {\n return new ZodObject({\n ...this._def,\n shape: () => ({\n ...this._def.shape(),\n ...augmentation,\n }),\n });\n }\n /**\n * Prior to zod@1.0.12 there was a bug in the\n * inferred type of merged objects. Please\n * upgrade if you are experiencing issues.\n */\n merge(merging) {\n const merged = new ZodObject({\n unknownKeys: merging._def.unknownKeys,\n catchall: merging._def.catchall,\n shape: () => ({\n ...this._def.shape(),\n ...merging._def.shape(),\n }),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n });\n return merged;\n }\n // merge<\n // Incoming extends AnyZodObject,\n // Augmentation extends Incoming[\"shape\"],\n // NewOutput extends {\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k][\"_output\"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // },\n // NewInput extends {\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k][\"_input\"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }\n // >(\n // merging: Incoming\n // ): ZodObject<\n // extendShape>,\n // Incoming[\"_def\"][\"unknownKeys\"],\n // Incoming[\"_def\"][\"catchall\"],\n // NewOutput,\n // NewInput\n // > {\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n setKey(key, schema) {\n return this.augment({ [key]: schema });\n }\n // merge(\n // merging: Incoming\n // ): //ZodObject = (merging) => {\n // ZodObject<\n // extendShape>,\n // Incoming[\"_def\"][\"unknownKeys\"],\n // Incoming[\"_def\"][\"catchall\"]\n // > {\n // // const mergedShape = objectUtil.mergeShapes(\n // // this._def.shape(),\n // // merging._def.shape()\n // // );\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n catchall(index) {\n return new ZodObject({\n ...this._def,\n catchall: index,\n });\n }\n pick(mask) {\n const shape = {};\n util_1.util.objectKeys(mask).forEach((key) => {\n if (mask[key] && this.shape[key]) {\n shape[key] = this.shape[key];\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => shape,\n });\n }\n omit(mask) {\n const shape = {};\n util_1.util.objectKeys(this.shape).forEach((key) => {\n if (!mask[key]) {\n shape[key] = this.shape[key];\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => shape,\n });\n }\n /**\n * @deprecated\n */\n deepPartial() {\n return deepPartialify(this);\n }\n partial(mask) {\n const newShape = {};\n util_1.util.objectKeys(this.shape).forEach((key) => {\n const fieldSchema = this.shape[key];\n if (mask && !mask[key]) {\n newShape[key] = fieldSchema;\n }\n else {\n newShape[key] = fieldSchema.optional();\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => newShape,\n });\n }\n required(mask) {\n const newShape = {};\n util_1.util.objectKeys(this.shape).forEach((key) => {\n if (mask && !mask[key]) {\n newShape[key] = this.shape[key];\n }\n else {\n const fieldSchema = this.shape[key];\n let newField = fieldSchema;\n while (newField instanceof ZodOptional) {\n newField = newField._def.innerType;\n }\n newShape[key] = newField;\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => newShape,\n });\n }\n keyof() {\n return createZodEnum(util_1.util.objectKeys(this.shape));\n }\n}\nexports.ZodObject = ZodObject;\nZodObject.create = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: \"strip\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nZodObject.strictCreate = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: \"strict\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nZodObject.lazycreate = (shape, params) => {\n return new ZodObject({\n shape,\n unknownKeys: \"strip\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nclass ZodUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const options = this._def.options;\n function handleResults(results) {\n // return first issue-free validation if it exists\n for (const result of results) {\n if (result.result.status === \"valid\") {\n return result.result;\n }\n }\n for (const result of results) {\n if (result.result.status === \"dirty\") {\n // add issues from dirty option\n ctx.common.issues.push(...result.ctx.common.issues);\n return result.result;\n }\n }\n // return invalid\n const unionErrors = results.map((result) => new ZodError_1.ZodError(result.ctx.common.issues));\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_union,\n unionErrors,\n });\n return parseUtil_1.INVALID;\n }\n if (ctx.common.async) {\n return Promise.all(options.map(async (option) => {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n parent: null,\n };\n return {\n result: await option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx,\n }),\n ctx: childCtx,\n };\n })).then(handleResults);\n }\n else {\n let dirty = undefined;\n const issues = [];\n for (const option of options) {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n parent: null,\n };\n const result = option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx,\n });\n if (result.status === \"valid\") {\n return result;\n }\n else if (result.status === \"dirty\" && !dirty) {\n dirty = { result, ctx: childCtx };\n }\n if (childCtx.common.issues.length) {\n issues.push(childCtx.common.issues);\n }\n }\n if (dirty) {\n ctx.common.issues.push(...dirty.ctx.common.issues);\n return dirty.result;\n }\n const unionErrors = issues.map((issues) => new ZodError_1.ZodError(issues));\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_union,\n unionErrors,\n });\n return parseUtil_1.INVALID;\n }\n }\n get options() {\n return this._def.options;\n }\n}\nexports.ZodUnion = ZodUnion;\nZodUnion.create = (types, params) => {\n return new ZodUnion({\n options: types,\n typeName: ZodFirstPartyTypeKind.ZodUnion,\n ...processCreateParams(params),\n });\n};\n/////////////////////////////////////////////////////\n/////////////////////////////////////////////////////\n////////// //////////\n////////// ZodDiscriminatedUnion //////////\n////////// //////////\n/////////////////////////////////////////////////////\n/////////////////////////////////////////////////////\nconst getDiscriminator = (type) => {\n if (type instanceof ZodLazy) {\n return getDiscriminator(type.schema);\n }\n else if (type instanceof ZodEffects) {\n return getDiscriminator(type.innerType());\n }\n else if (type instanceof ZodLiteral) {\n return [type.value];\n }\n else if (type instanceof ZodEnum) {\n return type.options;\n }\n else if (type instanceof ZodNativeEnum) {\n // eslint-disable-next-line ban/ban\n return Object.keys(type.enum);\n }\n else if (type instanceof ZodDefault) {\n return getDiscriminator(type._def.innerType);\n }\n else if (type instanceof ZodUndefined) {\n return [undefined];\n }\n else if (type instanceof ZodNull) {\n return [null];\n }\n else {\n return null;\n }\n};\nclass ZodDiscriminatedUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.object) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.object,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const discriminator = this.discriminator;\n const discriminatorValue = ctx.data[discriminator];\n const option = this.optionsMap.get(discriminatorValue);\n if (!option) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_union_discriminator,\n options: Array.from(this.optionsMap.keys()),\n path: [discriminator],\n });\n return parseUtil_1.INVALID;\n }\n if (ctx.common.async) {\n return option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n }\n else {\n return option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n get discriminator() {\n return this._def.discriminator;\n }\n get options() {\n return this._def.options;\n }\n get optionsMap() {\n return this._def.optionsMap;\n }\n /**\n * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.\n * However, it only allows a union of objects, all of which need to share a discriminator property. This property must\n * have a different value for each object in the union.\n * @param discriminator the name of the discriminator property\n * @param types an array of object schemas\n * @param params\n */\n static create(discriminator, options, params) {\n // Get all the valid discriminator values\n const optionsMap = new Map();\n // try {\n for (const type of options) {\n const discriminatorValues = getDiscriminator(type.shape[discriminator]);\n if (!discriminatorValues) {\n throw new Error(`A discriminator value for key \\`${discriminator}\\` could not be extracted from all schema options`);\n }\n for (const value of discriminatorValues) {\n if (optionsMap.has(value)) {\n throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);\n }\n optionsMap.set(value, type);\n }\n }\n return new ZodDiscriminatedUnion({\n typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,\n discriminator,\n options,\n optionsMap,\n ...processCreateParams(params),\n });\n }\n}\nexports.ZodDiscriminatedUnion = ZodDiscriminatedUnion;\nfunction mergeValues(a, b) {\n const aType = (0, util_1.getParsedType)(a);\n const bType = (0, util_1.getParsedType)(b);\n if (a === b) {\n return { valid: true, data: a };\n }\n else if (aType === util_1.ZodParsedType.object && bType === util_1.ZodParsedType.object) {\n const bKeys = util_1.util.objectKeys(b);\n const sharedKeys = util_1.util\n .objectKeys(a)\n .filter((key) => bKeys.indexOf(key) !== -1);\n const newObj = { ...a, ...b };\n for (const key of sharedKeys) {\n const sharedValue = mergeValues(a[key], b[key]);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newObj[key] = sharedValue.data;\n }\n return { valid: true, data: newObj };\n }\n else if (aType === util_1.ZodParsedType.array && bType === util_1.ZodParsedType.array) {\n if (a.length !== b.length) {\n return { valid: false };\n }\n const newArray = [];\n for (let index = 0; index < a.length; index++) {\n const itemA = a[index];\n const itemB = b[index];\n const sharedValue = mergeValues(itemA, itemB);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newArray.push(sharedValue.data);\n }\n return { valid: true, data: newArray };\n }\n else if (aType === util_1.ZodParsedType.date &&\n bType === util_1.ZodParsedType.date &&\n +a === +b) {\n return { valid: true, data: a };\n }\n else {\n return { valid: false };\n }\n}\nclass ZodIntersection extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const handleParsed = (parsedLeft, parsedRight) => {\n if ((0, parseUtil_1.isAborted)(parsedLeft) || (0, parseUtil_1.isAborted)(parsedRight)) {\n return parseUtil_1.INVALID;\n }\n const merged = mergeValues(parsedLeft.value, parsedRight.value);\n if (!merged.valid) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_intersection_types,\n });\n return parseUtil_1.INVALID;\n }\n if ((0, parseUtil_1.isDirty)(parsedLeft) || (0, parseUtil_1.isDirty)(parsedRight)) {\n status.dirty();\n }\n return { status: status.value, value: merged.data };\n };\n if (ctx.common.async) {\n return Promise.all([\n this._def.left._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }),\n this._def.right._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }),\n ]).then(([left, right]) => handleParsed(left, right));\n }\n else {\n return handleParsed(this._def.left._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }), this._def.right._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }));\n }\n }\n}\nexports.ZodIntersection = ZodIntersection;\nZodIntersection.create = (left, right, params) => {\n return new ZodIntersection({\n left: left,\n right: right,\n typeName: ZodFirstPartyTypeKind.ZodIntersection,\n ...processCreateParams(params),\n });\n};\nclass ZodTuple extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.array) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.array,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n if (ctx.data.length < this._def.items.length) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: \"array\",\n });\n return parseUtil_1.INVALID;\n }\n const rest = this._def.rest;\n if (!rest && ctx.data.length > this._def.items.length) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: \"array\",\n });\n status.dirty();\n }\n const items = [...ctx.data]\n .map((item, itemIndex) => {\n const schema = this._def.items[itemIndex] || this._def.rest;\n if (!schema)\n return null;\n return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));\n })\n .filter((x) => !!x); // filter nulls\n if (ctx.common.async) {\n return Promise.all(items).then((results) => {\n return parseUtil_1.ParseStatus.mergeArray(status, results);\n });\n }\n else {\n return parseUtil_1.ParseStatus.mergeArray(status, items);\n }\n }\n get items() {\n return this._def.items;\n }\n rest(rest) {\n return new ZodTuple({\n ...this._def,\n rest,\n });\n }\n}\nexports.ZodTuple = ZodTuple;\nZodTuple.create = (schemas, params) => {\n if (!Array.isArray(schemas)) {\n throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");\n }\n return new ZodTuple({\n items: schemas,\n typeName: ZodFirstPartyTypeKind.ZodTuple,\n rest: null,\n ...processCreateParams(params),\n });\n};\nclass ZodRecord extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.object) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.object,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const pairs = [];\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n for (const key in ctx.data) {\n pairs.push({\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),\n value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),\n });\n }\n if (ctx.common.async) {\n return parseUtil_1.ParseStatus.mergeObjectAsync(status, pairs);\n }\n else {\n return parseUtil_1.ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get element() {\n return this._def.valueType;\n }\n static create(first, second, third) {\n if (second instanceof ZodType) {\n return new ZodRecord({\n keyType: first,\n valueType: second,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(third),\n });\n }\n return new ZodRecord({\n keyType: ZodString.create(),\n valueType: first,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(second),\n });\n }\n}\nexports.ZodRecord = ZodRecord;\nclass ZodMap extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.map) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.map,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n const pairs = [...ctx.data.entries()].map(([key, value], index) => {\n return {\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, \"key\"])),\n value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, \"value\"])),\n };\n });\n if (ctx.common.async) {\n const finalMap = new Map();\n return Promise.resolve().then(async () => {\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n if (key.status === \"aborted\" || value.status === \"aborted\") {\n return parseUtil_1.INVALID;\n }\n if (key.status === \"dirty\" || value.status === \"dirty\") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n });\n }\n else {\n const finalMap = new Map();\n for (const pair of pairs) {\n const key = pair.key;\n const value = pair.value;\n if (key.status === \"aborted\" || value.status === \"aborted\") {\n return parseUtil_1.INVALID;\n }\n if (key.status === \"dirty\" || value.status === \"dirty\") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n }\n }\n}\nexports.ZodMap = ZodMap;\nZodMap.create = (keyType, valueType, params) => {\n return new ZodMap({\n valueType,\n keyType,\n typeName: ZodFirstPartyTypeKind.ZodMap,\n ...processCreateParams(params),\n });\n};\nclass ZodSet extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.set) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.set,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const def = this._def;\n if (def.minSize !== null) {\n if (ctx.data.size < def.minSize.value) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_small,\n minimum: def.minSize.value,\n type: \"set\",\n inclusive: true,\n exact: false,\n message: def.minSize.message,\n });\n status.dirty();\n }\n }\n if (def.maxSize !== null) {\n if (ctx.data.size > def.maxSize.value) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.too_big,\n maximum: def.maxSize.value,\n type: \"set\",\n inclusive: true,\n exact: false,\n message: def.maxSize.message,\n });\n status.dirty();\n }\n }\n const valueType = this._def.valueType;\n function finalizeSet(elements) {\n const parsedSet = new Set();\n for (const element of elements) {\n if (element.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (element.status === \"dirty\")\n status.dirty();\n parsedSet.add(element.value);\n }\n return { status: status.value, value: parsedSet };\n }\n const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));\n if (ctx.common.async) {\n return Promise.all(elements).then((elements) => finalizeSet(elements));\n }\n else {\n return finalizeSet(elements);\n }\n }\n min(minSize, message) {\n return new ZodSet({\n ...this._def,\n minSize: { value: minSize, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n max(maxSize, message) {\n return new ZodSet({\n ...this._def,\n maxSize: { value: maxSize, message: errorUtil_1.errorUtil.toString(message) },\n });\n }\n size(size, message) {\n return this.min(size, message).max(size, message);\n }\n nonempty(message) {\n return this.min(1, message);\n }\n}\nexports.ZodSet = ZodSet;\nZodSet.create = (valueType, params) => {\n return new ZodSet({\n valueType,\n minSize: null,\n maxSize: null,\n typeName: ZodFirstPartyTypeKind.ZodSet,\n ...processCreateParams(params),\n });\n};\nclass ZodFunction extends ZodType {\n constructor() {\n super(...arguments);\n this.validate = this.implement;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.function) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.function,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n function makeArgsIssue(args, error) {\n return (0, parseUtil_1.makeIssue)({\n data: args,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n (0, errors_1.getErrorMap)(),\n errors_1.defaultErrorMap,\n ].filter((x) => !!x),\n issueData: {\n code: ZodError_1.ZodIssueCode.invalid_arguments,\n argumentsError: error,\n },\n });\n }\n function makeReturnsIssue(returns, error) {\n return (0, parseUtil_1.makeIssue)({\n data: returns,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n (0, errors_1.getErrorMap)(),\n errors_1.defaultErrorMap,\n ].filter((x) => !!x),\n issueData: {\n code: ZodError_1.ZodIssueCode.invalid_return_type,\n returnTypeError: error,\n },\n });\n }\n const params = { errorMap: ctx.common.contextualErrorMap };\n const fn = ctx.data;\n if (this._def.returns instanceof ZodPromise) {\n // Would love a way to avoid disabling this rule, but we need\n // an alias (using an arrow function was what caused 2651).\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const me = this;\n return (0, parseUtil_1.OK)(async function (...args) {\n const error = new ZodError_1.ZodError([]);\n const parsedArgs = await me._def.args\n .parseAsync(args, params)\n .catch((e) => {\n error.addIssue(makeArgsIssue(args, e));\n throw error;\n });\n const result = await Reflect.apply(fn, this, parsedArgs);\n const parsedReturns = await me._def.returns._def.type\n .parseAsync(result, params)\n .catch((e) => {\n error.addIssue(makeReturnsIssue(result, e));\n throw error;\n });\n return parsedReturns;\n });\n }\n else {\n // Would love a way to avoid disabling this rule, but we need\n // an alias (using an arrow function was what caused 2651).\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const me = this;\n return (0, parseUtil_1.OK)(function (...args) {\n const parsedArgs = me._def.args.safeParse(args, params);\n if (!parsedArgs.success) {\n throw new ZodError_1.ZodError([makeArgsIssue(args, parsedArgs.error)]);\n }\n const result = Reflect.apply(fn, this, parsedArgs.data);\n const parsedReturns = me._def.returns.safeParse(result, params);\n if (!parsedReturns.success) {\n throw new ZodError_1.ZodError([makeReturnsIssue(result, parsedReturns.error)]);\n }\n return parsedReturns.data;\n });\n }\n }\n parameters() {\n return this._def.args;\n }\n returnType() {\n return this._def.returns;\n }\n args(...items) {\n return new ZodFunction({\n ...this._def,\n args: ZodTuple.create(items).rest(ZodUnknown.create()),\n });\n }\n returns(returnType) {\n return new ZodFunction({\n ...this._def,\n returns: returnType,\n });\n }\n implement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n strictImplement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n static create(args, returns, params) {\n return new ZodFunction({\n args: (args\n ? args\n : ZodTuple.create([]).rest(ZodUnknown.create())),\n returns: returns || ZodUnknown.create(),\n typeName: ZodFirstPartyTypeKind.ZodFunction,\n ...processCreateParams(params),\n });\n }\n}\nexports.ZodFunction = ZodFunction;\nclass ZodLazy extends ZodType {\n get schema() {\n return this._def.getter();\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const lazySchema = this._def.getter();\n return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });\n }\n}\nexports.ZodLazy = ZodLazy;\nZodLazy.create = (getter, params) => {\n return new ZodLazy({\n getter: getter,\n typeName: ZodFirstPartyTypeKind.ZodLazy,\n ...processCreateParams(params),\n });\n};\nclass ZodLiteral extends ZodType {\n _parse(input) {\n if (input.data !== this._def.value) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n received: ctx.data,\n code: ZodError_1.ZodIssueCode.invalid_literal,\n expected: this._def.value,\n });\n return parseUtil_1.INVALID;\n }\n return { status: \"valid\", value: input.data };\n }\n get value() {\n return this._def.value;\n }\n}\nexports.ZodLiteral = ZodLiteral;\nZodLiteral.create = (value, params) => {\n return new ZodLiteral({\n value: value,\n typeName: ZodFirstPartyTypeKind.ZodLiteral,\n ...processCreateParams(params),\n });\n};\nfunction createZodEnum(values, params) {\n return new ZodEnum({\n values,\n typeName: ZodFirstPartyTypeKind.ZodEnum,\n ...processCreateParams(params),\n });\n}\nclass ZodEnum extends ZodType {\n _parse(input) {\n if (typeof input.data !== \"string\") {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n (0, parseUtil_1.addIssueToContext)(ctx, {\n expected: util_1.util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodError_1.ZodIssueCode.invalid_type,\n });\n return parseUtil_1.INVALID;\n }\n if (this._def.values.indexOf(input.data) === -1) {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n (0, parseUtil_1.addIssueToContext)(ctx, {\n received: ctx.data,\n code: ZodError_1.ZodIssueCode.invalid_enum_value,\n options: expectedValues,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n get options() {\n return this._def.values;\n }\n get enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Values() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n extract(values) {\n return ZodEnum.create(values);\n }\n exclude(values) {\n return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)));\n }\n}\nexports.ZodEnum = ZodEnum;\nZodEnum.create = createZodEnum;\nclass ZodNativeEnum extends ZodType {\n _parse(input) {\n const nativeEnumValues = util_1.util.getValidEnumValues(this._def.values);\n const ctx = this._getOrReturnCtx(input);\n if (ctx.parsedType !== util_1.ZodParsedType.string &&\n ctx.parsedType !== util_1.ZodParsedType.number) {\n const expectedValues = util_1.util.objectValues(nativeEnumValues);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n expected: util_1.util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodError_1.ZodIssueCode.invalid_type,\n });\n return parseUtil_1.INVALID;\n }\n if (nativeEnumValues.indexOf(input.data) === -1) {\n const expectedValues = util_1.util.objectValues(nativeEnumValues);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n received: ctx.data,\n code: ZodError_1.ZodIssueCode.invalid_enum_value,\n options: expectedValues,\n });\n return parseUtil_1.INVALID;\n }\n return (0, parseUtil_1.OK)(input.data);\n }\n get enum() {\n return this._def.values;\n }\n}\nexports.ZodNativeEnum = ZodNativeEnum;\nZodNativeEnum.create = (values, params) => {\n return new ZodNativeEnum({\n values: values,\n typeName: ZodFirstPartyTypeKind.ZodNativeEnum,\n ...processCreateParams(params),\n });\n};\nclass ZodPromise extends ZodType {\n unwrap() {\n return this._def.type;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== util_1.ZodParsedType.promise &&\n ctx.common.async === false) {\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.promise,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n const promisified = ctx.parsedType === util_1.ZodParsedType.promise\n ? ctx.data\n : Promise.resolve(ctx.data);\n return (0, parseUtil_1.OK)(promisified.then((data) => {\n return this._def.type.parseAsync(data, {\n path: ctx.path,\n errorMap: ctx.common.contextualErrorMap,\n });\n }));\n }\n}\nexports.ZodPromise = ZodPromise;\nZodPromise.create = (schema, params) => {\n return new ZodPromise({\n type: schema,\n typeName: ZodFirstPartyTypeKind.ZodPromise,\n ...processCreateParams(params),\n });\n};\nclass ZodEffects extends ZodType {\n innerType() {\n return this._def.schema;\n }\n sourceType() {\n return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects\n ? this._def.schema.sourceType()\n : this._def.schema;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const effect = this._def.effect || null;\n const checkCtx = {\n addIssue: (arg) => {\n (0, parseUtil_1.addIssueToContext)(ctx, arg);\n if (arg.fatal) {\n status.abort();\n }\n else {\n status.dirty();\n }\n },\n get path() {\n return ctx.path;\n },\n };\n checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);\n if (effect.type === \"preprocess\") {\n const processed = effect.transform(ctx.data, checkCtx);\n if (ctx.common.issues.length) {\n return {\n status: \"dirty\",\n value: ctx.data,\n };\n }\n if (ctx.common.async) {\n return Promise.resolve(processed).then((processed) => {\n return this._def.schema._parseAsync({\n data: processed,\n path: ctx.path,\n parent: ctx,\n });\n });\n }\n else {\n return this._def.schema._parseSync({\n data: processed,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n if (effect.type === \"refinement\") {\n const executeRefinement = (acc\n // effect: RefinementEffect\n ) => {\n const result = effect.refinement(acc, checkCtx);\n if (ctx.common.async) {\n return Promise.resolve(result);\n }\n if (result instanceof Promise) {\n throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");\n }\n return acc;\n };\n if (ctx.common.async === false) {\n const inner = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inner.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (inner.status === \"dirty\")\n status.dirty();\n // return value is ignored\n executeRefinement(inner.value);\n return { status: status.value, value: inner.value };\n }\n else {\n return this._def.schema\n ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })\n .then((inner) => {\n if (inner.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (inner.status === \"dirty\")\n status.dirty();\n return executeRefinement(inner.value).then(() => {\n return { status: status.value, value: inner.value };\n });\n });\n }\n }\n if (effect.type === \"transform\") {\n if (ctx.common.async === false) {\n const base = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (!(0, parseUtil_1.isValid)(base))\n return base;\n const result = effect.transform(base.value, checkCtx);\n if (result instanceof Promise) {\n throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);\n }\n return { status: status.value, value: result };\n }\n else {\n return this._def.schema\n ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })\n .then((base) => {\n if (!(0, parseUtil_1.isValid)(base))\n return base;\n return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result }));\n });\n }\n }\n util_1.util.assertNever(effect);\n }\n}\nexports.ZodEffects = ZodEffects;\nexports.ZodTransformer = ZodEffects;\nZodEffects.create = (schema, effect, params) => {\n return new ZodEffects({\n schema,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect,\n ...processCreateParams(params),\n });\n};\nZodEffects.createWithPreprocess = (preprocess, schema, params) => {\n return new ZodEffects({\n schema,\n effect: { type: \"preprocess\", transform: preprocess },\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n ...processCreateParams(params),\n });\n};\nclass ZodOptional extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === util_1.ZodParsedType.undefined) {\n return (0, parseUtil_1.OK)(undefined);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nexports.ZodOptional = ZodOptional;\nZodOptional.create = (type, params) => {\n return new ZodOptional({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodOptional,\n ...processCreateParams(params),\n });\n};\nclass ZodNullable extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === util_1.ZodParsedType.null) {\n return (0, parseUtil_1.OK)(null);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nexports.ZodNullable = ZodNullable;\nZodNullable.create = (type, params) => {\n return new ZodNullable({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodNullable,\n ...processCreateParams(params),\n });\n};\nclass ZodDefault extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n let data = ctx.data;\n if (ctx.parsedType === util_1.ZodParsedType.undefined) {\n data = this._def.defaultValue();\n }\n return this._def.innerType._parse({\n data,\n path: ctx.path,\n parent: ctx,\n });\n }\n removeDefault() {\n return this._def.innerType;\n }\n}\nexports.ZodDefault = ZodDefault;\nZodDefault.create = (type, params) => {\n return new ZodDefault({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n defaultValue: typeof params.default === \"function\"\n ? params.default\n : () => params.default,\n ...processCreateParams(params),\n });\n};\nclass ZodCatch extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n // newCtx is used to not collect issues from inner types in ctx\n const newCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n };\n const result = this._def.innerType._parse({\n data: newCtx.data,\n path: newCtx.path,\n parent: {\n ...newCtx,\n },\n });\n if ((0, parseUtil_1.isAsync)(result)) {\n return result.then((result) => {\n return {\n status: \"valid\",\n value: result.status === \"valid\"\n ? result.value\n : this._def.catchValue({\n get error() {\n return new ZodError_1.ZodError(newCtx.common.issues);\n },\n input: newCtx.data,\n }),\n };\n });\n }\n else {\n return {\n status: \"valid\",\n value: result.status === \"valid\"\n ? result.value\n : this._def.catchValue({\n get error() {\n return new ZodError_1.ZodError(newCtx.common.issues);\n },\n input: newCtx.data,\n }),\n };\n }\n }\n removeCatch() {\n return this._def.innerType;\n }\n}\nexports.ZodCatch = ZodCatch;\nZodCatch.create = (type, params) => {\n return new ZodCatch({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n catchValue: typeof params.catch === \"function\" ? params.catch : () => params.catch,\n ...processCreateParams(params),\n });\n};\nclass ZodNaN extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== util_1.ZodParsedType.nan) {\n const ctx = this._getOrReturnCtx(input);\n (0, parseUtil_1.addIssueToContext)(ctx, {\n code: ZodError_1.ZodIssueCode.invalid_type,\n expected: util_1.ZodParsedType.nan,\n received: ctx.parsedType,\n });\n return parseUtil_1.INVALID;\n }\n return { status: \"valid\", value: input.data };\n }\n}\nexports.ZodNaN = ZodNaN;\nZodNaN.create = (params) => {\n return new ZodNaN({\n typeName: ZodFirstPartyTypeKind.ZodNaN,\n ...processCreateParams(params),\n });\n};\nexports.BRAND = Symbol(\"zod_brand\");\nclass ZodBranded extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const data = ctx.data;\n return this._def.type._parse({\n data,\n path: ctx.path,\n parent: ctx,\n });\n }\n unwrap() {\n return this._def.type;\n }\n}\nexports.ZodBranded = ZodBranded;\nclass ZodPipeline extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.common.async) {\n const handleAsync = async () => {\n const inResult = await this._def.in._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inResult.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (inResult.status === \"dirty\") {\n status.dirty();\n return (0, parseUtil_1.DIRTY)(inResult.value);\n }\n else {\n return this._def.out._parseAsync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx,\n });\n }\n };\n return handleAsync();\n }\n else {\n const inResult = this._def.in._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inResult.status === \"aborted\")\n return parseUtil_1.INVALID;\n if (inResult.status === \"dirty\") {\n status.dirty();\n return {\n status: \"dirty\",\n value: inResult.value,\n };\n }\n else {\n return this._def.out._parseSync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n }\n static create(a, b) {\n return new ZodPipeline({\n in: a,\n out: b,\n typeName: ZodFirstPartyTypeKind.ZodPipeline,\n });\n }\n}\nexports.ZodPipeline = ZodPipeline;\nclass ZodReadonly extends ZodType {\n _parse(input) {\n const result = this._def.innerType._parse(input);\n if ((0, parseUtil_1.isValid)(result)) {\n result.value = Object.freeze(result.value);\n }\n return result;\n }\n}\nexports.ZodReadonly = ZodReadonly;\nZodReadonly.create = (type, params) => {\n return new ZodReadonly({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodReadonly,\n ...processCreateParams(params),\n });\n};\nconst custom = (check, params = {}, \n/**\n * @deprecated\n *\n * Pass `fatal` into the params object instead:\n *\n * ```ts\n * z.string().custom((val) => val.length > 5, { fatal: false })\n * ```\n *\n */\nfatal) => {\n if (check)\n return ZodAny.create().superRefine((data, ctx) => {\n var _a, _b;\n if (!check(data)) {\n const p = typeof params === \"function\"\n ? params(data)\n : typeof params === \"string\"\n ? { message: params }\n : params;\n const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;\n const p2 = typeof p === \"string\" ? { message: p } : p;\n ctx.addIssue({ code: \"custom\", ...p2, fatal: _fatal });\n }\n });\n return ZodAny.create();\n};\nexports.custom = custom;\nexports.late = {\n object: ZodObject.lazycreate,\n};\nvar ZodFirstPartyTypeKind;\n(function (ZodFirstPartyTypeKind) {\n ZodFirstPartyTypeKind[\"ZodString\"] = \"ZodString\";\n ZodFirstPartyTypeKind[\"ZodNumber\"] = \"ZodNumber\";\n ZodFirstPartyTypeKind[\"ZodNaN\"] = \"ZodNaN\";\n ZodFirstPartyTypeKind[\"ZodBigInt\"] = \"ZodBigInt\";\n ZodFirstPartyTypeKind[\"ZodBoolean\"] = \"ZodBoolean\";\n ZodFirstPartyTypeKind[\"ZodDate\"] = \"ZodDate\";\n ZodFirstPartyTypeKind[\"ZodSymbol\"] = \"ZodSymbol\";\n ZodFirstPartyTypeKind[\"ZodUndefined\"] = \"ZodUndefined\";\n ZodFirstPartyTypeKind[\"ZodNull\"] = \"ZodNull\";\n ZodFirstPartyTypeKind[\"ZodAny\"] = \"ZodAny\";\n ZodFirstPartyTypeKind[\"ZodUnknown\"] = \"ZodUnknown\";\n ZodFirstPartyTypeKind[\"ZodNever\"] = \"ZodNever\";\n ZodFirstPartyTypeKind[\"ZodVoid\"] = \"ZodVoid\";\n ZodFirstPartyTypeKind[\"ZodArray\"] = \"ZodArray\";\n ZodFirstPartyTypeKind[\"ZodObject\"] = \"ZodObject\";\n ZodFirstPartyTypeKind[\"ZodUnion\"] = \"ZodUnion\";\n ZodFirstPartyTypeKind[\"ZodDiscriminatedUnion\"] = \"ZodDiscriminatedUnion\";\n ZodFirstPartyTypeKind[\"ZodIntersection\"] = \"ZodIntersection\";\n ZodFirstPartyTypeKind[\"ZodTuple\"] = \"ZodTuple\";\n ZodFirstPartyTypeKind[\"ZodRecord\"] = \"ZodRecord\";\n ZodFirstPartyTypeKind[\"ZodMap\"] = \"ZodMap\";\n ZodFirstPartyTypeKind[\"ZodSet\"] = \"ZodSet\";\n ZodFirstPartyTypeKind[\"ZodFunction\"] = \"ZodFunction\";\n ZodFirstPartyTypeKind[\"ZodLazy\"] = \"ZodLazy\";\n ZodFirstPartyTypeKind[\"ZodLiteral\"] = \"ZodLiteral\";\n ZodFirstPartyTypeKind[\"ZodEnum\"] = \"ZodEnum\";\n ZodFirstPartyTypeKind[\"ZodEffects\"] = \"ZodEffects\";\n ZodFirstPartyTypeKind[\"ZodNativeEnum\"] = \"ZodNativeEnum\";\n ZodFirstPartyTypeKind[\"ZodOptional\"] = \"ZodOptional\";\n ZodFirstPartyTypeKind[\"ZodNullable\"] = \"ZodNullable\";\n ZodFirstPartyTypeKind[\"ZodDefault\"] = \"ZodDefault\";\n ZodFirstPartyTypeKind[\"ZodCatch\"] = \"ZodCatch\";\n ZodFirstPartyTypeKind[\"ZodPromise\"] = \"ZodPromise\";\n ZodFirstPartyTypeKind[\"ZodBranded\"] = \"ZodBranded\";\n ZodFirstPartyTypeKind[\"ZodPipeline\"] = \"ZodPipeline\";\n ZodFirstPartyTypeKind[\"ZodReadonly\"] = \"ZodReadonly\";\n})(ZodFirstPartyTypeKind = exports.ZodFirstPartyTypeKind || (exports.ZodFirstPartyTypeKind = {}));\n// requires TS 4.4+\nclass Class {\n constructor(..._) { }\n}\nconst instanceOfType = (\n// const instanceOfType = any>(\ncls, params = {\n message: `Input not instance of ${cls.name}`,\n}) => (0, exports.custom)((data) => data instanceof cls, params);\nexports.instanceof = instanceOfType;\nconst stringType = ZodString.create;\nexports.string = stringType;\nconst numberType = ZodNumber.create;\nexports.number = numberType;\nconst nanType = ZodNaN.create;\nexports.nan = nanType;\nconst bigIntType = ZodBigInt.create;\nexports.bigint = bigIntType;\nconst booleanType = ZodBoolean.create;\nexports.boolean = booleanType;\nconst dateType = ZodDate.create;\nexports.date = dateType;\nconst symbolType = ZodSymbol.create;\nexports.symbol = symbolType;\nconst undefinedType = ZodUndefined.create;\nexports.undefined = undefinedType;\nconst nullType = ZodNull.create;\nexports.null = nullType;\nconst anyType = ZodAny.create;\nexports.any = anyType;\nconst unknownType = ZodUnknown.create;\nexports.unknown = unknownType;\nconst neverType = ZodNever.create;\nexports.never = neverType;\nconst voidType = ZodVoid.create;\nexports.void = voidType;\nconst arrayType = ZodArray.create;\nexports.array = arrayType;\nconst objectType = ZodObject.create;\nexports.object = objectType;\nconst strictObjectType = ZodObject.strictCreate;\nexports.strictObject = strictObjectType;\nconst unionType = ZodUnion.create;\nexports.union = unionType;\nconst discriminatedUnionType = ZodDiscriminatedUnion.create;\nexports.discriminatedUnion = discriminatedUnionType;\nconst intersectionType = ZodIntersection.create;\nexports.intersection = intersectionType;\nconst tupleType = ZodTuple.create;\nexports.tuple = tupleType;\nconst recordType = ZodRecord.create;\nexports.record = recordType;\nconst mapType = ZodMap.create;\nexports.map = mapType;\nconst setType = ZodSet.create;\nexports.set = setType;\nconst functionType = ZodFunction.create;\nexports.function = functionType;\nconst lazyType = ZodLazy.create;\nexports.lazy = lazyType;\nconst literalType = ZodLiteral.create;\nexports.literal = literalType;\nconst enumType = ZodEnum.create;\nexports.enum = enumType;\nconst nativeEnumType = ZodNativeEnum.create;\nexports.nativeEnum = nativeEnumType;\nconst promiseType = ZodPromise.create;\nexports.promise = promiseType;\nconst effectsType = ZodEffects.create;\nexports.effect = effectsType;\nexports.transformer = effectsType;\nconst optionalType = ZodOptional.create;\nexports.optional = optionalType;\nconst nullableType = ZodNullable.create;\nexports.nullable = nullableType;\nconst preprocessType = ZodEffects.createWithPreprocess;\nexports.preprocess = preprocessType;\nconst pipelineType = ZodPipeline.create;\nexports.pipeline = pipelineType;\nconst ostring = () => stringType().optional();\nexports.ostring = ostring;\nconst onumber = () => numberType().optional();\nexports.onumber = onumber;\nconst oboolean = () => booleanType().optional();\nexports.oboolean = oboolean;\nexports.coerce = {\n string: ((arg) => ZodString.create({ ...arg, coerce: true })),\n number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),\n boolean: ((arg) => ZodBoolean.create({\n ...arg,\n coerce: true,\n })),\n bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),\n date: ((arg) => ZodDate.create({ ...arg, coerce: true })),\n};\nexports.NEVER = parseUtil_1.INVALID;\n","module.exports = __WEBPACK_EXTERNAL_MODULE__205__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(607);\n","module.exports = new __parcel__URL__(\"Hero 01.0a89e3b5.png\").toString();","module.exports = new __parcel__URL__(\"Solaria Demo Update 01.c847244e.png\").toString();","module.exports = new __parcel__URL__(\"Level_0.076f9bf4.ldtkl\").toString();","module.exports = new __parcel__URL__(\"Level_1.fb97a422.ldtkl\").toString();","module.exports = new __parcel__URL__(\"top-down.8a075006.ldtk\").toString();","export const Config = {\n PlayerSpeed: 16*2, // pixels/sec\n PlayerFrameSpeed: 200, // ms\n}"],"names":["e","$parcel$export","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$parcel$interopDefault","a","__esModule","default","$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","$2c23f148d58cd887$export$f05c91211c084e80","$2c23f148d58cd887$export$e04e17a44f37debc","$2c23f148d58cd887$export$dfcd1bb88f6d711b","$2c23f148d58cd887$export$89f31cec7c284d42","$2c23f148d58cd887$export$a3f070f3e473c3b","$2c23f148d58cd887$export$856e7d6d9d698871","$2c23f148d58cd887$export$caffe607ed29fca1","$2c23f148d58cd887$export$adc62e83dbcda319","$2c23f148d58cd887$export$f73d3eb6fd876d80","$2c23f148d58cd887$export$da248c61eea53296","$2c23f148d58cd887$export$f0455ab08e3fbd0e","$2c23f148d58cd887$export$c35d437ae5945fcd","$2c23f148d58cd887$export$67ee29bab3792d4c","$2c23f148d58cd887$export$d230853e97069d46","$2c23f148d58cd887$export$6cfd78ddb48c90c6","$2c23f148d58cd887$export$3769e64eb87b5ecc","$2c23f148d58cd887$export$54dc36bc2fac5425","$2c23f148d58cd887$export$387a78ab20784494","$2c23f148d58cd887$export$d06866a9fb0606da","$2c23f148d58cd887$export$83c931ba0d3bbaf5","$2c23f148d58cd887$export$1a553341cd0b8415","$2c23f148d58cd887$export$43416332cf06b1f","$2c23f148d58cd887$export$63080c4de6cfc362","$2c23f148d58cd887$export$fa45ecb18b97ae89","$2c23f148d58cd887$export$c24f8f35353a1e26","$2c23f148d58cd887$export$8688def55452cbca","$2c23f148d58cd887$export$665d5a662b7213f3","$2c23f148d58cd887$export$79f141de891a5fed","$2c23f148d58cd887$export$41606648ac8a293c","$2c23f148d58cd887$export$8d01c972ee8b14a9","$2c23f148d58cd887$export$c89a927ffc67e6fa","$2c23f148d58cd887$export$e2395b697f5a931f","$2c23f148d58cd887$export$9735c82c4bae3302","$2c23f148d58cd887$export$44e6803d1d57f89a","$2c23f148d58cd887$export$1ed419d47673a225","$2c23f148d58cd887$export$b7c6eef0ebb06133","$2c23f148d58cd887$export$3c9e91dc1b611d2e","$2c23f148d58cd887$export$ce0ca64520c7bfd2","$2c23f148d58cd887$export$83caf30c40e9d4b8","$2c23f148d58cd887$export$4df0464d8c812c98","$2c23f148d58cd887$export$55e924fc640a8405","$2c23f148d58cd887$export$fbd6eb86d6a3f08","$2c23f148d58cd887$export$7cd2649c3408da6c","$2c23f148d58cd887$export$897cd666d936ac4c","$2c23f148d58cd887$export$cf976780b3106589","$2c23f148d58cd887$export$5dcfde0f6b96512b","$2c23f148d58cd887$export$ddb2ed749236e720","$2c23f148d58cd887$export$892596cec99bc70e","$2c23f148d58cd887$export$8ed4b5bb5352fe14","$2c23f148d58cd887$export$c46090c9df657074","$2c23f148d58cd887$export$b3bf2ffaa538264b","$2c23f148d58cd887$export$16fa2f45be04daa8","$2c23f148d58cd887$export$d16a7c95008e315d","$2c23f148d58cd887$export$abda45806f5adbae","$2c23f148d58cd887$export$e5a30aa3d28b26e2","$2c23f148d58cd887$export$de7807bd8bd828df","$2c23f148d58cd887$export$1bdfb0c7c42d632d","$2c23f148d58cd887$export$bf92f329076cd7a3","$2c23f148d58cd887$export$71de6146fb6d69d2","$2c23f148d58cd887$export$71efaa2be447940c","$2c23f148d58cd887$export$d78c8c6074541cf2","$2c23f148d58cd887$export$7d34ad93c25aa8e7","$2c23f148d58cd887$export$153e5dc2c098b35c","$2c23f148d58cd887$export$f7c1896972d6c454","$2c23f148d58cd887$export$c3e6e677dda8521a","$2c23f148d58cd887$export$e52858e61b0ea117","$2c23f148d58cd887$export$3d1f12550a40f54d","$2c23f148d58cd887$export$4544b2d7eff33859","$2c23f148d58cd887$export$dd6b48f99ee8a36","$2c23f148d58cd887$export$aafe01318a900193","$2c23f148d58cd887$export$fd69b6a3b7f47e29","$2c23f148d58cd887$export$e1545123b54f6785","$2c23f148d58cd887$export$7419ff430885d61c","$2c23f148d58cd887$export$a340d4e5571cbd07","$2c23f148d58cd887$export$e695250628cde35","$2c23f148d58cd887$export$c5e124f7bab3d492","$2c23f148d58cd887$export$cacd6541cfeeb6c1","$2c23f148d58cd887$export$a74d557191881f82","$2c23f148d58cd887$export$99bf88c530739783","$2c23f148d58cd887$export$4b7264771109adb6","$2c23f148d58cd887$export$62053d374d83dfb1","$2c23f148d58cd887$export$d7078bb1ea3ba3f2","$2c23f148d58cd887$export$86ae8da356d53161","$2c23f148d58cd887$export$62230588c4867d28","$2c23f148d58cd887$export$df007b1d5b86e25a","$2c23f148d58cd887$export$6ff391a2049fdf40","$2c23f148d58cd887$export$89e5ccdc4c19a8f6","$2c23f148d58cd887$export$2cbc8fe61dd10773","$2c23f148d58cd887$export$d45269226a4bbdc1","$2c23f148d58cd887$export$2c3b404bf3a77a1f","$2c23f148d58cd887$export$20434e7e042d306a","$2c23f148d58cd887$export$462adefbb095232e","$2c23f148d58cd887$export$83f8212621739c1f","$2c23f148d58cd887$export$bc644a473284d944","$2c23f148d58cd887$export$66b8a9cb33a156c","$2c23f148d58cd887$export$c7b7134fd828a5","$2c23f148d58cd887$export$ec8b666c5fe2c75a","$2c23f148d58cd887$export$4fae95256245c8c0","$2c23f148d58cd887$export$86d9a347f2bf71d6","$2c23f148d58cd887$export$ada873a34909da65","$2c23f148d58cd887$export$afee3afd6be961ec","$2c23f148d58cd887$export$c03216fb3a7a2f87","$2c23f148d58cd887$export$81940238f313e11f","$2c23f148d58cd887$export$40f8f9a8f94db930","$2c23f148d58cd887$export$c579e21b95165414","$2c23f148d58cd887$export$c983850c6c9d8b0e","$2c23f148d58cd887$export$be5b6c6ac24b4683","$2c23f148d58cd887$export$434ba092ed0eee4e","$2c23f148d58cd887$export$455f05776f1ba8ba","$2c23f148d58cd887$export$89abf52a030e56ee","$2c23f148d58cd887$export$549c899505235621","$2c23f148d58cd887$export$1f6d1255105a925c","$2c23f148d58cd887$export$23b468d4ca3f8c96","$2c23f148d58cd887$export$6976e674e6d5804c","$2c23f148d58cd887$export$420acfc1740638d3","$2c23f148d58cd887$export$e84927905accfe51","$2c23f148d58cd887$export$c9d7bf589772a8ce","$2c23f148d58cd887$export$d5011a4647754c9b","$2c23f148d58cd887$export$b8c6aa234afa01bc","$2c23f148d58cd887$export$6c3776220abeb931","$2c23f148d58cd887$export$27a9cd7ebdd38262","$2c23f148d58cd887$export$fb1b94e06ba8ebc8","$2c23f148d58cd887$export$3d953a2d86354b5f","$2c23f148d58cd887$export$88528019d270f582","$2c23f148d58cd887$export$402da60b1c009e43","$2c23f148d58cd887$export$757ccd1717b77f48","$2c23f148d58cd887$export$48ebf29bc7cb1dd7","$2c23f148d58cd887$export$3c8c04bde7eed7cb","$2c23f148d58cd887$export$adfa9d260876eca5","$2c23f148d58cd887$export$6c043ed3a716859a","$2c23f148d58cd887$export$9f9afb456a8bef30","$2c23f148d58cd887$export$1033a6fa0779f4f5","$2c23f148d58cd887$export$38f8109d2b8f43ef","$2c23f148d58cd887$export$b5aa7fe3676b74a9","$2c23f148d58cd887$export$5213deb2877a09f2","$2c23f148d58cd887$export$280e9a68c3ffd919","$2c23f148d58cd887$export$49a1ecce8d203","$2c23f148d58cd887$export$f5b8910cec6cf069","$2c23f148d58cd887$export$99f13cbf742a0580","$2c23f148d58cd887$export$2ae6ec0f10d96242","$2c23f148d58cd887$export$d379657aa3df1705","$2c23f148d58cd887$export$ffed6a4cd9a88787","$2c23f148d58cd887$export$7705889256a9371a","$2c23f148d58cd887$export$539f65e788a82c62","$2c23f148d58cd887$export$851e6d93385b6ad2","$2c23f148d58cd887$export$4b0c1c390bf9a356","$2c23f148d58cd887$export$16e4d70cc375e707","$2c23f148d58cd887$export$4b0075e5ea5e1f26","$2c23f148d58cd887$export$f3a6c1ca682fd40f","$2c23f148d58cd887$export$b04be29aa201d4f5","$2c23f148d58cd887$export$b3509fba7d85d294","$2c23f148d58cd887$export$17d680238e50603e","$2c23f148d58cd887$export$8b98feb4a2766c75","$2c23f148d58cd887$export$3b0d6d7590275603","$2c23f148d58cd887$export$38d47553764a3d88","$2c23f148d58cd887$export$1c4c6d3f8d56581","$2c23f148d58cd887$export$fc869739b2177284","$2c23f148d58cd887$export$243e62d78d3b544d","$2c23f148d58cd887$export$efa9a398d6368992","$2c23f148d58cd887$export$a2d8b23205c25948","$2c23f148d58cd887$export$5b12bf1653c0dd85","$2c23f148d58cd887$export$9f9b2346169b00c0","$2c23f148d58cd887$export$8c37b217b84d3f89","$2c23f148d58cd887$export$35624b13e79b24a9","$2c23f148d58cd887$export$f75e7304717c9cbc","$2c23f148d58cd887$export$ec1251c88c8bd5c9","$2c23f148d58cd887$export$d17844835b0fe8a8","$2c23f148d58cd887$export$d1d8cb3d5c2a5671","$2c23f148d58cd887$export$4d607ef791645d6","$2c23f148d58cd887$export$f0b55daf9f154b55","$2c23f148d58cd887$export$fa9699e41ba6faff","$2c23f148d58cd887$export$57ca7e07b341709d","$2c23f148d58cd887$export$77cea355fa80b5f4","$2c23f148d58cd887$export$8844adde4348f85c","$2c23f148d58cd887$export$d63d7cff08fe4dc9","$2c23f148d58cd887$export$a960801e47624f4f","$2c23f148d58cd887$export$ed6a63ee685a4d78","$2c23f148d58cd887$export$4fe52ae24ae61d51","$2c23f148d58cd887$export$c36c68baa13912a5","$2c23f148d58cd887$export$616c632b282478dd","$2c23f148d58cd887$export$459b1801e3134a24","$2c23f148d58cd887$export$2f09efa5b67124a7","$2c23f148d58cd887$export$618424ba3f30cd41","$2c23f148d58cd887$export$4a963ea7a16edf21","$2c23f148d58cd887$export$a4017560efebe97d","$2c23f148d58cd887$export$982e5de016bedff1","$2c23f148d58cd887$export$6860c0696b73f79b","$2c23f148d58cd887$export$94806efd9890932f","$2c23f148d58cd887$export$3bee0b2628b43478","$2c23f148d58cd887$export$caed39dbb767d548","$2c23f148d58cd887$export$7e5ab4f7f9fd407","$2c23f148d58cd887$export$330520496d871ecf","$2c23f148d58cd887$export$7d31b617c820d435","$2c23f148d58cd887$export$f23a2a272a8df60","$2c23f148d58cd887$export$14963ee5c8637e11","$2c23f148d58cd887$export$1d2c184034fc4cc2","$2c23f148d58cd887$export$fea21a521a6360c1","$2c23f148d58cd887$export$8c15bdf7e3727f73","$2c23f148d58cd887$export$6eb043bf81d89752","$2c23f148d58cd887$export$e390b859365a3d5b","$2c23f148d58cd887$export$82a33120f6a0d987","$2c23f148d58cd887$export$1ec85152758537e0","$2c23f148d58cd887$export$a8584993858a18df","$2c23f148d58cd887$export$906049a3747337a6","$2c23f148d58cd887$export$dbd8a6303ac26a42","$2c23f148d58cd887$export$9f68b6f37a444556","$2c23f148d58cd887$export$fe2b6ac465da985d","$2c23f148d58cd887$export$4c3c82f4dcd79fcc","$2c23f148d58cd887$export$e4ce43ec0499fb8f","$2c23f148d58cd887$export$e44279b5c44add28","$2c23f148d58cd887$export$dfa3a012bb2ef2e1","$2c23f148d58cd887$export$8201b979875baf73","$2c23f148d58cd887$export$b82688eb02220411","$2c23f148d58cd887$export$62297b13309008b2","$2c23f148d58cd887$export$b986383a50b53ea4","$2c23f148d58cd887$export$ad5b3d166367714c","$2c23f148d58cd887$export$a92776769f460054","$2c23f148d58cd887$export$eeb71495ca594706","$2c23f148d58cd887$export$a186db52eed6d40e","$2c23f148d58cd887$export$c07ce6d13c46df49","$2c23f148d58cd887$export$4617fb02663045ef","$2c23f148d58cd887$export$32437fc39ad02208","$2c23f148d58cd887$export$f9d61a2a6155ab51","$2c23f148d58cd887$export$9bd81f7d9b69ccb3","$2c23f148d58cd887$export$3e4ff2216a90b8a4","$2c23f148d58cd887$export$39a853cfb5a94a63","$2c23f148d58cd887$export$62833702c6700187","$2c23f148d58cd887$export$a43177620e7a9310","$2c23f148d58cd887$export$a16b6ef1fd362a19","$2c23f148d58cd887$export$91397be43fc980cc","$2c23f148d58cd887$export$23b9d128e61caefd","$2c23f148d58cd887$export$ab681471d41eeddc","$2c23f148d58cd887$export$38af1803e3442a7f","$2c23f148d58cd887$export$c1825d965cf69ea3","$2c23f148d58cd887$export$a98515d67472a41f","$2c23f148d58cd887$export$57486627f01aaaf3","$2c23f148d58cd887$export$77630fcd7c3f2eb6","$2c23f148d58cd887$export$3bf088dd0bb7575","$2c23f148d58cd887$export$2f3ac66e390c188b","$2c23f148d58cd887$export$d160a188872e1e4e","$2c23f148d58cd887$export$5c7bd08c630c970c","$2c23f148d58cd887$export$462bb059fed9d9e5","$2c23f148d58cd887$export$6428a7f2611ef1fa","$2c23f148d58cd887$export$80a00690bda7f17e","$2c23f148d58cd887$export$50994fad4c4676f4","$2c23f148d58cd887$export$85990f0f98a390bb","$2c23f148d58cd887$export$5bff0d6cc6200d64","$2c23f148d58cd887$export$3075603db8e6204c","$2c23f148d58cd887$export$e1896ac0c4970221","$2c23f148d58cd887$export$bd73ddfe5f8475d8","$2c23f148d58cd887$export$f62bb2892382b3dd","$2c23f148d58cd887$export$cbf2d83d1eab018a","$2c23f148d58cd887$export$9ad53eded130cce4","$2c23f148d58cd887$export$6a4eb2e7fc9e8903","$2c23f148d58cd887$export$e1dae5660003ffa7","$2c23f148d58cd887$export$a12e67a4b4590901","$2c23f148d58cd887$export$7c88eb83095afadd","$2c23f148d58cd887$export$c586aa7b67d94d19","$2c23f148d58cd887$export$47b45ce774071a36","$2c23f148d58cd887$export$9440a22058545f9a","$2c23f148d58cd887$export$5f1af8db9871e1d6","$2c23f148d58cd887$export$3720eb13f948f394","$2c23f148d58cd887$export$fd1bfc71f64c538c","$2c23f148d58cd887$export$235cb65c20ad2b7","$2c23f148d58cd887$export$16ec26812de3ce7a","$2c23f148d58cd887$export$dac3abbdc575ce73","$2c23f148d58cd887$export$c57e9b2d8b9e4de","$2c23f148d58cd887$export$fb98e3a2a4cd92d7","$2c23f148d58cd887$export$563a914cafbdc389","$2c23f148d58cd887$export$1def2aa75b7c7fe0","$2c23f148d58cd887$export$be58926105124dd4","$2c23f148d58cd887$export$2eba8ec3a333fdbb","$2c23f148d58cd887$export$41fb9f06171c75f4","$2c23f148d58cd887$export$14963f945d6d59f0","$2c23f148d58cd887$export$ba8651401a8a2b84","$2c23f148d58cd887$export$f8f26dd395d7e1bd","$2c23f148d58cd887$export$9b781de7bf37bf48","$2c23f148d58cd887$export$ab650c8e5b9b9f2c","$2c23f148d58cd887$export$41825a1ed6473903","$2c23f148d58cd887$export$f5ae2f144b95ebf4","$2c23f148d58cd887$export$31ac8f65680039dd","$2c23f148d58cd887$export$d5c6f73f7a77b9d","$2c23f148d58cd887$export$8bfbf00b5dba81f6","$2c23f148d58cd887$export$2af5ef044257da25","$2c23f148d58cd887$export$8c3375c231593a9d","$2c23f148d58cd887$export$9a4eae43f302c46e","$2c23f148d58cd887$export$812cd9544993280d","$2c23f148d58cd887$export$a4913eafbb02ceb4","$2c23f148d58cd887$export$7d15b64cf5a3a4c4","$2c23f148d58cd887$export$c372a5d5a3996cbf","$2c23f148d58cd887$export$7149c6ffc9994c32","$2c23f148d58cd887$export$d436988b04cb99a5","$2c23f148d58cd887$export$3ba9f2e94585ecc6","$2c23f148d58cd887$export$25dac40984956196","$2c23f148d58cd887$export$57932b71da6538b7","$2c23f148d58cd887$export$a17402ef5f32064d","$2c23f148d58cd887$export$d5dea09620a858fd","$2c23f148d58cd887$export$1377812d73ae3cab","$2c23f148d58cd887$export$331f4c7ef74a9752","$2c23f148d58cd887$export$5f4e18965661d41f","$2c23f148d58cd887$export$817667946f51142b","$2c23f148d58cd887$export$adc479603c39b28","$2c23f148d58cd887$export$ba30ba18962891e7","$2c23f148d58cd887$export$bcf8f1355133000b","$2c23f148d58cd887$export$256576ea924e6c90","$2c23f148d58cd887$export$786d9ab531bddbaa","$2c23f148d58cd887$export$e87630d8ef35465d","$2c23f148d58cd887$export$c3cedacda2d7ce48","$2c23f148d58cd887$export$5a62d8eea226ddc","$2c23f148d58cd887$export$640d107500a3202a","$2c23f148d58cd887$export$506bf22710a79182","$2c23f148d58cd887$export$8b958c8ecd94a804","$2c23f148d58cd887$export$816343276f749e02","$2c23f148d58cd887$export$d02631cccf789723","$2c23f148d58cd887$export$5dc5812d8b390c43","$2c23f148d58cd887$export$c5552dfdbc7cec71","$2c23f148d58cd887$export$56cb859c01fa134d","$2c23f148d58cd887$export$cba01ba138429a1d","$2c23f148d58cd887$export$202e0172ed3c7be0","$2c23f148d58cd887$export$d55298c9efc5ed14","$2c23f148d58cd887$var$__webpack_modules__","__webpack_exports__","__webpack_require__","d","Z","__WEBPACK_DEFAULT_EXPORT__","_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__","_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default","_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__","___CSS_LOADER_EXPORT___","_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default","push","cssWithMappingToString","list","toString","map","item","content","needLayer","concat","length","join","i","modules","media","dedupe","supports","layer","undefined","alreadyImportedModules","k","_k","cssMapping","btoa","base64","unescape","encodeURIComponent","JSON","stringify","__unused_webpack_exports","entryUnbind","path","keys","isCallable","tryToString","$TypeError","TypeError","argument","isObject","$String","String","toIndexedObject","toAbsoluteIndex","lengthOfArrayLike","createMethod","IS_INCLUDES","$this","el","fromIndex","value","O","index","includes","indexOf","fails","METHOD_NAME","method","uncurryThis","slice","arraySlice","floor","Math","sort","array","comparefn","element","j","middle","left","right","llength","rlength","lindex","rindex","stringSlice","it","TO_STRING_TAG_SUPPORT","classofRaw","TO_STRING_TAG","wellKnownSymbol","$Object","CORRECT_ARGUMENTS","arguments","tryGet","key","error","tag","result","callee","hasOwn","ownKeys","getOwnPropertyDescriptorModule","definePropertyModule","target","source","exceptions","f","getOwnPropertyDescriptor","DESCRIPTORS","createPropertyDescriptor","object","bitmap","writable","makeBuiltIn","defineGlobalProperty","options","simple","name","global","unsafe","nonConfigurable","nonWritable","P","document1","document","EXISTS","createElement","firefox","userAgent","match","UA","test","navigator","version","process","Deno","versions","v8","split","webkit","CONSTRUCTOR","METHOD","prototype","createNonEnumerableProperty","defineBuiltIn","copyConstructorProperties","isForced","targetProperty","sourceProperty","descriptor","TARGET","GLOBAL","STATIC","stat","dontCallGetSet","forced","sham","exec","bind","hasOwnProperty","NATIVE_BIND","Function","apply","FunctionPrototype","getDescriptor","CONFIGURABLE","PROPER","uncurryThisWithBind","fn","namespace","aCallable","isNullOrUndefined","V","func","check","window","self","g","toObject","classof","propertyIsEnumerable","store","functionToString","inspectSource","has","NATIVE_WEAK_MAP","shared","sharedKey","hiddenKeys","OBJECT_ALREADY_INITIALIZED","TypeError1","WeakMap1","WeakMap","state","metadata","facade","STATE","enforce","getterFor","TYPE","type","documentAll","all","replacement","feature","detection","data","normalize","POLYFILL","NATIVE","string","replace","toLowerCase","getBuiltIn","isPrototypeOf","USE_SYMBOL_AS_UID","$Symbol","toLength","obj","CONFIGURABLE_FUNCTION_NAME","InternalStateModule","enforceInternalState","getInternalState","CONFIGURABLE_LENGTH","TEMPLATE","getter","setter","arity","constructor","ceil","trunc","x","__unused_webpack_module","IE8_DOM_DEFINE","V8_PROTOTYPE_DEFINE_BUG","anObject","toPropertyKey","$defineProperty","$getOwnPropertyDescriptor","ENUMERABLE","WRITABLE","Attributes","current","propertyIsEnumerableModule","internalObjectKeys","enumBugKeys","getOwnPropertyNames","getOwnPropertySymbols","names","$propertyIsEnumerable","NASHORN_BUG","input","pref","val","valueOf","getOwnPropertyNamesModule","getOwnPropertySymbolsModule","uid","SHARED","IS_PURE","mode","copyright","license","V8_VERSION","symbol","Symbol","toIntegerOrInfinity","max","min","integer","IndexedObject","requireObjectCoercible","number","len","isSymbol","getMethod","ordinaryToPrimitive","TO_PRIMITIVE","exoticToPrim","toPrimitive","postfix","random","NATIVE_SYMBOL","iterator","Symbol1","WellKnownSymbolsStore","createWellKnownSymbol","withoutSetter","$","deletePropertyOrThrow","internalSort","arrayMethodIsStrict","FF","IE_OR_EDGE","V8","WEBKIT","nativeSort","FAILS_ON_UNDEFINED","FAILS_ON_NULL","STRICT_METHOD","STABLE_SORT","chr","fromCharCode","b","charAt","proto","itemsLength","items","arrayLength","y","nativeKeys","$2c23f148d58cd887$var$__webpack_module_cache__","$2c23f148d58cd887$var$__webpack_require__","moduleId","cachedModule","definition","o","prop","r","toStringTag","$2c23f148d58cd887$var$__webpack_exports__","y1j","ActionCompleteEvent","fWn","ActionContext","Ia8","ActionQueue","rqv","ActionSequence","zH6","ActionStartEvent","hLI","ActionsComponent","yyv","ActionsSystem","tX5","ActivateEvent","vtX","Actor","r7K","AddedComponent","cE4","AffineMatrix","fwF","Animation","sce","AnimationDirection","AQ6","AnimationEvents","_c7","AnimationStrategy","KUs","ArcadeSolver","Ajp","AudioContextFactory","dkO","Axes","RDh","Axis","_H9","BaseAlign","mxs","Blink","OmD","BodyComponent","kBf","BoundingBox","C4F","BroadphaseStrategy","NQt","BrowserComponent","JjN","BrowserEvents","EK_","Buttons","V1s","Camera","xHm","CameraEvents","Xz7","Canvas","Cdc","Circle","FKn","CircleCollider","SUY","Clock","ab2","ClosestLine","GfZ","ClosestLineJumpTable","YMS","Collider","oyv","ColliderComponent","aUb","CollisionContact","SdD","CollisionEndEvent","JUv","CollisionGroup","jEj","CollisionGroupManager","TFq","CollisionJumpTable","HDU","CollisionPostSolveEvent","R_y","CollisionPreSolveEvent","t50","CollisionStartEvent","s$$","CollisionSystem","v2G","CollisionType","Ilk","Color","s9i","ColorBlindFlags","dxL","ColorBlindnessMode","LLX","ColorBlindnessPostProcessor","wA2","Component","R_p","CompositeCollider","IQ$","Configurable","I5F","ConsoleAppender","X8$","ContactConstraintPoint","FR6","ContactEndEvent","pTZ","ContactSolveBias","U8o","ContactStartEvent","kbG","CoordPlane","FEv","CrossFade","iS_","DeactivateEvent","cGG","Debug","ETM","DebugConfig","RPN","DebugGraphicsComponent","skb","DebugSystem","SLU","DebugText","Q3w","DefaultAntialiasOptions","xK2","DefaultLoader","vrO","DefaultPhysicsConfig","EA2","DefaultPixelArtOptions","RdJ","DegreeOfFreedom","cNu","Delay","wtG","DeprecatedStaticToConfig","gU7","Detector","LSk","Die","Nmp","Direction","twX","Director","UND","DirectorEvents","d1Y","DisplayMode","xrL","DynamicTree","sRW","DynamicTreeCollisionProcessor","cmV","EX_VERSION","qWz","EaseBy","N0Q","EaseTo","q8b","EasingFunctions","ynB","EdgeCollider","jT9","ElasticToActorStrategy","wAz","EmitterType","D4V","Engine","NLr","EngineEvents","N6H","EnterTriggerEvent","W1A","EnterViewPortEvent","JHW","Entity","ZZ$","EntityEvents","v2K","EntityManager","pBf","EventDispatcher","vpe","EventEmitter","GMl","EventTypes","zW2","Events_namespaceObject","B0K","ExResponse","Nv7","ExcaliburGraphicsContext2DCanvas","C_p","ExcaliburGraphicsContextWebGL","MUA","ExitTriggerEvent","xqU","ExitViewPortEvent","pTp","Fade","trb","FadeInOut","vUK","Flags","j9l","Follow","Zxw","Font","v51","FontCache","gYv","FontSource","Hdx","FontStyle","Z$d","FontUnit","iqV","FpsSampler","o$7","FrameStats","olM","Future","Zm$","GameEvent","$QH","GameStartEvent","i78","GameStopEvent","nJg","Gamepad","h6u","GamepadAxisEvent","hts","GamepadButtonEvent","j88","GamepadConnectEvent","VME","GamepadDisconnectEvent","fy2","Gamepads","nt","Gif","Ukr","GlobalCoordinates","zsu","Graphic","oA6","GraphicsComponent","TVh","GraphicsGroup","xxj","GraphicsSystem","XdK","HiddenEvent","fBD","HorizontalFirst","Jmb","ImageFiltering","cXo","ImageSource","Dm5","InitializeEvent","IIB","Input_Index_namespaceObject","IX$","InputHost","ebW","InputMapper","zI0","Integrator","LYD","IsometricEntityComponent","cEG","IsometricEntitySystem","SEl","IsometricMap","t9V","IsometricTile","ez5","KeyEvent","N1d","Keyboard","R8U","Keys","SKZ","KillEvent","__J","Label","RI$","LimitCameraBoundsStrategy","x12","Line","ccz","LineSegment","aNw","Loader","XrL","LoaderEvents","xwn","LockCameraToActorAxisStrategy","dNK","LockCameraToActorStrategy","ini","LogLevel","YdH","Logger","F5T","Material","y3G","Matrix","l57","MatrixLocations","xn0","MediaEvent","t2V","Meet","uxB","MotionComponent","cpd","MotionSystem","fiy","MoveBy","$XZ","MoveTo","UG6","NativePointerButton","uqK","NativeSoundEvent","STE","NativeSoundProcessedEvent","Hq9","None","y$z","Observable","mAD","OffscreenSystem","sOq","Pair","hUw","ParallaxComponent","_0G","ParallelActions","Sqs","ParseGif","hpZ","Particle","Vol","ParticleEmitter","vYX","ParticleTransform","wIZ","Physics","cBi","PhysicsStats","c30","PhysicsWorld","PGK","PointerAbstraction","MPV","PointerButton","RFv","PointerComponent","Ux6","PointerEvent","rxy","PointerEventReceiver","I$c","PointerScope","kfC","PointerSystem","VjY","PointerType","mgq","Polygon","YVA","PolygonCollider","Kgp","Pool","HH$","PostCollisionEvent","M_d","PostDebugDrawEvent","rgh","PostDrawEvent","Ra6","PostFrameEvent","KhR","PostKillEvent","gvQ","PostTransformDrawEvent","BS5","PostUpdateEvent","xhz","PreCollisionEvent","xOq","PreDebugDrawEvent","a9j","PreDrawEvent","bHk","PreFrameEvent","CgK","PreKillEvent","A0M","PreLoadEvent","cEd","PreTransformDrawEvent","cuY","PreUpdateEvent","kvE","Projection","SBu","QuadIndexBuffer","PsT","QuadTree","AE_","Query","ctO","QueryManager","OLH","RadiusAroundActorStrategy","kky","Random","nSF","Raster","zHn","Ray","zwx","RealisticSolver","AeJ","Rectangle","hLz","RemovedComponent","wA","Repeat","jhr","RepeatForever","GVs","Resolution","_zO","Resource","LXZ","ResourceEvents","w6$","RotateBy","mhV","RotateTo","MOD","RotationType","kwd","ScaleBy","Lmr","ScaleTo","xsS","Scene","K5l","SceneEvents","lLr","Screen","Z$r","ScreenAppender","IXb","ScreenElement","Xsu","ScreenEvents","SGH","ScreenShader","SMj","ScrollPreventionMode","L34","Semaphore","exe","Shader","bnF","Shape","MFA","Side","kPj","SolverStrategy","$uU","Sound","Sap","SoundEvents","jyi","Sprite","E03","SpriteFont","V6q","SpriteSheet","rg2","StandardClock","DVW","StateMachine","nVo","StrategyContainer","F6N","Stream","xP7","System","Odq","SystemManager","uY9","SystemPriority","Zif","SystemType","c_d","TagQuery","MJk","TestClock","xvT","Text","PHM","TextAlign","dpR","TextureLoader","n9L","Tile","KwO","TileMap","SxM","TileMapEvents","B7y","Timer","x7r","Toaster","wx7","transform_Transform","Uvn","TransformComponent","uTP","Transition","OFT","TreeNode","xzN","Trigger","CcZ","TriggerEvents","M5Z","TwoPI","ZrN","Util_Index_namespaceObject","OWs","Vector","dF9","VectorView","oZy","VertexBuffer","rD2","VertexLayout","KmN","VerticalFirst","VHo","VisibleEvent","ohE","WebAudio","R$E","WebAudioInstance","xQN","WheelDeltaMode","AdJ","WheelEvent","q3I","World","Pab","canonicalizeAngle","uZ5","clamp","TAE","coroutine","McK","createId","F9c","frac","k0b","hasGraphicsTick","hnT","hasOnInitialize","RSJ","hasOnPostUpdate","Mku","hasOnPreUpdate","h90","hasPostDraw","rms","hasPreDraw","ErP","has_initialize","aVg","has_postupdate","lPc","has_preupdate","Z8E","isAddedComponent","k15","isComponentCtor","YsU","isLoaderConstructor","lNv","isRemovedComponent","Xyg","isSceneConstructor","cu9","isScreenElement","p88","isSystemConstructor","MZQ","maxMessages","FUM","obsolete","BxR","pixelSnapEpsilon","vdf","randomInRange","iaL","randomIntInRange","w6H","range","Q4c","resetObsoleteCounter","Xxe","sign","Uxb","toDegrees","Yr5","toRadians","Bhw","vec","yOA","webgl_util_namespaceObject","getAttributeComponentSize","getAttributePointerType","getGlTypeSizeBytes","DrawUtil_namespaceObject","circle","line","point","roundRect","vector","polyfill","audioContext","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","callback","setInterval","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","AudioContext","webkitAudioContext","replaceMe","ctx","decodeAudioData","arrayBuffer","Promise","resolve","reject","mozAudioContext","msAudioContext","oAudioContext","devicePixelRatio","DrawUtil","addItemToArray","contains","delay","fail","getPosition","omit","removeItemFromArray","useCanvasGraphicsContext","enable","freeze","_FROZEN","_reset","_FLAGS","flagName","disable","isEnabled","show","_isCompleted","promise","_resolver","_rejecter","isCompleted","_paused","_listeners","_listenersOnce","_pipes","clear","on","eventName","handler","_a","close","off","once","_b","newListeners","filter","h","newOnceListeners","emit","event","forEach","onces","pipe","emitter","splice","unpipe","pause","unpause","seed","_lowerMask","_upperMask","_w","_n","_m","_u","_s","_t","_c","_l","_f","_mt","Array","Date","now","_index","_twist","mag01","nextInt","next","floating","bool","likelihood","pickOne","pickSet","numPicks","allowDuplicates","_pickSetWithDuplicates","_pickSetWithoutDuplicates","currentPick","tempArray","shuffle","swap","randomIndex","d4","d6","d8","d10","d12","d20","PI","angle","tmpAngle","radians","degrees","from","to","_x","round","Zero","One","Half","Up","Down","Left","Right","fromAngle","cos","sin","isValid","isNaN","Infinity","distance","vec1","vec2","sqrt","pow","_y","setTo","equals","tolerance","abs","deltaX","deltaY","squareDistance","clampMagnitude","magnitude","newSize","size","newLength","scale","average","add","sizeOrScale","dest","sub","addEqual","subEqual","scaleEqual","dot","cross","num","perpendicular","normal","negate","toAngle","atan2","rotate","anchor","sinAngle","cosAngle","clone","fixed","toFixed","fromRGB","fromRGBString","parseInt","parseFloat","fromHex","hex","fromHSL","l","temp","HSLColor","toRGBA","lighten","factor","fromRGBA","darken","saturate","desaturate","multiply","color","newR","screen","color1","invert","color2","equal","format","toHSLA","toHex","_componentToHex","c","fillStyle","Black","White","Gray","LightGray","DarkGray","Yellow","Orange","Red","Vermilion","Rose","Magenta","Violet","Blue","Azure","Cyan","Viridian","Green","Chartreuse","Transparent","ExcaliburBlue","hue2rgb","p","q","t","_appenders","defaultLevel","Info","_logOnceSet","Set","_INSTANCE","addAppender","getInstance","appender","clearAppenders","_log","level","args","log","_logOnce","serialized","debug","debugOnce","info","infoOnce","warn","Warn","warnOnce","errorOnce","fatal","Fatal","fatalOnce","console","consoleArgs","unshift","_messages","_pos","_color","_options","canvas","_ctx","getContext","style","position","zIndex","body","appendChild","_positionScreenAppenderCanvas","engine","events","_d","width","resolution","height","pagePos","screenToPageCoordinates","top","xPos","message","clearRect","pos","fillText","getOpposite","side","Top","Bottom","fromDirection","direction","directions","directionEnum","Number","MAX_VALUE","maxIndex","leftOrOptions","bottom","_points","getSideFromIntersection","intersection","fromPoints","points","minX","minY","maxX","maxY","fromDimension","hasZeroDimensions","center","topLeft","bottomRight","topRight","bottomLeft","translate","getPoints","shifted","transform","matrix","xa1","xa2","xb1","xb2","ya1","ya2","yb1","yb2","matrixPos","getPerimeter","wx","_left","_right","_top","_bottom","rayCast","ray","farClipDistance","tmin","tmax","xinv","dir","yinv","tx1","tx2","ty1","ty2","rayCastTime","combine","other","dimensions","overlaps","epsilon","totalBoundingBox","intersect","overlapX","overlapY","intersectWithSide","bb","draw","ex","drawRect","rect","getBoundingClientRect","scrollX","scrollY","milliseconds","clock","future","schedule","setTimeout","newObj","Float32Array","_scaleX","_scaleSignX","_scaleY","_scaleSignY","ortho","near","far","mat","toDOMMatrix","DOMMatrix","fromFloat32Array","identity","reset","translation","sx","sy","rotation","angleRadians","vectorOrMatrix","resultX","resultY","a11","a21","a31","a41","a12","a22","a32","a42","a13","a23","a33","a43","a14","a24","a34","a44","b11","b21","b31","b41","b12","b22","b32","b42","b13","b23","b33","b43","b14","b24","b34","b44","getScale","setPosition","sine","cosine","setRotation","currentScale","getRotation","getScaleY","getScaleX","xscale","yscale","setScaleX","setScaleY","setScale","getBasisDeterminant","getAffineInverse","inverseDet","m","tx","ty","isIdentity","Float64Array","_scale","determinant","inverse","to4x4","TransformStack","_transforms","_currentTransform","save","restore","pop","StateStack","_states","_currentState","_getDefaultState","opacity","z","tint","material","_cloneState","Complete","Load","LoadStart","Progress","responseType","bustCache","logger","isLoaded","_cacheBust","uri","query","load","request","XMLHttpRequest","open","addEventListener","status","response","statusText","send","watch","change","__isProxy","Proxy","createHandler","typeType","watchAny","isStale","_transformStale","flipHorizontal","_flipHorizontal","flipVertical","_flipVertical","_rotation","origin","_origin","_e","_g","_ID","showDebug","_width","_height","cloneGraphicOptions","localBounds","_preDraw","_drawImage","_postDraw","_rotate","_flip","scaleDirX","scaleDirY","image","_logger","_dirty","sourceView","destSize","_updateSpriteDimensions","ready","then","newWidth","newHeight","nativeWidth","nativeHeight","drawImage","gl","_textureMap","Map","_gl","_MAX_TEXTURE_SIZE","getParameter","MAX_TEXTURE_SIZE","dispose","delete","filtering","forceUpdate","tex","bindTexture","TEXTURE_2D","texImage2D","RGBA","UNSIGNED_BYTE","createTexture","checkImageSizeSupportedAndLog","pixelStorei","UNPACK_PREMULTIPLY_ALPHA_WEBGL","texParameteri","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","filterMode","TEXTURE_MIN_FILTER","Pixel","NEAREST","LINEAR","TEXTURE_MAG_FILTER","deleteTexture","originalSrc","dataset","_LOGGER","Blended","naturalWidth","naturalHeight","_src","src","Image","_readyFuture","_resource","endsWith","fromHtmlImageElement","imageSource","setAttribute","url","blob","URL","createObjectURL","loadedFuture","onload","toSprite","unload","_text","alphabet","shadow","caseInsensitive","spacing","lineHeight","spriteSheet","_getCharacterSprites","text","results","textToRender","toLocaleLowerCase","letterIndex","letter","spriteIndex","letterSprite","sprites","measureText","maxWidth","lines","_getLinesFromText","maxWidthLine","reduce","sprite","xCursor","yCursor","render","bounds","offset","_cachedText","_cachedRenderWidth","_cachedLines","newLine","rows","columns","getSprite","_h","_j","spriteWithOptions","fromImageSourceWithSourceViews","sourceViews","fromImageSource","grid","cols","spriteWidth","spriteHeight","originOffset","margin","offsetDefaults","marginDefaults","fontSheet","_imageSource","_spriteSheet","_spriteFont","write","RenderSource","_texture","use","activeTexture","TEXTURE0","RenderTarget","antialias","samples","transparency","MAX_SAMPLES","drawingBufferFormat","bufferFormat","RGBA8","RGB8","_setupRenderBuffer","_setupFramebuffer","setResolution","_frameTexture","_renderBuffer","bindRenderbuffer","RENDERBUFFER","renderbufferStorageMultisample","renderBuffer","renderFrameBuffer","_renderFrameBuffer","frameBuffer","_frameBuffer","frameTexture","createRenderbuffer","createFramebuffer","bindFramebuffer","FRAMEBUFFER","framebufferRenderbuffer","COLOR_ATTACHMENT0","attachmentPoint","framebufferTexture2D","toRenderSource","blitRenderBufferToFrameBuffer","blitToScreen","READ_FRAMEBUFFER","DRAW_FRAMEBUFFER","clearBufferfv","COLOR","blitFramebuffer","COLOR_BUFFER_BIT","copyToTexture","texture","copyTexImage2D","viewport","FLOAT","SHORT","UNSIGNED_SHORT","BYTE","LOW_FLOAT","HIGH_FLOAT","FLOAT_VEC2","FLOAT_VEC3","FLOAT_VEC4","compiled","_compiled","uniforms","attributes","vertexSource","fragmentSource","deleteProgram","program","useProgram","_ACTIVE_SHADER_INSTANCE","isCurrentlyBound","compile","vertexShader","_compileShader","VERTEX_SHADER","fragmentShader","FRAGMENT_SHADER","attribute","_createProgram","getAttributes","uniform","getUniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","getActiveUniform","uniformLocation","getUniformLocation","glType","location","attributeCount","ACTIVE_ATTRIBUTES","getActiveAttrib","attributeLocation","getAttribLocation","normalized","setTexture","slotNumber","setUniformInt","setUniform","trySetUniformInt","trySetUniform","setUniformIntArray","trySetUniformIntArray","setUniformBoolean","trySetUniformBoolean","setUniformFloat","trySetUniformFloat","setUniformFloatArray","trySetUniformFloatArray","setUniformFloatVector","trySetUniformFloatVector","setUniformFloatColor","trySetUniformFloatColor","setUniformMatrix","trySetUniformMatrix","uniformType","createProgram","attachShader","linkProgram","LINK_STATUS","getProgramInfoLog","typeName","shader","createShader","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","errorInfo","getShaderInfoLog","_processSourceForError","errorLineStart","search","errorLineEnd","_","error2","buffer","createBuffer","bufferData","bindBuffer","ARRAY_BUFFER","STATIC_DRAW","DYNAMIC_DRAW","upload","count","bufferSubData","deleteBuffer","vertexBuffer","_vertexBuffer","_attributes","_layout","_vertexTotalSizeBytes","_shader","initialize","totalVertexSizeBytes","shaderAttributes","attrib","componentsPerVertex","vertAttribute","typeSize","uploadBuffer","vert","vertexAttribPointer","enableVertexAttribArray","GraphicsDiagnostics","DrawCallCount","DrawnImagesCount","LineRenderer","priority","_maxLines","_vertexIndex","_lineCount","context","_context","start","end","_isFull","flush","getTransform","finalStart","finalEnd","hasPendingDraws","drawArrays","LINES","PointRenderer","_maxPoints","_pointCount","_buffer","snapToPixel","finalPoint","POINTS","ScreenPassPainter","renderWithPostProcessor","postprocessor","getShader","getLayout","TRIANGLES","renderToScreen","numberOfQuads","useUint16","ELEMENT_ARRAY_BUFFER","totalVertices","maxUint16Index","bufferGlType","Uint16Array","Uint32Array","currentQuad","ImageRenderer","_maxImages","_maxTextures","_imageCount","_textures","pixelArtSampler","uvPadding","MAX_TEXTURE_IMAGE_UNITS","transformedFrag","_transformFragmentSource","_quads","maxTextures","newSource","texturePickerBuilder","_addImageAsTexture","maybeFiltering","getAttribute","force","textureLoader","removeAttribute","_bindTextures","_getTextureIdForImage","maybeTexture","swidth","sheight","dx","dy","dwidth","dheight","view","sw","sh","textureId","imageWidth","imageHeight","uvx0","uvy0","uvx1","uvy1","txWidth","txHeight","drawElements","RectangleRenderer","_maxRectangles","_rectangleCount","drawLine","drawRectangle","thickness","halfThick","startTop","startBottom","endTop","endBottom","stroke","strokeThickness","CircleRenderer","_maxCircles","_circleCount","radius","builder","recycler","maxObjects","totalAllocations","objects","disableWarnings","preallocate","using","done","borrow","poolIndex","DrawCall","defaultVertexSource","_initialized","_images","graphicsContext","images","_name","_vertexSource","_fragmentSource","_graphicsContext","_initialize","addImageSource","graphicsContextWebGL","__gl","_maxTextureSlots","isUsingScreenTexture","update","textureUniformName","removeImageSource","textureName","_loadImageSource","imageElement","uploadAndBind","startingTextureSlot","textureSlot","entries","MaterialRenderer","vertexIndex","topLeftScreen","bottomRightScreen","screenUVX0","screenUVY0","screenUVX1","screenUVY1","performance","materialScreenTexture","ExcaliburGraphicsContextWebGLDebug","_webglCtx","_debugText","rectOptions","lineOptions","drawPoint","pointOptions","drawText","_state","_ortho","checkIfResolutionSupported","dim","supported","_renderers","_isDrawLifecycle","useDrawSorting","_drawCallPool","instance","renderer","_drawCalls","_postProcessTargets","_postprocessors","_transform","smoothing","backgroundColor","multiSampleAntialiasing","_disposed","_totalPostProcessorTime","canvasElement","enableTransparency","antialiasing","powerPreference","premultipliedAlpha","alpha","depth","_init","values","clearColor","BLEND","blendEquation","FUNC_ADD","blendFunc","ONE","ONE_MINUS_SRC_ALPHA","blendEquationSeparate","blendFuncSeparate","REPEAT","_screenRenderer","_renderTarget","_msaaTarget","rendererName","_isCurrentRenderer","_currentRenderer","beginDrawLifecycle","endDrawLifecycle","drawCall","resetTransform","updateViewport","trace","drawCircle","addPostProcessor","removePostProcessor","clearPostProcessors","updatePostProcessors","delta","find","u","onUpdate","createMaterial","currentTarget","originalSort","firstIndex","findIndex","dc","originalSortOrder","oldTransform","oldState","currentRendererName","currentRenderer","ExcaliburGraphicsContext2DCanvasDebug","_ex","__ctx","strokeStyle","strokeRect","beginPath","moveTo","lineTo","lineWidth","closePath","arc","fill","imageSmoothingEnabled","_resolution","globalAlpha","fillRect","setTransform","_postprocessor","SVGA","Standard","Atari2600","GameBoy","GameBoyAdvance","NintendoDS","NES","SNES","ScreenResize","PixelRatioChange","FullScreenChange","_antialiasing","_canvasImageRendering","_resolutionStack","_viewportStack","_pixelRatioOverride","_isFullScreen","_isDisposed","_fullscreenChangeHandler","fullscreen","isFullScreen","_pixelRatioChangeHandler","_listenForPixelRatio","_devicePixelRatio","_calculateDevicePixelRatio","applyResolutionAndViewport","pixelRatio","_resizeHandler","parent","_setResolutionAndViewportByDisplayMode","_contentArea","_contentResolution","_displayMode","displayMode","Fixed","_canvas","canvasImageRendering","_browser","browser","_applyDisplayMode","_mediaQueryList","removeListener","nativeComponent","matchMedia","addListener","_resizeObserver","disconnect","removeEventListener","pixelRatioOverride","isHiDpi","FillContainer","FitContainer","FitContainerAndFill","FitContainerAndZoom","parentElement","_viewport","aspectRatio","scaledWidth","scaledHeight","setCurrentCamera","camera","_camera","pushResolutionAndViewport","peekViewport","peekResolution","popResolutionAndViewport","imageRendering","isSmooth","goFullScreen","elementId","maybeElement","getElementById","requestFullscreen","exitFullScreen","exitFullscreen","pageToScreenCoordinates","newX","newY","innerWidth","innerHeight","screenHeight","screenWidth","contentArea","screenMarginY","screenMarginX","screenToWorldCoordinates","worldToScreenCoordinates","pageToWorldCoordinates","worldToPageCoordinates","getWorldBounds","zoom","getScreenBounds","canvasWidth","halfCanvasWidth","canvasHeight","halfCanvasHeight","drawWidth","halfDrawWidth","drawHeight","halfDrawHeight","_computeFit","overflow","aspect","adjustedWidth","adjustedHeight","_computeFitScreenAndFill","vw","vh","_computeFitAndFill","_computeFitContainerAndFill","clientWidth","clientHeight","clip","_computeFitScreenAndZoom","_computeFitAndZoom","_computeFitContainerAndZoom","maxScaleFactor","zoomedWidth","zoomedHeight","_computeFitContainer","Window","ResizeObserver","observe","FillScreen","FitScreen","FitScreenAndFill","FitScreenAndZoom","create","unlock","_UNLOCKED","unlockTimeoutTimer","resume","createBufferSource","ended","connect","destination","onended","playbackState","PLAYING_STATE","FINISHED_STATE","currentTime","clearTimeout","isUnlocked","lineCap","quality","_smoothing","flagDirty","_lineWidth","_lineDash","_padding","strokeColor","lineDash","padding","_bitmap","bitmapWidth","bitmapHeight","maybeCtx","cloneRasterOptions","dirty","_getTotalWidth","_originalWidth","_getTotalHeight","_originalHeight","_strokeColor","rasterize","_applyRasterProperties","execute","setLineDash","getLineDash","cache","any","json","arraybuffer","states","currentState","machineDescription","machine","stateName","transitionState","transitions","startState","in","go","eventData","potentialNewState","onExit","canExit","onEnter","canEnter","onState","elapsedMs","saveKey","localStorage","setItem","parse","getItem","_createNewBufferSource","_instance","_audioContext","loop","playbackRate","_playbackRate","_volumeNode","_handleEnd","_playingFuture","_loop","volume","_volume","_stateMachine","gain","setTargetAtTime","duration","_duration","getTotalPlaybackDuration","createGain","PLAYING","pausedAt","startedAt","_playStarted","stop","SEEK","STOPPED","PAUSED","isPlaying","isPaused","isStopped","play","playStarted","seek","getPlaybackPosition","_bubbles","bubbles","stopPropagation","prevStats","stats","gamepad","button","axis","actor","contact","lastContact","action","_value","_path","_val","propagate","layPath","_actor","track","_processedData","VolumeChange","Processed","Pause","Stop","PlaybackEnd","Resume","PlaybackStart","_tracks","instances","paths","_isStopped","_wasPlayingOnHidden","canPlayFile","file","Audio","canPlayType","audiobuffer","decodeAudio","wireEngine","_engine","pauseAudioWhenHidden","instanceCount","some","_resumePlayback","_startPlayback","trackId","_getTrackInstance","getTrackId","resumed","complete","newTrack","BeforeLoad","AfterLoad","UserAction","LoadResourceStart","LoadResourceEnd","resources","_resources","onDraw","_numLoaded","_totalTimeMs","_loadingFuture","loadables","addResources","onInitialize","onUserAction","onBeforeLoad","onAfterLoad","addResource","loadable","markResourceComplete","progress","total","elapsedMilliseconds","seconds","speed","font","textbox","actualBoundingBoxLeft","actualBoundingBoxRight","actualBoundingBoxAscent","actualBoundingBoxDescent","areResourcesLoaded","resource","finally","x1","y1","x2","y2","cap","br","tl","tr","bl","defaultRadius","quadraticCurveTo","Director_Loader","_image","_imageElement","logo","playButtonRootElement","_playButtonRootElement","playButtonElement","_playButtonElement","_playButton","existingRoot","_styleBlock","textContent","_playButtonStyles","head","startButtonFactory","loadablesOrOptions","isArray","_originalOptions","_playButtonShown","logoWidth","logoHeight","loadingBarColor","suppressPlayButton","playButtonText","buttonElement","display","_configuredPixelRatio","_DEFAULT_LOADER_OPTIONS","showPlayButton","hidePlayButton","resizeHandler","_positionPlayButton","evt","click","playButtonClicked","startButtonHandler","fullscreenAfterLoad","fullscreenContainer","HTMLElement","removeChild","decode","offsetLeft","offsetTop","buttonWidth","buttonHeight","playButtonPosition","logoY","logoX","logoPosition","oldAntialias","getAntialiasing","setAntialiasing","loadingX","loadingY","loadingBarPosition","progressWidth","REPORTED_FEATURES","webgl","webaudio","gamepadapi","_features","failedTests","_criticalTests","canvasSupport","elem","arrayBufferSupport","xhr","dataUrlSupport","toDataURL","objectUrlSupport","rgbaSupport","cssText","_warningTest","webAudioSupport","webglSupport","_loadBrowserFeatures","getBrowserFeatures","logBrowserFeatures","msg","dataurl","objecturl","rgba","getGamepads","failedCritical","warning","_getX","getX","_getY","getY","_setX","setX","_setY","setY","WatchVector","original","_parent","_children","_isDirty","_isInverseDirty","_matrix","_inverse","children","globalPos","localPos","canonRotation","globalRotation","inverseRotation","globalScale","inverseScale","globalScaleX","globalScaleY","_calculateMatrix","applyInverse","owner","newComponent","hasClone","observers","subscriptions","observer","subscribe","unregister","unsubscribe","notifyAll","observersLength","notify","subscriptionsLength","_parentComponent","_addChildTransform","child","childTxComponent","zIndexChanged$","_z","_coordPlane","onAdd","childrenAdded$","childrenRemoved$","onRemove","_previousOwner","oldz","coordPlane","component","vel","acc","scaleFactor","angularVelocity","torque","inertia","mask","_CURRENT_GROUP","_MAX_GROUPS","_GROUPS","existingGroup","group","_CURRENT_BIT","groups","groupByName","_STARTING_BIT","category","_category","_mask","canCollide","overlap1","overlap2","collisionGroups","combinedName","combinedCategory","collidesWith","combinedMask","padStart","All","colliderA","colliderB","calculatePairHash","bodyA","bodyB","collisionType","PreventCollision","active","collide","hasCollider","collider","idA","idB","projection","getOverlap","isLeaf","_config","worldBounds","root","nodes","_insert","leaf","leafAABB","currentRoot","oldArea","area","combinedArea","combinedAABB","cost","inheritanceCost","leftCost","leftCombined","newArea","rightCost","rightCombined","oldParent","newParent","currentNode","_balance","_remove","sibling","grandParent","trackCollider","node","updateCollider","untrackCollider","boundsPadding","multdx","velocityMultiplier","multdy","balance","getHeight","helper","rayCastQuery","getNodes","numerator","begin","getSlope","divisor","getLength","intersectPoint","time","getPoint","_pairs","_collisionPairCache","_colliders","_dynamicCollisionTree","dynamicTree","getColliders","maxDistance","collisionGroup","collisionMask","searchAllColliders","maybeBody","ignoreCollisionGroupAll","hit","untrack","_pairExists","hash","broadphase","targets","potentialColliders","pair","physics","pairs","continuous","checkForFastBodies","Active","updateDistance","minDimension","disableMinimumSpeedForFastBody","minCollider","fastBodies","updateVec","oldPos","centerPoint","furthestPoint","getFurthestPoint","surfaceEpsilon","minTranslate","shift","fastBodyCollisions","narrowphase","contacts","newContacts","collisions","updated","composite","touching","gravity","useArcadePhysics","collisionResolutionStrategy","Arcade","useRealisticPhysics","Realistic","enabled","broadphaseStrategy","DynamicAABBTree","defaultMass","integrator","Euler","dynamicTreeVelocityMultiplier","positionIterations","velocityIterations","slop","steeringFactor","warmStart","bodiesCanSleepByDefault","sleepEpsilon","wakeThreshold","sleepBias","solver","colliders","compositeStrategy","bodies","canSleepByDefault","arcade","contactSolveBias","realistic","_compositeStrategy","_collisionProcessor","_dynamicAABBTree","addCollider","clearColliders","removeCollider","worldPos","axes","furthestPoints","bestPoint","getInertia","mass","totalInertia","otherColliders","potentialCollider","getClosestLineBetween","maybeLine","minLength","minLine","hits","minHit","minDistance","project","projections","proj","newProjection","slope","intercept","_normal","_dir","_slope","getEdge","_length","midpoint","flip","below","above2","sideVector","distanceToPoint","signed","x0","y0","findVectorToPoint","aMinusP","findPoint","hasPoint","currPoint","threshold","dxc","dyc","dx1","dy1","p0","q0","w0","denom","sDenom","tDenom","sClosest","tClosest","PolygonPolygonClosestLine","polygonA","polygonB","otherWorldPos","otherDirection","thisDirection","rayTowardsOther","rayTowardsThis","thisPoint","otherPoint","thisFace","getClosestFace","otherFace","face","PolygonEdgeClosestLine","polygon","edge","edgeLine","asLine","PolygonCircleClosestLine","circlex","circley","CircleCircleClosestLine","circleA","circleB","thisWorldPos","CircleEdgeClosestLine","circleWorldPos","edgeStart","edgeVector","EdgeEdgeClosestLine","edgeA","edgeB","edgeLineA","edgeStartA","edgeVectorA","edgeLineB","_globalMatrix","_naturalRadius","orig","discriminant","toi","toi1","toi2","positiveToi","minToi","shape","CollideCircleCircle","CollideCirclePolygon","CollideCircleEdge","getFurthestLocalPoint","globalMat","scalars","dotProduct","mtv","tangent","localPoints","_canceled","colliderAId","colliderBId","matchAwake","sleeping","sleepMotion","setSleeping","isCanceled","cancel","SeparatingAxis","findPolygonPolygonSeparation","polyA","polyB","bestSeparation","bestSide","bestAxis","bestSideIndex","bestOtherPoint","sides","getSides","localSides","getLocalSides","vertB","vertSeparation","separation","localSide","sideId","localPoint","findCirclePolygonSeparation","polyDir","pc","closestPointOnPoly","minOverlap","minAxis","minIndex","proj1","proj2","overlap","circleAPos","circleBPos","combinedRadius","mvt","local","samedir","xf","findSide","findLocalSide","cc","edgeWorld","asLocalLine","da","dda","db","ddb","den","pointOnEdge","dd","CollideEdgeEdge","CollidePolygonEdge","ec","linePoly","CollidePolygonPolygon","separationA","separationB","incident","reference","refDir","clipRight","clipLeft","FindContactSeparation","shapeA","txA","shapeB","txB","worldPoint","circlePoint","dist","_getTransformedBegin","_getTransformedEnd","transformedBegin","transformedEnd","_boundsFromBeginEnd","edgeNormal","registerGraphicsContext","debugDrawCall","drawLines","drawPolygon","firstPoint","drawBounds","boundingBox","drawRay","_localBoundsDirty","_localSidesDirty","_transformedPointsDirty","_sidesDirty","_transformedPoints","_sides","_localSides","_isCounterClockwiseWinding","reverse","isConvex","suppressConvexWarning","_calculateTransformation","sum","oldPoint","newPoint","oldDirection","orientation","angleSum","tessellate","polygons","triangulate","triangles","vertices","vertexCount","getPrevIndex","getNextIndex","prev","va","vb","vc","leftArm","rightArm","convexVertices","cutEarTip","findEarTip","isEar","isPointInTriangle","ab","bc","ca","ap","bp","cp","cross1","cross2","cross3","getTransformedPoints","currentSide","mostDirection","sideNormal","testRay","intersectCount","accum","pts","POSITIVE_INFINITY","faceIndex","_localBounds","_cachedMass","_cachedInertia","denominator","iplusone","crossTerm","contactSide","minContactTime","contactIndex","contactTime","scalar","Box","Edge","Capsule","$colliderAdded","$colliderRemoved","_collidersToRemove","_collider","processColliderRemoval","flipped","entity","precollision","onPreCollisionResolve","postcollision","onPostCollisionResolve","onCollisionStart","onCollisionEnd","useBoxCollider","usePolygonCollider","poly","useCircleCollider","useEdgeCollider","useCompositeCollider","dependencies","__oldTransformCaptured","enableFixedUpdateInterpolate","_sleeping","bounciness","friction","useGravity","limitDegreeOfFreedom","oldVel","oldAcc","_bodyConfig","config","updatePhysicsConfig","_mass","_DEFAULT_CONFIG","canSleep","updateDefaultPhysicsConfig","newMass","_cachedInverseInertia","inverseMass","updateMotion","currentMotion","bias","maybeCollider","inverseInertia","motion","oldRotation","oldScale","applyImpulse","impulse","finalImpulse","X","Y","Rotation","distanceFromCenter","applyLinearImpulse","applyAngularImpulse","captureOldTransform","Initialize","PreUpdate","PostUpdate","Kill","componentsOrOptions","componentsToAdd","nameToAdd","_tags","componentAdded$","componentRemoved$","tagAdded$","tagRemoved$","components","_componentsToRemove","_instanceOfComponentCacheDirty","_instanceOfComponentCache","scene","_isInitialized","addComponent","kill","unparent","isKilled","tags","hasTag","addTag","removeTag","types","getComponents","hasAll","requiredTypes","hasAllTags","requiredTags","_getCachedInstanceOfType","maybeComponent","addChild","getAncestors","removeAllChildren","getDescendants","queue","curr","newEntity","componentInstance","addTemplate","templateEntity","removeComponent","ctor","typeOrInstance","componentToRemove","clearComponents","processComponentRemoval","isInitialized","_preupdate","onPreUpdate","_postupdate","onPostUpdate","graphic","tick","_offset","recalculateBounds","_anchor","_current","_graphics","visible","copyGraphics","graphics","onPreDraw","onPostDraw","onPreTransformDraw","onPostTransformDraw","graphicOrOptions","getGraphic","getOptions","getNames","currentOptions","nameOrGraphic","optionsToSet","graphicToSet","remove","hide","offsetX","offsetY","elapsed","idempotencyToken","_radius","useColliderShape","useGraphicsBounds","CreateReversibleEasingFunction","easing","CreateVectorEasingFunction","Linear","startValue","endValue","EaseInQuad","EaseOutQuad","EaseInOutQuad","EaseInCubic","EaseOutCubic","EaseInOutCubic","_actions","_currentAction","_completedActions","_entity","clearActions","getActions","hasNext","isComplete","repeatBuilder","repeat","_stopped","_repeatBuilder","_repeatContext","_actionQueue","getQueue","_repeat","_originalRepeat","_started","_tx","_motion","_speed","_delta","_start","_end","_distance","destx","desty","rotationType","_rotationType","ShortestPath","_currentNonCannonAngle","distance1","distance2","_shortDistance","_longDistance","_shortestPathIsPositive","_direction","LongestPath","Clockwise","CounterClockwise","distanceTraveled","angleRadiansOffset","scaleX","scaleY","speedX","speedY","_endX","_endY","_speedX","_speedY","_startX","_startY","_distanceX","_distanceY","directionX","directionY","scaleOffsetX","scaleOffsetY","_startScale","_endScale","_directionX","_directionY","CallMethod","_method","_hasBeenCalled","easingFcn","_currentLerpTime","_lerpDuration","_lerpStart","_lerpEnd","timeVisible","timeNotVisible","numBlinks","_timeVisible","_timeNotVisible","_elapsedTime","_totalTime","endOpacity","_multiplier","_endOpacity","_ogspeed","_delay","entityToFollow","followDistance","_followTx","_followMotion","_maximumDistance","_distanceBetween","actorToFollowSpeed","actorToMeet","_speedWasSpecified","_meetTx","_meetMotion","actorToMeetSpeed","_queue","runAction","easeTo","easeBy","xOrPos","yOrSpeed","speedOrUndefined","moveBy","xOffsetOrVector","yOffsetOrSpeed","xOffset","yOffset","rotateTo","rotateBy","scaleTo","sizeXOrVector","sizeYOrSpeed","speedXOrUndefined","speedYOrUndefined","sizeX","sizeY","scaleBy","sizeOffsetXOrVector","sizeOffsetYOrSpeed","sizeOffsetX","sizeOffsetY","blink","fade","die","callMethod","times","repeatForever","follow","meet","toPromise","_getCtx","FontTextInstance","_textFragments","disposed","_setDimension","_lastHashCode","getHashCode","_applyFont","metrics","textHeight","lineAdjustedHeight","bottomBounds","textBounds","lineHeightRatio","fontString","textAlign","baseAlign","includeColor","textBaseline","shadowColor","shadowBlur","blur","shadowOffsetX","shadowOffsetY","_drawText","strokeText","_splitTextBitmap","textImages","currentX","currentY","hashCode","frag","_MEASURE_CACHE","measurement","measureTextWithoutCache","getTextInstance","textInstance","_TEXT_CACHE","_TEXT_USAGE","checkAndClearCache","deferred","currentHashCodes","FONT_TIMEOUT","newTextMeasurementCache","cacheSize","clearCache","_o","_p","_q","_r","_v","family","Normal","bold","unit","Px","LeftToRight","_textBounds","_textMeasurement","colorOverride","_textWidth","_textHeight","_calculateDimension","_font","thePos","theVel","theAcc","theAngle","_handleAnchorChange","_handleOffsetChange","isOffScreen","draggable","_draggable","isDraggable","_pointerDragStartHandler","_pointerDragEndHandler","_pointerDragMoveHandler","_pointerDragLeaveHandler","currentGraphic","_dragging","pe","defaults","pointer","actions","Passive","builtInComponents","_prekill","onPreKill","_postkill","onPostKill","unkill","newZ","getGlobalPos","localCenter","getGlobalScale","getGlobalRotation","recurse","geom","containment","within","otherCollider","me","self1","useWorld","coords","_complete","fcn","interval","repeats","numberOfRepeats","randomRange","_totalTimeAlive","_running","_numberOfTicks","maxNumberOfRepeats","_baseInterval","_generateRandomInterval","_MAX_ID","_callbacks","newInterval","newNumberOfRepeats","timesRepeated","getTimeRunning","timeToNextAction","timeElapsedTowardNextAction","isRunning","cancelTimer","parallaxFactor","useTransform","PreDraw","PostDraw","flagCollidersDirty","_collidersDirty","flagTilesDirty","tiles","_token","_rows","_cols","renderFromTopOfGraphic","meshingLookBehind","_originalOffsets","debugFlags","_composite","_oldPos","_oldScale","tileWidth","tileHeight","currentCol","tile","_getOrSetColliderOriginalOffset","originalOffset","_updateColliders","shareEdges","checkAndCombine","maxLookBack","solid","defaultGeometry","getTileByIndex","getTile","getTileByPoint","_getTileCoordinates","getRows","getColumns","getOnScreenTiles","maybeParallax","oneMinusFactor","parallaxOffset","currentScene","tileStartX","tileStartY","tileEndX","tileEndY","_oldRotation","graphicsIndex","graphicsLen","offsets","getGraphicsOffsets","getGraphics","gfx","showAll","showGrid","gridColor","gridWidth","showSolidBounds","showColliderBounds","solidBoundsColor","colliderBoundsColor","showColliderGeometry","tilemap","geometryColor","geometryLineWidth","geometryPointSize","pointSize","_posDirty","_recalculate","_solid","_offsets","addGraphic","removeGraphic","clearGraphics","geometryPos","_geometry","_bounds","lockToActor","addStrategy","lockToActorAxis","elasticToActor","cameraElasticity","cameraFriction","radiusAroundActor","limitCameraBounds","box","cam","_eng","currentFocus","getFocus","focus","cameraVel","stretch","boundSizeChecked","focusX","focusY","_cameraStrategies","strategy","dz","az","_angularVelocity","_posChanged","drawPos","_cameraMoving","_isShaking","_shakeMagnitudeX","_shakeMagnitudeY","_shakeDuration","_elapsedShakeTime","_xShake","_yShake","_isZooming","_zoomStart","_zoomEnd","_currentZoomTime","_zoomDuration","_zoomEasing","_easing","_halfWidth","_halfHeight","_snapPos","_follow","ax","ay","move","easingFn","_lerpPromise","_lerpResolve","shake","magnitudeX","magnitudeY","zoomOverTime","_zoomPromise","_zoomResolve","cameraStrategy","removeStrategy","clearAllStrategies","_screen","currentRes","loadingComplete","res","updateTransform","runStrategies","newZoom","zoomEasing","lerpPoint","moveEasing","_isDoneShaking","fixedUpdateFps","blend","currentFrameLagMs","interpolatedPos","snapPos","newCanvasWidth","newCanvasHeight","cameraPos","ExitTrigger","EnterTrigger","triggerDefaults","opts","_dispatchAction","_target","Highest","Higher","Average","Lower","Lowest","_world","entities","_entityIndex","_entitiesToRemove","updateEntities","removeEntity","findEntitiesForRemoval","addEntity","queryManager","idOrEntity","currFrame","actors","killed","processEntityRemovals","processComponentRemovals","getById","getByName","requiredComponents","entityAdded$","entityRemoved$","checkAndAdd","getEntities","_queries","_addComponentHandlers","_removeComponentHandlers","_componentToQueriesIndex","_tagQueries","_addTagHandlers","_removeTagHandlers","_tagToQueriesIndex","_createAddComponentHandler","_createRemoveComponentHandler","_createAddTagHandler","_createRemoveTagHandler","createQuery","queries","createTagQuery","maybeAddComponent","maybeRemoveComponent","maybeAddTag","maybeRemoveTag","tagQuery","systems","initialized","systemType","addSystem","systemOrCtor","system","removeSystem","updateSystems","preupdate","postupdate","entityManager","systemManager","queryTags","Update","entityOrSystem","clearEntities","clearSystems","EulerIntegrator","integrate","totalAcc","_ACC","_VEL","_POS","_VEL_ACC","_SCALE_FACTOR","_SCALE","world","_physicsConfigDirty","$configUpdate","optionalBody","directionMap","distanceMap","solve","preSolve","aDir","bDir","aDist","bDist","solvePosition","solveVelocity","postSolve","opposite","velAdj","normalImpulse","tangentImpulse","normalMass","tangentMass","aToContact","bToContact","originalVelocityAndRestitution","aToContactNormal","bToContactNormal","aToContactTangent","bToContactTangent","getRelativeVelocity","velA","velB","lastFrameContacts","idToContactConstraint","getContactConstraints","finishedContactIds","contactPoints","pointIndex","restitution","relativeVelocity","steeringForce","steeringConstant","impulseForce","constraints","impulseDelta","tangentVelocity","maxFriction","newImpulse","normalVelocity","_processor","_physics","collisionProcessor","_configDirty","_lastFrameContacts","_currentFrameContacts","_arcadeSolver","_realisticSolver","_trackCollider","_untrackCollider","colliderComponent","colliderComp","compositeColliders","getSolver","compositeId","substring","runContactStartEnd","Frame","Loop","End","frames","frameDuration","_idempotencyToken","_firstTick","_currentFrame","_timeLeftInFrame","_pingPongDirection","_done","_playing","_reversed","totalDuration","goToFrame","maybeFrame","currentFrame","fromSpriteSheet","frameIndices","durationPerFrameMs","invalidIndices","fromSpriteSheetCoordinates","frameCoordinates","defaultDuration","coord","currentFrameIndex","currentFrameTimeLeft","reversed","Backward","Forward","canFinish","Freeze","frameNumber","frameIndex","_nextFrame","PingPong","members","_updateDimensions","member","useBounds","shouldUseBounds","_isAnimationOrGroup","base","assign","props","ParticleImpl","emitterOrConfig","life","beginColor","endColor","velocity","acceleration","startSize","endSize","particleSprite","particleRotationalVelocity","currentRotation","focusAccel","fadeFlag","_rRate","_gRate","_bRate","_aRate","_currentColor","particleSize","sizeRate","elapsedMultiplier","isOffscreen","particleTransform","Global","tmpColor","removeParticle","accel","_sprite","_particlesToEmit","numParticles","isEmitting","particles","deadParticles","minVel","maxVel","minAngle","maxAngle","emitRate","particleLife","minSize","maxSize","emitterType","randomRotation","particle","emitParticles","particleCount","_createParticle","clearParticles","ranX","ranY","sortedTransforms","_sortedTransforms","Draw","_zHasChanged","_zIndexUpdate","_targetInterpolationTransform","parallax","_applyTransform","particleOpacity","_drawGraphicsComponent","graphicsComponent","transformComponent","oldFlipHorizontal","oldFlipVertical","isDebug","showBounds","boundsColor","ancestor","blendTransform","oldTx","newTx","oldTxWithNewParent","oldGlobalPos","oldGlobalScale","oldGlobalRotation","interpolatedScale","interpolatedRotation","_collisionSystem","debugDraw","filterSettings","entitySettings","txSettings","motionSettings","colliderSettings","physicsSettings","graphicsSettings","bodySettings","cameraSettings","useFilter","allIds","ids","allNames","nameQuery","cursor","_pushCameraTransform","debugZIndex","showPosition","positionColor","showPositionLabel","showZIndex","showId","showName","showRotation","rotationColor","showScale","scaleColor","showCollisionGroup","showCollisionType","showMass","showMotion","showSleeping","showVelocity","velocityColor","showAcceleration","accelerationColor","showGeometry","showOwner","_popCameraTransform","showBroadphaseSpacePartitionDebug","showCollisionContacts","showCollisionNormals","contactSize","collisionContactColor","collisionNormalColor","showFocus","focusColor","showZoom","overrideUseColliderShape","overrideUseGraphicsBounds","lastFrameEntityToPointers","currentFrameEntityToPointers","_sortedEntities","_scene","_receivers","pointers","_engineReceiver","entityCurrentlyUnderPointer","pointerId","entityWasUnderPointer","entered","addPointerToEntity","_processPointerToEntity","_dispatchEvents","receiver","currentFramePointerCoords","screenPos","graphicBounds","_processDownAndEmit","lastDownPerPointer","currentFrameDown","isDragStart","_processUpAndEmit","lastUpPerPointer","currentFrameUp","isDragEnd","_processMoveAndEmit","lastMovePerPointer","currentFrameMove","isDragging","_processEnterLeaveAndEmit","lastUpDownMoveEvents","_processCancelAndEmit","currentFrameCancel","_processWheelAndEmit","currentFrameWheel","lastFrameEntities","currentFrameEntities","mapOrOptions","elevation","iso","maxZindexPerElevation","_worldBounds","entityOffscreen","_isOffscreen","transformedBounds","newConfig","_gamePadTimeStamps","_oldPads","_pads","_initSuccess","_navigator","_minimumConfiguration","_enabled","_clonePads","toggleEnabled","setMinimumGamepadConfiguration","_enableAndUpdate","_isGamepadValid","pad","axesLength","buttonLength","buttons","connected","gamepads","bi","ai","at","timestamp","navigatorGamepad","getButton","pressed","updateButton","getAxes","updateAxes","_clonePad","getValidGamepads","pads","arr","clonedPad","MinAxisMoveThreshold","_axes","_buttons","_buttonsUp","_buttonsDown","isButtonPressed","isButtonHeld","wasButtonPressed","wasButtonReleased","Boolean","buttonIndex","axesIndex","inputs","_handlers","command","inputHandler","commandHandler","isCrossOriginIframe","noop","originalEvent","_keys","_keysUp","_keysDown","_releaseAllKeys","ev","keyEvent","_handleKeyDown","metaKey","MetaLeft","MetaRight","_handleKeyUp","keyboardOptions","grabWindowFocus","getKeys","wasPressed","isHeld","wasReleased","triggerEvent","character","KeyboardEvent","fromPagePosition","yOrEngine","engineOrUndefined","coordinates","pointerType","nativeEvent","pageX","pageY","screenX","screenY","deltaZ","deltaMode","lastPagePos","lastScreenPos","lastWorldPos","_onPointerMove","_onPointerDown","primary","_activeNativePointerIdsToNormalized","lastFramePointerCoords","currentFramePointerDown","lastFramePointerDown","_pointers","_boundHandle","_handle","_boundWheel","_handleWheel","recreate","eventReceiver","isDown","wasDown","native","touchAction","wheelOptions","passive","pageScrollPreventionMode","onmousewheel","grabFocus","detach","_normalizePointerId","nativePointerId","currentPointerIds","preventDefault","eventCoords","TouchEvent","Unknown","Touch","changedTouches","touch","_nativeButtonToPointerButton","Mouse","_stringToPointerType","ScrollWheelNormalizationFactor","wheelDeltaX","wheelDeltaY","wheelDelta","detail","Page","we","page","clientX","clientY","MouseEvent","pointerSystem","NoButton","Middle","Pen","pointerTarget","keyboard","inputMapper","Activate","Deactivate","PreDebugDraw","PostDebugDraw","PreLoad","triggers","tileMaps","timers","_timers","_cancelQueue","onPreLoad","loader","onTransition","onActivate","onDeactivate","_initializeChildren","pointerScope","director","getSceneName","_activate","_deactivate","_predraw","_postdraw","removeTimer","timer","_collectActorStats","addTimer","transfer","isTimerActive","isCurrentScene","_ui","ui","alive","_colorBlindnessMode","simulate","_simulate","colorBlindnessMode","colorBlindMode","Protanope","Deuteranope","Tritanope","_colorBlindPostProcessor","correct","colorBlindness","prevFrame","isometric","positionSize","useTestClock","wasRunning","testClock","toTestClock","useStandardClock","currentClock","standardClock","toStandardClock","_id","_fps","_actorStats","remaining","_durationStats","_physicsStats","_graphicsStats","drawCalls","drawnImages","otherStats","fps","fs","_collisions","_contacts","_fastBodies","_fastBodyCollisions","_broadphase","_narrowphase","ps","_nativeHandlers","_decorate","_windowGlobal","_documentGlobal","_windowComponent","_documentComponent","nativeContextAntialiasing","_samplePeriod","_currentFrameTime","_frames","_previousSampleTime","_beginFrameTime","initialFps","samplePeriod","_nowFn","nowFn","instant","_onFatalException","_maxFps","_lastTime","_elapsed","_scheduledCbs","_totalElapsed","maxFps","onFatalException","fpsSampler","defaultUpdateMs","setFatalExceptionHandler","cb","timeoutMs","scheduledTime","_runScheduledCbs","overrideUpdateMs","fpsInterval","leftover","mainloop","_requestId","_currentTime","_updateMs","step","run","numberOfSteps","Util_Toaster","_toasterCss","_container","_createFragment","toastMessage","innerText","toast","linkTarget","linkName","className","messageFragments","link","href","finalMessage","dismissBtn","keydownHandler","first","firstChild","insertBefore","NavigationStart","Navigation","NavigationEnd","isTransitioning","_isTransitioning","scenes","sceneKey","_sceneToInstance","_sceneToLoader","_sceneToTransition","_loadedScenes","rootScene","currentSceneName","sceneOrOptions","getSceneInstance","_deferredGoto","deferredScene","swapScene","configureStart","startScene","maybeStartTransition","maybeLoaderOrCtor","mainLoader","inTransition","playTransition","_getLoader","sceneName","_getInTransition","sceneOrRoute","_getOutTransition","out","getDeferredScene","maybeDeferred","getSceneDefinition","maybeScene","sceneInstance","assertAdded","assertRemoved","outTransition","nameOrScene","potentialSceneOrOptions","goto","destinationScene","maybeDest","sourceScene","engineInputEnabled","maybeSourceOut","maybeDestinationIn","sourceOut","destinationIn","sceneActivationData","hideLoader","maybeLoadScene","_emitEvent","onPreviousSceneDeactivate","sceneDefinition","newScene","sceneToLoad","sceneToLoadInstance","transition","currentTransition","sceneInputEnabled","blockInput","previousScene","nextScene","destLoader","sourceName","destinationName","FallbackGraphicsContext","Visible","Hidden","Start","PreFrame","PostFrame","isFullscreen","_isDebug","shouldSnapToPixel","_inputEnabled","_suppressPlayButton","enableCanvasTransparency","stack","_toaster","_timescale","_performanceThresholdTriggered","_fpsSamples","_isLoading","_hideLoader","_isReadyFuture","currentFrameElapsedMs","_lagMs","_screenShotRequests","_DEFAULT_ENGINE_OPTIONS","detector","suppressMinimumBrowserFeatureDetection","_compatible","testMessage","canvasElementId","suppressConsoleBootMessage","_originalDisplayMode","pixelArt","suppressHiDPIScaling","_mainloop","___EXCALIBUR_DEVTOOL","_monitorPerformanceThresholdAndTriggerFallback","allow","configurePerformanceCanvas2DFallback","showPlayerMessage","numberOfFrames","useCanvas2DFallback","newCanvas","cloneNode","parentNode","replaceChild","Document","timescale","addScene","removeScene","goToScene","scrollPreventionMode","visibilityState","toggleInputEnabled","_overrideInitialize","_update","_loader","_draw","_checkForScreenShots","toggle","toggleDebug","isReady","sceneNameOrLoader","frameId","beforeUpdate","fixedTimestepMs","afterUpdate","afterDraw","screenshot","preserveHiDPIResolution","finalWidth","finalHeight","raw","_wiredEventDispatchers","_deferedHandlerRemovals","_processDeferredHandlerRemovals","eventHandler","_removeHandler","eventHandlers","metaHandler","wire","eventDispatcher","unwire","newFont","spriteFont","sf","getTextWidth","_gfx","_recalculateBounds","_tileBounds","graphicsOffset","tileToWorld","_isometricEntityComponent","halfTileWidth","halfTileHeight","yPos","totalWidth","totalHeight","updateColliders","worldToTile","worldCoordinate","tileCoordinate","tileCoord","_getMaxZIndex","maxZ","NEGATIVE_INFINITY","currentZ","actionBuilder","_sequenceBuilder","_sequenceContext","parallelActions","every","_defaultOptions","maxDepth","capacity","_isDivided","halfWidth","halfHeight","_split","newLevelOptions","_insertIntoSubNodes","insert","getAllItems","getTreeDepth","_stream","_gif","_animation","_transparentColor","toSpriteSheet","toAnimation","readCheckBytes","checkBytes","bitsToNum","ba","byteToBitArr","bite","dataArray","readByte","byteLength","readBytes","bytes","read","readUnsigned","Uint8Array","lzwDecode","minCodeSize","last","output","clearCode","eoiCode","codeSize","dict","readCode","charCodeAt","stream","_st","_handler","globalColorTable","parseColorTable","ct","rgb","readSubBlocks","parseHeader","hdr","sig","ver","colorRes","globalColorTableSize","gctFlag","sorted","bgColor","pixelAspectRatio","bits","parseExt","block","label","extType","parseGCExt","reserved","disposalMethod","userInput","transparencyGiven","delayTime","transparencyIndex","terminator","gce","parseComExt","comment","com","parsePTExt","ptHeader","ptData","pte","parseAppExt","identifier","authCode","parseNetscapeExt","unknown","iterations","app","NETSCAPE","parseUnknownAppExt","appData","parseUnknownExt","parseImg","img","leftPos","topPos","lctFlag","interlaced","lctSize","lct","lzwMinCodeSize","lzwData","pixels","deinterlace","newPixels","cpRow","toRow","fromRow","fromPixels","steps","pass","arrayToImage","parseBlock","sentinel","eof","frame","_isLoaded","FontFace","fonts","toFont","coroutineGenerator","generator","_currentProgress","_completeFuture","started","_currentDistance","updateTransition","onStart","onEnd","onReset","screenCover","_progress","_calculateBounds","lineNormal","halfThickness","minPoint","obsoleteMessage","logMessage","suppressObsoleteMessages","showStackTrace","alternateMethod","property","SyntaxError","methodSignature","AsyncWaitQueue","enqueue","dequeue","_count","_waitQueue","waiting","enter","exit","$3MXpL","$f82d5511d53990a3$exports","compare","compareVersions","satisfies","validate","validateStrict","trim","EntityLayer","ldtkLayer","order","ldtkToEntity","entityToLdtk","ldtkLevel","worldX","worldY","__pxTotalOffsetX","__pxTotalOffsetY","entityInstances","projectMetadata","defs","__identifier","factories","px","pivotX","pivotY","__tile","tilesets","tilesetUid","w","spritesheet","runFactory","getEntitiesByIdentifier","getLdtkEntitiesByIdentifier","getEntitiesByField","getLdtkEntitiesByField","fieldInstances","__value","FetchLoader","fetch","__createBinding","__exportStar","IntGridLayer","intGridCsv","__cHei","__cWid","__gridSize","layers","intGridValues","LdtkResource","levels","levelsByName","fileLoader","_imageLoader","LoaderCache","_levelLoader","LevelResource","startZIndex","textQuality","useExcaliburWiring","useMapBackgroundColor","useTilemapCameraStrategy","headless","strict","entityIdentifierFactories","pathMap","registerEntityIdentifierFactory","LdtkProjectMetadata","supportedLdtkVersion","jsonVersion","relPath","pathRelativeToBase","getOrAdd","Tileset","ldtkTileset","externalRelPath","imageLoader","Level","getEntityLayers","getLevel","getTileLayers","TileLayer","getIntGridLayers","addToScene","useLevelOffsets","levelFilter","LdtkLevel","__bgColor","layerInstances","gridTiles","_loaded","allSettled","reason","pathInMap","mapPath","filenameFromPath","__tilesetDefUid","tileGridSize","__tilesetRelPath","pxHei","pxWid","LdtkEntityDefinition","LdtkLayerDefinition","LdtkLayerInstance","LdtkEntityInstance","tuple","nullable","__type","defUid","__grid","__pivot","__smartColor","__tags","__worldX","__worldY","iid","__opacity","union","literal","autoLayerTiles","layerDefUid","levelId","overrideTilesetUid","pxOffsetX","pxOffsetY","boolean","__bgPos","cropRect","topLeftPx","__neighbours","levelIid","bgRelPath","worldDepth","worldGridHeight","worldGridWidth","worldLayout","tileRect","iconTilesetUid","customData","tileId","embedAtlas","enumsTags","optional","enumValueId","tileIds","tagsSourceEnumUid","autoSourceLayerDefUid","displayOpacity","gridSize","groupUid","intGridValuesGroups","parallaxFactorX","parallaxFactorY","parallaxScaling","tilesetDefUid","nineSliceBorders","tileRenderMode","tilesetId","uiTileRect","enums","externalLevels","toc","instancesData","fields","heiPx","iids","widPix","worlds","ZodError","quotelessJson","ZodIssueCode","util","arrayToEnum","issues","addIssue","addIssues","setPrototypeOf","__proto__","errors","_errors","unionErrors","returnTypeError","argumentsError","jsonStringifyReplacer","isEmpty","flatten","formErrors","fieldErrors","__importDefault","getErrorMap","setErrorMap","defaultErrorMap","errorUtil","errToObj","isAsync","isDirty","isAborted","OK","DIRTY","INVALID","ParseStatus","addIssueToContext","EMPTY_PATH","makeIssue","errorMaps","issueData","defaultError","common","contextualErrorMap","schemaErrorMap","abort","mergeArray","mergeObjectAsync","mergeObjectSync","alwaysSet","getParsedType","ZodParsedType","objectUtil","assertEqual","assertIs","assertNever","getValidEnumValues","objectKeys","objectValues","isInteger","isFinite","joinValues","mergeShapes","nan","function","bigint","null","catch","date","__setModuleDefault","__importStar","invalid_type","received","expected","invalid_literal","unrecognized_keys","invalid_union","invalid_union_discriminator","invalid_enum_value","invalid_arguments","invalid_return_type","invalid_date","invalid_string","validation","startsWith","too_small","exact","inclusive","minimum","too_big","maximum","custom","invalid_intersection_types","not_multiple_of","multipleOf","not_finite","oe","coerce","ZodFirstPartyTypeKind","late","ZodSchema","Schema","ZodReadonly","ZodPipeline","ZodBranded","BRAND","ZodNaN","ZodCatch","ZodDefault","ZodNullable","ZodOptional","ZodTransformer","ZodEffects","ZodPromise","ZodNativeEnum","ZodEnum","ZodLiteral","ZodLazy","ZodFunction","ZodSet","ZodMap","ZodRecord","ZodTuple","ZodIntersection","ZodDiscriminatedUnion","ZodUnion","ZodObject","ZodArray","ZodVoid","ZodNever","ZodUnknown","ZodAny","ZodNull","ZodUndefined","ZodSymbol","ZodDate","ZodBoolean","ZodBigInt","ZodNumber","ZodString","ZodType","NEVER","void","transformer","strictObject","record","preprocess","pipeline","ostring","onumber","oboolean","never","nativeEnum","lazy","instanceof","enum","effect","discriminatedUnion","_cachedPath","_key","success","_error","errorMap","invalid_type_error","required_error","description","spa","safeParseAsync","_def","safeParse","parseAsync","refine","refinement","superRefine","nullish","or","and","brand","describe","readonly","isNullable","isOptional","_getType","_getOrReturnCtx","parsedType","_processInputParams","_parseSync","_parse","_parseAsync","async","_refinement","J","schema","Q","ee","E","M","R","te","innerType","defaultValue","ie","se","catchValue","ae","ne","checks","kind","RegExp","regex","lastIndex","toUpperCase","precision","_regex","_addCheck","email","emoji","uuid","cuid","cuid2","ulid","ip","datetime","nonempty","isDatetime","isEmail","isURL","isEmoji","isUUID","isCUID","isCUID2","isULID","isIP","maxLength","I","gte","lte","setLimit","gt","lt","int","positive","negative","nonpositive","nonnegative","finite","safe","MIN_SAFE_INTEGER","MAX_SAFE_INTEGER","minValue","maxValue","isInt","BigInt","T","getTime","minDate","maxDate","C","L","_any","_unknown","exactLength","N","_cached","nonstrict","passthrough","augment","extend","_getCached","catchall","unknownKeys","strip","merge","setKey","pick","deepPartial","S","unwrap","partial","required","keyof","strictCreate","lazycreate","A","G","W","H","D","discriminator","optionsMap","U","valid","rest","keySchema","keyType","valueSchema","valueType","B","F","K","implement","returns","Reflect","parameters","returnType","strictImplement","Values","Enum","extract","exclude","sourceType","createWithPreprocess","removeDefault","removeCatch","re","de","le","ue","ce","he","fe","ye","ve","ge","be","xe","Ie","Ze","Te","ke","Ce","ze","Le","Pe","Oe","je","Ee","Se","Ne","Me","Ae","De","Ue","Re","Ve","$53be842a0003f2fd$exports","$ee38e295ce16494f$exports","$6e5a0b5cd91b5e01$exports","$bbaeefda90929bac$exports","$2b4fa2e46d897f1a$exports","$7c4c300842bd4cf2$export$e9a269813a6315a4","HeroSpriteSheetPng","$7c4c300842bd4cf2$export$f4c5de44377d2946","$9d936a2aecb96285$export$29cd7b75162a9425","PlayerSpeed","PlayerFrameSpeed","$51d548b0596e1d08$export$2616165974278734","playerSpriteSheet","leftIdle","rightIdle","upIdle","downIdle","leftWalk","rightWalk","upWalk","downWalk","Input","ArrowRight","ArrowLeft","ArrowUp","ArrowDown","$ad2bcec7a0192558$var$game","player","factory","require","define","amd","__WEBPACK_EXTERNAL_MODULE__205__","semver","validateAndParse","isWildcard","tryParse","compareStrings","forceType","compareSegments","v1","v2","n1","n2","p1","p2","operator","assertValidOperator","operatorResMap","allowedOperators","op","v3","vp","r1","r2","r3","rp","nonZero","this","entityMetadata","ts","tsxCoord","tsyCoord","ldtkEntityIdentifier","preExisting","ldtkEntities","ldtk","maybeEntity","fieldIdentifier","normalizedValue","field","contentType","layerMetadata","solidValue","xCoord","yCoord","tileset","imagePath","friendlyTileset","levelPath","friendlyLevel","entityLayer","firstTileLayer","errored","inputPath","matches","basePath","relativeToBase","originSplit","relativeSplit","exTile","LdtkTilesetRectangle","LdtkPixel","LdtkFieldInstance","LdtkTileInstance","LdtkWorld","LdtkEnumValueDefinition","LdtkEnumDefinition","LdtkTilesetDefinition","LdtkDefinitions","util_1","super","subs","actualProto","_mapper","mapper","issue","processError","mod","en_1","overrideErrorMap","k2","errors_1","params","fullPath","fullIssue","errorMessage","maps","arrayValue","syncPairs","finalObject","_arg","validKeys","filtered","checker","separator","second","ZodError_1","errorUtil_1","parseUtil_1","ParseInputLazyPath","handleResult","processCreateParams","iss","def","maybeAsyncResult","getIssueProperties","setError","refinementData","option","incoming","defaultValueFunc","catchValueFunc","This","cuidRegex","cuid2Regex","ulidRegex","uuidRegex","emailRegex","emojiRegex","ipv4Regex","ipv6Regex","tooBig","tooSmall","ch","floatSafeRemainder","valDecCount","stepDecCount","decCount","deepPartialify","newShape","fieldSchema","shapeKeys","extraKeys","keyValidator","augmentation","merging","newField","createZodEnum","childCtx","getDiscriminator","discriminatorValue","discriminatorValues","mergeValues","aType","bType","bKeys","sharedKeys","sharedValue","newArray","handleParsed","parsedLeft","parsedRight","merged","itemIndex","schemas","third","finalMap","finalizeSet","elements","parsedSet","makeArgsIssue","makeReturnsIssue","parsedArgs","parsedReturns","expectedValues","enumValues","opt","nativeEnumValues","promisified","checkCtx","arg","processed","executeRefinement","inner","newCtx","inResult","handleAsync","_fatal","cls","stringType","numberType","nanType","bigIntType","booleanType","dateType","symbolType","undefinedType","nullType","anyType","unknownType","neverType","voidType","arrayType","objectType","strictObjectType","unionType","discriminatedUnionType","intersectionType","tupleType","recordType","mapType","setType","functionType","lazyType","literalType","enumType","nativeEnumType","promiseType","effectsType","optionalType","nullableType","preprocessType","pipelineType","__webpack_module_cache__","__webpack_modules__"],"version":3,"file":"index.c2a0b4ac.js.map"} \ No newline at end of file diff --git a/index.html b/index.html index 8d543c5..0c2520f 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -Sample LDtk \ No newline at end of file +Sample LDtk \ No newline at end of file diff --git a/index.runtime.a7f5c002.js b/index.runtime.a8c72a04.js similarity index 74% rename from index.runtime.a7f5c002.js rename to index.runtime.a8c72a04.js index 90f4b25..515104d 100644 --- a/index.runtime.a7f5c002.js +++ b/index.runtime.a8c72a04.js @@ -1,2 +1,2 @@ -var e=globalThis,r={},t={},a=e.parcelRequire4b3c;null==a&&((a=function(e){if(e in r)return r[e].exports;if(e in t){var a=t[e];delete t[e];var n={id:e,exports:{}};return r[e]=n,a.call(n.exports,n,n.exports),n.exports}var o=Error("Cannot find module '"+e+"'");throw o.code="MODULE_NOT_FOUND",o}).register=function(e,r){t[e]=r},e.parcelRequire4b3c=a),(0,a.register)("27Lyk",function(e,r){Object.defineProperty(e.exports,"register",{get:()=>t,set:e=>t=e,enumerable:!0,configurable:!0});var t,a=new Map;t=function(e,r){for(var t=0;tt,set:e=>t=e,enumerable:!0,configurable:!0});var t,a=new Map;t=function(e,r){for(var t=0;t","node_modules/@parcel/runtime-js/lib/helpers/bundle-manifest.js","node_modules/@parcel/runtime-js/lib/runtime-ee372134491327ba.js"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequire4b3c\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequire4b3c\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"27Lyk\", function(module, exports) {\n\n$parcel$export(module.exports, \"register\", () => $18c11f3350a906ea$export$6503ec6e8aabbaf, (v) => $18c11f3350a906ea$export$6503ec6e8aabbaf = v);\nvar $18c11f3350a906ea$export$6503ec6e8aabbaf;\nvar $18c11f3350a906ea$export$f7ad0328861e2f03;\n\"use strict\";\nvar $18c11f3350a906ea$var$mapping = new Map();\nfunction $18c11f3350a906ea$var$register(baseUrl, manifest) {\n for(var i = 0; i < manifest.length - 1; i += 2)$18c11f3350a906ea$var$mapping.set(manifest[i], {\n baseUrl: baseUrl,\n path: manifest[i + 1]\n });\n}\nfunction $18c11f3350a906ea$var$resolve(id) {\n var resolved = $18c11f3350a906ea$var$mapping.get(id);\n if (resolved == null) throw new Error(\"Could not resolve bundle with id \" + id);\n return new URL(resolved.path, resolved.baseUrl).toString();\n}\n$18c11f3350a906ea$export$6503ec6e8aabbaf = $18c11f3350a906ea$var$register;\n$18c11f3350a906ea$export$f7ad0328861e2f03 = $18c11f3350a906ea$var$resolve;\n\n});\n\nvar $882f3ba79d3c206b$exports = {};\n\n(parcelRequire(\"27Lyk\")).register(new URL(\"\", import.meta.url).toString(), JSON.parse('[\"aT88m\",\"index.c2a0b4ac.js\",\"gwldb\",\"Hero 01.0a89e3b5.png\",\"aR98p\",\"Solaria Demo Update 01.c847244e.png\",\"hFN2b\",\"Level_0.076f9bf4.ldtkl\",\"adHXu\",\"Level_1.fb97a422.ldtkl\",\"8jGU4\",\"top-down.8a075006.ldtk\"]'));\n\n\n//# sourceMappingURL=index.runtime.a7f5c002.js.map\n","\"use strict\";\n\nvar mapping = new Map();\nfunction register(baseUrl, manifest) {\n for (var i = 0; i < manifest.length - 1; i += 2) {\n mapping.set(manifest[i], {\n baseUrl: baseUrl,\n path: manifest[i + 1]\n });\n }\n}\nfunction resolve(id) {\n var resolved = mapping.get(id);\n if (resolved == null) {\n throw new Error('Could not resolve bundle with id ' + id);\n }\n return new URL(resolved.path, resolved.baseUrl).toString();\n}\nmodule.exports.register = register;\nmodule.exports.resolve = resolve;","require('./helpers/bundle-manifest').register(new __parcel__URL__(\"\").toString(),JSON.parse(\"[\\\"aT88m\\\",\\\"index.c2a0b4ac.js\\\",\\\"gwldb\\\",\\\"Hero 01.0a89e3b5.png\\\",\\\"aR98p\\\",\\\"Solaria Demo Update 01.c847244e.png\\\",\\\"hFN2b\\\",\\\"Level_0.076f9bf4.ldtkl\\\",\\\"adHXu\\\",\\\"Level_1.fb97a422.ldtkl\\\",\\\"8jGU4\\\",\\\"top-down.8a075006.ldtk\\\"]\"));"],"names":["$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","Object","defineProperty","get","$18c11f3350a906ea$export$6503ec6e8aabbaf","set","v","enumerable","configurable","$18c11f3350a906ea$var$mapping","Map","baseUrl","manifest","i","length","path","URL","url","toString","JSON","parse"],"version":3,"file":"index.runtime.a7f5c002.js.map"} \ No newline at end of file +{"mappings":"A,I,E,W,E,C,E,E,C,E,E,E,iB,A,O,I,A,C,E,S,C,E,G,K,E,O,C,C,E,C,O,C,G,K,E,C,I,E,C,C,E,A,Q,C,C,E,C,I,E,C,G,E,Q,C,C,E,O,C,C,E,C,E,E,I,C,E,O,C,E,E,O,E,E,O,A,C,I,E,A,M,uB,E,I,O,E,I,C,mB,C,C,E,Q,C,S,C,C,C,E,C,C,E,C,C,E,E,iB,C,G,A,C,E,E,Q,A,E,Q,S,C,C,C,E,O,c,C,E,O,C,W,C,I,I,E,I,A,G,E,E,W,C,E,a,C,C,GCEA,IAgBA,EAhBI,EAAU,IAAI,IAgBlB,EAfA,SAAkB,CAAO,CAAE,CAAQ,EACjC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAS,MAAM,CAAG,EAAG,GAAK,EAC5C,EAAQ,GAAG,CAAC,CAAQ,CAAC,EAAE,CAAE,CACvB,QAAS,EACT,KAAM,CAAQ,CAAC,EAAI,EAAE,AACvB,EAEJ,C,GCVA,AAAA,EAAA,SAAA,QAAA,CAA8C,IAAA,IAAoB,GAAA,YAAA,GAAA,EAAI,QAAQ,GAAG,KAAK,KAAK,CAAC","sources":["","node_modules/@parcel/runtime-js/lib/helpers/bundle-manifest.js","node_modules/@parcel/runtime-js/lib/runtime-5b39b8a772d93f1c.js"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequire4b3c\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequire4b3c\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"27Lyk\", function(module, exports) {\n\n$parcel$export(module.exports, \"register\", () => $18c11f3350a906ea$export$6503ec6e8aabbaf, (v) => $18c11f3350a906ea$export$6503ec6e8aabbaf = v);\nvar $18c11f3350a906ea$export$6503ec6e8aabbaf;\nvar $18c11f3350a906ea$export$f7ad0328861e2f03;\n\"use strict\";\nvar $18c11f3350a906ea$var$mapping = new Map();\nfunction $18c11f3350a906ea$var$register(baseUrl, manifest) {\n for(var i = 0; i < manifest.length - 1; i += 2)$18c11f3350a906ea$var$mapping.set(manifest[i], {\n baseUrl: baseUrl,\n path: manifest[i + 1]\n });\n}\nfunction $18c11f3350a906ea$var$resolve(id) {\n var resolved = $18c11f3350a906ea$var$mapping.get(id);\n if (resolved == null) throw new Error(\"Could not resolve bundle with id \" + id);\n return new URL(resolved.path, resolved.baseUrl).toString();\n}\n$18c11f3350a906ea$export$6503ec6e8aabbaf = $18c11f3350a906ea$var$register;\n$18c11f3350a906ea$export$f7ad0328861e2f03 = $18c11f3350a906ea$var$resolve;\n\n});\n\nvar $03aa293807d544f4$exports = {};\n\n(parcelRequire(\"27Lyk\")).register(new URL(\"\", import.meta.url).toString(), JSON.parse('[\"aT88m\",\"index.a78842eb.js\",\"gwldb\",\"Hero 01.0a89e3b5.png\",\"aR98p\",\"Solaria Demo Update 01.c847244e.png\",\"hFN2b\",\"Level_0.4121d29c.ldtkl\",\"adHXu\",\"Level_1.0859d067.ldtkl\",\"ctRFm\",\"House.9ff42634.ldtkl\",\"8jGU4\",\"top-down.3490dc55.ldtk\"]'));\n\n\n//# sourceMappingURL=index.runtime.a8c72a04.js.map\n","\"use strict\";\n\nvar mapping = new Map();\nfunction register(baseUrl, manifest) {\n for (var i = 0; i < manifest.length - 1; i += 2) {\n mapping.set(manifest[i], {\n baseUrl: baseUrl,\n path: manifest[i + 1]\n });\n }\n}\nfunction resolve(id) {\n var resolved = mapping.get(id);\n if (resolved == null) {\n throw new Error('Could not resolve bundle with id ' + id);\n }\n return new URL(resolved.path, resolved.baseUrl).toString();\n}\nmodule.exports.register = register;\nmodule.exports.resolve = resolve;","require('./helpers/bundle-manifest').register(new __parcel__URL__(\"\").toString(),JSON.parse(\"[\\\"aT88m\\\",\\\"index.a78842eb.js\\\",\\\"gwldb\\\",\\\"Hero 01.0a89e3b5.png\\\",\\\"aR98p\\\",\\\"Solaria Demo Update 01.c847244e.png\\\",\\\"hFN2b\\\",\\\"Level_0.4121d29c.ldtkl\\\",\\\"adHXu\\\",\\\"Level_1.0859d067.ldtkl\\\",\\\"ctRFm\\\",\\\"House.9ff42634.ldtkl\\\",\\\"8jGU4\\\",\\\"top-down.3490dc55.ldtk\\\"]\"));"],"names":["$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","Object","defineProperty","get","$18c11f3350a906ea$export$6503ec6e8aabbaf","set","v","enumerable","configurable","$18c11f3350a906ea$var$mapping","Map","baseUrl","manifest","i","length","path","URL","url","toString","JSON","parse"],"version":3,"file":"index.runtime.a8c72a04.js.map"} \ No newline at end of file diff --git a/top-down.8a075006.ldtk b/top-down.3490dc55.ldtk similarity index 92% rename from top-down.8a075006.ldtk rename to top-down.3490dc55.ldtk index ed4e5d2..6907656 100644 --- a/top-down.8a075006.ldtk +++ b/top-down.3490dc55.ldtk @@ -11,7 +11,7 @@ "iid": "db4c4660-6280-11ee-bc44-d73e490029da", "jsonVersion": "1.5.3", "appBuildId": 473703, - "nextUid": 20, + "nextUid": 23, "identifierStyle": "Capitalize", "toc": [], "worldLayout": "Free", @@ -550,6 +550,79 @@ "tilesetUid": null } ] + }, + { + "identifier": "Door", + "uid": 20, + "tags": [], + "exportToToc": false, + "allowOutOfBounds": false, + "doc": null, + "width": 16, + "height": 16, + "resizableX": false, + "resizableY": false, + "minWidth": null, + "maxWidth": null, + "minHeight": null, + "maxHeight": null, + "keepAspectRatio": false, + "tileOpacity": 1, + "fillOpacity": 1, + "lineOpacity": 1, + "hollow": false, + "color": "#733E39", + "renderMode": "Rectangle", + "showName": true, + "tilesetId": null, + "tileRenderMode": "FitInside", + "tileRect": null, + "uiTileRect": null, + "nineSliceBorders": [], + "maxCount": 0, + "limitScope": "PerLevel", + "limitBehavior": "MoveLastOne", + "pivotX": 0, + "pivotY": 0, + "fieldDefs": [ + { + "identifier": "scene", + "doc": null, + "__type": "String", + "uid": 22, + "type": "F_String", + "isArray": false, + "canBeNull": true, + "arrayMinLength": null, + "arrayMaxLength": null, + "editorDisplayMode": "Hidden", + "editorDisplayScale": 1, + "editorDisplayPos": "Above", + "editorLinkStyle": "StraightArrow", + "editorDisplayColor": null, + "editorAlwaysShow": false, + "editorShowInWorld": true, + "editorCutLongValues": true, + "editorTextSuffix": null, + "editorTextPrefix": null, + "useForSmartColor": false, + "exportToToc": false, + "searchable": false, + "min": null, + "max": null, + "regex": null, + "acceptFileTypes": null, + "defaultOverride": null, + "textLanguageMode": null, + "symmetricalRef": false, + "autoChainRef": true, + "allowOutOfLevelRef": true, + "allowedRefs": "OnlySame", + "allowedRefsEntityUid": null, + "allowedRefTags": [], + "tilesetUid": null + } + ] } ], "tilesets": [ { @@ -664,7 +737,30 @@ "externalRelPath": "top-down/Level_1.ldtkl", "fieldInstances": [], "layerInstances": null, - "__neighbours": [{ "levelIid": "db4d09b0-6280-11ee-bc44-1b84534fe012", "dir": "w" }] + "__neighbours": [ { "levelIid": "db4d09b0-6280-11ee-bc44-1b84534fe012", "dir": "w" }, { "levelIid": "bc0f7ad0-b0a0-11ee-9c50-2597384ac3cd", "dir": "n" } ] + }, + { + "identifier": "House", + "iid": "bc0f7ad0-b0a0-11ee-9c50-2597384ac3cd", + "uid": 21, + "worldX": 336, + "worldY": -256, + "worldDepth": 0, + "pxWid": 256, + "pxHei": 256, + "__bgColor": "#696A79", + "bgColor": null, + "useAutoIdentifier": false, + "bgRelPath": null, + "bgPos": null, + "bgPivotX": 0.5, + "bgPivotY": 0.5, + "__smartColor": "#ADADB5", + "__bgPos": null, + "externalRelPath": "top-down/House.ldtkl", + "fieldInstances": [], + "layerInstances": null, + "__neighbours": [{ "levelIid": "471aa8b0-b0a0-11ee-83ad-197e8057ca90", "dir": "s" }] } ], "worlds": [],